summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--compat/int-hash.cpp37
-rw-r--r--compat/int-hash.hpp27
-rw-r--r--src/character.cpp1
-rw-r--r--src/entity.cpp20
-rw-r--r--src/world.cpp5
-rw-r--r--src/world.hpp8
6 files changed, 61 insertions, 37 deletions
diff --git a/compat/int-hash.cpp b/compat/int-hash.cpp
new file mode 100644
index 00000000..ae2e6729
--- /dev/null
+++ b/compat/int-hash.cpp
@@ -0,0 +1,37 @@
+#include "int-hash.hpp"
+#include <bit>
+
+namespace floormat {
+
+size_t int_hash32(uint32_t x) noexcept
+{
+ if constexpr(sizeof(size_t) == 4)
+ {
+ // by Chris Wellons <https://nullprogram.com/blog/2018/07/31/>
+
+ x ^= x >> 15;
+ x *= 0x2c1b3c6dU;
+ x ^= x >> 12;
+ x *= 0x297a2d39U;
+ x ^= x >> 15;
+
+ return x;
+ }
+ else
+ return int_hash64(x);
+}
+
+size_t int_hash64(uint64_t x) noexcept
+{
+ // NASAM by Pelle Evensen <https://mostlymangling.blogspot.com/2020/01/nasam-not-another-strange-acronym-mixer.html>
+
+ x ^= std::rotr(x, 25) ^ std::rotr(x, 47);
+ x *= 0x9E6C63D0676A9A99UL;
+ x ^= x >> 23 ^ x >> 51;
+ x *= 0x9E6D62D06F6A9A9BUL;
+ x ^= x >> 23 ^ x >> 51;
+
+ return x;
+}
+
+} // namespace floormat
diff --git a/compat/int-hash.hpp b/compat/int-hash.hpp
index 52b4c170..e5cfc67a 100644
--- a/compat/int-hash.hpp
+++ b/compat/int-hash.hpp
@@ -1,30 +1,11 @@
#pragma once
-#include <bit>
namespace floormat {
-constexpr inline size_t int_hash(size_t x) noexcept
-{
- if constexpr(sizeof(size_t) == 4)
- {
- // by Chris Wellons <https://nullprogram.com/blog/2018/07/31/>
- x ^= x >> 15;
- x *= 0x2c1b3c6dU;
- x ^= x >> 12;
- x *= 0x297a2d39U;
- x ^= x >> 15;
- }
- else if constexpr(sizeof(size_t) == 8)
- {
- // NASAM by Pelle Evensen <https://mostlymangling.blogspot.com/2020/01/nasam-not-another-strange-acronym-mixer.html>
- x ^= std::rotr(x, 25) ^ std::rotr(x, 47);
- x *= 0x9E6C63D0676A9A99UL;
- x ^= x >> 23 ^ x >> 51;
- x *= 0x9E6D62D06F6A9A9BUL;
- x ^= x >> 23 ^ x >> 51;
- }
+size_t int_hash32(uint32_t x) noexcept;
+size_t int_hash64(uint64_t x) noexcept;
- return x;
-}
+inline size_t int_hash(uint32_t x) noexcept { return int_hash32(x); }
+inline size_t int_hash(uint64_t x) noexcept { return int_hash64(x); }
} // namespace floormat
diff --git a/src/character.cpp b/src/character.cpp
index e6f2da04..a2098788 100644
--- a/src/character.cpp
+++ b/src/character.cpp
@@ -5,6 +5,7 @@
#include "src/entity.hpp"
#include "shaders/tile.hpp"
#include "src/RTree-search.hpp"
+#include "compat/exception.hpp"
#include <cmath>
#include <utility>
#include <algorithm>
diff --git a/src/entity.cpp b/src/entity.cpp
index be91db7f..13f19620 100644
--- a/src/entity.cpp
+++ b/src/entity.cpp
@@ -127,7 +127,7 @@ Pair<global_coords, Vector2b> entity::normalize_coords(global_coords coord, Vect
}
template<bool neighbor = true>
-static bool do_search(struct chunk* c, chunk_coords_ coord, object_id id, Vector2 min, Vector2 max, Vector2i off = {})
+static bool do_search(struct chunk* c, chunk_coords_ coord, object_id id, Vector2 min, Vector2 max, Vector2b off = {})
{
if constexpr(neighbor)
{
@@ -168,15 +168,15 @@ bool entity::can_move_to(Vector2i delta, global_coords coord2, Vector2b offset,
half_bbox = Vector2(bbox_size)*.5f,
min = center - half_bbox, max = min + Vector2(bbox_size);
auto ch = chunk_coords_{coord_.chunk(), coord_.z()};
- return do_search<false>(&c_, ch, id, min, max) &&
- do_search(&c_, ch, id, min, max, {-1, -1}) &&
- do_search(&c_, ch, id, min, max, {-1, 0}) &&
- do_search(&c_, ch, id, min, max, { 0, -1}) &&
- do_search(&c_, ch, id, min, max, { 1, 1}) &&
- do_search(&c_, ch, id, min, max, { 1, 0}) &&
- do_search(&c_, ch, id, min, max, { 0, 1}) &&
- do_search(&c_, ch, id, min, max, { 1, -1}) &&
- do_search(&c_, ch, id, min, max, {-1, 1});
+ if (!do_search<false>(&c_, ch, id, min, max))
+ return false;
+ constexpr Vector2b offsets[] = {
+ {-1, -1}, {-1, 0}, { 0, -1}, { 1, 1}, { 1, 0}, { 0, 1}, { 1, -1}, {-1, 1},
+ };
+ for (const auto& off : offsets)
+ if (!do_search(&c_, ch, id, min, max, off))
+ return false;
+ return true;
}
bool entity::can_move_to(Vector2i delta)
diff --git a/src/world.cpp b/src/world.cpp
index f0818b44..028ddd45 100644
--- a/src/world.cpp
+++ b/src/world.cpp
@@ -2,6 +2,7 @@
#include "chunk.hpp"
#include "entity.hpp"
#include "compat/int-hash.hpp"
+#include "compat/exception.hpp"
using namespace floormat;
@@ -12,9 +13,9 @@ size_t std::hash<chunk_coords_>::operator()(const chunk_coords_& coord) const no
x |= size_t(uint16_t(coord.y)) << 16;
x |= size_t(uint16_t(coord.x));
if constexpr(sizeof(size_t) > 4)
- x |= size_t(uint8_t(coord.z+8) & 0xf) << 20;
+ x |= size_t(uint8_t(coord.z-chunk_min_z) & 0xf) << 32;
else
- x ^= size_t(uint8_t(coord.z+8) & 0xf) * size_t(1664525);
+ x ^= size_t(uint8_t(coord.z-chunk_min_z) & 0xf) * size_t(1664525);
return int_hash(x);
}
diff --git a/src/world.hpp b/src/world.hpp
index 90067c35..2dce958c 100644
--- a/src/world.hpp
+++ b/src/world.hpp
@@ -4,8 +4,9 @@
#include "global-coords.hpp"
#include "entity-type.hpp"
#include "compat/exception.hpp"
-#include <unordered_map>
+#include "compat/int-hash.hpp"
#include <memory>
+#include <unordered_map>
#include <tsl/robin_map.h>
template<>
@@ -17,6 +18,9 @@ namespace floormat {
struct entity;
template<typename T> struct entity_type_;
+struct object_id_hasher {
+ size_t operator()(object_id id) const noexcept { return int_hash(id); }
+};
struct world final
{
@@ -32,7 +36,7 @@ private:
} _last_chunk;
std::unordered_map<chunk_coords_, chunk> _chunks;
- tsl::robin_map<object_id, std::weak_ptr<entity>> _entities;
+ tsl::robin_map<object_id, std::weak_ptr<entity>, object_id_hasher> _entities;
size_t _last_collection = 0;
size_t _collect_every = 64;
std::shared_ptr<char> _unique_id = std::make_shared<char>('A');