diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2023-09-26 07:52:51 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2023-09-26 07:52:51 +0200 |
commit | 4c668acd91bdb9b7bb216d3ee45e4d2a1e2f50f5 (patch) | |
tree | c80f303ffaaf5f345ea0584270d89d9a675ff2e5 /src | |
parent | 25a494edf3790f7c6b923948e748b8a5b035277f (diff) |
a
Diffstat (limited to 'src')
-rw-r--r-- | src/path-search.cpp | 63 | ||||
-rw-r--r-- | src/path-search.hpp | 6 |
2 files changed, 40 insertions, 29 deletions
diff --git a/src/path-search.cpp b/src/path-search.cpp index da3195cb..0ec4a91d 100644 --- a/src/path-search.cpp +++ b/src/path-search.cpp @@ -237,6 +237,41 @@ auto path_search::bbox_union(bbox bb, Vector2i coord, Vector2b offset, Vector2ub }; } +void path_search::fill_cache_(world& w, chunk_coords_ coord, Vector2ub own_size, object_id own_id) +{ + int32_t x = coord.x, y = coord.y; + int8_t z = coord.z; + + auto off = Vector2i(x - cache.start.x(), y - cache.start.y()); + fm_debug_assert(off.x() >= 0 && off.y() >= 0); + fm_debug_assert(off.x() < cache.size.x() && off.y() < cache.size.y()); + auto ch = chunk_coords_{(int16_t)x, (int16_t)y, z}; + auto* c = w.at(ch); + auto nb = w.neighbors(ch); + + if (!c && std::all_of(nb.begin(), nb.end(), [](const auto& c) { return c.c == nullptr; })) + return; + + auto& bits = cache.array[off.y()*cache.size.x()+off.x()]; + for (auto i = 0uz; i < TILE_COUNT; i++) + { + auto pos = Vector2i(local_coords{i}); + auto bb_N = make_neighbor_tile_bbox(pos, own_size, rotation::N), + bb_W = make_neighbor_tile_bbox(pos, own_size, rotation::W); + bool b_N = is_passable_(c, nb, bb_N.min, bb_N.max, own_id), + b_W = is_passable_(c, nb, bb_W.min, bb_W.max, own_id); + bits.can_go_north[i] = b_N; + bits.can_go_west[i] = b_W; + } +} + +void path_search::fill_cache(world& w, Vector2i cmin, Vector2i cmax, int8_t z, Vector2ub own_size, object_id own_id) +{ + for (int32_t y = cmin.y(); y <= cmax.y(); y++) + for (int32_t x = cmin.x(); x <= cmax.x(); x++) + fill_cache_(w, {(int16_t)x, (int16_t)y, z}, own_size, own_id); +} + Optional<path_search_result> path_search::operator()(world& w, Vector2ub own_size, object_id own_id, global_coords from, Vector2b from_offset, global_coords to, Vector2b to_offset) @@ -258,33 +293,7 @@ Optional<path_search_result> path_search::operator()(world& w, Vector2ub own_siz ensure_allocated(from.chunk(), to.chunk()); auto [cmin, cmax] = Math::minmax(Vector2i(from.chunk()) - Vector2i(1, 1), Vector2i(to.chunk()) + Vector2i(1, 1)); - - for (int32_t y = cmin.y(); y <= cmax.y(); y++) - { - for (int32_t x = cmin.x(); x <= cmax.x(); x++) - { - auto off = Vector2i(x - cmin.x(), y - cmin.y()); - fm_debug_assert(off.x() >= 0 && off.y() >= 0); - fm_debug_assert(off.x() < cache.size.x() && off.y() < cache.size.y()); - auto ch = chunk_coords_{(int16_t)x, (int16_t)y, from.z()}; - if (auto* c = w.at(ch)) - { - auto& bits = cache.array[off.y()*cache.size.x()+off.x()]; - auto nb = w.neighbors(ch); - for (auto i = 0uz; i < TILE_COUNT; i++) - { - auto pos = Vector2i(local_coords{i}); - auto bb_N = make_neighbor_tile_bbox(pos, own_size, rotation::N), - bb_W = make_neighbor_tile_bbox(pos, own_size, rotation::W); - bool b_N = is_passable_(c, nb, bb_N.min, bb_N.max, own_id), - b_W = is_passable_(c, nb, bb_W.min, bb_W.max, own_id); - - bits.can_go_north[i] = b_N; - bits.can_go_west[i] = b_W; - } - } - } - } + fill_cache(w, cmin, cmax, from.z(), own_size, own_id); // todo... return {}; diff --git a/src/path-search.hpp b/src/path-search.hpp index 2541a7ea..f3601a26 100644 --- a/src/path-search.hpp +++ b/src/path-search.hpp @@ -77,11 +77,13 @@ class path_search final // todo bucketize by array length path_search_result* pool = nullptr; - void ensure_allocated(chunk_coords a, chunk_coords b); - public: struct bbox { Vector2 min, max; }; + void ensure_allocated(chunk_coords a, chunk_coords b); + void fill_cache(world& w, Vector2i cmin, Vector2i cmax, int8_t z, Vector2ub own_size, object_id own_id); + void fill_cache_(world& w, chunk_coords_ coord, Vector2ub own_size, object_id own_id); + // todo remember to check from.z() == to.z() // todo add simple bresenham short-circuit Optional<path_search_result> operator()(world& w, Vector2ub own_size, object_id own_id, global_coords from, Vector2b from_offset, global_coords to, Vector2b to_offset); |