Merge pull request #94246 from theashtronaut/fix-astar-partial-path

Fix AStar2D, AStar3D, AStarGrid2D from not returning a path when the destination is disabled/solid even with `allow_partial_path` option
This commit is contained in:
Rémi Verschelde 2024-09-16 13:34:22 +02:00
commit 91553f5811
No known key found for this signature in database
GPG Key ID: C3336907360768E1
7 changed files with 21 additions and 15 deletions

View File

@ -319,11 +319,11 @@ Vector3 AStar3D::get_closest_position_in_segment(const Vector3 &p_point) const {
return closest_point;
}
bool AStar3D::_solve(Point *begin_point, Point *end_point) {
bool AStar3D::_solve(Point *begin_point, Point *end_point, bool p_allow_partial_path) {
last_closest_point = nullptr;
pass++;
if (!end_point->enabled) {
if (!end_point->enabled && !p_allow_partial_path) {
return false;
}
@ -443,7 +443,7 @@ Vector<Vector3> AStar3D::get_point_path(int64_t p_from_id, int64_t p_to_id, bool
Point *begin_point = a;
Point *end_point = b;
bool found_route = _solve(begin_point, end_point);
bool found_route = _solve(begin_point, end_point, p_allow_partial_path);
if (!found_route) {
if (!p_allow_partial_path || last_closest_point == nullptr) {
return Vector<Vector3>();
@ -497,7 +497,7 @@ Vector<int64_t> AStar3D::get_id_path(int64_t p_from_id, int64_t p_to_id, bool p_
Point *begin_point = a;
Point *end_point = b;
bool found_route = _solve(begin_point, end_point);
bool found_route = _solve(begin_point, end_point, p_allow_partial_path);
if (!found_route) {
if (!p_allow_partial_path || last_closest_point == nullptr) {
return Vector<int64_t>();
@ -726,7 +726,7 @@ Vector<Vector2> AStar2D::get_point_path(int64_t p_from_id, int64_t p_to_id, bool
AStar3D::Point *begin_point = a;
AStar3D::Point *end_point = b;
bool found_route = _solve(begin_point, end_point);
bool found_route = _solve(begin_point, end_point, p_allow_partial_path);
if (!found_route) {
if (!p_allow_partial_path || astar.last_closest_point == nullptr) {
return Vector<Vector2>();
@ -780,7 +780,7 @@ Vector<int64_t> AStar2D::get_id_path(int64_t p_from_id, int64_t p_to_id, bool p_
AStar3D::Point *begin_point = a;
AStar3D::Point *end_point = b;
bool found_route = _solve(begin_point, end_point);
bool found_route = _solve(begin_point, end_point, p_allow_partial_path);
if (!found_route) {
if (!p_allow_partial_path || astar.last_closest_point == nullptr) {
return Vector<int64_t>();
@ -816,11 +816,11 @@ Vector<int64_t> AStar2D::get_id_path(int64_t p_from_id, int64_t p_to_id, bool p_
return path;
}
bool AStar2D::_solve(AStar3D::Point *begin_point, AStar3D::Point *end_point) {
bool AStar2D::_solve(AStar3D::Point *begin_point, AStar3D::Point *end_point, bool p_allow_partial_path) {
astar.last_closest_point = nullptr;
astar.pass++;
if (!end_point->enabled) {
if (!end_point->enabled && !p_allow_partial_path) {
return false;
}

View File

@ -115,7 +115,7 @@ class AStar3D : public RefCounted {
HashSet<Segment, Segment> segments;
Point *last_closest_point = nullptr;
bool _solve(Point *begin_point, Point *end_point);
bool _solve(Point *begin_point, Point *end_point, bool p_allow_partial_path);
protected:
static void _bind_methods();
@ -171,7 +171,7 @@ class AStar2D : public RefCounted {
GDCLASS(AStar2D, RefCounted);
AStar3D astar;
bool _solve(AStar3D::Point *begin_point, AStar3D::Point *end_point);
bool _solve(AStar3D::Point *begin_point, AStar3D::Point *end_point, bool p_allow_partial_path);
protected:
static void _bind_methods();

View File

@ -491,11 +491,11 @@ void AStarGrid2D::_get_nbors(Point *p_point, LocalVector<Point *> &r_nbors) {
}
}
bool AStarGrid2D::_solve(Point *p_begin_point, Point *p_end_point) {
bool AStarGrid2D::_solve(Point *p_begin_point, Point *p_end_point, bool p_allow_partial_path) {
last_closest_point = nullptr;
pass++;
if (_get_solid_unchecked(p_end_point->id)) {
if (_get_solid_unchecked(p_end_point->id) && !p_allow_partial_path) {
return false;
}
@ -647,7 +647,7 @@ Vector<Vector2> AStarGrid2D::get_point_path(const Vector2i &p_from_id, const Vec
Point *begin_point = a;
Point *end_point = b;
bool found_route = _solve(begin_point, end_point);
bool found_route = _solve(begin_point, end_point, p_allow_partial_path);
if (!found_route) {
if (!p_allow_partial_path || last_closest_point == nullptr) {
return Vector<Vector2>();
@ -700,7 +700,7 @@ TypedArray<Vector2i> AStarGrid2D::get_id_path(const Vector2i &p_from_id, const V
Point *begin_point = a;
Point *end_point = b;
bool found_route = _solve(begin_point, end_point);
bool found_route = _solve(begin_point, end_point, p_allow_partial_path);
if (!found_route) {
if (!p_allow_partial_path || last_closest_point == nullptr) {
return TypedArray<Vector2i>();

View File

@ -159,8 +159,8 @@ private: // Internal routines.
void _get_nbors(Point *p_point, LocalVector<Point *> &r_nbors);
Point *_jump(Point *p_from, Point *p_to);
bool _solve(Point *p_begin_point, Point *p_end_point, bool p_allow_partial_path);
Point *_forced_successor(int32_t p_x, int32_t p_y, int32_t p_dx, int32_t p_dy, bool p_inclusive = false);
bool _solve(Point *p_begin_point, Point *p_end_point);
protected:
static void _bind_methods();

View File

@ -143,6 +143,7 @@
<description>
Returns an array with the IDs of the points that form the path found by AStar2D between the given points. The array is ordered from the starting point to the ending point of the path.
If there is no valid path to the target, and [param allow_partial_path] is [code]true[/code], returns a path to the point closest to the target that can be reached.
[b]Note:[/b] When [param allow_partial_path] is [code]true[/code] and [param to_id] is disabled the search may take an unusually long time to finish.
[codeblocks]
[gdscript]
var astar = AStar2D.new()
@ -235,6 +236,7 @@
Returns an array with the points that are in the path found by AStar2D between the given points. The array is ordered from the starting point to the ending point of the path.
If there is no valid path to the target, and [param allow_partial_path] is [code]true[/code], returns a path to the point closest to the target that can be reached.
[b]Note:[/b] This method is not thread-safe. If called from a [Thread], it will return an empty array and will print an error message.
Additionally, when [param allow_partial_path] is [code]true[/code] and [param to_id] is disabled the search may take an unusually long time to finish.
</description>
</method>
<method name="get_point_position" qualifiers="const">

View File

@ -172,6 +172,7 @@
<description>
Returns an array with the IDs of the points that form the path found by AStar3D between the given points. The array is ordered from the starting point to the ending point of the path.
If there is no valid path to the target, and [param allow_partial_path] is [code]true[/code], returns a path to the point closest to the target that can be reached.
[b]Note:[/b] When [param allow_partial_path] is [code]true[/code] and [param to_id] is disabled the search may take an unusually long time to finish.
[codeblocks]
[gdscript]
var astar = AStar3D.new()
@ -262,6 +263,7 @@
Returns an array with the points that are in the path found by AStar3D between the given points. The array is ordered from the starting point to the ending point of the path.
If there is no valid path to the target, and [param allow_partial_path] is [code]true[/code], returns a path to the point closest to the target that can be reached.
[b]Note:[/b] This method is not thread-safe. If called from a [Thread], it will return an empty array and will print an error message.
Additionally, when [param allow_partial_path] is [code]true[/code] and [param to_id] is disabled the search may take an unusually long time to finish.
</description>
</method>
<method name="get_point_position" qualifiers="const">

View File

@ -79,6 +79,7 @@
<description>
Returns an array with the IDs of the points that form the path found by AStar2D between the given points. The array is ordered from the starting point to the ending point of the path.
If there is no valid path to the target, and [param allow_partial_path] is [code]true[/code], returns a path to the point closest to the target that can be reached.
[b]Note:[/b] When [param allow_partial_path] is [code]true[/code] and [param to_id] is solid the search may take an unusually long time to finish.
</description>
</method>
<method name="get_point_data_in_region" qualifiers="const">
@ -97,6 +98,7 @@
Returns an array with the points that are in the path found by [AStarGrid2D] between the given points. The array is ordered from the starting point to the ending point of the path.
If there is no valid path to the target, and [param allow_partial_path] is [code]true[/code], returns a path to the point closest to the target that can be reached.
[b]Note:[/b] This method is not thread-safe. If called from a [Thread], it will return an empty array and will print an error message.
Additionally, when [param allow_partial_path] is [code]true[/code] and [param to_id] is solid the search may take an unusually long time to finish.
</description>
</method>
<method name="get_point_position" qualifiers="const">