Răsfoiți Sursa

Merge pull request #2585 from RevoluPowered/feature/fix-armature-and-root-node

FBX importer armature fixes and root bone fixes - animations should now work for more models.
Kim Kulling 6 ani în urmă
părinte
comite
1097f47ff5

+ 2 - 12
code/FBX/FBXConverter.cpp

@@ -90,7 +90,6 @@ namespace Assimp {
         , anim_fps()
         , anim_fps()
         , out(out)
         , out(out)
         , doc(doc)
         , doc(doc)
-        , mRemoveEmptyBones( removeEmptyBones )
         , mCurrentUnit(FbxUnit::cm) {
         , mCurrentUnit(FbxUnit::cm) {
             // animations need to be converted first since this will
             // animations need to be converted first since this will
             // populate the node_anim_chain_bits map, which is needed
             // populate the node_anim_chain_bits map, which is needed
@@ -1462,14 +1461,8 @@ namespace Assimp {
 
 
                     const WeightIndexArray& indices = cluster->GetIndices();
                     const WeightIndexArray& indices = cluster->GetIndices();
 
 
-                    if (indices.empty() && mRemoveEmptyBones ) {
-                        continue;
-                    }
-
                     const MatIndexArray& mats = geo.GetMaterialIndices();
                     const MatIndexArray& mats = geo.GetMaterialIndices();
 
 
-                    bool ok = false;
-
                     const size_t no_index_sentinel = std::numeric_limits<size_t>::max();
                     const size_t no_index_sentinel = std::numeric_limits<size_t>::max();
 
 
                     count_out_indices.clear();
                     count_out_indices.clear();
@@ -1509,8 +1502,7 @@ namespace Assimp {
                                     out_indices.push_back(std::distance(outputVertStartIndices->begin(), it));
                                     out_indices.push_back(std::distance(outputVertStartIndices->begin(), it));
                                 }
                                 }
 
 
-                                ++count_out_indices.back();
-                                ok = true;
+                                ++count_out_indices.back();                               
                             }
                             }
                         }
                         }
                     }
                     }
@@ -1518,10 +1510,8 @@ namespace Assimp {
                     // if we found at least one, generate the output bones
                     // if we found at least one, generate the output bones
                     // XXX this could be heavily simplified by collecting the bone
                     // XXX this could be heavily simplified by collecting the bone
                     // data in a single step.
                     // data in a single step.
-                    if (ok && mRemoveEmptyBones) {
-                        ConvertCluster(bones, model, *cluster, out_indices, index_out_indices,
+                    ConvertCluster(bones, model, *cluster, out_indices, index_out_indices,
                             count_out_indices, node_global_transform);
                             count_out_indices, node_global_transform);
-                    }
                 }
                 }
             }
             }
             catch (std::exception&) {
             catch (std::exception&) {

+ 0 - 3
code/FBX/FBXConverter.h

@@ -470,9 +470,6 @@ private:
 
 
     aiScene* const out;
     aiScene* const out;
     const FBX::Document& doc;
     const FBX::Document& doc;
-
-    bool mRemoveEmptyBones;
-
     FbxUnit mCurrentUnit;
     FbxUnit mCurrentUnit;
 };
 };
 
 

+ 0 - 8
code/FBX/FBXDocument.cpp

@@ -90,14 +90,6 @@ const Object* LazyObject::Get(bool dieOnError)
         return object.get();
         return object.get();
     }
     }
 
 
-    // if this is the root object, we return a dummy since there
-    // is no root object int he fbx file - it is just referenced
-    // with id 0.
-    if(id == 0L) {
-        object.reset(new Object(id, element, "Model::RootNode"));
-        return object.get();
-    }
-
     const Token& key = element.KeyToken();
     const Token& key = element.KeyToken();
     const TokenList& tokens = element.Tokens();
     const TokenList& tokens = element.Tokens();
 
 

+ 4 - 41
code/FBX/FBXExporter.cpp

@@ -1706,8 +1706,7 @@ void FBXExporter::WriteObjects ()
                     }
                     }
                     if (end) { break; }
                     if (end) { break; }
                 }
                 }
-                limbnodes.insert(parent);
-                skeleton.insert(parent);
+                
                 // if it was the skeleton root we can finish here
                 // if it was the skeleton root we can finish here
                 if (end) { break; }
                 if (end) { break; }
             }
             }
@@ -1848,46 +1847,10 @@ void FBXExporter::WriteObjects ()
             inverse_bone_xform.Inverse();
             inverse_bone_xform.Inverse();
             aiMatrix4x4 tr = inverse_bone_xform * mesh_xform;
             aiMatrix4x4 tr = inverse_bone_xform * mesh_xform;
 
 
-            // this should be the same as the bone's mOffsetMatrix.
-            // if it's not the same, the skeleton isn't in the bind pose.
-            float epsilon = 1e-4f; // some error is to be expected
-            float epsilon_custom = mProperties->GetPropertyFloat("BINDPOSE_EPSILON", -1);
-            if(epsilon_custom > 0) {
-                epsilon = epsilon_custom;
-            }
-            
-            bool bone_xform_okay = true;
-            if (b && ! tr.Equal(b->mOffsetMatrix, epsilon)) {
-                not_in_bind_pose.insert(b);
-                bone_xform_okay = false;
-            }
+            sdnode.AddChild("Transform", tr);
 
 
-            // if we have a bone we should use the mOffsetMatrix,
-            // otherwise try to just use the calculated transform.
-            if (b) {
-                sdnode.AddChild("Transform", b->mOffsetMatrix);
-            } else {
-                sdnode.AddChild("Transform", tr);
-            }
-            // note: it doesn't matter if we mix these,
-            // because if they disagree we'll throw an exception later.
-            // it could be that the skeleton is not in the bone pose
-            // but all bones are still defined,
-            // in which case this would use the mOffsetMatrix for everything
-            // and a correct skeleton would still be output.
-
-            // transformlink should be the position of the bone in world space.
-            // if the bone is in the bind pose (or nonexistent),
-            // we can just use the matrix we already calculated
-            if (bone_xform_okay) {
-                sdnode.AddChild("TransformLink", bone_xform);
-            // otherwise we can only work it out using the mesh position.
-            } else {
-                aiMatrix4x4 trl = b->mOffsetMatrix;
-                trl.Inverse();
-                trl *= mesh_xform;
-                sdnode.AddChild("TransformLink", trl);
-            }
+
+            sdnode.AddChild("TransformLink", bone_xform);
             // note: this means we ALWAYS rely on the mesh node transform
             // note: this means we ALWAYS rely on the mesh node transform
             // being unchanged from the time the skeleton was bound.
             // being unchanged from the time the skeleton was bound.
             // there's not really any way around this at the moment.
             // there's not really any way around this at the moment.

+ 0 - 2
code/FBX/FBXMeshGeometry.cpp

@@ -115,7 +115,6 @@ MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::strin
 
 
     if(tempVerts.empty()) {
     if(tempVerts.empty()) {
         FBXImporter::LogWarn("encountered mesh with no vertices");
         FBXImporter::LogWarn("encountered mesh with no vertices");
-        return;
     }
     }
 
 
     std::vector<int> tempFaces;
     std::vector<int> tempFaces;
@@ -123,7 +122,6 @@ MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::strin
 
 
     if(tempFaces.empty()) {
     if(tempFaces.empty()) {
         FBXImporter::LogWarn("encountered mesh with no faces");
         FBXImporter::LogWarn("encountered mesh with no faces");
-        return;
     }
     }
 
 
     m_vertices.reserve(tempFaces.size());
     m_vertices.reserve(tempFaces.size());