Rocket Rotation

I have a rocket consisting of 4 parts where each has its own display list. I would like the entire rocket rotate in place. I can get the body to rotate but the other parts either rotate independently in place or they orbit around the body disjointedly or they all move like the hands of a clock (in a large circle). There’s something conceptual that I’m missing.

	/*----------------TOP-------------*/
glPushMatrix();	
	glTranslatef(0,2,0);
	glCallList(head);
glPopMatrix();

	/*----------------TOP RING-------------*/
glPushMatrix();
	glTranslatef(0,1.92,0);
	glCallList(top_ring);
glPopMatrix();

	/*----------------BOTTOM-------------*/
glPushMatrix();
	glTranslatef( -.0035, 1.63, 0 );
	glCallList(bottom);
glPopMatrix();

	/*----------------BODY-------------*/
glPushMatrix();
	glTranslatef(0,1.713,0);
	glRotatef( angle, 0, 0 , 1 );
	glCallList(body);
glPopMatrix();

WIthout seeing what’s going on in your Display Lists and how your geometry for the rocket sections is made it’s hard to comment.

You need to set a center of rotation (perhaps the middle of the entire rocket, or it’s theoretical centre of gravity) and create a matrix that describes the translation to that point, then rotate that matrix according to where you want the rocket to point.

After that you should just offset the individual sections from that using a translation kind of like you are doing above.

Things to be aware of are where the actual origin of the individual pieces are. Are they all based around a common origin, or do they have their own individual origins? Both have their advantages and disadvantages, and both will affect how your matrix affects their rotation and position in space.

You are drawing each part of the rocket as a separate object in the world with its own independant position.
The code you gave only rotates the body, everything else stays in its original position.

OpenGL matrices are all about co-ordinate systems, the View matrix locates the camera co-ordinate system in the world co-ordinate system, and specifies the direction it is facing.
The Model matrix locates the object you are drawing in the world, and its orientation.
Each glTranslatef and glRotatef changes the co-ordinate system that will be used by the following glCallList.
When you call glPopMatrix you restore the co-ordinate system that was in use the last time you called glPushMatrix.
Your code restores the world co-ordinate system after drawing each object, effectivly making them independant of each other.

To keep the parts of the rocket together you need to first specify a whole-rocket co-ordinate system, translate & rotate it, and then draw all of the parts relative to this.
This requires nesting the push/pop’s so that we first push the world co-ordinate system, then push the rocket co-ordinate system.
Dont pop the world co-ordinate system until the entire rocket has been drawn.

/Entire Rocket/
glPushMatrix(); /Save world co-ordinate system/
glTranslatef( 0,1.713,0 ); /Position rocket co-ordinate system in the world/
glRotatef( angle, 0, 0 , 1 ); /Rotate rocket around origin of rocket co-ordinate system/

/----------------BODY-------------/
glCallList(body);

/----------------TOP-------------/
glPushMatrix(); /Save rocket co-ordinate system/
glTranslatef(0,2,0); /Position head co-ordinate system relative to Body (rocket co-ordinate system)/
glCallList(head);
glPopMatrix(); /Restore rocket co-ordinate system/

/----------------TOP RING-------------/
glPushMatrix();
glTranslatef(0,1.92,0); /*Position top ring relative to rocket
glCallList(top_ring);
glPopMatrix(); /Restore rocket co-ordinate system/

/----------------BOTTOM-------------/
glPushMatrix();
glTranslatef( -.0035, 1.63, 0 ); /Position bottom relative to body/
glCallList(bottom);
glPopMatrix(); /Restore rocket co-ordinate system/

glPopMatrix(); /Restore world co-ordinate system/

To add a moving antenae to the top, nest another push/translate/rotate/draw/pop just before the glPopMatrix at the end of the “TOP” section.

In pseudo-code: use nested Pushes and Pops to do this sort of thing (as Simon says). This will rotate the entire rocket assembly around (0,0,0). If you want to rotate around some other point, like the CG of the rocket, you have to add glTranslates before and after the glRotate (as Simon says).


Push;

   Rotate (angle, 0,0,1);  // Rotates entire assembly

   Push;  Trans(0.0000,2.000,0);  CallList(  head  );  Pop;
   Push;  Trans(0.0000,1.920,0);  CallList(top_ring);  Pop;
   Push;  Trans(-.0035,1.630,0);  CallList( bottom );  Pop;
   Push;  Trans(0.0000,1.713,0);  CallList(  body  );  Pop;

Pop;

Thanks! That was really helpful. I was able to get it working also using your advice.