From ee1e40f1b04265652fcf65551b345ca9fa622009 Mon Sep 17 00:00:00 2001 From: Relintai Date: Mon, 30 Sep 2024 16:17:19 +0200 Subject: [PATCH 1/8] Renamed looking_at to create_looking_at, and from_scale to create_from_scale in Basis. --- core/math/basis.cpp | 37 ++++++++++++++-------------- core/math/basis.h | 4 +-- modules/gdnative/gdnative/basis.cpp | 10 ++++---- modules/gdnative/gdnative_api.json | 6 ++--- modules/gdnative/include/gdn/basis.h | 4 +-- 5 files changed, 31 insertions(+), 30 deletions(-) diff --git a/core/math/basis.cpp b/core/math/basis.cpp index 83c616e97..8fb42fa5e 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -217,7 +217,25 @@ Basis Basis::transposed() const { return tr; } -Basis Basis::from_scale(const Vector3 &p_scale) { +Basis Basis::create_looking_at(const Vector3 &p_target, const Vector3 &p_up) { +#ifdef MATH_CHECKS + ERR_FAIL_COND_V_MSG(p_target.is_equal_approx(Vector3()), Basis(), "The target vector can't be zero."); + ERR_FAIL_COND_V_MSG(p_up.is_equal_approx(Vector3()), Basis(), "The up vector can't be zero."); +#endif + Vector3 v_z = -p_target.normalized(); + Vector3 v_x = p_up.cross(v_z); +#ifdef MATH_CHECKS + ERR_FAIL_COND_V_MSG(v_x.is_equal_approx(Vector3()), Basis(), "The target vector and up vector can't be parallel to each other."); +#endif + v_x.normalize(); + Vector3 v_y = v_z.cross(v_x); + + Basis basis; + basis.set_columns(v_x, v_y, v_z); + return basis; +} + +Basis Basis::create_from_scale(const Vector3 &p_scale) { return Basis(p_scale.x, 0, 0, 0, p_scale.y, 0, 0, 0, p_scale.z); } @@ -1185,20 +1203,3 @@ void Basis::rotate_sh(real_t *p_values) { p_values[8] = d4 * s_scale_dst4; } -Basis Basis::looking_at(const Vector3 &p_target, const Vector3 &p_up) { -#ifdef MATH_CHECKS - ERR_FAIL_COND_V_MSG(p_target.is_equal_approx(Vector3()), Basis(), "The target vector can't be zero."); - ERR_FAIL_COND_V_MSG(p_up.is_equal_approx(Vector3()), Basis(), "The up vector can't be zero."); -#endif - Vector3 v_z = -p_target.normalized(); - Vector3 v_x = p_up.cross(v_z); -#ifdef MATH_CHECKS - ERR_FAIL_COND_V_MSG(v_x.is_equal_approx(Vector3()), Basis(), "The target vector and up vector can't be parallel to each other."); -#endif - v_x.normalize(); - Vector3 v_y = v_z.cross(v_x); - - Basis basis; - basis.set_columns(v_x, v_y, v_z); - return basis; -} diff --git a/core/math/basis.h b/core/math/basis.h index 17975d0ed..beb583f8e 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -286,8 +286,8 @@ struct _NO_DISCARD_CLASS_ Basis { // only be used in cases of single normals, or when the basis changes each time. Vector3 xform_normal(const Vector3 &p_vector) const { return get_normal_xform_basis().xform_normal_fast(p_vector); } - static Basis looking_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0)); - static Basis from_scale(const Vector3 &p_scale); + static Basis create_looking_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0)); + static Basis create_from_scale(const Vector3 &p_scale); operator Quaternion() const { return get_quaternion(); } diff --git a/modules/gdnative/gdnative/basis.cpp b/modules/gdnative/gdnative/basis.cpp index 46e36ba0a..f1c5e59b7 100644 --- a/modules/gdnative/gdnative/basis.cpp +++ b/modules/gdnative/gdnative/basis.cpp @@ -691,23 +691,23 @@ pandemonium_vector3 GDAPI pandemonium_basis_xform_normal(const pandemonium_basis return dest; } -pandemonium_basis GDAPI pandemonium_basis_looking_at(const pandemonium_vector3 *p_target) { +pandemonium_basis GDAPI pandemonium_basis_create_looking_at(const pandemonium_vector3 *p_target) { pandemonium_basis dest; const Vector3 *target = (const Vector3 *)p_target; - *((Basis *)&dest) = Basis::looking_at(*target); + *((Basis *)&dest) = Basis::create_looking_at(*target); return dest; } pandemonium_basis GDAPI pandemonium_basis_looking_at_up(const pandemonium_vector3 *p_target, const pandemonium_vector3 *p_up) { pandemonium_basis dest; const Vector3 *target = (const Vector3 *)p_target; const Vector3 *up = (const Vector3 *)p_up; - *((Basis *)&dest) = Basis::looking_at(*target, *up); + *((Basis *)&dest) = Basis::create_looking_at(*target, *up); return dest; } -pandemonium_basis GDAPI pandemonium_basis_from_scale(const pandemonium_vector3 *p_scale) { +pandemonium_basis GDAPI pandemonium_basis_create_from_scale(const pandemonium_vector3 *p_scale) { pandemonium_basis dest; const Vector3 *scale = (const Vector3 *)p_scale; - *((Basis *)&dest) = Basis::from_scale(*scale); + *((Basis *)&dest) = Basis::create_from_scale(*scale); return dest; } diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index 5ce6629c2..d74db07c5 100644 --- a/modules/gdnative/gdnative_api.json +++ b/modules/gdnative/gdnative_api.json @@ -1696,7 +1696,7 @@ ] }, { - "name": "pandemonium_basis_looking_at", + "name": "pandemonium_basis_create_looking_at", "return_type": "pandemonium_basis", "arguments": [ ["const pandemonium_vector3 *", "p_target"] @@ -1711,7 +1711,7 @@ ] }, { - "name": "pandemonium_basis_from_scale", + "name": "pandemonium_basis_create_from_scale", "return_type": "pandemonium_basis", "arguments": [ ["const pandemonium_vector3 *", "p_scale"] @@ -13911,4 +13911,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/modules/gdnative/include/gdn/basis.h b/modules/gdnative/include/gdn/basis.h index 7658d7611..98eb5da3d 100644 --- a/modules/gdnative/include/gdn/basis.h +++ b/modules/gdnative/include/gdn/basis.h @@ -213,9 +213,9 @@ pandemonium_basis GDAPI pandemonium_basis_get_normal_xform_basis(const pandemoni pandemonium_vector3 GDAPI pandemonium_basis_xform_normal_fast(const pandemonium_basis *p_self, const pandemonium_vector3 *p_vector); pandemonium_vector3 GDAPI pandemonium_basis_xform_normal(const pandemonium_basis *p_self, const pandemonium_vector3 *p_vector); -pandemonium_basis GDAPI pandemonium_basis_looking_at(const pandemonium_vector3 *p_target); +pandemonium_basis GDAPI pandemonium_basis_create_looking_at(const pandemonium_vector3 *p_target); pandemonium_basis GDAPI pandemonium_basis_looking_at_up(const pandemonium_vector3 *p_target, const pandemonium_vector3 *p_up); -pandemonium_basis GDAPI pandemonium_basis_from_scale(const pandemonium_vector3 *p_scale); +pandemonium_basis GDAPI pandemonium_basis_create_from_scale(const pandemonium_vector3 *p_scale); // p_elements is a pointer to an array of 3 (!!) vector3 void GDAPI pandemonium_basis_get_elements(const pandemonium_basis *p_self, pandemonium_vector3 *p_elements); From 6ac0c2bbc086351dfc91989ebeb4de3531a56f96 Mon Sep 17 00:00:00 2001 From: Relintai Date: Mon, 30 Sep 2024 16:26:52 +0200 Subject: [PATCH 2/8] Undo unecessary breaking change to gdnative. --- modules/gdnative/gdnative/basis.cpp | 4 ++-- modules/gdnative/gdnative_api.json | 4 ++-- modules/gdnative/include/gdn/basis.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/gdnative/gdnative/basis.cpp b/modules/gdnative/gdnative/basis.cpp index f1c5e59b7..1f829e6f8 100644 --- a/modules/gdnative/gdnative/basis.cpp +++ b/modules/gdnative/gdnative/basis.cpp @@ -691,7 +691,7 @@ pandemonium_vector3 GDAPI pandemonium_basis_xform_normal(const pandemonium_basis return dest; } -pandemonium_basis GDAPI pandemonium_basis_create_looking_at(const pandemonium_vector3 *p_target) { +pandemonium_basis GDAPI pandemonium_basis_looking_at(const pandemonium_vector3 *p_target) { pandemonium_basis dest; const Vector3 *target = (const Vector3 *)p_target; *((Basis *)&dest) = Basis::create_looking_at(*target); @@ -704,7 +704,7 @@ pandemonium_basis GDAPI pandemonium_basis_looking_at_up(const pandemonium_vector *((Basis *)&dest) = Basis::create_looking_at(*target, *up); return dest; } -pandemonium_basis GDAPI pandemonium_basis_create_from_scale(const pandemonium_vector3 *p_scale) { +pandemonium_basis GDAPI pandemonium_basis_from_scale(const pandemonium_vector3 *p_scale) { pandemonium_basis dest; const Vector3 *scale = (const Vector3 *)p_scale; *((Basis *)&dest) = Basis::create_from_scale(*scale); diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index d74db07c5..2d77d2b06 100644 --- a/modules/gdnative/gdnative_api.json +++ b/modules/gdnative/gdnative_api.json @@ -1696,7 +1696,7 @@ ] }, { - "name": "pandemonium_basis_create_looking_at", + "name": "pandemonium_basis_looking_at", "return_type": "pandemonium_basis", "arguments": [ ["const pandemonium_vector3 *", "p_target"] @@ -1711,7 +1711,7 @@ ] }, { - "name": "pandemonium_basis_create_from_scale", + "name": "pandemonium_basis_from_scale", "return_type": "pandemonium_basis", "arguments": [ ["const pandemonium_vector3 *", "p_scale"] diff --git a/modules/gdnative/include/gdn/basis.h b/modules/gdnative/include/gdn/basis.h index 98eb5da3d..7658d7611 100644 --- a/modules/gdnative/include/gdn/basis.h +++ b/modules/gdnative/include/gdn/basis.h @@ -213,9 +213,9 @@ pandemonium_basis GDAPI pandemonium_basis_get_normal_xform_basis(const pandemoni pandemonium_vector3 GDAPI pandemonium_basis_xform_normal_fast(const pandemonium_basis *p_self, const pandemonium_vector3 *p_vector); pandemonium_vector3 GDAPI pandemonium_basis_xform_normal(const pandemonium_basis *p_self, const pandemonium_vector3 *p_vector); -pandemonium_basis GDAPI pandemonium_basis_create_looking_at(const pandemonium_vector3 *p_target); +pandemonium_basis GDAPI pandemonium_basis_looking_at(const pandemonium_vector3 *p_target); pandemonium_basis GDAPI pandemonium_basis_looking_at_up(const pandemonium_vector3 *p_target, const pandemonium_vector3 *p_up); -pandemonium_basis GDAPI pandemonium_basis_create_from_scale(const pandemonium_vector3 *p_scale); +pandemonium_basis GDAPI pandemonium_basis_from_scale(const pandemonium_vector3 *p_scale); // p_elements is a pointer to an array of 3 (!!) vector3 void GDAPI pandemonium_basis_get_elements(const pandemonium_basis *p_self, pandemonium_vector3 *p_elements); From 010e1b51a83adbba952704d34be2e99ab0276029 Mon Sep 17 00:00:00 2001 From: Relintai Date: Mon, 30 Sep 2024 16:27:21 +0200 Subject: [PATCH 3/8] Added non-static looking_at and from_scale helper methods to Basis. --- core/math/basis.cpp | 7 +++++++ core/math/basis.h | 3 +++ 2 files changed, 10 insertions(+) diff --git a/core/math/basis.cpp b/core/math/basis.cpp index 8fb42fa5e..875453ce4 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -239,6 +239,13 @@ Basis Basis::create_from_scale(const Vector3 &p_scale) { return Basis(p_scale.x, 0, 0, 0, p_scale.y, 0, 0, 0, p_scale.z); } +Basis Basis::looking_at(const Vector3 &p_target, const Vector3 &p_up) { + return Basis::create_looking_at(p_target, p_up); +} +Basis Basis::from_scale(const Vector3 &p_scale) { + return Basis::create_from_scale(p_scale); +} + // Multiplies the matrix from left by the scaling matrix: M -> S.M // See the comment for Basis::rotated for further explanation. void Basis::scale(const Vector3 &p_scale) { diff --git a/core/math/basis.h b/core/math/basis.h index beb583f8e..bdf22ad34 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -289,6 +289,9 @@ struct _NO_DISCARD_CLASS_ Basis { static Basis create_looking_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0)); static Basis create_from_scale(const Vector3 &p_scale); + Basis looking_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0)); + Basis from_scale(const Vector3 &p_scale); + operator Quaternion() const { return get_quaternion(); } Basis(const Quaternion &p_quat) { set_quaternion(p_quat); } From 6f53257e05d72088c28028eb568526f4da146ae0 Mon Sep 17 00:00:00 2001 From: Relintai Date: Mon, 30 Sep 2024 16:41:05 +0200 Subject: [PATCH 4/8] Transform now uses Basis::create_looking_at. --- core/math/transform.cpp | 30 +----------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/core/math/transform.cpp b/core/math/transform.cpp index 2820101e5..ec9d69431 100644 --- a/core/math/transform.cpp +++ b/core/math/transform.cpp @@ -83,35 +83,7 @@ void Transform::rotate_basis(const Vector3 &p_axis, real_t p_phi) { } void Transform::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up) { -#ifdef MATH_CHECKS - ERR_FAIL_COND(p_eye == p_target); - ERR_FAIL_COND(p_up.length() == 0); -#endif - // Reference: MESA source code - Vector3 v_x, v_y, v_z; - - /* Make rotation matrix */ - - /* Z vector */ - v_z = p_eye - p_target; - - v_z.normalize(); - - v_y = p_up; - - v_x = v_y.cross(v_z); -#ifdef MATH_CHECKS - ERR_FAIL_COND(v_x.length() == 0); -#endif - - /* Recompute Y = Z cross X */ - v_y = v_z.cross(v_x); - - v_x.normalize(); - v_y.normalize(); - - basis.set(v_x, v_y, v_z); - + basis = Basis::create_looking_at(p_target - p_eye, p_up); origin = p_eye; } From 422314a8fd5e19eae16cc1a36fffd20ac1365046 Mon Sep 17 00:00:00 2001 From: Relintai Date: Mon, 30 Sep 2024 16:41:20 +0200 Subject: [PATCH 5/8] Added set_look_at helper method to Basis. --- core/math/basis.cpp | 16 ++++++++++++++++ core/math/basis.h | 2 ++ 2 files changed, 18 insertions(+) diff --git a/core/math/basis.cpp b/core/math/basis.cpp index 875453ce4..5401d2da0 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -242,6 +242,22 @@ Basis Basis::create_from_scale(const Vector3 &p_scale) { Basis Basis::looking_at(const Vector3 &p_target, const Vector3 &p_up) { return Basis::create_looking_at(p_target, p_up); } +void Basis::set_look_at(const Vector3 &p_target, const Vector3 &p_up) { +#ifdef MATH_CHECKS + ERR_FAIL_COND_MSG(p_target.is_equal_approx(Vector3()), "The target vector can't be zero."); + ERR_FAIL_COND_MSG(p_up.is_equal_approx(Vector3()), "The up vector can't be zero."); +#endif + Vector3 v_z = -p_target.normalized(); + Vector3 v_x = p_up.cross(v_z); +#ifdef MATH_CHECKS + ERR_FAIL_COND_MSG(v_x.is_equal_approx(Vector3()), "The target vector and up vector can't be parallel to each other."); +#endif + v_x.normalize(); + Vector3 v_y = v_z.cross(v_x); + + set_columns(v_x, v_y, v_z); +} + Basis Basis::from_scale(const Vector3 &p_scale) { return Basis::create_from_scale(p_scale); } diff --git a/core/math/basis.h b/core/math/basis.h index bdf22ad34..9c32b7fb4 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -290,6 +290,8 @@ struct _NO_DISCARD_CLASS_ Basis { static Basis create_from_scale(const Vector3 &p_scale); Basis looking_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0)); + void set_look_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0)); + Basis from_scale(const Vector3 &p_scale); operator Quaternion() const { return get_quaternion(); } From 951ae7b11db0376dd0dbdf080e2f2e3652ac33ed Mon Sep 17 00:00:00 2001 From: Relintai Date: Mon, 30 Sep 2024 17:04:00 +0200 Subject: [PATCH 6/8] Backported from godot4: Add the ability to look-at in model-space. This is a much simpler attempt to solve the same problem as #76060, but without breaking any compatibility. * Adds a description of what model space is in the Vector3 enums (MODEL_* constants). This has the proper axes laid out for imported 3D assets. * Adds the option to `look_at` using model_space, which uses Vector3.MODEL_FRONT as forward vector. The attempt of this PR is to still break the assumption that there is a single direction of forward (which is not the case in Godot) and make it easier to understand where 3D models are facing, as well as orienting them via look_at. - reduz https://github.com/godotengine/godot/commit/5fdc1232eff45e31ee53f58e618de6c58d3f7203 Also bound the new Basis helper methods. --- core/math/basis.cpp | 29 +++++++++++++++++++---------- core/math/basis.h | 9 ++++----- core/math/transform.cpp | 8 ++++---- core/math/transform.h | 4 ++-- core/variant/variant_call.cpp | 15 +++++++++++++-- doc/classes/Basis.xml | 19 +++++++++++++++++++ doc/classes/Spatial.xml | 8 +++++--- doc/classes/Transform.xml | 3 ++- doc/classes/Vector3.xml | 20 +++++++++++++++++++- scene/main/spatial.cpp | 20 +++++++++----------- scene/main/spatial.h | 4 ++-- 11 files changed, 98 insertions(+), 41 deletions(-) diff --git a/core/math/basis.cpp b/core/math/basis.cpp index 5401d2da0..1089ac5b7 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -217,12 +217,17 @@ Basis Basis::transposed() const { return tr; } -Basis Basis::create_looking_at(const Vector3 &p_target, const Vector3 &p_up) { +Basis Basis::create_looking_at(const Vector3 &p_target, const Vector3 &p_up, bool p_use_model_front) { #ifdef MATH_CHECKS ERR_FAIL_COND_V_MSG(p_target.is_equal_approx(Vector3()), Basis(), "The target vector can't be zero."); ERR_FAIL_COND_V_MSG(p_up.is_equal_approx(Vector3()), Basis(), "The up vector can't be zero."); #endif - Vector3 v_z = -p_target.normalized(); + Vector3 v_z = p_target.normalized(); + + if (!p_use_model_front) { + v_z = -v_z; + } + Vector3 v_x = p_up.cross(v_z); #ifdef MATH_CHECKS ERR_FAIL_COND_V_MSG(v_x.is_equal_approx(Vector3()), Basis(), "The target vector and up vector can't be parallel to each other."); @@ -235,19 +240,20 @@ Basis Basis::create_looking_at(const Vector3 &p_target, const Vector3 &p_up) { return basis; } -Basis Basis::create_from_scale(const Vector3 &p_scale) { - return Basis(p_scale.x, 0, 0, 0, p_scale.y, 0, 0, 0, p_scale.z); +Basis Basis::looking_at(const Vector3 &p_target, const Vector3 &p_up, bool p_use_model_front) { + return Basis::create_looking_at(p_target, p_up, p_use_model_front); } - -Basis Basis::looking_at(const Vector3 &p_target, const Vector3 &p_up) { - return Basis::create_looking_at(p_target, p_up); -} -void Basis::set_look_at(const Vector3 &p_target, const Vector3 &p_up) { +void Basis::set_look_at(const Vector3 &p_target, const Vector3 &p_up, bool p_use_model_front) { #ifdef MATH_CHECKS ERR_FAIL_COND_MSG(p_target.is_equal_approx(Vector3()), "The target vector can't be zero."); ERR_FAIL_COND_MSG(p_up.is_equal_approx(Vector3()), "The up vector can't be zero."); #endif - Vector3 v_z = -p_target.normalized(); + Vector3 v_z = p_target.normalized(); + + if (!p_use_model_front) { + v_z = -v_z; + } + Vector3 v_x = p_up.cross(v_z); #ifdef MATH_CHECKS ERR_FAIL_COND_MSG(v_x.is_equal_approx(Vector3()), "The target vector and up vector can't be parallel to each other."); @@ -258,6 +264,9 @@ void Basis::set_look_at(const Vector3 &p_target, const Vector3 &p_up) { set_columns(v_x, v_y, v_z); } +Basis Basis::create_from_scale(const Vector3 &p_scale) { + return Basis(p_scale.x, 0, 0, 0, p_scale.y, 0, 0, 0, p_scale.z); +} Basis Basis::from_scale(const Vector3 &p_scale) { return Basis::create_from_scale(p_scale); } diff --git a/core/math/basis.h b/core/math/basis.h index 9c32b7fb4..730187ff1 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -286,12 +286,11 @@ struct _NO_DISCARD_CLASS_ Basis { // only be used in cases of single normals, or when the basis changes each time. Vector3 xform_normal(const Vector3 &p_vector) const { return get_normal_xform_basis().xform_normal_fast(p_vector); } - static Basis create_looking_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0)); + static Basis create_looking_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0), bool p_use_model_front = false); + Basis looking_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0), bool p_use_model_front = false); + void set_look_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0), bool p_use_model_front = false); + static Basis create_from_scale(const Vector3 &p_scale); - - Basis looking_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0)); - void set_look_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0)); - Basis from_scale(const Vector3 &p_scale); operator Quaternion() const { return get_quaternion(); } diff --git a/core/math/transform.cpp b/core/math/transform.cpp index ec9d69431..f3f3e87a3 100644 --- a/core/math/transform.cpp +++ b/core/math/transform.cpp @@ -82,14 +82,14 @@ void Transform::rotate_basis(const Vector3 &p_axis, real_t p_phi) { basis.rotate(p_axis, p_phi); } -void Transform::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up) { - basis = Basis::create_looking_at(p_target - p_eye, p_up); +void Transform::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up, bool p_use_model_front) { + basis = Basis::create_looking_at(p_target - p_eye, p_up, p_use_model_front); origin = p_eye; } -Transform Transform::looking_at(const Vector3 &p_target, const Vector3 &p_up) const { +Transform Transform::looking_at(const Vector3 &p_target, const Vector3 &p_up, bool p_use_model_front) const { Transform t = *this; - t.set_look_at(origin, p_target, p_up); + t.set_look_at(origin, p_target, p_up,p_use_model_front); return t; } diff --git a/core/math/transform.h b/core/math/transform.h index 135b207b4..28b86ef7a 100644 --- a/core/math/transform.h +++ b/core/math/transform.h @@ -55,8 +55,8 @@ struct _NO_DISCARD_CLASS_ Transform { void rotate_local(const Vector3 &p_axis, real_t p_phi); void rotate_basis(const Vector3 &p_axis, real_t p_phi); - void set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up); - Transform looking_at(const Vector3 &p_target, const Vector3 &p_up) const; + void set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up, bool p_use_model_front = false); + Transform looking_at(const Vector3 &p_target, const Vector3 &p_up, bool p_use_model_front = false) const; void scale(const Vector3 &p_scale); Transform scaled(const Vector3 &p_scale) const; diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 79f625c36..49b3c8c28 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -1541,6 +1541,8 @@ struct _VariantCall { VCALL_PTR0R(Basis, orthogonalized); VCALL_PTR0R(Basis, is_symmetric); VCALL_PTR0R(Basis, diagonalize); + VCALL_PTR3R(Basis, looking_at); + VCALL_PTR3(Basis, set_look_at); static void _call_Basis_xform(Variant &r_ret, Variant &p_self, const Variant **p_args) { switch (p_args[0]->type) { @@ -3375,6 +3377,8 @@ void register_variant_methods() { ADDFUNC0R(BASIS, BASIS, Basis, orthogonalized, varray()); ADDFUNC0R(BASIS, BOOL, Basis, is_symmetric, varray()); ADDFUNC0R(BASIS, BASIS, Basis, diagonalize, varray()); + ADDFUNC3R(BASIS, BASIS, Basis, looking_at, VECTOR3, "target", VECTOR3, "up", BOOL, "use_model_front", varray(Vector3(0, 1, 0), false)); + ADDFUNC3(BASIS, NIL, Basis, set_look_at, VECTOR3, "target", VECTOR3, "up", BOOL, "use_model_front", varray(Vector3(0, 1, 0), false)); ADDFUNC1R(BASIS, VECTOR3, Basis, xform, NIL, "v3_or_v3i", varray()); ADDFUNC1R(BASIS, VECTOR3, Basis, xform_inv, NIL, "v3_or_v3i", varray()); @@ -3387,8 +3391,8 @@ void register_variant_methods() { ADDFUNC2(TRANSFORM, NIL, Transform, rotate, VECTOR3, "axis", REAL, "phi", varray()); ADDFUNC2(TRANSFORM, NIL, Transform, rotate_local, VECTOR3, "axis", REAL, "phi", varray()); ADDFUNC2(TRANSFORM, NIL, Transform, rotate_basis, VECTOR3, "axis", REAL, "phi", varray()); - ADDFUNC3(TRANSFORM, NIL, Transform, set_look_at, VECTOR3, "eye", VECTOR3, "target", VECTOR3, "up", varray()); - ADDFUNC2R(TRANSFORM, TRANSFORM, Transform, looking_at, VECTOR3, "target", VECTOR3, "up", varray()); + ADDFUNC4(TRANSFORM, NIL, Transform, set_look_at, VECTOR3, "eye", VECTOR3, "target", VECTOR3, "up", BOOL, "use_model_front", varray(false)); + ADDFUNC3R(TRANSFORM, TRANSFORM, Transform, looking_at, VECTOR3, "target", VECTOR3, "up", BOOL, "use_model_front", varray(false)); ADDFUNC1(TRANSFORM, NIL, Transform, scale, VECTOR3, "scale", varray()); ADDFUNC1R(TRANSFORM, TRANSFORM, Transform, scaled, VECTOR3, "scale", varray()); ADDFUNC1R(TRANSFORM, TRANSFORM, Transform, scaled_local, VECTOR3, "scale", varray()); @@ -3530,6 +3534,13 @@ void register_variant_methods() { _VariantCall::add_variant_constant(Variant::VECTOR3, "FORWARD", Vector3(0, 0, -1)); _VariantCall::add_variant_constant(Variant::VECTOR3, "BACK", Vector3(0, 0, 1)); + _VariantCall::add_variant_constant(Variant::VECTOR3, "MODEL_LEFT", Vector3(1, 0, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR3, "MODEL_RIGHT", Vector3(-1, 0, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR3, "MODEL_TOP", Vector3(0, 1, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR3, "MODEL_BOTTOM", Vector3(0, -1, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR3, "MODEL_FRONT", Vector3(0, 0, 1)); + _VariantCall::add_variant_constant(Variant::VECTOR3, "MODEL_REAR", Vector3(0, 0, -1)); + _VariantCall::add_constant(Variant::VECTOR3I, "AXIS_X", Vector3i::AXIS_X); _VariantCall::add_constant(Variant::VECTOR3I, "AXIS_Y", Vector3i::AXIS_Y); _VariantCall::add_constant(Variant::VECTOR3I, "AXIS_Z", Vector3i::AXIS_Z); diff --git a/doc/classes/Basis.xml b/doc/classes/Basis.xml index 72bc323fa..8b764e02e 100644 --- a/doc/classes/Basis.xml +++ b/doc/classes/Basis.xml @@ -225,6 +225,25 @@ + + + + + + + Creates a Basis with a rotation such that the forward axis (-Z) points towards the [param target] position. + The up axis (+Y) points as close to the [param up] vector as possible while staying perpendicular to the forward axis. The resulting Basis is orthonormalized. The [param target] and [param up] vectors cannot be zero, and cannot be parallel to each other. + + + + + + + + Sets this Basis with a rotation such that the forward axis (-Z) points towards the [param target] position. + The up axis (+Y) points as close to the [param up] vector as possible while staying perpendicular to the forward axis. The resulting Basis is orthonormalized. The [param target] and [param up] vectors cannot be zero, and cannot be parallel to each other. + + diff --git a/doc/classes/Spatial.xml b/doc/classes/Spatial.xml index 3bb8935fa..182cd78d9 100644 --- a/doc/classes/Spatial.xml +++ b/doc/classes/Spatial.xml @@ -125,9 +125,10 @@ - + + - Rotates the node so that the local forward axis (-Z) points toward the [code]target[/code] position. + Rotates the node so that the local forward axis (-Z, [constant Vector3.FORWARD]) points toward the [code]target[/code] position. If the [param use_model_front] options is specified, then the model is oriented in reverse, towards the model front axis (+Z, [constant Vector3.MODEL_FRONT]), which is more useful for orienting 3D models. The local up axis (+Y) points as close to the [code]up[/code] vector as possible while staying perpendicular to the local forward axis. The resulting transform is orthogonal, and the scale is preserved. Non-uniform scaling may not work correctly. The [code]target[/code] position cannot be the same as the node's position, the [code]up[/code] vector cannot be zero, and the direction from the node's position to the [code]target[/code] vector cannot be parallel to the [code]up[/code] vector. Operations take place in global space. @@ -137,7 +138,8 @@ - + + Moves the node to the specified [code]position[/code], and then rotates itself to point toward the [code]target[/code] as per [method look_at]. Operations take place in global space. diff --git a/doc/classes/Transform.xml b/doc/classes/Transform.xml index 791481d54..b5653739a 100644 --- a/doc/classes/Transform.xml +++ b/doc/classes/Transform.xml @@ -104,8 +104,9 @@ + - Returns a copy of the transform rotated such that its -Z axis points towards the [code]target[/code] position. + Returns a copy of the transform rotated such that its (-Z, [constant Vector3.FORWARD]) axis points towards the [code]target[/code] position. If the [param use_model_front] options is specified, then the model is oriented in reverse, towards the model front axis (+Z, [constant Vector3.MODEL_FRONT]), which is more useful for orienting 3D models. The transform will first be rotated around the given [code]up[/code] vector, and then fully aligned to the target by a further rotation around an axis perpendicular to both the [code]target[/code] and [code]up[/code] vectors. Operations take place in global space. diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml index 5afada672..c7c43145f 100644 --- a/doc/classes/Vector3.xml +++ b/doc/classes/Vector3.xml @@ -389,10 +389,28 @@ Down unit vector. - Forward unit vector. Represents the local direction of forward, and the global direction of north. + Forward unit vector. Represents the local direction of forward, and the global direction of north. Keep in mind that the forward direction for lights, cameras, etc is different from 3D assets like characters, which face towards the camera by convention. Use [constant Vector3.MODEL_FRONT] and similar constants when working in 3D asset space. Back unit vector. Represents the local direction of back, and the global direction of south. + + Unit vector pointing towards the left side of imported 3D assets. + + + Unit vector pointing towards the right side of imported 3D assets. + + + Unit vector pointing towards the top side (up) of imported 3D assets. + + + Unit vector pointing towards the bottom side (down) of imported 3D assets. + + + Unit vector pointing towards the front side (facing forward) of imported 3D assets. + + + Unit vector pointing towards the rear side (back) of imported 3D assets. + diff --git a/scene/main/spatial.cpp b/scene/main/spatial.cpp index e628fe6b2..de84516e2 100644 --- a/scene/main/spatial.cpp +++ b/scene/main/spatial.cpp @@ -900,22 +900,20 @@ void Spatial::set_identity() { set_transform(Transform()); } -void Spatial::look_at(const Vector3 &p_target, const Vector3 &p_up) { +void Spatial::look_at(const Vector3 &p_target, const Vector3 &p_up, bool p_use_model_front) { Vector3 origin(get_global_transform().origin); - look_at_from_position(origin, p_target, p_up); + look_at_from_position(origin, p_target, p_up, p_use_model_front); } -void Spatial::look_at_from_position(const Vector3 &p_pos, const Vector3 &p_target, const Vector3 &p_up) { +void Spatial::look_at_from_position(const Vector3 &p_pos, const Vector3 &p_target, const Vector3 &p_up, bool p_use_model_front) { ERR_FAIL_COND_MSG(p_pos == p_target, "Node origin and target are in the same position, look_at() failed."); ERR_FAIL_COND_MSG(p_up == Vector3(), "The up vector can't be zero, look_at() failed."); ERR_FAIL_COND_MSG(p_up.cross(p_target - p_pos) == Vector3(), "Up vector and direction between node origin and target are aligned, look_at() failed."); - Transform lookat; - lookat.origin = p_pos; - - Vector3 original_scale(get_scale()); - lookat = lookat.looking_at(p_target, p_up); - set_global_transform(lookat); + Vector3 forward = p_target - p_pos; + Basis lookat_basis = Basis::create_looking_at(forward, p_up, p_use_model_front); + Vector3 original_scale = get_scale(); + set_global_transform(Transform(lookat_basis, p_pos)); set_scale(original_scale); } @@ -1048,8 +1046,8 @@ void Spatial::_bind_methods() { ClassDB::bind_method(D_METHOD("orthonormalize"), &Spatial::orthonormalize); ClassDB::bind_method(D_METHOD("set_identity"), &Spatial::set_identity); - ClassDB::bind_method(D_METHOD("look_at", "target", "up"), &Spatial::look_at); - ClassDB::bind_method(D_METHOD("look_at_from_position", "position", "target", "up"), &Spatial::look_at_from_position); + ClassDB::bind_method(D_METHOD("look_at", "target", "up", "use_model_front"), &Spatial::look_at, DEFVAL(Vector3(0, 1, 0)), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("look_at_from_position", "position", "target", "up", "use_model_front"), &Spatial::look_at_from_position, DEFVAL(Vector3(0, 1, 0)), DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_merging_mode", "mode"), &Spatial::set_merging_mode); ClassDB::bind_method(D_METHOD("get_merging_mode"), &Spatial::get_merging_mode); diff --git a/scene/main/spatial.h b/scene/main/spatial.h index 579ebe5be..84f79cbac 100644 --- a/scene/main/spatial.h +++ b/scene/main/spatial.h @@ -237,8 +237,8 @@ public: void global_scale(const Vector3 &p_scale); void global_translate(const Vector3 &p_offset); - void look_at(const Vector3 &p_target, const Vector3 &p_up); - void look_at_from_position(const Vector3 &p_pos, const Vector3 &p_target, const Vector3 &p_up); + void look_at(const Vector3 &p_target, const Vector3 &p_up, bool p_use_model_front = false); + void look_at_from_position(const Vector3 &p_pos, const Vector3 &p_target, const Vector3 &p_up, bool p_use_model_front = false); Vector3 to_local(Vector3 p_global) const; Vector3 to_global(Vector3 p_local) const; From 506a0756c5d1d41f1f8a114801d60e41004b8115 Mon Sep 17 00:00:00 2001 From: Relintai Date: Mon, 30 Sep 2024 17:26:29 +0200 Subject: [PATCH 7/8] Update gdnative api. --- modules/gdnative/gdnative/basis.cpp | 13 +++++++++++-- modules/gdnative/gdnative/transform.cpp | 8 ++++---- modules/gdnative/gdnative_api.json | 20 +++++++++++++++++--- modules/gdnative/include/gdn/basis.h | 3 ++- modules/gdnative/include/gdn/transform.h | 4 ++-- 5 files changed, 36 insertions(+), 12 deletions(-) diff --git a/modules/gdnative/gdnative/basis.cpp b/modules/gdnative/gdnative/basis.cpp index 1f829e6f8..a040143ae 100644 --- a/modules/gdnative/gdnative/basis.cpp +++ b/modules/gdnative/gdnative/basis.cpp @@ -691,12 +691,21 @@ pandemonium_vector3 GDAPI pandemonium_basis_xform_normal(const pandemonium_basis return dest; } -pandemonium_basis GDAPI pandemonium_basis_looking_at(const pandemonium_vector3 *p_target) { +pandemonium_basis GDAPI pandemonium_basis_looking_at(const pandemonium_vector3 *p_target, const pandemonium_vector3 *p_up, const pandemonium_bool p_use_model_front) { pandemonium_basis dest; const Vector3 *target = (const Vector3 *)p_target; - *((Basis *)&dest) = Basis::create_looking_at(*target); + const Vector3 *up = (const Vector3 *)p_up; + *((Basis *)&dest) = Basis::create_looking_at(*target, *up, p_use_model_front); return dest; } + +void GDAPI pandemonium_basis_set_look_at(pandemonium_basis *p_self, const pandemonium_vector3 *p_target, const pandemonium_vector3 *p_up, const pandemonium_bool p_use_model_front) { + Basis *self = (Basis *)p_self; + const Vector3 *target = (const Vector3 *)p_target; + const Vector3 *up = (const Vector3 *)p_up; + self->set_look_at(*target, *up, p_use_model_front); +} + pandemonium_basis GDAPI pandemonium_basis_looking_at_up(const pandemonium_vector3 *p_target, const pandemonium_vector3 *p_up) { pandemonium_basis dest; const Vector3 *target = (const Vector3 *)p_target; diff --git a/modules/gdnative/gdnative/transform.cpp b/modules/gdnative/gdnative/transform.cpp index 59cd5bd5a..521024497 100644 --- a/modules/gdnative/gdnative/transform.cpp +++ b/modules/gdnative/gdnative/transform.cpp @@ -94,20 +94,20 @@ void GDAPI pandemonium_transform_rotate_basis(pandemonium_transform *p_self, con self->rotate_basis(*axis, p_phi); } -void GDAPI pandemonium_transform_set_look_at(pandemonium_transform *p_self, const pandemonium_vector3 *p_eye, const pandemonium_vector3 *p_target, const pandemonium_vector3 *p_up) { +void GDAPI pandemonium_transform_set_look_at(pandemonium_transform *p_self, const pandemonium_vector3 *p_eye, const pandemonium_vector3 *p_target, const pandemonium_vector3 *p_up, const pandemonium_bool p_use_model_front) { Transform *self = (Transform *)p_self; const Vector3 *eye = (const Vector3 *)p_eye; const Vector3 *target = (const Vector3 *)p_target; const Vector3 *up = (const Vector3 *)p_up; - self->set_look_at(*eye, *target, *up); + self->set_look_at(*eye, *target, *up, p_use_model_front); } -pandemonium_transform GDAPI pandemonium_transform_looking_at(const pandemonium_transform *p_self, const pandemonium_vector3 *p_target, const pandemonium_vector3 *p_up) { +pandemonium_transform GDAPI pandemonium_transform_looking_at(const pandemonium_transform *p_self, const pandemonium_vector3 *p_target, const pandemonium_vector3 *p_up, const pandemonium_bool p_use_model_front) { pandemonium_transform dest; const Transform *self = (const Transform *)p_self; const Vector3 *target = (const Vector3 *)p_target; const Vector3 *up = (const Vector3 *)p_up; - *((Transform *)&dest) = self->looking_at(*target, *up); + *((Transform *)&dest) = self->looking_at(*target, *up, p_use_model_front); return dest; } diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index 2d77d2b06..49046b902 100644 --- a/modules/gdnative/gdnative_api.json +++ b/modules/gdnative/gdnative_api.json @@ -1699,7 +1699,19 @@ "name": "pandemonium_basis_looking_at", "return_type": "pandemonium_basis", "arguments": [ - ["const pandemonium_vector3 *", "p_target"] + ["const pandemonium_vector3 *", "p_target"], + ["const pandemonium_vector3 *", "p_up"], + ["const pandemonium_bool", "p_use_model_front"] + ] + }, + { + "name": "pandemonium_basis_set_look_at", + "return_type": "void", + "arguments": [ + ["pandemonium_basis *", "p_self"], + ["const pandemonium_vector3 *", "p_target"], + ["const pandemonium_vector3 *", "p_up"], + ["const pandemonium_bool", "p_use_model_front"] ] }, { @@ -6733,7 +6745,8 @@ ["pandemonium_transform *", "p_self"], ["const pandemonium_vector3 *", "p_eye"], ["const pandemonium_vector3 *", "p_target"], - ["const pandemonium_vector3 *", "p_up"] + ["const pandemonium_vector3 *", "p_up"], + ["const pandemonium_bool", "p_use_model_front"] ] }, { @@ -6742,7 +6755,8 @@ "arguments": [ ["const pandemonium_transform *", "p_self"], ["const pandemonium_vector3 *", "p_target"], - ["const pandemonium_vector3 *", "p_up"] + ["const pandemonium_vector3 *", "p_up"], + ["const pandemonium_bool", "p_use_model_front"] ] }, { diff --git a/modules/gdnative/include/gdn/basis.h b/modules/gdnative/include/gdn/basis.h index 7658d7611..d69032107 100644 --- a/modules/gdnative/include/gdn/basis.h +++ b/modules/gdnative/include/gdn/basis.h @@ -213,7 +213,8 @@ pandemonium_basis GDAPI pandemonium_basis_get_normal_xform_basis(const pandemoni pandemonium_vector3 GDAPI pandemonium_basis_xform_normal_fast(const pandemonium_basis *p_self, const pandemonium_vector3 *p_vector); pandemonium_vector3 GDAPI pandemonium_basis_xform_normal(const pandemonium_basis *p_self, const pandemonium_vector3 *p_vector); -pandemonium_basis GDAPI pandemonium_basis_looking_at(const pandemonium_vector3 *p_target); +pandemonium_basis GDAPI pandemonium_basis_looking_at(const pandemonium_vector3 *p_target, const pandemonium_vector3 *p_up, const pandemonium_bool p_use_model_front); +void GDAPI pandemonium_basis_set_look_at(pandemonium_basis *p_self, const pandemonium_vector3 *p_target, const pandemonium_vector3 *p_up, const pandemonium_bool p_use_model_front); pandemonium_basis GDAPI pandemonium_basis_looking_at_up(const pandemonium_vector3 *p_target, const pandemonium_vector3 *p_up); pandemonium_basis GDAPI pandemonium_basis_from_scale(const pandemonium_vector3 *p_scale); diff --git a/modules/gdnative/include/gdn/transform.h b/modules/gdnative/include/gdn/transform.h index e31f397bd..e3ee8cc94 100644 --- a/modules/gdnative/include/gdn/transform.h +++ b/modules/gdnative/include/gdn/transform.h @@ -76,9 +76,9 @@ void GDAPI pandemonium_transform_rotate(pandemonium_transform *p_self, const pan void GDAPI pandemonium_transform_rotate_local(pandemonium_transform *p_self, const pandemonium_vector3 *p_axis, pandemonium_real p_phi); void GDAPI pandemonium_transform_rotate_basis(pandemonium_transform *p_self, const pandemonium_vector3 *p_axis, pandemonium_real p_phi); -void GDAPI pandemonium_transform_set_look_at(pandemonium_transform *p_self, const pandemonium_vector3 *p_eye, const pandemonium_vector3 *p_target, const pandemonium_vector3 *p_up); +void GDAPI pandemonium_transform_set_look_at(pandemonium_transform *p_self, const pandemonium_vector3 *p_eye, const pandemonium_vector3 *p_target, const pandemonium_vector3 *p_up, const pandemonium_bool p_use_model_front); -pandemonium_transform GDAPI pandemonium_transform_looking_at(const pandemonium_transform *p_self, const pandemonium_vector3 *p_target, const pandemonium_vector3 *p_up); +pandemonium_transform GDAPI pandemonium_transform_looking_at(const pandemonium_transform *p_self, const pandemonium_vector3 *p_target, const pandemonium_vector3 *p_up, const pandemonium_bool p_use_model_front); void GDAPI pandemonium_transform_scale(pandemonium_transform *p_self, const pandemonium_vector3 *p_scale); pandemonium_transform GDAPI pandemonium_transform_scaled(const pandemonium_transform *p_self, const pandemonium_vector3 *p_scale); From a59cb3956b4dbca68297b5ca2dc84fce5178760b Mon Sep 17 00:00:00 2001 From: Relintai Date: Mon, 30 Sep 2024 18:55:39 +0200 Subject: [PATCH 8/8] Backported from godot 4: Make SkeletonIk3D node usable - warriormaster12 https://github.com/godotengine/godot/commit/ddf93f3f59aa5b31908792821e3dfa11ab7b8673 --- .../skeleton_3d/editor/skeleton_ik_editor_plugin.cpp | 10 ++-------- modules/skeleton_3d/nodes/skeleton_ik.cpp | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/modules/skeleton_3d/editor/skeleton_ik_editor_plugin.cpp b/modules/skeleton_3d/editor/skeleton_ik_editor_plugin.cpp index df7bc7582..9d3eabf9a 100644 --- a/modules/skeleton_3d/editor/skeleton_ik_editor_plugin.cpp +++ b/modules/skeleton_3d/editor/skeleton_ik_editor_plugin.cpp @@ -52,24 +52,18 @@ void SkeletonIKEditorPlugin::_play() { skeleton_ik->start(); } else { skeleton_ik->stop(); - skeleton_ik->get_parent_skeleton()->clear_bones_global_pose_override(); } } void SkeletonIKEditorPlugin::edit(Object *p_object) { - if (p_object != skeleton_ik) { - if (skeleton_ik) { - play_btn->set_pressed(false); - _play(); - } - } - SkeletonIK *s = Object::cast_to(p_object); if (!s) { return; } skeleton_ik = s; + + play_btn->set_pressed(skeleton_ik->is_running()); } bool SkeletonIKEditorPlugin::handles(Object *p_object) const { diff --git a/modules/skeleton_3d/nodes/skeleton_ik.cpp b/modules/skeleton_3d/nodes/skeleton_ik.cpp index 77e9fe9d6..b5b0c27d1 100644 --- a/modules/skeleton_3d/nodes/skeleton_ik.cpp +++ b/modules/skeleton_3d/nodes/skeleton_ik.cpp @@ -425,7 +425,7 @@ void SkeletonIK::_notification(int p_what) { } break; case NOTIFICATION_EXIT_TREE: { - reload_chain(); + stop(); } break; } }