# XNA Framework and looking around relative to the world instead of camera?

So I've been toying around with creating a game in the XNA framework. A great place to start is simply being able to move and walk around.

I kinda have looking around...

I start off with the camera position/direction as follows:

cameraDirection = Matrix.CreateLookAt(new Vector3(0, 0, 1.5f), new Vector3(0, 1, -1), Vector3.Up);


I also have a small cube rendered in a static location, on which I plan to walk around. I'm manipulating the cameraDirection from a controller as follows:

GamePadState one = GamePad.GetState(PlayerIndex.One);
if (one.Buttons.Back == ButtonState.Pressed)
this.Exit();
if (one.ThumbSticks.Right.Length() > .1f) {//Deadzone, must push stick at least 10%
cameraDirection *= Matrix.CreateRotationY((float)(gameTime.ElapsedGameTime.TotalMilliseconds * (.002 * one.ThumbSticks.Right.X)));
cameraDirection *= Matrix.CreateRotationX((float)(gameTime.ElapsedGameTime.TotalMilliseconds * (-.002 * one.ThumbSticks.Right.Y)));
}


And at first this appeared to work. Then I realized that the X and Y axes are relative to the camera's current orientation. If I turn left and right while looking straight forward, that appears to work. If I look straight down and then turn left and right, I'm rotating along a different axis. I want to look around in relation to the world's axes instead of the camera's... How can I do this?

First, you should be aware that there really is no such thing as a camera. There is only the camera view and projection matricies, which transform all the vertices in the world into a position relative to the camera.

That said, your problem is due to the order of transformations applied to the camera view matrix.

Instead of applying transformations to the camera view matrix over and over, which results in weird skewing of the view, and other fun unwanted stuff (like gimbal lock, as 3nixios pointed out).

The order of matrix multiplication matters. If you multiply by x and then by y, you get a different result from y by x. So multiplying many times in a row by different amounts along different axis produces a different result from what you were expecting.

Store yaw, pitch (and roll) in 3 separate floats in your camera. Store position in a Vector3.

Then at each camera update, do this:

cameraView = Matrix.CreateRotationX(Pitch);
cameraView *= Matrix.CreateRotationY(Yaw);
cameraView *= Matrix.CreateTranslation(Position);


Remember that the order of those multiplications matters!

Then just add to yaw/pitch like this:

float elapsed = (float)(gameTime.ElapsedGameTime.TotalMilliseconds;
Yaw += elapsed * (.002 * one.ThumbSticks.Right.X));

if(Yaw > (MathHelper.Pi * 2)){
Yaw -= MathHelper.Pi * 2;
}


(And the same for pitch and roll.)

// Move up by 5 units per second.