# rotations relative to object

I was wondering, if I had a helicopter and I wanted it to have two angles, heading and pitch.

I seem to be unable to apply the pitch angle about the helicopter’s own vertical axis.

I have tried applying the pitch rotation and the obtaining the modelview matrix and then figuring out the corrected y-axis and then rotating about that instead of the standard y axis. However, this causes all sorts of weird rotation effects.

Any help would be appreciated.

Cheers
Sharanga

Not really sure if it will work, but have you tried change the order of the head and pitch rotations? Matrix multiplications are not commutative, order does matter.

You either have to apply one rotation, and then send the next rotation through the first one, and then apply the second rotation… Or you can use a different method of storing the rotation in memory.

That’s because you’re doing the math wrong. What you’re describing should work, when implemented right.

You could cheat, too. If the heading is around the gravity up axis, rather than around the helicopter’s up axis, then you can FIRST apply the pitch and THEN the heading.

Note that a vertex’s path from model space to view space goes in the reverse flow of the code, so to implement the order that I’m describing, you have to do this, assuming world up is Y, your helicopter is modeled pointing “forward” in negative Z, positive heading means “to the right” and positive pitch means “up”:

glMatrixMode( GL_MODELVIEW );

glTranslatefv( &(helicopterPos-cameraPos) );
glRotatef( -helicopterHeading, 0, 1, 0 );
glRotatef( -helicopterPitch, 1, 0, 0 );

myDrawHelicopter();

If you want to support camera rotation, too, then that goes before the translate (after the LoadIdentity).

[This message has been edited by jwatte (edited 10-03-2002).]

What I really want is to rotate about the helicopter’s up axis, not the vertical.

This is a common problem.

What you need to do is the following.

Start out with you helicopter pointing down the Z axis. Then turn it 90 degrees up (pitch/X axis). If you now apply heading, and do it wrong, you make it spin around sidewise, since you told it to rotate on the Y axis.

However, this Y axis is still in world space, and thus, you also need to turn the Y axis 90 degrees up. (So that it points in the original Z axis direction)

How to do this? Well, the best way is, if you want to be able to keep turning the helicopter frame after frame and perform all kinds of wicked rotations, then your solution is the following:

Your helicopter needs to remember where it is. (This is the same as aligning the Y axis with the helicopter).

This is done by storing the matrix for it from frame to frame, and then reinserting it before each new rotation.

So, for your helicopter (or one for each) you need an array of 16 floats (or doubles). Store this in the helicopter struct/class for convenience.

float heliMatrix [16]; // This needs to start out as the indentity matrix.

Then, when you update your helicopter, do this:

glRotatef (xRot, 1, 0, 0);
glRotatef (yRot, 0, 1, 0);
glRotatef (zRot, 0, 0, 1);

// Draw helicopter

// Remember where the helicopter is.
glGetFloatv (GL_MODELVIEW_MATRIX, heliMatrix);

The only crux here is that xRot, yRot and zRot must be the CHANGE in rotation per frame, not the real angle to rotate to.

This should produce what you want.

[This message has been edited by NordFenris (edited 10-04-2002).]

Thanks. That works very well.

But it causes another problem. I won’t be able to keep track of the position or orientation of the helicopter. I’ve tried mucking about with the helicopter’s modelview matrix, without much success. Can gluUnProject be used to figure out the position of the helicopter?

Cheers
Sha

I store the up, forward, and right vectors of all my objects. Since I have those, I can easily rotate my object about those vectors (which make up it’s local axes). Also, since I have the 3 vectors, when it is time to draw the object, I can simply make a matrix with the 3 vectors being the three rows to orient my object. I never use any calls to glRotate.