1
\$\begingroup\$

Whenever I change the orientation of the camera, yaw and roll become inverted (or correct); the strafing, movement and pitch do remain correct however.

Can you tell what is causing this and how to fix it ?

private Vector3 _cameraOrientation;
private Vector3 _cameraPosition;
private Matrix _matrixProjection;
private Matrix _matrixView;

protected override void Update(GameTime gameTime)
{
    var state = GamePad.GetState(PlayerIndex.One);
    if (state.Buttons.Back == ButtonState.Pressed ||
        Keyboard.GetState().IsKeyDown(Keys.Escape))
        Exit();
    if (state.Buttons.Start == ButtonState.Pressed) _cameraPosition = _cameraOrientation = Vector3.Zero;

    var right = state.ThumbSticks.Right;
    var left = state.ThumbSticks.Left;

    // get position/orientation deltas from gamepad
    var position = new Vector3
    {
        X = left.X,
        Y = state.Buttons.A == ButtonState.Pressed ? -1 : state.Buttons.Y == ButtonState.Pressed ? 1 : 0,
        Z = -left.Y,
    };
    var orientation = new Vector3
    {
        X = -right.Y,
        Y = -right.X,
        Z = state.Buttons.X == ButtonState.Pressed ? -1 : state.Buttons.B == ButtonState.Pressed ? 1 : 0
    };

    // update position according orientation
    _cameraOrientation += orientation;
    var cameraReference = Vector3.Forward;
    var cameraRotation =
        Matrix.CreateRotationX(MathHelper.WrapAngle(MathHelper.ToRadians(_cameraOrientation.X))) *
        Matrix.CreateRotationY(MathHelper.WrapAngle(MathHelper.ToRadians(_cameraOrientation.Y))) *
        Matrix.CreateRotationZ(MathHelper.WrapAngle(MathHelper.ToRadians(_cameraOrientation.Z)));
    _cameraPosition += Vector3.Transform(position, cameraRotation);

    // update matrices
    var cameraPosition = _cameraPosition;
    var cameraTransformedReference = Vector3.Transform(cameraReference, cameraRotation);
    var cameraTarget = cameraPosition + cameraTransformedReference;
    var cameraUpVector = Vector3.Transform(Vector3.Up, cameraRotation); // Vector3.Up;
    _matrixView = Matrix.CreateLookAt(cameraPosition, cameraTarget, cameraUpVector);
    _matrixProjection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45),
        _graphics.GraphicsDevice.Viewport.AspectRatio, 0.01f, 100000f);

    base.Update(gameTime);
}
\$\endgroup\$
4
  • \$\begingroup\$ I've just started going through the code. If you keep this algorithm, I'd recommend that you rename variables like position to velocity, positionDelta, or anything else that is more indicative of their purposes. \$\endgroup\$ – Jon May 4 '15 at 0:04
  • \$\begingroup\$ Also, you can accumulate just the rotation, first, and then determine the correct movement direction from cameraRotation; i.e. cameraRotation.Forward, cameraRotation.Left. Both of the directions returned are relative to the stored rotation, not "the world". So, If (left.X != 0) _cameraPosition += cameraRotation.Right * left.X; \$\endgroup\$ – Jon May 4 '15 at 0:05
  • \$\begingroup\$ Unconfirmed, but I think your problem may be order-of-operations; i.e. Matrix.CreateRotationX creates "pitch". You are applying X, then Y, then Z which is Pitch, then Yaw, then Roll. Each of the matrices you are creating is relative to world-space ("Up" is +Y). When you pitch the camera past 90 degrees (first), camera-space "Up" becomes world-space "Down". \$\endgroup\$ – Jon May 4 '15 at 0:11
  • \$\begingroup\$ (Sorry Mods; I'll compile all of my comments into an answer after a little feedback from the OP) -- You are also starting your camera at Vector3.Forward, looking toward (0,0); that means that, initially, Camera.Forward is Vector3.Backward. Positive rotations are clock-wise, relative to the axis being twisted which is why starting at Vector3.Forward is an intuitive solution. The other and, more common, intuitive solution is starting at Vector3.Backward, looking toward (0,0), and inverting your sticks' pitch values. \$\endgroup\$ – Jon May 4 '15 at 0:23
1
\$\begingroup\$

This answer works properly : beginner: camera quaternion rotation (space sim)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.