From 86b9d7355f349eff0ceb33a54554798902b68702 Mon Sep 17 00:00:00 2001 From: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com> Date: Fri, 27 Sep 2024 19:28:41 +0200 Subject: [PATCH] [Core] Add `is_same` to types that have float components Compares `NaN` as equal. Added to: * `AABB` * `Basis` * `Color` * `Plane` * `Projection` * `Quaternion` * `Rect2` * `Transform2D` * `Transform3D` * `Vector2` * `Vector3` * `Vector4` And added as a method in `Math` --- core/math/aabb.cpp | 4 +++ core/math/aabb.h | 1 + core/math/basis.cpp | 4 +++ core/math/basis.h | 1 + core/math/color.cpp | 4 +++ core/math/color.h | 1 + core/math/math_funcs.h | 8 +++++ core/math/plane.cpp | 4 +++ core/math/plane.h | 1 + core/math/projection.cpp | 4 +++ core/math/projection.h | 2 ++ core/math/quaternion.cpp | 4 +++ core/math/quaternion.h | 1 + core/math/rect2.cpp | 4 +++ core/math/rect2.h | 1 + core/math/transform_2d.cpp | 4 +++ core/math/transform_2d.h | 1 + core/math/transform_3d.cpp | 4 +++ core/math/transform_3d.h | 1 + core/math/vector2.cpp | 4 +++ core/math/vector2.h | 1 + core/math/vector3.cpp | 4 +++ core/math/vector3.h | 1 + core/math/vector4.cpp | 4 +++ core/math/vector4.h | 1 + core/templates/hashfuncs.h | 46 ++++++++---------------- core/variant/variant.cpp | 71 +++++++++----------------------------- 27 files changed, 99 insertions(+), 87 deletions(-) diff --git a/core/math/aabb.cpp b/core/math/aabb.cpp index 7d1d7c5648b..a1ad58cc63c 100644 --- a/core/math/aabb.cpp +++ b/core/math/aabb.cpp @@ -76,6 +76,10 @@ bool AABB::is_equal_approx(const AABB &p_aabb) const { return position.is_equal_approx(p_aabb.position) && size.is_equal_approx(p_aabb.size); } +bool AABB::is_same(const AABB &p_aabb) const { + return position.is_same(p_aabb.position) && size.is_same(p_aabb.size); +} + bool AABB::is_finite() const { return position.is_finite() && size.is_finite(); } diff --git a/core/math/aabb.h b/core/math/aabb.h index 7a5581b5d45..58c7e288457 100644 --- a/core/math/aabb.h +++ b/core/math/aabb.h @@ -63,6 +63,7 @@ struct [[nodiscard]] AABB { bool operator!=(const AABB &p_rval) const; bool is_equal_approx(const AABB &p_aabb) const; + bool is_same(const AABB &p_aabb) const; bool is_finite() const; _FORCE_INLINE_ bool intersects(const AABB &p_aabb) const; /// Both AABBs overlap _FORCE_INLINE_ bool intersects_inclusive(const AABB &p_aabb) const; /// Both AABBs (or their faces) overlap diff --git a/core/math/basis.cpp b/core/math/basis.cpp index 34ed1c2d855..bb397f8924b 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -694,6 +694,10 @@ bool Basis::is_equal_approx(const Basis &p_basis) const { return rows[0].is_equal_approx(p_basis.rows[0]) && rows[1].is_equal_approx(p_basis.rows[1]) && rows[2].is_equal_approx(p_basis.rows[2]); } +bool Basis::is_same(const Basis &p_basis) const { + return rows[0].is_same(p_basis.rows[0]) && rows[1].is_same(p_basis.rows[1]) && rows[2].is_same(p_basis.rows[2]); +} + bool Basis::is_finite() const { return rows[0].is_finite() && rows[1].is_finite() && rows[2].is_finite(); } diff --git a/core/math/basis.h b/core/math/basis.h index 236d6661033..46d9c04edc0 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -121,6 +121,7 @@ struct [[nodiscard]] Basis { } bool is_equal_approx(const Basis &p_basis) const; + bool is_same(const Basis &p_basis) const; bool is_finite() const; bool operator==(const Basis &p_matrix) const; diff --git a/core/math/color.cpp b/core/math/color.cpp index 1638acd74d8..7a85900d6ad 100644 --- a/core/math/color.cpp +++ b/core/math/color.cpp @@ -259,6 +259,10 @@ bool Color::is_equal_approx(const Color &p_color) const { return Math::is_equal_approx(r, p_color.r) && Math::is_equal_approx(g, p_color.g) && Math::is_equal_approx(b, p_color.b) && Math::is_equal_approx(a, p_color.a); } +bool Color::is_same(const Color &p_color) const { + return Math::is_same(r, p_color.r) && Math::is_same(g, p_color.g) && Math::is_same(b, p_color.b) && Math::is_same(a, p_color.a); +} + Color Color::clamp(const Color &p_min, const Color &p_max) const { return Color( CLAMP(r, p_min.r, p_max.r), diff --git a/core/math/color.h b/core/math/color.h index 70fad78acbd..43e0af4777c 100644 --- a/core/math/color.h +++ b/core/math/color.h @@ -94,6 +94,7 @@ struct [[nodiscard]] Color { void operator/=(float p_scalar); bool is_equal_approx(const Color &p_color) const; + bool is_same(const Color &p_color) const; Color clamp(const Color &p_min = Color(0, 0, 0, 0), const Color &p_max = Color(1, 1, 1, 1)) const; void invert(); diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index 1afc5f4bbbd..3eb10ac2d40 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -594,6 +594,10 @@ public: return abs(s) < (float)CMP_EPSILON; } + static _ALWAYS_INLINE_ bool is_same(float a, float b) { + return (a == b) || (is_nan(a) && is_nan(b)); + } + static _ALWAYS_INLINE_ bool is_equal_approx(double a, double b) { // Check for exact equality first, required to handle "infinity" values. if (a == b) { @@ -620,6 +624,10 @@ public: return abs(s) < CMP_EPSILON; } + static _ALWAYS_INLINE_ bool is_same(double a, double b) { + return (a == b) || (is_nan(a) && is_nan(b)); + } + static _ALWAYS_INLINE_ float absf(float g) { union { float f; diff --git a/core/math/plane.cpp b/core/math/plane.cpp index 6b9bcea0813..5422fa9ca81 100644 --- a/core/math/plane.cpp +++ b/core/math/plane.cpp @@ -172,6 +172,10 @@ bool Plane::is_equal_approx(const Plane &p_plane) const { return normal.is_equal_approx(p_plane.normal) && Math::is_equal_approx(d, p_plane.d); } +bool Plane::is_same(const Plane &p_plane) const { + return normal.is_same(p_plane.normal) && Math::is_same(d, p_plane.d); +} + bool Plane::is_finite() const { return normal.is_finite() && Math::is_finite(d); } diff --git a/core/math/plane.h b/core/math/plane.h index 6529fea60ac..c3105a47b4c 100644 --- a/core/math/plane.h +++ b/core/math/plane.h @@ -73,6 +73,7 @@ struct [[nodiscard]] Plane { Plane operator-() const { return Plane(-normal, -d); } bool is_equal_approx(const Plane &p_plane) const; + bool is_same(const Plane &p_plane) const; bool is_equal_approx_any_side(const Plane &p_plane) const; bool is_finite() const; diff --git a/core/math/projection.cpp b/core/math/projection.cpp index d0ca7c56849..023ea81de44 100644 --- a/core/math/projection.cpp +++ b/core/math/projection.cpp @@ -699,6 +699,10 @@ void Projection::flip_y() { } } +bool Projection::is_same(const Projection &p_cam) const { + return columns[0].is_same(p_cam.columns[0]) && columns[1].is_same(p_cam.columns[1]) && columns[2].is_same(p_cam.columns[2]) && columns[3].is_same(p_cam.columns[3]); +} + Projection::Projection() { set_identity(); } diff --git a/core/math/projection.h b/core/math/projection.h index 5af43561c0c..52ebc1005c8 100644 --- a/core/math/projection.h +++ b/core/math/projection.h @@ -133,6 +133,8 @@ struct [[nodiscard]] Projection { void flip_y(); + bool is_same(const Projection &p_cam) const; + bool operator==(const Projection &p_cam) const { for (uint32_t i = 0; i < 4; i++) { for (uint32_t j = 0; j < 4; j++) { diff --git a/core/math/quaternion.cpp b/core/math/quaternion.cpp index 08eac14b76d..de680276647 100644 --- a/core/math/quaternion.cpp +++ b/core/math/quaternion.cpp @@ -66,6 +66,10 @@ bool Quaternion::is_equal_approx(const Quaternion &p_quaternion) const { return Math::is_equal_approx(x, p_quaternion.x) && Math::is_equal_approx(y, p_quaternion.y) && Math::is_equal_approx(z, p_quaternion.z) && Math::is_equal_approx(w, p_quaternion.w); } +bool Quaternion::is_same(const Quaternion &p_quaternion) const { + return Math::is_same(x, p_quaternion.x) && Math::is_same(y, p_quaternion.y) && Math::is_same(z, p_quaternion.z) && Math::is_same(w, p_quaternion.w); +} + bool Quaternion::is_finite() const { return Math::is_finite(x) && Math::is_finite(y) && Math::is_finite(z) && Math::is_finite(w); } diff --git a/core/math/quaternion.h b/core/math/quaternion.h index 655e55e0a20..fda5976c6fc 100644 --- a/core/math/quaternion.h +++ b/core/math/quaternion.h @@ -54,6 +54,7 @@ struct [[nodiscard]] Quaternion { } _FORCE_INLINE_ real_t length_squared() const; bool is_equal_approx(const Quaternion &p_quaternion) const; + bool is_same(const Quaternion &p_quaternion) const; bool is_finite() const; real_t length() const; void normalize(); diff --git a/core/math/rect2.cpp b/core/math/rect2.cpp index c55226a57ec..76da2a398fb 100644 --- a/core/math/rect2.cpp +++ b/core/math/rect2.cpp @@ -38,6 +38,10 @@ bool Rect2::is_equal_approx(const Rect2 &p_rect) const { return position.is_equal_approx(p_rect.position) && size.is_equal_approx(p_rect.size); } +bool Rect2::is_same(const Rect2 &p_rect) const { + return position.is_same(p_rect.position) && size.is_same(p_rect.size); +} + bool Rect2::is_finite() const { return position.is_finite() && size.is_finite(); } diff --git a/core/math/rect2.h b/core/math/rect2.h index 817923c1348..944c0f71704 100644 --- a/core/math/rect2.h +++ b/core/math/rect2.h @@ -203,6 +203,7 @@ struct [[nodiscard]] Rect2 { } bool is_equal_approx(const Rect2 &p_rect) const; + bool is_same(const Rect2 &p_rect) const; bool is_finite() const; bool operator==(const Rect2 &p_rect) const { return position == p_rect.position && size == p_rect.size; } diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp index f6525fe5caf..c00d09ecd41 100644 --- a/core/math/transform_2d.cpp +++ b/core/math/transform_2d.cpp @@ -180,6 +180,10 @@ bool Transform2D::is_equal_approx(const Transform2D &p_transform) const { return columns[0].is_equal_approx(p_transform.columns[0]) && columns[1].is_equal_approx(p_transform.columns[1]) && columns[2].is_equal_approx(p_transform.columns[2]); } +bool Transform2D::is_same(const Transform2D &p_transform) const { + return columns[0].is_same(p_transform.columns[0]) && columns[1].is_same(p_transform.columns[1]) && columns[2].is_same(p_transform.columns[2]); +} + bool Transform2D::is_finite() const { return columns[0].is_finite() && columns[1].is_finite() && columns[2].is_finite(); } diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h index 1ee7d3d84f7..728f741b09d 100644 --- a/core/math/transform_2d.h +++ b/core/math/transform_2d.h @@ -101,6 +101,7 @@ struct [[nodiscard]] Transform2D { Transform2D orthonormalized() const; bool is_conformal() const; bool is_equal_approx(const Transform2D &p_transform) const; + bool is_same(const Transform2D &p_transform) const; bool is_finite() const; Transform2D looking_at(const Vector2 &p_target) const; diff --git a/core/math/transform_3d.cpp b/core/math/transform_3d.cpp index 2c91a7604b0..14f04e959ac 100644 --- a/core/math/transform_3d.cpp +++ b/core/math/transform_3d.cpp @@ -174,6 +174,10 @@ bool Transform3D::is_equal_approx(const Transform3D &p_transform) const { return basis.is_equal_approx(p_transform.basis) && origin.is_equal_approx(p_transform.origin); } +bool Transform3D::is_same(const Transform3D &p_transform) const { + return basis.is_same(p_transform.basis) && origin.is_same(p_transform.origin); +} + bool Transform3D::is_finite() const { return basis.is_finite() && origin.is_finite(); } diff --git a/core/math/transform_3d.h b/core/math/transform_3d.h index b1de233445e..f87f60f3266 100644 --- a/core/math/transform_3d.h +++ b/core/math/transform_3d.h @@ -75,6 +75,7 @@ struct [[nodiscard]] Transform3D { void orthogonalize(); Transform3D orthogonalized() const; bool is_equal_approx(const Transform3D &p_transform) const; + bool is_same(const Transform3D &p_transform) const; bool is_finite() const; bool operator==(const Transform3D &p_transform) const; diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp index e86b97d6a80..39abda72df3 100644 --- a/core/math/vector2.cpp +++ b/core/math/vector2.cpp @@ -194,6 +194,10 @@ bool Vector2::is_equal_approx(const Vector2 &p_v) const { return Math::is_equal_approx(x, p_v.x) && Math::is_equal_approx(y, p_v.y); } +bool Vector2::is_same(const Vector2 &p_v) const { + return Math::is_same(x, p_v.x) && Math::is_same(y, p_v.y); +} + bool Vector2::is_zero_approx() const { return Math::is_zero_approx(x) && Math::is_zero_approx(y); } diff --git a/core/math/vector2.h b/core/math/vector2.h index edb47db6fd3..9cc25d3ddaa 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -129,6 +129,7 @@ struct [[nodiscard]] Vector2 { Vector2 reflect(const Vector2 &p_normal) const; bool is_equal_approx(const Vector2 &p_v) const; + bool is_same(const Vector2 &p_v) const; bool is_zero_approx() const; bool is_finite() const; diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp index 1e900026651..19ca8873f52 100644 --- a/core/math/vector3.cpp +++ b/core/math/vector3.cpp @@ -156,6 +156,10 @@ bool Vector3::is_equal_approx(const Vector3 &p_v) const { return Math::is_equal_approx(x, p_v.x) && Math::is_equal_approx(y, p_v.y) && Math::is_equal_approx(z, p_v.z); } +bool Vector3::is_same(const Vector3 &p_v) const { + return Math::is_same(x, p_v.x) && Math::is_same(y, p_v.y) && Math::is_same(z, p_v.z); +} + bool Vector3::is_zero_approx() const { return Math::is_zero_approx(x) && Math::is_zero_approx(y) && Math::is_zero_approx(z); } diff --git a/core/math/vector3.h b/core/math/vector3.h index 14bc44c4e79..18427a45f3b 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -155,6 +155,7 @@ struct [[nodiscard]] Vector3 { _FORCE_INLINE_ Vector3 reflect(const Vector3 &p_normal) const; bool is_equal_approx(const Vector3 &p_v) const; + bool is_same(const Vector3 &p_v) const; bool is_zero_approx() const; bool is_finite() const; diff --git a/core/math/vector4.cpp b/core/math/vector4.cpp index b6b914f36da..98b340ddd82 100644 --- a/core/math/vector4.cpp +++ b/core/math/vector4.cpp @@ -62,6 +62,10 @@ bool Vector4::is_equal_approx(const Vector4 &p_vec4) const { return Math::is_equal_approx(x, p_vec4.x) && Math::is_equal_approx(y, p_vec4.y) && Math::is_equal_approx(z, p_vec4.z) && Math::is_equal_approx(w, p_vec4.w); } +bool Vector4::is_same(const Vector4 &p_vec4) const { + return Math::is_same(x, p_vec4.x) && Math::is_same(y, p_vec4.y) && Math::is_same(z, p_vec4.z) && Math::is_same(w, p_vec4.w); +} + bool Vector4::is_zero_approx() const { return Math::is_zero_approx(x) && Math::is_zero_approx(y) && Math::is_zero_approx(z) && Math::is_zero_approx(w); } diff --git a/core/math/vector4.h b/core/math/vector4.h index 9197e3587ab..210a4d4340b 100644 --- a/core/math/vector4.h +++ b/core/math/vector4.h @@ -89,6 +89,7 @@ struct [[nodiscard]] Vector4 { _FORCE_INLINE_ real_t length_squared() const; bool is_equal_approx(const Vector4 &p_vec4) const; bool is_zero_approx() const; + bool is_same(const Vector4 &p_vec4) const; bool is_finite() const; real_t length() const; void normalize(); diff --git a/core/templates/hashfuncs.h b/core/templates/hashfuncs.h index 21eef10297a..df412d44c83 100644 --- a/core/templates/hashfuncs.h +++ b/core/templates/hashfuncs.h @@ -409,116 +409,98 @@ struct HashMapComparatorDefault { template <> struct HashMapComparatorDefault { static bool compare(const float &p_lhs, const float &p_rhs) { - return (p_lhs == p_rhs) || (Math::is_nan(p_lhs) && Math::is_nan(p_rhs)); + return Math::is_same(p_lhs, p_rhs); } }; template <> struct HashMapComparatorDefault { static bool compare(const double &p_lhs, const double &p_rhs) { - return (p_lhs == p_rhs) || (Math::is_nan(p_lhs) && Math::is_nan(p_rhs)); + return Math::is_same(p_lhs, p_rhs); } }; template <> struct HashMapComparatorDefault { static bool compare(const Color &p_lhs, const Color &p_rhs) { - return ((p_lhs.r == p_rhs.r) || (Math::is_nan(p_lhs.r) && Math::is_nan(p_rhs.r))) && ((p_lhs.g == p_rhs.g) || (Math::is_nan(p_lhs.g) && Math::is_nan(p_rhs.g))) && ((p_lhs.b == p_rhs.b) || (Math::is_nan(p_lhs.b) && Math::is_nan(p_rhs.b))) && ((p_lhs.a == p_rhs.a) || (Math::is_nan(p_lhs.a) && Math::is_nan(p_rhs.a))); + return p_lhs.is_same(p_rhs); } }; template <> struct HashMapComparatorDefault { static bool compare(const Vector2 &p_lhs, const Vector2 &p_rhs) { - return ((p_lhs.x == p_rhs.x) || (Math::is_nan(p_lhs.x) && Math::is_nan(p_rhs.x))) && ((p_lhs.y == p_rhs.y) || (Math::is_nan(p_lhs.y) && Math::is_nan(p_rhs.y))); + return p_lhs.is_same(p_rhs); } }; template <> struct HashMapComparatorDefault { static bool compare(const Vector3 &p_lhs, const Vector3 &p_rhs) { - return ((p_lhs.x == p_rhs.x) || (Math::is_nan(p_lhs.x) && Math::is_nan(p_rhs.x))) && ((p_lhs.y == p_rhs.y) || (Math::is_nan(p_lhs.y) && Math::is_nan(p_rhs.y))) && ((p_lhs.z == p_rhs.z) || (Math::is_nan(p_lhs.z) && Math::is_nan(p_rhs.z))); + return p_lhs.is_same(p_rhs); } }; template <> struct HashMapComparatorDefault { static bool compare(const Vector4 &p_lhs, const Vector4 &p_rhs) { - return ((p_lhs.x == p_rhs.x) || (Math::is_nan(p_lhs.x) && Math::is_nan(p_rhs.x))) && ((p_lhs.y == p_rhs.y) || (Math::is_nan(p_lhs.y) && Math::is_nan(p_rhs.y))) && ((p_lhs.z == p_rhs.z) || (Math::is_nan(p_lhs.z) && Math::is_nan(p_rhs.z))) && ((p_lhs.w == p_rhs.w) || (Math::is_nan(p_lhs.w) && Math::is_nan(p_rhs.w))); + return p_lhs.is_same(p_rhs); } }; template <> struct HashMapComparatorDefault { static bool compare(const Rect2 &p_lhs, const Rect2 &p_rhs) { - return HashMapComparatorDefault().compare(p_lhs.position, p_rhs.position) && HashMapComparatorDefault().compare(p_lhs.size, p_rhs.size); + return p_lhs.is_same(p_rhs); } }; template <> struct HashMapComparatorDefault { static bool compare(const AABB &p_lhs, const AABB &p_rhs) { - return HashMapComparatorDefault().compare(p_lhs.position, p_rhs.position) && HashMapComparatorDefault().compare(p_lhs.size, p_rhs.size); + return p_lhs.is_same(p_rhs); } }; template <> struct HashMapComparatorDefault { static bool compare(const Plane &p_lhs, const Plane &p_rhs) { - return HashMapComparatorDefault().compare(p_lhs.normal, p_rhs.normal) && ((p_lhs.d == p_rhs.d) || (Math::is_nan(p_lhs.d) && Math::is_nan(p_rhs.d))); + return p_lhs.is_same(p_rhs); } }; template <> struct HashMapComparatorDefault { static bool compare(const Transform2D &p_lhs, const Transform2D &p_rhs) { - for (int i = 0; i < 3; ++i) { - if (!HashMapComparatorDefault().compare(p_lhs.columns[i], p_rhs.columns[i])) { - return false; - } - } - - return true; + return p_lhs.is_same(p_rhs); } }; template <> struct HashMapComparatorDefault { static bool compare(const Basis &p_lhs, const Basis &p_rhs) { - for (int i = 0; i < 3; ++i) { - if (!HashMapComparatorDefault().compare(p_lhs.rows[i], p_rhs.rows[i])) { - return false; - } - } - - return true; + return p_lhs.is_same(p_rhs); } }; template <> struct HashMapComparatorDefault { static bool compare(const Transform3D &p_lhs, const Transform3D &p_rhs) { - return HashMapComparatorDefault().compare(p_lhs.basis, p_rhs.basis) && HashMapComparatorDefault().compare(p_lhs.origin, p_rhs.origin); + return p_lhs.is_same(p_rhs); } }; template <> struct HashMapComparatorDefault { static bool compare(const Projection &p_lhs, const Projection &p_rhs) { - for (int i = 0; i < 4; ++i) { - if (!HashMapComparatorDefault().compare(p_lhs.columns[i], p_rhs.columns[i])) { - return false; - } - } - - return true; + return p_lhs.is_same(p_rhs); } }; template <> struct HashMapComparatorDefault { static bool compare(const Quaternion &p_lhs, const Quaternion &p_rhs) { - return ((p_lhs.x == p_rhs.x) || (Math::is_nan(p_lhs.x) && Math::is_nan(p_rhs.x))) && ((p_lhs.y == p_rhs.y) || (Math::is_nan(p_lhs.y) && Math::is_nan(p_rhs.y))) && ((p_lhs.z == p_rhs.z) || (Math::is_nan(p_lhs.z) && Math::is_nan(p_rhs.z))) && ((p_lhs.w == p_rhs.w) || (Math::is_nan(p_lhs.w) && Math::is_nan(p_rhs.w))); + return p_lhs.is_same(p_rhs); } }; diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index 186643b024a..5089a757c63 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -3254,32 +3254,20 @@ uint32_t Variant::recursive_hash(int recursion_count) const { #define hash_compare_scalar(p_lhs, p_rhs) \ (hash_compare_scalar_base(p_lhs, p_rhs, true)) -#define hash_compare_vector2(p_lhs, p_rhs) \ - (hash_compare_scalar((p_lhs).x, (p_rhs).x) && \ - hash_compare_scalar((p_lhs).y, (p_rhs).y)) +#define hash_compare_vector2(p_lhs, p_rhs) \ + (p_lhs).is_same(p_rhs) -#define hash_compare_vector3(p_lhs, p_rhs) \ - (hash_compare_scalar((p_lhs).x, (p_rhs).x) && \ - hash_compare_scalar((p_lhs).y, (p_rhs).y) && \ - hash_compare_scalar((p_lhs).z, (p_rhs).z)) +#define hash_compare_vector3(p_lhs, p_rhs) \ + (p_lhs).is_same(p_rhs) -#define hash_compare_vector4(p_lhs, p_rhs) \ - (hash_compare_scalar((p_lhs).x, (p_rhs).x) && \ - hash_compare_scalar((p_lhs).y, (p_rhs).y) && \ - hash_compare_scalar((p_lhs).z, (p_rhs).z) && \ - hash_compare_scalar((p_lhs).w, (p_rhs).w)) +#define hash_compare_vector4(p_lhs, p_rhs) \ + (p_lhs).is_same(p_rhs) -#define hash_compare_quaternion(p_lhs, p_rhs) \ - (hash_compare_scalar((p_lhs).x, (p_rhs).x) && \ - hash_compare_scalar((p_lhs).y, (p_rhs).y) && \ - hash_compare_scalar((p_lhs).z, (p_rhs).z) && \ - hash_compare_scalar((p_lhs).w, (p_rhs).w)) +#define hash_compare_quaternion(p_lhs, p_rhs) \ + (p_lhs).is_same(p_rhs) -#define hash_compare_color(p_lhs, p_rhs) \ - (hash_compare_scalar((p_lhs).r, (p_rhs).r) && \ - hash_compare_scalar((p_lhs).g, (p_rhs).g) && \ - hash_compare_scalar((p_lhs).b, (p_rhs).b) && \ - hash_compare_scalar((p_lhs).a, (p_rhs).a)) +#define hash_compare_color(p_lhs, p_rhs) \ + (p_lhs).is_same(p_rhs) #define hash_compare_packed_array(p_lhs, p_rhs, p_type, p_compare_func) \ const Vector &l = PackedArrayRef::get_array(p_lhs); \ @@ -3350,13 +3338,7 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count, bool s Transform2D *l = _data._transform2d; Transform2D *r = p_variant._data._transform2d; - for (int i = 0; i < 3; i++) { - if (!hash_compare_vector2(l->columns[i], r->columns[i])) { - return false; - } - } - - return true; + return l->is_same(*r); } break; case VECTOR3: { @@ -3388,17 +3370,14 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count, bool s const Plane *l = reinterpret_cast(_data._mem); const Plane *r = reinterpret_cast(p_variant._data._mem); - return hash_compare_vector3(l->normal, r->normal) && - hash_compare_scalar(l->d, r->d); + return l->is_same(*r); } break; case AABB: { const ::AABB *l = _data._aabb; const ::AABB *r = p_variant._data._aabb; - return hash_compare_vector3(l->position, r->position) && - hash_compare_vector3(l->size, r->size); - + return l->is_same(*r); } break; case QUATERNION: { @@ -3412,38 +3391,20 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count, bool s const Basis *l = _data._basis; const Basis *r = p_variant._data._basis; - for (int i = 0; i < 3; i++) { - if (!hash_compare_vector3(l->rows[i], r->rows[i])) { - return false; - } - } - - return true; + return l->is_same(*r); } break; case TRANSFORM3D: { const Transform3D *l = _data._transform3d; const Transform3D *r = p_variant._data._transform3d; - for (int i = 0; i < 3; i++) { - if (!hash_compare_vector3(l->basis.rows[i], r->basis.rows[i])) { - return false; - } - } - - return hash_compare_vector3(l->origin, r->origin); + return l->is_same(*r); } break; case PROJECTION: { const Projection *l = _data._projection; const Projection *r = p_variant._data._projection; - for (int i = 0; i < 4; i++) { - if (!hash_compare_vector4(l->columns[i], r->columns[i])) { - return false; - } - } - - return true; + return l->is_same(*r); } break; case COLOR: {