Sign in to follow this  
iradel

quaternion camera rotation question

Recommended Posts

iradel    122
When my program first starts and the camera is pointing straight ahead, moving the mouse up and down produces the expected movement (rotation around global X-axis). When I turn left or right 90 degrees, moving the mouse up or down results in a pure rotation (around the global X-axis). Does someone understand what I'm talking about, and what can I do to fix it? I thought quaternions always rotated around their local axes, and not the global axes. Pseudocode:

Quaternion rotate_this_frame;
rotate_this_frame.MakeFromEuler(pitch, yaw, roll);

camera_quaternion *= rotate_this_frame;

camera_quaternion.GetMatrix(&m_oViewMatrix);

glLoadMatrixf(m_oViewMatrix);


Thank you.

Share this post


Link to post
Share on other sites
jyk    2094
Quaternions rotate about whatever axis you tell them to; it could be a local axis, or it could be a global axis. It looks to me like you're updating your quaternion incrementally rather than constructing it from scratch each frame. Is that correct? If so, you may want to normalize it occasionally (you may be doing that elsewhere in the code).

As for the problem you mentioned, the answer may depend on the type of quaternion multiplication you're using. Are you using the standard form (mirrors OpenGL/column vectors) or the reversed form (mirrors D3D/row vectors)? (Even though this is the OpenGL forum, it seems possible that you could have ended up with quaternion code from a row-vector-friendly library.) If you're not sure which it is, perhaps you could post the quaternion multiplication function.

Share this post


Link to post
Share on other sites
iradel    122
Quote:
Original post by jyk
As for the problem you mentioned, the answer may depend on the type of quaternion multiplication you're using. Are you using the standard form (mirrors OpenGL/column vectors) or the reversed form (mirrors D3D/row vectors)? (Even though this is the OpenGL forum, it seems possible that you could have ended up with quaternion code from a row-vector-friendly library.) If you're not sure which it is, perhaps you could post the quaternion multiplication function.


You're absolutely right on both counts. First of all I wasn't normalizing the quaternion with my incremental multiplications. And secondly, I accidentally used multiplication code from a D3D book which used row vectors.

After fixing both of those issues, the rotations seem to work exactly as expected.

Thank you!

Share this post


Link to post
Share on other sites
iradel    122
When my camera is in some rotated orientation, how do I get the proper local forward, up, and right vecs? The following code screws up as soon as I leave the starting position. Thank you.


m_oCamQuat.GetMatrix(&m_oViewMatrix);
glLoadMatrixf(m_oViewMatrix);

m_oRight = m_oViewMatrix.GetColumn(0);
m_oUp = m_oViewMatrix.GetColumn(1);
m_oForward = m_oUp.CrossProduct(m_oRight);

glTranslatef(-m_oPosition.x, -m_oPosition.y, -m_oPosition.z);


Share this post


Link to post
Share on other sites
jyk    2094
Glad you solved your first set of problems. Sounds like you may have solved your second set as well. However, with these issues it can often be the case that 'two wrongs make a right', that is, an 'even number of mistakes' can cancel each other out and produce seemingly correct results! So I'd like to suggest a couple more things to look into:

1. Make sure your quat-to-matrix function is correct for OpenGL-style matrices (column vectors, column major). There are basically only two ways to do it, and they're transposes of each other. You can just look at matrix element 1 (1,0 with 0-based 2d indexing). It should be 2xy+2wz (or some variation thereof). If it's not, the code is probably the transpose of what it should be and should be adjusted accordingly.

