From 74d2eb842beae502537434a4b6cafe3cec30db62 Mon Sep 17 00:00:00 2001 From: Gordon MacPherson Date: Wed, 7 Aug 2019 22:38:33 +0100 Subject: [PATCH] Fixed armature being marked as 'limbnode' This also fixes issue with root bone overwritten - which should not happen as it is a hack. Before the behaviour would create an additional bone which would end up breaking animations completely on import. Additionally this fixes required bones being removed. Co-authored-by: K. S. Ernest (iFire) Lee --- code/FBX/FBXConverter.cpp | 14 ++---------- code/FBX/FBXConverter.h | 3 --- code/FBX/FBXDocument.cpp | 8 ------- code/FBX/FBXExporter.cpp | 43 +++--------------------------------- code/FBX/FBXMeshGeometry.cpp | 2 -- 5 files changed, 5 insertions(+), 65 deletions(-) diff --git a/code/FBX/FBXConverter.cpp b/code/FBX/FBXConverter.cpp index 9f940d322..949ba0532 100644 --- a/code/FBX/FBXConverter.cpp +++ b/code/FBX/FBXConverter.cpp @@ -90,7 +90,6 @@ namespace Assimp { , anim_fps() , out(out) , doc(doc) - , mRemoveEmptyBones( removeEmptyBones ) , mCurrentUnit(FbxUnit::cm) { // animations need to be converted first since this will // populate the node_anim_chain_bits map, which is needed @@ -1462,14 +1461,8 @@ namespace Assimp { const WeightIndexArray& indices = cluster->GetIndices(); - if (indices.empty() && mRemoveEmptyBones ) { - continue; - } - const MatIndexArray& mats = geo.GetMaterialIndices(); - bool ok = false; - const size_t no_index_sentinel = std::numeric_limits::max(); count_out_indices.clear(); @@ -1509,8 +1502,7 @@ namespace Assimp { 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 // XXX this could be heavily simplified by collecting the bone // 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); - } } } catch (std::exception&) { diff --git a/code/FBX/FBXConverter.h b/code/FBX/FBXConverter.h index 17a7bc56b..fb1a87ca6 100644 --- a/code/FBX/FBXConverter.h +++ b/code/FBX/FBXConverter.h @@ -470,9 +470,6 @@ private: aiScene* const out; const FBX::Document& doc; - - bool mRemoveEmptyBones; - FbxUnit mCurrentUnit; }; diff --git a/code/FBX/FBXDocument.cpp b/code/FBX/FBXDocument.cpp index 1af08fe6d..506fd978d 100644 --- a/code/FBX/FBXDocument.cpp +++ b/code/FBX/FBXDocument.cpp @@ -90,14 +90,6 @@ const Object* LazyObject::Get(bool dieOnError) 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 TokenList& tokens = element.Tokens(); diff --git a/code/FBX/FBXExporter.cpp b/code/FBX/FBXExporter.cpp index b73a8f172..8ebc8555a 100644 --- a/code/FBX/FBXExporter.cpp +++ b/code/FBX/FBXExporter.cpp @@ -1706,8 +1706,7 @@ void FBXExporter::WriteObjects () } if (end) { break; } } - limbnodes.insert(parent); - skeleton.insert(parent); + // if it was the skeleton root we can finish here if (end) { break; } } @@ -1848,46 +1847,10 @@ void FBXExporter::WriteObjects () inverse_bone_xform.Inverse(); 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 // being unchanged from the time the skeleton was bound. // there's not really any way around this at the moment. diff --git a/code/FBX/FBXMeshGeometry.cpp b/code/FBX/FBXMeshGeometry.cpp index 44a0264ca..e60fc25e2 100644 --- a/code/FBX/FBXMeshGeometry.cpp +++ b/code/FBX/FBXMeshGeometry.cpp @@ -115,7 +115,6 @@ MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::strin if(tempVerts.empty()) { FBXImporter::LogWarn("encountered mesh with no vertices"); - return; } std::vector tempFaces; @@ -123,7 +122,6 @@ MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::strin if(tempFaces.empty()) { FBXImporter::LogWarn("encountered mesh with no faces"); - return; } m_vertices.reserve(tempFaces.size());