summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-02-04 13:38:46 +0100
committerStanislaw Halik <sthalik@misaki.pl>2024-02-04 13:38:46 +0100
commit5b7b84462e81b5c4bbc835a12c08a4e8a11152b1 (patch)
tree52755133877ce34d3526dc0e4a469a42d876dc9b
parentf5038f16a15cdd4579417ef499bb8ddcb9fc6269 (diff)
a
-rw-r--r--src/dijkstra.cpp48
-rw-r--r--src/path-search.cpp30
-rw-r--r--src/path-search.hpp3
3 files changed, 55 insertions, 26 deletions
diff --git a/src/dijkstra.cpp b/src/dijkstra.cpp
index 64830c7d..765033e0 100644
--- a/src/dijkstra.cpp
+++ b/src/dijkstra.cpp
@@ -14,7 +14,9 @@ namespace floormat {
template<typename T> using bbox = path_search::bbox<T>;
using visited = astar::visited;
-using namespace floormat::detail_astar;
+using detail_astar::div_size;
+using detail_astar::div_factor;
+using detail_astar::min_size;
namespace {
@@ -177,10 +179,10 @@ path_search_result astar::Dijkstra(world& w, const point from, const point to,
if (from.coord().z() != 0) [[unlikely]]
return {};
- if (!path_search::is_passable(w, from.coord(), from.offset(), own_size, own_id, p))
+ if (!path_search::is_passable(w, cache, from.coord(), from.offset(), own_size, own_id, p))
return {};
- if (!path_search::is_passable(w, to.coord(), to.offset(), own_size, own_id, p))
+ if (!path_search::is_passable(w, cache, to.coord(), to.offset(), own_size, own_id, p))
return {};
constexpr int8_t div_min = -div_factor*2, div_max = div_factor*2;
@@ -353,7 +355,11 @@ path_search_result astar::Dijkstra(world& w, const point from, const point to,
return result;
}
-struct detail_astar::chunk_cache
+} // namespace floormat
+
+namespace floormat::detail_astar {
+
+struct chunk_cache
{
static constexpr size_t dimensions[] = {
TILE_COUNT,
@@ -373,9 +379,9 @@ struct detail_astar::chunk_cache
std::bitset<size> exists{false};
};
-detail_astar::cache::cache() = default;
+cache::cache() = default;
-Vector2ui detail_astar::cache::get_size_to_allocate(uint32_t max_dist)
+Vector2ui cache::get_size_to_allocate(uint32_t max_dist)
{
constexpr auto chunk_size = Vector2ui(iTILE_SIZE2) * TILE_MAX_DIM;
constexpr auto rounding = chunk_size - Vector2ui(1);
@@ -383,7 +389,7 @@ Vector2ui detail_astar::cache::get_size_to_allocate(uint32_t max_dist)
return nchunks + Vector2ui(3);
}
-void detail_astar::cache::allocate(point from, uint32_t max_dist)
+void cache::allocate(point from, uint32_t max_dist)
{
auto off = get_size_to_allocate(max_dist);
start = Vector2i(from.chunk()) - Vector2i(off);
@@ -396,7 +402,7 @@ void detail_astar::cache::allocate(point from, uint32_t max_dist)
array[i].exists = {};
}
-size_t detail_astar::cache::get_chunk_index(Vector2i start, Vector2ui size, Vector2i coord)
+size_t cache::get_chunk_index(Vector2i start, Vector2ui size, Vector2i coord)
{
auto off = Vector2ui(coord - start);
fm_assert(off < size);
@@ -405,9 +411,9 @@ size_t detail_astar::cache::get_chunk_index(Vector2i start, Vector2ui size, Vect
return index;
}
-size_t detail_astar::cache::get_chunk_index(Vector2i chunk) const { return get_chunk_index(start, size, chunk); }
+size_t cache::get_chunk_index(Vector2i chunk) const { return get_chunk_index(start, size, chunk); }
-size_t detail_astar::cache::get_tile_index(Vector2i pos, Vector2b offset_)
+size_t cache::get_tile_index(Vector2i pos, Vector2b offset_)
{
Vector2i offset{offset_};
constexpr auto tile_start = div_size * div_factor/-2;
@@ -430,7 +436,7 @@ size_t detail_astar::cache::get_tile_index(Vector2i pos, Vector2b offset_)
return index;
}
-void detail_astar::cache::add_index(size_t chunk_index, size_t tile_index, uint32_t index)
+void cache::add_index(size_t chunk_index, size_t tile_index, uint32_t index)
{
fm_debug_assert(index != (uint32_t)-1);
auto& c = array[chunk_index];
@@ -439,7 +445,7 @@ void detail_astar::cache::add_index(size_t chunk_index, size_t tile_index, uint3
c.indexes[tile_index] = {index};
}
-void detail_astar::cache::add_index(point pt, uint32_t index)
+void cache::add_index(point pt, uint32_t index)
{
auto ch = get_chunk_index(Vector2i(pt.chunk()));
auto tile = get_tile_index(Vector2i(pt.local()), pt.offset());
@@ -448,7 +454,7 @@ void detail_astar::cache::add_index(point pt, uint32_t index)
array[ch].indexes[tile] = {index};
}
-uint32_t detail_astar::cache::lookup_index(size_t chunk_index, size_t tile_index)
+uint32_t cache::lookup_index(size_t chunk_index, size_t tile_index)
{
auto& c = array[chunk_index];
if (c.exists[tile_index])
@@ -457,7 +463,7 @@ uint32_t detail_astar::cache::lookup_index(size_t chunk_index, size_t tile_index
return (uint32_t)-1;
}
-chunk* detail_astar::cache::try_get_chunk(world& w, floormat::chunk_coords_ ch)
+chunk* cache::try_get_chunk(world& w, floormat::chunk_coords_ ch)
{
auto idx = get_chunk_index({ch.x, ch.y});
auto& page = array[idx];
@@ -477,4 +483,16 @@ chunk* detail_astar::cache::try_get_chunk(world& w, floormat::chunk_coords_ ch)
return page.chunk;
}
-} // namespace floormat
+std::array<world::neighbor_pair, 8> cache::get_neighbors(world& w, chunk_coords_ ch0)
+{
+ fm_debug_assert(!size.isZero());
+ std::array<world::neighbor_pair, 8> neighbors;
+ for (auto i = 0uz; const auto& x : world::neighbor_offsets)
+ {
+ auto ch = ch0 + x;
+ neighbors[i++] = { try_get_chunk(w, ch), ch0 };
+ }
+ return neighbors;
+}
+
+} // namespace floormat::detail_astar
diff --git a/src/path-search.cpp b/src/path-search.cpp
index 739826be..f5a36feb 100644
--- a/src/path-search.cpp
+++ b/src/path-search.cpp
@@ -85,7 +85,8 @@ bool path_search::is_passable_(chunk* c0, const std::array<world::neighbor_pair,
return true;
}
-bool path_search::is_passable(world& w, global_coords coord, Vector2b offset, Vector2ui size_,
+bool path_search::is_passable(world& w, global_coords coord,
+ Vector2b offset, Vector2ui size_,
object_id own_id, const pred& p)
{
auto center = iTILE_SIZE2 * Vector2i(coord.local()) + Vector2i(offset);
@@ -94,23 +95,30 @@ bool path_search::is_passable(world& w, global_coords coord, Vector2b offset, Ve
return is_passable(w, coord, {min, max}, own_id, p);
}
-bool path_search::is_passable(world& w, chunk_coords_ ch, const bbox<float>& bb, object_id own_id, const pred& p)
+bool path_search::is_passable(world& w, struct detail_astar::cache& cache, global_coords coord,
+ Vector2b offset, Vector2ui size_,
+ object_id own_id, const pred& p)
+{
+ auto center = iTILE_SIZE2 * Vector2i(coord.local()) + Vector2i(offset);
+ auto size = Vector2(size_);
+ auto min = Vector2(center) - size*.5f, max = min + size;
+ return is_passable(w, cache, coord, {min, max}, own_id, p);
+}
+
+bool path_search::is_passable(world& w, chunk_coords_ ch, const bbox<float>& bb,
+ object_id own_id, const pred& p)
{
auto* c = w.at(ch);
auto neighbors = w.neighbors(ch);
return is_passable_(c, neighbors, bb.min, bb.max, own_id, p);
}
-bool path_search::is_passable(world& w, struct detail_astar::cache& cache, chunk_coords_ ch0, const bbox<float>& bb, object_id own_id, const pred& p)
+bool path_search::is_passable(world& w, struct detail_astar::cache& cache, chunk_coords_ ch0,
+ const bbox<float>& bb, object_id own_id, const pred& p)
{
- fm_debug_assert(!cache.size.isZero());
- std::array<world::neighbor_pair, 8> neighbors;
- for (auto i = 0uz; const auto& x : world::neighbor_offsets)
- {
- auto ch = ch0 + x;
- neighbors[i++] = { cache.try_get_chunk(w, ch), ch0 };
- }
- return is_passable_(cache.try_get_chunk(w, ch0), neighbors, bb.min, bb.max, own_id, p);
+ auto* c = cache.try_get_chunk(w, ch0);
+ auto nbs = cache.get_neighbors(w, ch0);
+ return is_passable_(c, nbs, bb.min, bb.max, own_id, p);
}
} // namespace floormat
diff --git a/src/path-search.hpp b/src/path-search.hpp
index 672ecc3d..5617765f 100644
--- a/src/path-search.hpp
+++ b/src/path-search.hpp
@@ -49,6 +49,8 @@ struct cache
void add_index(point pt, uint32_t index);
uint32_t lookup_index(size_t chunk_index, size_t tile_index);
chunk* try_get_chunk(world& w, chunk_coords_ ch);
+
+ std::array<world::neighbor_pair, 8> get_neighbors(world& w, chunk_coords_ ch0);
};
} // namespace detail_astar
struct path_search_result;
@@ -84,6 +86,7 @@ public:
static bool is_passable_(chunk* c0, const std::array<world::neighbor_pair, 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());
};