Sfoglia il codice sorgente

Merge pull request #88821 from lyuma/preserve_initial_pose

Allow preserving the initial bone pose in rest fixer
Rémi Verschelde 1 anno fa
parent
commit
04e16a27cf

+ 38 - 6
editor/import/3d/post_import_plugin_skeleton_rest_fixer.cpp

@@ -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/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/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/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));
 		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).
 		// 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.
 		// 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();
 			Vector<int> bones_to_process = src_skeleton->get_parentless_bones();
 			for (int i = 0; i < bones_to_process.size(); i++) {
 			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_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) {
 			while (bones_to_process.size() > 0) {
@@ -123,6 +128,7 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
 					bones_to_process.push_back(src_children[i]);
 					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_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.
 			// 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;
 			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());
+				}
 			}
 			}
 		}
 		}