Selaa lähdekoodia

Issue 1639: Smd mesh vertex bone assignment

bone.mOffsetMatrix not set when bone.iParent == -1
wxyu 6 vuotta sitten
vanhempi
commit
2761681022
2 muutettua tiedostoa jossa 20 lisäystä ja 84 poistoa
  1. 20 77
      code/SMDLoader.cpp
  2. 0 7
      code/SMDLoader.h

+ 20 - 77
code/SMDLoader.cpp

@@ -169,11 +169,11 @@ void SMDImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
 
         // now fix invalid time values and make sure the animation starts at frame 0
         FixTimeValues();
-
-        // compute absolute bone transformation matrices
-    //  ComputeAbsoluteBoneTransformations();
     }
 
+    // build output nodes (bones are added as empty dummy nodes)
+    CreateOutputNodes();
+
     if (!(pScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE))
     {
         // create output meshes
@@ -181,10 +181,13 @@ void SMDImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
 
         // build an output material list
         CreateOutputMaterials();
-    }
 
-    // build output nodes (bones are added as empty dummy nodes)
-    CreateOutputNodes();
+        // use root node that renders all meshes
+        pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
+        pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
+        for (unsigned int i = 0; i < pScene->mNumMeshes; ++i)
+            pScene->mRootNode->mMeshes[i] = i;
+    }
 
     // build the output animation
     CreateOutputAnimations(pFile, pIOHandler);
@@ -397,7 +400,7 @@ void SMDImporter::CreateOutputMeshes()
         for (unsigned int iBone = 0; iBone < asBones.size();++iBone)
             if (!aaiBones[iBone].empty())++iNum;
 
-        if (false && iNum)
+        if (iNum)
         {
             pcMesh->mNumBones = iNum;
             pcMesh->mBones = new aiBone*[pcMesh->mNumBones];
@@ -456,7 +459,14 @@ void SMDImporter::AddBoneChildren(aiNode* pcNode, uint32_t iParent)
         pc->mName.Set(bone.mName);
 
         // store the local transformation matrix of the bind pose
-        pc->mTransformation = bone.sAnim.asKeys[bone.sAnim.iFirstTimeKey].matrix;
+        if (bone.sAnim.asKeys.size())
+            pc->mTransformation = bone.sAnim.asKeys[0].matrix;
+
+        if (bone.iParent == -1)
+            bone.mOffsetMatrix = pc->mTransformation;
+        else
+            bone.mOffsetMatrix = asBones[bone.iParent].mOffsetMatrix * pc->mTransformation;
+
         pc->mParent = pcNode;
 
         // add children to this node, too
@@ -469,17 +479,11 @@ void SMDImporter::AddBoneChildren(aiNode* pcNode, uint32_t iParent)
 void SMDImporter::CreateOutputNodes()
 {
     pScene->mRootNode = new aiNode();
-    if (!(pScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE))
-    {
-        // create one root node that renders all meshes
-        pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
-        pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
-        for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
-            pScene->mRootNode->mMeshes[i] = i;
-    }
 
     // now add all bones as dummy sub nodes to the graph
     AddBoneChildren(pScene->mRootNode,(uint32_t)-1);
+    for (auto &bone : asBones)
+        bone.mOffsetMatrix.Inverse();
 
     // if we have only one bone we can even remove the root node
     if (pScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE &&
@@ -624,67 +628,6 @@ void SMDImporter::GetAnimationFileList(const std::string &pFile, IOSystem* pIOHa
     }
 }
 
-// ------------------------------------------------------------------------------------------------
-void SMDImporter::ComputeAbsoluteBoneTransformations()
-{
-    // For each bone: determine the key with the lowest time value
-    // theoretically the SMD format should have all keyframes
-    // in order. However, I've seen a file where this wasn't true.
-    for (unsigned int i = 0; i < asBones.size();++i)
-    {
-        SMD::Bone& bone = asBones[i];
-
-        uint32_t iIndex = 0;
-        double dMin = 10e10;
-        for (unsigned int i = 0; i < bone.sAnim.asKeys.size();++i)
-        {
-            double d = std::min(bone.sAnim.asKeys[i].dTime,dMin);
-            if (d < dMin)
-            {
-                dMin = d;
-                iIndex = i;
-            }
-        }
-        bone.sAnim.iFirstTimeKey = iIndex;
-    }
-
-    unsigned int iParent = 0;
-    while (iParent < asBones.size())
-    {
-        for (unsigned int iBone = 0; iBone < asBones.size();++iBone)
-        {
-            SMD::Bone& bone = asBones[iBone];
-
-            if (iParent == bone.iParent)
-            {
-                SMD::Bone& parentBone = asBones[iParent];
-
-
-                uint32_t iIndex = bone.sAnim.iFirstTimeKey;
-                const aiMatrix4x4& mat = bone.sAnim.asKeys[iIndex].matrix;
-                aiMatrix4x4& matOut = bone.sAnim.asKeys[iIndex].matrixAbsolute;
-
-                // The same for the parent bone ...
-                iIndex = parentBone.sAnim.iFirstTimeKey;
-                const aiMatrix4x4& mat2 = parentBone.sAnim.asKeys[iIndex].matrixAbsolute;
-
-                // Compute the absolute transformation matrix
-                matOut = mat * mat2;
-            }
-        }
-        ++iParent;
-    }
-
-    // Store the inverse of the absolute transformation matrix
-    // of the first key as bone offset matrix
-    for (iParent = 0; iParent < asBones.size();++iParent)
-    {
-        SMD::Bone& bone = asBones[iParent];
-        bone.mOffsetMatrix = bone.sAnim.asKeys[bone.sAnim.iFirstTimeKey].matrixAbsolute;
-        bone.mOffsetMatrix.Inverse();
-    }
-}
-\
 // ------------------------------------------------------------------------------------------------
 // create output materials
 void SMDImporter::CreateOutputMaterials()

+ 0 - 7
code/SMDLoader.h

@@ -290,13 +290,6 @@ protected:
      */
     unsigned int GetTextureIndex(const std::string& filename);
 
-    // -------------------------------------------------------------------
-    /** Computes absolute bone transformations
-     * All output transformations are in worldspace.
-     */
-    void ComputeAbsoluteBoneTransformations();
-
-
     // -------------------------------------------------------------------
     /** Parse a line in the skeleton section
      */