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 <ernest.lee@chibifire.com>
pull/2585/head
Gordon MacPherson 2019-08-07 22:38:33 +01:00
parent 42f07c8bbc
commit 74d2eb842b
5 changed files with 5 additions and 65 deletions

View File

@ -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<size_t>::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&) {

View File

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

View File

@ -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();

View File

@ -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.

View File

@ -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<int> 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());