From c489a322b944da55dabd18db60a46e5f314c5d5d Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Thu, 6 Jun 2024 15:33:51 +0200 Subject: w --- src/chunk-collision.cpp | 92 +++++++++++++++++++++++++++++-------------------- src/hole-cut.cpp | 32 ++++++++--------- src/hole.hpp | 9 ++--- 3 files changed, 74 insertions(+), 59 deletions(-) (limited to 'src') diff --git a/src/chunk-collision.cpp b/src/chunk-collision.cpp index 1f6e0d27..33b0453b 100644 --- a/src/chunk-collision.cpp +++ b/src/chunk-collision.cpp @@ -1,8 +1,10 @@ #include "chunk.hpp" #include "ground-atlas.hpp" #include "object.hpp" +#include "world.hpp" #include "src/RTree-search.hpp" #include "rect-intersects.hpp" +#include "hole.hpp" #include "src/chunk-scenery.hpp" #include "src/tile-bbox.hpp" #include "src/hole.hpp" @@ -10,7 +12,6 @@ #include #include #include -//#include namespace floormat { @@ -32,13 +33,6 @@ constexpr object_id make_id(collision_type type, pass_mode p, object_id id) return std::bit_cast(make_id_(type, p, id)); } -struct Data -{ - object_id id; - Vector2 min, max; -}; - -#if 0 template void add_holes_from(chunk::RTree& rtree, chunk& c, Vector2b chunk_offset) { @@ -65,35 +59,55 @@ void add_holes_from(chunk::RTree& rtree, chunk& c, Vector2b chunk_offset) } } -void filter_through_holes(chunk::RTree& rtree, Data bbox, unsigned stack) +#if 0 +void filter_through_holes(chunk::RTree& rtree, object_id id, Vector2 min, Vector2 max, unsigned stack = 0) { - using Rect = typename chunk::RTree::Rect; - Vector2 hmin, hmax; +start: + CutResult::rect hole; bool ret = true; - rtree.Search(bbox.min.data(), bbox.max.data(), [&](uint64_t data, const Rect& r) { + rtree.Search(min.data(), max.data(), [&](uint64_t data, const chunk::RTree::Rect& r) { [[maybe_unused]] auto x = std::bit_cast(data); if (x.pass == (uint64_t)pass_mode::pass && x.tag == (uint64_t)collision_type::none) { - hmin = Vector2(r.m_min[0], r.m_min[1]); - hmax = Vector2(r.m_max[0], r.m_max[1]); - return ret = false; + CutResult::rect holeʹ { + .min = { r.m_min[0], r.m_min[1] }, + .max = { r.m_max[0], r.m_max[1] }, + }; + if (rect_intersects(holeʹ.min, holeʹ.max, min, max)) + { + hole = holeʹ; + return ret = false; + } } return true; }); if (ret) [[likely]] - rtree.Insert(bbox.min.data(), bbox.max.data(), bbox.id); + rtree.Insert(min.data(), max.data(), id); else { - //auto res = cut_rectangle_result::cut(); - //for (auto i = 0uz; i < ) - fm_assert(++stack <= 4096); - } + auto res = CutResult::cut(min, max, hole.min, hole.max); + if (!res.found) + { + rtree.Insert(min.data(), max.data(), id); + } + else if (res.size == 1) + { + min = res.array[0].min; + max = res.array[0].max; + goto start; + } + else + { + fm_assert(stack <= 1024); + for (auto i = 0uz; i < res.size; i++) + filter_through_holes(rtree, id, res.array[i].min, res.array[i].max, stack+1); + }} } #else -void filter_through_holes(chunk::RTree& rtree, Data bbox, unsigned) +void filter_through_holes(chunk::RTree& rtree, object_id id, Vector2 min, Vector2 max, unsigned = 0) { - rtree.Insert(bbox.min.data(), bbox.max.data(), bbox.id); + rtree.Insert(min.data(), max.data(), id); } #endif @@ -109,13 +123,21 @@ void chunk::ensure_passability() noexcept _rtree->RemoveAll(); + { + add_holes_from(*_rtree, *this, {}); + const auto nbs = _world->neighbors(_coord); + for (auto i = 0u; i < 8; i++) + if (nbs[i]) + add_holes_from(*_rtree, *nbs[i], world::neighbor_offsets[i]); + } + for (auto i = 0uz; i < TILE_COUNT; i++) { if (const auto* atlas = ground_atlas_at(i)) { auto [min, max] = whole_tile(i); auto id = make_id(collision_type::geometry, atlas->pass_mode(), i+1); - filter_through_holes(*_rtree, {id, min, max}, 0); + filter_through_holes(*_rtree, id, min, max); } } for (auto i = 0uz; i < TILE_COUNT; i++) @@ -125,35 +147,31 @@ void chunk::ensure_passability() noexcept { auto [min, max] = wall_north(i, (float)atlas->info().depth); auto id = make_id(collision_type::geometry, atlas->info().passability, TILE_COUNT+i+1); - filter_through_holes(*_rtree, {id, min, max}, 0); + filter_through_holes(*_rtree, id, min, max); if (tile.wall_west_atlas()) { auto [min, max] = wall_pillar(i, (float)atlas->info().depth); - filter_through_holes(*_rtree, {id, min, max}, 0); + filter_through_holes(*_rtree, id, min, max); } } if (const auto* atlas = tile.wall_west_atlas().get()) { auto [min, max] = wall_west(i, (float)atlas->info().depth); auto id = make_id(collision_type::geometry, atlas->info().passability, TILE_COUNT*2+i+1); - filter_through_holes(*_rtree, {id, min, max}, 0); + filter_through_holes(*_rtree, id, min, max); } } - for (const std::shared_ptr& s : objects()) - if (!s->is_dynamic()) - if (bbox box; _bbox_for_scenery(*s, box)) - filter_through_holes(*_rtree, {std::bit_cast(box.data), Vector2(box.start), Vector2(box.end)}, 0); - - //for (auto [id, min, max] : vec) _rtree->Insert(min.data(), max.data(), id); - //arrayResize(vec, 0); arrayResize(vec2, 0); // done with holes - - for (const std::shared_ptr& s : objects()) + for (const std::shared_ptr& sʹ : objects()) { bbox box; - if (s->is_dynamic()) - if (_bbox_for_scenery(*s, box)) + if (sʹ->type() != object_type::hole && _bbox_for_scenery(*sʹ, box)) + { + if (sʹ->is_dynamic()) _add_bbox(box); + else + filter_through_holes(*_rtree, std::bit_cast(box.data), Vector2(box.start), Vector2(box.end)); + } } } diff --git a/src/hole-cut.cpp b/src/hole-cut.cpp index 51d1a8af..bb27c10b 100644 --- a/src/hole-cut.cpp +++ b/src/hole-cut.cpp @@ -15,9 +15,9 @@ namespace floormat { namespace { -template using crr = cut_rectangle_result; -template using bbox = typename cut_rectangle_result::bbox; -template using rect = typename cut_rectangle_result::rect; +template using Cr = CutResult; +template using bbox = typename Cr::bbox; +template using rect = typename Cr::rect; enum shift : uint8_t { __ = 0, x0 = 1 << 0, x1 = 1 << 1, y0 = 1 << 2, y1 = 1 << 3, }; enum class location : uint8_t { R0, R1, H0, H1, }; @@ -151,12 +151,13 @@ constexpr bool check_empty(Vec2ʹ r0, Vec2ʹ r1, Vec2ʹ h0, Vec2ʹ h } template -constexpr cut_rectangle_result cut_rectangle(Vec2ʹ r0, Vec2ʹ r1, Vec2ʹ h0, Vec2ʹ h1) +constexpr Cr cut_rectangle(Vec2ʹ r0, Vec2ʹ r1, Vec2ʹ h0, Vec2ʹ h1) { if (check_empty(r0, r1, h0, h1)) return { - .size = 1, .array = {{ { r0, r1 }, }}, + .size = 1, + .found = false, }; const bool sx = h0.x() <= r0.x(); @@ -168,9 +169,10 @@ constexpr cut_rectangle_result cut_rectangle(Vec2ʹ r0, Vec2ʹ r1, Vec2 CORRADE_ASSUME(val < 16); const auto elt = elements[val]; const auto sz = elt.size; - cut_rectangle_result res = { - .size = sz, + Cr res = { .array = {}, + .size = sz, + .found = true, }; for (auto i = 0u; i < 8; i++) @@ -180,7 +182,7 @@ constexpr cut_rectangle_result cut_rectangle(Vec2ʹ r0, Vec2ʹ r1, Vec2 } template -constexpr cut_rectangle_result cut_rectangle(bbox input, bbox hole) +constexpr Cr cut_rectangle(bbox input, bbox hole) { using Vec2 = Vec2ʹ; @@ -197,16 +199,10 @@ constexpr cut_rectangle_result cut_rectangle(bbox input, bbox hole) } // namespace -template struct cut_rectangle_result; -template struct cut_rectangle_result; - -template crr cut_rectangle_result::cut(bbox input, bbox hole) { return cut_rectangle(input, hole); } -template crr cut_rectangle_result::cut(Vec2 r0, Vec2 r1, Vec2 h0, Vec2 h1) { return cut_rectangle(r0, r1, h0, h1); } - -template cut_rectangle_result cut_rectangle_result::cut(bbox input, bbox hole); -template cut_rectangle_result cut_rectangle_result::cut(bbox input, bbox hole); +template Cr CutResult::cut(bbox input, bbox hole) { return cut_rectangle(input, hole); } +template Cr CutResult::cut(Vec2 r0, Vec2 r1, Vec2 h0, Vec2 h1) { return cut_rectangle(r0, r1, h0, h1); } -template cut_rectangle_result cut_rectangle_result::cut(Vector2i r0, Vector2i r1, Vector2i h0, Vector2i h1); -template cut_rectangle_result cut_rectangle_result::cut(Vector2 r0, Vector2 r1, Vector2 h0, Vector2 h1); +template struct CutResult; +template struct CutResult; } // namespace floormat diff --git a/src/hole.hpp b/src/hole.hpp index 384a5044..5e993072 100644 --- a/src/hole.hpp +++ b/src/hole.hpp @@ -56,17 +56,18 @@ private: }; template -struct cut_rectangle_result // todo rename +struct CutResult { using Vec2 = VectorTypeFor<2, T>; struct bbox { Vec2 position; Vector2ub bbox_size; }; struct rect { Vec2 min, max; }; - static cut_rectangle_result cut(bbox input, bbox hole); - static cut_rectangle_result cut(Vec2 r0, Vec2 r1, Vec2 h0, Vec2 h1); + static CutResult cut(bbox input, bbox hole); + static CutResult cut(Vec2 r0, Vec2 r1, Vec2 h0, Vec2 h1); - uint8_t size = 0; std::array array; + uint8_t size = 0; + bool found = false; }; } // namespace floormat -- cgit v1.2.3