2. Once you're sure that's right, the next thing to look at is where you set up the camera matrix. The only change to make is that after the line 'm_oCamQuat.GetMatrix(&m_oViewMatrix)', the matrix should be transposed before proceeding. (This is because you're setting up a view rather than object matrix.)

3. You're correct that the direction vectors are the columns of the matrix (assuming the quat-to-matrix code is correct). They should be extracted from the matrix as-is, not the transposed version that you use to set up the view matrix.

4. forward should probably be rightXup rather than upXright. However, it'd probably be easier to just get the forward vector from the 3rd column of the matrix.

'Hope some of that helps.

Share this post


Link to post
Share on other sites
iradel    122
I have fixed the quat-to-matrix code to use OpenGL style matrices. Thank you very much for that help!

I am having some trouble figuring out the proper rotation for the following: I am working on a little space-flight game, and I have a HUD where I have a sphere. And inside the sphere, I want a little ship to rotate as the actual camera rotates, to give the user a sense of which way the ship is pointed. Right now I have the following code:


// draw stuff that's oriented with the camera
...

// draw some temporary hud stuff
glPushMatrix();
glLoadIdentity();

glTranslatef(-2.1f, -1.45f, -5.0f); // lower-left-hand corner of screen

glMultMatrixf(goCamera.m_oViewMatrix);

glutWireCube(0.25f);

glPopMatrix();



The effect of this is that the cube does rotate inside the sphere as you move the mouse around and rotate your main view, but it rotates 'backwards' from the main rotation. So it's like the camera is rotating around the cube, but that looks backwards from the main rotation. What I want is for the cube to rotate right when I move the mouse right, rotate left when I move the mouse left, and so on. How do I get a 'reverse' rotation from a rotation matrix?

Thank you.

Share this post


Link to post
Share on other sites
jyk    2094
Quote:
How do I get a 'reverse' rotation from a rotation matrix?
In general, the 'reverse' rotation is the rotation represented by the transpose of the matrix. So to reverse the rotation, simply transpose the matrix. I'm not sure exactly why your code isn't working currently 'cause I'm not sure what 'm_oViewMatrix' is, that is, if it's the matrix that was extracted from the quaternion, or the transpose of the matrix that was extracted from the quaternion. If the former, it seems your code should work in its current form. If the latter, it makes sense that a transpose would be necessary.

Share this post


Link to post
Share on other sites
iradel    122
Quote:
Original post by jyk
In general, the 'reverse' rotation is the rotation represented by the transpose of the matrix. So to reverse the rotation, simply transpose the matrix. I'm not sure exactly why your code isn't working currently 'cause I'm not sure what 'm_oViewMatrix' is, that is, if it's the matrix that was extracted from the quaternion, or the transpose of the matrix that was extracted from the quaternion. If the former, it seems your code should work in its current form. If the latter, it makes sense that a transpose would be necessary.

'm_oViewMatrix' is the transpose of the matrix that was extracted from the quaternion. So I transposed it again and used glMultMatrixf to rotate my object by it. Basically I want my object in the 'hud' to be rotated the same way that the camera is pointed in the world, to give a sense of which way you're facing. But it doesn't rotate correctly for all orientations of the camera... sometimes it's rotating the right way, but you move/roll the mouse around and it'll start rotating the opposite way. Seems like it should be easier than this...

Share this post


Link to post
Share on other sites
jyk    2094
Quote:
'm_oViewMatrix' is the transpose of the matrix that was extracted from the quaternion. So I transposed it again and used glMultMatrixf to rotate my object by it.
It seems like that should do it. In any case, I'd think that if you tried both the original matrix and the transpose (and I take it you have), one of them would work. If neither gives the correct results, then I'm not sure what the problem is.

The only question I can think of is, are you sure that the cube isn't correctly reflecting the orientation of the ship? It seems like this could be somewhat confusing to determine visually.

Sorry I don't have a better answer :-|

Share this post


Link to post
Share on other sites
iradel    122
I think I see the problem, the hud model is rotating around it's own local axes...which only works when the global camera is very close to its default orientation. If you move the camera around, it messes up. Now to figure out a solution... :)

Share this post


Link to post
Share on other sites
iradel    122
Lets say I was doing a split-screen or a multiplayer game, something where there are 2 ships flying around in space. Ship 1 is looking at ship 2. Meanwhile, Ship 2 is moving his mouse around and rotating around in the world. I know what his camera quat/matrix is (from his point of view). Looking at him from ship 1, what rotation do I need to apply when drawing ship 2 so that he is oriented correctly from ship 1's perspective?

Share this post


Link to post
Share on other sites
jyk    2094
Quote:
Lets say I was doing a split-screen or a multiplayer game, something where there are 2 ships flying around in space. Ship 1 is looking at ship 2. Meanwhile, Ship 2 is moving his mouse around and rotating around in the world. I know what his camera quat/matrix is (from his point of view). Looking at him from ship 1, what rotation do I need to apply when drawing ship 2 so that he is oriented correctly from ship 1's perspective?
Well, I'm not sure if I follow, but here's a guess. If A is ship 1's rotation and B is ship 2's rotation, you want to find a rotation C that represents B in A's space. This should be:
Quaternion C = A.Conjugate()*B;
Anyway, you might try that and see if it gives you the results you're looking for.

Share this post


Link to post
Share on other sites
iradel    122
That works. Thank you very much! I wish I knew quaternion math better rather than fumbling my way through it. But this is the first time I'm having to deal with gimbal lock in a game/project.

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