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
    Commented May 4, 2015 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
    Commented May 4, 2015 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
    Commented May 4, 2015 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
    Commented May 4, 2015 at 0:23

1 Answer 1

1
\$\begingroup\$

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

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .