mirror of
https://github.com/godotengine/godot.git
synced 2024-11-27 09:16:35 +08:00
Add rest fixer toggle to disable bone pose reset
Adds a "Reset All Bone Poses After Import" option to the Skeleton3D Rest Fixer settings. Default value of true resets the bone poses to rest (usually a t-pose), matching previous behavior. If disabled, keeps the bones posed as they would have been before silhouette adjustment.
This commit is contained in:
parent
2e7fc81315
commit
6a6bd2307c
@ -42,6 +42,7 @@ void PostImportPluginSkeletonRestFixer::get_internal_import_options(InternalImpo
|
||||
r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/apply_node_transforms"), true));
|
||||
r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/normalize_position_tracks"), true));
|
||||
r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/overwrite_axis"), true));
|
||||
r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/reset_all_bone_poses_after_import"), true));
|
||||
r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/fix_silhouette/enable"), false));
|
||||
// TODO: PostImportPlugin need to be implemented such as validate_option(PropertyInfo &property, const Dictionary &p_options).
|
||||
// get_internal_option_visibility() is not sufficient because it can only retrieve options implemented in the core and can only read option values.
|
||||
@ -113,6 +114,10 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
|
||||
Vector<int> bones_to_process = src_skeleton->get_parentless_bones();
|
||||
for (int i = 0; i < bones_to_process.size(); i++) {
|
||||
src_skeleton->set_bone_rest(bones_to_process[i], global_transform.orthonormalized() * src_skeleton->get_bone_rest(bones_to_process[i]));
|
||||
|
||||
src_skeleton->set_bone_pose_position(bones_to_process[i], global_transform.orthonormalized().xform(src_skeleton->get_bone_pose_position(bones_to_process[i])));
|
||||
src_skeleton->set_bone_pose_rotation(bones_to_process[i], global_transform.basis.get_rotation_quaternion() * src_skeleton->get_bone_pose_rotation(bones_to_process[i]));
|
||||
src_skeleton->set_bone_pose_scale(bones_to_process[i], (global_transform.orthonormalized().basis * Basis().scaled(src_skeleton->get_bone_pose_scale((bones_to_process[i])))).get_scale());
|
||||
}
|
||||
|
||||
while (bones_to_process.size() > 0) {
|
||||
@ -123,6 +128,7 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
|
||||
bones_to_process.push_back(src_children[i]);
|
||||
}
|
||||
src_skeleton->set_bone_rest(src_idx, Transform3D(src_skeleton->get_bone_rest(src_idx).basis, src_skeleton->get_bone_rest(src_idx).origin * scl));
|
||||
src_skeleton->set_bone_pose_position(src_idx, src_skeleton->get_bone_pose_position(src_idx) * scl);
|
||||
}
|
||||
|
||||
// Fix animation.
|
||||
@ -603,6 +609,30 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p_options.has("retarget/rest_fixer/reset_all_bone_poses_after_import") && !bool(p_options["retarget/rest_fixer/reset_all_bone_poses_after_import"])) {
|
||||
// If Reset All Bone Poses After Import is disabled, preserve the original bone pose, adjusted for the new bone rolls.
|
||||
for (int bone_idx = 0; bone_idx < src_skeleton->get_bone_count(); bone_idx++) {
|
||||
Transform3D old_rest = old_skeleton_rest[bone_idx];
|
||||
Transform3D new_rest = src_skeleton->get_bone_rest(bone_idx);
|
||||
Transform3D old_pg;
|
||||
Transform3D new_pg;
|
||||
int parent_idx = src_skeleton->get_bone_parent(bone_idx);
|
||||
if (parent_idx >= 0) {
|
||||
old_pg = old_skeleton_global_rest[parent_idx];
|
||||
new_pg = src_skeleton->get_bone_global_rest(parent_idx);
|
||||
}
|
||||
|
||||
Quaternion old_pg_q = old_pg.basis.get_rotation_quaternion();
|
||||
Quaternion new_pg_q = new_pg.basis.get_rotation_quaternion();
|
||||
Quaternion qt = src_skeleton->get_bone_pose_rotation(bone_idx);
|
||||
src_skeleton->set_bone_pose_rotation(bone_idx, new_pg_q.inverse() * old_pg_q * qt * old_rest.basis.get_rotation_quaternion().inverse() * old_pg_q.inverse() * new_pg_q * new_rest.basis.get_rotation_quaternion());
|
||||
|
||||
Basis sc = Basis().scaled(src_skeleton->get_bone_pose_scale(bone_idx));
|
||||
src_skeleton->set_bone_pose_scale(bone_idx, (new_pg.basis.inverse() * old_pg.basis * sc * old_rest.basis.inverse() * old_pg.basis.inverse() * new_pg.basis * new_rest.basis).get_scale());
|
||||
Vector3 ps = src_skeleton->get_bone_pose_position(bone_idx);
|
||||
src_skeleton->set_bone_pose_position(bone_idx, new_pg_q.xform_inv(old_pg_q.xform(ps - old_rest.origin)) + new_rest.origin);
|
||||
}
|
||||
}
|
||||
|
||||
is_rest_changed = true;
|
||||
}
|
||||
@ -669,12 +699,14 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
|
||||
}
|
||||
}
|
||||
|
||||
// Init skeleton pose to new rest.
|
||||
for (int i = 0; i < src_skeleton->get_bone_count(); i++) {
|
||||
Transform3D fixed_rest = src_skeleton->get_bone_rest(i);
|
||||
src_skeleton->set_bone_pose_position(i, fixed_rest.origin);
|
||||
src_skeleton->set_bone_pose_rotation(i, fixed_rest.basis.get_rotation_quaternion());
|
||||
src_skeleton->set_bone_pose_scale(i, fixed_rest.basis.get_scale());
|
||||
if (!p_options.has("retarget/rest_fixer/reset_all_bone_poses_after_import") || bool(p_options["retarget/rest_fixer/reset_all_bone_poses_after_import"])) {
|
||||
// Init skeleton pose to new rest.
|
||||
for (int i = 0; i < src_skeleton->get_bone_count(); i++) {
|
||||
Transform3D fixed_rest = src_skeleton->get_bone_rest(i);
|
||||
src_skeleton->set_bone_pose_position(i, fixed_rest.origin);
|
||||
src_skeleton->set_bone_pose_rotation(i, fixed_rest.basis.get_rotation_quaternion());
|
||||
src_skeleton->set_bone_pose_scale(i, fixed_rest.basis.get_scale());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user