diff --git a/doc/classes/BoneAttachment3D.xml b/doc/classes/BoneAttachment3D.xml
index bb4b45cd487a..f4b6ee0aa53e 100644
--- a/doc/classes/BoneAttachment3D.xml
+++ b/doc/classes/BoneAttachment3D.xml
@@ -16,12 +16,6 @@
Returns the [NodePath] to the external [Skeleton3D] node, if one has been set.
-
-
-
- Returns the override mode for the BoneAttachment3D node.
-
-
@@ -48,13 +42,6 @@
Sets the [NodePath] to the external skeleton that the BoneAttachment3D node should use. The external [Skeleton3D] node is only used when [code]use_external_skeleton[/code] is set to [code]true[/code].
-
-
-
-
- Sets the override mode for the BoneAttachment3D node. The override mode defines which of the bone poses the BoneAttachment3D node will override.
-
-
diff --git a/doc/classes/Skeleton3D.xml b/doc/classes/Skeleton3D.xml
index 80a36acacc92..165fe56b8b38 100644
--- a/doc/classes/Skeleton3D.xml
+++ b/doc/classes/Skeleton3D.xml
@@ -29,22 +29,23 @@
This is useful for using the bone transform in calculations with transforms from [Node3D]-based nodes.
-
+
+
- Clear all the bones in this skeleton.
+ Removes the pose override on the bone at [code]bone_idx[/code].
-
+
- Removes the global pose override on all bones in the skeleton.
+ Removes the pose override on all bones in the skeleton.
-
+
- Removes the local pose override on all bones in the skeleton.
+ Clear all the bones in this skeleton.
@@ -113,13 +114,6 @@
-
-
-
-
- Returns the local pose override transform for [code]bone_idx[/code].
-
-
@@ -142,6 +136,20 @@
Returns the pose transform of the specified bone. Pose is applied on top of the custom pose, which is applied on top the rest pose.
+
+
+
+
+ Returns the pose without override transform for [code]bone_idx[/code].
+
+
+
+
+
+
+ Returns the pose override transform for [code]bone_idx[/code].
+
+
@@ -185,7 +193,7 @@
Takes the passed-in global pose and converts it to local pose transform.
- This can be used to easily convert a global pose from [method get_bone_global_pose] to a global transform in [method set_bone_local_pose_override].
+ This can be used to easily convert a global pose from [method get_bone_global_pose] to a global transform in [method set_bone_pose_override].
@@ -212,6 +220,12 @@
Returns whether the bone pose for the bone at [code]bone_idx[/code] is enabled.
+
+
+
+
+
+
@@ -294,25 +308,11 @@
-
Sets the global pose transform, [code]pose[/code], for the bone at [code]bone_idx[/code].
- [code]amount[/code] is the interpolation strength that will be used when applying the pose, and [code]persistent[/code] determines if the applied pose will remain.
[b]Note:[/b] The pose transform needs to be a global pose! Use [method world_transform_to_global_pose] to convert a world transform, like one you can get from a [Node3D], to a global pose.
-
-
-
-
-
-
-
- Sets the local pose transform, [code]pose[/code], for the bone at [code]bone_idx[/code].
- [code]amount[/code] is the interpolation strength that will be used when applying the pose, and [code]persistent[/code] determines if the applied pose will remain.
- [b]Note:[/b] The pose transform needs to be a local pose! Use [method global_pose_to_local_pose] to convert a global pose to a local pose.
-
-
@@ -329,6 +329,16 @@
[b]Note:[/b] [code]parent_idx[/code] must be less than [code]bone_idx[/code].
+
+
+
+
+
+
+ Sets the local pose transform, [code]pose[/code], for the bone at [code]bone_idx[/code].
+ [b]Note:[/b] The pose transform needs to be a local pose! Use [method global_pose_to_local_pose] to convert a global pose to a local pose.
+
+
diff --git a/editor/plugins/skeleton_ik_3d_editor_plugin.cpp b/editor/plugins/skeleton_ik_3d_editor_plugin.cpp
index 7dc34a0874b8..f0f54993aa98 100644
--- a/editor/plugins/skeleton_ik_3d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_ik_3d_editor_plugin.cpp
@@ -46,7 +46,6 @@ void SkeletonIK3DEditorPlugin::_play() {
skeleton_ik->start();
} else {
skeleton_ik->stop();
- skeleton_ik->get_parent_skeleton()->clear_bones_global_pose_override();
}
}
diff --git a/scene/3d/bone_attachment_3d.cpp b/scene/3d/bone_attachment_3d.cpp
index 8623c7d8b631..03fa3f86e53e 100644
--- a/scene/3d/bone_attachment_3d.cpp
+++ b/scene/3d/bone_attachment_3d.cpp
@@ -65,8 +65,6 @@ void BoneAttachment3D::_validate_property(PropertyInfo &property) const {
bool BoneAttachment3D::_set(const StringName &p_path, const Variant &p_value) {
if (p_path == SNAME("override_pose")) {
set_override_pose(p_value);
- } else if (p_path == SNAME("override_mode")) {
- set_override_mode(p_value);
} else if (p_path == SNAME("use_external_skeleton")) {
set_use_external_skeleton(p_value);
} else if (p_path == SNAME("external_skeleton")) {
@@ -79,8 +77,6 @@ bool BoneAttachment3D::_set(const StringName &p_path, const Variant &p_value) {
bool BoneAttachment3D::_get(const StringName &p_path, Variant &r_ret) const {
if (p_path == SNAME("override_pose")) {
r_ret = get_override_pose();
- } else if (p_path == SNAME("override_mode")) {
- r_ret = get_override_mode();
} else if (p_path == SNAME("use_external_skeleton")) {
r_ret = get_use_external_skeleton();
} else if (p_path == SNAME("external_skeleton")) {
@@ -92,9 +88,6 @@ bool BoneAttachment3D::_get(const StringName &p_path, Variant &r_ret) const {
void BoneAttachment3D::_get_property_list(List *p_list) const {
p_list->push_back(PropertyInfo(Variant::BOOL, "override_pose", PROPERTY_HINT_NONE, ""));
- if (override_pose) {
- p_list->push_back(PropertyInfo(Variant::INT, "override_mode", PROPERTY_HINT_ENUM, "Global Pose Override, Local Pose Override, Custom Pose"));
- }
p_list->push_back(PropertyInfo(Variant::BOOL, "use_external_skeleton", PROPERTY_HINT_NONE, ""));
if (use_external_skeleton) {
@@ -213,11 +206,7 @@ void BoneAttachment3D::_transform_changed() {
our_trans = sk->world_transform_to_global_pose(get_global_transform());
}
- if (override_mode == OVERRIDE_MODES::MODE_GLOBAL_POSE) {
- sk->set_bone_global_pose_override(bone_idx, our_trans, 1.0, true);
- } else if (override_mode == OVERRIDE_MODES::MODE_LOCAL_POSE) {
- sk->set_bone_local_pose_override(bone_idx, sk->global_pose_to_local_pose(bone_idx, our_trans), 1.0, true);
- }
+ sk->set_bone_global_pose_override(bone_idx, our_trans, 1);
}
}
@@ -269,11 +258,7 @@ void BoneAttachment3D::set_override_pose(bool p_override) {
if (!override_pose) {
Skeleton3D *sk = _get_skeleton3d();
if (sk) {
- if (override_mode == OVERRIDE_MODES::MODE_GLOBAL_POSE) {
- sk->set_bone_global_pose_override(bone_idx, Transform3D(), 0.0, false);
- } else if (override_mode == OVERRIDE_MODES::MODE_LOCAL_POSE) {
- sk->set_bone_local_pose_override(bone_idx, Transform3D(), 0.0, false);
- }
+ sk->clear_bone_pose_override(bone_idx);
}
_transform_changed();
}
@@ -284,27 +269,6 @@ bool BoneAttachment3D::get_override_pose() const {
return override_pose;
}
-void BoneAttachment3D::set_override_mode(int p_mode) {
- if (override_pose) {
- Skeleton3D *sk = _get_skeleton3d();
- if (sk) {
- if (override_mode == OVERRIDE_MODES::MODE_GLOBAL_POSE) {
- sk->set_bone_global_pose_override(bone_idx, Transform3D(), 0.0, false);
- } else if (override_mode == OVERRIDE_MODES::MODE_LOCAL_POSE) {
- sk->set_bone_local_pose_override(bone_idx, Transform3D(), 0.0, false);
- }
- }
- override_mode = p_mode;
- _transform_changed();
- return;
- }
- override_mode = p_mode;
-}
-
-int BoneAttachment3D::get_override_mode() const {
- return override_mode;
-}
-
void BoneAttachment3D::set_use_external_skeleton(bool p_use_external) {
use_external_skeleton = p_use_external;
@@ -391,8 +355,6 @@ void BoneAttachment3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_override_pose", "override_pose"), &BoneAttachment3D::set_override_pose);
ClassDB::bind_method(D_METHOD("get_override_pose"), &BoneAttachment3D::get_override_pose);
- ClassDB::bind_method(D_METHOD("set_override_mode", "override_mode"), &BoneAttachment3D::set_override_mode);
- ClassDB::bind_method(D_METHOD("get_override_mode"), &BoneAttachment3D::get_override_mode);
ClassDB::bind_method(D_METHOD("set_use_external_skeleton", "use_external_skeleton"), &BoneAttachment3D::set_use_external_skeleton);
ClassDB::bind_method(D_METHOD("get_use_external_skeleton"), &BoneAttachment3D::get_use_external_skeleton);
diff --git a/scene/3d/bone_attachment_3d.h b/scene/3d/bone_attachment_3d.h
index 395dfde1d707..23a8d9bd6ad7 100644
--- a/scene/3d/bone_attachment_3d.h
+++ b/scene/3d/bone_attachment_3d.h
@@ -41,14 +41,8 @@ class BoneAttachment3D : public Node3D {
int bone_idx = -1;
bool override_pose = false;
- int override_mode = 0;
bool _override_dirty = false;
- enum OVERRIDE_MODES {
- MODE_GLOBAL_POSE,
- MODE_LOCAL_POSE,
- };
-
bool use_external_skeleton = false;
NodePath external_skeleton_node;
ObjectID external_skeleton_node_cache;
@@ -80,8 +74,6 @@ class BoneAttachment3D : public Node3D {
void set_override_pose(bool p_override);
bool get_override_pose() const;
- void set_override_mode(int p_mode);
- int get_override_mode() const;
void set_use_external_skeleton(bool p_external_skeleton);
bool get_use_external_skeleton() const;
diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp
index c1f5ab1d3256..cec0ffa5c67f 100644
--- a/scene/3d/physics_body_3d.cpp
+++ b/scene/3d/physics_body_3d.cpp
@@ -2915,7 +2915,7 @@ void PhysicalBone3D::_body_state_changed(PhysicsDirectBodyState3D *p_state) {
// Update skeleton
if (parent_skeleton) {
if (-1 != bone_id) {
- parent_skeleton->set_bone_global_pose_override(bone_id, parent_skeleton->get_global_transform().affine_inverse() * (global_transform * body_offset_inverse), 1.0, true);
+ parent_skeleton->set_bone_global_pose_override(bone_id, parent_skeleton->get_global_transform().affine_inverse() * (global_transform * body_offset_inverse), 1);
}
}
}
@@ -3429,7 +3429,7 @@ void PhysicalBone3D::_stop_physics_simulation() {
}
if (_internal_simulate_physics) {
PhysicsServer3D::get_singleton()->body_set_state_sync_callback(get_rid(), nullptr, nullptr);
- parent_skeleton->set_bone_global_pose_override(bone_id, Transform3D(), 0.0, false);
+ parent_skeleton->clear_bone_pose_override(bone_id);
set_as_top_level(false);
_internal_simulate_physics = false;
}
diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp
index 598897456dfa..95576ed9f567 100644
--- a/scene/3d/skeleton_3d.cpp
+++ b/scene/3d/skeleton_3d.cpp
@@ -315,7 +315,7 @@ void Skeleton3D::_notification(int p_what) {
for (uint32_t i = 0; i < bind_count; i++) {
uint32_t bone_index = E->get()->skin_bone_indices_ptrs[i];
ERR_CONTINUE(bone_index >= (uint32_t)len);
- rs->skeleton_bone_set_transform(skeleton, i, bonesptr[bone_index].pose_global * skin->get_bind_pose(i));
+ rs->skeleton_bone_set_transform(skeleton, i, bonesptr[bone_index].global_pose_cache * skin->get_bind_pose(i));
}
}
#ifdef TOOLS_ENABLED
@@ -362,67 +362,76 @@ void Skeleton3D::_notification(int p_what) {
}
}
-void Skeleton3D::clear_bones_global_pose_override() {
- for (int i = 0; i < bones.size(); i += 1) {
- bones.write[i].global_pose_override_amount = 0;
- bones.write[i].global_pose_override_reset = true;
+void Skeleton3D::clear_bone_pose_overrides() {
+ const int bone_size = bones.size();
+ for (int i = 0; i < bone_size; i += 1) {
+ bones.write[i].is_override_enabled = false;
+ bones.write[i].pose_override = Transform3D();
+ bones.write[i].pose_cache_dirty = true;
}
_make_dirty();
}
-void Skeleton3D::set_bone_global_pose_override(int p_bone, const Transform3D &p_pose, real_t p_amount, bool p_persistent) {
+void Skeleton3D::clear_bone_pose_override(int p_bone) {
const int bone_size = bones.size();
ERR_FAIL_INDEX(p_bone, bone_size);
- bones.write[p_bone].global_pose_override_amount = p_amount;
- bones.write[p_bone].global_pose_override = p_pose;
- bones.write[p_bone].global_pose_override_reset = !p_persistent;
+ bones.write[p_bone].is_override_enabled = false;
+ bones.write[p_bone].pose_override = Transform3D();
+ bones.write[p_bone].pose_cache_dirty = true;
_make_dirty();
}
-Transform3D Skeleton3D::get_bone_global_pose_override(int p_bone) const {
+bool Skeleton3D::is_bone_pose_overridden(int p_bone) const {
const int bone_size = bones.size();
- ERR_FAIL_INDEX_V(p_bone, bone_size, Transform3D());
- return bones[p_bone].global_pose_override;
+ ERR_FAIL_INDEX_V(p_bone, bone_size, false);
+ return bones[p_bone].is_override_enabled;
}
-Transform3D Skeleton3D::get_bone_global_pose(int p_bone) const {
+Transform3D Skeleton3D::get_bone_pose_override(int p_bone) const {
const int bone_size = bones.size();
ERR_FAIL_INDEX_V(p_bone, bone_size, Transform3D());
- if (dirty) {
- const_cast(this)->notification(NOTIFICATION_UPDATE_SKELETON);
- }
- return bones[p_bone].pose_global;
+ return bones[p_bone].pose_override;
}
-Transform3D Skeleton3D::get_bone_global_pose_no_override(int p_bone) const {
+void Skeleton3D::set_bone_pose_override(int p_bone, const Transform3D &p_pose, float p_amount) {
+ const int bone_size = bones.size();
+ ERR_FAIL_INDEX(p_bone, bone_size);
+ bones.write[p_bone].is_override_enabled = true;
+ bones.write[p_bone].pose_override = get_bone_pose_no_override(p_bone).interpolate_with(p_pose, p_amount);
+ bones.write[p_bone].pose_cache_dirty = true;
+ _make_dirty();
+}
+
+Transform3D Skeleton3D::get_bone_global_pose_override(int p_bone) const {
const int bone_size = bones.size();
ERR_FAIL_INDEX_V(p_bone, bone_size, Transform3D());
if (dirty) {
const_cast(this)->notification(NOTIFICATION_UPDATE_SKELETON);
}
- return bones[p_bone].pose_global_no_override;
+ return const_cast(this)->local_pose_to_global_pose(p_bone, bones[p_bone].pose_override);
}
-void Skeleton3D::clear_bones_local_pose_override() {
- for (int i = 0; i < bones.size(); i += 1) {
- bones.write[i].local_pose_override_amount = 0;
- }
- _make_dirty();
+void Skeleton3D::set_bone_global_pose_override(int p_bone, const Transform3D &p_pose, float p_amount) {
+ Transform3D tr = global_pose_to_local_pose(p_bone, p_pose);
+ set_bone_pose_override(p_bone, tr, p_amount);
}
-void Skeleton3D::set_bone_local_pose_override(int p_bone, const Transform3D &p_pose, real_t p_amount, bool p_persistent) {
+Transform3D Skeleton3D::get_bone_global_pose(int p_bone) const {
const int bone_size = bones.size();
- ERR_FAIL_INDEX(p_bone, bone_size);
- bones.write[p_bone].local_pose_override_amount = p_amount;
- bones.write[p_bone].local_pose_override = p_pose;
- bones.write[p_bone].local_pose_override_reset = !p_persistent;
- _make_dirty();
+ ERR_FAIL_INDEX_V(p_bone, bone_size, Transform3D());
+ if (dirty) {
+ const_cast(this)->notification(NOTIFICATION_UPDATE_SKELETON);
+ }
+ return bones[p_bone].global_pose_cache;
}
-Transform3D Skeleton3D::get_bone_local_pose_override(int p_bone) const {
+Transform3D Skeleton3D::get_bone_global_pose_no_override(int p_bone) const {
const int bone_size = bones.size();
ERR_FAIL_INDEX_V(p_bone, bone_size, Transform3D());
- return bones[p_bone].local_pose_override;
+ if (dirty) {
+ const_cast(this)->notification(NOTIFICATION_UPDATE_SKELETON);
+ }
+ return bones[p_bone].global_pose_no_override;
}
void Skeleton3D::update_bone_rest_forward_vector(int p_bone, bool p_force_update) {
@@ -743,6 +752,12 @@ Transform3D Skeleton3D::get_bone_pose(int p_bone) const {
return bones[p_bone].pose_cache;
}
+Transform3D Skeleton3D::get_bone_pose_no_override(int p_bone) const {
+ const int bone_size = bones.size();
+ ERR_FAIL_INDEX_V(p_bone, bone_size, Transform3D());
+ return bones[p_bone].pose;
+}
+
void Skeleton3D::_make_dirty() {
if (dirty) {
return;
@@ -1041,46 +1056,25 @@ void Skeleton3D::force_update_bone_children_transforms(int p_bone_idx) {
if (bone_enabled) {
b.update_pose_cache();
- Transform3D pose = b.pose_cache;
+ Transform3D current_pose = b.pose_cache;
if (b.parent >= 0) {
- b.pose_global = bonesptr[b.parent].pose_global * pose;
- b.pose_global_no_override = b.pose_global;
+ b.global_pose_cache = bonesptr[b.parent].global_pose_cache * current_pose;
+ b.global_pose_no_override = bonesptr[b.parent].global_pose_no_override * b.pose;
} else {
- b.pose_global = pose;
- b.pose_global_no_override = b.pose_global;
+ b.global_pose_cache = current_pose;
+ b.global_pose_no_override = b.pose;
}
} else {
if (b.parent >= 0) {
- b.pose_global = bonesptr[b.parent].pose_global * b.rest;
- b.pose_global_no_override = b.pose_global;
+ b.global_pose_cache = bonesptr[b.parent].global_pose_cache * b.rest;
+ b.global_pose_no_override = bonesptr[b.parent].global_pose_no_override * b.rest;
} else {
- b.pose_global = b.rest;
- b.pose_global_no_override = b.pose_global;
+ b.global_pose_cache = b.rest;
+ b.global_pose_no_override = b.rest;
}
}
- if (b.local_pose_override_amount >= CMP_EPSILON) {
- Transform3D override_local_pose;
- if (b.parent >= 0) {
- override_local_pose = bonesptr[b.parent].pose_global * b.local_pose_override;
- } else {
- override_local_pose = b.local_pose_override;
- }
- b.pose_global = b.pose_global.interpolate_with(override_local_pose, b.local_pose_override_amount);
- }
-
- if (b.global_pose_override_amount >= CMP_EPSILON) {
- b.pose_global = b.pose_global.interpolate_with(b.global_pose_override, b.global_pose_override_amount);
- }
-
- if (b.local_pose_override_reset) {
- b.local_pose_override_amount = 0.0;
- }
- if (b.global_pose_override_reset) {
- b.global_pose_override_amount = 0.0;
- }
-
// Add the bone's children to the list of bones to be processed.
int child_bone_size = b.child_bones.size();
for (int i = 0; i < child_bone_size; i++) {
@@ -1118,7 +1112,7 @@ Transform3D Skeleton3D::local_pose_to_global_pose(int p_bone_idx, Transform3D p_
ERR_FAIL_INDEX_V(p_bone_idx, bone_size, Transform3D());
if (bones[p_bone_idx].parent >= 0) {
int parent_bone_idx = bones[p_bone_idx].parent;
- return bones[parent_bone_idx].pose_global * p_local_pose;
+ return bones[parent_bone_idx].global_pose_cache * p_local_pose;
} else {
return p_local_pose;
}
@@ -1215,7 +1209,15 @@ void Skeleton3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear_bones"), &Skeleton3D::clear_bones);
+ ClassDB::bind_method(D_METHOD("is_bone_enabled", "bone_idx"), &Skeleton3D::is_bone_enabled);
+ ClassDB::bind_method(D_METHOD("set_bone_enabled", "bone_idx", "enabled"), &Skeleton3D::set_bone_enabled, DEFVAL(true));
+
ClassDB::bind_method(D_METHOD("get_bone_pose", "bone_idx"), &Skeleton3D::get_bone_pose);
+ ClassDB::bind_method(D_METHOD("get_bone_pose_no_override", "bone_idx"), &Skeleton3D::get_bone_pose_no_override);
+
+ ClassDB::bind_method(D_METHOD("get_bone_global_pose", "bone_idx"), &Skeleton3D::get_bone_global_pose);
+ ClassDB::bind_method(D_METHOD("get_bone_global_pose_no_override", "bone_idx"), &Skeleton3D::get_bone_global_pose_no_override);
+
ClassDB::bind_method(D_METHOD("set_bone_pose_position", "bone_idx", "position"), &Skeleton3D::set_bone_pose_position);
ClassDB::bind_method(D_METHOD("set_bone_pose_rotation", "bone_idx", "rotation"), &Skeleton3D::set_bone_pose_rotation);
ClassDB::bind_method(D_METHOD("set_bone_pose_scale", "bone_idx", "scale"), &Skeleton3D::set_bone_pose_scale);
@@ -1224,18 +1226,16 @@ void Skeleton3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_bone_pose_rotation", "bone_idx"), &Skeleton3D::get_bone_pose_rotation);
ClassDB::bind_method(D_METHOD("get_bone_pose_scale", "bone_idx"), &Skeleton3D::get_bone_pose_scale);
- ClassDB::bind_method(D_METHOD("is_bone_enabled", "bone_idx"), &Skeleton3D::is_bone_enabled);
- ClassDB::bind_method(D_METHOD("set_bone_enabled", "bone_idx", "enabled"), &Skeleton3D::set_bone_enabled, DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("clear_bone_pose_overrides"), &Skeleton3D::clear_bone_pose_overrides);
- ClassDB::bind_method(D_METHOD("clear_bones_global_pose_override"), &Skeleton3D::clear_bones_global_pose_override);
- ClassDB::bind_method(D_METHOD("set_bone_global_pose_override", "bone_idx", "pose", "amount", "persistent"), &Skeleton3D::set_bone_global_pose_override, DEFVAL(false));
- ClassDB::bind_method(D_METHOD("get_bone_global_pose_override", "bone_idx"), &Skeleton3D::get_bone_global_pose_override);
- ClassDB::bind_method(D_METHOD("get_bone_global_pose", "bone_idx"), &Skeleton3D::get_bone_global_pose);
- ClassDB::bind_method(D_METHOD("get_bone_global_pose_no_override", "bone_idx"), &Skeleton3D::get_bone_global_pose_no_override);
+ ClassDB::bind_method(D_METHOD("clear_bone_pose_override", "bone_idx"), &Skeleton3D::clear_bone_pose_override);
+ ClassDB::bind_method(D_METHOD("is_bone_pose_overridden", "bone_idx"), &Skeleton3D::is_bone_pose_overridden);
+
+ ClassDB::bind_method(D_METHOD("set_bone_pose_override", "bone_idx", "pose", "amount"), &Skeleton3D::set_bone_pose_override);
+ ClassDB::bind_method(D_METHOD("get_bone_pose_override", "bone_idx"), &Skeleton3D::get_bone_pose_override);
- ClassDB::bind_method(D_METHOD("clear_bones_local_pose_override"), &Skeleton3D::clear_bones_local_pose_override);
- ClassDB::bind_method(D_METHOD("set_bone_local_pose_override", "bone_idx", "pose", "amount", "persistent"), &Skeleton3D::set_bone_local_pose_override, DEFVAL(false));
- ClassDB::bind_method(D_METHOD("get_bone_local_pose_override", "bone_idx"), &Skeleton3D::get_bone_local_pose_override);
+ ClassDB::bind_method(D_METHOD("set_bone_global_pose_override", "bone_idx", "pose", "amount"), &Skeleton3D::set_bone_global_pose_override);
+ ClassDB::bind_method(D_METHOD("get_bone_global_pose_override", "bone_idx"), &Skeleton3D::get_bone_global_pose_override);
ClassDB::bind_method(D_METHOD("force_update_all_bone_transforms"), &Skeleton3D::force_update_all_bone_transforms);
ClassDB::bind_method(D_METHOD("force_update_bone_child_transform", "bone_idx"), &Skeleton3D::force_update_bone_children_transforms);
diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h
index 80ff2a1f79e7..9d187d83e0ee 100644
--- a/scene/3d/skeleton_3d.h
+++ b/scene/3d/skeleton_3d.h
@@ -80,8 +80,13 @@ class Skeleton3D : public Node3D {
_FORCE_INLINE_ void update_pose_cache() {
if (pose_cache_dirty) {
- pose_cache.basis.set_quaternion_scale(pose_rotation, pose_scale);
- pose_cache.origin = pose_position;
+ pose.basis.set_quaternion_scale(pose_rotation, pose_scale);
+ pose.origin = pose_position;
+ if (is_override_enabled) {
+ pose_cache = pose_override;
+ } else {
+ pose_cache = pose;
+ }
pose_cache_dirty = false;
}
}
@@ -91,20 +96,18 @@ class Skeleton3D : public Node3D {
Quaternion pose_rotation;
Vector3 pose_scale = Vector3(1, 1, 1);
- Transform3D pose_global;
- Transform3D pose_global_no_override;
+ Transform3D pose;
+ Transform3D pose_override;
+ bool is_override_enabled = false;
- real_t global_pose_override_amount = 0.0;
- bool global_pose_override_reset = false;
- Transform3D global_pose_override;
+ // The `global_pose` should be used for conversion to local from global coordinates in the setter.
+ // Since `global_pose_cache` is a cache, one shouldn't use `global_pose_cache` for display.
+ Transform3D global_pose_cache;
+ Transform3D global_pose_no_override;
PhysicalBone3D *physical_bone = nullptr;
PhysicalBone3D *cache_parent_physical_bone = nullptr;
- real_t local_pose_override_amount;
- bool local_pose_override_reset;
- Transform3D local_pose_override;
-
Vector child_bones;
// The forward direction vector and rest bone forward axis are cached because they do not change
@@ -115,14 +118,10 @@ class Skeleton3D : public Node3D {
Bone() {
parent = -1;
enabled = true;
- global_pose_override_amount = 0;
- global_pose_override_reset = false;
#ifndef _3D_DISABLED
physical_bone = nullptr;
cache_parent_physical_bone = nullptr;
#endif // _3D_DISABLED
- local_pose_override_amount = 0;
- local_pose_override_reset = false;
child_bones = Vector();
rest_bone_forward_vector = Vector3(0, 0, 0);
@@ -135,10 +134,10 @@ class Skeleton3D : public Node3D {
void _skin_changed();
bool animate_physical_bones = true;
- Vector bones;
bool process_order_dirty;
- Vector parentless_bones;
+ Vector bones = Vector();
+ Vector parentless_bones = Vector();
void _make_dirty();
bool dirty = false;
@@ -175,7 +174,7 @@ class Skeleton3D : public Node3D {
NOTIFICATION_UPDATE_SKELETON = 50
};
- // skeleton creation api
+ // Skeleton creation API
void add_bone(const String &p_name);
int find_bone(const String &p_name) const;
String get_bone_name(int p_bone) const;
@@ -198,8 +197,6 @@ class Skeleton3D : public Node3D {
void set_bone_rest(int p_bone, const Transform3D &p_rest);
Transform3D get_bone_rest(int p_bone) const;
- Transform3D get_bone_global_pose(int p_bone) const;
- Transform3D get_bone_global_pose_no_override(int p_bone) const;
void set_bone_enabled(int p_bone, bool p_enabled);
bool is_bone_enabled(int p_bone) const;
@@ -208,27 +205,34 @@ class Skeleton3D : public Node3D {
bool is_show_rest_only() const;
void clear_bones();
- // posing api
-
+ // Posing api
void set_bone_pose_position(int p_bone, const Vector3 &p_position);
void set_bone_pose_rotation(int p_bone, const Quaternion &p_rotation);
void set_bone_pose_scale(int p_bone, const Vector3 &p_scale);
Transform3D get_bone_pose(int p_bone) const;
+ Transform3D get_bone_pose_no_override(int p_bone) const;
+
+ Transform3D get_bone_global_pose(int p_bone) const;
+ Transform3D get_bone_global_pose_no_override(int p_bone) const;
Vector3 get_bone_pose_position(int p_bone) const;
Quaternion get_bone_pose_rotation(int p_bone) const;
Vector3 get_bone_pose_scale(int p_bone) const;
- void clear_bones_global_pose_override();
- Transform3D get_bone_global_pose_override(int p_bone) const;
- void set_bone_global_pose_override(int p_bone, const Transform3D &p_pose, real_t p_amount, bool p_persistent = false);
+ // Pose override
+ bool is_bone_pose_overridden(int p_bone) const;
+ void clear_bone_pose_override(int p_bone);
+ void clear_bone_pose_overrides();
- void clear_bones_local_pose_override();
- Transform3D get_bone_local_pose_override(int p_bone) const;
- void set_bone_local_pose_override(int p_bone, const Transform3D &p_pose, real_t p_amount, bool p_persistent = false);
+ Transform3D get_bone_pose_override(int p_bone) const;
+ void set_bone_pose_override(int p_bone, const Transform3D &p_pose, float p_amount);
- void localize_rests(); // used for loaders and tools
+ Transform3D get_bone_global_pose_override(int p_bone) const;
+ void set_bone_global_pose_override(int p_bone, const Transform3D &p_pose, float p_amount);
+
+ // Rest
+ void localize_rests(); // Used for loaders and tools.
Ref create_skin_from_rest_transforms();
@@ -259,7 +263,6 @@ class Skeleton3D : public Node3D {
#endif // _3D_DISABLED
// Physical bone API
-
void set_animate_physical_bones(bool p_enabled);
bool get_animate_physical_bones() const;
@@ -270,7 +273,7 @@ class Skeleton3D : public Node3D {
PhysicalBone3D *get_physical_bone_parent(int p_bone);
private:
- /// This is a slow API, so it's cached
+ /// This is a slow API, so it's cached.
PhysicalBone3D *_get_physical_bone_parent(int p_bone);
void _rebuild_physical_bones_cache();
diff --git a/scene/3d/skeleton_ik_3d.cpp b/scene/3d/skeleton_ik_3d.cpp
index f29b06006997..9e5f2285fdd2 100644
--- a/scene/3d/skeleton_ik_3d.cpp
+++ b/scene/3d/skeleton_ik_3d.cpp
@@ -254,7 +254,7 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove
// Before skipping, make sure we undo the global pose overrides
ChainItem *ci(&p_task->chain.chain_root);
while (ci) {
- p_task->skeleton->set_bone_global_pose_override(ci->bone, ci->initial_transform, 0.0, false);
+ p_task->skeleton->clear_bone_pose_override(ci->bone);
if (!ci->children.is_empty()) {
ci = &ci->children.write[0];
@@ -269,7 +269,7 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove
// Update the initial root transform so its synced with any animation changes
_update_chain(p_task->skeleton, &p_task->chain.chain_root);
- p_task->skeleton->set_bone_global_pose_override(p_task->chain.chain_root.bone, Transform3D(), 0.0, false);
+ p_task->skeleton->clear_bone_pose_override(p_task->chain.chain_root.bone);
Vector3 origin_pos = p_task->skeleton->get_bone_global_pose(p_task->chain.chain_root.bone).origin;
make_goal(p_task, p_task->skeleton->get_global_transform().affine_inverse(), blending_delta);
@@ -305,7 +305,7 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove
new_bone_pose.basis.orthonormalize();
new_bone_pose.basis.scale(p_task->skeleton->get_bone_global_pose(ci->bone).basis.get_scale());
- p_task->skeleton->set_bone_global_pose_override(ci->bone, new_bone_pose, 1.0, true);
+ p_task->skeleton->set_bone_global_pose_override(ci->bone, new_bone_pose, 1);
if (!ci->children.is_empty()) {
ci = &ci->children.write[0];
@@ -527,7 +527,7 @@ void SkeletonIK3D::start(bool p_one_time) {
void SkeletonIK3D::stop() {
set_process_internal(false);
if (skeleton) {
- skeleton->clear_bones_global_pose_override();
+ skeleton->clear_bone_pose_overrides();
}
}
diff --git a/scene/resources/skeleton_modification_3d_ccdik.cpp b/scene/resources/skeleton_modification_3d_ccdik.cpp
index f19be47db25f..0c660e27ba6b 100644
--- a/scene/resources/skeleton_modification_3d_ccdik.cpp
+++ b/scene/resources/skeleton_modification_3d_ccdik.cpp
@@ -129,9 +129,7 @@ void SkeletonModification3DCCDIK::_execute(real_t p_delta) {
// Reset the local bone overrides for CCDIK affected nodes
for (uint32_t i = 0; i < ccdik_data_chain.size(); i++) {
- stack->skeleton->set_bone_local_pose_override(ccdik_data_chain[i].bone_idx,
- stack->skeleton->get_bone_local_pose_override(ccdik_data_chain[i].bone_idx),
- 0.0, false);
+ stack->skeleton->clear_bone_pose_override(ccdik_data_chain[i].bone_idx);
}
Node3D *node_target = Object::cast_to(ObjectDB::get_instance(target_node_cache));
@@ -228,7 +226,7 @@ void SkeletonModification3DCCDIK::_execute_ccdik_joint(int p_joint_idx, Node3D *
bone_trans.basis.set_axis_angle(rotation_axis, rotation_angle);
}
- stack->skeleton->set_bone_local_pose_override(ccdik_data.bone_idx, bone_trans, stack->strength, true);
+ stack->skeleton->set_bone_pose_override(ccdik_data.bone_idx, bone_trans, stack->strength);
stack->skeleton->force_update_bone_children_transforms(ccdik_data.bone_idx);
}
diff --git a/scene/resources/skeleton_modification_3d_fabrik.cpp b/scene/resources/skeleton_modification_3d_fabrik.cpp
index b62dda3f4fa4..1513b022b42d 100644
--- a/scene/resources/skeleton_modification_3d_fabrik.cpp
+++ b/scene/resources/skeleton_modification_3d_fabrik.cpp
@@ -285,7 +285,7 @@ void SkeletonModification3DFABRIK::chain_apply() {
current_trans.basis.rotate_to_align(forward_vector, current_trans.origin.direction_to(next_trans.origin));
current_trans.basis.rotate_local(forward_vector, fabrik_data_chain[i].roll);
}
- stack->skeleton->set_bone_local_pose_override(current_bone_idx, stack->skeleton->global_pose_to_local_pose(current_bone_idx, current_trans), stack->strength, true);
+ stack->skeleton->set_bone_global_pose_override(current_bone_idx, current_trans, stack->strength);
}
// Update all the bones so the next modification has up-to-date data.
diff --git a/scene/resources/skeleton_modification_3d_jiggle.cpp b/scene/resources/skeleton_modification_3d_jiggle.cpp
index 3e36c241f78c..211150a4adaf 100644
--- a/scene/resources/skeleton_modification_3d_jiggle.cpp
+++ b/scene/resources/skeleton_modification_3d_jiggle.cpp
@@ -172,7 +172,7 @@ void SkeletonModification3DJiggle::_execute_jiggle_joint(int p_joint_idx, Node3D
return;
}
- Transform3D bone_local_pos = stack->skeleton->get_bone_local_pose_override(jiggle_data_chain[p_joint_idx].bone_idx);
+ Transform3D bone_local_pos = stack->skeleton->get_bone_pose_override(jiggle_data_chain[p_joint_idx].bone_idx);
if (bone_local_pos == Transform3D()) {
bone_local_pos = stack->skeleton->get_bone_pose(jiggle_data_chain[p_joint_idx].bone_idx);
}
@@ -237,7 +237,7 @@ void SkeletonModification3DJiggle::_execute_jiggle_joint(int p_joint_idx, Node3D
new_bone_trans.basis.rotate_local(forward_vector, jiggle_data_chain[p_joint_idx].roll);
new_bone_trans = stack->skeleton->global_pose_to_local_pose(jiggle_data_chain[p_joint_idx].bone_idx, new_bone_trans);
- stack->skeleton->set_bone_local_pose_override(jiggle_data_chain[p_joint_idx].bone_idx, new_bone_trans, stack->strength, true);
+ stack->skeleton->set_bone_pose_override(jiggle_data_chain[p_joint_idx].bone_idx, new_bone_trans, stack->strength);
stack->skeleton->force_update_bone_children_transforms(jiggle_data_chain[p_joint_idx].bone_idx);
}
@@ -264,7 +264,7 @@ void SkeletonModification3DJiggle::_setup_modification(SkeletonModificationStack
for (uint32_t i = 0; i < jiggle_data_chain.size(); i++) {
int bone_idx = jiggle_data_chain[i].bone_idx;
if (bone_idx > 0 && bone_idx < stack->skeleton->get_bone_count()) {
- jiggle_data_chain[i].dynamic_position = stack->skeleton->local_pose_to_global_pose(bone_idx, stack->skeleton->get_bone_local_pose_override(bone_idx)).origin;
+ jiggle_data_chain[i].dynamic_position = stack->skeleton->get_bone_global_pose_override(bone_idx).origin;
}
}
}
diff --git a/scene/resources/skeleton_modification_3d_lookat.cpp b/scene/resources/skeleton_modification_3d_lookat.cpp
index 3e8c1e3a7729..5c5670f336e4 100644
--- a/scene/resources/skeleton_modification_3d_lookat.cpp
+++ b/scene/resources/skeleton_modification_3d_lookat.cpp
@@ -96,7 +96,7 @@ void SkeletonModification3DLookAt::_execute(real_t p_delta) {
if (_print_execution_error(bone_idx <= -1, "Bone index is invalid. Cannot execute modification!")) {
return;
}
- Transform3D new_bone_trans = stack->skeleton->get_bone_local_pose_override(bone_idx);
+ Transform3D new_bone_trans = stack->skeleton->get_bone_pose_override(bone_idx);
if (new_bone_trans == Transform3D()) {
new_bone_trans = stack->skeleton->get_bone_pose(bone_idx);
}
@@ -124,7 +124,7 @@ void SkeletonModification3DLookAt::_execute(real_t p_delta) {
new_bone_trans.basis.rotate_local(Vector3(0, 1, 0), additional_rotation.y);
new_bone_trans.basis.rotate_local(Vector3(0, 0, 1), additional_rotation.z);
- stack->skeleton->set_bone_local_pose_override(bone_idx, new_bone_trans, stack->strength, true);
+ stack->skeleton->set_bone_pose_override(bone_idx, new_bone_trans, stack->strength);
stack->skeleton->force_update_bone_children_transforms(bone_idx);
// If we completed it successfully, then we can set execution_error_found to false
diff --git a/scene/resources/skeleton_modification_3d_twoboneik.cpp b/scene/resources/skeleton_modification_3d_twoboneik.cpp
index acc5ff716ce3..2121626f279a 100644
--- a/scene/resources/skeleton_modification_3d_twoboneik.cpp
+++ b/scene/resources/skeleton_modification_3d_twoboneik.cpp
@@ -178,11 +178,11 @@ void SkeletonModification3DTwoBoneIK::_execute(real_t p_delta) {
}
Transform3D pole_trans = stack->skeleton->world_transform_to_global_pose(pole->get_global_transform());
- Transform3D bone_one_local_pos = stack->skeleton->get_bone_local_pose_override(joint_one_bone_idx);
+ Transform3D bone_one_local_pos = stack->skeleton->get_bone_pose_override(joint_one_bone_idx);
if (bone_one_local_pos == Transform3D()) {
bone_one_local_pos = stack->skeleton->get_bone_pose(joint_one_bone_idx);
}
- Transform3D bone_two_local_pos = stack->skeleton->get_bone_local_pose_override(joint_two_bone_idx);
+ Transform3D bone_two_local_pos = stack->skeleton->get_bone_pose_override(joint_two_bone_idx);
if (bone_two_local_pos == Transform3D()) {
bone_two_local_pos = stack->skeleton->get_bone_pose(joint_two_bone_idx);
}
@@ -192,7 +192,7 @@ void SkeletonModification3DTwoBoneIK::_execute(real_t p_delta) {
bone_one_trans.basis = stack->skeleton->global_pose_z_forward_to_bone_forward(joint_one_bone_idx, bone_one_trans.basis);
stack->skeleton->update_bone_rest_forward_vector(joint_one_bone_idx);
bone_one_trans.basis.rotate_local(stack->skeleton->get_bone_axis_forward_vector(joint_one_bone_idx), joint_one_roll);
- stack->skeleton->set_bone_local_pose_override(joint_one_bone_idx, stack->skeleton->global_pose_to_local_pose(joint_one_bone_idx, bone_one_trans), stack->strength, true);
+ stack->skeleton->set_bone_global_pose_override(joint_one_bone_idx, bone_one_trans, stack->strength);
stack->skeleton->force_update_bone_children_transforms(joint_one_bone_idx);
bone_two_trans = stack->skeleton->local_pose_to_global_pose(joint_two_bone_idx, bone_two_local_pos);
@@ -200,14 +200,14 @@ void SkeletonModification3DTwoBoneIK::_execute(real_t p_delta) {
bone_two_trans.basis = stack->skeleton->global_pose_z_forward_to_bone_forward(joint_two_bone_idx, bone_two_trans.basis);
stack->skeleton->update_bone_rest_forward_vector(joint_two_bone_idx);
bone_two_trans.basis.rotate_local(stack->skeleton->get_bone_axis_forward_vector(joint_two_bone_idx), joint_two_roll);
- stack->skeleton->set_bone_local_pose_override(joint_two_bone_idx, stack->skeleton->global_pose_to_local_pose(joint_two_bone_idx, bone_two_trans), stack->strength, true);
+ stack->skeleton->set_bone_global_pose_override(joint_two_bone_idx, bone_two_trans, stack->strength);
stack->skeleton->force_update_bone_children_transforms(joint_two_bone_idx);
} else {
- Transform3D bone_one_local_pos = stack->skeleton->get_bone_local_pose_override(joint_one_bone_idx);
+ Transform3D bone_one_local_pos = stack->skeleton->get_bone_pose_override(joint_one_bone_idx);
if (bone_one_local_pos == Transform3D()) {
bone_one_local_pos = stack->skeleton->get_bone_pose(joint_one_bone_idx);
}
- Transform3D bone_two_local_pos = stack->skeleton->get_bone_local_pose_override(joint_two_bone_idx);
+ Transform3D bone_two_local_pos = stack->skeleton->get_bone_pose_override(joint_two_bone_idx);
if (bone_two_local_pos == Transform3D()) {
bone_two_local_pos = stack->skeleton->get_bone_pose(joint_two_bone_idx);
}
@@ -269,12 +269,12 @@ void SkeletonModification3DTwoBoneIK::_execute(real_t p_delta) {
// Apply the rotation to the first joint
bone_one_trans = stack->skeleton->global_pose_to_local_pose(joint_one_bone_idx, bone_one_trans);
bone_one_trans.origin = Vector3(0, 0, 0);
- stack->skeleton->set_bone_local_pose_override(joint_one_bone_idx, bone_one_trans, stack->strength, true);
+ stack->skeleton->set_bone_pose_override(joint_one_bone_idx, bone_one_trans, stack->strength);
stack->skeleton->force_update_bone_children_transforms(joint_one_bone_idx);
if (use_pole_node) {
// Update bone_two_trans so its at the latest position, with the rotation of bone_one_trans taken into account, then look at the target.
- bone_two_trans = stack->skeleton->local_pose_to_global_pose(joint_two_bone_idx, stack->skeleton->get_bone_local_pose_override(joint_two_bone_idx));
+ bone_two_trans = stack->skeleton->local_pose_to_global_pose(joint_two_bone_idx, stack->skeleton->get_bone_pose_override(joint_two_bone_idx));
stack->skeleton->update_bone_rest_forward_vector(joint_two_bone_idx);
Vector3 forward_vector = stack->skeleton->get_bone_axis_forward_vector(joint_two_bone_idx);
bone_two_trans.basis.rotate_to_align(forward_vector, bone_two_trans.origin.direction_to(target_trans.origin));
@@ -283,7 +283,7 @@ void SkeletonModification3DTwoBoneIK::_execute(real_t p_delta) {
bone_two_trans.basis.rotate_local(stack->skeleton->get_bone_axis_forward_vector(joint_two_bone_idx), joint_two_roll);
bone_two_trans = stack->skeleton->global_pose_to_local_pose(joint_two_bone_idx, bone_two_trans);
- stack->skeleton->set_bone_local_pose_override(joint_two_bone_idx, bone_two_trans, stack->strength, true);
+ stack->skeleton->set_bone_pose_override(joint_two_bone_idx, bone_two_trans, stack->strength);
stack->skeleton->force_update_bone_children_transforms(joint_two_bone_idx);
} else {
// Calculate the angles for the second joint using the law of cosigns, make a quaternion with the delta rotation needed to rotate the joint into
@@ -299,7 +299,7 @@ void SkeletonModification3DTwoBoneIK::_execute(real_t p_delta) {
bone_two_trans = stack->skeleton->global_pose_to_local_pose(joint_two_bone_idx, bone_two_trans);
bone_two_trans.origin = Vector3(0, 0, 0);
- stack->skeleton->set_bone_local_pose_override(joint_two_bone_idx, bone_two_trans, stack->strength, true);
+ stack->skeleton->set_bone_pose_override(joint_two_bone_idx, bone_two_trans, stack->strength);
stack->skeleton->force_update_bone_children_transforms(joint_two_bone_idx);
}
}
diff --git a/scene/resources/skeleton_modification_stack_3d.cpp b/scene/resources/skeleton_modification_stack_3d.cpp
index 7ccba1228c29..ce8c33e60c68 100644
--- a/scene/resources/skeleton_modification_stack_3d.cpp
+++ b/scene/resources/skeleton_modification_stack_3d.cpp
@@ -174,7 +174,7 @@ void SkeletonModificationStack3D::set_enabled(bool p_enabled) {
enabled = p_enabled;
if (!enabled && is_setup && skeleton != nullptr) {
- skeleton->clear_bones_local_pose_override();
+ skeleton->clear_bone_pose_overrides();
}
}