From 73709fa1ae598e18ba8c8803e3d4db1c47d6c9df Mon Sep 17 00:00:00 2001 From: Relintai Date: Wed, 17 Aug 2022 10:42:50 +0200 Subject: [PATCH] Backported from Godot4: Clean up Hash Functions Clean up and do fixes to hash functions and newly introduced murmur3 hashes in #61934 * Clean up usage of murmur3 * Fixed usages of binary murmur3 on floats (this is invalid) * Changed DJB2 to use xor (which seems to be better) - reduz https://github.com/godotengine/godot/commit/141c3755814cea60888c7ee548c7ce709550b784 --- core/array.cpp | 6 +- core/class_db.cpp | 52 ++--- core/dictionary.cpp | 8 +- core/io/file_access_pack.h | 6 + core/io/networked_multiplayer_peer.cpp | 26 +++ core/io/networked_multiplayer_peer.h | 2 + core/resource.cpp | 4 +- core/variant.cpp | 232 ++++++++++++---------- modules/mesh_utils/delaunay/delaunay_3d.h | 2 +- 9 files changed, 197 insertions(+), 141 deletions(-) diff --git a/core/array.cpp b/core/array.cpp index 056ee332f..e5766d762 100644 --- a/core/array.cpp +++ b/core/array.cpp @@ -117,12 +117,12 @@ bool Array::operator==(const Array &p_array) const { } uint32_t Array::hash() const { - uint32_t h = hash_djb2_one_32(0); + uint32_t h = hash_murmur3_one_32(0); for (int i = 0; i < _p->array.size(); i++) { - h = hash_djb2_one_32(_p->array[i].hash(), h); + h = hash_murmur3_one_32(_p->array[i].hash(), h); } - return h; + return hash_fmix32(h); } void Array::operator=(const Array &p_array) { _ref(p_array); diff --git a/core/class_db.cpp b/core/class_db.cpp index e753913dc..a90b72139 100644 --- a/core/class_db.cpp +++ b/core/class_db.cpp @@ -343,7 +343,7 @@ uint64_t ClassDB::get_api_hash(APIType p_api) { OBJTYPE_RLOCK; #ifdef DEBUG_METHODS_ENABLED - uint64_t hash = hash_djb2_one_64(HashMapHasherDefault::hash(VERSION_FULL_CONFIG)); + uint64_t hash = hash_murmur3_one_64(HashMapHasherDefault::hash(VERSION_FULL_CONFIG)); List names; @@ -361,8 +361,8 @@ uint64_t ClassDB::get_api_hash(APIType p_api) { if (t->api != p_api || !t->exposed) { continue; } - hash = hash_djb2_one_64(t->name.hash(), hash); - hash = hash_djb2_one_64(t->inherits.hash(), hash); + hash = hash_murmur3_one_64(t->name.hash(), hash); + hash = hash_murmur3_one_64(t->inherits.hash(), hash); { //methods @@ -386,27 +386,27 @@ uint64_t ClassDB::get_api_hash(APIType p_api) { for (List::Element *F = snames.front(); F; F = F->next()) { MethodBind *mb = t->method_map[F->get()]; - hash = hash_djb2_one_64(mb->get_name().hash(), hash); - hash = hash_djb2_one_64(mb->get_argument_count(), hash); - hash = hash_djb2_one_64(mb->get_argument_type(-1), hash); //return + hash = hash_murmur3_one_64(mb->get_name().hash(), hash); + hash = hash_murmur3_one_64(mb->get_argument_count(), hash); + hash = hash_murmur3_one_64(mb->get_argument_type(-1), hash); //return for (int i = 0; i < mb->get_argument_count(); i++) { const PropertyInfo info = mb->get_argument_info(i); - hash = hash_djb2_one_64(info.type, hash); - hash = hash_djb2_one_64(info.name.hash(), hash); - hash = hash_djb2_one_64(info.hint, hash); - hash = hash_djb2_one_64(info.hint_string.hash(), hash); + hash = hash_murmur3_one_64(info.type, hash); + hash = hash_murmur3_one_64(info.name.hash(), hash); + hash = hash_murmur3_one_64(info.hint, hash); + hash = hash_murmur3_one_64(info.hint_string.hash(), hash); } - hash = hash_djb2_one_64(mb->get_default_argument_count(), hash); + hash = hash_murmur3_one_64(mb->get_default_argument_count(), hash); for (int i = 0; i < mb->get_default_argument_count(); i++) { //hash should not change, i hope for tis Variant da = mb->get_default_argument(i); - hash = hash_djb2_one_64(da.hash(), hash); + hash = hash_murmur3_one_64(da.hash(), hash); } - hash = hash_djb2_one_64(mb->get_hint_flags(), hash); + hash = hash_murmur3_one_64(mb->get_hint_flags(), hash); } } @@ -423,8 +423,8 @@ uint64_t ClassDB::get_api_hash(APIType p_api) { snames.sort_custom(); for (List::Element *F = snames.front(); F; F = F->next()) { - hash = hash_djb2_one_64(F->get().hash(), hash); - hash = hash_djb2_one_64(t->constant_map[F->get()], hash); + hash = hash_murmur3_one_64(F->get().hash(), hash); + hash = hash_murmur3_one_64(t->constant_map[F->get()], hash); } } @@ -442,9 +442,9 @@ uint64_t ClassDB::get_api_hash(APIType p_api) { for (List::Element *F = snames.front(); F; F = F->next()) { MethodInfo &mi = t->signal_map[F->get()]; - hash = hash_djb2_one_64(F->get().hash(), hash); + hash = hash_murmur3_one_64(F->get().hash(), hash); for (int i = 0; i < mi.arguments.size(); i++) { - hash = hash_djb2_one_64(mi.arguments[i].type, hash); + hash = hash_murmur3_one_64(mi.arguments[i].type, hash); } } } @@ -465,23 +465,23 @@ uint64_t ClassDB::get_api_hash(APIType p_api) { PropertySetGet *psg = t->property_setget.getptr(F->get()); ERR_FAIL_COND_V(!psg, 0); - hash = hash_djb2_one_64(F->get().hash(), hash); - hash = hash_djb2_one_64(psg->setter.hash(), hash); - hash = hash_djb2_one_64(psg->getter.hash(), hash); + hash = hash_murmur3_one_64(F->get().hash(), hash); + hash = hash_murmur3_one_64(psg->setter.hash(), hash); + hash = hash_murmur3_one_64(psg->getter.hash(), hash); } } //property list for (List::Element *F = t->property_list.front(); F; F = F->next()) { - hash = hash_djb2_one_64(F->get().name.hash(), hash); - hash = hash_djb2_one_64(F->get().type, hash); - hash = hash_djb2_one_64(F->get().hint, hash); - hash = hash_djb2_one_64(F->get().hint_string.hash(), hash); - hash = hash_djb2_one_64(F->get().usage, hash); + hash = hash_murmur3_one_64(F->get().name.hash(), hash); + hash = hash_murmur3_one_64(F->get().type, hash); + hash = hash_murmur3_one_64(F->get().hint, hash); + hash = hash_murmur3_one_64(F->get().hint_string.hash(), hash); + hash = hash_murmur3_one_64(F->get().usage, hash); } } - return hash; + return hash_fmix32(hash); #else return 0; #endif diff --git a/core/dictionary.cpp b/core/dictionary.cpp index 158d127de..5bdc705eb 100644 --- a/core/dictionary.cpp +++ b/core/dictionary.cpp @@ -213,14 +213,14 @@ void Dictionary::_unref() const { _p = nullptr; } uint32_t Dictionary::hash() const { - uint32_t h = hash_djb2_one_32(Variant::DICTIONARY); + uint32_t h = hash_murmur3_one_32(Variant::DICTIONARY); for (OrderedHashMap::Element E = _p->variant_map.front(); E; E = E.next()) { - h = hash_djb2_one_32(E.key().hash(), h); - h = hash_djb2_one_32(E.value().hash(), h); + h = hash_murmur3_one_32(E.key().hash(), h); + h = hash_murmur3_one_32(E.value().hash(), h); } - return h; + return hash_fmix32(h); } Array Dictionary::keys() const { diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h index be98e88a1..79dbcf2e6 100644 --- a/core/io/file_access_pack.h +++ b/core/io/file_access_pack.h @@ -36,6 +36,7 @@ #include "core/os/file_access.h" #include "core/print_string.h" #include "core/set.h" +#include "core/hashfuncs.h" // Pandemonium's packed file magic header ("GDPC" in ASCII). #define PACK_HEADER_MAGIC 0x43504447 @@ -81,6 +82,11 @@ private: return a == p_md5.a && b == p_md5.b; }; + static uint32_t hash(const PathMD5 &p_val) { + uint32_t h = hash_murmur3_one_32(p_val.a); + return hash_fmix32(hash_murmur3_one_32(p_val.b, h)); + } + PathMD5() { a = b = 0; }; diff --git a/core/io/networked_multiplayer_peer.cpp b/core/io/networked_multiplayer_peer.cpp index 5ed47232e..7e85568ed 100644 --- a/core/io/networked_multiplayer_peer.cpp +++ b/core/io/networked_multiplayer_peer.cpp @@ -30,6 +30,30 @@ #include "networked_multiplayer_peer.h" +#include "core/os/os.h" + +uint32_t NetworkedMultiplayerPeer::generate_unique_id() const { + uint32_t hash = 0; + + while (hash == 0 || hash == 1) { + hash = hash_murmur3_one_32( + (uint32_t)OS::get_singleton()->get_ticks_usec()); + hash = hash_murmur3_one_32( + (uint32_t)OS::get_singleton()->get_unix_time(), hash); + hash = hash_murmur3_one_32( + (uint32_t)OS::get_singleton()->get_user_data_dir().hash64(), hash); + hash = hash_murmur3_one_32( + (uint32_t)((uint64_t)this), hash); // Rely on ASLR heap + hash = hash_murmur3_one_32( + (uint32_t)((uint64_t)&hash), hash); // Rely on ASLR stack + + hash = hash_fmix32(hash); + hash = hash & 0x7FFFFFFF; // Make it compatible with unsigned, since negative ID is used for exclusion + } + + return hash; +} + void NetworkedMultiplayerPeer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_transfer_mode", "mode"), &NetworkedMultiplayerPeer::set_transfer_mode); ClassDB::bind_method(D_METHOD("get_transfer_mode"), &NetworkedMultiplayerPeer::get_transfer_mode); @@ -45,6 +69,8 @@ void NetworkedMultiplayerPeer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_refuse_new_connections", "enable"), &NetworkedMultiplayerPeer::set_refuse_new_connections); ClassDB::bind_method(D_METHOD("is_refusing_new_connections"), &NetworkedMultiplayerPeer::is_refusing_new_connections); + ClassDB::bind_method(D_METHOD("generate_unique_id"), &NetworkedMultiplayerPeer::generate_unique_id); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "refuse_new_connections"), "set_refuse_new_connections", "is_refusing_new_connections"); ADD_PROPERTY(PropertyInfo(Variant::INT, "transfer_mode", PROPERTY_HINT_ENUM, "Unreliable,Unreliable Ordered,Reliable"), "set_transfer_mode", "get_transfer_mode"); diff --git a/core/io/networked_multiplayer_peer.h b/core/io/networked_multiplayer_peer.h index 50815d17e..806958a06 100644 --- a/core/io/networked_multiplayer_peer.h +++ b/core/io/networked_multiplayer_peer.h @@ -72,6 +72,8 @@ public: virtual ConnectionStatus get_connection_status() const = 0; + uint32_t generate_unique_id() const; + NetworkedMultiplayerPeer(); }; diff --git a/core/resource.cpp b/core/resource.cpp index bfc18fe3e..408296026 100644 --- a/core/resource.cpp +++ b/core/resource.cpp @@ -262,7 +262,7 @@ void Resource::notify_change_to_owners() { #ifdef TOOLS_ENABLED uint32_t Resource::hash_edited_version() const { - uint32_t hash = hash_djb2_one_32(get_edited_version()); + uint32_t hash = hash_murmur3_one_32(get_edited_version()); List plist; get_property_list(&plist); @@ -271,7 +271,7 @@ uint32_t Resource::hash_edited_version() const { if (E->get().usage & PROPERTY_USAGE_STORAGE && E->get().type == Variant::OBJECT && E->get().hint == PROPERTY_HINT_RESOURCE_TYPE) { RES res = get(E->get().name); if (res.is_valid()) { - hash = hash_djb2_one_32(res->hash_edited_version(), hash); + hash = hash_murmur3_one_32(res->hash_edited_version(), hash); } } } diff --git a/core/variant.cpp b/core/variant.cpp index 12e3fbb44..4818d2599 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -3228,10 +3228,10 @@ uint32_t Variant::hash() const { return _data._bool ? 1 : 0; } break; case INT: { - return _data._int; + return hash_one_uint64((uint64_t)_data._int); } break; case REAL: { - return hash_djb2_one_float(_data._real); + return hash_murmur3_one_float(_data._real); } break; case STRING: { return reinterpret_cast(_data._mem)->hash(); @@ -3239,34 +3239,22 @@ uint32_t Variant::hash() const { // math types case RECT2: { - uint32_t hash = hash_djb2_one_float(reinterpret_cast(_data._mem)->position.x); - hash = hash_djb2_one_float(reinterpret_cast(_data._mem)->position.y, hash); - hash = hash_djb2_one_float(reinterpret_cast(_data._mem)->size.x, hash); - return hash_djb2_one_float(reinterpret_cast(_data._mem)->size.y, hash); + return HashMapHasherDefault::hash(*reinterpret_cast(_data._mem)); } break; case RECT2I: { - uint32_t hash = hash_djb2_one_float(reinterpret_cast(_data._mem)->position.x); - hash = hash_djb2_one_float(reinterpret_cast(_data._mem)->position.y, hash); - hash = hash_djb2_one_float(reinterpret_cast(_data._mem)->size.x, hash); - return hash_djb2_one_float(reinterpret_cast(_data._mem)->size.y, hash); + return HashMapHasherDefault::hash(*reinterpret_cast(_data._mem)); } break; case VECTOR2: { - uint32_t hash = hash_djb2_one_float(reinterpret_cast(_data._mem)->x); - return hash_djb2_one_float(reinterpret_cast(_data._mem)->y, hash); + return HashMapHasherDefault::hash(*reinterpret_cast(_data._mem)); } break; case VECTOR2I: { - uint32_t hash = hash_djb2_one_float(reinterpret_cast(_data._mem)->x); - return hash_djb2_one_float(reinterpret_cast(_data._mem)->y, hash); + return HashMapHasherDefault::hash(*reinterpret_cast(_data._mem)); } break; case VECTOR3: { - uint32_t hash = hash_djb2_one_float(reinterpret_cast(_data._mem)->x); - hash = hash_djb2_one_float(reinterpret_cast(_data._mem)->y, hash); - return hash_djb2_one_float(reinterpret_cast(_data._mem)->z, hash); + return HashMapHasherDefault::hash(*reinterpret_cast(_data._mem)); } break; case VECTOR3I: { - uint32_t hash = hash_djb2_one_float(reinterpret_cast(_data._mem)->x); - hash = hash_djb2_one_float(reinterpret_cast(_data._mem)->y, hash); - return hash_djb2_one_float(reinterpret_cast(_data._mem)->z, hash); + return HashMapHasherDefault::hash(*reinterpret_cast(_data._mem)); } break; case VECTOR4: { return HashMapHasherDefault::hash(*reinterpret_cast(_data._mem)); @@ -3274,60 +3262,69 @@ uint32_t Variant::hash() const { case VECTOR4I: { return HashMapHasherDefault::hash(*reinterpret_cast(_data._mem)); } break; - case PLANE: { - uint32_t hash = hash_djb2_one_float(reinterpret_cast(_data._mem)->normal.x); - hash = hash_djb2_one_float(reinterpret_cast(_data._mem)->normal.y, hash); - hash = hash_djb2_one_float(reinterpret_cast(_data._mem)->normal.z, hash); - return hash_djb2_one_float(reinterpret_cast(_data._mem)->d, hash); - + uint32_t h = HASH_MURMUR3_SEED; + const Plane &p = *reinterpret_cast(_data._mem); + h = hash_murmur3_one_real(p.normal.x, h); + h = hash_murmur3_one_real(p.normal.y, h); + h = hash_murmur3_one_real(p.normal.z, h); + h = hash_murmur3_one_real(p.d, h); + return hash_fmix32(h); } break; case QUATERNION: { - uint32_t hash = hash_djb2_one_float(reinterpret_cast(_data._mem)->x); - hash = hash_djb2_one_float(reinterpret_cast(_data._mem)->y, hash); - hash = hash_djb2_one_float(reinterpret_cast(_data._mem)->z, hash); - return hash_djb2_one_float(reinterpret_cast(_data._mem)->w, hash); - + uint32_t h = HASH_MURMUR3_SEED; + const Quaternion &q = *reinterpret_cast(_data._mem); + h = hash_murmur3_one_real(q.x, h); + h = hash_murmur3_one_real(q.y, h); + h = hash_murmur3_one_real(q.z, h); + h = hash_murmur3_one_real(q.w, h); + return hash_fmix32(h); } break; case AABB: { - uint32_t hash = 5831; - for (int i = 0; i < 3; i++) { - hash = hash_djb2_one_float(_data._aabb->position[i], hash); - hash = hash_djb2_one_float(_data._aabb->size[i], hash); - } - - return hash; + return HashMapHasherDefault::hash(*_data._aabb); } break; case BASIS: { - uint32_t hash = 5831; - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - hash = hash_djb2_one_float(_data._basis->rows[i][j], hash); - } - } - - return hash; + uint32_t h = HASH_MURMUR3_SEED; + const Basis &b = *_data._basis; + h = hash_murmur3_one_real(b[0].x, h); + h = hash_murmur3_one_real(b[0].y, h); + h = hash_murmur3_one_real(b[0].z, h); + h = hash_murmur3_one_real(b[1].x, h); + h = hash_murmur3_one_real(b[1].y, h); + h = hash_murmur3_one_real(b[1].z, h); + h = hash_murmur3_one_real(b[2].x, h); + h = hash_murmur3_one_real(b[2].y, h); + h = hash_murmur3_one_real(b[2].z, h); + return hash_fmix32(h); } break; case TRANSFORM: { - uint32_t hash = 5831; - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - hash = hash_djb2_one_float(_data._transform->basis.rows[i][j], hash); - } - hash = hash_djb2_one_float(_data._transform->origin[i], hash); - } - - return hash; + uint32_t h = HASH_MURMUR3_SEED; + const Transform &t = *_data._transform; + h = hash_murmur3_one_real(t.basis[0].x, h); + h = hash_murmur3_one_real(t.basis[0].y, h); + h = hash_murmur3_one_real(t.basis[0].z, h); + h = hash_murmur3_one_real(t.basis[1].x, h); + h = hash_murmur3_one_real(t.basis[1].y, h); + h = hash_murmur3_one_real(t.basis[1].z, h); + h = hash_murmur3_one_real(t.basis[2].x, h); + h = hash_murmur3_one_real(t.basis[2].y, h); + h = hash_murmur3_one_real(t.basis[2].z, h); + h = hash_murmur3_one_real(t.origin.x, h); + h = hash_murmur3_one_real(t.origin.y, h); + h = hash_murmur3_one_real(t.origin.z, h); + return hash_fmix32(h); } break; case TRANSFORM2D: { - uint32_t hash = 5831; - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 2; j++) { - hash = hash_djb2_one_float(_data._transform2d->columns[i][j], hash); - } - } + uint32_t h = HASH_MURMUR3_SEED; + const Transform2D &t = *_data._transform2d; + h = hash_murmur3_one_real(t[0].x, h); + h = hash_murmur3_one_real(t[0].y, h); + h = hash_murmur3_one_real(t[1].x, h); + h = hash_murmur3_one_real(t[1].y, h); + h = hash_murmur3_one_real(t[2].x, h); + h = hash_murmur3_one_real(t[2].y, h); - return hash; + return hash_fmix32(h); } break; case PROJECTION: { uint32_t h = HASH_MURMUR3_SEED; @@ -3353,19 +3350,22 @@ uint32_t Variant::hash() const { // misc types case COLOR: { - uint32_t hash = hash_djb2_one_float(reinterpret_cast(_data._mem)->r); - hash = hash_djb2_one_float(reinterpret_cast(_data._mem)->g, hash); - hash = hash_djb2_one_float(reinterpret_cast(_data._mem)->b, hash); - return hash_djb2_one_float(reinterpret_cast(_data._mem)->a, hash); + uint32_t h = HASH_MURMUR3_SEED; + const Color &c = *reinterpret_cast(_data._mem); + h = hash_murmur3_one_float(c.r, h); + h = hash_murmur3_one_float(c.g, h); + h = hash_murmur3_one_float(c.b, h); + h = hash_murmur3_one_float(c.a, h); + return hash_fmix32(h); } break; case NODE_PATH: { return reinterpret_cast(_data._mem)->hash(); } break; case RID: { - return hash_djb2_one_64(reinterpret_cast(_data._mem)->get_id()); + return hash_one_uint64(reinterpret_cast(_data._mem)->get_id()); } break; case OBJECT: { - return hash_djb2_one_64(make_uint64_t(_UNSAFE_OBJ_PROXY_PTR(*this))); + return hash_one_uint64(hash_make_uint64_t(_UNSAFE_OBJ_PROXY_PTR(*this))); } break; case STRING_NAME: { return reinterpret_cast(_data._mem)->hash(); @@ -3383,9 +3383,9 @@ uint32_t Variant::hash() const { int len = arr.size(); if (likely(len)) { PoolVector::Read r = arr.read(); - return hash_djb2_buffer((uint8_t *)&r[0], len); + return hash_murmur3_buffer((uint8_t *)&r[0], len); } else { - return hash_djb2_one_64(0); + return hash_murmur3_one_64(0); } } break; @@ -3394,9 +3394,9 @@ uint32_t Variant::hash() const { int len = arr.size(); if (likely(len)) { PoolVector::Read r = arr.read(); - return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(int)); + return hash_murmur3_buffer((uint8_t *)&r[0], len * sizeof(int)); } else { - return hash_djb2_one_64(0); + return hash_murmur3_one_64(0); } } break; @@ -3406,14 +3406,20 @@ uint32_t Variant::hash() const { if (likely(len)) { PoolVector::Read r = arr.read(); - return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(real_t)); + uint32_t h = HASH_MURMUR3_SEED; + + for (int i = 0; i < len; i++) { + h = hash_murmur3_one_real(r[i], h); + } + + return hash_fmix32(h); } else { - return hash_djb2_one_float(0.0); + return hash_murmur3_one_real(0.0); } } break; case POOL_STRING_ARRAY: { - uint32_t hash = 5831; + uint32_t hash = HASH_MURMUR3_SEED; const PoolVector &arr = *reinterpret_cast *>(_data._mem); int len = arr.size(); @@ -3421,14 +3427,16 @@ uint32_t Variant::hash() const { PoolVector::Read r = arr.read(); for (int i = 0; i < len; i++) { - hash = hash_djb2_one_32(r[i].hash(), hash); + hash = hash_murmur3_one_32(r[i].hash(), hash); } + + hash = hash_fmix32(hash); } return hash; } break; case POOL_VECTOR2_ARRAY: { - uint32_t hash = 5831; + uint32_t hash = HASH_MURMUR3_SEED; const PoolVector &arr = *reinterpret_cast *>(_data._mem); int len = arr.size(); @@ -3436,15 +3444,17 @@ uint32_t Variant::hash() const { PoolVector::Read r = arr.read(); for (int i = 0; i < len; i++) { - hash = hash_djb2_one_float(r[i].x, hash); - hash = hash_djb2_one_float(r[i].y, hash); + hash = hash_murmur3_one_real(r[i].x, hash); + hash = hash_murmur3_one_real(r[i].y, hash); } + + hash = hash_fmix32(hash); } return hash; } break; case POOL_VECTOR2I_ARRAY: { - uint32_t hash = 5831; + uint32_t hash = HASH_MURMUR3_SEED; const PoolVector &arr = *reinterpret_cast *>(_data._mem); int len = arr.size(); @@ -3452,15 +3462,17 @@ uint32_t Variant::hash() const { PoolVector::Read r = arr.read(); for (int i = 0; i < len; i++) { - hash = hash_djb2_one_float(r[i].x, hash); - hash = hash_djb2_one_float(r[i].y, hash); + hash = hash_murmur3_one_32(r[i].x, hash); + hash = hash_murmur3_one_32(r[i].y, hash); } + + hash = hash_fmix32(hash); } return hash; } break; case POOL_VECTOR3_ARRAY: { - uint32_t hash = 5831; + uint32_t hash = HASH_MURMUR3_SEED; const PoolVector &arr = *reinterpret_cast *>(_data._mem); int len = arr.size(); @@ -3468,16 +3480,18 @@ uint32_t Variant::hash() const { PoolVector::Read r = arr.read(); for (int i = 0; i < len; i++) { - hash = hash_djb2_one_float(r[i].x, hash); - hash = hash_djb2_one_float(r[i].y, hash); - hash = hash_djb2_one_float(r[i].z, hash); + hash = hash_murmur3_one_real(r[i].x, hash); + hash = hash_murmur3_one_real(r[i].y, hash); + hash = hash_murmur3_one_real(r[i].z, hash); } + + hash = hash_fmix32(hash); } return hash; } break; case POOL_VECTOR3I_ARRAY: { - uint32_t hash = 5831; + uint32_t hash = HASH_MURMUR3_SEED; const PoolVector &arr = *reinterpret_cast *>(_data._mem); int len = arr.size(); @@ -3485,16 +3499,18 @@ uint32_t Variant::hash() const { PoolVector::Read r = arr.read(); for (int i = 0; i < len; i++) { - hash = hash_djb2_one_float(r[i].x, hash); - hash = hash_djb2_one_float(r[i].y, hash); - hash = hash_djb2_one_float(r[i].z, hash); + hash = hash_murmur3_one_32(r[i].x, hash); + hash = hash_murmur3_one_32(r[i].y, hash); + hash = hash_murmur3_one_32(r[i].z, hash); } + + hash = hash_fmix32(hash); } return hash; } break; case POOL_VECTOR4_ARRAY: { - uint32_t hash = 5831; + uint32_t hash = HASH_MURMUR3_SEED; const PoolVector &arr = *reinterpret_cast *>(_data._mem); int len = arr.size(); @@ -3502,17 +3518,19 @@ uint32_t Variant::hash() const { PoolVector::Read r = arr.read(); for (int i = 0; i < len; i++) { - hash = hash_djb2_one_float(r[i].x, hash); - hash = hash_djb2_one_float(r[i].y, hash); - hash = hash_djb2_one_float(r[i].z, hash); - hash = hash_djb2_one_float(r[i].w, hash); + hash = hash_murmur3_one_real(r[i].x, hash); + hash = hash_murmur3_one_real(r[i].y, hash); + hash = hash_murmur3_one_real(r[i].z, hash); + hash = hash_murmur3_one_real(r[i].w, hash); } + + hash = hash_fmix32(hash); } return hash; } break; case POOL_VECTOR4I_ARRAY: { - uint32_t hash = 5831; + uint32_t hash = HASH_MURMUR3_SEED; const PoolVector &arr = *reinterpret_cast *>(_data._mem); int len = arr.size(); @@ -3520,17 +3538,19 @@ uint32_t Variant::hash() const { PoolVector::Read r = arr.read(); for (int i = 0; i < len; i++) { - hash = hash_djb2_one_float(r[i].x, hash); - hash = hash_djb2_one_float(r[i].y, hash); - hash = hash_djb2_one_float(r[i].z, hash); - hash = hash_djb2_one_float(r[i].w, hash); + hash = hash_murmur3_one_32(r[i].x, hash); + hash = hash_murmur3_one_32(r[i].y, hash); + hash = hash_murmur3_one_32(r[i].z, hash); + hash = hash_murmur3_one_32(r[i].w, hash); } + + hash = hash_fmix32(hash); } return hash; } break; case POOL_COLOR_ARRAY: { - uint32_t hash = 5831; + uint32_t hash = HASH_MURMUR3_SEED; const PoolVector &arr = *reinterpret_cast *>(_data._mem); int len = arr.size(); @@ -3538,11 +3558,13 @@ uint32_t Variant::hash() const { PoolVector::Read r = arr.read(); for (int i = 0; i < len; i++) { - hash = hash_djb2_one_float(r[i].r, hash); - hash = hash_djb2_one_float(r[i].g, hash); - hash = hash_djb2_one_float(r[i].b, hash); - hash = hash_djb2_one_float(r[i].a, hash); + hash = hash_murmur3_one_real(r[i].r, hash); + hash = hash_murmur3_one_real(r[i].g, hash); + hash = hash_murmur3_one_real(r[i].b, hash); + hash = hash_murmur3_one_real(r[i].a, hash); } + + hash = hash_fmix32(hash); } return hash; diff --git a/modules/mesh_utils/delaunay/delaunay_3d.h b/modules/mesh_utils/delaunay/delaunay_3d.h index fe08dec32..c887896c0 100644 --- a/modules/mesh_utils/delaunay/delaunay_3d.h +++ b/modules/mesh_utils/delaunay/delaunay_3d.h @@ -132,7 +132,7 @@ class Delaunay3D { _FORCE_INLINE_ static uint32_t hash(const Triangle &p_triangle) { uint32_t h = hash_djb2_one_32(p_triangle.triangle[0]); h = hash_djb2_one_32(p_triangle.triangle[1], h); - return hash_djb2_one_32(p_triangle.triangle[2], h); + return hash_fmix32(hash_djb2_one_32(p_triangle.triangle[2], h)); } };