Code:
struct ROTATE_DTP
{
ROTATE_DTP ( )
{
entireModel = 0;
rotateMeshID = 0;
rotateAxis = X;
rotateDeg = 0;
isRotationBlock = false;
rotationBlockMeshID = NULL;
xRot = 0;
yRot = 0;
zRot = 0;
}
//variables for NON-rotation blcoks. AKA entire model rotations and single mesh rotations
bool entireModel;
uint rotateMeshID;
AXIS_DTP rotateAxis;
float rotateDeg;
//variables for rotation blocks
bool isRotationBlock; //to say if it is a rotation block
bool *rotationBlockMeshID; //stores mesh ID's in the rotation block
float xRot, yRot, zRot; //rotation values for rotation blocks only
};
...
void MODEL_DTP::DrawModel ( void )
{
ROTATE_DTP rotate; //the current rotation that needs to be done
bool isRotate = false;
//Push the matrix for rotation purposes
glPushMatrix ( );
//Do the rotations that need to be done on the rotation stack
while ( !rotation.empty() )
{
rotate = rotation.top();
rotation.pop();
if ( rotate.entireModel )
{
glRotatef ( rotate.rotateDeg, (rotate.rotateAxis == X),
(rotate.rotateAxis == Y), (rotate.rotateAxis == Z) );
}
else if ( rotate.isRotationBlock )
{
glPushMatrix ( );
glRotatef ( rotate.xRot, 1.0, 0.0, 0.0 );
glRotatef ( rotate.yRot, 0.0, 1.0, 0.0 );
glRotatef ( rotate.zRot, 0.0, 0.0, 1.0 );
for ( int n = 0; n < UnitModel.GetMeshCount(); n++ )
{
if ( rotate.rotationBlockMeshID[n] )
{
glBindTexture ( GL_TEXTURE_2D, texture [MECH_METAL] );
LMesh &mesh = UnitModel.GetMesh(n);
// Texturing Contour Anchored To The Object
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
// Texturing Contour Anchored To The Object
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
glEnable(GL_TEXTURE_GEN_S); // Auto Texture Generation
glEnable(GL_TEXTURE_GEN_T); // Auto Texture Generation
glVertexPointer(4, GL_FLOAT, 0, &mesh.GetVertex(0));
glNormalPointer(GL_FLOAT, 0, &mesh.GetNormal(0));
glColorPointer(3, GL_FLOAT, 0, &mesh.GetBinormal(0));
glDrawElements(GL_TRIANGLES, mesh.GetTriangleCount()*3,
GL_UNSIGNED_SHORT, &mesh.GetTriangle(0));
//set the master list variable to true for this mesh
//so we know not to draw this mesh in the main drawing loop
rotationBlockMeshIDMasterList[n] = true;
}
}
glPopMatrix ( );
}
else
{
rotateMeshMatrix[rotate.rotateMeshID][rotate.rotateAxis] = rotate;
}
}
//Do the drawing of the model after the rotating has been done
for (uint i= 0; i<UnitModel.GetMeshCount(); i++)
{
isRotate = (!rotateMeshMatrix[i][0].entireModel) ||
(!rotateMeshMatrix[i][1].entireModel) ||
(!rotateMeshMatrix[i][2].entireModel);
//Skip the drawing of this mesh, if it was part of a rotation block
//and no more rotations need to be done to it.
if ( rotationBlockMeshIDMasterList[i] )
{
rotationBlockMeshIDMasterList[i] = false; //resets it for the next frame
continue;
}
if ( isRotate )
{
glPushMatrix ( );
if ( !rotateMeshMatrix[i][0].entireModel )
glRotatef ( rotateMeshMatrix[i][0].rotateDeg,
1.0f, 0.0f, 0.0f );
if ( !rotateMeshMatrix[i][1].entireModel )
glRotatef ( rotateMeshMatrix[i][1].rotateDeg,
0.0f, 1.0f, 0.0f );
if ( !rotateMeshMatrix[i][2].entireModel )
glRotatef ( rotateMeshMatrix[i][2].rotateDeg,
0.0f, 0.0f, 1.0f );
}
glBindTexture ( GL_TEXTURE_2D, texture [MECH_METAL] );
LMesh &mesh = UnitModel.GetMesh(i);
// Texturing Contour Anchored To The Object
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
// Texturing Contour Anchored To The Object
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
glEnable(GL_TEXTURE_GEN_S); // Auto Texture Generation
glEnable(GL_TEXTURE_GEN_T); // Auto Texture Generation
glVertexPointer(4, GL_FLOAT, 0, &mesh.GetVertex(0));
glNormalPointer(GL_FLOAT, 0, &mesh.GetNormal(0));
glColorPointer(3, GL_FLOAT, 0, &mesh.GetBinormal(0));
glDrawElements(GL_TRIANGLES, mesh.GetTriangleCount()*3,
GL_UNSIGNED_SHORT, &mesh.GetTriangle(0));
if ( isRotate )
glPopMatrix ( );
}
glDisable ( GL_TEXTURE_GEN_S );
glDisable ( GL_TEXTURE_GEN_T );
//Pop off the matrix
glPopMatrix ( );
}
...
void MODEL_DTP::RotateModel ( float deg, AXIS_DTP axisID )
{
ROTATE_DTP rot;
rot.entireModel = true;
rot.rotateAxis = axisID;
rot.rotateDeg = deg;
rotation.push ( rot );
}
...
//Terminated by a -1
void MODEL_DTP::RotateBlock ( float xRot, float yRot, float zRot, ... )
{
ROTATE_DTP rotationBlock;
rotationBlock.isRotationBlock = true;
rotationBlock.xRot = xRot;
rotationBlock.yRot = yRot;
rotationBlock.zRot = zRot;
rotationBlock.rotationBlockMeshID = new bool [ UnitModel.GetMeshCount() ];
for ( int k = 0; k < UnitModel.GetMeshCount(); k++ )
rotationBlock.rotationBlockMeshID[k] = false;
va_list ap;
int arg;
va_start ( ap, zRot );
while ( !((arg = va_arg(ap, int)) == -1) )
{
rotationBlock.rotationBlockMeshID[arg] = true;
}
va_end(ap);
rotation.push ( rotationBlock );
}
...
//rotate a mesh a certain # of degrees on an axis
void MODEL_DTP::RotateMesh ( GLuint meshID, float deg, AXIS_DTP axisID )
{
ROTATE_DTP rot;
rot.entireModel = false;
rot.rotateMeshID = meshID;
rot.rotateAxis = axisID;
rot.rotateDeg = deg;
rotation.push ( rot );
}
Here is a diagram: