I’m trying to achieve an object rotation about 3 axes by incrementing values of rotation angles for axes, and displaying those axes to make next rotation direction predictable for the viewer. But after a few rotations, only rotation about Z-axis is performed in accord with displayed axis. Is there a chance it can be done simply, without poring over quaternions?
glPushMatrix ();
glRotatef (angleX, 1.0, 0.0, 0.0);
glRotatef (angleY, 0.0, 1.0, 0.0);
glRotatef (angleZ, 0.0, 0.0, 1.0);
glBegin(GL_LINES);
glVertex3f(80.0, 0.0, 0.0); //x axis
glVertex3f(-80.0, 0.0, 0.0);
glVertex3f(0.0, 80.0, 0.0); //y axis
glVertex3f(0.0, -80.0, 0.0);
glVertex3f( 0.0, 0.0, 80.0); //z axis
glVertex3f( 0.0, 0.0, -80.0);
//here is some code for drawing arrows at axes ends
glEnd();
glPopMatrix();
Edit:
I have axes like those:
http://img841.imageshack.us/i/arrowsx.jpg/
angleX, angleY, angleZ are globals incremented on key press – e.g. after pressing ‘A’ angleX is incremented by 10, and I expect axis X won’t move after that and axes Y and Z will rotate about axis X. But it is true only when I change only one of angle variables. After rotation about more then one axis, when I change, e.g. angleX – all axes from picture will change their positions.
The code you posted essentially lumps all of your rotations about each axis into a single rotation about that axis. As you note, it works well as long as all you’re doing is incremental rotations about a single axis. From your update, it also appears that you want the key strokes to apply rotations to the image as displayed, rather than in aggregate as you have coded. One way to achieve the behavior you’re looking for is to store in a queue or resizable vector (std::vector, or std::queue or some other container if you’re using C++) each of the rotations that you apply. Each time the user presses a key, add another rotation of the fixed angle size about the desired axis to the list. During playback, apply the rotations in the order they were entered (maybe reverse order, I’ll have to give it more thought). This will then apply the rotations to the displayed geometry, rather than to the canonical (i.e. un-rotated) geometry.
There might be an easier and less memory intensive way to do this using quaternions; that’s one area that I really need to get better versed on. Give what I know right now, though, this is the way I’d go about achieving the behavior I think you’re after.