Skip to content

Commit 261952a

Browse files
committed
Merge pull request #87378 from smix8/navmesh_bordersize
Add NavigationMesh `border_size` property for tile baking
2 parents 4a30fe5 + d6c3101 commit 261952a

File tree

4 files changed

+32
-4
lines changed

4 files changed

+32
-4
lines changed

doc/classes/NavigationMesh.xml

+5
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@
9696
The distance to erode/shrink the walkable area of the heightfield away from obstructions.
9797
[b]Note:[/b] While baking, this value will be rounded up to the nearest multiple of [member cell_size].
9898
</member>
99+
<member name="border_size" type="float" setter="set_border_size" getter="get_border_size" default="0.0">
100+
The size of the non-navigable border around the bake bounding area.
101+
In conjunction with the [member filter_baking_aabb] and a [member edge_max_error] value at [code]1.0[/code] or below the border size can be used to bake tile aligned navigation meshes without the tile edges being shrunk by [member agent_radius].
102+
[b]Note:[/b] While baking and not zero, this value will be rounded up to the nearest multiple of [member cell_size].
103+
</member>
99104
<member name="cell_height" type="float" setter="set_cell_height" getter="get_cell_height" default="0.25">
100105
The cell height used to rasterize the navigation mesh vertices on the Y axis. Must match with the cell height on the navigation map.
101106
</member>

modules/navigation/nav_mesh_generator_3d.cpp

