Skip to content

Commit

Permalink
Keep global rest of unmapped bones if no mapped bone descendants
Browse files Browse the repository at this point in the history
  • Loading branch information
ydeltastar committed May 5, 2024
1 parent 7ebc866 commit 1cfbae3
Showing 1 changed file with 49 additions and 5 deletions.
54 changes: 49 additions & 5 deletions editor/import/3d/post_import_plugin_skeleton_rest_fixer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,52 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
old_skeleton_global_rest.push_back(src_skeleton->get_bone_global_rest(i));
}

// Scan hierarchy and populate a whitelist of unmapped bones without mapped descendants.
Vector<int> keep_unmapped_rest;
{
// Scan descendants for mapped bones.
std::function<bool(int)> has_mapped_desc = [&](int parent_bone) {
Vector<int> bones_to_process = src_skeleton->get_bone_children(parent_bone);
while (bones_to_process.size() > 0) {
int src_idx = bones_to_process[0];
bones_to_process.erase(src_idx);
Vector<int> src_children = src_skeleton->get_bone_children(src_idx);
for (int i = 0; i < src_children.size(); i++) {
bones_to_process.push_back(src_children[i]);
}

StringName src_bone_name = is_renamed ? StringName(src_skeleton->get_bone_name(src_idx)) : bone_map->find_profile_bone_name(src_skeleton->get_bone_name(src_idx));
if (src_bone_name != StringName()) {
if (profile->has_bone(src_bone_name)) {
return true;
}
}
}

return false;
};

// Populate list
Vector<int> bones_to_process = src_skeleton->get_parentless_bones();
while (bones_to_process.size() > 0) {
int src_idx = bones_to_process[0];
bones_to_process.erase(src_idx);
Vector<int> src_children = src_skeleton->get_bone_children(src_idx);
for (int i = 0; i < src_children.size(); i++) {
bones_to_process.push_back(src_children[i]);
}

StringName src_bone_name = is_renamed ? StringName(src_skeleton->get_bone_name(src_idx)) : bone_map->find_profile_bone_name(src_skeleton->get_bone_name(src_idx));
if (src_bone_name != StringName()) {
if (!profile->has_bone(src_bone_name)) {
if (!has_mapped_desc(src_idx)) {
keep_unmapped_rest.push_back(src_idx); // No mapped descendants. Add to whitelist.
}
}
}
}
}

Vector<Basis> diffs;
diffs.resize(src_skeleton->get_bone_count());
Basis *diffs_w = diffs.ptrw();
Expand All @@ -472,13 +518,11 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
int prof_idx = profile->find_bone(src_bone_name);
if (prof_idx >= 0) {
tgt_rot = src_pg.inverse() * prof_skeleton->get_bone_global_rest(prof_idx).basis; // Mapped bone uses reference pose.
}
/*
// If there is rest-relative animation, this logic may be work fine, but currently not so...
} else {
// tgt_rot = src_pg.inverse() * old_skeleton_global_rest[src_idx].basis; // Non-Mapped bone keeps global rest.
if (keep_unmapped_rest.has(src_idx)) {
tgt_rot = src_pg.inverse() * old_skeleton_global_rest[src_idx].basis; // Non-Mapped bone without mapped children keeps global rest.
}
}
*/
}

if (src_skeleton->get_bone_parent(src_idx) >= 0) {
Expand Down

0 comments on commit 1cfbae3

Please sign in to comment.