games and code code it, play it
Camera calculations
January 8th, 2008

Handling the camera in 3D games is all about math. You learn the theory, explore few tutorials and you’re ready to implement your own camera. Most of the time this results in empty screen, with camera pointing who knows where. I’ve included simple camera work over my terrain projects. If I want to remember this procedure, it’ll be best to write it down. This time I’ll list the source code line by line.

Which part of 3D scene is seen on a 2D screen is defined with few matrices. Theory behind this is easy to find on the Internet so I’ll jump into the code.

There is only one object in my 3D scene: terrain. It is defined with bunch of vertexes and covered with textures. It is stretch from point (X:-32,Y:-32) to (X:+32,X:+32) with Z varying from 0 to 32.

Camera is defined with it’s position in 3D world and angle at which is pointing at the world.
On this image camera is positioned at (X:0,Y:-100,Z:100) and it is looking at 45° relative to X axis.

So, how to code all this for DirectX?

A camera is defined by position and angle:

Vector3 cameraPos = new Vector3(0, -64, 64);
Vector3 cameraAngle = new Vector3(MathHelper.Pi / 4, 0, 0);

Type of the camera is defined by projection matrix:

float WindowRatio = (float)this.Window.ClientBounds.Width / (float)this.Window.ClientBounds.Height;
Matrix projMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, WindowRatio, 1.0f, 1000.0f);

View matrix is defined by source point, destination point and reference vector:

viewMatrix = Matrix.CreateLookAt(cameraPos,cameraTarget,Vector3.Up);

As you can see, we don’t yet have cameraTarget. We must calculate it from camera position and camera orientation:

//create rotation matrix from angles
Matrix mRotate = Matrix.CreateFromYawPitchRoll(cameraAngle.Y, cameraAngle.X, cameraAngle.Z);
//get where will target be positioned in relation to the camera
Vector3 transformedCamera = Vector3.Transform(Vector3.Forward, mRotate);
//camera target is transformedCamera added to cameraPos
Vector3 cameraTarget = transformedCamera + cameraPos;

This code should produce a view like one on the first image.

We’ll use arrow keys to move the camera left, right, forward and backward and mouse scroll wheel for zooming:

KeyboardState ks = Keyboard.GetState();
MouseState ms = Mouse.GetState();
Vector3 moveVector=Vector3.Zero;

Moving the camera is easy, just change the X and Y point of the camera position vector:

KeyboardState ks = Keyboard.GetState();
if(ks.IsKeyDown(Keys.Left))
moveVector.X-=0.5f;
if(ks.IsKeyDown(Keys.Right))
moveVector.X+=0.5f;
if(ks.IsKeyDown(Keys.Up))
moveVector.Y+=0.5f;
if(ks.IsKeyDown(Keys.Down))
moveVector.Y-=0.5f;

Zooming is little more complicated, but not too much. If we just change the Z point of camera vector, it will look like the camera is tied to some pole and it is pulled up and down like a flag. Instead, camera should fly towards the point it is pointing. For that, we again need to use rotation matrix and calculate a zoom factor from it.

First we need a global variable to store the last mouse position:

int lastScroll;

Then in UpdateInput() procedure we calculate the zoom factor:

//how much has scroll wheel moved?
int scrollDiff = ms.ScrollWheelValue-lastScroll;
//create rotation matrix from angles
Matrix mRotate = Matrix.CreateFromYawPitchRoll(cameraAngle.Y, cameraAngle.X, cameraAngle.Z);
//create vector which points to the target
Vector3 zoomVector = Vector3.Transform(Vector3.Forward, mRotate);
//add zoom factor to moveVector
moveVector += zoomVector * (scrollDiff * 0.05f);
//reset the scroll value
lastScroll = ms.ScrollWheelValue;
//allow the movement only if camera will stay within limits
if ((cameraPos.Z+moveVector.Z>10) &amp;amp;(cameraPos.Z+moveVector.Z<100))
cameraPos += moveVector;

This code will provide simple camera movement. Camera limits should be defined better to avoid going through the terrain and too far on the sides. I suppose now that I've written all this down, I should finally remember the procedure.

Code is unorganized for better readability. Organized code with camera class, together with terrain project is here: Terrain and camera

Category: Uncategorized

Was this article helpful? Improve it with your comment.