summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--editor/import/post_import_plugin_skeleton_rest_fixer.cpp82
1 files changed, 35 insertions, 47 deletions
diff --git a/editor/import/post_import_plugin_skeleton_rest_fixer.cpp b/editor/import/post_import_plugin_skeleton_rest_fixer.cpp
index 6214a2b70d..82d9cfc274 100644
--- a/editor/import/post_import_plugin_skeleton_rest_fixer.cpp
+++ b/editor/import/post_import_plugin_skeleton_rest_fixer.cpp
@@ -31,6 +31,7 @@
#include "post_import_plugin_skeleton_rest_fixer.h"
#include "editor/import/scene_import_settings.h"
+#include "scene/3d/bone_attachment_3d.h"
#include "scene/3d/importer_mesh_instance_3d.h"
#include "scene/3d/skeleton_3d.h"
#include "scene/animation/animation_player.h"
@@ -105,42 +106,6 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
global_transform.origin = Vector3(); // Translation by a Node is not a bone animation, so the retargeted model should be at the origin.
}
- // Calc IBM difference.
- LocalVector<Vector<Transform3D>> ibm_diffs;
- {
- TypedArray<Node> nodes = p_base_scene->find_children("*", "ImporterMeshInstance3D");
- while (nodes.size()) {
- ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(nodes.pop_back());
- ERR_CONTINUE(!mi);
-
- Ref<Skin> skin = mi->get_skin();
- ERR_CONTINUE(!skin.is_valid());
-
- Node *node = mi->get_node(mi->get_skeleton_path());
- ERR_CONTINUE(!node);
-
- Skeleton3D *mesh_skeleton = Object::cast_to<Skeleton3D>(node);
- if (!mesh_skeleton || mesh_skeleton != src_skeleton) {
- continue;
- }
-
- Vector<Transform3D> ibm_diff;
- ibm_diff.resize(src_skeleton->get_bone_count());
- Transform3D *ibm_diff_w = ibm_diff.ptrw();
-
- int skin_len = skin->get_bind_count();
- for (int i = 0; i < skin_len; i++) {
- StringName bn = skin->get_bind_name(i);
- int bone_idx = src_skeleton->find_bone(bn);
- if (bone_idx >= 0) {
- ibm_diff_w[bone_idx] = global_transform * src_skeleton->get_bone_global_rest(bone_idx) * skin->get_bind_pose(i);
- }
- }
-
- ibm_diffs.push_back(ibm_diff);
- }
- }
-
// Apply node transforms.
if (bool(p_options["retarget/rest_fixer/apply_node_transforms"])) {
Vector3 scl = global_transform.basis.get_scale_local();
@@ -288,12 +253,11 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
Vector<Transform3D> silhouette_diff; // Transform values to be ignored when overwrite axis.
silhouette_diff.resize(src_skeleton->get_bone_count());
Transform3D *silhouette_diff_w = silhouette_diff.ptrw();
+ LocalVector<Transform3D> pre_silhouette_skeleton_global_rest;
+ for (int i = 0; i < src_skeleton->get_bone_count(); i++) {
+ pre_silhouette_skeleton_global_rest.push_back(src_skeleton->get_bone_global_rest(i));
+ }
if (bool(p_options["retarget/rest_fixer/fix_silhouette/enable"])) {
- LocalVector<Transform3D> old_skeleton_global_rest;
- for (int i = 0; i < src_skeleton->get_bone_count(); i++) {
- old_skeleton_global_rest.push_back(src_skeleton->get_bone_global_rest(i));
- }
-
Vector<int> bones_to_process = prof_skeleton->get_parentless_bones();
while (bones_to_process.size() > 0) {
int prof_idx = bones_to_process[0];
@@ -450,7 +414,7 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
// For skin modification in overwrite rest.
for (int i = 0; i < src_skeleton->get_bone_count(); i++) {
- silhouette_diff_w[i] = old_skeleton_global_rest[i] * src_skeleton->get_bone_global_rest(i).inverse();
+ silhouette_diff_w[i] = pre_silhouette_skeleton_global_rest[i] * src_skeleton->get_bone_global_rest(i).affine_inverse();
}
is_rest_changed = true;
@@ -652,7 +616,9 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
ERR_CONTINUE(!mi);
Ref<Skin> skin = mi->get_skin();
- ERR_CONTINUE(!skin.is_valid());
+ if (skin.is_null()) {
+ continue;
+ }
Node *node = mi->get_node(mi->get_skeleton_path());
ERR_CONTINUE(!node);
@@ -662,20 +628,42 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
continue;
}
- Vector<Transform3D> ibm_diff = ibm_diffs[skin_idx];
-
int skin_len = skin->get_bind_count();
for (int i = 0; i < skin_len; i++) {
StringName bn = skin->get_bind_name(i);
int bone_idx = src_skeleton->find_bone(bn);
if (bone_idx >= 0) {
- Transform3D new_rest = silhouette_diff[bone_idx] * src_skeleton->get_bone_global_rest(bone_idx);
- skin->set_bind_pose(i, new_rest.inverse() * ibm_diff[bone_idx]);
+ Transform3D adjust_transform = src_skeleton->get_bone_global_rest(bone_idx).affine_inverse() * silhouette_diff[bone_idx].affine_inverse() * pre_silhouette_skeleton_global_rest[bone_idx];
+ adjust_transform.scale(global_transform.basis.get_scale_local());
+ skin->set_bind_pose(i, adjust_transform * skin->get_bind_pose(i));
}
}
skin_idx++;
}
+ nodes = src_skeleton->get_children();
+ while (nodes.size()) {
+ BoneAttachment3D *attachment = Object::cast_to<BoneAttachment3D>(nodes.pop_back());
+ if (attachment == nullptr) {
+ continue;
+ }
+ int bone_idx = attachment->get_bone_idx();
+ if (bone_idx == -1) {
+ bone_idx = src_skeleton->find_bone(attachment->get_bone_name());
+ }
+ ERR_CONTINUE(bone_idx < 0 || bone_idx >= src_skeleton->get_bone_count());
+ Transform3D adjust_transform = src_skeleton->get_bone_global_rest(bone_idx).affine_inverse() * silhouette_diff[bone_idx].affine_inverse() * pre_silhouette_skeleton_global_rest[bone_idx];
+ adjust_transform.scale(global_transform.basis.get_scale_local());
+
+ TypedArray<Node> child_nodes = attachment->get_children();
+ while (child_nodes.size()) {
+ Node3D *child = Object::cast_to<Node3D>(child_nodes.pop_back());
+ if (child == nullptr) {
+ continue;
+ }
+ child->set_transform(adjust_transform * child->get_transform());
+ }
+ }
}
// Init skeleton pose to new rest.