Browse Source

closes https://github.com/assimp/assimp/issues/2368: add missign anim mesh for multimaterial meshes in fbx,.

Kim Kulling 6 years ago
parent
commit
418c07a9bb
3 changed files with 46 additions and 6 deletions
  1. 2 2
      code/CreateAnimMesh.cpp
  2. 44 0
      code/FBXConverter.cpp
  3. 0 4
      code/FBXParser.cpp

+ 2 - 2
code/CreateAnimMesh.cpp

@@ -47,10 +47,10 @@ namespace Assimp    {
 aiAnimMesh *aiCreateAnimMesh(const aiMesh *mesh)
 {
     aiAnimMesh *animesh = new aiAnimMesh;
-    animesh->mVertices = NULL;
+    /*animesh->mVertices = NULL;
     animesh->mNormals = NULL;
     animesh->mTangents = NULL;
-    animesh->mBitangents = NULL;
+    animesh->mBitangents = NULL;*/
     animesh->mNumVertices = mesh->mNumVertices;
     if (mesh->mVertices) {
         animesh->mVertices = new aiVector3D[animesh->mNumVertices];

+ 44 - 0
code/FBXConverter.cpp

@@ -1385,6 +1385,50 @@ namespace Assimp {
                 ConvertWeights(out_mesh, model, mesh, node_global_transform, index, &reverseMapping);
             }
 
+            std::vector<aiAnimMesh*> animMeshes;
+            size_t bsIdx(0), bsChannelIdx(0);
+            for (const BlendShape* blendShape : mesh.GetBlendShapes()) {
+                for (const BlendShapeChannel* blendShapeChannel : blendShape->BlendShapeChannels()) {
+                    const std::vector<const ShapeGeometry*>& shapeGeometries = blendShapeChannel->GetShapeGeometries();
+                    for (size_t i = 0; i < shapeGeometries.size(); i++) {
+                        aiAnimMesh* animMesh = aiCreateAnimMesh(out_mesh);
+                        const ShapeGeometry* shapeGeometry = shapeGeometries.at(i);
+                        const std::vector<aiVector3D>& vertices = shapeGeometry->GetVertices();
+                        const std::vector<aiVector3D>& normals = shapeGeometry->GetNormals();
+                        const std::vector<unsigned int>& indices = shapeGeometry->GetIndices();
+                        animMesh->mName.Set(FixAnimMeshName(shapeGeometry->Name()));
+                        for (size_t j = 0; j < indices.size(); j++) {
+                            unsigned int index = indices.at(j);
+                            aiVector3D vertex = vertices.at(j);
+                            aiVector3D normal = normals.at(j);
+                            unsigned int count = 0;
+                            const unsigned int* outIndices = mesh.ToOutputVertexIndex(index, count);
+                            for (unsigned int k = 0; k < count; k++) {
+                                unsigned int index = outIndices[k];
+                                animMesh->mVertices[index] += vertex;
+                                if (animMesh->mNormals != nullptr) {
+                                    animMesh->mNormals[index] += normal;
+                                    animMesh->mNormals[index].NormalizeSafe();
+                                }
+                            }
+                        }
+                        animMesh->mWeight = shapeGeometries.size() > 1 ? blendShapeChannel->DeformPercent() / 100.0f : 1.0f;
+                        animMeshes.push_back(animMesh);
+                    }
+                    bsChannelIdx++;
+                }
+                bsIdx++;
+            }
+
+            const size_t numAnimMeshes = animMeshes.size();
+            if (numAnimMeshes > 0) {
+                out_mesh->mNumAnimMeshes = static_cast<unsigned int>(numAnimMeshes);
+                out_mesh->mAnimMeshes = new aiAnimMesh * [numAnimMeshes];
+                for (size_t i = 0; i < numAnimMeshes; i++) {
+                    out_mesh->mAnimMeshes[i] = animMeshes.at(i);
+                }
+            }
+
             return static_cast<unsigned int>(meshes.size() - 1);
         }
 

+ 0 - 4
code/FBXParser.cpp

@@ -963,7 +963,6 @@ void ParseVectorDataArray(std::vector<float>& out, const Element& el)
     }
 }
 
-
 // ------------------------------------------------------------------------------------------------
 // read an array of uints
 void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el)
@@ -1280,7 +1279,6 @@ float ParseTokenAsFloat(const Token& t)
     return i;
 }
 
-
 // ------------------------------------------------------------------------------------------------
 // wrapper around ParseTokenAsInt() with ParseError handling
 int ParseTokenAsInt(const Token& t)
@@ -1293,8 +1291,6 @@ int ParseTokenAsInt(const Token& t)
     return i;
 }
 
-
-
 // ------------------------------------------------------------------------------------------------
 // wrapper around ParseTokenAsInt64() with ParseError handling
 int64_t ParseTokenAsInt64(const Token& t)