diff options
Diffstat (limited to 'src/chunk.hpp')
-rw-r--r-- | src/chunk.hpp | 49 |
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 |