# [SOLVED] Rotating a Camera around its own axis

I’m having trouble transforming the matrix for my camera (intended as a first person camera for a future First Person Shooter Project).

Previously, instead of CreateFromAxisAngle, I used CreateRotation to rotate the view around the axes. That didn’t work as intended, since as I understand that rotates around world axes. The further you got from the starting target direction, the worse the camera behaved.

I researched it and I understand I have to transform the Vectors/Matrices to a rotation around a local axis, but I’m having trouble actually doing that. The current code doesn’t seem to rotate the camera, since the models I have drawn (in the main game class) are never visible.

I’m hoping someone could point out where I went wrong!

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace MonoGame3D
{
public class Camera
{
// We need this to calculate the aspectRatio
// in the ProjectionMatrix property.
GraphicsDevice graphicsDevice;
float angleX;
float angleY;
Vector3 cameraUpVector = Vector3.UnitZ;
Vector3 lookAtVector = new Vector3(0, -1, -.5f);
MouseState currentMouseState, previousMouseState;

``````    Vector3 position = new Vector3(0, 20, 10);
``````
``````    public Matrix ViewMatrix
{
get
{
lookAtVector = Vector3.Transform(lookAtVector, Matrix.CreateFromAxisAngle(cameraUpVector, angleX));
lookAtVector = Vector3.Transform(lookAtVector, Matrix.CreateFromAxisAngle(Vector3.Cross(cameraUpVector, lookAtVector), angleY));
lookAtVector += position;
cameraUpVector = Vector3.Transform(cameraUpVector, Matrix.CreateFromAxisAngle(Vector3.Cross(cameraUpVector, lookAtVector), angleY));
``````
``````            return Matrix.CreateLookAt(
position, lookAtVector, cameraUpVector);
}
}
``````
``````    public Matrix ProjectionMatrix
{
get
{
float fieldOfView = Microsoft.Xna.Framework.MathHelper.PiOver4;
float nearClipPlane = 1;
float farClipPlane = 200;
float aspectRatio = graphicsDevice.Viewport.Width / (float)graphicsDevice.Viewport.Height;
``````
``````            return Matrix.CreatePerspectiveFieldOfView(
fieldOfView, aspectRatio, nearClipPlane, farClipPlane);
}
}
``````
``````    public Camera(GraphicsDevice graphicsDevice)
{
this.graphicsDevice = graphicsDevice;
}
``````
``````    public void Update(GameTime gameTime)
{
previousMouseState = currentMouseState;
currentMouseState = Mouse.GetState();
``````
``````        angleX -= (currentMouseState.Position.X - previousMouseState.Position.X) * (float)gameTime.ElapsedGameTime.TotalSeconds;
angleY -= (currentMouseState.Position.Y - previousMouseState.Position.Y) * (float)gameTime.ElapsedGameTime.TotalSeconds;
}
}
``````

}

I don’t have all the time right now but here is some of my code. Not perfect, but works.

You have to have a Camera.Forward and Camera.Up vector.

In my case I save them all in a class called “camera” along with the position.

Then when I move the mouse

float mouseAmount = 0.01f;`

``````    Vector3 direction = camera.Forward;
direction.Normalize();

Vector3 normal = Vector3.Cross(direction, camera.Up);

`   //You don't have to have the button pressed for an FPS obviously)`
if (mouseState.RightButton == ButtonState.Pressed)
{
float y = mouseState.Y - mouseLastState.Y;
float x = mouseState.X - mouseLastState.X;

y *= GameSettings.g_ScreenHeight/800.0f;
x *= GameSettings.g_ScreenWidth/1280.0f;

camera.Forward += x * mouseAmount * normal;

camera.Forward -= y * mouseAmount * camera.Up;
camera.Forward.Normalize();
}
``````

Then later

camera.Lookat is Position + Forward;

``````_view = Matrix.CreateLookAt(camera.Position, camera.Lookat, camera.Up);
_projection = Matrix.CreatePerspectiveFieldOfView(camera.FieldOfView,
GameSettings.g_ScreenWidth / (float)GameSettings.g_ScreenHeight, 1, GameSettings.g_FarPlane);``````

Thank you! Your method is way easier, and it works a lot better than “CreateFromAxisAngle” shenanigans. It’s working now!