Setting cursor to center for mouse->camera movement issues

I’ve looked up solutions on here for this issue, but they seem to only be bandaids rather than fixes. I control the camera with the mouse by centering the mouse position (viewport.width / 2, viewport.height / 2) and recording the change between frames and multiplying by the delta (elapsedgametime.totalseconds). This can work wonders but when I change between framerates (targetelapsedtime) the camera speeds up when the fps decreases and slows down when fps increases.

To isolate the problem I tested the change between frames with a constant value, and flipped between target framerates and it works perfectly. So centering the mouse position and recording the change between frames seems to be the issue but is there a good solution for this?

// Cache mouse location
                //float deltaX = ScreenManager.Instance.Input.MousePosition.X - (Graphics.GraphicsDevice.Viewport.Width / 2);
                //float deltaY = ScreenManager.Instance.Input.MousePosition.Y - (Graphics.GraphicsDevice.Viewport.Height / 2);
                float deltaX = 4.0f;
                float deltaY = 0.0f;

                mouseRotationBuffer.X -= RotateSpeed.X * deltaX * dt;
                mouseRotationBuffer.Y -= RotateSpeed.Y * deltaY * dt;

                if (mouseRotationBuffer.Y < MathHelper.ToRadians(-verticalMaxes))
                    mouseRotationBuffer.Y = mouseRotationBuffer.Y -
                        (mouseRotationBuffer.Y - MathHelper.ToRadians(-verticalMaxes));
                if (mouseRotationBuffer.Y > MathHelper.ToRadians(verticalMaxes))
                    mouseRotationBuffer.Y = mouseRotationBuffer.Y -
                        (mouseRotationBuffer.Y - MathHelper.ToRadians(verticalMaxes));

                // Make -Mathhelper.Clamp to invert the Pitch rotation
                Rotation = new Vector3(-MathHelper.Clamp(mouseRotationBuffer.Y, MathHelper.ToRadians(-verticalMaxes),
                    MathHelper.ToRadians(verticalMaxes)), MathHelper.WrapAngle(mouseRotationBuffer.X), 0);

            Mouse.SetPosition(Graphics.GraphicsDevice.Viewport.Width / 2, Graphics.GraphicsDevice.Viewport.Height / 2);

Notice the deltaX and deltaY: the constant rate of 4.0f each frame works perfectly when I switch between target framerate, but using the center mouse code is not a consistent speed. Btw dt is my delta time.

this.TargetElapsedTime = TimeSpan.FromSeconds(1d / 250d);

The camera moves slowly with a target fps of 250, but moves very fast with 30fps, for example.

Umm… so removing the delta time seems to fix the problem. Is this an anomaly that will surely creep on me later or perhaps I’ve overlooked something like: maybe mouse movement being using for the camera is somehow exempt from this but I do not know. Any thoughts?

Also I further tested it by toggling off and on target fps, fixedtimestep and vsync and all is still fine.

That’s fine. You don’t need to multiply by dt as the value you got from mouse is already the mouse distance (pixels) since last frame.

You only need to multiply by dt for animations that are defined as velocities (pixels/seconds or rotations/seconds). By multiplying by dt (seconds) you cancel out the time and get distances out of velocities ( (pixels/seconds)*seconds = pixels).
To put this into some perspective, the mouse velocity is mouseSpeed = mouseDelta/dt.

Additionally a nice thing you can do is to normalize the mouse input by dividing it by Window.ClientBounds. This will give users a similar feel across different devices and window sizes.

1 Like

That makes sense, and I suppose normalizing the mouse input is my next bullet point. Thanks for the response :smiley: