[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!