OpenFrameworks ofxAssimpModelLoader to animate a model using key press

I am using OpenFrameworks for animating a 3d model using keypress. The following are the steps that I have successfully completed :-

  • Loading a ‘.dae’ file using ofxAssimpModelLoader
  • Getting the scene , bones and the nodes present in the 3d model
  • Drawing the skeleton using the nodes

My end goal is to be able to lift the hand or legs using keyboard key press. I went through many of the common tutorials for skeletal animation using Assimp but i am still unable to get it woking. Here is my code.

Using Qt Creator with openFrameworks

#include "ofMain.h"
#include "ofxAssimpModelLoader.h"
#include "ofVboMesh.h"

#include <iostream>
#include <memory>
#include <string>

class SkeletonDrawer : public ofxAssimpModelLoader
{
public:
    void drawSkeleton();

    aiNode *getNodeFromName(string name);

private:
    std::map<aiNode*, aiMatrix4x4> nodeMatrices;
    void collectNodes(const struct aiScene *sc, const struct aiNode *nd);
};


class ofApp : public ofBaseApp{

public:
void setup();
void update();
void draw();

void keyPressed(int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void mouseEntered(int x, int y);
void mouseExited(int x, int y);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);


SkeletonDrawer model;

ofLight light;

};

Here is the cpp file :

void ofApp::setup(){
    ofDisableArbTex();

    if (model.loadModel("/home/anirudhnj/Downloads/ninja/ninja.dae", 20))
    {
        model.setAnimation(0);
        model.setPosition(ofGetWidth() / 2, ofGetHeight() * 0.75, 0);
        ofPushMatrix();
        model.setRotation(1,90,90,0,0);
        ofPopMatrix();

    }

    ofEnableBlendMode(OF_BLENDMODE_ALPHA);

    glEnable(GL_DEPTH_TEST);
    glShadeModel(GL_SMOOTH);
    light.enable();
    ofEnableSeparateSpecularLight();
}

void SkeletonDrawer::collectNodes(const struct aiScene *sc, const struct aiNode *nd)
{
    for (unsigned n = 0; n < nd->mNumMeshes; ++n)
    {
        const struct aiMesh *mesh = sc->mMeshes[nd->mMeshes[n]];

        for (int a = 0; a < mesh->mNumBones; ++a)
        {
            const aiBone *bone = mesh->mBones[a];

            //ofLog(OF_LOG_NOTICE)<<bone->mName.C_Str();

            // find the corresponding node
            aiNode *node = sc->mRootNode->FindNode(bone->mName);

            aiNode *tempNode = node;
            aiMatrix4x4 nodeMat;
            while (tempNode)
            {
                nodeMatrices[tempNode] = nodeMat;
                tempNode = tempNode->mParent;
            }
        }
    }

    // process all children
    for (unsigned n = 0; n < nd->mNumChildren; n++)
    {
        collectNodes(sc, nd->mChildren[n]);
    }
}

//Returns the node with the given name
    aiNode * SkeletonDrawer::getNodeFromName(string name)
    {
        aiNode * rootNode = scene.get()->mRootNode;
        aiNode * selectedNode = rootNode->FindNode(name.c_str()) ;

    return selectedNode;

}


void SkeletonDrawer::drawSkeleton()
{
    //const aiScene * currentScene = scene.get();
    // find all nodes connected to the bone hierarchy
    collectNodes(scene.get(), scene.get()->mRootNode);

    // calculate node matrices
    map<aiNode*, aiMatrix4x4>::iterator i = nodeMatrices.begin();
    for(; i != nodeMatrices.end(); ++i)
    {
        aiNode *node = i->first;

        aiMatrix4x4 nodeMat;
        const aiNode *tempNode = node;
        while (tempNode)
        {
            nodeMat = tempNode->mTransformation * nodeMat;
            tempNode = tempNode->mParent;
        }
        nodeMatrices[node] = nodeMat;
    }

    // do all transformations similarly to ofxAssimpModelLoader::draw()
    ofPushMatrix();

    ofTranslate(pos);

    ofRotate(180, 0, 0,1);
    ofRotateX(-90);
    ofTranslate(-scene_center.x, -scene_center.y, scene_center.z);

    if (normalizeScale)
    {
        ofScale(normalizedScale, normalizedScale, normalizedScale);
    }

    for (int i = 0; i < rotAngle.size(); i++)
    {
        ofRotate(rotAngle[i], rotAxis[i].x, rotAxis[i].y, rotAxis[i].z);
    }

    ofScale(scale.x, scale.y, scale.z);

    // draw bones, all nodes connected with their parents
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_TEXTURE_2D);
    glDisable(GL_LIGHTING);

    glColor3f(1, 0, 0);
    glLineWidth(5.);
    glBegin(GL_LINES);

    aiMatrix4x4 mat0, mat1;
    aiQuaternion q0, q1;
    aiVector3D p0, p1;

    i = nodeMatrices.begin();
    for(; i != nodeMatrices.end(); ++i)
    {
        aiNode *n0 = i->first;
        aiNode *n1 = n0->mParent;
        if (n1 == NULL)
            continue;
        // get the position from the matrices
        mat0 = i->second;
        mat0.DecomposeNoScaling(q0, p0);
        mat1 = nodeMatrices[n1];
        mat1.DecomposeNoScaling(q1, p1);

        glVertex3f(p0.x, p0.y, p0.z);
        glVertex3f(p1.x, p1.y, p1.z);
    }
    glEnd();
    ofPopMatrix();
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_LIGHTING);
}

//--------------------------------------------------------------
void ofApp::update(){

}

//--------------------------------------------------------------
void ofApp::draw(){
    ofBackground(50, 50, 50, 0);
    ofSetColor(255, 255, 255, 255);

    ofPushMatrix();
    ofTranslate(model.getPosition().x, model.getPosition().y, 0);
    ofRotate(-mouseX, 0, 1, 0);
    ofTranslate(-model.getPosition().x, -model.getPosition().y, 0);
    model.drawFaces();
    model.drawSkeleton();
    ofPopMatrix();
}

//--------------------------------------------------------------
        void ofApp::keyPressed(int key){
            aiQuaternion quaternion ;
            aiVector3t<float>  movement;
            aiNode * selectedNode = model.getNodeFromName("LeftLegJoint");

            if(!selectedNode)
                return;

            selectedNode->mTransformation.DecomposeNoScaling(quaternion ,movement) ;

             //**Code here ????**
                if(key == OF_KEY_UP)
                {

                }

            if(key == OF_KEY_DOWN)
            {

            }

            if(key == OF_KEY_LEFT)
            {

            }

            if(key == OF_KEY_RIGHT)
            {

            }

        }