DirectX Camera Jitter

Started by
6 comments, last by Dakattack64 8 years, 8 months ago
I'm making a small DirectX Demo Scene but my camera seems to "snap" to odd positions when I attempt to rotate it. It only happens when rotating and I can't seem to find out what is causing it.

// Get the cursor pos and calculate change in movement
POINT cursorPos;
GetCursorPos(&cursorPos);
LONG deltaX = oldCursorPos.x - cursorPos.x;
LONG deltaY = oldCursorPos.y - cursorPos.y;
 
// Hold right click to rotate
if (GetAsyncKeyState(VK_RBUTTON))
{
XMMATRIX xRotation = XMMatrixRotationY(((float)-deltaX  * (float)timer.Delta()));
XMMATRIX yRotation = XMMatrixRotationX(((float)-deltaY * (float)timer.Delta()));
 
XMMATRIX view = XMLoadFloat4x4(&cameraMatrix);
 
XMFLOAT4 viewVector = XMFLOAT4(cameraMatrix.m[3][0], cameraMatrix.m[3][1], cameraMatrix.m[3][2], 1.0f);
for (size_t i = 0; i < 3; i++) { cameraMatrix.m[3][i] = 0.0f; }
 
view = view * xRotation;
view = yRotation * view;
 
XMStoreFloat4x4(&cameraMatrix, view);
 
cameraMatrix.m[3][0] = viewVector.x;
cameraMatrix.m[3][1] = viewVector.y;
cameraMatrix.m[3][2] = viewVector.z;
}
 
oldCursorPos = cursorPos;
Above is the code that performs the rotations to the camera matrix, below is the code I use to set the view matrix equal to the inverse of the camera matrix. Both of these operations are done every frame.

XMMATRIX camera = XMLoadFloat4x4(&cameraMatrix);
XMMATRIX view = XMMatrixInverse(NULL, camera);
XMStoreFloat4x4(&sceneMatrix.viewMatrix, view);
Both of these snippets don't seem to be the problem though, as I have triple checked my notes and this is exactly how my instructor expects it to be done. This bug happens in debug and release mode.
I put the source code in the link above if an attractive person such as yourself dare look at the rest of the code. Beware: It is a small demo application so try not to cringe at the hard-coded objects and such.
Posted this on stackoverflow as well if you feel like getting some +rep over there. Thanks all!
Advertisement

You shouldn't be scaling mouse movement by the time delta. Mouse movement should have a direct mapping to rotation. These lines:

XMMATRIX xRotation = XMMatrixRotationY(((float)-deltaX * (float)timer.Delta()));
XMMATRIX yRotation = XMMatrixRotationX(((float)-deltaY * (float)timer.Delta()));

The input for XMMatrixRotationX/Y() is in radians, 0<=2xPI - I think your mouse input creates huge angle changes by only small movements... Try scaling them down with a float (you could use it for mouse sensitivity setting)!

Also just noticed that you use the delta input for angles - you should have global MouseAngleX/Ys and add the deltas to those, and use those for input to the XMMatrixRotationX/Y() :)

.:vinterberg:.

Thanks guys! I removed time.Delta() and replaced it with a simple modifiable float value for rotationSpeed. Everything is working now :)

You shouldn't be scaling mouse movement by the time delta. Mouse movement should have a direct mapping to rotation. These lines:

XMMATRIX xRotation = XMMatrixRotationY(((float)-deltaX * (float)timer.Delta()));
XMMATRIX yRotation = XMMatrixRotationX(((float)-deltaY * (float)timer.Delta()));

This is wrong. You're camera movement should be tied to the frame-time just like all movement. Otherwize, a 30 fps game would result in a more sluggish camera rotation compared to when it was running at 60 fps.

In any case, it doesn't explain the issue.

Edit : Unless of course, you're not taking input snapshots per frame, but rather updating input at a frame-independent rate, such as by directly pushing windows msgs into your engine.

You shouldn't be scaling mouse movement by the time delta. Mouse movement should have a direct mapping to rotation. These lines:

XMMATRIX xRotation = XMMatrixRotationY(((float)-deltaX * (float)timer.Delta()));
XMMATRIX yRotation = XMMatrixRotationX(((float)-deltaY * (float)timer.Delta()));

This is wrong. You're camera movement should be tied to the frame-time just like all movement. Otherwize, a 30 fps game would result in a more sluggish camera rotation compared to when it was running at 60 fps.

In any case, it doesn't explain the issue.

Edit : Unless of course, you're not taking input snapshots per frame, but rather updating input at a frame-independent rate, such as by directly pushing windows msgs into your engine.

We're talking about mouse cursor movement.

If we were talking about control pad analog sticks rotating the camera, then there should be a time delta applied, but we're talking about mouse movement, which should definitely not have a time delta applied (as proved by the fact that it fixed the bug!)

I'm talking about mouse movement as well. I never mentioned a gamepad. And I use time-scaled mouse movement, and I don't have the issue the OP is having.

And changing a line of code resulting in a fix is not actually a proof that the line contained the bug.

I'm talking about mouse movement as well. I never mentioned a gamepad. And I use time-scaled mouse movement, and I don't have the issue the OP is having.

And changing a line of code resulting in a fix is not actually a proof that the line contained the bug.

No, time shouldn't be involved because regardless of what frame you are on or how fast your FPS is, the change in mouse movement (deltaX/deltaY) remains constant.

Say I move my mouse 2 inches to the right at a constant speed; to make it simple lets say it takes us 1 second to do this.

At 30fps, each frame will calculate deltaX as 2/30 or 0.0667 inches.

At 60fps, each frame will calculate deltaX as 2/60 or 0.0333 inches.

Using 60fps we simply calculate distance at a faster rate than we do at 30fps, but that doesn't change the overall distance I moved or the time it took to get there.

If you imagine a line representing the distance my hand moved, and ticks on the line representing where the program calculated deltaX, the 60fps program will simply have more ticks and they will be spaced closer together. But the distance I traveled and the time it took to get there remain constant.

As a matter of fact I'm not even sure if this would be used in joystick movements either, as you would simply multiply a movement speed times the value of the X axis of the stick ranging from -1.0f to 1.0f. Unless I'm misunderstanding how the hardware is used.

This topic is closed to new replies.

Advertisement