Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add NavigationMesh border_size property for tile baking #87378

Merged
merged 1 commit into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions doc/classes/NavigationMesh.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@
The distance to erode/shrink the walkable area of the heightfield away from obstructions.
[b]Note:[/b] While baking, this value will be rounded up to the nearest multiple of [member cell_size].
</member>
<member name="border_size" type="float" setter="set_border_size" getter="get_border_size" default="0.0">
The size of the non-navigable border around the bake bounding area.
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].
[b]Note:[/b] While baking and not zero, this value will be rounded up to the nearest multiple of [member cell_size].
</member>
<member name="cell_height" type="float" setter="set_cell_height" getter="get_cell_height" default="0.25">
The cell height used to rasterize the navigation mesh vertices on the Y axis. Must match with the cell height on the navigation map.
</member>
Expand Down
12 changes: 9 additions & 3 deletions modules/navigation/nav_mesh_generator_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,9 @@ void NavMeshGenerator3D::generator_bake_from_source_geometry_data(Ref<Navigation

cfg.cs = p_navigation_mesh->get_cell_size();
cfg.ch = p_navigation_mesh->get_cell_height();
if (p_navigation_mesh->get_border_size() > 0.0) {
cfg.borderSize = (int)Math::ceil(p_navigation_mesh->get_border_size() / cfg.cs);
}
cfg.walkableSlopeAngle = p_navigation_mesh->get_agent_max_slope();
cfg.walkableHeight = (int)Math::ceil(p_navigation_mesh->get_agent_height() / cfg.ch);
cfg.walkableClimb = (int)Math::floor(p_navigation_mesh->get_agent_max_climb() / cfg.ch);
Expand All @@ -637,6 +640,9 @@ void NavMeshGenerator3D::generator_bake_from_source_geometry_data(Ref<Navigation
cfg.detailSampleDist = MAX(p_navigation_mesh->get_cell_size() * p_navigation_mesh->get_detail_sample_distance(), 0.1f);
cfg.detailSampleMaxError = p_navigation_mesh->get_cell_height() * p_navigation_mesh->get_detail_sample_max_error();

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())) {
WARN_PRINT("Property border_size is ceiled to cell_size voxel units and loses precision.");
}
if (!Math::is_equal_approx((float)cfg.walkableHeight * cfg.ch, p_navigation_mesh->get_agent_height())) {
WARN_PRINT("Property agent_height is ceiled to cell_height voxel units and loses precision.");
}
Expand Down Expand Up @@ -738,11 +744,11 @@ void NavMeshGenerator3D::generator_bake_from_source_geometry_data(Ref<Navigation

if (p_navigation_mesh->get_sample_partition_type() == NavigationMesh::SAMPLE_PARTITION_WATERSHED) {
ERR_FAIL_COND(!rcBuildDistanceField(&ctx, *chf));
ERR_FAIL_COND(!rcBuildRegions(&ctx, *chf, 0, cfg.minRegionArea, cfg.mergeRegionArea));
ERR_FAIL_COND(!rcBuildRegions(&ctx, *chf, cfg.borderSize, cfg.minRegionArea, cfg.mergeRegionArea));
} else if (p_navigation_mesh->get_sample_partition_type() == NavigationMesh::SAMPLE_PARTITION_MONOTONE) {
ERR_FAIL_COND(!rcBuildRegionsMonotone(&ctx, *chf, 0, cfg.minRegionArea, cfg.mergeRegionArea));
ERR_FAIL_COND(!rcBuildRegionsMonotone(&ctx, *chf, cfg.borderSize, cfg.minRegionArea, cfg.mergeRegionArea));
} else {
ERR_FAIL_COND(!rcBuildLayerRegions(&ctx, *chf, 0, cfg.minRegionArea));
ERR_FAIL_COND(!rcBuildLayerRegions(&ctx, *chf, cfg.borderSize, cfg.minRegionArea));
}

bake_state = "Creating contours..."; // step #8
Expand Down
15 changes: 14 additions & 1 deletion scene/resources/navigation_mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,15 @@ float NavigationMesh::get_cell_height() const {
return cell_height;
}

void NavigationMesh::set_border_size(float p_value) {
ERR_FAIL_COND(p_value < 0);
border_size = p_value;
}

float NavigationMesh::get_border_size() const {
return border_size;
}

void NavigationMesh::set_agent_height(float p_value) {
ERR_FAIL_COND(p_value < 0);
agent_height = p_value;
Expand Down Expand Up @@ -464,6 +473,9 @@ void NavigationMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_cell_height", "cell_height"), &NavigationMesh::set_cell_height);
ClassDB::bind_method(D_METHOD("get_cell_height"), &NavigationMesh::get_cell_height);

ClassDB::bind_method(D_METHOD("set_border_size", "border_size"), &NavigationMesh::set_border_size);
ClassDB::bind_method(D_METHOD("get_border_size"), &NavigationMesh::get_border_size);

ClassDB::bind_method(D_METHOD("set_agent_height", "agent_height"), &NavigationMesh::set_agent_height);
ClassDB::bind_method(D_METHOD("get_agent_height"), &NavigationMesh::get_agent_height);

Expand Down Expand Up @@ -537,9 +549,10 @@ void NavigationMesh::_bind_methods() {
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");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "geometry_source_group_name"), "set_source_group_name", "get_source_group_name");
ADD_PROPERTY_DEFAULT("geometry_source_group_name", StringName("navigation_mesh_source_group"));
ADD_GROUP("Cells", "cell_");
ADD_GROUP("Cells", "");
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");
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");
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");
ADD_GROUP("Agents", "agent_");
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");
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");
Expand Down
4 changes: 4 additions & 0 deletions scene/resources/navigation_mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class NavigationMesh : public Resource {
protected:
float cell_size = 0.25f; // Must match ProjectSettings default 3D cell_size and NavigationServer NavMap cell_size.
float cell_height = 0.25f; // Must match ProjectSettings default 3D cell_height and NavigationServer NavMap cell_height.
float border_size = 0.0f;
float agent_height = 1.5f;
float agent_radius = 0.5f;
float agent_max_climb = 0.25f;
Expand Down Expand Up @@ -131,6 +132,9 @@ class NavigationMesh : public Resource {
void set_cell_height(float p_value);
float get_cell_height() const;

void set_border_size(float p_value);
float get_border_size() const;

void set_agent_height(float p_value);
float get_agent_height() const;

Expand Down
Loading