From bfbd8741a7742a170c710ca8bc010f4d07092eed Mon Sep 17 00:00:00 2001 From: VicooDi Date: Fri, 18 Oct 2024 19:55:12 +0200 Subject: [PATCH 1/4] fixed non normalized quaternion --- scene/3d/skeleton_3d.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 9e4c9b183266..3e9975be5271 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -865,7 +865,7 @@ void Skeleton3D::set_bone_pose_rotation(int p_bone, const Quaternion &p_rotation const int bone_size = bones.size(); ERR_FAIL_INDEX(p_bone, bone_size); - bones[p_bone].pose_rotation = p_rotation; + bones[p_bone].pose_rotation = p_rotation.normalized(); bones[p_bone].pose_cache_dirty = true; if (is_inside_tree()) { _make_dirty(); From 79954732c3ad8e25f130da43baa81c3bb988ce6a Mon Sep 17 00:00:00 2001 From: VicooDi Date: Sun, 20 Oct 2024 00:33:11 +0200 Subject: [PATCH 2/4] normalize button --- core/math/quaternion.cpp | 2 +- editor/editor_properties.cpp | 25 +++++++++++++++++++++++++ editor/editor_properties.h | 3 +++ scene/3d/skeleton_3d.cpp | 4 +++- 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/core/math/quaternion.cpp b/core/math/quaternion.cpp index 08eac14b76d6..0cadf0350483 100644 --- a/core/math/quaternion.cpp +++ b/core/math/quaternion.cpp @@ -83,7 +83,7 @@ Quaternion Quaternion::normalized() const { } bool Quaternion::is_normalized() const { - return Math::is_equal_approx(length_squared(), 1, (real_t)UNIT_EPSILON); //use less epsilon + return Math::is_equal_approx(length_squared(), 1, (real_t)0.01/*UNIT_EPSILON*/); //use less epsilon // 0.01 is a temporary fix for precision errors } Quaternion Quaternion::inverse() const { diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index c5a35e466c91..6c4bf455d2f3 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -1941,6 +1941,21 @@ void EditorPropertyQuaternion::_set_read_only(bool p_read_only) { } } +void EditorPropertyQuaternion::_edit_normalize_quaternion_value() { + if (normalize_quaternion_bttn->is_pressed()) { + Quaternion temp; + for (int i = 0; i < 4; i++) { + temp[i] = (real_t)spin[i]->get_value(); + } + temp = temp.normalized(); + for (int i = 0; i < 4; i++) { + spin[i]->set_value_no_signal((double)temp[i]); + } + _value_changed(-1, ""); + update_property(); + } +} + void EditorPropertyQuaternion::_edit_custom_value() { if (edit_button->is_pressed()) { edit_custom_bc->show(); @@ -2025,6 +2040,7 @@ void EditorPropertyQuaternion::_notification(int p_what) { euler[i]->add_theme_color_override("label_color", colors[i]); } edit_button->set_icon(get_editor_theme_icon(SNAME("Edit"))); + normalize_quaternion_bttn->set_icon(get_editor_theme_icon(SNAME("Key"))); euler_label->add_theme_color_override(SceneStringName(font_color), get_theme_color(SNAME("property_color"), SNAME("EditorProperty"))); warning->set_icon(get_editor_theme_icon(SNAME("NodeWarning"))); warning->add_theme_color_override(SceneStringName(font_color), get_theme_color(SNAME("warning_color"), EditorStringName(Editor))); @@ -2065,6 +2081,7 @@ EditorPropertyQuaternion::EditorPropertyQuaternion() { VBoxContainer *bc = memnew(VBoxContainer); edit_custom_bc = memnew(VBoxContainer); + normalize_quaternion = memnew(VBoxContainer); BoxContainer *edit_custom_layout; if (horizontal) { default_layout = memnew(HBoxContainer); @@ -2076,10 +2093,12 @@ EditorPropertyQuaternion::EditorPropertyQuaternion() { } edit_custom_bc->hide(); add_child(bc); + normalize_quaternion->set_h_size_flags(SIZE_EXPAND_FILL); edit_custom_bc->set_h_size_flags(SIZE_EXPAND_FILL); default_layout->set_h_size_flags(SIZE_EXPAND_FILL); edit_custom_layout->set_h_size_flags(SIZE_EXPAND_FILL); bc->add_child(default_layout); + bc->add_child(normalize_quaternion); bc->add_child(edit_custom_bc); static const char *desc[4] = { "x", "y", "z", "w" }; @@ -2095,6 +2114,12 @@ EditorPropertyQuaternion::EditorPropertyQuaternion() { } } + normalize_quaternion_bttn = memnew(Button); + normalize_quaternion_bttn->set_flat(true); + default_layout->add_child(normalize_quaternion_bttn); + normalize_quaternion_bttn->connect(SceneStringName(pressed), callable_mp(this, &EditorPropertyQuaternion::_edit_normalize_quaternion_value)); + add_focusable(normalize_quaternion_bttn); + warning = memnew(Button); warning->set_text(TTR("Temporary Euler may be changed implicitly!")); warning->set_clip_text(true); diff --git a/editor/editor_properties.h b/editor/editor_properties.h index 004630da3e22..897e2104158b 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -487,14 +487,17 @@ class EditorPropertyQuaternion : public EditorProperty { AcceptDialog *warning_dialog = nullptr; Label *euler_label = nullptr; + VBoxContainer *normalize_quaternion = nullptr; VBoxContainer *edit_custom_bc = nullptr; EditorSpinSlider *euler[3]; Button *edit_button = nullptr; + Button *normalize_quaternion_bttn = nullptr; Vector3 edit_euler; void _value_changed(double p_val, const String &p_name); void _edit_custom_value(); + void _edit_normalize_quaternion_value(); void _custom_value_changed(double p_val); void _warning_pressed(); diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 3e9975be5271..86dbd0142a6c 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -865,7 +865,9 @@ void Skeleton3D::set_bone_pose_rotation(int p_bone, const Quaternion &p_rotation const int bone_size = bones.size(); ERR_FAIL_INDEX(p_bone, bone_size); - bones[p_bone].pose_rotation = p_rotation.normalized(); + //ERR_FAIL_COND_EDMSG(!p_rotation.is_normalized(), "The quaternion bone " + get_bone_name(p_bone) + " pose rotation must be normalized."); + + bones[p_bone].pose_rotation = p_rotation; bones[p_bone].pose_cache_dirty = true; if (is_inside_tree()) { _make_dirty(); From 21c33219dca7ea39603e7c9f6208c3e2b70bf804 Mon Sep 17 00:00:00 2001 From: VicooDi Date: Sun, 20 Oct 2024 17:43:00 +0200 Subject: [PATCH 3/4] normalize button revision --- core/math/quaternion.cpp | 2 +- editor/editor_properties.cpp | 16 ++++++++++++---- scene/3d/skeleton_3d.cpp | 4 +++- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/core/math/quaternion.cpp b/core/math/quaternion.cpp index 0cadf0350483..eb2fa2d86565 100644 --- a/core/math/quaternion.cpp +++ b/core/math/quaternion.cpp @@ -83,7 +83,7 @@ Quaternion Quaternion::normalized() const { } bool Quaternion::is_normalized() const { - return Math::is_equal_approx(length_squared(), 1, (real_t)0.01/*UNIT_EPSILON*/); //use less epsilon // 0.01 is a temporary fix for precision errors + return Math::is_equal_approx(length(), 1, (real_t)UNIT_EPSILON); //use less epsilon } Quaternion Quaternion::inverse() const { diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 6c4bf455d2f3..9b04fbc215e5 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -1943,16 +1943,25 @@ void EditorPropertyQuaternion::_set_read_only(bool p_read_only) { void EditorPropertyQuaternion::_edit_normalize_quaternion_value() { if (normalize_quaternion_bttn->is_pressed()) { + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->create_action("Quaternion Normalized"); + Quaternion temp; for (int i = 0; i < 4; i++) { temp[i] = (real_t)spin[i]->get_value(); + + //undo_redo->add_undo_property(spin[i], "Un-Normalize Quaternion", spin[i]); + undo_redo->add_undo_property(get_edited_object(), get_edited_property(), spin[i]); } temp = temp.normalized(); for (int i = 0; i < 4; i++) { spin[i]->set_value_no_signal((double)temp[i]); + + undo_redo->add_undo_property(get_edited_object(), get_edited_property(), temp[i]); + //undo_redo->add_do_property(spin[i], "Re-Normalize Quaternion", temp[i]); } _value_changed(-1, ""); - update_property(); + undo_redo->commit_action(); } } @@ -2040,7 +2049,6 @@ void EditorPropertyQuaternion::_notification(int p_what) { euler[i]->add_theme_color_override("label_color", colors[i]); } edit_button->set_icon(get_editor_theme_icon(SNAME("Edit"))); - normalize_quaternion_bttn->set_icon(get_editor_theme_icon(SNAME("Key"))); euler_label->add_theme_color_override(SceneStringName(font_color), get_theme_color(SNAME("property_color"), SNAME("EditorProperty"))); warning->set_icon(get_editor_theme_icon(SNAME("NodeWarning"))); warning->add_theme_color_override(SceneStringName(font_color), get_theme_color(SNAME("warning_color"), EditorStringName(Editor))); @@ -2115,10 +2123,10 @@ EditorPropertyQuaternion::EditorPropertyQuaternion() { } normalize_quaternion_bttn = memnew(Button); - normalize_quaternion_bttn->set_flat(true); - default_layout->add_child(normalize_quaternion_bttn); + normalize_quaternion_bttn->set_text("Normalize"); normalize_quaternion_bttn->connect(SceneStringName(pressed), callable_mp(this, &EditorPropertyQuaternion::_edit_normalize_quaternion_value)); add_focusable(normalize_quaternion_bttn); + normalize_quaternion->add_child(normalize_quaternion_bttn); warning = memnew(Button); warning->set_text(TTR("Temporary Euler may be changed implicitly!")); diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 86dbd0142a6c..a04d65708ab7 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -865,7 +865,9 @@ void Skeleton3D::set_bone_pose_rotation(int p_bone, const Quaternion &p_rotation const int bone_size = bones.size(); ERR_FAIL_INDEX(p_bone, bone_size); - //ERR_FAIL_COND_EDMSG(!p_rotation.is_normalized(), "The quaternion bone " + get_bone_name(p_bone) + " pose rotation must be normalized."); + if(!p_rotation.is_normalized()) { + WARN_PRINT_ED("The quaternion bone " + get_bone_name(p_bone) + " pose rotation must be normalized."); + } bones[p_bone].pose_rotation = p_rotation; bones[p_bone].pose_cache_dirty = true; From d39089466b55ef00a00e80a2b446747e2b56a1ab Mon Sep 17 00:00:00 2001 From: VicooDi Date: Sun, 20 Oct 2024 18:25:34 +0200 Subject: [PATCH 4/4] fix format --- scene/3d/skeleton_3d.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index a04d65708ab7..521c8ff38a9c 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -865,7 +865,7 @@ void Skeleton3D::set_bone_pose_rotation(int p_bone, const Quaternion &p_rotation const int bone_size = bones.size(); ERR_FAIL_INDEX(p_bone, bone_size); - if(!p_rotation.is_normalized()) { + if (!p_rotation.is_normalized()) { WARN_PRINT_ED("The quaternion bone " + get_bone_name(p_bone) + " pose rotation must be normalized."); }