summaryrefslogtreecommitdiffhomepage
path: root/src/search-astar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/search-astar.cpp')
-rw-r--r--src/search-astar.cpp57
1 files changed, 48 insertions, 9 deletions
diff --git a/src/search-astar.cpp b/src/search-astar.cpp
index f11acfe9..1f1663f9 100644
--- a/src/search-astar.cpp
+++ b/src/search-astar.cpp
@@ -33,6 +33,39 @@ using Search::min_size;
namespace {
+void simplify_path(ArrayView<const point> src, std::vector<point>& dest)
+{
+ const auto size = (uint32_t)src.size();
+ fm_assert(size >= 2);
+ dest.reserve(size);
+ auto last_vec = src[1] - src[0];
+
+ dest.clear();
+ dest.reserve(src.size());
+
+ if (last_vec.isZero()) [[unlikely]]
+ {
+ fm_assert(size <= 2);
+ return;
+ }
+
+ dest.push_back(src[1]);
+
+ for (auto i = 2u; i < size; i++)
+ {
+ const auto pos = src[i];
+ const auto vec = pos - src[i-1];
+ if (vec != last_vec || Math::abs(vec).max() != div_size.x())
+ {
+ dest.push_back(pos);
+ last_vec = vec;
+ }
+ }
+
+ if (dest.back() != src.back())
+ dest.push_back(src.back());
+}
+
constexpr bbox<Int> bbox_from_pos1(point pt, Vector2ui size)
{
auto center = Vector2i(pt.local()) * iTILE_SIZE2 + Vector2i(pt.offset());
@@ -94,27 +127,33 @@ struct heap_comparator
inline bool operator()(uint32_t a, uint32_t b) const { return nodes[b].dist < nodes[a].dist; }
};
-void set_result_from_idx(path_search_result& result, const Array<visited>& nodes,
+void set_result_from_idx(path_search_result& result,
+ Array<point>& temp_nodes, const Array<visited>& nodes,
point to, const uint32_t idx)
{
- fm_debug_assert(idx != (uint32_t)-1);
+ uint32_t len = 0;
+ for (auto i = idx; i != (uint32_t)-1; i = nodes[i].prev)
+ len++;
- auto& path = result.raw_path().vec;
- path.clear();
+ fm_debug_assert(idx != (uint32_t)-1);
+ arrayResize(temp_nodes, 0);
+ arrayReserve(temp_nodes, len+1);
const auto& to_node = nodes[idx];
if (result.is_found() && to != to_node.pt)
- path.push_back(to);
+ arrayAppend(temp_nodes, to);
result.set_cost(to_node.dist);
auto i = idx;
do {
const auto& node = nodes[i];
- path.push_back(node.pt);
+ arrayAppend(temp_nodes, node.pt);
i = node.prev;
} while (i != (uint32_t)-1);
- std::reverse(path.begin(), path.end());
+ std::reverse(temp_nodes.begin(), temp_nodes.end());
+ simplify_path(temp_nodes, result.raw_path().vec);
+ arrayResize(temp_nodes, 0);
}
} // namespace
@@ -304,13 +343,13 @@ path_search_result astar::Dijkstra(world& w, const point from, const point to,
{
result.set_found(true);
result.set_distance(0);
- set_result_from_idx(result, nodes, to, goal_idx);
+ set_result_from_idx(result, temp_nodes, nodes, to, goal_idx);
}
else if (closest_idx != (uint32_t)-1)
{
result.set_found(false);
result.set_distance(closest_dist);
- set_result_from_idx(result, nodes, to, closest_idx);
+ set_result_from_idx(result, temp_nodes, nodes, to, closest_idx);
}
result.set_time(timeline.currentFrameTime());