Generic Manual Pose Loading         Code is for manually loading and updating poses

This code is for manually loading and updating poses.

This is a generic pose loader, it should be able to load any mesh with poses on its submeshes. It will not load poses on shared geometry. There is also an update method which will traverse your mesh and update all of the poses that have the name provided. Be sure your exporter names your poses correctly in your .mesh, otherwise the updatePose will not work.

Required Variables:

Ogre::Entity* head;
    Ogre::MeshPtr mesh;
    map<int, Ogre::VertexPoseKeyFrame*> vertexPoseKeyFrameMap;    
    const char * poseAnimationStateName = "PoseAnimationState";

Loading Code:

void MeshPoseManager::loadHead(std::string meshFile){
       try{
          // Pre-load the mesh so that we can tweak it with a manual animation
          mesh = MeshManager::getSingleton().load(meshFile, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
          //we'll read through this list while loading
          PoseList poseList = mesh->getPoseList();
          //used to loop through each submesh
          int numSubMeshes = mesh->getNumSubMeshes();
          int curPoseIndex = 0;
          //create the animation on the mesh
          Animation* anim = mesh->createAnimation(poseAnimationStateName, 0);
          //skip submesh 0 since it is the shared geometry, and we have no poses on that
          for(int curSubMesh = 1; curSubMesh <= numSubMeshes; curSubMesh++){      
             //create the VertexTrack on this animation
             Ogre::VertexAnimationTrack *vt = anim->createVertexTrack(curSubMesh, VAT_POSE);
             //create the keyframe we will use to update this vertex track
             //keep all our keyframes in a map for later updating
             vertexPoseKeyFrameMap[curSubMesh] = vt->createVertexPoseKeyFrame(0);
             //add the references to each pose that applies to this subMesh
             while(poseList[curPoseIndex]->getTarget() == curSubMesh-1){
                //create a pose reference for each pose
                vertexPoseKeyFrameMap[curSubMesh]->addPoseReference(curPoseIndex, 0.0f);
                curPoseIndex++;
             }
          }
          //create the head
          head = mSceneMgr->createEntity("Head", meshFile);
          head->getAnimationState(poseAnimationStateName)->setTimePosition(0);
          head->getAnimationState(poseAnimationStateName)->setEnabled(true);
          //put entity in scene
          SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
          headNode->attachObject(head);
       }
       catch(runtime_error err){
          std::string error = "ERROR: ";
          error.append(__FILE__);
          error.append(err.what());
          LogManager::getSingleton().logMessage(error);
       }
    }

Update Code:

/** Goes through all the submeshes and all the poses finding and updating poses with this name*/
    void MeshPoseManager::updatePose(std::string poseName, float weight){   
       //get the pose list
       PoseList poseList = mesh->getPoseList();
       int curPoseIndex = 0;
       //loop through each submesh
       int numSubMeshes = mesh->getNumSubMeshes();
       //skip submesh 0 since it is the shared geometry, and we have no poses on that
       for(int curSubMesh = 1; curSubMesh <= numSubMeshes; curSubMesh++){
          //while the poses apply to the current submesh, check to see if the current pose matches the name, then get the next pose
          while(poseList[curPoseIndex]->getTarget() == curSubMesh-1){
             //get next pose and check if it's the one we want to update
             if(!poseList[curPoseIndex]->getName().compare(poseName)){
                //We found our pose, update it
                vertexPoseKeyFrameMap[curSubMesh]->updatePoseReference(curPoseIndex, weight);
                // Dirty animation state since we're fudging this manually
                //If we don't notify dirty, Ogre doesn't know to update this state
                //and nothing happens
                head->getAnimationState(poseAnimationStateName)->getParent()->_notifyDirty();            
             }
             curPoseIndex++;
             //go to the next pose
          }
          //go to the next submesh
       }   
    }

As you can see, the mesh I was loading was a head, but the solution should generalize to any mesh with poses on its submeshes. Please post here http://www.ogre3d.org/phpBB2/viewtopic.php?t=24587 if you have any troubles with the code above.

Hope this is useful.
-brentrossen