From b65970860e2cb0b255528553392965b893cbb35f Mon Sep 17 00:00:00 2001 From: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com> Date: Sun, 3 Mar 2024 19:47:59 +0100 Subject: [PATCH] Add scalar versions of `Vector*` `min/max/clamp/snap(ped)` Also added `snapped` to the integer vectors for completeness --- include/godot_cpp/variant/aabb.hpp | 2 +- include/godot_cpp/variant/rect2.hpp | 14 +++++--------- include/godot_cpp/variant/rect2i.hpp | 14 +++++--------- include/godot_cpp/variant/vector2.hpp | 10 ++++++++++ include/godot_cpp/variant/vector2i.hpp | 11 +++++++++++ include/godot_cpp/variant/vector3.hpp | 11 +++++++++++ include/godot_cpp/variant/vector3i.hpp | 11 +++++++++++ include/godot_cpp/variant/vector4.hpp | 11 +++++++++++ include/godot_cpp/variant/vector4i.hpp | 11 +++++++++++ src/variant/vector2.cpp | 12 ++++++++++++ src/variant/vector2i.cpp | 18 ++++++++++++++++++ src/variant/vector3.cpp | 19 +++++++++++++++++++ src/variant/vector3i.cpp | 21 +++++++++++++++++++++ src/variant/vector4.cpp | 21 +++++++++++++++++++++ src/variant/vector4i.cpp | 24 ++++++++++++++++++++++++ 15 files changed, 191 insertions(+), 19 deletions(-) diff --git a/include/godot_cpp/variant/aabb.hpp b/include/godot_cpp/variant/aabb.hpp index 7706d511..8f2bce76 100644 --- a/include/godot_cpp/variant/aabb.hpp +++ b/include/godot_cpp/variant/aabb.hpp @@ -102,7 +102,7 @@ struct _NO_DISCARD_ AABB { _FORCE_INLINE_ void expand_to(const Vector3 &p_vector); /** expand to contain a point if necessary */ _FORCE_INLINE_ AABB abs() const { - return AABB(Vector3(position.x + MIN(size.x, (real_t)0), position.y + MIN(size.y, (real_t)0), position.z + MIN(size.z, (real_t)0)), size.abs()); + return AABB(position + size.minf(0), size.abs()); } Variant intersects_segment_bind(const Vector3 &p_from, const Vector3 &p_to) const; diff --git a/include/godot_cpp/variant/rect2.hpp b/include/godot_cpp/variant/rect2.hpp index cfd24b2f..201e02ba 100644 --- a/include/godot_cpp/variant/rect2.hpp +++ b/include/godot_cpp/variant/rect2.hpp @@ -154,14 +154,12 @@ struct _NO_DISCARD_ Rect2 { return Rect2(); } - new_rect.position.x = Math::max(p_rect.position.x, position.x); - new_rect.position.y = Math::max(p_rect.position.y, position.y); + new_rect.position = p_rect.position.max(position); Point2 p_rect_end = p_rect.position + p_rect.size; Point2 end = position + size; - new_rect.size.x = Math::min(p_rect_end.x, end.x) - new_rect.position.x; - new_rect.size.y = Math::min(p_rect_end.y, end.y) - new_rect.position.y; + new_rect.size = p_rect_end.min(end) - new_rect.position; return new_rect; } @@ -174,11 +172,9 @@ struct _NO_DISCARD_ Rect2 { #endif Rect2 new_rect; - new_rect.position.x = Math::min(p_rect.position.x, position.x); - new_rect.position.y = Math::min(p_rect.position.y, position.y); + new_rect.position = p_rect.position.min(position); - new_rect.size.x = Math::max(p_rect.position.x + p_rect.size.x, position.x + size.x); - new_rect.size.y = Math::max(p_rect.position.y + p_rect.size.y, position.y + size.y); + new_rect.size = (p_rect.position + p_rect.size).max(position + size); new_rect.size = new_rect.size - new_rect.position; // Make relative again. @@ -283,7 +279,7 @@ struct _NO_DISCARD_ Rect2 { } _FORCE_INLINE_ Rect2 abs() const { - return Rect2(Point2(position.x + Math::min(size.x, (real_t)0), position.y + Math::min(size.y, (real_t)0)), size.abs()); + return Rect2(position + size.minf(0), size.abs()); } Vector2 get_support(const Vector2 &p_normal) const { diff --git a/include/godot_cpp/variant/rect2i.hpp b/include/godot_cpp/variant/rect2i.hpp index c2a15ac3..eff49583 100644 --- a/include/godot_cpp/variant/rect2i.hpp +++ b/include/godot_cpp/variant/rect2i.hpp @@ -97,14 +97,12 @@ struct _NO_DISCARD_ Rect2i { return Rect2i(); } - new_rect.position.x = Math::max(p_rect.position.x, position.x); - new_rect.position.y = Math::max(p_rect.position.y, position.y); + new_rect.position = p_rect.position.max(position); Point2i p_rect_end = p_rect.position + p_rect.size; Point2i end = position + size; - new_rect.size.x = Math::min(p_rect_end.x, end.x) - new_rect.position.x; - new_rect.size.y = Math::min(p_rect_end.y, end.y) - new_rect.position.y; + new_rect.size = p_rect_end.min(end) - new_rect.position; return new_rect; } @@ -117,11 +115,9 @@ struct _NO_DISCARD_ Rect2i { #endif Rect2i new_rect; - new_rect.position.x = Math::min(p_rect.position.x, position.x); - new_rect.position.y = Math::min(p_rect.position.y, position.y); + new_rect.position = p_rect.position.min(position); - new_rect.size.x = Math::max(p_rect.position.x + p_rect.size.x, position.x + size.x); - new_rect.size.y = Math::max(p_rect.position.y + p_rect.size.y, position.y + size.y); + new_rect.size = (p_rect.position + p_rect.size).max(position + size); new_rect.size = new_rect.size - new_rect.position; // Make relative again. @@ -219,7 +215,7 @@ struct _NO_DISCARD_ Rect2i { } _FORCE_INLINE_ Rect2i abs() const { - return Rect2i(Point2i(position.x + Math::min(size.x, 0), position.y + Math::min(size.y, 0)), size.abs()); + return Rect2i(position + size.mini(0), size.abs()); } _FORCE_INLINE_ void set_end(const Vector2i &p_end) { diff --git a/include/godot_cpp/variant/vector2.hpp b/include/godot_cpp/variant/vector2.hpp index 13c0da6f..51dd8cce 100644 --- a/include/godot_cpp/variant/vector2.hpp +++ b/include/godot_cpp/variant/vector2.hpp @@ -91,10 +91,18 @@ struct _NO_DISCARD_ Vector2 { return Vector2(MIN(x, p_vector2.x), MIN(y, p_vector2.y)); } + Vector2 minf(real_t p_scalar) const { + return Vector2(MIN(x, p_scalar), MIN(y, p_scalar)); + } + Vector2 max(const Vector2 &p_vector2) const { return Vector2(MAX(x, p_vector2.x), MAX(y, p_vector2.y)); } + Vector2 maxf(real_t p_scalar) const { + return Vector2(MAX(x, p_scalar), MAX(y, p_scalar)); + } + real_t distance_to(const Vector2 &p_vector2) const; real_t distance_squared_to(const Vector2 &p_vector2) const; real_t angle_to(const Vector2 &p_vector2) const; @@ -168,7 +176,9 @@ struct _NO_DISCARD_ Vector2 { Vector2 ceil() const; Vector2 round() const; Vector2 snapped(const Vector2 &p_by) const; + Vector2 snappedf(real_t p_by) const; Vector2 clamp(const Vector2 &p_min, const Vector2 &p_max) const; + Vector2 clampf(real_t p_min, real_t p_max) const; real_t aspect() const { return width / height; } operator String() const; diff --git a/include/godot_cpp/variant/vector2i.hpp b/include/godot_cpp/variant/vector2i.hpp index afeaeead..0d787c3f 100644 --- a/include/godot_cpp/variant/vector2i.hpp +++ b/include/godot_cpp/variant/vector2i.hpp @@ -83,10 +83,18 @@ struct _NO_DISCARD_ Vector2i { return Vector2i(MIN(x, p_vector2i.x), MIN(y, p_vector2i.y)); } + Vector2i mini(int32_t p_scalar) const { + return Vector2i(MIN(x, p_scalar), MIN(y, p_scalar)); + } + Vector2i max(const Vector2i &p_vector2i) const { return Vector2i(MAX(x, p_vector2i.x), MAX(y, p_vector2i.y)); } + Vector2i maxi(int32_t p_scalar) const { + return Vector2i(MAX(x, p_scalar), MAX(y, p_scalar)); + } + Vector2i operator+(const Vector2i &p_v) const; void operator+=(const Vector2i &p_v); Vector2i operator-(const Vector2i &p_v) const; @@ -123,7 +131,10 @@ struct _NO_DISCARD_ Vector2i { real_t aspect() const { return width / (real_t)height; } Vector2i sign() const { return Vector2i(SIGN(x), SIGN(y)); } Vector2i abs() const { return Vector2i(Math::abs(x), Math::abs(y)); } + Vector2i snapped(const Vector2i &p_step) const; + Vector2i snappedi(int32_t p_step) const; Vector2i clamp(const Vector2i &p_min, const Vector2i &p_max) const; + Vector2i clampi(int32_t p_min, int32_t p_max) const; operator String() const; operator Vector2() const; diff --git a/include/godot_cpp/variant/vector3.hpp b/include/godot_cpp/variant/vector3.hpp index a8d96ed0..0d3ad62b 100644 --- a/include/godot_cpp/variant/vector3.hpp +++ b/include/godot_cpp/variant/vector3.hpp @@ -82,10 +82,18 @@ struct _NO_DISCARD_ Vector3 { return Vector3(MIN(x, p_vector3.x), MIN(y, p_vector3.y), MIN(z, p_vector3.z)); } + Vector3 minf(real_t p_scalar) const { + return Vector3(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar)); + } + Vector3 max(const Vector3 &p_vector3) const { return Vector3(MAX(x, p_vector3.x), MAX(y, p_vector3.y), MAX(z, p_vector3.z)); } + Vector3 maxf(real_t p_scalar) const { + return Vector3(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar)); + } + _FORCE_INLINE_ real_t length() const; _FORCE_INLINE_ real_t length_squared() const; @@ -98,7 +106,9 @@ struct _NO_DISCARD_ Vector3 { _FORCE_INLINE_ void zero(); void snap(const Vector3 p_val); + void snapf(real_t p_val); Vector3 snapped(const Vector3 p_val) const; + Vector3 snappedf(real_t p_val) const; void rotate(const Vector3 &p_axis, const real_t p_angle); Vector3 rotated(const Vector3 &p_axis, const real_t p_angle) const; @@ -128,6 +138,7 @@ struct _NO_DISCARD_ Vector3 { _FORCE_INLINE_ Vector3 ceil() const; _FORCE_INLINE_ Vector3 round() const; Vector3 clamp(const Vector3 &p_min, const Vector3 &p_max) const; + Vector3 clampf(real_t p_min, real_t p_max) const; _FORCE_INLINE_ real_t distance_to(const Vector3 &p_to) const; _FORCE_INLINE_ real_t distance_squared_to(const Vector3 &p_to) const; diff --git a/include/godot_cpp/variant/vector3i.hpp b/include/godot_cpp/variant/vector3i.hpp index ae5148ff..b2cdbbdf 100644 --- a/include/godot_cpp/variant/vector3i.hpp +++ b/include/godot_cpp/variant/vector3i.hpp @@ -75,10 +75,18 @@ struct _NO_DISCARD_ Vector3i { return Vector3i(MIN(x, p_vector3i.x), MIN(y, p_vector3i.y), MIN(z, p_vector3i.z)); } + Vector3i mini(int32_t p_scalar) const { + return Vector3i(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar)); + } + Vector3i max(const Vector3i &p_vector3i) const { return Vector3i(MAX(x, p_vector3i.x), MAX(y, p_vector3i.y), MAX(z, p_vector3i.z)); } + Vector3i maxi(int32_t p_scalar) const { + return Vector3i(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar)); + } + _FORCE_INLINE_ int64_t length_squared() const; _FORCE_INLINE_ double length() const; @@ -89,7 +97,10 @@ struct _NO_DISCARD_ Vector3i { _FORCE_INLINE_ Vector3i abs() const; _FORCE_INLINE_ Vector3i sign() const; + Vector3i snapped(const Vector3i &p_step) const; + Vector3i snappedi(int32_t p_step) const; Vector3i clamp(const Vector3i &p_min, const Vector3i &p_max) const; + Vector3i clampi(int32_t p_min, int32_t p_max) const; /* Operators */ diff --git a/include/godot_cpp/variant/vector4.hpp b/include/godot_cpp/variant/vector4.hpp index 26c57c35..a2e8faec 100644 --- a/include/godot_cpp/variant/vector4.hpp +++ b/include/godot_cpp/variant/vector4.hpp @@ -74,10 +74,18 @@ struct _NO_DISCARD_ Vector4 { return Vector4(MIN(x, p_vector4.x), MIN(y, p_vector4.y), MIN(z, p_vector4.z), MIN(w, p_vector4.w)); } + Vector4 minf(real_t p_scalar) const { + return Vector4(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar), MIN(w, p_scalar)); + } + Vector4 max(const Vector4 &p_vector4) const { return Vector4(MAX(x, p_vector4.x), MAX(y, p_vector4.y), MAX(z, p_vector4.z), MAX(w, p_vector4.w)); } + Vector4 maxf(real_t p_scalar) const { + return Vector4(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar), MAX(w, p_scalar)); + } + _FORCE_INLINE_ real_t length_squared() const; bool is_equal_approx(const Vector4 &p_vec4) const; bool is_zero_approx() const; @@ -102,8 +110,11 @@ struct _NO_DISCARD_ Vector4 { Vector4 posmod(const real_t p_mod) const; Vector4 posmodv(const Vector4 &p_modv) const; void snap(const Vector4 &p_step); + void snapf(real_t p_step); Vector4 snapped(const Vector4 &p_step) const; + Vector4 snappedf(real_t p_step) const; Vector4 clamp(const Vector4 &p_min, const Vector4 &p_max) const; + Vector4 clampf(real_t p_min, real_t p_max) const; Vector4 inverse() const; _FORCE_INLINE_ real_t dot(const Vector4 &p_vec4) const; diff --git a/include/godot_cpp/variant/vector4i.hpp b/include/godot_cpp/variant/vector4i.hpp index 36f2855e..8e9510fd 100644 --- a/include/godot_cpp/variant/vector4i.hpp +++ b/include/godot_cpp/variant/vector4i.hpp @@ -77,10 +77,18 @@ struct _NO_DISCARD_ Vector4i { return Vector4i(MIN(x, p_vector4i.x), MIN(y, p_vector4i.y), MIN(z, p_vector4i.z), MIN(w, p_vector4i.w)); } + Vector4i mini(int32_t p_scalar) const { + return Vector4i(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar), MIN(w, p_scalar)); + } + Vector4i max(const Vector4i &p_vector4i) const { return Vector4i(MAX(x, p_vector4i.x), MAX(y, p_vector4i.y), MAX(z, p_vector4i.z), MAX(w, p_vector4i.w)); } + Vector4i maxi(int32_t p_scalar) const { + return Vector4i(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar), MAX(w, p_scalar)); + } + _FORCE_INLINE_ int64_t length_squared() const; _FORCE_INLINE_ double length() const; @@ -91,7 +99,10 @@ struct _NO_DISCARD_ Vector4i { _FORCE_INLINE_ Vector4i abs() const; _FORCE_INLINE_ Vector4i sign() const; + Vector4i snapped(const Vector4i &p_step) const; + Vector4i snappedi(int32_t p_step) const; Vector4i clamp(const Vector4i &p_min, const Vector4i &p_max) const; + Vector4i clampi(int32_t p_min, int32_t p_max) const; /* Operators */ diff --git a/src/variant/vector2.cpp b/src/variant/vector2.cpp index df870805..409ba50e 100644 --- a/src/variant/vector2.cpp +++ b/src/variant/vector2.cpp @@ -137,12 +137,24 @@ Vector2 Vector2::clamp(const Vector2 &p_min, const Vector2 &p_max) const { CLAMP(y, p_min.y, p_max.y)); } +Vector2 Vector2::clampf(real_t p_min, real_t p_max) const { + return Vector2( + CLAMP(x, p_min, p_max), + CLAMP(y, p_min, p_max)); +} + Vector2 Vector2::snapped(const Vector2 &p_step) const { return Vector2( Math::snapped(x, p_step.x), Math::snapped(y, p_step.y)); } +Vector2 Vector2::snappedf(real_t p_step) const { + return Vector2( + Math::snapped(x, p_step), + Math::snapped(y, p_step)); +} + Vector2 Vector2::limit_length(const real_t p_len) const { const real_t l = length(); Vector2 v = *this; diff --git a/src/variant/vector2i.cpp b/src/variant/vector2i.cpp index c1c1ab07..4baff3bb 100644 --- a/src/variant/vector2i.cpp +++ b/src/variant/vector2i.cpp @@ -35,12 +35,30 @@ namespace godot { +Vector2i Vector2i::snapped(const Vector2i &p_step) const { + return Vector2i( + Math::snapped(x, p_step.x), + Math::snapped(y, p_step.y)); +} + +Vector2i Vector2i::snappedi(int32_t p_step) const { + return Vector2i( + Math::snapped(x, p_step), + Math::snapped(y, p_step)); +} + Vector2i Vector2i::clamp(const Vector2i &p_min, const Vector2i &p_max) const { return Vector2i( CLAMP(x, p_min.x, p_max.x), CLAMP(y, p_min.y, p_max.y)); } +Vector2i Vector2i::clampi(int32_t p_min, int32_t p_max) const { + return Vector2i( + CLAMP(x, p_min, p_max), + CLAMP(y, p_min, p_max)); +} + int64_t Vector2i::length_squared() const { return x * (int64_t)x + y * (int64_t)y; } diff --git a/src/variant/vector3.cpp b/src/variant/vector3.cpp index 61536580..e6601856 100644 --- a/src/variant/vector3.cpp +++ b/src/variant/vector3.cpp @@ -54,18 +54,37 @@ Vector3 Vector3::clamp(const Vector3 &p_min, const Vector3 &p_max) const { CLAMP(z, p_min.z, p_max.z)); } +Vector3 Vector3::clampf(real_t p_min, real_t p_max) const { + return Vector3( + CLAMP(x, p_min, p_max), + CLAMP(y, p_min, p_max), + CLAMP(z, p_min, p_max)); +} + void Vector3::snap(const Vector3 p_step) { x = Math::snapped(x, p_step.x); y = Math::snapped(y, p_step.y); z = Math::snapped(z, p_step.z); } +void Vector3::snapf(real_t p_step) { + x = Math::snapped(x, p_step); + y = Math::snapped(y, p_step); + z = Math::snapped(z, p_step); +} + Vector3 Vector3::snapped(const Vector3 p_step) const { Vector3 v = *this; v.snap(p_step); return v; } +Vector3 Vector3::snappedf(real_t p_step) const { + Vector3 v = *this; + v.snapf(p_step); + return v; +} + Vector3 Vector3::limit_length(const real_t p_len) const { const real_t l = length(); Vector3 v = *this; diff --git a/src/variant/vector3i.cpp b/src/variant/vector3i.cpp index eef05b87..7b25d897 100644 --- a/src/variant/vector3i.cpp +++ b/src/variant/vector3i.cpp @@ -35,6 +35,20 @@ namespace godot { +Vector3i Vector3i::snapped(const Vector3i &p_step) const { + return Vector3i( + Math::snapped(x, p_step.x), + Math::snapped(y, p_step.y), + Math::snapped(z, p_step.z)); +} + +Vector3i Vector3i::snappedi(int32_t p_step) const { + return Vector3i( + Math::snapped(x, p_step), + Math::snapped(y, p_step), + Math::snapped(z, p_step)); +} + Vector3i::Axis Vector3i::min_axis_index() const { return x < y ? (x < z ? Vector3i::AXIS_X : Vector3i::AXIS_Z) : (y < z ? Vector3i::AXIS_Y : Vector3i::AXIS_Z); } @@ -50,6 +64,13 @@ Vector3i Vector3i::clamp(const Vector3i &p_min, const Vector3i &p_max) const { CLAMP(z, p_min.z, p_max.z)); } +Vector3i Vector3i::clampi(int32_t p_min, int32_t p_max) const { + return Vector3i( + CLAMP(x, p_min, p_max), + CLAMP(y, p_min, p_max), + CLAMP(z, p_min, p_max)); +} + Vector3i::operator String() const { return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ")"; } diff --git a/src/variant/vector4.cpp b/src/variant/vector4.cpp index 72c79d1e..641c6968 100644 --- a/src/variant/vector4.cpp +++ b/src/variant/vector4.cpp @@ -169,12 +169,25 @@ void Vector4::snap(const Vector4 &p_step) { w = Math::snapped(w, p_step.w); } +void Vector4::snapf(real_t p_step) { + x = Math::snapped(x, p_step); + y = Math::snapped(y, p_step); + z = Math::snapped(z, p_step); + w = Math::snapped(w, p_step); +} + Vector4 Vector4::snapped(const Vector4 &p_step) const { Vector4 v = *this; v.snap(p_step); return v; } +Vector4 Vector4::snappedf(real_t p_step) const { + Vector4 v = *this; + v.snapf(p_step); + return v; +} + Vector4 Vector4::inverse() const { return Vector4(1.0f / x, 1.0f / y, 1.0f / z, 1.0f / w); } @@ -187,6 +200,14 @@ Vector4 Vector4::clamp(const Vector4 &p_min, const Vector4 &p_max) const { CLAMP(w, p_min.w, p_max.w)); } +Vector4 Vector4::clampf(real_t p_min, real_t p_max) const { + return Vector4( + CLAMP(x, p_min, p_max), + CLAMP(y, p_min, p_max), + CLAMP(z, p_min, p_max), + CLAMP(w, p_min, p_max)); +} + Vector4::operator String() const { return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ", " + String::num_real(z, false) + ", " + String::num_real(w, false) + ")"; } diff --git a/src/variant/vector4i.cpp b/src/variant/vector4i.cpp index f1817dc8..b0e330ca 100644 --- a/src/variant/vector4i.cpp +++ b/src/variant/vector4i.cpp @@ -35,6 +35,22 @@ namespace godot { +Vector4i Vector4i::snapped(const Vector4i &p_step) const { + return Vector4i( + Math::snapped(x, p_step.x), + Math::snapped(y, p_step.y), + Math::snapped(z, p_step.z), + Math::snapped(w, p_step.w)); +} + +Vector4i Vector4i::snappedi(int32_t p_step) const { + return Vector4i( + Math::snapped(x, p_step), + Math::snapped(y, p_step), + Math::snapped(z, p_step), + Math::snapped(w, p_step)); +} + Vector4i::Axis Vector4i::min_axis_index() const { uint32_t min_index = 0; int32_t min_value = x; @@ -67,6 +83,14 @@ Vector4i Vector4i::clamp(const Vector4i &p_min, const Vector4i &p_max) const { CLAMP(w, p_min.w, p_max.w)); } +Vector4i Vector4i::clampi(int32_t p_min, int32_t p_max) const { + return Vector4i( + CLAMP(x, p_min, p_max), + CLAMP(y, p_min, p_max), + CLAMP(z, p_min, p_max), + CLAMP(w, p_min, p_max)); +} + Vector4i::operator String() const { return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ", " + itos(w) + ")"; }