From 1d8cef82366b989a920c6cdedde817d4a360e538 Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Thu, 4 Nov 2021 18:17:41 -0500 Subject: [PATCH] [3.x] Backport some APIs in math structs --- core/math/rect2.h | 4 ++ core/math/vector2.cpp | 12 ++++ core/math/vector2.h | 1 + core/math/vector3.cpp | 11 ++++ core/math/vector3.h | 1 + core/variant_call.cpp | 8 +++ doc/classes/AABB.xml | 6 ++ doc/classes/Rect2.xml | 6 ++ doc/classes/Vector2.xml | 8 +++ doc/classes/Vector3.xml | 7 +++ modules/gdnative/gdnative/vector2.cpp | 2 +- .../glue/GodotSharp/GodotSharp/Core/AABB.cs | 10 ++++ .../glue/GodotSharp/GodotSharp/Core/Color.cs | 58 +++++++++++++++++++ .../glue/GodotSharp/GodotSharp/Core/Rect2.cs | 10 ++++ .../GodotSharp/GodotSharp/Core/Vector2.cs | 20 +++++++ .../GodotSharp/GodotSharp/Core/Vector3.cs | 19 ++++++ servers/physics_2d/joints_2d_sw.cpp | 4 +- 17 files changed, 184 insertions(+), 3 deletions(-) diff --git a/core/math/rect2.h b/core/math/rect2.h index 65773cec67d..48a04f94916 100644 --- a/core/math/rect2.h +++ b/core/math/rect2.h @@ -46,6 +46,8 @@ struct Rect2 { real_t get_area() const { return size.width * size.height; } + _FORCE_INLINE_ Vector2 get_center() const { return position + (size * 0.5); } + inline bool intersects(const Rect2 &p_rect, const bool p_include_borders = false) const { if (p_include_borders) { if (position.x > (p_rect.position.x + p_rect.size.width)) { @@ -268,6 +270,8 @@ struct Rect2i { int get_area() const { return size.width * size.height; } + _FORCE_INLINE_ Vector2i get_center() const { return position + (size / 2); } + inline bool intersects(const Rect2i &p_rect) const { if (position.x > (p_rect.position.x + p_rect.size.width)) { return false; diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp index eea9975b687..0ddc6a3aa12 100644 --- a/core/math/vector2.cpp +++ b/core/math/vector2.cpp @@ -128,6 +128,7 @@ Vector2 Vector2::snapped(const Vector2 &p_by) const { } Vector2 Vector2::clamped(real_t p_len) const { + WARN_DEPRECATED_MSG("'Vector2.clamped()' is deprecated because it has been renamed to 'limit_length'."); real_t l = length(); Vector2 v = *this; if (l > 0 && p_len < l) { @@ -138,6 +139,17 @@ Vector2 Vector2::clamped(real_t p_len) const { return v; } +Vector2 Vector2::limit_length(const real_t p_len) const { + const real_t l = length(); + Vector2 v = *this; + if (l > 0 && p_len < l) { + v /= l; + v *= p_len; + } + + return v; +} + Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_weight) const { Vector2 p0 = p_pre_a; Vector2 p1 = *this; diff --git a/core/math/vector2.h b/core/math/vector2.h index 96ff644905d..be68989c7c6 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -100,6 +100,7 @@ struct Vector2 { Vector2 plane_project(real_t p_d, const Vector2 &p_vec) const; Vector2 clamped(real_t p_len) const; + Vector2 limit_length(const real_t p_len = 1.0) const; _FORCE_INLINE_ static Vector2 linear_interpolate(const Vector2 &p_a, const Vector2 &p_b, real_t p_weight); _FORCE_INLINE_ Vector2 linear_interpolate(const Vector2 &p_to, real_t p_weight) const; diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp index 17eebaad0f0..e8486aadabe 100644 --- a/core/math/vector3.cpp +++ b/core/math/vector3.cpp @@ -62,6 +62,17 @@ Vector3 Vector3::snapped(Vector3 p_val) const { return v; } +Vector3 Vector3::limit_length(const real_t p_len) const { + const real_t l = length(); + Vector3 v = *this; + if (l > 0 && p_len < l) { + v /= l; + v *= p_len; + } + + return v; +} + Vector3 Vector3::cubic_interpolaten(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, real_t p_weight) const { Vector3 p0 = p_pre_a; Vector3 p1 = *this; diff --git a/core/math/vector3.h b/core/math/vector3.h index 43e87062b66..5510fa884d5 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -85,6 +85,7 @@ struct Vector3 { _FORCE_INLINE_ Vector3 normalized() const; _FORCE_INLINE_ bool is_normalized() const; _FORCE_INLINE_ Vector3 inverse() const; + Vector3 limit_length(const real_t p_len = 1.0) const; _FORCE_INLINE_ void zero(); diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 4a44cf641c0..44f84479e8b 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -406,9 +406,11 @@ struct _VariantCall { VCALL_LOCALMEM1R(Vector2, cross); VCALL_LOCALMEM0R(Vector2, abs); VCALL_LOCALMEM1R(Vector2, clamped); + VCALL_LOCALMEM1R(Vector2, limit_length); VCALL_LOCALMEM0R(Vector2, sign); VCALL_LOCALMEM0R(Rect2, get_area); + VCALL_LOCALMEM0R(Rect2, get_center); VCALL_LOCALMEM0R(Rect2, has_no_area); VCALL_LOCALMEM1R(Rect2, has_point); VCALL_LOCALMEM1R(Rect2, is_equal_approx); @@ -455,6 +457,7 @@ struct _VariantCall { VCALL_LOCALMEM1R(Vector3, slide); VCALL_LOCALMEM1R(Vector3, bounce); VCALL_LOCALMEM1R(Vector3, reflect); + VCALL_LOCALMEM1R(Vector3, limit_length); VCALL_LOCALMEM0R(Vector3, sign); VCALL_LOCALMEM0R(Plane, normalized); @@ -792,6 +795,7 @@ struct _VariantCall { VCALL_PTR0R(AABB, abs); VCALL_PTR0R(AABB, get_area); + VCALL_PTR0R(AABB, get_center); VCALL_PTR0R(AABB, has_no_area); VCALL_PTR0R(AABB, has_no_surface); VCALL_PTR1R(AABB, has_point); @@ -1754,9 +1758,11 @@ void register_variant_methods() { ADDFUNC1R(VECTOR2, REAL, Vector2, cross, VECTOR2, "with", varray()); ADDFUNC0R(VECTOR2, VECTOR2, Vector2, abs, varray()); ADDFUNC1R(VECTOR2, VECTOR2, Vector2, clamped, REAL, "length", varray()); + ADDFUNC1R(VECTOR2, VECTOR2, Vector2, limit_length, REAL, "length", varray(1.0)); ADDFUNC0R(VECTOR2, VECTOR2, Vector2, sign, varray()); ADDFUNC0R(RECT2, REAL, Rect2, get_area, varray()); + ADDFUNC0R(RECT2, VECTOR2, Rect2, get_center, varray()); ADDFUNC0R(RECT2, BOOL, Rect2, has_no_area, varray()); ADDFUNC1R(RECT2, BOOL, Rect2, has_point, VECTOR2, "point", varray()); ADDFUNC1R(RECT2, BOOL, Rect2, is_equal_approx, RECT2, "rect", varray()); @@ -1803,6 +1809,7 @@ void register_variant_methods() { ADDFUNC1R(VECTOR3, VECTOR3, Vector3, slide, VECTOR3, "n", varray()); ADDFUNC1R(VECTOR3, VECTOR3, Vector3, bounce, VECTOR3, "n", varray()); ADDFUNC1R(VECTOR3, VECTOR3, Vector3, reflect, VECTOR3, "n", varray()); + ADDFUNC1R(VECTOR3, VECTOR3, Vector3, limit_length, REAL, "length", varray(1.0)); ADDFUNC0R(VECTOR3, VECTOR3, Vector3, sign, varray()); ADDFUNC0R(PLANE, PLANE, Plane, normalized, varray()); @@ -1996,6 +2003,7 @@ void register_variant_methods() { ADDFUNC0R(AABB, AABB, AABB, abs, varray()); ADDFUNC0R(AABB, REAL, AABB, get_area, varray()); + ADDFUNC0R(AABB, VECTOR3, AABB, get_center, varray()); ADDFUNC0R(AABB, BOOL, AABB, has_no_area, varray()); ADDFUNC0R(AABB, BOOL, AABB, has_no_surface, varray()); ADDFUNC1R(AABB, BOOL, AABB, has_point, VECTOR3, "point", varray()); diff --git a/doc/classes/AABB.xml b/doc/classes/AABB.xml index 8bcce70f871..502e7b59a9e 100644 --- a/doc/classes/AABB.xml +++ b/doc/classes/AABB.xml @@ -55,6 +55,12 @@ Returns the volume of the [AABB]. + + + + Returns the center of the [AABB], which is equal to [member position] + ([member size] / 2). + + diff --git a/doc/classes/Rect2.xml b/doc/classes/Rect2.xml index 00469002c96..7f1a9fe72c2 100644 --- a/doc/classes/Rect2.xml +++ b/doc/classes/Rect2.xml @@ -72,6 +72,12 @@ Returns the area of the [Rect2]. + + + + Returns the center of the [Rect2], which is equal to [member position] + ([member size] / 2). + + diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml index d936680a629..4ade0853508 100644 --- a/doc/classes/Vector2.xml +++ b/doc/classes/Vector2.xml @@ -78,6 +78,7 @@ + Deprecated, please use [method limit_length] instead. Returns the vector with a maximum length by limiting its length to [code]length[/code]. @@ -162,6 +163,13 @@ This method runs faster than [method length], so prefer it if you need to compare vectors or need the squared distance for some formula. + + + + + Returns the vector with a maximum length by limiting its length to [code]length[/code]. + + diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml index 15411e9be6a..d217a11f298 100644 --- a/doc/classes/Vector3.xml +++ b/doc/classes/Vector3.xml @@ -138,6 +138,13 @@ This method runs faster than [method length], so prefer it if you need to compare vectors or need the squared distance for some formula. + + + + + Returns the vector with a maximum length by limiting its length to [code]length[/code]. + + diff --git a/modules/gdnative/gdnative/vector2.cpp b/modules/gdnative/gdnative/vector2.cpp index 9c8ad3ab609..c968fc12b40 100644 --- a/modules/gdnative/gdnative/vector2.cpp +++ b/modules/gdnative/gdnative/vector2.cpp @@ -212,7 +212,7 @@ godot_vector2 GDAPI godot_vector2_clamped(const godot_vector2 *p_self, const god godot_vector2 dest; const Vector2 *self = (const Vector2 *)p_self; - *((Vector2 *)&dest) = self->clamped(p_length); + *((Vector2 *)&dest) = self->limit_length(p_length); return dest; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs index 1a286ae1448..ffda4b67444 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs @@ -66,6 +66,16 @@ namespace Godot return new AABB(topLeft, _size.Abs()); } + /// + /// Returns the center of the , which is equal + /// to + ( / 2). + /// + /// The center. + public Vector3 GetCenter() + { + return _position + (_size * 0.5f); + } + /// /// Returns if this completely encloses another one. /// diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs index 684650a815e..89870c13232 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs @@ -946,6 +946,64 @@ namespace Godot return left.r > right.r; } + /// + /// Compares two s by first checking if + /// the red value of the color is less than + /// or equal to the red value of the color. + /// If the red values are exactly equal, then it repeats this check + /// with the green values of the two colors, then with the blue values, + /// and then with the alpha value. + /// This operator is useful for sorting colors. + /// + /// The left color. + /// The right color. + /// Whether or not the left is less than or equal to the right. + public static bool operator <=(Color left, Color right) + { + if (left.r == right.r) + { + if (left.g == right.g) + { + if (left.b == right.b) + { + return left.a <= right.a; + } + return left.b < right.b; + } + return left.g < right.g; + } + return left.r < right.r; + } + + /// + /// Compares two s by first checking if + /// the red value of the color is greater than + /// or equal to the red value of the color. + /// If the red values are exactly equal, then it repeats this check + /// with the green values of the two colors, then with the blue values, + /// and then with the alpha value. + /// This operator is useful for sorting colors. + /// + /// The left color. + /// The right color. + /// Whether or not the left is greater than or equal to the right. + public static bool operator >=(Color left, Color right) + { + if (left.r == right.r) + { + if (left.g == right.g) + { + if (left.b == right.b) + { + return left.a >= right.a; + } + return left.b > right.b; + } + return left.g > right.g; + } + return left.r > right.r; + } + /// /// Returns if this color and are equal. /// diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs index acfa3107a2e..b6117002694 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs @@ -161,6 +161,16 @@ namespace Godot return _size.x * _size.y; } + /// + /// Returns the center of the , which is equal + /// to + ( / 2). + /// + /// The center. + public Vector2 GetCenter() + { + return _position + (_size * 0.5f); + } + /// /// Returns a copy of the grown a given amount of units towards /// all the sides. diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs index a6ea34a1fe7..1916cf61a77 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs @@ -171,6 +171,7 @@ namespace Godot /// /// The length to limit to. /// The vector with its length limited. + [Obsolete("Clamped is deprecated because it has been renamed to LimitLength.")] public Vector2 Clamped(real_t length) { var v = this; @@ -347,6 +348,25 @@ namespace Godot ); } + /// + /// Returns the vector with a maximum length by limiting its length to . + /// + /// The length to limit to. + /// The vector with its length limited. + public Vector2 LimitLength(real_t length = 1.0f) + { + Vector2 v = this; + real_t l = Length(); + + if (l > 0 && length < l) + { + v /= l; + v *= length; + } + + return v; + } + /// /// Returns the axis of the vector's largest value. See . /// If both components are equal, this method returns . diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs index 1f83dbbf10d..281abcaf08a 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs @@ -326,6 +326,25 @@ namespace Godot ); } + /// + /// Returns the vector with a maximum length by limiting its length to . + /// + /// The length to limit to. + /// The vector with its length limited. + public Vector3 LimitLength(real_t length = 1.0f) + { + Vector3 v = this; + real_t l = Length(); + + if (l > 0 && length < l) + { + v /= l; + v *= length; + } + + return v; + } + /// /// Returns the axis of the vector's largest value. See . /// If all components are equal, this method returns . diff --git a/servers/physics_2d/joints_2d_sw.cpp b/servers/physics_2d/joints_2d_sw.cpp index 51f83d047bf..c424251af8e 100644 --- a/servers/physics_2d/joints_2d_sw.cpp +++ b/servers/physics_2d/joints_2d_sw.cpp @@ -307,7 +307,7 @@ bool GrooveJoint2DSW::setup(real_t p_step) { Vector2 delta = (B->get_transform().get_origin() + rB) - (A->get_transform().get_origin() + rA); real_t _b = get_bias(); - gbias = (delta * -(_b == 0 ? space->get_constraint_bias() : _b) * (1.0 / p_step)).clamped(get_max_bias()); + gbias = (delta * -(_b == 0 ? space->get_constraint_bias() : _b) * (1.0 / p_step)).limit_length(get_max_bias()); // apply accumulated impulse A->apply_impulse(rA, -jn_acc); @@ -325,7 +325,7 @@ void GrooveJoint2DSW::solve(real_t p_step) { Vector2 jOld = jn_acc; j += jOld; - jn_acc = (((clamp * j.cross(xf_normal)) > 0) ? j : j.project(xf_normal)).clamped(jn_max); + jn_acc = (((clamp * j.cross(xf_normal)) > 0) ? j : j.project(xf_normal)).limit_length(jn_max); j = jn_acc - jOld;