diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2023-10-16 12:40:09 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2023-10-16 12:40:09 +0200 |
commit | 79cc88894cd4b91878a1cefe610eb69996730e00 (patch) | |
tree | 92b5549ff50e64c315e6bba9410d7601c104e877 /src | |
parent | cbb73181de4f6fbe3e7bae9d7259c5169d04b275 (diff) |
a
Diffstat (limited to 'src')
-rw-r--r-- | src/path-search-dijkstra.cpp | 55 |
1 files changed, 32 insertions, 23 deletions
diff --git a/src/path-search-dijkstra.cpp b/src/path-search-dijkstra.cpp index 321ca2e4..47c87689 100644 --- a/src/path-search-dijkstra.cpp +++ b/src/path-search-dijkstra.cpp @@ -117,7 +117,7 @@ path_search_result astar::Dijkstra(world& w, const point from_, const point to_, constexpr auto min_size = Vector2ui{div_size*3/2}; const auto own_size = Math::max(Vector2ui(own_size_), min_size); - constexpr auto goal_distance = (div_size*3/2).length(); + constexpr auto goal_thres = (div_size*3/2).length(); const auto [from, from_offset] = from_; const auto [to, to_offset] = to_; @@ -165,11 +165,13 @@ path_search_result astar::Dijkstra(world& w, const point from_, const point to_, } } - auto closest = distance(from_, to_); + auto closest_dist = distance(from_, to_); auto closest_pos = from_; uint32_t closest_path_len = 0; auto goal_idx = (uint32_t)-1; const auto goal_bb = bbox_from_pos(Vector2(to_.local()), to_.offset(), own_size); + const auto goal_chunk_idx = cache.get_chunk_index(Vector2i(to_.chunk())); + const auto goal_tile_idx = cache.get_tile_index(Vector2i(to_.local()), to_offset); while (!Q.empty()) { @@ -181,9 +183,12 @@ path_search_result astar::Dijkstra(world& w, const point from_, const point to_, cur_dist = n.dist; } - if (auto d = distance(cur_pt, to_); d < closest) [[unlikely]] + if (cur_dist >= max_dist) [[unlikely]] + continue; + + if (auto d = distance(cur_pt, to_); d < closest_dist) [[unlikely]] { - closest = d; + closest_dist = d; closest_pos = cur_pt; closest_path_len = cur_dist; } @@ -191,43 +196,48 @@ path_search_result astar::Dijkstra(world& w, const point from_, const point to_, #ifndef FM_NO_DEBUG if (debug >= 2) [[unlikely]] DBG_nospace << "node" - << " px:" << closest << " path:" << closest_path_len + << " px:" << closest_dist << " path:" << closest_path_len << " pos:" << closest_pos; #endif const auto bb0 = bbox_from_pos(Vector2(cur_pt.local()), cur_pt.offset(), own_size); - if (auto dist_to_goal = distance(cur_pt, to_); dist_to_goal < goal_distance) [[unlikely]] + if (auto dist_to_goal = distance(cur_pt, to_); dist_to_goal < goal_thres) [[unlikely]] { if (auto dist = cur_dist + dist_to_goal; dist < max_dist) { auto vec = Vector2(cur_pt.coord() - to_.coord()) * TILE_SIZE2 + Vector2(cur_pt.offset() - to_.offset()); auto bb1 = bbox<float>{goal_bb.min + vec, goal_bb.max + vec}; auto bb = bbox_union(goal_bb, bb1); + bool fresh = true; + + if (goal_idx != (uint32_t)-1) + { + if (dist >= nodes[goal_idx].dist) + continue; + fresh = false; + } + if (path_search::is_passable(w, to_.chunk3(), bb, own_id, p)) { - if (goal_idx != (uint32_t)-1) + if (fresh) { - auto& n = nodes[goal_idx]; - if (dist >= n.dist) - continue; - n.dist = dist; - n.prev = id; - } - else - { - auto chunk_idx = cache.get_chunk_index(Vector2i(to_.chunk())); - auto tile_idx = cache.get_tile_index(Vector2i(to_.local()), to_offset); goal_idx = (uint32_t)nodes.size(); - cache.add_index(chunk_idx, tile_idx, goal_idx); + cache.add_index(goal_chunk_idx, goal_tile_idx, goal_idx); auto new_node = visited { .dist = dist, .prev = id, .pt = to_, }; nodes.push_back(new_node); - auto idx = cache.lookup_index(chunk_idx, tile_idx); + auto idx = cache.lookup_index(goal_chunk_idx, goal_tile_idx); fm_assert(idx == goal_idx); } + else + { + auto& n = nodes[goal_idx]; + n.dist = dist; + n.prev = id; + } max_dist = dist; continue; // path can only get longer } @@ -254,7 +264,6 @@ path_search_result astar::Dijkstra(world& w, const point from_, const point to_, if (nodes[new_idx].dist <= dist) continue; fresh = false; - } { auto vec_ = Vector2(vec); @@ -265,7 +274,8 @@ path_search_result astar::Dijkstra(world& w, const point from_, const point to_, } if (fresh) - { const auto sz = nodes.size(); + { + const auto sz = nodes.size(); new_idx = (uint32_t)sz; cache.add_index(chunk_idx, tile_idx, new_idx); auto new_node = visited { @@ -303,8 +313,7 @@ path_search_result astar::Dijkstra(world& w, const point from_, const point to_, dbg << "found len:" << nodes[goal_idx].dist; else { - dbg << "closest px:" << closest - << " path:" << closest_path_len + dbg << "closest_dist px:" << closest_dist << " path:" << closest_path_len << " pos:" << closest_pos; } dbg << " nodes:" << nodes.size(); |