@@ -282,7 +282,6 @@ void NavMeshQueries3D::_query_task_find_start_end_positions(NavMeshPathQueryTask
282282
283283void NavMeshQueries3D::_query_task_build_path_corridor (NavMeshPathQueryTask3D &p_query_task) {
284284 const Vector3 p_target_position = p_query_task.target_position ;
285- const uint32_t p_navigation_layers = p_query_task.navigation_layers ;
286285 const Polygon *begin_poly = p_query_task.begin_polygon ;
287286 const Polygon *end_poly = p_query_task.end_polygon ;
288287 Vector3 begin_point = p_query_task.begin_position ;
@@ -325,68 +324,35 @@ void NavMeshQueries3D::_query_task_build_path_corridor(NavMeshPathQueryTask3D &p
325324 for (uint32_t connection_index = 0 ; connection_index < edge.connections .size (); connection_index++) {
326325 const Edge::Connection &connection = edge.connections [connection_index];
327326
328- // Only consider the connection to another polygon if this polygon is in a region with compatible layers.
329- const NavBaseIteration3D *owner = connection.polygon ->owner ;
330- bool skip_connection = false ;
331- if (p_query_task.exclude_regions || p_query_task.include_regions ) {
332- switch (owner->get_type ()) {
333- case NavigationUtilities::PathSegmentType::PATH_SEGMENT_TYPE_REGION: {
334- if (p_query_task.exclude_regions && p_query_task.excluded_regions .has (owner->get_self ())) {
335- skip_connection = true ;
336- } else if (p_query_task.include_regions && !p_query_task.included_regions .has (owner->get_self ())) {
337- skip_connection = true ;
338- }
339- } break ;
340- case NavigationUtilities::PathSegmentType::PATH_SEGMENT_TYPE_LINK: {
341- const LocalVector<Polygon> &link_polygons = owner->get_navmesh_polygons ();
342- if (link_polygons.size () != 2 ) {
343- // Whatever this is, it is not a valid connected link.
344- skip_connection = true ;
345- } else {
346- const RID link_start_region = link_polygons[0 ].owner ->get_self ();
347- const RID link_end_region = link_polygons[1 ].owner ->get_self ();
348- if (p_query_task.exclude_regions && (p_query_task.excluded_regions .has (link_start_region) || p_query_task.excluded_regions .has (link_end_region))) {
349- // At least one region of the link is excluded so skip.
350- skip_connection = true ;
351- }
352- if (p_query_task.include_regions && (!p_query_task.included_regions .has (link_start_region) || !p_query_task.excluded_regions .has (link_end_region))) {
353- // Not both regions of the link are included so skip.
354- skip_connection = true ;
355- }
356- }
357- } break ;
358- }
359- }
360-
361- if (skip_connection) {
327+ const NavBaseIteration3D *connection_owner = connection.polygon ->owner ;
328+ const bool owner_is_usable = _query_task_is_connection_owner_usable (p_query_task, connection_owner);
329+ if (!owner_is_usable) {
362330 continue ;
363331 }
364332
365- if ((p_navigation_layers & owner->get_navigation_layers ()) != 0 ) {
366- Vector3 pathway[2 ] = { connection.pathway_start , connection.pathway_end };
367- const Vector3 new_entry = Geometry3D::get_closest_point_to_segment (least_cost_poly.entry , pathway);
368- const real_t new_traveled_distance = least_cost_poly.entry .distance_to (new_entry) * poly_travel_cost + poly_enter_cost + least_cost_poly.traveled_distance ;
369-
370- // Check if the neighbor polygon has already been processed.
371- NavigationPoly &neighbor_poly = navigation_polys[connection.polygon ->id ];
372- if (new_traveled_distance < neighbor_poly.traveled_distance ) {
373- // Add the polygon to the heap of polygons to traverse next.
374- neighbor_poly.back_navigation_poly_id = least_cost_id;
375- neighbor_poly.back_navigation_edge = connection.edge ;
376- neighbor_poly.back_navigation_edge_pathway_start = connection.pathway_start ;
377- neighbor_poly.back_navigation_edge_pathway_end = connection.pathway_end ;
378- neighbor_poly.traveled_distance = new_traveled_distance;
379- neighbor_poly.distance_to_destination =
380- new_entry.distance_to (end_point) *
381- owner->get_travel_cost ();
382- neighbor_poly.entry = new_entry;
383-
384- if (neighbor_poly.traversable_poly_index != traversable_polys.INVALID_INDEX ) {
385- traversable_polys.shift (neighbor_poly.traversable_poly_index );
386- } else {
387- neighbor_poly.poly = connection.polygon ;
388- traversable_polys.push (&neighbor_poly);
389- }
333+ Vector3 pathway[2 ] = { connection.pathway_start , connection.pathway_end };
334+ const Vector3 new_entry = Geometry3D::get_closest_point_to_segment (least_cost_poly.entry , pathway);
335+ const real_t new_traveled_distance = least_cost_poly.entry .distance_to (new_entry) * poly_travel_cost + poly_enter_cost + least_cost_poly.traveled_distance ;
336+
337+ // Check if the neighbor polygon has already been processed.
338+ NavigationPoly &neighbor_poly = navigation_polys[connection.polygon ->id ];
339+ if (new_traveled_distance < neighbor_poly.traveled_distance ) {
340+ // Add the polygon to the heap of polygons to traverse next.
341+ neighbor_poly.back_navigation_poly_id = least_cost_id;
342+ neighbor_poly.back_navigation_edge = connection.edge ;
343+ neighbor_poly.back_navigation_edge_pathway_start = connection.pathway_start ;
344+ neighbor_poly.back_navigation_edge_pathway_end = connection.pathway_end ;
345+ neighbor_poly.traveled_distance = new_traveled_distance;
346+ neighbor_poly.distance_to_destination =
347+ new_entry.distance_to (end_point) *
348+ connection_owner->get_travel_cost ();
349+ neighbor_poly.entry = new_entry;
350+
351+ if (neighbor_poly.traversable_poly_index != traversable_polys.INVALID_INDEX ) {
352+ traversable_polys.shift (neighbor_poly.traversable_poly_index );
353+ } else {
354+ neighbor_poly.poly = connection.polygon ;
355+ traversable_polys.push (&neighbor_poly);
390356 }
391357 }
392358 }
@@ -1156,6 +1122,50 @@ void NavMeshQueries3D::_query_task_clip_path(NavMeshPathQueryTask3D &p_query_tas
11561122 }
11571123}
11581124
1125+ bool NavMeshQueries3D::_query_task_is_connection_owner_usable (const NavMeshPathQueryTask3D &p_query_task, const NavBaseIteration3D *p_owner) {
1126+ bool owner_usable = true ;
1127+
1128+ if ((p_query_task.navigation_layers & p_owner->get_navigation_layers ()) == 0 ) {
1129+ // Not usable. No matching bit between task filter bitmask and owner bitmask.
1130+ owner_usable = false ;
1131+ return owner_usable;
1132+ }
1133+
1134+ if (p_query_task.exclude_regions || p_query_task.include_regions ) {
1135+ switch (p_owner->get_type ()) {
1136+ case NavigationUtilities::PathSegmentType::PATH_SEGMENT_TYPE_REGION: {
1137+ if (p_query_task.exclude_regions && p_query_task.excluded_regions .has (p_owner->get_self ())) {
1138+ // Not usable. Exclude region filter is active and this region is excluded.
1139+ owner_usable = false ;
1140+ } else if (p_query_task.include_regions && !p_query_task.included_regions .has (p_owner->get_self ())) {
1141+ // Not usable. Include region filter is active and this region is not included.
1142+ owner_usable = false ;
1143+ }
1144+ } break ;
1145+ case NavigationUtilities::PathSegmentType::PATH_SEGMENT_TYPE_LINK: {
1146+ const LocalVector<Polygon> &link_polygons = p_owner->get_navmesh_polygons ();
1147+ if (link_polygons.size () != 2 ) {
1148+ // Not usable. Whatever this is, it is not a valid connected link.
1149+ owner_usable = false ;
1150+ } else {
1151+ const RID link_start_region = link_polygons[0 ].owner ->get_self ();
1152+ const RID link_end_region = link_polygons[1 ].owner ->get_self ();
1153+ if (p_query_task.exclude_regions && (p_query_task.excluded_regions .has (link_start_region) || p_query_task.excluded_regions .has (link_end_region))) {
1154+ // Not usable. Exclude region filter is active and at least one region of the link is excluded.
1155+ owner_usable = false ;
1156+ }
1157+ if (p_query_task.include_regions && (!p_query_task.included_regions .has (link_start_region) || !p_query_task.excluded_regions .has (link_end_region))) {
1158+ // Not usable. Include region filter is active and not both regions of the links are included.
1159+ owner_usable = false ;
1160+ }
1161+ }
1162+ } break ;
1163+ }
1164+ }
1165+
1166+ return owner_usable;
1167+ }
1168+
11591169LocalVector<uint32_t > NavMeshQueries3D::get_simplified_path_indices (const LocalVector<Vector3> &p_path, real_t p_epsilon) {
11601170 p_epsilon = MAX (0.0 , p_epsilon);
11611171 real_t squared_epsilon = p_epsilon * p_epsilon;
0 commit comments