Bläddra i källkod

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.
smix8 3 år sedan
förälder
incheckning
0c4d99f4fd

+ 6 - 0
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].
 		</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

@@ -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);

+ 24 - 0
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<Vector3> &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);

+ 8 - 0
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<Mesh> &p_mesh);
 
 	void set_vertices(const Vector<Vector3> &p_vertices);