summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2023-07-09 23:53:57 +0200
committerRémi Verschelde <rverschelde@gmail.com>2023-07-09 23:53:57 +0200
commit1b8cbfe6e3dce27ea3c1c8d065c0186549ac3f5c (patch)
tree64b6105adf452971cfd6786a2cfb8ee2ed756b0a
parent0bf8261f2596914e21d7eadb844603abee53b530 (diff)
parente5c24f7118854d36845af0de81d83da5ec18e2a8 (diff)
downloadredot-engine-1b8cbfe6e3dce27ea3c1c8d065c0186549ac3f5c.tar.gz
Merge pull request #79004 from smix8/fix_closest_navpath_pos_4.x
Fix closest possible navigation path position
-rw-r--r--modules/navigation/nav_map.cpp79
1 files changed, 77 insertions, 2 deletions
diff --git a/modules/navigation/nav_map.cpp b/modules/navigation/nav_map.cpp
index 2e4bf38f50..3a1d412618 100644
--- a/modules/navigation/nav_map.cpp
+++ b/modules/navigation/nav_map.cpp
@@ -301,6 +301,46 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
}
}
+ // Search all faces of start polygon as well.
+ bool closest_point_on_start_poly = false;
+ for (size_t point_id = 2; point_id < begin_poly->points.size(); point_id++) {
+ Face3 f(begin_poly->points[0].pos, begin_poly->points[point_id - 1].pos, begin_poly->points[point_id].pos);
+ Vector3 spoint = f.get_closest_point_to(p_destination);
+ real_t dpoint = spoint.distance_to(p_destination);
+ if (dpoint < end_d) {
+ end_point = spoint;
+ end_d = dpoint;
+ closest_point_on_start_poly = true;
+ }
+ }
+
+ if (closest_point_on_start_poly) {
+ // No point to run PostProcessing when start and end convex polygon is the same.
+ if (r_path_types) {
+ r_path_types->resize(2);
+ r_path_types->write[0] = begin_poly->owner->get_type();
+ r_path_types->write[1] = begin_poly->owner->get_type();
+ }
+
+ if (r_path_rids) {
+ r_path_rids->resize(2);
+ (*r_path_rids)[0] = begin_poly->owner->get_self();
+ (*r_path_rids)[1] = begin_poly->owner->get_self();
+ }
+
+ if (r_path_owners) {
+ r_path_owners->resize(2);
+ r_path_owners->write[0] = begin_poly->owner->get_owner_id();
+ r_path_owners->write[1] = begin_poly->owner->get_owner_id();
+ }
+
+ Vector<Vector3> path;
+ path.resize(2);
+ path.write[0] = begin_point;
+ path.write[1] = end_point;
+ return path;
+ }
+
// Reset open and navigation_polys
gd::NavigationPoly np = navigation_polys[0];
navigation_polys.clear();
@@ -346,9 +386,44 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
}
}
- // If we did not find a route, return an empty path.
+ // We did not find a route but we have both a start polygon and an end polygon at this point.
+ // Usually this happens because there was not a single external or internal connected edge, e.g. our start polygon is an isolated, single convex polygon.
if (!found_route) {
- return Vector<Vector3>();
+ end_d = FLT_MAX;
+ // Search all faces of the start polygon for the closest point to our target position.
+ for (size_t point_id = 2; point_id < begin_poly->points.size(); point_id++) {
+ Face3 f(begin_poly->points[0].pos, begin_poly->points[point_id - 1].pos, begin_poly->points[point_id].pos);
+ Vector3 spoint = f.get_closest_point_to(p_destination);
+ real_t dpoint = spoint.distance_to(p_destination);
+ if (dpoint < end_d) {
+ end_point = spoint;
+ end_d = dpoint;
+ }
+ }
+
+ if (r_path_types) {
+ r_path_types->resize(2);
+ r_path_types->write[0] = begin_poly->owner->get_type();
+ r_path_types->write[1] = begin_poly->owner->get_type();
+ }
+
+ if (r_path_rids) {
+ r_path_rids->resize(2);
+ (*r_path_rids)[0] = begin_poly->owner->get_self();
+ (*r_path_rids)[1] = begin_poly->owner->get_self();
+ }
+
+ if (r_path_owners) {
+ r_path_owners->resize(2);
+ r_path_owners->write[0] = begin_poly->owner->get_owner_id();
+ r_path_owners->write[1] = begin_poly->owner->get_owner_id();
+ }
+
+ Vector<Vector3> path;
+ path.resize(2);
+ path.write[0] = begin_point;
+ path.write[1] = end_point;
+ return path;
}
Vector<Vector3> path;