diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/chunk-bbox.cpp | 171 | ||||
-rw-r--r-- | src/chunk.cpp | 7 | ||||
-rw-r--r-- | src/chunk.hpp | 27 | ||||
-rw-r--r-- | src/collision.cpp | 6 | ||||
-rw-r--r-- | src/collision.hpp | 73 |
5 files changed, 1 insertions, 283 deletions
diff --git a/src/chunk-bbox.cpp b/src/chunk-bbox.cpp deleted file mode 100644 index 52be8635..00000000 --- a/src/chunk-bbox.cpp +++ /dev/null @@ -1,171 +0,0 @@ -#include "chunk.hpp" -#include "compat/LooseQuadtree-impl.h" -#include "src/tile-atlas.hpp" -#include "src/collision.hpp" -#include <bit> -#include <Magnum/Math/Vector4.h> - -namespace floormat { - -struct collision_bbox final -{ - using BB = loose_quadtree::BoundingBox<std::int16_t>; - operator BB() const noexcept; - - std::int16_t left = 0, top = 0; - std::uint16_t width = 0, height = 0; - enum pass_mode pass_mode = pass_mode::pass; -}; - -collision_bbox::operator BB() const noexcept -{ - return { left, top, (std::int16_t)width, (std::int16_t)height }; -} - -static constexpr Vector2s tile_start(std::size_t k) -{ - const auto i = std::uint8_t(k); - const local_coords coord{i}; - return sTILE_SIZE2 * Vector2s(coord.x, coord.y) - sTILE_SIZE2/2; -} - -void chunk::ensure_passability() noexcept -{ - if (!_pass_modified) - return; - _pass_modified = false; - - if (!_lqt_move) - _lqt_move = make_lqt(); - if (!_lqt_shoot) - _lqt_shoot = make_lqt(); - if (!_lqt_view) - _lqt_view = make_lqt(); - - _lqt_move->Clear(); - _lqt_shoot->Clear(); - _lqt_view->Clear(); - - std::vector<collision_bbox> bboxes; - _bboxes.clear(); - bboxes.reserve(TILE_COUNT*4); - - constexpr auto scenery_tile = [](std::size_t k, pass_mode p, const scenery& sc) constexpr -> collision_bbox { - constexpr auto half = sTILE_SIZE2/2; - auto center = tile_start(k) + Vector2s(sc.bbox_offset) + half; - auto size = Vector2us(sc.bbox_size)*2; - auto start = center - Vector2s(sc.bbox_size); - return { start[0], start[1], size[0], size[1], p }; - }; - - constexpr auto whole_tile = [](std::size_t k, pass_mode p) constexpr -> collision_bbox { - auto start = tile_start(k); - return { start[0], start[1], usTILE_SIZE2[0], usTILE_SIZE2[1], p }; - }; - - constexpr auto wall_north = [](std::size_t k, pass_mode p) constexpr -> collision_bbox { - auto start = tile_start(k) - Vector2s(0, 1); - return { start[0], start[1], usTILE_SIZE2[0], 2, p }; - }; - - constexpr auto wall_west = [](std::size_t k, pass_mode p) constexpr -> collision_bbox { - auto start = tile_start(k) - Vector2s(1, 0); - return { start[0], start[1], 2, usTILE_SIZE2[1], p }; - }; - - for (std::size_t i = 0; i < TILE_COUNT; i++) - { - const auto tile = const_cast<chunk&>(*this)[i]; - if (auto s = tile.scenery(); s && s.frame.passability != pass_mode::pass) - if (auto bb = scenery_tile(i, s.frame.passability, s.frame); bb.width && bb.height) - bboxes.push_back(bb); - if (auto atlas = tile.ground_atlas()) - if (auto p = atlas->pass_mode(pass_mode::pass); p != pass_mode::pass) - bboxes.push_back(whole_tile(i, p)); - if (auto atlas = tile.wall_north_atlas()) - if (auto p = atlas->pass_mode(pass_mode::blocked); p != pass_mode::pass) - bboxes.push_back(wall_north(i, p)); - if (auto atlas = tile.wall_west_atlas()) - if (auto p = atlas->pass_mode(pass_mode::blocked); p != pass_mode::pass) - bboxes.push_back(wall_west(i, p)); - } - - _bboxes.reserve(bboxes.size()); - - for (const collision_bbox& bbox : bboxes) - { - _bboxes.push_back(bbox); - auto* ptr = &_bboxes.back(); - - switch (bbox.pass_mode) - { - case pass_mode::blocked: - _lqt_view->Insert(ptr); - [[fallthrough]]; - case pass_mode::see_through: - _lqt_shoot->Insert(ptr); - [[fallthrough]]; - case pass_mode::shoot_through: - _lqt_move->Insert(ptr); - break; - case pass_mode::pass: - break; - } - } -} - -auto chunk::query_collisions(Vector4s vec, collision type) const -> Query -{ - const_cast<chunk&>(*this).ensure_passability(); - loose_quadtree::BoundingBox<float> bbox ( vec[0], vec[1], vec[2], vec[3] ); - return { lqt_from_collision_type(type)->QueryIntersectsRegion(bbox) }; -} - -auto chunk::query_collisions(Vector2s position, Vector2us size, collision type) const -> Query -{ - const_cast<chunk&>(*this).ensure_passability(); - constexpr auto half = sTILE_SIZE2/2; - const auto start = position - half; - loose_quadtree::BoundingBox<float> bbox ( start[0], start[1], (Short)size[0], (Short)size[1] ); - return { lqt_from_collision_type(type)->QueryIntersectsRegion(bbox) }; -} - -auto chunk::query_collisions(local_coords p, Vector2us size, Vector2s offset, collision type) const -> Query -{ - const_cast<chunk&>(*this).ensure_passability(); - const auto pos = Vector2s(p.x, p.y) * sTILE_SIZE2 + offset; - const auto start = pos - Vector2s(size/2); - loose_quadtree::BoundingBox<float> bbox ( start[0], start[1], (Short)size[0], (Short)size[1] ); - return { lqt_from_collision_type(type)->QueryIntersectsRegion(bbox) }; -} - -auto chunk::lqt_from_collision_type(collision type) const noexcept -> lqt* -{ - switch (type) - { - case collision::move: - return _lqt_move.get(); - case collision::shoot: - return _lqt_shoot.get(); - case collision::view: - return _lqt_view.get(); - } - fm_abort("wrong collision type '%hhu'", std::uint8_t(type)); -} - -auto chunk::make_lqt() -> std::unique_ptr<lqt> -{ - return std::make_unique<lqt>(); -} - -void chunk::cleanup_lqt() -{ - if (_lqt_move) - _lqt_move->ForceCleanup(); - if (_lqt_shoot) - _lqt_shoot->ForceCleanup(); - if (_lqt_view) - _lqt_view->ForceCleanup(); -} - -} // namespace floormat diff --git a/src/chunk.cpp b/src/chunk.cpp index 94506f1a..033e1831 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -1,6 +1,5 @@ #include "chunk.hpp" #include "src/tile-atlas.hpp" -#include "compat/LooseQuadtree-impl.h" namespace floormat { @@ -42,11 +41,7 @@ void chunk::mark_modified() noexcept } chunk::chunk() noexcept = default; - -chunk::~chunk() noexcept -{ - cleanup_lqt(); -} +chunk::~chunk() noexcept = default; chunk::chunk(chunk&&) noexcept = default; chunk& chunk::operator=(chunk&&) noexcept = default; diff --git a/src/chunk.hpp b/src/chunk.hpp index 2f257c38..9dd0f117 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -8,21 +8,10 @@ #include <memory> #include <Magnum/GL/Mesh.h> -namespace loose_quadtree { -template<typename Number, typename Object, typename BBExtractor> class LooseQuadtree; -template<typename Number, typename Object, typename BBExtractor> struct Query; -template<typename Number> struct BoundingBox; -template<typename Number> struct TrivialBBExtractor; -} // namespace loose_quadtree - namespace floormat { struct anim_atlas; -template<typename Num, typename BB, typename BBE> struct collision_iterator; -template<typename Num, typename BB, typename BBE> struct collision_query; -struct collision_bbox; - enum class collision : std::uint8_t { view, shoot, move, }; @@ -88,17 +77,6 @@ struct chunk final void ensure_passability() noexcept; - using BB = loose_quadtree::BoundingBox<std::int16_t>; - using BBE = loose_quadtree::TrivialBBExtractor<std::int16_t>; - using lqt = loose_quadtree::LooseQuadtree<float, BB, BBE>; - using Query = collision_query<float, BB, BBE>; - - Query query_collisions(Vector2s position, Vector2us size, collision type) const; - Query query_collisions(local_coords p, Vector2us size, Vector2s offset, collision type) const; - Query query_collisions(Vector4s vec, collision type) const; - - lqt* lqt_from_collision_type(collision type) const noexcept; - private: std::array<std::shared_ptr<tile_atlas>, TILE_COUNT> _ground_atlases; std::array<std::uint8_t, TILE_COUNT> ground_indexes = {}; @@ -110,17 +88,12 @@ private: std::array<std::uint8_t, TILE_COUNT> scenery_indexes = {}; std::array<scenery, TILE_COUNT> _scenery_variants = {}; - std::unique_ptr<lqt> _lqt_move, _lqt_shoot, _lqt_view; - std::vector<loose_quadtree::BoundingBox<std::int16_t>> _bboxes; - GL::Mesh ground_mesh{NoCreate}, wall_mesh{NoCreate}, scenery_mesh{NoCreate}; mutable bool _maybe_empty : 1 = true, _ground_modified : 1 = true, _walls_modified : 1 = true, _scenery_modified : 1 = true, _pass_modified : 1 = true; - static std::unique_ptr<lqt> make_lqt(); - void cleanup_lqt(); }; } // namespace floormat diff --git a/src/collision.cpp b/src/collision.cpp deleted file mode 100644 index e2e4974d..00000000 --- a/src/collision.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "collision.hpp" -#include <bit> - -namespace floormat { - -} // namespace floormat diff --git a/src/collision.hpp b/src/collision.hpp deleted file mode 100644 index 0568cc39..00000000 --- a/src/collision.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once -#include "compat/LooseQuadtree-impl.h" -#include "src/pass-mode.hpp" - -namespace floormat { - -template<typename Num, typename BB, typename BBE> -struct collision_iterator final -{ - using Query = typename loose_quadtree::LooseQuadtree<Num, BB, BBE>::Query; - - explicit collision_iterator() noexcept : q{nullptr} {} - explicit collision_iterator(Query* q) noexcept : q{q} {} - ~collision_iterator() noexcept - { - if (q) - while (!q->EndOfQuery()) - q->Next(); - } - collision_iterator& operator++() noexcept - { - fm_debug_assert(q != nullptr && !q->EndOfQuery()); - q->Next(); - return *this; - } - const BB* operator++(int) noexcept - { - fm_debug_assert(q != nullptr && !q->EndOfQuery()); - auto* bbox = q->GetCurrent(); - fm_debug_assert(bbox != nullptr); - operator++(); - return bbox; - } - const BB& operator*() const noexcept { return *operator->(); } - const BB* operator->() const noexcept - { - fm_debug_assert(q != nullptr && !q->EndOfQuery()); - auto* ptr = q->GetCurrent(); - fm_debug_assert(ptr != nullptr); - return ptr; - } - bool operator==(const collision_iterator& other) const noexcept - { - if (q && !other.q) [[likely]] - return q->EndOfQuery(); - else if (!q && !other.q) - return true; - else if (!q) - return other.q->EndOfQuery(); - else - return q == other.q; - } - operator bool() const noexcept { return q && !q->EndOfQuery(); } - -private: - Query* q; -}; - -template<typename Num, typename BB, typename BBE> -struct collision_query -{ - using Query = typename loose_quadtree::LooseQuadtree<Num, BB, BBE>::Query; - collision_query(Query&& q) noexcept : q{std::move(q)} {} - ~collision_query() noexcept { while (!q.EndOfQuery()) q.Next(); } - collision_iterator<Num, BB, BBE> begin() noexcept { return collision_iterator<Num, BB, BBE>{&q}; } - static collision_iterator<Num, BB, BBE> end() noexcept { return collision_iterator<Num, BB, BBE>{nullptr}; } - operator bool() const noexcept { return !q.EndOfQuery(); } - -private: - Query q; -}; - -} // namespace floormat |