From 3fbbc3bbd680950a9efaf95e09be009c0e409a06 Mon Sep 17 00:00:00 2001 From: nikitalita <69168929+nikitalita@users.noreply.github.com> Date: Mon, 5 Feb 2024 23:35:16 -0800 Subject: [PATCH] Fix `Skeleton3D` deprecated format missing pose --- scene/3d/skeleton_3d.cpp | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index ee30f60c7223..cae1b2ce9ccc 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -95,17 +95,32 @@ bool Skeleton3D::_set(const StringName &p_path, const Variant &p_value) { } else if (what == "scale") { set_bone_pose_scale(which, p_value); #ifndef DISABLE_DEPRECATED - } else if (what == "pose") { + } else if (what == "pose" || what == "bound_children") { // Kept for compatibility from 3.x to 4.x. WARN_DEPRECATED_MSG("Skeleton uses old pose format, which is deprecated (and loads slower). Consider re-importing or re-saving the scene." + (is_inside_tree() ? vformat(" Path: \"%s\"", get_path()) : String())); - // Old Skeleton poses were relative to rest, new ones are absolute, so we need to recompute the pose. - // Skeleton3D nodes were always written with rest before pose, so this *SHOULD* work... - Transform3D rest = get_bone_rest(which); - Transform3D pose = rest * (Transform3D)p_value; - set_bone_pose_position(which, pose.origin); - set_bone_pose_rotation(which, pose.basis.get_rotation_quaternion()); - set_bone_pose_scale(which, pose.basis.get_scale()); + if (what == "pose") { + // Old Skeleton poses were relative to rest, new ones are absolute, so we need to recompute the pose. + // Skeleton3D nodes were always written with rest before pose, so this *SHOULD* work... + Transform3D rest = get_bone_rest(which); + Transform3D pose = rest * (Transform3D)p_value; + set_bone_pose_position(which, pose.origin); + set_bone_pose_rotation(which, pose.basis.get_rotation_quaternion()); + set_bone_pose_scale(which, pose.basis.get_scale()); + } else { // bound_children + // This handles the case where the pose was set to the rest position; the pose property would == Transform() and would not be saved to the scene by default. + // However, the bound_children property was always saved regardless of value, and it was always saved after both pose and rest. + // We don't do anything else with bound_children, as it's not present on Skeleton3D. + Vector3 pos = get_bone_pose_position(which); + Quaternion rot = get_bone_pose_rotation(which); + Vector3 scale = get_bone_pose_scale(which); + Transform3D rest = get_bone_rest(which); + if (rest != Transform3D() && pos == Vector3() && rot == Quaternion() && scale == Vector3(1, 1, 1)) { + set_bone_pose_position(which, rest.origin); + set_bone_pose_rotation(which, rest.basis.get_rotation_quaternion()); + set_bone_pose_scale(which, rest.basis.get_scale()); + } + } #endif } else { return false;