The following code produces the desired output, but I want to replace it:

```
void BVH::RenderFigure( const Joint * joint, const double * data, float scale )
{
glPushMatrix();
glTranslatef( joint->offset[ 0 ] * scale,
joint->offset[ 1 ] * scale,
joint->offset[ 2 ] * scale );
int i, j;
for ( i=0; i<joint->channels.size(); i++ )
{
Channel * channel = joint->channels[ i ];
if ( channel->type == X_ROTATION )
glRotatef( data[ channel->index ], 1.0f, 0.0f, 0.0f );
else if ( channel->type == Y_ROTATION )
glRotatef( data[ channel->index ], 0.0f, 1.0f, 0.0f );
else if ( channel->type == Z_ROTATION )
glRotatef( data[ channel->index ], 0.0f, 0.0f, 1.0f );
}
glPointSize(5.0);
glBegin(GL_POINTS);
glVertex3f( 0,0,0 );
glEnd();
for ( i=0; i<joint->children.size(); i++ )
{
RenderFigure( joint->children[ i ], data, scale );
}
glPopMatrix();
}
```

I would like to replace it with this code. The problem is combining all of the rotation matrices. If I uncomment the line M = parent * T it will produce the same render of the above code if I don’t do any rotations. This means my hierarchy is correct and that the translations are correct. I can’t figure out why the rotations don’t work. I am basically interested in building the model matrix so I can get the world coordinates of each point where each point is part of a hierarchical human figure as defined by the BVH file specification. This is why I am trying to render in this way. What am I doing wrong with the rotation matrices? I need to apply the rotations in this order (as defined in the BVH spec) Z, X, then Y. For each point it should be: Position = Mparent * M * (0,0,0,1) where M = RotationZXY * Offset

```
void BVH::getPositions( const Joint * joint, const double * data,
float scale, glm::mat4 parent)
{
glm::mat4 T = glm::translate((float)(joint->offset[ 0 ] * scale),
(float)(joint->offset[ 1 ] * scale),
(float)(joint->offset[ 2 ] * scale));
int i, j;
double x,y,z;
for ( i=0; i<joint->channels.size(); i++ )
{
Channel * channel = joint->channels[ i ];
if ( channel->type == X_ROTATION )
x = data[ channel->index ];
else if ( channel->type == Y_ROTATION )
y = data[ channel->index ];
else if ( channel->type == Z_ROTATION )
z = data[ channel->index ];
}
glm::mat4 Mx = glm::rotate((float)x,1.0f, 0.0f, 0.0f);
glm::mat4 My = glm::rotate((float)y, 0.0f, 1.0f, 0.0f);
glm::mat4 Mz = glm::rotate((float)z, 0.0f, 0.0f, 1.0f);
glm::mat4 M = My * Mx * Mz;
M = M * T;
M = parent * M;
//M = parent * T
glm::vec3 point = glm::vec3(M * glm::vec4(glm::vec3(0,0,0),1));
glPointSize(5.0);
glBegin(GL_POINTS);
glVertex3f( point.x,point.y,pointz );
glEnd();
for ( i=0; i<joint->children.size(); i++ )
{
getPositions( joint->children[ i ], data, scale, M );
}
}
```