+9-3
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,9 @@ void NavMeshGenerator3D::generator_bake_from_source_geometry_data(Ref<Navigation
630630

631631
cfg.cs = p_navigation_mesh->get_cell_size();
632632
cfg.ch = p_navigation_mesh->get_cell_height();
633+
if (p_navigation_mesh->get_border_size() > 0.0) {
634+
cfg.borderSize = (int)Math::ceil(p_navigation_mesh->get_border_size() / cfg.cs);
635+
}
633636
cfg.walkableSlopeAngle = p_navigation_mesh->get_agent_max_slope();
634637
cfg.walkableHeight = (int)Math::ceil(p_navigation_mesh->get_agent_height() / cfg.ch);
635638
cfg.walkableClimb = (int)Math::floor(p_navigation_mesh->get_agent_max_climb() / cfg.ch);
@@ -642,6 +645,9 @@ void NavMeshGenerator3D::generator_bake_from_source_geometry_data(Ref<Navigation
642645
cfg.detailSampleDist = MAX(p_navigation_mesh->get_cell_size() * p_navigation_mesh->get_detail_sample_distance(), 0.1f);
643646
cfg.detailSampleMaxError = p_navigation_mesh->get_cell_height() * p_navigation_mesh->get_detail_sample_max_error();
644647

648+
if (p_navigation_mesh->get_border_size() > 0.0 && !Math::is_equal_approx(p_navigation_mesh->get_cell_size(), p_navigation_mesh->get_border_size())) {
649+
WARN_PRINT("Property border_size is ceiled to cell_size voxel units and loses precision.");
650+
}
645651
if (!Math::is_equal_approx((float)cfg.walkableHeight * cfg.ch, p_navigation_mesh->get_agent_height())) {
646652
WARN_PRINT("Property agent_height is ceiled to cell_height voxel units and loses precision.");
647653
}
@@ -743,11 +749,11 @@ void NavMeshGenerator3D::generator_bake_from_source_geometry_data(Ref<Navigation
743749

744750
if (p_navigation_mesh->get_sample_partition_type() == NavigationMesh::SAMPLE_PARTITION_WATERSHED) {
745751
ERR_FAIL_COND(!rcBuildDistanceField(&ctx, *chf));
746-
ERR_FAIL_COND(!rcBuildRegions(&ctx, *chf, 0, cfg.minRegionArea, cfg.mergeRegionArea));
752+
ERR_FAIL_COND(!rcBuildRegions(&ctx, *chf, cfg.borderSize, cfg.minRegionArea, cfg.mergeRegionArea));
747753
} else if (p_navigation_mesh->get_sample_partition_type() == NavigationMesh::SAMPLE_PARTITION_MONOTONE) {
748-
ERR_FAIL_COND(!rcBuildRegionsMonotone(&ctx, *chf, 0, cfg.minRegionArea, cfg.mergeRegionArea));
754+
ERR_FAIL_COND(!rcBuildRegionsMonotone(&ctx, *chf, cfg.borderSize, cfg.minRegionArea, cfg.mergeRegionArea));
749755
} else {
750-
ERR_FAIL_COND(!rcBuildLayerRegions(&ctx, *chf, 0, cfg.minRegionArea));
756+
ERR_FAIL_COND(!rcBuildLayerRegions(&ctx, *chf, cfg.borderSize, cfg.minRegionArea));
751757
}
752758

753759
bake_state = "Creating contours..."; // step #8

scene/resources/navigation_mesh.cpp

+14-1
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,15 @@ float NavigationMesh::get_cell_height() const {
153153
return cell_height;
154154
}
155155

156+
void NavigationMesh::set_border_size(float p_value) {
157+
ERR_FAIL_COND(p_value < 0);
158+
border_size = p_value;
159+
}
160+
161+
float NavigationMesh::get_border_size() const {
162+
return border_size;
163+
}
164+
156165
void NavigationMesh::set_agent_height(float p_value) {
157166
ERR_FAIL_COND(p_value < 0);
158167
agent_height = p_value;
@@ -464,6 +473,9 @@ void NavigationMesh::_bind_methods() {
464473
ClassDB::bind_method(D_METHOD("set_cell_height", "cell_height"), &NavigationMesh::set_cell_height);
465474
ClassDB::bind_method(D_METHOD("get_cell_height"), &NavigationMesh::get_cell_height);
466475

476+
ClassDB::bind_method(D_METHOD("set_border_size", "border_size"), &NavigationMesh::set_border_size);
477+
ClassDB::bind_method(D_METHOD("get_border_size"), &NavigationMesh::get_border_size);
478+
467479
ClassDB::bind_method(D_METHOD("set_agent_height", "agent_height"), &NavigationMesh::set_agent_height);
468480
ClassDB::bind_method(D_METHOD("get_agent_height"), &NavigationMesh::get_agent_height);
469481

@@ -537,9 +549,10 @@ void NavigationMesh::_bind_methods() {
537549
ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry_source_geometry_mode", PROPERTY_HINT_ENUM, "Root Node Children,Group With Children,Group Explicit"), "set_source_geometry_mode", "get_source_geometry_mode");
538550
ADD_PROPERTY(PropertyInfo(Variant::STRING, "geometry_source_group_name"), "set_source_group_name", "get_source_group_name");
539551
ADD_PROPERTY_DEFAULT("geometry_source_group_name", StringName("navigation_mesh_source_group"));
540-
ADD_GROUP("Cells", "cell_");
552+
ADD_GROUP("Cells", "");
541553
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell_size", PROPERTY_HINT_RANGE, "0.01,500.0,0.01,or_greater,suffix:m"), "set_cell_size", "get_cell_size");
542554
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell_height", PROPERTY_HINT_RANGE, "0.01,500.0,0.01,or_greater,suffix:m"), "set_cell_height", "get_cell_height");
555+
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "border_size", PROPERTY_HINT_RANGE, "0.0,500.0,0.01,or_greater,suffix:m"), "set_border_size", "get_border_size");
543556
ADD_GROUP("Agents", "agent_");
544557
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "agent_height", PROPERTY_HINT_RANGE, "0.0,500.0,0.01,or_greater,suffix:m"), "set_agent_height", "get_agent_height");
545558
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "agent_radius", PROPERTY_HINT_RANGE, "0.0,500.0,0.01,or_greater,suffix:m"), "set_agent_radius", "get_agent_radius");

scene/resources/navigation_mesh.h

+4
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ class NavigationMesh : public Resource {
8080
protected:
8181
float cell_size = 0.25f; // Must match ProjectSettings default 3D cell_size and NavigationServer NavMap cell_size.
8282
float cell_height = 0.25f; // Must match ProjectSettings default 3D cell_height and NavigationServer NavMap cell_height.
83+
float border_size = 0.0f;
8384
float agent_height = 1.5f;
8485
float agent_radius = 0.5f;
8586
float agent_max_climb = 0.25f;
@@ -131,6 +132,9 @@ class NavigationMesh : public Resource {
131132
void set_cell_height(float p_value);
132133
float get_cell_height() const;
133134

135+
void set_border_size(float p_value);
136+
float get_border_size() const;
137+
134138
void set_agent_height(float p_value);
135139
float get_agent_height() const;
136140

0 commit comments

Comments
 (0)