From 0c4d99f4fdcee4b1b6c289c83fb448262e60974b Mon Sep 17 00:00:00 2001
From: smix8 <52464204+smix8@users.noreply.github.com>
Date: Thu, 23 Jun 2022 13:54:41 +0200
Subject: Implement NavigationMesh bake area
Adds two new properties to NavigationMesh resources to restrict the navmesh baking to an area enclosed by an AABB with volume.
---
doc/classes/NavigationMesh.xml | 6 ++++++
modules/navigation/navigation_mesh_generator.cpp | 15 +++++++++++++++
scene/resources/navigation_mesh.cpp | 24 ++++++++++++++++++++++++
scene/resources/navigation_mesh.h | 8 ++++++++
4 files changed, 53 insertions(+)
diff --git a/doc/classes/NavigationMesh.xml b/doc/classes/NavigationMesh.xml
index 3c18b56658..966f964b12 100644
--- a/doc/classes/NavigationMesh.xml
+++ b/doc/classes/NavigationMesh.xml
@@ -107,6 +107,12 @@
The maximum allowed length for contour edges along the border of the mesh.
[b]Note:[/b] While baking, this value will be rounded up to the nearest multiple of [member cell_size].
+
+ If the baking [AABB] has a volume the navigation mesh baking will be restricted to its enclosing area.
+
+
+ The position offset applied to the [member filter_baking_aabb] [AABB].
+
If [code]true[/code], marks spans that are ledges as non-walkable.
diff --git a/modules/navigation/navigation_mesh_generator.cpp b/modules/navigation/navigation_mesh_generator.cpp
index e430f5fd59..c620776dc6 100644
--- a/modules/navigation/navigation_mesh_generator.cpp
+++ b/modules/navigation/navigation_mesh_generator.cpp
@@ -482,6 +482,21 @@ void NavigationMeshGenerator::_build_recast_navigation_mesh(
cfg.bmax[1] = bmax[1];
cfg.bmax[2] = bmax[2];
+ AABB baking_aabb = p_nav_mesh->get_filter_baking_aabb();
+
+ bool aabb_has_no_volume = baking_aabb.has_no_volume();
+
+ if (!aabb_has_no_volume) {
+ Vector3 baking_aabb_offset = p_nav_mesh->get_filter_baking_aabb_offset();
+
+ cfg.bmin[0] = baking_aabb.position[0] + baking_aabb_offset.x;
+ cfg.bmin[1] = baking_aabb.position[1] + baking_aabb_offset.y;
+ cfg.bmin[2] = baking_aabb.position[2] + baking_aabb_offset.z;
+ cfg.bmax[0] = cfg.bmin[0] + baking_aabb.size[0];
+ cfg.bmax[1] = cfg.bmin[1] + baking_aabb.size[1];
+ cfg.bmax[2] = cfg.bmin[2] + baking_aabb.size[2];
+ }
+
#ifdef TOOLS_ENABLED
if (ep) {
ep->step(TTR("Calculating grid size..."), 2);
diff --git a/scene/resources/navigation_mesh.cpp b/scene/resources/navigation_mesh.cpp
index 784ecc3a4d..a808ead66b 100644
--- a/scene/resources/navigation_mesh.cpp
+++ b/scene/resources/navigation_mesh.cpp
@@ -272,6 +272,24 @@ bool NavigationMesh::get_filter_walkable_low_height_spans() const {
return filter_walkable_low_height_spans;
}
+void NavigationMesh::set_filter_baking_aabb(const AABB &p_aabb) {
+ filter_baking_aabb = p_aabb;
+ notify_property_list_changed();
+}
+
+AABB NavigationMesh::get_filter_baking_aabb() const {
+ return filter_baking_aabb;
+}
+
+void NavigationMesh::set_filter_baking_aabb_offset(const Vector3 &p_aabb_offset) {
+ filter_baking_aabb_offset = p_aabb_offset;
+ notify_property_list_changed();
+}
+
+Vector3 NavigationMesh::get_filter_baking_aabb_offset() const {
+ return filter_baking_aabb_offset;
+}
+
void NavigationMesh::set_vertices(const Vector &p_vertices) {
vertices = p_vertices;
notify_property_list_changed();
@@ -469,6 +487,10 @@ void NavigationMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_filter_walkable_low_height_spans", "filter_walkable_low_height_spans"), &NavigationMesh::set_filter_walkable_low_height_spans);
ClassDB::bind_method(D_METHOD("get_filter_walkable_low_height_spans"), &NavigationMesh::get_filter_walkable_low_height_spans);
+ ClassDB::bind_method(D_METHOD("set_filter_baking_aabb", "baking_aabb"), &NavigationMesh::set_filter_baking_aabb);
+ ClassDB::bind_method(D_METHOD("get_filter_baking_aabb"), &NavigationMesh::get_filter_baking_aabb);
+ ClassDB::bind_method(D_METHOD("set_filter_baking_aabb_offset", "baking_aabb_offset"), &NavigationMesh::set_filter_baking_aabb_offset);
+ ClassDB::bind_method(D_METHOD("get_filter_baking_aabb_offset"), &NavigationMesh::get_filter_baking_aabb_offset);
ClassDB::bind_method(D_METHOD("set_vertices", "vertices"), &NavigationMesh::set_vertices);
ClassDB::bind_method(D_METHOD("get_vertices"), &NavigationMesh::get_vertices);
@@ -516,6 +538,8 @@ void NavigationMesh::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_low_hanging_obstacles"), "set_filter_low_hanging_obstacles", "get_filter_low_hanging_obstacles");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_ledge_spans"), "set_filter_ledge_spans", "get_filter_ledge_spans");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_walkable_low_height_spans"), "set_filter_walkable_low_height_spans", "get_filter_walkable_low_height_spans");
+ ADD_PROPERTY(PropertyInfo(Variant::AABB, "filter_baking_aabb"), "set_filter_baking_aabb", "get_filter_baking_aabb");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "filter_baking_aabb_offset"), "set_filter_baking_aabb_offset", "get_filter_baking_aabb_offset");
BIND_ENUM_CONSTANT(SAMPLE_PARTITION_WATERSHED);
BIND_ENUM_CONSTANT(SAMPLE_PARTITION_MONOTONE);
diff --git a/scene/resources/navigation_mesh.h b/scene/resources/navigation_mesh.h
index 93c1c11876..40b275c792 100644
--- a/scene/resources/navigation_mesh.h
+++ b/scene/resources/navigation_mesh.h
@@ -117,6 +117,8 @@ protected:
bool filter_low_hanging_obstacles = false;
bool filter_ledge_spans = false;
bool filter_walkable_low_height_spans = false;
+ AABB filter_baking_aabb;
+ Vector3 filter_baking_aabb_offset;
public:
// Recast settings
@@ -186,6 +188,12 @@ public:
void set_filter_walkable_low_height_spans(bool p_value);
bool get_filter_walkable_low_height_spans() const;
+ void set_filter_baking_aabb(const AABB &p_aabb);
+ AABB get_filter_baking_aabb() const;
+
+ void set_filter_baking_aabb_offset(const Vector3 &p_aabb_offset);
+ Vector3 get_filter_baking_aabb_offset() const;
+
void create_from_mesh(const Ref &p_mesh);
void set_vertices(const Vector &p_vertices);
--
cgit v1.2.3