Skip to content

Commit

Permalink
Merge pull request #2430 from Hugo-Pereira/fix_assimp_export_consistency
Browse files Browse the repository at this point in the history
[FBX Export] fixed ordering of skin indices and weights, to be consistent between systems
  • Loading branch information
kimkulling committed May 4, 2019
2 parents 2f38545 + 34ede56 commit 4a6b9d7
Showing 1 changed file with 14 additions and 3 deletions.
17 changes: 14 additions & 3 deletions code/FBXExporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1575,19 +1575,30 @@ void FBXExporter::WriteObjects ()
// one sticky point is that the number of vertices may not match,
// because assimp splits vertices by normal, uv, etc.

// functor for aiNode sorting
struct SortNodeByName
{
bool operator()(const aiNode *lhs, const aiNode *rhs) const
{
return strcmp(lhs->mName.C_Str(), rhs->mName.C_Str()) < 0;
}
};

// first we should mark the skeleton for each mesh.
// the skeleton must include not only the aiBones,
// but also all their parent nodes.
// anything that affects the position of any bone node must be included.
std::vector<std::set<const aiNode*>> skeleton_by_mesh(mScene->mNumMeshes);
// Use SorNodeByName to make sure the exported result will be the same across all systems
// Otherwise the aiNodes of the skeleton would be sorted based on the pointer address, which isn't consistent
std::vector<std::set<const aiNode*, SortNodeByName>> skeleton_by_mesh(mScene->mNumMeshes);
// at the same time we can build a list of all the skeleton nodes,
// which will be used later to mark them as type "limbNode".
std::unordered_set<const aiNode*> limbnodes;
// and a map of nodes by bone name, as finding them is annoying.
std::map<std::string,aiNode*> node_by_bone;
for (size_t mi = 0; mi < mScene->mNumMeshes; ++mi) {
const aiMesh* m = mScene->mMeshes[mi];
std::set<const aiNode*> skeleton;
std::set<const aiNode*, SortNodeByName> skeleton;
for (size_t bi =0; bi < m->mNumBones; ++bi) {
const aiBone* b = m->mBones[bi];
const std::string name(b->mName.C_Str());
Expand Down Expand Up @@ -1728,7 +1739,7 @@ void FBXExporter::WriteObjects ()
aiMatrix4x4 mesh_xform = get_world_transform(mesh_node, mScene);

// now make a subdeformer for each bone in the skeleton
const std::set<const aiNode*> &skeleton = skeleton_by_mesh[mi];
const std::set<const aiNode*, SortNodeByName> skeleton= skeleton_by_mesh[mi];
for (const aiNode* bone_node : skeleton) {
// if there's a bone for this node, find it
const aiBone* b = nullptr;
Expand Down

0 comments on commit 4a6b9d7

Please sign in to comment.