PDA

View Full Version : quaternion algorithm question

Junkstyle
07-15-2002, 11:39 AM
I don't know how many quaternion equations/algorithms I coded up before I got one that worked for me, but I finally coded one that works. It is listed below. But I would like to do a slightly different version with a new step 3. The new step 3 doesn't work and I'm not sure if something is fundamentally wrong with this approach so I thought I'd ask.

// Given:
// 1) user input xRot, yRot, zRot
// 2) current quaternion of 3d object
//
// Problem:
// 1) rotate object to new orientation
//

// step 1:
EulerToQuatenion(xRot, yRot, zRot, quaternionInput);

// step 2:
vector4 result;
QuaternionMultiply(quaternion, quaternionInput, result);
Vector4Copy(result, quaternion);

// step 3:
GetAxisAngleRotationFromQuaternion(quaternion, axis, angle);

glTranslatef(loc.x, loc.y, loc.z);
glRotatef(angle, axis.x, axis.y, axis.z);

The above code works just great. Now if I changed step 3 to be:

// new step 3:
matrix4 modelview;
CreateModelViewMatrixFromQuaternion(quaternion, modelView);

glTranslatef(loc.x, loc.y, loc.z);
glMultMatrixf(modelView);

This doesn't work for some reason.
Any suggestions?

[This message has been edited by Junkstyle (edited 07-15-2002).]

Junkstyle
07-15-2002, 06:12 PM
Okay what I've noticed using the new Step 3 part was the rotation from the matrix gives me rotation around the major axis X, Y, Z. Where the original Step 3 gives rotation around the models current forward, up, right axis (what I want).

ioquan
07-15-2002, 07:19 PM
JunkStyle, take a look at my engine at http://home.earthlink.net/~ioquan/x3d.htm. (http://home.earthlink.net/~ioquan/x3d.htm)

I think it will be helpful, since I believe you are basing your algorithm on my method.

The relevant sections are Entity3D::Update(), Entity3D::MakeTransformMatrix() (ignore the stuff about parent objects), and the Object: http://www.opengl.org/discussion_boards/ubb/biggrin.gifraw functions. Matrix.cpp might be helpful too.

(by the way - the player's x and z rotation axes are locked in my demo. However, the engine is still perfectly capable of doing full 3D rotations like your ship needs to do. You can simply unlock those axes (toggle a bool value), set the rotation velocity to something, and they will spin in any direction. )

edit: fixed url

[This message has been edited by ioquan (edited 07-16-2002).]

Junkstyle
07-15-2002, 09:03 PM
thanks ioquan!

Really i've gone quite mad(crazy) working with these algorithms for the past 2 days straight. I don't know how many fricken ones I've coded. Right now i have a method working but it doesn't use the FORWARD, UP, RIGHT vectors for anything. I actually store a quaternion with the object and do a quaternion multiply with the new quaternion formed by the user input. I got it so I am using the glMultMatrixf().

What i need is to still get the Forward, Up, and Right vectors so I can use it for some physics things and targeting things for my game. So I'll take a look. Its going to be fun to look back at this and laugh. I'm laughing right now but its kindof the hysterical laugh you get from going crazy.

ioquan
07-15-2002, 11:49 PM
JunkStyle, why did you scrap the 3 vector orientation system? Perhaps if you take a look at my code, you will see better how it works. You can put the 3 vectors in the 3 rows of a matrix, and use glMultMatrix with it - it will orient your object. This 3 vector system is also what allows you to do rotations based on local axes. And it comes in handy when you're ready to shoot a missile and you already have the look vector there for your aim.

Junkstyle
07-16-2002, 10:26 AM
ioquan, what I have uses the same formulas as you do I just store the resultant quaternion though. Slightly different approach.

basically:
1) make a quaternion from user input (yaw, pitch, roll)

2) multiply previous quaternion that represents the old rotation of the object by the new input quaternion to get the combined rotation of both of them. This combined quaternion becomes the new rotation quaternion stored for that object.

3) take that quaternion and make a rotation matrix. And also drop in the translation vector into that matrix.

4) call glMultMatrixf() and I'm done

Where are the Forward, Up, Right vectors? Well inside the matrix used in glMultMatrixf().

Are they orthogonal?
I've dotted them all and I get very very close to 0.0

The length of them are very very close to 1.0

Will they drift?
No, I don't think so I keep the old quaternion for the objects rotation. I throw away the matrix each time and recalculated it from the new quaternion.

Any bonuses for doing it this way?
In a network game I only have to send the quaternion[x y z w] on the wire to have the complete orientation of something.

Anyways, I think this is working good. Once I clean up the code I can send it too you if you like. Currently it looks like WWIII from my 40 hours of quaternion hell.