Skip to content

Commit e30d3af

Browse files
committed
Merge pull request #102766 from smix8/region_filters
Add path query region filters
2 parents 7d1e236 + 9dfeabc commit e30d3af

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
@@ -30,6 +30,8 @@
3030

3131
#pragma once
3232

33+
#include "../nav_utils.h"
34+
3335
#include "servers/navigation/navigation_utilities.h"
3436

3537
struct NavBaseIteration {
@@ -42,6 +44,7 @@ struct NavBaseIteration {
4244
ObjectID owner_object_id;
4345
RID owner_rid;
4446
bool owner_use_edge_connections = false;
47+
LocalVector<gd::Polygon> navmesh_polygons;
4548

4649
bool get_enabled() const { return enabled; }
4750
NavigationUtilities::PathSegmentType get_type() const { return owner_type; }
@@ -51,4 +54,5 @@ struct NavBaseIteration {
5154
real_t get_enter_cost() const { return enter_cost; }
5255
real_t get_travel_cost() const { return travel_cost; }
5356
bool get_use_edge_connections() const { return owner_use_edge_connections; }
57+
const LocalVector<gd::Polygon> &get_navmesh_polygons() const { return navmesh_polygons; }
5458
};

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
@@ -70,6 +70,10 @@ class NavMeshQueries3D {
7070
PathPostProcessing path_postprocessing = PathPostProcessing::PATH_POSTPROCESSING_CORRIDORFUNNEL;
7171
bool simplify_path = false;
7272
real_t simplify_epsilon = 0.0;
73+
bool exclude_regions = false;
74+
bool include_regions = false;
75+
LocalVector<RID> excluded_regions;
76+
LocalVector<RID> included_regions;
7377

7478
// Path building.
7579
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
@@ -37,12 +37,10 @@
3737

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

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

modules/navigation/nav_link.h

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

4342
Vector3 get_start_position() const { return start_position; }
4443
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
@@ -68,6 +68,8 @@ class NavigationPathQueryParameters2D : public RefCounted {
6868
BitField<PathMetadataFlags> metadata_flags = PATH_METADATA_INCLUDE_ALL;
6969
bool simplify_path = false;
7070
real_t simplify_epsilon = 0.0;
71+
LocalVector<RID> _excluded_regions;
72+
LocalVector<RID> _included_regions;
7173

7274
public:
7375
void set_pathfinding_algorithm(const PathfindingAlgorithm p_pathfinding_algorithm);
@@ -96,6 +98,12 @@ class NavigationPathQueryParameters2D : public RefCounted {
9698

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

101109
VARIANT_ENUM_CAST(NavigationPathQueryParameters2D::PathfindingAlgorithm);

0 commit comments

Comments
 (0)