Search code examples
openglskeletal-animationskeletal-mesh

Draw bone for skinned mesh


I have the JointTransform matrix for each bones of each frame in the animation of a simple rigged model. I would like to draw the bones as lines. I'm using OpenGl 2. I just want to calculate the start and end Vector3 points. How would I do this?


Solution

  • It depends on whether your matrices are in world or local space, whether you are storing the joints as a tree (or a flattened array with indexing), and whether you are using push/pop or your own matrix maths.

    If you are storing the joints in a hierarchy, and the data is local space, you will need to recurse to render the character:

    void recurseHierarahcy(Joint* p)
        glPushMatrix();
        glMultMatrix(p->localTransform);
        for(int i = 0; i < p->numChildren; ++i) {
           Joint* child = p->getCHild(i);
           glBegin(GL_LINES);
             // the line starts at the origin of the parent frame...
             glVertex3f(0,0,0);
    
             // and extends to the translation of the child (in local space)
             glVertex3f(child->localTransform[12], 
                        child->localTransform[13], 
                        child->localTransform[14]);
           glEnd();
           recurseHierarahcy(child);
        }
        glPopMatrix();
    }
    

    If you have world space matrices, then you just need to join the dots between the world space transforms... (I'm assuming these transforms are in world space, and you've stored the character in an array!)

    void drawJointLines(Joint* joints, int count)
       glBegin(GL_LINES);
       for(int i = 0; i < count; ++i ){
           Joint* joint = joints + I;
    
           // only draw lines for joints that have parents.
           if(joint->hasParent()) {
               Joint* parent = joint->getParent();
    
               // the line extends between the parent and the child.
               glVertex3f(joint->worldTransform[12], 
                          joint->worldTransform[13], 
                          joint->worldTransform[14]);
               glVertex3f(parent->worldTransform[12], 
                          parent->worldTransform[13], 
                          parent->worldTransform[14]);
           }
       }
       glEnd();
    }