From 75cb3539b1a7119434711d49248763bd6fddda7e Mon Sep 17 00:00:00 2001 From: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com> Date: Fri, 27 Sep 2024 18:19:18 +0200 Subject: [PATCH] [Core] Add missing `HashMapComparatorDefault` cases Added for: * `AABB` * `Basis` * `Color` * `Plane` * `Projection` * `Quaternion` * `Rect2` * `Transform2D` * `Transform3D` * `Vector4` Ensures these handles `NaN` correctly --- core/templates/hashfuncs.h | 95 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/core/templates/hashfuncs.h b/core/templates/hashfuncs.h index fc7a78bcf53..21eef10297a 100644 --- a/core/templates/hashfuncs.h +++ b/core/templates/hashfuncs.h @@ -32,10 +32,17 @@ #define HASHFUNCS_H #include "core/math/aabb.h" +#include "core/math/basis.h" +#include "core/math/color.h" #include "core/math/math_defs.h" #include "core/math/math_funcs.h" +#include "core/math/plane.h" +#include "core/math/projection.h" +#include "core/math/quaternion.h" #include "core/math/rect2.h" #include "core/math/rect2i.h" +#include "core/math/transform_2d.h" +#include "core/math/transform_3d.h" #include "core/math/vector2.h" #include "core/math/vector2i.h" #include "core/math/vector3.h" @@ -413,6 +420,13 @@ struct HashMapComparatorDefault { } }; +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))); + } +}; + template <> struct HashMapComparatorDefault { static bool compare(const Vector2 &p_lhs, const Vector2 &p_rhs) { @@ -427,6 +441,87 @@ struct HashMapComparatorDefault { } }; +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))); + } +}; + +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); + } +}; + +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); + } +}; + +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))); + } +}; + +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; + } +}; + +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; + } +}; + +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); + } +}; + +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; + } +}; + +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))); + } +}; + constexpr uint32_t HASH_TABLE_SIZE_MAX = 29; inline constexpr uint32_t hash_table_size_primes[HASH_TABLE_SIZE_MAX] = {