one final problem with rotation [Archive] - C Board

PDA

View Full Version : one final problem with rotation


DavidP
11-18-2003, 05:12 PM
Well, my engine is nearing completion.

One problem remains. It is a problem that I have probably handled in the past, and therefore should know how to fix....but...it has escaped my mind and I am not sure how to handle it. So any help would be appreciated.

Once again I am working with 3d models.

At the current moment I am rotating certain areas/parts/meshes of my models, however, they are rotating around a pivot point that I do not want them to rotate around.

For example, when I try to rotate the leg to make it look like my model is walking, it will rotate around the origin. I do not want it to do that. I want it to rotate around a certain point of the mesh.

Here is some code snippets (they are kind of long, you may skip them if you want to, there is a JPEG diagram at the bottom of the post):


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:

grady
11-18-2003, 08:07 PM
Translate to black dot labeled "pivot point" then rotate.

DavidP
11-18-2003, 10:39 PM
yeah i was thinking about that....problem is...i'm not exactly sure what the coordinate of that black dot is on the pivot point....

looks like i am going to have to delve deep into the model and look at each point individually!

how fun! (especially when there are about 18000 points)

MrWizard
11-19-2003, 03:50 AM
Sounds like you need rotation around an arbitrary point. The steps to perform that are as follows:

1) Translate the point to the origin ( -px, -py, -pz )
2) Perform the rotation
3) Translate the point back to position ( px, py, pz )

So multiply those matrices in the correct order and you should be fine. Let me know if you have any problems.

EDIT: Forgot this game was 3D! Look up the formula for rotation around an arbitrary vector. The quick steps are.

1) Translate the vector so it passes through origin
2) Rotate the vector onto one of the primary axis.
3) Do rotation w.r.t. that standard axis.
4) Inverse of Step 2
5) Inverse of Step 1