Browse Source

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.

(cherry picked from commit 0c4d99f4fdcee4b1b6c289c83fb448262e60974b)
smix8 3 years ago
parent
commit
fcff804844

+ 6 - 0
doc/classes/NavigationMesh.xml

@@ -108,6 +108,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].
 		</member>
+		<member name="filter_baking_aabb" type="AABB" setter="set_filter_baking_aabb" getter="get_filter_baking_aabb" default="AABB( 0, 0, 0, 0, 0, 0 )">
+			If the baking [AABB] has a volume the navigation mesh baking will be restricted to its enclosing area.
+		</member>
+		<member name="filter_baking_aabb_offset" type="Vector3" setter="set_filter_baking_aabb_offset" getter="get_filter_baking_aabb_offset" default="Vector3( 0, 0, 0 )">
+			The position offset applied to the [member filter_baking_aabb] [AABB].
+		</member>
 		<member name="filter_ledge_spans" type="bool" setter="set_filter_ledge_spans" getter="get_filter_ledge_spans" default="false">
 			If [code]true[/code], marks spans that are ledges as non-walkable.
 		</member>

+ 15 - 0
modules/navigation/navigation_mesh_generator.cpp

@@ -459,6 +459,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_area();
+
+	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);

+ 24 - 0
scene/resources/navigation_mesh.cpp

@@ -268,6 +268,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;
+	_change_notify();
+}
+
+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;
+	_change_notify();
+}
+
+Vector3 NavigationMesh::get_filter_baking_aabb_offset() const {
+	return filter_baking_aabb_offset;
+}
+
 void NavigationMesh::set_vertices(const PoolVector<Vector3> &p_vertices) {
 	vertices = p_vertices;
 	_change_notify();
@@ -467,6 +485,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);
@@ -514,6 +536,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);

+ 8 - 0
scene/resources/navigation_mesh.h

@@ -114,6 +114,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
@@ -183,6 +185,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<Mesh> &p_mesh);
 
 	void set_vertices(const PoolVector<Vector3> &p_vertices);