Search code examples
c#3dcameradirect3dsharpdx

SharpDX Camera Rotation is weird


I know SharpDX is no longer maintained, but i already bought a book so i wanted to make use of it.

I want to make a game engine using SharpDX everything is working perfectly!

Except that one thing i tried to get working over 3 weeks.

There is a weird thing going on with the camera rotation.

Demonstration Video

why am i able to rotate the camera on the Z axis?

and how do i fix it?

Code:

            var Window = new System.Windows.Form();

            var viewMatrix = Matrix.LookAtRH(new Vector3(), cameraTarget, cameraUp);

            var lastX = 0;
            var lastY = 0;

            Window.MouseDown += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    lastX = e.X;
                    lastY = e.Y;
                }
            };

            Window.MouseMove += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    var yRotate = lastX - e.X;
                    var xRotate = lastY - e.Y;
                    lastY = e.Y;
                    lastX = e.X;

                    viewMatrix *= Matrix.RotationX(-xRotate * moveFactor);
                    viewMatrix *= Matrix.RotationY(-yRotate * moveFactor);

                    updateText();
                }
           };

Project: https://workupload.com/file/NANE9PbDJ24

Help would be greatly appreciated!


Solution

  • We don't update the view matrix like that for several reasons.

    1. Matrix are floating points, and errors accumulate
    2. With euler angles the order of rotation is important
    3. It's difficult to extract or check parameters like the rotation around an axis from the matrix

    You should keep a rotationX, and rotationY and recalculate your view matrix at each modification.
    Something like this:

    float rotationX = 0;
    float rotationY = 0;
    float dist = 1;
    
    Window.MouseMove += (s, e) = >
    {
        if (e.Button == MouseButtons.Left)
        {
            var yRotate = lastX - e.X;
            var xRotate = lastY - e.Y;
            rotationX += xRotate * moveFactor;
            rotationY += yRotate * moveFactor;
            lastY = e.Y;
            lastX = e.X;
    
            float h = cos(rotationX) * dist;
            Vector3 cameraTarget = Vector3(cos(rotationY) * h, sin(rotationX) * dist, sin(rotationY) * h);
    
            viewMatrix = Matrix.LookAtRH(new Vector3(), cameraTarget, cameraUp);
    
            updateText();
        }
    };
    

    edit: Added moveFactor