Commit 187ba4c5 by Rémi Verschelde

AStar: Make get_closest_point() deterministic for equidistant points

Closes godotengine/godot-docs#3667. Supersedes #39405.
parent 201d5a7f
...@@ -280,10 +280,16 @@ int AStar::get_closest_point(const Vector3 &p_point, bool p_include_disabled) co ...@@ -280,10 +280,16 @@ int AStar::get_closest_point(const Vector3 &p_point, bool p_include_disabled) co
continue; // Disabled points should not be considered. continue; // Disabled points should not be considered.
} }
// Keep the closest point's ID, and in case of multiple closest IDs,
// the smallest one (makes it deterministic).
real_t d = p_point.distance_squared_to((*it.value)->pos); real_t d = p_point.distance_squared_to((*it.value)->pos);
if (closest_id < 0 || d < closest_dist) { int id = *(it.key);
if (d <= closest_dist) {
if (d == closest_dist && id > closest_id) { // Keep lowest ID.
continue;
}
closest_dist = d; closest_dist = d;
closest_id = *(it.key); closest_id = id;
} }
} }
...@@ -291,7 +297,6 @@ int AStar::get_closest_point(const Vector3 &p_point, bool p_include_disabled) co ...@@ -291,7 +297,6 @@ int AStar::get_closest_point(const Vector3 &p_point, bool p_include_disabled) co
} }
Vector3 AStar::get_closest_position_in_segment(const Vector3 &p_point) const { Vector3 AStar::get_closest_position_in_segment(const Vector3 &p_point) const {
bool found = false;
real_t closest_dist = 1e20; real_t closest_dist = 1e20;
Vector3 closest_point; Vector3 closest_point;
...@@ -311,10 +316,9 @@ Vector3 AStar::get_closest_position_in_segment(const Vector3 &p_point) const { ...@@ -311,10 +316,9 @@ Vector3 AStar::get_closest_position_in_segment(const Vector3 &p_point) const {
Vector3 p = Geometry3D::get_closest_point_to_segment(p_point, segment); Vector3 p = Geometry3D::get_closest_point_to_segment(p_point, segment);
real_t d = p_point.distance_squared_to(p); real_t d = p_point.distance_squared_to(p);
if (!found || d < closest_dist) { if (d < closest_dist) {
closest_point = p; closest_point = p;
closest_dist = d; closest_dist = d;
found = true;
} }
} }
......
...@@ -131,7 +131,8 @@ ...@@ -131,7 +131,8 @@
<argument index="1" name="include_disabled" type="bool" default="false"> <argument index="1" name="include_disabled" type="bool" default="false">
</argument> </argument>
<description> <description>
Returns the ID of the closest point to [code]to_position[/code], optionally taking disabled points into account. Returns -1 if there are no points in the points pool. Returns the ID of the closest point to [code]to_position[/code], optionally taking disabled points into account. Returns [code]-1[/code] if there are no points in the points pool.
[b]Note:[/b] If several points are the closest to [code]to_position[/code], the one with the smallest ID will be returned, ensuring a deterministic result.
</description> </description>
</method> </method>
<method name="get_closest_position_in_segment" qualifiers="const"> <method name="get_closest_position_in_segment" qualifiers="const">
......
...@@ -114,7 +114,8 @@ ...@@ -114,7 +114,8 @@
<argument index="1" name="include_disabled" type="bool" default="false"> <argument index="1" name="include_disabled" type="bool" default="false">
</argument> </argument>
<description> <description>
Returns the ID of the closest point to [code]to_position[/code], optionally taking disabled points into account. Returns -1 if there are no points in the points pool. Returns the ID of the closest point to [code]to_position[/code], optionally taking disabled points into account. Returns [code]-1[/code] if there are no points in the points pool.
[b]Note:[/b] If several points are the closest to [code]to_position[/code], the one with the smallest ID will be returned, ensuring a deterministic result.
</description> </description>
</method> </method>
<method name="get_closest_position_in_segment" qualifiers="const"> <method name="get_closest_position_in_segment" qualifiers="const">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment