PDA

View Full Version : Help with Skeletal animation



tjames221188
04-20-2010, 08:40 AM
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 (http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=Quaternion_Camera_Class). 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.CreateFromAxis Angle(0.0f, 1.0f, 1.0f, rot);

eval_tree(&amp;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.

ZbuffeR
04-20-2010, 08:51 AM
Column major versus row major matrices ?
What do each of your quat matrices look like ?

tjames221188
04-20-2010, 09:25 AM
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.