Arcball/Orbit camera rotation problem

Hi guys,

I’m trying to incorporate and an arcball/orbit camera that will rotate around a center point.

This is the effect I want:

My initial view is set directly downwards, facing XY plane where I draw my sprites.

CameraPosition = new Vector3(0, 0, 5f);
CameraTarget = Vector3.Zero;
View = Matrix.CreateLookAt(CameraPosition, CameraTarget, Vector3.Up)

I’d like to rotate this plane around the CameraTarget and seems to me that something is not right with my rotation matrices angles.
This is the code I’m using:

private void OrbitCamera(float amountX, float amountY)
        {
            float x = MathHelper.ToRadians(amountX);
            float y = MathHelper.ToRadians(amountY);
            var desiredOrbitalDistance = Vector3.Distance(Vector3.Zero, CameraPosition);

            cameraDirection = Vector3.TransformNormal(cameraDirection, Matrix.CreateFromAxisAngle(Matrix.Identity.Up, x) * Matrix.CreateFromAxisAngle(View.Right, y));
            
            cameraDirection.Normalize();
            CameraPosition = cameraDirection * desiredOrbitalDistance;                
        }

And this is the result I’m getting:
https://s10.gifyu.com/images/ezgif-5-35b3c45395.gif

How can I achive the same rotation as in the example I’ve attached?
Any advice will be appreciated.

You are using View.Right here, but you want to use the camera’s right axis instead. As I told you in the other topic, the view matrix is the inverse of the camera matrix.

Sorry if I ask silly questions, this is a still very fresh topic to me. So I understand that in order to get the camera side axis I do something like this?

cameraSidewaysVector = Vector3.Cross(Vector3.Up, cameraDirection);

and than use that instead of the View.Right

However the thing is I want my camera to behave differently. I want it to rotate 360 degrees around a Vector always facing up and located in the center. Something like this:

and also have the possibility to rotate 360 degrees using the y mouse movement and move the camera ‘below’ the grid. Hopefully my explanation is clear. How can I achieve that?

Hmm, seems to me that the camera works fine… I just had to apply Matrix.CreateRotationX(MathHelper.PiOver2) to the World Matrix. I don’t know if that’s the optimal solution however, and it breaks my unproject function for getting the mouse world coordinates.

Involving some world matrix doesn’t sound like the right solution here. What world matrix? Those are usually used to place objects in the world. The camera should only be defined by a view and projection matrix.

1 Like

This, it’s incredible how many people get this wrong and apparently for “good measure” they at least introduce “identity world matrix” for camera… or how many people scale their view matrix while they want to change their projection or the fact how few people realizes that matrices are named according to space they transform to.

Ok, maybe I should have been more clear. Of course I didn’t mean World matrix for the camera. The camera is only defined by view and projection. I’m using SpriteBatch to draw the sprites. As I finally realized that the camera is fine, In order to have the sprites drawn the way I want I’ve set my basicEffect parameter properties to this:

basicEffect.World = Matrix.CreateScale(1, -1, 1) * Matrix.CreateRotationX(MathHelper.PiOver2);
basicEffect.View = camera.View;
basicEffect.Projection = camera.Projection;

Still, I don’t know how to fix my unproject function.

Your unproject/object picking doesn’t work anymore because it assumes objects to be in the XY-plane. You just introduced a 90 degree rotation around X, which puts everything in the XZ-plane.

If you have to rotate the world so things show up where you want them, your camera is not exactly fine. You should fix the camera instead and leave your sprites in XY, otherwise you have to rotate everything you’ll ever draw from now on.

Alright, I’ve changed the cameraUpVector to Vector3.Forward and all is good now… Thanks for all the useful info.