diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2023-02-25 21:11:18 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2023-02-25 21:11:18 +0100 |
commit | 0b694f21edc97bd95faa65197bdda6b440479df3 (patch) | |
tree | 6ea5311aeb8c0b9613db429b1ffbe670924ea6b7 | |
parent | a823c20d5d789a680a83a5edc5794abf943da378 (diff) |
a
-rw-r--r-- | editor/draw.cpp | 45 | ||||
-rw-r--r-- | floormat/main.hpp | 1 | ||||
-rw-r--r-- | main/draw.cpp | 11 | ||||
-rw-r--r-- | main/main-impl.hpp | 1 | ||||
-rw-r--r-- | src/RTree.h | 1 | ||||
-rw-r--r-- | src/chunk-collision.cpp | 4 | ||||
-rw-r--r-- | src/chunk.hpp | 8 |
7 files changed, 60 insertions, 11 deletions
diff --git a/editor/draw.cpp b/editor/draw.cpp index 783ead39..5f56f01e 100644 --- a/editor/draw.cpp +++ b/editor/draw.cpp @@ -68,6 +68,9 @@ void app::draw_collision_boxes() shader.set_tint({0, .5f, 1, 1}); + using rtree_type = std::decay_t<decltype(*world[chunk_coords{}].rtree())>; + using rect_type = typename rtree_type::Rect; + for (std::int16_t y = miny; y <= maxy; y++) for (std::int16_t x = minx; x <= maxx; x++) { @@ -80,9 +83,7 @@ void app::draw_collision_boxes() if (floormat_main::check_chunk_visible(shader.camera_offset(), sz)) { constexpr float maxf = 1 << 24, max2f[] = { maxf, maxf }, min2f[] = { -maxf, -maxf }; - auto* rtree = c.rtree(); - using rtree_type = std::decay_t<decltype(*rtree)>; - using rect_type = typename rtree_type::Rect; + const auto* rtree = c.rtree(); rtree->Search(min2f, max2f, [&](std::uint64_t data, const rect_type& rect) { [[maybe_unused]] auto x = std::bit_cast<collision_data>(data); Vector2 start(rect.m_min[0], rect.m_min[1]), end(rect.m_max[0], rect.m_max[1]); @@ -94,6 +95,44 @@ void app::draw_collision_boxes() } } + shader.set_tint({1, 0, 1, 1}); + + if (cursor.tile) + { + const auto tile_ = M->pixel_to_tile_(Vector2d(*cursor.pixel)); + const auto subpixel = Vector2(Vector2ub(Vector2d(std::fmod(tile_[0], 1.), std::fmod(tile_[1], 1.)) * dTILE_SIZE2)); + const auto tile = *cursor.tile; + const auto curchunk = tile.chunk(); + const auto curtile = tile.local(); + + for (std::int16_t y = miny; y <= maxy; y++) + for (std::int16_t x = minx; x <= maxx; x++) + { + const chunk_coords pos{x, y}; + auto& c = world[pos]; + if (c.empty()) + continue; + c.ensure_passability(); + const with_shifted_camera_offset o{shader, pos, {minx, miny}, {maxx, maxy}}; + if (floormat_main::check_chunk_visible(shader.camera_offset(), sz)) + { + constexpr auto chunk_size = TILE_SIZE2 * TILE_MAX_DIM, half_tile = TILE_SIZE2/2; + auto chunk_dist = (Vector2(pos.x, pos.y) - Vector2(curchunk.x, curchunk.y))*chunk_size; + auto t0 = chunk_dist + Vector2(curtile.x, curtile.y)*TILE_SIZE2 + subpixel - half_tile; + auto t1 = t0+Vector2(1e-4f); + const auto* rtree = c.rtree(); + rtree->Search(t0.data(), t1.data(), [&](std::uint64_t data, const rect_type& rect) { + [[maybe_unused]] auto x = std::bit_cast<collision_data>(data); + Vector2 start(rect.m_min[0], rect.m_min[1]), end(rect.m_max[0], rect.m_max[1]); + auto size = end - start; + auto center = Vector3(start + size*.5f, 0.f); + _wireframe_rect.draw(shader, { center, size, 3 }); + return true; + }); + } + } + } + shader.set_tint({1, 1, 1, 1}); } diff --git a/floormat/main.hpp b/floormat/main.hpp index 8b5648a2..db2eb5c0 100644 --- a/floormat/main.hpp +++ b/floormat/main.hpp @@ -59,6 +59,7 @@ struct floormat_main virtual std::uint32_t cursor() const noexcept = 0; virtual global_coords pixel_to_tile(Vector2d position) const noexcept = 0; + virtual Vector2d pixel_to_tile_(Vector2d position) const noexcept = 0; virtual draw_bounds get_draw_bounds() const noexcept = 0; [[nodiscard]] static bool check_chunk_visible(const Vector2d& offset, const Vector2i& size) noexcept; virtual struct meshes meshes() noexcept = 0; diff --git a/main/draw.cpp b/main/draw.cpp index 1a9dae26..2a3b3f7b 100644 --- a/main/draw.cpp +++ b/main/draw.cpp @@ -39,12 +39,17 @@ void main_impl::recalc_viewport(Vector2i fb_size, Vector2i win_size) noexcept global_coords main_impl::pixel_to_tile(Vector2d position) const noexcept { + auto vec = pixel_to_tile_(position); + const auto x = (std::int32_t)std::floor(vec[0]), y = (std::int32_t)std::floor(vec[1]); + return { x, y }; +} + +Vector2d main_impl::pixel_to_tile_(Vector2d position) const noexcept +{ constexpr Vector2d pixel_size(TILE_SIZE2); constexpr Vector2d half{.5, .5}; const Vector2d px = position - Vector2d{framebufferSize()}*.5 - _shader.camera_offset(); - const Vector2d vec = tile_shader::unproject(px*.5) / pixel_size + half; - const auto x = (std::int32_t)std::floor(vec[0]), y = (std::int32_t)std::floor(vec[1]); - return { x, y }; + return tile_shader::unproject(px*.5) / pixel_size + half; } auto main_impl::get_draw_bounds() const noexcept -> draw_bounds diff --git a/main/main-impl.hpp b/main/main-impl.hpp index 43add3bf..c078cb87 100644 --- a/main/main-impl.hpp +++ b/main/main-impl.hpp @@ -40,6 +40,7 @@ struct main_impl final : Platform::Sdl2Application, floormat_main const fm_settings& settings() const noexcept override; global_coords pixel_to_tile(Vector2d position) const noexcept override; + Vector2d pixel_to_tile_(Vector2d position) const noexcept override; ArrayView<const clickable<anim_atlas, scenery>> clickable_scenery() const noexcept override; ArrayView<clickable<anim_atlas, scenery>> clickable_scenery() noexcept override; diff --git a/src/RTree.h b/src/RTree.h index f4139450..04d84863 100644 --- a/src/RTree.h +++ b/src/RTree.h @@ -278,6 +278,7 @@ public: void ListTree(std::vector<Rect>& vec, std::vector<Node*>& temp) const; }; +#include <cinttypes> extern template class RTree<std::uint64_t, float, 2, float>; //#undef RTREE_TEMPLATE diff --git a/src/chunk-collision.cpp b/src/chunk-collision.cpp index f37fd24b..80436ad2 100644 --- a/src/chunk-collision.cpp +++ b/src/chunk-collision.cpp @@ -6,8 +6,8 @@ namespace floormat { -const RTree<std::uint64_t, float, 2, float>* chunk::rtree() const noexcept { return &_rtree; } -RTree<std::uint64_t, float, 2, float>* chunk::rtree() noexcept { return &_rtree; } +const chunk::RTree* chunk::rtree() const noexcept { return &_rtree; } +chunk::RTree* chunk::rtree() noexcept { return &_rtree; } namespace { diff --git a/src/chunk.hpp b/src/chunk.hpp index 0cd7dfc7..6ba8ef5e 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -86,8 +86,10 @@ struct chunk final void ensure_passability() noexcept; - const RTree<std::uint64_t, float, 2, float>* rtree() const noexcept; - RTree<std::uint64_t, float, 2, float>* rtree() noexcept; + using RTree = ::RTree<std::uint64_t, float, 2, float>; + + const RTree* rtree() const noexcept; + RTree* rtree() noexcept; private: std::array<std::shared_ptr<tile_atlas>, TILE_COUNT> _ground_atlases; @@ -102,7 +104,7 @@ private: GL::Mesh ground_mesh{NoCreate}, wall_mesh{NoCreate}, scenery_mesh{NoCreate}; - RTree<std::uint64_t, float, 2, float> _rtree; + RTree _rtree; mutable bool _maybe_empty : 1 = true, _ground_modified : 1 = true, |