Sign in to follow this  

Pitch/Yaw problem with my camera

Recommended Posts

NumberXaero    2624
Im trying to add some quick utility functions for pitching and yawing a camera. Ive been going bananas trying to fix this odd side effect. The camera stores a normalized direction, up and right vector. For pitch, I created a quaternion from the right vector and the angle amount I wanted to rotate, rotated the dir vector then recomputed the up vector from the original right vector and the new direction. Worked fine. Same for yaw, created the rotation quaternion from the up vector this time and the angle, rotated the camera direction, then recreated the new right from the old up and new direction. When I went to test them (pitch/yaw) using up down arrows to pitch, worked fine, dir changed, up changed, right stayed same. Test the yaw function with left and right arrows, worked fine, direction changed, right changed, up stayed the same. Through all this the box I was looking at did not roll at all. The edges of the box stayed parallel with the the window edges when yawing or pitching. I then noticed that when using the mouse (or the keys in the same fashion) if you attempt to look around in a circular motion (think drawing a circle with your mouse on the screen) the box Im looking at starts to roll left or right (depending if you drawing the circle CW or CCW), yet I havent created the roll function yet, and the quaterion math only changes two vecs at a time (creates rotated version of dir, and uses old version of one vector to recreate perpendicular to the two). I also tried matrices to rotate the dir in the same way, by creating a rotation matrix from an axis/angle, same effect. Ive attempted renormalizing everything even when Im sure they are normalized. Ive also used the rotation quaternion/matrix to rotate the second vector instead of creating it with the crossproduct, nothing. My brother actually found the same effect in Lightwave 8 when using the camera rotation mode, if you draw the an imaginary circle with the mouse it starts to roll! Any ideas as to why it would be doing this? If it should be doing this (for whatever reason, which I would like to know) how do you stop it, the camera is a free look camera.

Share this post

Link to post
Share on other sites
jyk    2094
If I understand you correctly, you are applying rotations incrementally about your camera's local axes. Even if no roll is applied, this can result in perceived roll relative to a plane. Visualize the following. From identity, pitch down 90 degrees. Now yaw 90 degrees. Finally, pitch back up 90 degrees. If all rotations take place about the camera's local axes, you will now find yourself rolled 90 degrees from your initial orientation, even though no roll was applied.

What you have going there (and will complete if you add roll) is what many people struggle to get working, that is, 6dof camera movement such as you might find in a 3d space shooter.

It sounds though like you want FPS-style movement, like the 'spectator' cam in Quake. Here, yaw always occurs about the world up axis, and pitch about the local side axis.

This is fairly simple to do, and can be done with Euler angles and matrices, or more simply with polar coordinates. For a camera of this sort, quaternions are not necessary.

Share this post

Link to post
Share on other sites
ajas95    767
Your problem is an important one, so you really need to grok this. It goes way beyond cameras.

The problem, as Jyk pointed out, is that you want to apply yaw around the world y-axis, while pitching around your local x-axis (assuming x = side, y = up, and z = in). In general, if you have an orientation defined by Q, and you want to apply a rotation R, if you do:

Q = Q * R

it treats R as a rotation around Q's local axes. But if you do:

Q = R * Q

it treats R as a rotation around the world's axes (or whatever space Q is relative to).

To convince yourself of this, think about the gun barrel of a turret on a tank. It's defined directly ahead of the turret, say at (0, 0, -10). But relative to the tank, you'd have to apply the turret's transformation relative to the tank:

Barrel (in tank space) = Turret * (0, 0, -10)

but to get the position of the gun barrel in world-space, you then have to then apply the transformation of the tank relative to the world origin:

Barrel (in world-space) = Tank * Turret * (0, 0, -10)

So as you go to the left (pre-multiply), you're going up the chain to world space. And as you go right, you're changing those child orientations based on your own axes.

Getting back to the camera then, since yaw is the world y-axis and pitch is local x-axis, you'd need to pre- or post-multiply accordingly.

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this