summaryrefslogtreecommitdiffhomepage
path: root/src/chunk.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/chunk.hpp')
-rw-r--r--src/chunk.hpp49
1 files changed, 48 insertions, 1 deletions
diff --git a/src/chunk.hpp b/src/chunk.hpp
index 8d6f5a6b..54f59e2d 100644
--- a/src/chunk.hpp
+++ b/src/chunk.hpp
@@ -2,6 +2,7 @@
#include "tile.hpp"
#include "tile-iterator.hpp"
#include "scenery.hpp"
+#include <concepts>
#include <type_traits>
#include <array>
#include <memory>
@@ -22,7 +23,8 @@ enum class collision_type : std::uint8_t {
struct collision_data final {
std::uint64_t tag : 2;
- std::uint64_t data : 62;
+ std::uint64_t pass : 2;
+ std::uint64_t data : 60;
};
struct chunk final
@@ -56,6 +58,7 @@ struct chunk final
void mark_ground_modified() noexcept;
void mark_walls_modified() noexcept;
void mark_scenery_modified() noexcept;
+ bool is_passability_modified() const noexcept;
void mark_modified() noexcept;
struct ground_mesh_tuple final {
@@ -92,6 +95,9 @@ struct chunk final
const RTree* rtree() const noexcept;
RTree* rtree() noexcept;
+ template<std::invocable<tile_ref&> F> void with_scenery_bbox_update(tile_ref t, F&& fun);
+ template<std::invocable<> F> void with_scenery_bbox_update(std::size_t i, F&& fun);
+
private:
std::array<std::shared_ptr<tile_atlas>, TILE_COUNT> _ground_atlases;
std::array<std::uint8_t, TILE_COUNT> ground_indexes = {};
@@ -112,6 +118,47 @@ private:
_walls_modified : 1 = true,
_scenery_modified : 1 = true,
_pass_modified : 1 = true;
+
+ struct bbox final // NOLINT(cppcoreguidelines-pro-type-member-init)
+ {
+ std::uint64_t id;
+ Vector2i start, end;
+
+ bool operator==(const bbox& other) const noexcept;
+ };
+ bool _bbox_for_scenery(std::size_t i, bbox& value) noexcept;
+ void _remove_bbox(const bbox& x);
+ void _add_bbox(const bbox& x);
+ void _replace_bbox(const bbox& x0, const bbox& x, bool b0, bool b);
};
+template<std::invocable<tile_ref&> F>
+void chunk::with_scenery_bbox_update(tile_ref t, F&& fun)
+{
+ if (is_passability_modified())
+ return fun(t);
+ else
+ {
+ bbox x0, x;
+ std::size_t i = t.index();
+ bool b0 = _bbox_for_scenery(i, x0);
+ fun(t);
+ _replace_bbox(x0, x, b0, _bbox_for_scenery(i, x));
+ }
+}
+
+template<std::invocable<> F>
+void chunk::with_scenery_bbox_update(std::size_t i, F&& fun)
+{
+ if (is_passability_modified())
+ return fun();
+ else
+ {
+ bbox x0, x;
+ bool b0 = _bbox_for_scenery(i, x0);
+ fun();
+ _replace_bbox(x0, x, b0, _bbox_for_scenery(i, x));
+ }
+}
+
} // namespace floormat