Camera roll has no effect - Game Development Stack Exchange most recent 30 from gamedev.stackexchange.com 2019-10-18T11:45:09Z https://gamedev.stackexchange.com/feeds/question/73683 https://creativecommons.org/licenses/by-sa/4.0/rdf https://gamedev.stackexchange.com/q/73683 3 Camera roll has no effect Ray https://gamedev.stackexchange.com/users/39660 2014-04-20T09:58:59Z 2014-04-21T11:42:26Z <p>Consider my following (abstracted) C# w/ SharpDX code:</p> <pre><code>class Game { Camera _camera = new Camera(); private void Window_KeyDown(object sender, KeyEventArgs e) { // Roll if (e.KeyCode == Keys.Home) { _camera.TurnRoll(-0.05f); } else if (e.KeyCode == Keys.End) { _camera.TurnRoll(0.05f); } // Other rotation / movement works... } } class Camera { private Vector3 _position; private Vector3 _rotation; private Vector3 _right; private Vector3 _up; private Vector3 _forward; private Matrix _view; public Camera() { _right = Vector3.Right; _up = Vector3.Up; _forward = Vector3.ForwardLH; UpdateViewMatrix(); } public void TurnRoll(float roll) { // Relative rotation _rotation.Z += roll; UpdateViewMatrix(); } private void UpdateViewMatrix() { Matrix cameraRotationMatrix = Matrix.RotationYawPitchRoll(_rotation.Y, _rotation.X, _rotation.Z); Vector3 cameraTarget = Vector3.TransformCoordinate(Vector3.ForwardLH, cameraRotationMatrix); cameraTarget = cameraTarget.Normalize(); cameraTarget += _position; // I bet the problem lies in and/or after this line Matrix rotateYTempMatrix = Matrix.RotationY(_rotation.Y); _right = Vector3.TransformCoordinate(Vector3.Right, rotateYTempMatrix); _up = Vector3.TransformCoordinate(Vector3.Up, rotateYTempMatrix); _forward = Vector3.TransformCoordinate(Vector3.ForwardLH, rotateYTempMatrix); _view = Matrix.LookAtLH(_position, cameraTarget, _up); } } </code></pre> <p>My problem: Even when pressing the Home and End keys, the camera roll visibly stays untouched. I have trouble correcting my UpdateViewMatrix function, and I bet that the error is in there. I'm a bit lost with the maths here and my tries to use another rotation matrix to update the _up vector all failed or created other problems.</p> <p>Can anybody clear my math mind up and help me correct this method?</p> <p><strong>EDIT:</strong> Solved with the help of winged's answer below. I edited the code to be</p> <pre><code>private void UpdateViewMatrix() { Matrix rotation = Matrix.RotationYawPitchRoll(_rotation.Y, _rotation.X, _rotation.Z); _forward = Vector3.TransformCoordinate(Vector3.ForwardLH, rotation); _forward += _position; _up = Vector3.TransformCoordinate(Vector3.Up, rotation); _view = Matrix.LookAtLH(_position, _forward, _up); } </code></pre> <p>However, this is still not completely correct. The camera rolls now, which solves this question. But if it is rolled and I try to yaw it, the yaw happens like as if the camera is non-rolled and moves along the default Y-axis :/. Especially when looking downwards 90 degrees this causes something like gimble-lock to happen (or IS it gimble lock?) because rolling and yawing the camera has the same effect then.</p> <p><strong>EDIT2:</strong> I completely replaced my rotation with quaternions. I don't know why people think these are "harder" or at least "different" to understand. This solution works perfectly.</p> <pre><code>public void Turn(Vector3 turning) { // Relative rotation Quaternion delta = Quaternion.RotationYawPitchRoll(-turning.Y, -turning.X, -turning.Z); _rotation = delta * _rotation; _rotation.Normalize(); UpdateViewMatrix(); } public void TurnRoll(float roll) { Turn(new Vector3(0, 0, roll)); } private void UpdateViewMatrix() { Matrix view = Matrix.RotationQuaternion(_rotation); Matrix translation = Matrix.Translation(-_position.X, -_position.Y, -_position.Z); _view = translation * view; } </code></pre> https://gamedev.stackexchange.com/questions/73683/-/73687#73687 2 Answer by Winged for Camera roll has no effect Winged https://gamedev.stackexchange.com/users/44157 2014-04-20T11:49:50Z 2014-04-20T11:49:50Z <p>I guess that the problem lies in here:</p> <p><code>_up = Vector3.TransformCoordinate(Vector3.Up, rotateYTempMatrix);</code></p> <p>You're calculating the up vector (and also the rest of them) from a matrix unrelated to the <code>cameraRotationMatrix</code> matrix, in which you have stored the new rotation. Usually, what I do is multiply an old rotation matrix by the new rotation matrix, and then calculate the up vector from the outcome matrix.</p> <p>Hope this helps.</p>