diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/astar.hpp | 4 | ||||
-rw-r--r-- | src/chunk-region.cpp | 37 | ||||
-rw-r--r-- | src/chunk.hpp | 6 | ||||
-rw-r--r-- | src/path-search-pred.hpp | 18 | ||||
-rw-r--r-- | src/path-search.cpp | 24 | ||||
-rw-r--r-- | src/path-search.hpp | 22 |
6 files changed, 76 insertions, 35 deletions
diff --git a/src/astar.hpp b/src/astar.hpp index bc2ecd6f..0a46ec6d 100644 --- a/src/astar.hpp +++ b/src/astar.hpp @@ -46,7 +46,7 @@ public: point pt; }; - using pred = path_search::pred; + using pred = detail_astar::pred; fm_DECLARE_DELETED_COPY_ASSIGNMENT(astar); @@ -57,7 +57,7 @@ public: // todo add simple bresenham short-circuit path_search_result Dijkstra(world& w, point from, point to, object_id own_id, uint32_t max_dist, Vector2ub own_size, - int debug = 0, const pred& p = path_search::never_continue()); + int debug = 0, const pred& p = detail_astar::never_continue()); private: static constexpr auto initial_capacity = TILE_COUNT * 16 * detail_astar::div_factor*detail_astar::div_factor; diff --git a/src/chunk-region.cpp b/src/chunk-region.cpp index 253c1d4f..67c474bc 100644 --- a/src/chunk-region.cpp +++ b/src/chunk-region.cpp @@ -1,6 +1,10 @@ #include "chunk-region.hpp" #include "path-search-bbox.hpp" #include "world.hpp" +#include "collision.hpp" +#include "object.hpp" +#include "compat/function2.hpp" +#include <bit> #include <array> #include <Corrade/Containers/GrowableArray.h> #include <Magnum/Math/Functions.h> @@ -13,6 +17,7 @@ using detail_astar::bbox; using detail_astar::div_factor; using detail_astar::div_size; using detail_astar::div_count; +using detail_astar::pred; static_assert(div_count.x() == div_count.y()); static_assert((iTILE_SIZE2 % div_size).isZero()); @@ -44,11 +49,11 @@ constexpr bbox<Int> make_pos(Vector2i ij, Vector2i from) return bbox_from_pos2(pos, pos0); } -bool check_pos(chunk& c, const std::array<chunk*, 8>& nbs, Vector2i ij, Vector2i from) +bool check_pos(chunk& c, const std::array<chunk*, 8>& nbs, Vector2i ij, Vector2i from, const pred& p) { auto pos = make_pos(ij, from); - bool ret = path_search::is_passable_(&c, nbs, Vector2(pos.min), Vector2(pos.max), 0); - //if (ret) Debug{} << "check" << ij << ij/div_factor << ij % div_factor << pos.min << pos.max << ret; + bool ret = path_search::is_passable_(&c, nbs, Vector2(pos.min), Vector2(pos.max), 0, p); + //if (ret) Debug{} << "check" << ij << pos.min << pos.max << ret; //Debug{} << "check" << ij << pos.min << pos.max << ret; return ret; } @@ -117,6 +122,22 @@ void chunk::delete_pass_region(pass_region*& ptr) } } +pred chunk::default_region_predicate() noexcept +{ + return [this](collision_data data) { + auto x = std::bit_cast<collision_data>(data); + // XXX 'scenery' is used for all object types + if (x.tag == (uint64_t)collision_type::scenery) + { + auto& w = _world; + auto obj = w->find_object(x.data); + if (obj->type() == object_type::critter) + return path_search_continue::pass; + } + return path_search_continue::blocked; + }; +} + auto chunk::get_pass_region() -> const pass_region* { if (!_region_modified) @@ -140,6 +161,12 @@ void chunk::mark_region_modified() noexcept { _region_modified = true; } void chunk::make_pass_region(pass_region& ret) { + return make_pass_region(ret, default_region_predicate()); +} + +void chunk::make_pass_region(pass_region& ret, const pred& f) +{ + ret = {}; auto& tmp = get_tmp(); const auto nbs = _world->neighbors(_coord); @@ -161,7 +188,7 @@ void chunk::make_pass_region(pass_region& ret) { auto positions = get_positions(i); for (auto i = 0u; i < 4; i++) - if (check_pos(*this, nbs, positions[i], fours[i])) + if (check_pos(*this, nbs, positions[i], fours[i], f)) tmp.append(ret.bits, positions[i]); } @@ -174,7 +201,7 @@ void chunk::make_pass_region(pass_region& ret) Vector2i from = fours[i], pos{p - from}; if ((uint32_t)pos.x() >= div_count.x() || (uint32_t)pos.y() >= div_count.y()) [[unlikely]] continue; - if (tmp.check_visited(ret.bits, pos, i) && check_pos(*this, nbs, pos, from)) + if (tmp.check_visited(ret.bits, pos, i) && check_pos(*this, nbs, pos, from, f)) tmp.append(ret.bits, pos); } } diff --git a/src/chunk.hpp b/src/chunk.hpp index 5404d25b..0efe9847 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -5,7 +5,7 @@ #include "src/RTree-fwd.h" #include "global-coords.hpp" #include "wall-defs.hpp" -#include "collision.hpp" +#include "path-search-pred.hpp" #include <type_traits> #include <array> #include <Corrade/Containers/Array.h> @@ -119,8 +119,10 @@ public: static constexpr size_t max_wall_quad_count = TILE_COUNT*Wall::Direction_COUNT*(Wall::Group_COUNT+4); + detail_astar::pred default_region_predicate() noexcept; const pass_region* get_pass_region(); void make_pass_region(pass_region& ret); + void make_pass_region(pass_region& ret, const detail_astar::pred& f); private: struct ground_stuff @@ -162,7 +164,7 @@ private: struct bbox final // NOLINT(cppcoreguidelines-pro-type-member-init) { - object_id id; + object_id id; // todo change to collision_data Vector2i start, end; bool operator==(const bbox& other) const noexcept; diff --git a/src/path-search-pred.hpp b/src/path-search-pred.hpp new file mode 100644 index 00000000..f0f99c3e --- /dev/null +++ b/src/path-search-pred.hpp @@ -0,0 +1,18 @@ +#pragma once +#include "compat/function2.fwd.hpp" +#include "collision.hpp" + +namespace floormat { + +enum class path_search_continue : bool { pass = false, blocked = true }; + +} // namespace floormat + +namespace floormat::detail_astar { + +using pred = fu2::function_view<path_search_continue(collision_data) const>; + +const pred& never_continue() noexcept; +const pred& always_continue() noexcept; + +} // namespace floormat::detail_astar diff --git a/src/path-search.cpp b/src/path-search.cpp index 769bc4b9..a41c2820 100644 --- a/src/path-search.cpp +++ b/src/path-search.cpp @@ -8,24 +8,24 @@ #include "compat/function2.hpp" #include <bit> -namespace floormat { - -using namespace detail_astar; +namespace floormat::detail_astar { namespace { - -constexpr int div_BITS = 2; -static_assert(1 << div_BITS == div_factor); - constexpr auto never_continue_1 = [](collision_data) constexpr { return path_search_continue::blocked; }; -constexpr auto never_continue_ = path_search::pred{never_continue_1}; +constexpr auto never_continue_ = pred{never_continue_1}; constexpr auto always_continue_1 = [](collision_data) constexpr { return path_search_continue::pass; }; -constexpr auto always_continue_ = path_search::pred{always_continue_1}; - +constexpr auto always_continue_ = pred{always_continue_1}; } // namespace -auto path_search::never_continue() noexcept -> const pred& { return never_continue_; } -auto path_search::always_continue() noexcept -> const pred& { return always_continue_; } +const pred& never_continue() noexcept { return never_continue_; } +const pred& always_continue() noexcept { return always_continue_; } +//static_assert(1 << 2 == div_factor); + +} // namespace floormat::detail_astar + +namespace floormat { + +using namespace detail_astar; bool path_search::is_passable_1(chunk& c, Vector2 min, Vector2 max, object_id own_id, const pred& p) { diff --git a/src/path-search.hpp b/src/path-search.hpp index daf3379d..05516676 100644 --- a/src/path-search.hpp +++ b/src/path-search.hpp @@ -2,9 +2,8 @@ #include "tile-constants.hpp" #include "global-coords.hpp" #include "object-id.hpp" -#include "collision.hpp" -#include "compat/function2.fwd.hpp" #include "path-search-result.hpp" +#include "path-search-pred.hpp" #include <array> namespace floormat { @@ -30,26 +29,21 @@ constexpr inline auto div_count = iTILE_SIZE2 * TILE_MAX_DIM / detail_astar::div namespace floormat { struct path_search_result; -enum class path_search_continue : bool { pass = false, blocked = true }; class path_search final { friend struct path_search_result; template<typename T> using bbox = detail_astar::bbox<T>; + using pred = detail_astar::pred; public: - using pred = fu2::function_view<path_search_continue(collision_data) const>; - - static const pred& never_continue() noexcept; - static const pred& always_continue() noexcept; - - static bool is_passable_1(chunk& c, Vector2 min, Vector2 max, object_id own_id, const pred& p = never_continue()); + static bool is_passable_1(chunk& c, Vector2 min, Vector2 max, object_id own_id, const pred& p = detail_astar::never_continue()); static bool is_passable_(chunk* c0, const std::array<chunk*, 8>& neighbors, - Vector2 min, Vector2 max, object_id own_id, const pred& p = never_continue()); - static bool is_passable(world& w, global_coords coord, Vector2b offset, Vector2ui size, object_id own_id, const pred& p = never_continue()); - static bool is_passable(world& w, struct detail_astar::cache& cache, global_coords coord, Vector2b offset, Vector2ui size, object_id own_id, const pred& p = never_continue()); - static bool is_passable(world& w, chunk_coords_ ch0, const bbox<float>& bb, object_id own_id, const pred& p = never_continue()); - static bool is_passable(world& w, struct detail_astar::cache& cache, chunk_coords_ ch0, const bbox<float>& bb, object_id own_id, const pred& p = never_continue()); + Vector2 min, Vector2 max, object_id own_id, const pred& p = detail_astar::never_continue()); + static bool is_passable(world& w, global_coords coord, Vector2b offset, Vector2ui size, object_id own_id, const pred& p = detail_astar::never_continue()); + static bool is_passable(world& w, struct detail_astar::cache& cache, global_coords coord, Vector2b offset, Vector2ui size, object_id own_id, const pred& p = detail_astar::never_continue()); + static bool is_passable(world& w, chunk_coords_ ch0, const bbox<float>& bb, object_id own_id, const pred& p = detail_astar::never_continue()); + static bool is_passable(world& w, struct detail_astar::cache& cache, chunk_coords_ ch0, const bbox<float>& bb, object_id own_id, const pred& p = detail_astar::never_continue()); }; } // namespace floormat |