Skip to content

Commit 9dfeabc

Browse files
committed
Add path query region filters
Adds filter lists to exclude or include specific regions in path queries.
1 parent c2732ae commit 9dfeabc

13 files changed

+235
-3
lines changed

doc/classes/NavigationPathQueryParameters2D.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@
1010
<link title="Using NavigationPathQueryObjects">$DOCS_URL/tutorials/navigation/navigation_using_navigationpathqueryobjects.html</link>
1111
</tutorials>
1212
<members>
13+
<member name="excluded_regions" type="RID[]" setter="set_excluded_regions" getter="get_excluded_regions" default="[]">
14+
The list of region [RID]s that will be excluded from the path query. Use [method NavigationRegion2D.get_rid] to get the [RID] associated with a [NavigationRegion2D] node.
15+
[b]Note:[/b] The returned array is copied and any changes to it will not update the original property value. To update the value you need to modify the returned array, and then set it to the property again.
16+
</member>
17+
<member name="included_regions" type="RID[]" setter="set_included_regions" getter="get_included_regions" default="[]">
18+
The list of region [RID]s that will be included by the path query. Use [method NavigationRegion2D.get_rid] to get the [RID] associated with a [NavigationRegion2D] node. If left empty all regions are included. If a region ends up being both included and excluded at the same time it will be excluded.
19+
[b]Note:[/b] The returned array is copied and any changes to it will not update the original property value. To update the value you need to modify the returned array, and then set it to the property again.
20+
</member>
1321
<member name="map" type="RID" setter="set_map" getter="get_map" default="RID()">
1422
The navigation map [RID] used in the path query.
1523
</member>

doc/classes/NavigationPathQueryParameters3D.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@
1010
<link title="Using NavigationPathQueryObjects">$DOCS_URL/tutorials/navigation/navigation_using_navigationpathqueryobjects.html</link>
1111
</tutorials>
1212
<members>
13+
<member name="excluded_regions" type="RID[]" setter="set_excluded_regions" getter="get_excluded_regions" default="[]">
14+
The list of region [RID]s that will be excluded from the path query. Use [method NavigationRegion3D.get_rid] to get the [RID] associated with a [NavigationRegion3D] node.
15+
[b]Note:[/b] The returned array is copied and any changes to it will not update the original property value. To update the value you need to modify the returned array, and then set it to the property again.
16+
</member>
17+
<member name="included_regions" type="RID[]" setter="set_included_regions" getter="get_included_regions" default="[]">
18+
The list of region [RID]s that will be included by the path query. Use [method NavigationRegion3D.get_rid] to get the [RID] associated with a [NavigationRegion3D] node. If left empty all regions are included. If a region ends up being both included and excluded at the same time it will be excluded.
19+
[b]Note:[/b] The returned array is copied and any changes to it will not update the original property value. To update the value you need to modify the returned array, and then set it to the property again.
20+
</member>
1321
<member name="map" type="RID" setter="set_map" getter="get_map" default="RID()">
1422
The navigation map [RID] used in the path query.
1523
</member>

