Skip to content

Commit

Permalink
Merge pull request #2585 from RevoluPowered/feature/fix-armature-and-…
Browse files Browse the repository at this point in the history
…root-node

FBX importer armature fixes and root bone fixes - animations should now work for more models.
  • Loading branch information
kimkulling committed Aug 8, 2019
2 parents 42f07c8 + 74d2eb8 commit 1097f47
Show file tree
Hide file tree
Showing 5 changed files with 6 additions and 66 deletions.
14 changes: 2 additions & 12 deletions code/FBX/FBXConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -1509,19 +1502,16 @@ namespace Assimp {
out_indices.push_back(std::distance(outputVertStartIndices->begin(), it));
}

++count_out_indices.back();
ok = true;
++count_out_indices.back();
}
}
}

// 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&) {
Expand Down
3 changes: 0 additions & 3 deletions code/FBX/FBXConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -470,9 +470,6 @@ class FBXConverter {

aiScene* const out;
const FBX::Document& doc;

bool mRemoveEmptyBones;

FbxUnit mCurrentUnit;
};

Expand Down
8 changes: 0 additions & 8 deletions code/FBX/FBXDocument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
45 changes: 4 additions & 41 deletions code/FBX/FBXExporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
}
Expand Down Expand Up @@ -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.
Expand Down
2 changes: 0 additions & 2 deletions code/FBX/FBXMeshGeometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,13 @@ 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;
ParseVectorDataArray(tempFaces,PolygonVertexIndex);

if(tempFaces.empty()) {
FBXImporter::LogWarn("encountered mesh with no faces");
return;
}

m_vertices.reserve(tempFaces.size());
Expand Down

0 comments on commit 1097f47

Please sign in to comment.