Advertisement
Guest User

Untitled

a guest
Oct 29th, 2011
309
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.33 KB | None | 0 0
  1. typedef map<string, aiMatrix4x4> Pose;
  2. class RiggedModel : public ofxAssimpModelLoader {
  3. protected:
  4.     void updatePose(int which = 0) {
  5.         const aiMesh* mesh = modelMeshes[which].mesh;
  6.         int n = mesh->mNumBones;
  7.         vector<aiMatrix4x4> boneMatrices(n);
  8.         for(int a = 0; a < n; a++) {
  9.             const aiBone* bone = mesh->mBones[a];
  10.             aiNode* node = scene->mRootNode->FindNode(bone->mName);
  11.             boneMatrices[a] = bone->mOffsetMatrix;
  12.             const aiNode* tempNode = node;
  13.             while(tempNode) {
  14.                 boneMatrices[a] = tempNode->mTransformation * boneMatrices[a];
  15.                 tempNode = tempNode->mParent;
  16.             }
  17.             modelMeshes[which].hasChanged = true;
  18.             modelMeshes[which].validCache = false;
  19.         }
  20.        
  21.         modelMeshes[which].animatedPos.assign(modelMeshes[which].animatedPos.size(),0);
  22.         if(mesh->HasNormals()){
  23.             modelMeshes[which].animatedNorm.assign(modelMeshes[which].animatedNorm.size(),0);
  24.         }
  25.        
  26.         // loop through all vertex weights of all bones
  27.         for(int a = 0; a < n; a++) {
  28.             const aiBone* bone = mesh->mBones[a];
  29.             const aiMatrix4x4& posTrafo = boneMatrices[a];
  30.             for( size_t b = 0; b < bone->mNumWeights; b++) {
  31.                 const aiVertexWeight& weight = bone->mWeights[b];
  32.                 size_t vertexId = weight.mVertexId;
  33.                 const aiVector3D& srcPos = mesh->mVertices[vertexId];
  34.                 modelMeshes[which].animatedPos[vertexId] += weight.mWeight * (posTrafo * srcPos);
  35.             }
  36.             if(mesh->HasNormals()) {
  37.                 // 3x3 matrix, contains the bone matrix without the translation, only with rotation and possibly scaling
  38.                 aiMatrix3x3 normTrafo = aiMatrix3x3( posTrafo);
  39.                 for( size_t b = 0; b < bone->mNumWeights; b++) {
  40.                     const aiVertexWeight& weight = bone->mWeights[b];
  41.                     size_t vertexId = weight.mVertexId;
  42.                     const aiVector3D& srcNorm = mesh->mNormals[vertexId];
  43.                     modelMeshes[which].animatedNorm[vertexId] += weight.mWeight * (normTrafo * srcNorm);
  44.                 }
  45.             }
  46.         }
  47.     }
  48. public:
  49.     Pose getPose(int which = 0) {
  50.         const aiMesh* mesh = modelMeshes[which].mesh;  
  51.         int n = mesh->mNumBones;
  52.         Pose pose;
  53.         for(int a = 0; a < n; a++) {
  54.             const aiBone* bone = mesh->mBones[a];
  55.             aiNode* node = scene->mRootNode->FindNode(bone->mName);
  56.             pose[node->mName.data] = node->mTransformation;
  57.         }
  58.         return pose;
  59.     }
  60.     void setPose(Pose& pose, int which = 0) {
  61.         // load the pose
  62.         for(Pose::iterator i = pose.begin(); i != pose.end(); i++) {
  63.             const string& name = i->first;
  64.             const aiMatrix4x4& mat = i->second;
  65.             scene->mRootNode->FindNode(name)->mTransformation = mat;
  66.         }
  67.         updatePose(which);
  68.         updateGLResources();
  69.     }
  70.     void updateAnimation(unsigned int animationIndex, float currentTime) {
  71.         const aiAnimation* mAnim = scene->mAnimations[animationIndex];
  72.        
  73.         // calculate the transformations for each animation channel
  74.         for( unsigned int a = 0; a < mAnim->mNumChannels; a++)
  75.         {
  76.             const aiNodeAnim* channel = mAnim->mChannels[a];
  77.            
  78.             aiNode* targetNode = scene->mRootNode->FindNode(channel->mNodeName);
  79.            
  80.             // ******** Position *****
  81.             aiVector3D presentPosition( 0, 0, 0);
  82.             if( channel->mNumPositionKeys > 0)
  83.             {
  84.                 // Look for present frame number. Search from last position if time is after the last time, else from beginning
  85.                 // Should be much quicker than always looking from start for the average use case.
  86.                 unsigned int frame = 0;// (currentTime >= lastAnimationTime) ? lastFramePositionIndex : 0;
  87.                 while( frame < channel->mNumPositionKeys - 1)
  88.                 {
  89.                     if( currentTime < channel->mPositionKeys[frame+1].mTime)
  90.                         break;
  91.                     frame++;
  92.                 }
  93.                
  94.                 // interpolate between this frame's value and next frame's value
  95.                 unsigned int nextFrame = (frame + 1) % channel->mNumPositionKeys;
  96.                 const aiVectorKey& key = channel->mPositionKeys[frame];
  97.                 const aiVectorKey& nextKey = channel->mPositionKeys[nextFrame];
  98.                 double diffTime = nextKey.mTime - key.mTime;
  99.                 if( diffTime < 0.0)
  100.                     diffTime += mAnim->mDuration;
  101.                 if( diffTime > 0)
  102.                 {
  103.                     float factor = float( (currentTime - key.mTime) / diffTime);
  104.                     presentPosition = key.mValue + (nextKey.mValue - key.mValue) * factor;
  105.                 } else
  106.                 {
  107.                     presentPosition = key.mValue;
  108.                 }
  109.             }
  110.            
  111.             // ******** Rotation *********
  112.             aiQuaternion presentRotation( 1, 0, 0, 0);
  113.             if( channel->mNumRotationKeys > 0)
  114.             {
  115.                 unsigned int frame = 0;//(currentTime >= lastAnimationTime) ? lastFrameRotationIndex : 0;
  116.                 while( frame < channel->mNumRotationKeys - 1)
  117.                 {
  118.                     if( currentTime < channel->mRotationKeys[frame+1].mTime)
  119.                         break;
  120.                     frame++;
  121.                 }
  122.                
  123.                 // interpolate between this frame's value and next frame's value
  124.                 unsigned int nextFrame = (frame + 1) % channel->mNumRotationKeys;
  125.                 const aiQuatKey& key = channel->mRotationKeys[frame];
  126.                 const aiQuatKey& nextKey = channel->mRotationKeys[nextFrame];
  127.                 double diffTime = nextKey.mTime - key.mTime;
  128.                 if( diffTime < 0.0)
  129.                     diffTime += mAnim->mDuration;
  130.                 if( diffTime > 0)
  131.                 {
  132.                     float factor = float( (currentTime - key.mTime) / diffTime);
  133.                     aiQuaternion::Interpolate( presentRotation, key.mValue, nextKey.mValue, factor);
  134.                 } else
  135.                 {
  136.                     presentRotation = key.mValue;
  137.                 }
  138.             }
  139.            
  140.             // ******** Scaling **********
  141.             aiVector3D presentScaling( 1, 1, 1);
  142.             if( channel->mNumScalingKeys > 0)
  143.             {
  144.                 unsigned int frame = 0;//(currentTime >= lastAnimationTime) ? lastFrameScaleIndex : 0;
  145.                 while( frame < channel->mNumScalingKeys - 1)
  146.                 {
  147.                     if( currentTime < channel->mScalingKeys[frame+1].mTime)
  148.                         break;
  149.                     frame++;
  150.                 }
  151.                
  152.                 // TODO: (thom) interpolation maybe? This time maybe even logarithmic, not linear
  153.                 presentScaling = channel->mScalingKeys[frame].mValue;
  154.             }
  155.            
  156.             // build a transformation matrix from it
  157.             //aiMatrix4x4& mat;// = mTransforms[a];
  158.             aiMatrix4x4 mat = aiMatrix4x4( presentRotation.GetMatrix());
  159.             mat.a1 *= presentScaling.x; mat.b1 *= presentScaling.x; mat.c1 *= presentScaling.x;
  160.             mat.a2 *= presentScaling.y; mat.b2 *= presentScaling.y; mat.c2 *= presentScaling.y;
  161.             mat.a3 *= presentScaling.z; mat.b3 *= presentScaling.z; mat.c3 *= presentScaling.z;
  162.             mat.a4 = presentPosition.x; mat.b4 = presentPosition.y; mat.c4 = presentPosition.z;
  163.             //mat.Transpose();
  164.            
  165.             targetNode->mTransformation = mat;
  166.            
  167.         }
  168.        
  169.         lastAnimationTime = currentTime;
  170.        
  171.         // update mesh position for the animation
  172.         for (unsigned int i = 0; i < modelMeshes.size(); ++i){
  173.             updatePose(i);
  174.         }
  175.     }
  176. };
  177.  
  178.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement