summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editor/plugins/node_3d_editor_gizmos.cpp12
-rw-r--r--scene/3d/skeleton_3d.cpp22
2 files changed, 19 insertions, 15 deletions
diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp
index d04e88e915..d20f3d105b 100644
--- a/editor/plugins/node_3d_editor_gizmos.cpp
+++ b/editor/plugins/node_3d_editor_gizmos.cpp
@@ -2097,7 +2097,6 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Color bonecolor = Color(1.0, 0.4, 0.4, 0.3);
Color rootcolor = Color(0.4, 1.0, 0.4, 0.1);
- //LocalVector<int> bones_to_process = skel->get_parentless_bones();
LocalVector<int> bones_to_process;
bones_to_process = skel->get_parentless_bones();
@@ -2109,19 +2108,18 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
child_bones_vector = skel->get_bone_children(current_bone_idx);
int child_bones_size = child_bones_vector.size();
- // You have children but no parent, then you must be a root/parentless bone.
- if (child_bones_size >= 0 && skel->get_bone_parent(current_bone_idx) <= 0) {
- grests[current_bone_idx] = skel->global_pose_to_local_pose(current_bone_idx, skel->get_bone_global_pose(current_bone_idx));
+ if (skel->get_bone_parent(current_bone_idx) < 0) {
+ grests[current_bone_idx] = skel->get_bone_rest(current_bone_idx);
}
for (int i = 0; i < child_bones_size; i++) {
int child_bone_idx = child_bones_vector[i];
- grests[child_bone_idx] = skel->global_pose_to_local_pose(child_bone_idx, skel->get_bone_global_pose(child_bone_idx));
+ grests[child_bone_idx] = grests[current_bone_idx] * skel->get_bone_rest(child_bone_idx);
Vector3 v0 = grests[current_bone_idx].origin;
Vector3 v1 = grests[child_bone_idx].origin;
- Vector3 d = skel->get_bone_rest(child_bone_idx).origin.normalized();
- real_t dist = skel->get_bone_rest(child_bone_idx).origin.length();
+ Vector3 d = (v1 - v0).normalized();
+ real_t dist = v0.distance_to(v1);
// Find closest axis.
int closest = -1;
diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp
index 94fb49ae81..0f5de621ea 100644
--- a/scene/3d/skeleton_3d.cpp
+++ b/scene/3d/skeleton_3d.cpp
@@ -896,19 +896,25 @@ Ref<SkinReference> Skeleton3D::register_skin(const Ref<Skin> &p_skin) {
int len = bones.size();
// calculate global rests and invert them
- Vector<int> bones_to_process = get_parentless_bones();
+ LocalVector<int> bones_to_process;
+ bones_to_process = get_parentless_bones();
while (bones_to_process.size() > 0) {
int current_bone_idx = bones_to_process[0];
- bones_to_process.erase(current_bone_idx);
const Bone &b = bonesptr[current_bone_idx];
-
- // Note: the code below may not work by default. May need to track an integer for the bone pose index order
- // in the while loop, instead of using current_bone_idx.
- if (b.parent >= 0) {
- skin->set_bind_pose(current_bone_idx, skin->get_bind_pose(b.parent) * b.rest);
- } else {
+ bones_to_process.erase(current_bone_idx);
+ LocalVector<int> child_bones_vector;
+ child_bones_vector = get_bone_children(current_bone_idx);
+ int child_bones_size = child_bones_vector.size();
+ if (b.parent < 0) {
skin->set_bind_pose(current_bone_idx, b.rest);
}
+ for (int i = 0; i < child_bones_size; i++) {
+ int child_bone_idx = child_bones_vector[i];
+ const Bone &cb = bonesptr[child_bone_idx];
+ skin->set_bind_pose(child_bone_idx, skin->get_bind_pose(current_bone_idx) * cb.rest);
+ // Add the bone's children to the list of bones to be processed.
+ bones_to_process.push_back(child_bones_vector[i]);
+ }
}
for (int i = 0; i < len; i++) {