# D3DXQUATERNION-Based Camera for Flight Simulations

### Introduction

CCamera is a DirectX Quaternion-based camera class for flight simulations. If you don't know what Quaternion is and why to use it, then I would recommed to go through http://www.cprogramming.com/tutorial/3d/quaternions.html so that you can have a good idea what a Quaternion really is.

After going through the above link, you might think that: Do I have to write my own Quaternion class to implement Quaternion in my application/game/game engine?

### Details

Well, if you are using DirectX 9.0, don't worry; Microsoft has already taken care of all the Quaternion stuff for you and has provided you with D3DXQUATERNION structure along with a certain set of APIs that you can use to manipulate the Quaternion the way you want.

Based on D3DXQUATERNION, CCamera is a Camera class that can be used for flight simulations. Before we proceed, let me explain some terms that will be used later on; this a good time to discuss them.

• Roll: Roation around Z-Axis i.e. Rotation around the front-to-back axis
• Pitch: Rotation around X-Axis i.e. Rotation around the side-to-side axis
• Yaw: Rotation around Y-Axis, i.e. Rotation around the vertical axis

To have a good understanding of them, I found a very good example (I don't know where, but it really helped). Look at the front wall where you are sitting and consider that three vectors are coming out of your head. One is going from your right ear onwards, one from your head upward, and one from your nose away.

Now, if you rotate the vector that is coming out of your right ear (X-Axis), your focus will shift from the wall's current location amd will shift to the new location. This is Pitch. Similarly, if you you rotate the vector that is coming from your nose, it is roll; if you rotate the vector coming out of your head, it's Yaw. By varying these three vectors, you can change the orientation of your camera.

• Move: Translate Forward-Backward
• Strafe: Translate Left-Right
• Up: Tanslate Up-Down
• Slerp: Spherical Linear Interpolation. Interpolating between two orientations uses quaternions in a smooth way, depending upon the angle to interpolate.

Okay, now let's move on to CCamera. CCamera aggregates D3DXQUATERNION for the rotiaon purposes, D3DXVECTOR3 to the position management, in 3D space. To implement CCamera, create an object of it, like in the sample

`wiCam::CCamera TheCamera;`

and before rendering your scene, manipulate the camera orientation. You can see that in Display(), in which the scene is being rendered. The effect of your implementation will be calculated in the aggregated quaternion/vector and when you extract the view matrix to render, the overall effect will be applied to the view matrix and will be returned to you, like so:

```   // Update the view matrix representing the cameras
// new position/orientation.

D3DXMATRIX V = *TheCamera.GetViewMatrix();
Device->SetTransform(D3DTS_VIEW, &V);
```

and GetViewMatrix is implemented as

```const D3DXMATRIX * CCamera::GetViewMatrix()
{
if (m_bNeedUpdated)
{
Update();
}

return &m_matView;
}

void CCamera::Update()
{
// 1) Build a new view matrix

// 1.1) First calcuate Translation
D3DXMATRIX matTranslation;

D3DXMatrixTranslation(  &matTranslation ,
-m_vectPosition.x ,
-m_vectPosition.y ,
-m_vectPosition.z );

// 1.2) Now calculate rotation, by taking the conjucate of the
// quaternion
D3DXMATRIX matRotation;
D3DXMatrixRotationQuaternion( &matRotation,
&D3DXQUATERNION( -m_quatOrientation.x ,
-m_quatOrientation.y ,
-m_quatOrientation.z ,
m_quatOrientation.w ));

// 2) Apply rotation & translation matrix at view matrix
D3DXMatrixMultiply(&m_matView , &matTranslation , &matRotation );

// 3) Set flag to false, to save CPU
m_bNeedUpdated = false;
}
```

To change the camera orientation, you can use the public interface methods, as shown here:

```if( KEY_DOWN('W') ) TheCamera.Move( 1.0f * timeDelta);   // Forward
if( KEY_DOWN('S') ) TheCamera.Move( -1.0f * timeDelta);  // Backward
if( KEY_DOWN('A') ) TheCamera.Strafe(-1.0f * timeDelta); // Left Side
if( KEY_DOWN('D') ) TheCamera.Strafe(1.0f * timeDelta);  // Right Side
if( KEY_DOWN('R') ) TheCamera.Up(1.0f * timeDelta);      // Upward
if( KEY_DOWN('F') ) TheCamera.Up(-1.0f * timeDelta);     // Downward
if( KEY_DOWN('B') ) TheCamera.SetSpeed(++fSpeed);        // Increase
// Translation
// Speed
if( KEY_DOWN('V') ) TheCamera.SetSpeed(--fSpeed);        // Decrease
// Translation
// Speed
if( KEY_DOWN('J') ) TheCamera.SetRPM(++fRPM);            // Increase
// Rotation
// Per Minute
if( KEY_DOWN('K') ) TheCamera.SetRPM(--fRPM);            // Decrease
// Rotation
// Per Minute
if( KEY_DOWN('N') ) TheCamera.Roll(0.02f);               // Roll left
// side
if( KEY_DOWN('M') ) TheCamera.Roll(-0.02f);              // Roll right
// side
if( KEY_DOWN(VK_UP)) TheCamera.Pitch(0.02f);             // Pitch
// upward
if( KEY_DOWN(VK_DOWN)) TheCamera.Pitch(-0.02f);          // Pitch
// downward
if( KEY_DOWN(VK_LEFT)) TheCamera.Yaw(-0.02f);            // Yaw Sideways
if( KEY_DOWN(VK_RIGHT)) TheCamera.Yaw(0.02f);
```

If you run the sample, press the space bar and keep holding the key; you'll find that the camera rotates at your back. Well, this is Slerp. You can adjust its speed as well. For the sake of this article, I've hardcoded a target quaternion, and calculated the slerp so that you can see its implementation and execution, In real flight simulation, you'll have to get the target quaternion from your target and then you'll be able to implement Slerp between your current orientation and the target orientation.

Other then that, the rest of the code implements the DirectX and some utility functions, which has nothing much to do with the camera. The code is copy right un-protected and you can use it freely. If you use it, do let me know about that. Have fun.

### References

www.gamedev.net
Introduction to 3D Game Programming with DirectX 9.0

• #### you can repossess the excellent clarisonic in myer

Posted by iouwanzi on 06/06/2013 12:12pm

• #### Skal krÃ¸llerne vÃ¦re faste og spÃ¦ndstige skal du fÃ¸re glattejernet langsomt gennem hÃ¥ret

Posted by wanzixiao on 05/30/2013 06:16pm

• #### Lightweight stylish â Nike Unshackled TR Attack in divulge 2013 3 series

Posted by Tufffruntee on 04/19/2013 06:30am

Nike Free TR Fit 3 prominent features is to use the trendy plot: Nike Free 5 soles improved bending Gouge; stylish tractor imitate making training more focused when; lighter load, the permeability is stronger, and more fashionable shoe designs not just aim for shoes [url=http://northernroofing.co.uk/roofins.cfm]nike free uk[/url] more pleasant wearing, barefoot training have compassion for incline, but also more fashionable appearance. Nike On the house TR Robust 3 provides supreme lateral reliability, you can take the legs in the lap boost during training. Diligent vamp majuscule letters breathable grating, lower suds's one of a kind lay out can be [url=http://fossilsdirect.co.uk/glossarey.cfm]nike huarache free[/url] seen by virtue of it. Lightweight, demanding, piddling bubbles means used at hand entirely occasional seams, more flexible, advocate is stronger. Lack more advance, factor of a training irritate, lather close in more parts of the neediness for give, bubbles loose. Throw away two-ply talk moisture wicking mock materials, unshiny on your feet, mitigate living feet dry and comfortable. Phylite [url=http://fossilsdirect.co.uk/glossarey.cfm]nike huarache[/url] midsole offers lightweight surprise level, famous durability and unbroken outsole can do to greatly reduce the total dialect heft of the shoe. Qianzhang pods on the outsole and heel-shaped Green rubber enhances the shoe multi-directional traction on sundry surfaces.

• #### Slerp

Posted by brekehan on 07/30/2007 11:29pm

I don't quite understand the slerp function. It is not discussed in the article. Can someone give me a little insight as to what it does? I googled slerp and all I can get is complicated math explanations. I am trying to understand its purpose. I see it being called when the space bar is hit in the main code, but don't see any comments on the space bar.

• #### RE:

Posted by Ejaz on 07/31/2007 07:48am

The basic idea of SLERP (Spherical Linear Interpolation) is, generatation of a series of quaternions between two quaternion orientations (which you specify). The series of quaternions will result in smooth motion between the first and end quaternion (something which both the Euler and Axis Angle representation cannot achieve consistently).

• #### RE: Slerp

Posted by brekehan on 07/31/2007 07:42am

That was the mathematical Explanation I was speaking of. It is too hard to understand and I am a Math Minor! I assume it is a calculation between two rotations, but I don't see its use. Why can't I just assign my rotation that I want to achieve in my game? What is the advantage of Slerp? What situations would you need to calculate between two rotations?

• #### Re: Slerp

Posted by Ejaz on 07/31/2007 12:41am

Please take a look at http://en.wikipedia.org/wiki/Slerp

• #### problem with camera circular movement

Posted by sepul on 03/28/2006 05:13pm

when I rotate camera circular style (left-top-right-down-...) on each move, the camera gets rotated around z-axis I have the same exact problem with my own class too, do you how can this problem be solved ? thanks

• #### Excellent example

Posted by luisleal on 12/09/2004 05:05pm

This example was clear, woked well and I was able to create a C# version. Thanks

• #### Test message - Please ignore

Posted by Brad Jones on 11/19/2004 09:28am

This is a test message that will be removed.

• #### A very good tutorial

Posted by hese on 11/15/2004 07:54am

This tutorial is very helpful and the sample works fine except when I'm trying to rotate x-axis and y-axis simultaneously. Then the z-axis rotates too. I know it happens because the yaw and the pitch operations are done separately but I don't know how to correct it. I'm also trying to modify the camera class so that I could use it for an object other than the actual camera. My goal is to get the object to rotate and to move towards the camera by using the Slerp function. I modified the SetTransform function's parameters as below. D3DXMATRIX V = *TheObjectCamera.GetViewMatrix(); g_pDevice->SetTransform(D3DTS_WORLD, &V); How should I modify the Camera class or is there an easier way to do this? P.S. I'm programming a space simulation game just for fun.

• #### hese

Posted by hese on 11/22/2004 09:13am

Yes I would be happy to send my implementation. Where do I send it?

• #### From Ejaz Anwer (posted by the Webmaster)

Posted by Brad Jones on 11/19/2004 09:29am

```Well, I think you should compute a cross product of the two
vectors to get the 3d vector (which will be mutually orthogonal) for
the y-axis according to the other two new vectors. D3DXVec3Cross will
serve the purpose for you.

For the second part, in case of matrix computation, order is very
critical. Is it possible that you send a copy of your implementation, so
that I can see exactely how it is implemented and what is the
problem?```

• #### Re: Re: A very good tutorial

Posted by hese on 11/18/2004 09:26am

Thank you very much for answering. I understand you point about the spinning but I'm trying to rotate x- and y-axis by a mouse just like in any ordinary fps game. I still want the camera to move in the direction of the orientation so I can't use a constant y-axis. And for the second part, I made a copy of the camera class and tried to modify that so it could give me the orientation of the particle (the orientation and movement of the particle isn't in any way depending of the position or orientation of the camera). For instance I modified the Update function by changing the order in which the translation and rotation matrices are multiplied so the particle rotates around itself. I've succeeded in getting the slerp function to work correctly for the particle in XZ-plane (in other words the particle rotates around a constant y-axis, up vector(0,1,0), and moves towards the camera's position) but when I'm trying to add y-axis it starts acting strangely. And thank you for the link to the MeshViewer example. It will probably solve my problem if I'm able to modify it so that the particle moves to the direction of the orientation. P.S. Is there any way I can add empty lines to my text so it would be easier to read?

• #### Re: A very good tutorial

Posted by Ejaz on 11/16/2004 12:27pm

Dear hese, I'm not sure that I preceive what exactly you want to do and how you are doing. In case of Roll/Pitch/Yaw, when you press up/down key, the pitch is changed, so if you hold any of the key and press left/right, Yaw start along with it. Values are calculated, orientation is updated, and in the end, the renderer renders the new scene, which gives the fell of spining (this gives the view of the pilot). For the second part, I guess the rotation of a particular object should be associated with the object itself, coz you may have other objects in the scene (sooner or later) and each object rotation behaviour shouldn't be the part of the camera. What you can do is, place the camera (at some particular point), render the object, upon rotaion of the object, update its (object) orientation and when the main renderer will start its work, it will go through each object in the scene and render the update oriented object. I don't know that exactly this will help, but have a look at http://www.codeguru.com/Cpp/G-M/directx/directx8/article.php/c6701/ for managing multiple objects in a scene and changing there orientation. Regards, Ejaz.

• You must have javascript enabled in order to post comments.

## Top White Papers and Webcasts

• On-demand Event Event Date: August 27, 2015 With the cloud enabling companies to spin up servers and stand up data stores more quickly, mobile apps can be created faster, reducing the time-to-value. But three major obstacles stand in the way for many organizations: The backlog of app project requests confronting every enterprise regardless of their internal app development capabilities Finding and employing better, faster tools to speed and simplify the process of developing those apps. The emergence of …

• When individual departments procure cloud service for their own use, they usually don't consider the hazardous organization-wide implications. Read this paper to learn best practices for setting up an internal, IT-based cloud brokerage function that service the entire organization. Find out how this approach enables you to retain top-down visibility and control of network security and manage the impact of cloud traffic on your WAN.

## Most Popular Programming Stories

• There have been no articles posted today.