Help with Skeletal animation

Hi there,

I don’t usually like to ask for help but this has had me stumped for days!

I have been asked to produce a basic skeletal animation program for a uni project. The skeleton is very basic and uses gluCylinders to represent a bone. the quaternion class has been taken from the nehe quaternion camera class here. Most of it is done, however there is one problem that i cannot make any sense out of. I’m hoping that somebody has experienced a similar problem.

The problem:

Whenever I rotate a joint that has at least 1 child, the cylinder and all child cylinders grow and shrink as they rotate. it looks like this:
http://yfrog.com/50piczsj

here is the code for the structs:


//joints
struct arc {
	glQuaternion q_vrot;//variable rotation
	float matrix[16];//translates arc to correct position
	Node *node;//child node
};
//bones
struct Node {
	float length;//bone length
	float matrix[16];//point of rotation
	int num_arcs;//number of children
	arc *arcs[4];//children
};

and here is the code for the methods that do the drawing:

GLvoid drawCylinder(GLfloat length)
{
	
	glPushMatrix();
		gluCylinder(quadratic, boneRadius, boneRadius, length, 32, 32);
		gluDisk(quadratic, 0.0f, boneRadius*2.0f, 32, 32);
		gluSphere(quadratic, boneRadius*1.5f, 32, 32);
		glTranslatef(0.0f, 0.0f, length);
		gluDisk(quadratic, 0.0f, boneRadius, 32, 32);
	glPopMatrix();
}

GLvoid eval_node( GLfloat m[16], Node *node)
{
	GLfloat temp_mat[16];//used to store the current matrix
	GLfloat quat_mat[16];//used to store the matrix from the quaternion
	//concatenate node matrix and current matrix
	glMultMatrixf(node->matrix);
	if (node->length > 0)
		drawCylinder(node->length);
	else
	{
		glPushMatrix();
			gluSphere(quadratic, 0.5f, 32, 32);//if length !> 0 it must be the head, so draw a sphere
		glPopMatrix();
	}

	
	/*loop over each arc coming from this node and follow 
	the arcs to recursively evaluate child nodes*/
	for(int i = 0; i < node->num_arcs; i++)
	{
		glPushMatrix();
			
			node->arcs[i]->q_vrot.CreateMatrix(quat_mat);
			glMultMatrixf(node->arcs[i]->matrix);
			glMultMatrixf(quat_mat);
			glGetFloatv(GL_MODELVIEW_MATRIX, temp_mat);
			eval_node(temp_mat, node->arcs[i]->node);
		glPopMatrix();
	}
}

//main routine evaluates recursively from root
GLvoid eval_tree(arc *a)
{
	eval_node( a->matrix, a->node );
}

int DrawGLScene(GLvoid)									
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	
	glLoadIdentity();
	
	glTranslatef(-camera.xpos, -camera.ypos, -camera.zpos);
	
	//animation
	left_shoulder2left_upper_arm.q_vrot.CreateFromAxisAngle(0.0f, 1.0f, 1.0f, rot);
	
	eval_tree(&arc_root);

	if (rot >= 360.0f)
		rot = 0.0f;
	else
		rot+= 0.2f;
	return TRUE;										
}

Any suggestions would be hugely appreciated.

Many thanks in advance,

Toby.

Column major versus row major matrices ?
What do each of your quat matrices look like ?

Hi, thanks for your quick reply.

the quat matrix for the arc - left_shoulder2left_upper_arm (the one that im changing in drawglscene) is:

-2.8793850 -0.34202015 0.34202015 0
0.34202015 -0.93969256 1.9396925 0
-0.34202015 1.9396925 -0.9396925 0
0 0 0 1

this is when the variable ‘rot’ is 200.0f

thanks again,

Toby.