#### Archived

This topic is now archived and is closed to further replies.

# Need Some Freelook Help w/ Quaternions Plz Help

This topic is 5521 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I have some questions on quaternions and gluLookAt(): If I have a rotation matrix, I change it to a quaternion, and then change it back, is this doing anything to prevent gimbal''s lock? When I have two rotation matrices, one for rotating around the y axis and one for rotating around the x axis (yaw and pitch, no roll), I convert them both to quaternions. But then how do I combine them so to speak? I tried using the approach on NeHe''s game tutorial #7, however all I got was a bunch of sparatic and uncontrollable (and completely locked on one axis, free on the other), rotation. Is the unit vector that gluLookAt() takes for the "up" vector just supposed to be perpendicular to the line created between the viewing and the position? My computer graphics teacher told me that no, its just supposed to be 0, 1, 0 for 99% of all cases. I tried to explain that if you want the camera to rotate then you rotate the up vector, but he has a degree from MIT so I think he knows what he''s talking about. Once I have my unit vectors telling my camera which way its x axis, z axis, and y axis are, I have a relatively simple method for moving. If they move forward, I just add the z axis vector to the position. If they move backwards, I just subtract the z axis vector (my camera is looking down the z axis). If they strafe, I add the x axis and so on. The problem with this is that eventually my coordinates get very manipulated and twisted. It gets to the point where when I press left, I start going up! What''s the deal with this? Perhaps if I post my code it can become more clear, but any help I can get would be, well, very helpful.

Nobody knows?

##### Share on other sites
quote:
If I have a rotation matrix, I change it to a quaternion, and then change it back, is this doing anything to prevent gimbal's lock?

No. If you want the benefits of quaternions, you have to work in quaternions. If you want to avoid gimbal lock, you can store a rotation matrix, instead of the euler angles you originally used to create it.

quote:
Is the unit vector that gluLookAt() takes for the "up" vector just supposed to be perpendicular to the line created between the viewing and the position?

It's supposed to be straight up, but it doesn't much matter. Internally, it performs a Gramm-Schmidt orthonormalization of the upvector, resulting in the second type you mentioned. Since it'll go ahead and compute that for you, there's no real need for you to.

How appropriate. You fight like a cow.

[edited by - sneftel on May 3, 2003 11:09:41 PM]

##### Share on other sites
The way to avoid gimble lock is to store your rotations as a matrix (not create a new matrix each frame). Alternatively, you can store it as a quaternion, which has the same effect. The only way it doesn''t work is if you store it as 3 angles.

As far as gluLookAt goes, if you always use the up vector (0,1,0) as up, you will have problems if you try to look at something that is, well, straight up. In that special case, your up vector will be the same as your center vector, and glulookat will not be happy. You can get around this by either keeping track of what the up vector should really be ((right vector) cross (forward vector)), or just not letting the camera rotate all the way up. Or, don''t use glulookat. See, if you are already storing your rotations as a matrix, you can just call glLoadMatrix() to set the orientation, you will have no need to call gluLookAt.

Its confusing but hang in there! Check out the openGL camera code at www.flipcode.com/cotd, for an example of a camera that uses matrices to store position and orientation.

##### Share on other sites
Ok so if I have two quarternions, one storing my yaw rotation and one storing my pitch rotation, how do I combine them into one more final rotation? I''m still very confused about the up vector, I think I will just try to make it so they can''t look all the way up.

##### Share on other sites
thats the funny thing with quaternions: if you want to combine the two rotation represented by the two, you can just multiply them, like you would with a matrix. the method of multiplying is differnet ofcource, but you can look that up in the tutorials section.

##### Share on other sites
Where can I find the "method" of multiplying them? I used the one NeHe has and it worked somewhat but on one axis the vector wouldn''t keep its position.

##### Share on other sites
here is a method that multiplies quaternion:

    void MultiplyQuat(Quaternion * ptrQuat1, Quaternion * ptrQuat2, Quaternion * ptrResult){	ptrResult->x = (ptrQuat1->w * ptrQuat2->x) + (ptrQuat1->x * ptrQuat2->w) + (ptrQuat1->y * ptrQuat2->z) - (ptrQuat1->z * ptrQuat2->y);	ptrResult->y = (ptrQuat1->w * ptrQuat2->y) + (ptrQuat1->y * ptrQuat2->w) + (ptrQuat1->z * ptrQuat2->x) - (ptrQuat1->x * ptrQuat2->z);	ptrResult->z = (ptrQuat1->w * ptrQuat2->z) + (ptrQuat1->z * ptrQuat2->w) + (ptrQuat1->x * ptrQuat2->y) - (ptrQuat1->y * ptrQuat2->x);	ptrResult->w = (ptrQuat1->w * ptrQuat2->w) - (ptrQuat1->x * ptrQuat2->x) - (ptrQuat1->y * ptrQuat2->y) - (ptrQuat1->z * ptrQuat2->z);}

it assumes a structure like so:

        typedef struct{	float x, y, z, w;} Quaternion;

i hate to state the obvious, but your quaternions need to have been created properly for you to see the desired result after multiplying them. in other words, if u still have a problem after implementing the code above (or equivalent code), the problem is probably in how u are creating them.

[edited by - jorgander on May 5, 2003 11:30:08 AM]

##### Share on other sites
I remember trying to implement them but I ran into a problem. My pitch rotations of the view vector would work, but every frame my yaw rotations would reset. Does anybody know why this is happening? Thanks

##### Share on other sites
CHA CHING! THANK YOU SO MUCH, that quaternion multiplication code made it work for me. I cannot thank you enough. I''ve been stressing over this forever. It turns out the function I used is some wierd crap. It looks like this:

pQuatResult->x = pQuat2->x*pQuat1->x
-pQuat2->y*pQuat1->y
-pQuat2->z*pQuat1->z
-pQuat2->w*pQuat1->w;

pQuatResult->y = pQuat2->x*pQuat1->y
+pQuat2->y*pQuat1->x
+pQuat2->z*pQuat1->w
-pQuat2->w*pQuat1->z;

pQuatResult->z = pQuat2->x*pQuat1->z
-pQuat2->y*pQuat1->w
+pQuat2->z*pQuat1->x
+pQuat2->w*pQuat1->y;

pQuatResult->w = pQuat2->x*pQuat1->w
+pQuat2->y*pQuat1->z
-pQuat2->z*pQuat1->y
+pQuat2->w*pQuat1->x;

I dont know what that is for but it sure doesn''t work for what I''m doing. Thanks again man.

• 10
• 9
• 48
• 12
• 10
• ### Forum Statistics

• Total Topics
631385
• Total Posts
2999705
×