I know this is a very basic question, but I’ve been struggling for too long and right now I’m just try-and-error-ing. I would be really thankful for an explanation what is going on.
So, what I’m trying to do is implement a simple 3D camera. I managed to get the movement right, but I really struggle with the rotation. Imagine the camera is looking at (0, 0, 0). I want my camera to orbit the point around the Y-Axis (“left and right”) as well as around the axis pointing left from the camera (“Up and down”).
Now, I’ve managed to do just that. The Camera rotates as I want, but only if I disable the other rotation. Also, when I do the vertical rotation before the horizontal rotation, the camera only rotates horizontally. When I do the horizontal rotation before the vertical rotation, the rotation becomes really messy.
I know that matrix multiplication is not commutative, so I’m assuming this is where the error comes from. But I don’t exactly understand what the problem is, since it doesn’t work properly no matter the order.
This is what I do in my camera class:
Up is a property that stores the cameras Up direction, which is initially (-1, 1, 0).Normalized();
Position is initialized to (1000, 1000, 0)
Target is (0, 0, 0)
Left is the normalized cross of Up x (Target - Position)
At the end of the camera update code, I calculate a new ViewMatrix using
Matrix.CreateLookAt(Position, Target, Up);
var deltaX = Mouse.GetState().X - 100; //Get mouse movement since last frame with right mouse button pressed var deltaY = Mouse.GetState().Y - 100; deltaX = -deltaX; // invert for right feeling var direction = Position - Target; //Vector pointing from target to position //Vertical rotation: var rotLeft = Matrix.CreateFromAxisAngle(Left, deltaY * rotationSpeed); Position = Vector3.Transform(direction, rotLeft) + Target; Up = Vector3.Transform(Up, rotLeft); //Horizontal rotation: var rotY = Matrix.CreateRotationY(deltaX * rotationSpeed); Position = Vector3.Transform(direction, rotY) + Target; Up = Vector3.Transform(Up, rotY); Mouse.SetPosition(100, 100);