modules/navigation/2d/godot_navigation_server_2d.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,8 @@ void GodotNavigationServer2D::query_path(const Ref<NavigationPathQueryParameters
513513
query_parameters->set_metadata_flags((int64_t)p_query_parameters->get_metadata_flags());
514514
query_parameters->set_simplify_path(p_query_parameters->get_simplify_path());
515515
query_parameters->set_simplify_epsilon(p_query_parameters->get_simplify_epsilon());
516+
query_parameters->set_excluded_regions(p_query_parameters->get_excluded_regions());
517+
query_parameters->set_included_regions(p_query_parameters->get_included_regions());
516518

517519
Ref<NavigationPathQueryResult3D> query_result;
518520
query_result.instantiate();

modules/navigation/3d/nav_base_iteration_3d.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#ifndef NAV_BASE_ITERATION_3D_H
3232
#define NAV_BASE_ITERATION_3D_H
3333

34+
#include "../nav_utils.h"
35+
3436
#include "servers/navigation/navigation_utilities.h"
3537

3638
struct NavBaseIteration {
@@ -43,6 +45,7 @@ struct NavBaseIteration {
4345
ObjectID owner_object_id;
4446
RID owner_rid;
4547
bool owner_use_edge_connections = false;
48+
LocalVector<gd::Polygon> navmesh_polygons;
4649

4750
bool get_enabled() const { return enabled; }
4851
NavigationUtilities::PathSegmentType get_type() const { return owner_type; }
@@ -52,6 +55,7 @@ struct NavBaseIteration {
5255
real_t get_enter_cost() const { return enter_cost; }
5356
real_t get_travel_cost() const { return travel_cost; }
5457
bool get_use_edge_connections() const { return owner_use_edge_connections; }
58+
const LocalVector<gd::Polygon> &get_navmesh_polygons() const { return navmesh_polygons; }
5559
};
5660

5761
#endif // NAV_BASE_ITERATION_3D_H

modules/navigation/3d/nav_mesh_queries_3d.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,29 @@ void NavMeshQueries3D::map_query_path(NavMap *map, const Ref<NavigationPathQuery
158158
query_task.navigation_layers = p_query_parameters->get_navigation_layers();
159159
query_task.callback = p_callback;
160160

161+
const TypedArray<RID> &_excluded_regions = p_query_parameters->get_excluded_regions();
162+
const TypedArray<RID> &_included_regions = p_query_parameters->get_included_regions();
163+
164+
uint32_t _excluded_region_count = _excluded_regions.size();
165+
uint32_t _included_region_count = _included_regions.size();
166+
167+
query_task.exclude_regions = _excluded_region_count > 0;
168+
query_task.include_regions = _included_region_count > 0;
169+
170+
if (query_task.exclude_regions) {
171+
query_task.excluded_regions.resize(_excluded_region_count);
172+
for (uint32_t i = 0; i < _excluded_region_count; i++) {
173+
query_task.excluded_regions[i] = _excluded_regions[i];
174+
}
175+
}
176+
177+
if (query_task.include_regions) {
178+
query_task.included_regions.resize(_included_region_count);
179+
for (uint32_t i = 0; i < _included_region_count; i++) {
180+
query_task.included_regions[i] = _included_regions[i];
181+
}
182+
}
183+
161184
switch (p_query_parameters->get_pathfinding_algorithm()) {
162185
case NavigationPathQueryParameters3D::PathfindingAlgorithm::PATHFINDING_ALGORITHM_ASTAR: {
163186
query_task.pathfinding_algorithm = PathfindingAlgorithm::PATHFINDING_ALGORITHM_ASTAR;
@@ -217,6 +240,13 @@ void NavMeshQueries3D::_query_task_find_start_end_positions(NavMeshPathQueryTask
217240
continue;
218241
}
219242

243+
if (p_query_task.exclude_regions && p_query_task.excluded_regions.has(region.get_self())) {
244+
continue;
245+
}
246+
if (p_query_task.include_regions && !p_query_task.included_regions.has(region.get_self())) {
247+
continue;
248+
}
249+
220250
// Find the initial poly and the end poly on this map.
221251
for (const gd::Polygon &p : region.get_navmesh_polygons()) {
222252
// Only consider the polygon if it in a region with compatible layers.
@@ -295,6 +325,41 @@ void NavMeshQueries3D::_query_task_build_path_corridor(NavMeshPathQueryTask3D &p
295325

296326
// Only consider the connection to another polygon if this polygon is in a region with compatible layers.
297327
const NavBaseIteration *owner = connection.polygon->owner;
328+
bool skip_connection = false;
329+
if (p_query_task.exclude_regions || p_query_task.include_regions) {
330+
switch (owner->get_type()) {
331+
case NavigationUtilities::PathSegmentType::PATH_SEGMENT_TYPE_REGION: {
332+
if (p_query_task.exclude_regions && p_query_task.excluded_regions.has(owner->get_self())) {
333+
skip_connection = true;
334+
} else if (p_query_task.include_regions && !p_query_task.included_regions.has(owner->get_self())) {
335+
skip_connection = true;
336+
}
337+
} break;
338+
case NavigationUtilities::PathSegmentType::PATH_SEGMENT_TYPE_LINK: {
339+
const LocalVector<gd::Polygon> &link_polygons = owner->get_navmesh_polygons();
340+
if (link_polygons.size() != 2) {
341+
// Whatever this is, it is not a valid connected link.
342+
skip_connection = true;
343+
} else {
344+
const RID link_start_region = link_polygons[0].owner->get_self();
345+
const RID link_end_region = link_polygons[1].owner->get_self();
346+
if (p_query_task.exclude_regions && (p_query_task.excluded_regions.has(link_start_region) || p_query_task.excluded_regions.has(link_end_region))) {
347+
// At least one region of the link is excluded so skip.
348+
skip_connection = true;
349+
}
350+
if (p_query_task.include_regions && (!p_query_task.included_regions.has(link_start_region) || !p_query_task.excluded_regions.has(link_end_region))) {
351+
// Not both regions of the link are included so skip.
352+
skip_connection = true;
353+
}
354+
}
355+
} break;
356+
}
357+
}
358+
359+
if (skip_connection) {
360+
continue;
361+
}
362+
298363
if ((p_navigation_layers & owner->get_navigation_layers()) != 0) {
299364
Vector3 pathway[2] = { connection.pathway_start, connection.pathway_end };
300365
const Vector3 new_entry = Geometry3D::get_closest_point_to_segment(least_cost_poly.entry, pathway);

modules/navigation/3d/nav_mesh_queries_3d.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ class NavMeshQueries3D {
7171
PathPostProcessing path_postprocessing = PathPostProcessing::PATH_POSTPROCESSING_CORRIDORFUNNEL;
7272
bool simplify_path = false;
7373
real_t simplify_epsilon = 0.0;
74+
bool exclude_regions = false;
75+
bool include_regions = false;
76+
LocalVector<RID> excluded_regions;
77+
LocalVector<RID> included_regions;
7478

7579
// Path building.
7680
Vector3 begin_position;

modules/navigation/3d/nav_region_iteration_3d.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,10 @@
3838

3939
struct NavRegionIteration : NavBaseIteration {
4040
Transform3D transform;
41-
LocalVector<gd::Polygon> navmesh_polygons;
4241
real_t surface_area = 0.0;
4342
AABB bounds;
4443

4544
const Transform3D &get_transform() const { return transform; }
46-
const LocalVector<gd::Polygon> &get_navmesh_polygons() const { return navmesh_polygons; }
4745
real_t get_surface_area() const { return surface_area; }
4846
AABB get_bounds() const { return bounds; }
4947
};

modules/navigation/nav_link.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ struct NavLinkIteration : NavBaseIteration {
3939
bool bidirectional = true;
4040
Vector3 start_position;
4141
Vector3 end_position;
42-
LocalVector<gd::Polygon> navmesh_polygons;
4342

4443
Vector3 get_start_position() const { return start_position; }
4544
Vector3 get_end_position() const { return end_position; }

servers/navigation/navigation_path_query_parameters_2d.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,38 @@ real_t NavigationPathQueryParameters2D::get_simplify_epsilon() const {
102102
return simplify_epsilon;
103103
}
104104

105+
void NavigationPathQueryParameters2D::set_included_regions(const TypedArray<RID> &p_regions) {
106+
_included_regions.resize(p_regions.size());
107+
for (uint32_t i = 0; i < _included_regions.size(); i++) {
108+
_included_regions[i] = p_regions[i];
109+
}
110+
}
111+
112+
TypedArray<RID> NavigationPathQueryParameters2D::get_included_regions() const {
113+
TypedArray<RID> r_regions;
114+
r_regions.resize(_included_regions.size());
115+
for (uint32_t i = 0; i < _included_regions.size(); i++) {
116+
r_regions[i] = _included_regions[i];
117+
}
118+
return r_regions;
119+
}
120+
121+
void NavigationPathQueryParameters2D::set_excluded_regions(const TypedArray<RID> &p_regions) {
122+
_excluded_regions.resize(p_regions.size());
123+
for (uint32_t i = 0; i < _excluded_regions.size(); i++) {
124+
_excluded_regions[i] = p_regions[i];
125+
}
126+
}
127+
128+
TypedArray<RID> NavigationPathQueryParameters2D::get_excluded_regions() const {
129+
TypedArray<RID> r_regions;
130+
r_regions.resize(_excluded_regions.size());
131+
for (uint32_t i = 0; i < _excluded_regions.size(); i++) {
132+
r_regions[i] = _excluded_regions[i];
133+
}
134+
return r_regions;
135+
}
136+
105137
void NavigationPathQueryParameters2D::_bind_methods() {
106138
ClassDB::bind_method(D_METHOD("set_pathfinding_algorithm", "pathfinding_algorithm"), &NavigationPathQueryParameters2D::set_pathfinding_algorithm);
107139
ClassDB::bind_method(D_METHOD("get_pathfinding_algorithm"), &NavigationPathQueryParameters2D::get_pathfinding_algorithm);
@@ -130,6 +162,12 @@ void NavigationPathQueryParameters2D::_bind_methods() {
130162
ClassDB::bind_method(D_METHOD("set_simplify_epsilon", "epsilon"), &NavigationPathQueryParameters2D::set_simplify_epsilon);
131163
ClassDB::bind_method(D_METHOD("get_simplify_epsilon"), &NavigationPathQueryParameters2D::get_simplify_epsilon);
132164

165+
ClassDB::bind_method(D_METHOD("set_included_regions", "regions"), &NavigationPathQueryParameters2D::set_included_regions);
166+
ClassDB::bind_method(D_METHOD("get_included_regions"), &NavigationPathQueryParameters2D::get_included_regions);
167+
168+
ClassDB::bind_method(D_METHOD("set_excluded_regions", "regions"), &NavigationPathQueryParameters2D::set_excluded_regions);
169+
ClassDB::bind_method(D_METHOD("get_excluded_regions"), &NavigationPathQueryParameters2D::get_excluded_regions);
170+
133171
ADD_PROPERTY(PropertyInfo(Variant::RID, "map"), "set_map", "get_map");
134172
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "start_position"), "set_start_position", "get_start_position");
135173
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "target_position"), "set_target_position", "get_target_position");
@@ -139,6 +177,8 @@ void NavigationPathQueryParameters2D::_bind_methods() {
139177
ADD_PROPERTY(PropertyInfo(Variant::INT, "metadata_flags", PROPERTY_HINT_FLAGS, "Include Types,Include RIDs,Include Owners"), "set_metadata_flags", "get_metadata_flags");
140178
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "simplify_path"), "set_simplify_path", "get_simplify_path");
141179
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "simplify_epsilon"), "set_simplify_epsilon", "get_simplify_epsilon");
180+
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "excluded_regions", PROPERTY_HINT_ARRAY_TYPE, "RID"), "set_excluded_regions", "get_excluded_regions");
181+
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "included_regions", PROPERTY_HINT_ARRAY_TYPE, "RID"), "set_included_regions", "get_included_regions");
142182

143183
BIND_ENUM_CONSTANT(PATHFINDING_ALGORITHM_ASTAR);
144184

servers/navigation/navigation_path_query_parameters_2d.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ class NavigationPathQueryParameters2D : public RefCounted {
6969
BitField<PathMetadataFlags> metadata_flags = PATH_METADATA_INCLUDE_ALL;
7070
bool simplify_path = false;
7171
real_t simplify_epsilon = 0.0;
72+
LocalVector<RID> _excluded_regions;
73+
LocalVector<RID> _included_regions;
7274

7375
public:
7476
void set_pathfinding_algorithm(const PathfindingAlgorithm p_pathfinding_algorithm);
@@ -97,6 +99,12 @@ class NavigationPathQueryParameters2D : public RefCounted {
9799

98100
void set_simplify_epsilon(real_t p_epsilon);
99101
real_t get_simplify_epsilon() const;
102+
103+
void set_excluded_regions(const TypedArray<RID> &p_regions);
104+
TypedArray<RID> get_excluded_regions() const;
105+
106+
void set_included_regions(const TypedArray<RID> &p_regions);
107+
TypedArray<RID> get_included_regions() const;
100108
};
101109

102110
VARIANT_ENUM_CAST(NavigationPathQueryParameters2D::PathfindingAlgorithm);

0 commit comments

Comments
 (0)