From various threads and websites I've figured out how to rotate a ball based on its velocity and direction. I know how to work out the angular velocity and the axis of rotation. The problem comes when I want the ball to change direction or when the ball collides with something.
My first code went something like this:
glPushMatrix();
//Translate to the position of the ball
glTranslatef(pos.x,pos.y,pos.z);
//Angle to rotate the ball - note this is cumulative for each render
angle += RAD_TO_PI * ((vel.length() / radius));
//Axis of rotation is perpedicular to velocity vector and vertical vector
Vector3D axis = vel.cross(Vector3D(0.0,-1.0,0.0));
axis.normalize();
//Apply rotation
glRotatef(angle,axis.x,axis.y,axis.z);
//Draw the ball
glCallList(displayList);
glPopMatrix();
The problem with this is that when the ball changes direction (eg when it hits a wall) the orientation of the ball changes drastically. This is because the orientation of the ball in the previous frame is not stored anywhere - only the angle is stored. This means that all rotations are performed from an initial default orientation.
My other method I adapted from this post:
http://www.gamedev.net/community/forums/viewreply.asp?ID=1189690
Here's more or less what my rotation code looks like now:
//initialize rotation matrix class
Matrix4f rotationMatrix;
//set initial rotation to the identity matrix
rotationMatrix.setIdentity();
//During the render routine:
glPushMatrix();
//Translate to the position of the ball
glTranslatef(pos.x,pos.y,pos.z);
//Angle to rotate the ball
angle = RAD_TO_PI * ((vel.length() / radius));
//Axis of rotation is perpedicular to velocity vector and vertical vector
Vector3D axis = vel.cross(Vector3D(0.0,-1.0,0.0));
axis.normalize();
//Rotate the matrix using the matrix class' rotate method - this
//appears to be equivelent to glRotate
rotationMatrix.rotate(angle,axis);
//Multiply the current model view matrix with the rotation matrix
glMultMatrix(rotationMatrix);
//Draw the ball
glCallList(displayList);
glPopMatrix();
This code uses a matrix class called rotationMatrix to store the rotation. As in the first method it works fine until it changes direction; the orientation of the ball is preserved which is good but it seems to combine the previous rotation matrix with the new one and then the ball seems to spin in any arbitary direction. Somehow I need to preserve the orientation from the previous spinning direction but not the actual rotation.
This is getting pretty hard to explain but I know that it's quite a common problem. I've seen it come up quite a few times in previous forum posts but I haven't found any real solutions to it. I know I could use Quaternions but I don't really want to have to deal with those just yet. I have an example from a pool game which only seems to use matrices and matrix transformations but it's written in DirectX which I haven't had any experience in yet.
Can anyone point out the flaws in my code or point me in the direction of a solution that works?