Browse Source

Change GridMap navigation_layers to be per mesh_library item

Changes GridMap navigation_layers from a single bitmask for the entire GridMap to a bitmask for each item used in the mesh_library with a baked navmesh.
smix8 2 years ago
parent
commit
61f33e205c

+ 15 - 0
doc/classes/MeshLibrary.xml

@@ -59,6 +59,13 @@
 				Returns the item's name.
 			</description>
 		</method>
+		<method name="get_item_navigation_layers" qualifiers="const">
+			<return type="int" />
+			<param index="0" name="id" type="int" />
+			<description>
+				Returns the item's navigation layers bitmask.
+			</description>
+		</method>
 		<method name="get_item_navigation_mesh" qualifiers="const">
 			<return type="NavigationMesh" />
 			<param index="0" name="id" type="int" />
@@ -126,6 +133,14 @@
 				This name is shown in the editor. It can also be used to look up the item later using [method find_item_by_name].
 			</description>
 		</method>
+		<method name="set_item_navigation_layers">
+			<return type="void" />
+			<param index="0" name="id" type="int" />
+			<param index="1" name="navigation_layers" type="int" />
+			<description>
+				Sets the item's navigation layers bitmask.
+			</description>
+		</method>
 		<method name="set_item_navigation_mesh">
 			<return type="void" />
 			<param index="0" name="id" type="int" />

+ 1 - 19
modules/gridmap/doc_classes/GridMap.xml

@@ -89,13 +89,6 @@
 				Returns an array of [Transform3D] and [Mesh] references corresponding to the non-empty cells in the grid. The transforms are specified in local space.
 			</description>
 		</method>
-		<method name="get_navigation_layer_value" qualifiers="const">
-			<return type="bool" />
-			<param index="0" name="layer_number" type="int" />
-			<description>
-				Returns whether or not the specified layer of the [member navigation_layers] bitmask is enabled, given a [code]layer_number[/code] between 1 and 32.
-			</description>
-		</method>
 		<method name="get_navigation_map" qualifiers="const">
 			<return type="RID" />
 			<description>
@@ -179,14 +172,6 @@
 				Based on [code]value[/code], enables or disables the specified layer in the [member collision_mask], given a [code]layer_number[/code] between 1 and 32.
 			</description>
 		</method>
-		<method name="set_navigation_layer_value">
-			<return type="void" />
-			<param index="0" name="layer_number" type="int" />
-			<param index="1" name="value" type="bool" />
-			<description>
-				Based on [code]value[/code], enables or disables the specified layer in the [member navigation_layers] bitmask, given a [code]layer_number[/code] between 1 and 32.
-			</description>
-		</method>
 		<method name="set_navigation_map">
 			<return type="void" />
 			<param index="0" name="navigation_map" type="RID" />
@@ -197,7 +182,7 @@
 	</methods>
 	<members>
 		<member name="bake_navigation" type="bool" setter="set_bake_navigation" getter="is_baking_navigation" default="false">
-			If [code]true[/code], this GridMap bakes a navigation region.
+			If [code]true[/code], this GridMap creates a navigation region for each cell that uses a [member mesh_library] item with a navigation mesh. The created navigation region will use the navigation layers bitmask assigned to the [MeshLibrary]'s item.
 		</member>
 		<member name="cell_center_x" type="bool" setter="set_center_x" getter="get_center_x" default="true">
 			If [code]true[/code], grid items are centered on the X axis.
@@ -232,9 +217,6 @@
 		<member name="mesh_library" type="MeshLibrary" setter="set_mesh_library" getter="get_mesh_library">
 			The assigned [MeshLibrary].
 		</member>
-		<member name="navigation_layers" type="int" setter="set_navigation_layers" getter="get_navigation_layers" default="1">
-			A bitmask determining all navigation layers the GridMap generated navigation regions belong to. These navigation layers can be checked upon when requesting a path with [method NavigationServer3D.map_get_path].
-		</member>
 		<member name="physics_material" type="PhysicsMaterial" setter="set_physics_material" getter="get_physics_material">
 			Overrides the default friction and bounce physics properties for the whole [GridMap].
 		</member>

+ 3 - 36
modules/gridmap/grid_map.cpp

@@ -256,33 +256,6 @@ RID GridMap::get_navigation_map() const {
 	return RID();
 }
 
-void GridMap::set_navigation_layers(uint32_t p_navigation_layers) {
-	navigation_layers = p_navigation_layers;
-	_recreate_octant_data();
-}
-
-uint32_t GridMap::get_navigation_layers() const {
-	return navigation_layers;
-}
-
-void GridMap::set_navigation_layer_value(int p_layer_number, bool p_value) {
-	ERR_FAIL_COND_MSG(p_layer_number < 1, "Navigation layer number must be between 1 and 32 inclusive.");
-	ERR_FAIL_COND_MSG(p_layer_number > 32, "Navigation layer number must be between 1 and 32 inclusive.");
-	uint32_t _navigation_layers = get_navigation_layers();
-	if (p_value) {
-		_navigation_layers |= 1 << (p_layer_number - 1);
-	} else {
-		_navigation_layers &= ~(1 << (p_layer_number - 1));
-	}
-	set_navigation_layers(_navigation_layers);
-}
-
-bool GridMap::get_navigation_layer_value(int p_layer_number) const {
-	ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Navigation layer number must be between 1 and 32 inclusive.");
-	ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Navigation layer number must be between 1 and 32 inclusive.");
-	return get_navigation_layers() & (1 << (p_layer_number - 1));
-}
-
 void GridMap::set_mesh_library(const Ref<MeshLibrary> &p_mesh_library) {
 	if (!mesh_library.is_null()) {
 		mesh_library->unregister_owner(this);
@@ -663,11 +636,12 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
 		if (navigation_mesh.is_valid()) {
 			Octant::NavigationCell nm;
 			nm.xform = xform * mesh_library->get_item_navigation_mesh_transform(c.item);
+			nm.navigation_layers = mesh_library->get_item_navigation_layers(c.item);
 
 			if (bake_navigation) {
 				RID region = NavigationServer3D::get_singleton()->region_create();
 				NavigationServer3D::get_singleton()->region_set_owner_id(region, get_instance_id());
-				NavigationServer3D::get_singleton()->region_set_navigation_layers(region, navigation_layers);
+				NavigationServer3D::get_singleton()->region_set_navigation_layers(region, nm.navigation_layers);
 				NavigationServer3D::get_singleton()->region_set_navigation_mesh(region, navigation_mesh);
 				NavigationServer3D::get_singleton()->region_set_transform(region, get_global_transform() * nm.xform);
 				if (is_inside_tree()) {
@@ -792,7 +766,7 @@ void GridMap::_octant_enter_world(const OctantKey &p_key) {
 				if (navigation_mesh.is_valid()) {
 					RID region = NavigationServer3D::get_singleton()->region_create();
 					NavigationServer3D::get_singleton()->region_set_owner_id(region, get_instance_id());
-					NavigationServer3D::get_singleton()->region_set_navigation_layers(region, navigation_layers);
+					NavigationServer3D::get_singleton()->region_set_navigation_layers(region, F.value.navigation_layers);
 					NavigationServer3D::get_singleton()->region_set_navigation_mesh(region, navigation_mesh);
 					NavigationServer3D::get_singleton()->region_set_transform(region, get_global_transform() * F.value.xform);
 					if (map_override.is_valid()) {
@@ -1070,12 +1044,6 @@ void GridMap::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_navigation_map", "navigation_map"), &GridMap::set_navigation_map);
 	ClassDB::bind_method(D_METHOD("get_navigation_map"), &GridMap::get_navigation_map);
 
-	ClassDB::bind_method(D_METHOD("set_navigation_layers", "layers"), &GridMap::set_navigation_layers);
-	ClassDB::bind_method(D_METHOD("get_navigation_layers"), &GridMap::get_navigation_layers);
-
-	ClassDB::bind_method(D_METHOD("set_navigation_layer_value", "layer_number", "value"), &GridMap::set_navigation_layer_value);
-	ClassDB::bind_method(D_METHOD("get_navigation_layer_value", "layer_number"), &GridMap::get_navigation_layer_value);
-
 	ClassDB::bind_method(D_METHOD("set_mesh_library", "mesh_library"), &GridMap::set_mesh_library);
 	ClassDB::bind_method(D_METHOD("get_mesh_library"), &GridMap::get_mesh_library);
 
@@ -1135,7 +1103,6 @@ void GridMap::_bind_methods() {
 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_priority"), "set_collision_priority", "get_collision_priority");
 	ADD_GROUP("Navigation", "");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bake_navigation"), "set_bake_navigation", "is_baking_navigation");
-	ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
 
 	BIND_CONSTANT(INVALID_CELL_ITEM);
 

+ 1 - 6
modules/gridmap/grid_map.h

@@ -99,6 +99,7 @@ class GridMap : public Node3D {
 			RID region;
 			Transform3D xform;
 			RID navigation_mesh_debug_instance;
+			uint32_t navigation_layers = 1;
 		};
 
 		struct MultimeshInstance {
@@ -255,12 +256,6 @@ public:
 	void set_navigation_map(RID p_navigation_map);
 	RID get_navigation_map() const;
 
-	void set_navigation_layers(uint32_t p_navigation_layers);
-	uint32_t get_navigation_layers() const;
-
-	void set_navigation_layer_value(int p_layer_number, bool p_value);
-	bool get_navigation_layer_value(int p_layer_number) const;
-
 	void set_mesh_library(const Ref<MeshLibrary> &p_mesh_library);
 	Ref<MeshLibrary> get_mesh_library() const;
 

+ 21 - 0
scene/resources/mesh_library.cpp

@@ -67,6 +67,8 @@ bool MeshLibrary::_set(const StringName &p_name, const Variant &p_value) {
 		} else if (what == "navmesh_transform") { // Renamed in 4.0 beta 9.
 			set_item_navigation_mesh_transform(idx, p_value);
 #endif // DISABLE_DEPRECATED
+		} else if (what == "navigation_layers") {
+			set_item_navigation_layers(idx, p_value);
 		} else {
 			return false;
 		}
@@ -101,6 +103,8 @@ bool MeshLibrary::_get(const StringName &p_name, Variant &r_ret) const {
 	} else if (what == "navmesh_transform") { // Renamed in 4.0 beta 9.
 		r_ret = get_item_navigation_mesh_transform(idx);
 #endif // DISABLE_DEPRECATED
+	} else if (what == "navigation_layers") {
+		r_ret = get_item_navigation_layers(idx);
 	} else if (what == "preview") {
 		r_ret = get_item_preview(idx);
 	} else {
@@ -119,6 +123,7 @@ void MeshLibrary::_get_property_list(List<PropertyInfo> *p_list) const {
 		p_list->push_back(PropertyInfo(Variant::ARRAY, prop_name + PNAME("shapes")));
 		p_list->push_back(PropertyInfo(Variant::OBJECT, prop_name + PNAME("navigation_mesh"), PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh"));
 		p_list->push_back(PropertyInfo(Variant::TRANSFORM3D, prop_name + PNAME("navigation_mesh_transform"), PROPERTY_HINT_NONE, "suffix:m"));
+		p_list->push_back(PropertyInfo(Variant::INT, prop_name + PNAME("navigation_layers"), PROPERTY_HINT_LAYERS_3D_NAVIGATION));
 		p_list->push_back(PropertyInfo(Variant::OBJECT, prop_name + PNAME("preview"), PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT));
 	}
 }
@@ -179,6 +184,15 @@ void MeshLibrary::set_item_navigation_mesh_transform(int p_item, const Transform
 	notify_property_list_changed();
 }
 
+void MeshLibrary::set_item_navigation_layers(int p_item, uint32_t p_navigation_layers) {
+	ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
+	item_map[p_item].navigation_layers = p_navigation_layers;
+	notify_property_list_changed();
+	notify_change_to_owners();
+	emit_changed();
+	notify_property_list_changed();
+}
+
 void MeshLibrary::set_item_preview(int p_item, const Ref<Texture2D> &p_preview) {
 	ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
 	item_map[p_item].preview = p_preview;
@@ -216,6 +230,11 @@ Transform3D MeshLibrary::get_item_navigation_mesh_transform(int p_item) const {
 	return item_map[p_item].navigation_mesh_transform;
 }
 
+uint32_t MeshLibrary::get_item_navigation_layers(int p_item) const {
+	ERR_FAIL_COND_V_MSG(!item_map.has(p_item), 0, "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
+	return item_map[p_item].navigation_layers;
+}
+
 Ref<Texture2D> MeshLibrary::get_item_preview(int p_item) const {
 	ERR_FAIL_COND_V_MSG(!item_map.has(p_item), Ref<Texture2D>(), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
 	return item_map[p_item].preview;
@@ -328,6 +347,7 @@ void MeshLibrary::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_item_mesh_transform", "id", "mesh_transform"), &MeshLibrary::set_item_mesh_transform);
 	ClassDB::bind_method(D_METHOD("set_item_navigation_mesh", "id", "navigation_mesh"), &MeshLibrary::set_item_navigation_mesh);
 	ClassDB::bind_method(D_METHOD("set_item_navigation_mesh_transform", "id", "navigation_mesh"), &MeshLibrary::set_item_navigation_mesh_transform);
+	ClassDB::bind_method(D_METHOD("set_item_navigation_layers", "id", "navigation_layers"), &MeshLibrary::set_item_navigation_layers);
 	ClassDB::bind_method(D_METHOD("set_item_shapes", "id", "shapes"), &MeshLibrary::_set_item_shapes);
 	ClassDB::bind_method(D_METHOD("set_item_preview", "id", "texture"), &MeshLibrary::set_item_preview);
 	ClassDB::bind_method(D_METHOD("get_item_name", "id"), &MeshLibrary::get_item_name);
@@ -335,6 +355,7 @@ void MeshLibrary::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_item_mesh_transform", "id"), &MeshLibrary::get_item_mesh_transform);
 	ClassDB::bind_method(D_METHOD("get_item_navigation_mesh", "id"), &MeshLibrary::get_item_navigation_mesh);
 	ClassDB::bind_method(D_METHOD("get_item_navigation_mesh_transform", "id"), &MeshLibrary::get_item_navigation_mesh_transform);
+	ClassDB::bind_method(D_METHOD("get_item_navigation_layers", "id"), &MeshLibrary::get_item_navigation_layers);
 	ClassDB::bind_method(D_METHOD("get_item_shapes", "id"), &MeshLibrary::_get_item_shapes);
 	ClassDB::bind_method(D_METHOD("get_item_preview", "id"), &MeshLibrary::get_item_preview);
 	ClassDB::bind_method(D_METHOD("remove_item", "id"), &MeshLibrary::remove_item);

+ 3 - 0
scene/resources/mesh_library.h

@@ -54,6 +54,7 @@ public:
 		Ref<Texture2D> preview;
 		Ref<NavigationMesh> navigation_mesh;
 		Transform3D navigation_mesh_transform;
+		uint32_t navigation_layers = 1;
 	};
 
 	RBMap<int, Item> item_map;
@@ -76,6 +77,7 @@ public:
 	void set_item_mesh_transform(int p_item, const Transform3D &p_transform);
 	void set_item_navigation_mesh(int p_item, const Ref<NavigationMesh> &p_navigation_mesh);
 	void set_item_navigation_mesh_transform(int p_item, const Transform3D &p_transform);
+	void set_item_navigation_layers(int p_item, uint32_t p_navigation_layers);
 	void set_item_shapes(int p_item, const Vector<ShapeData> &p_shapes);
 	void set_item_preview(int p_item, const Ref<Texture2D> &p_preview);
 	String get_item_name(int p_item) const;
@@ -83,6 +85,7 @@ public:
 	Transform3D get_item_mesh_transform(int p_item) const;
 	Ref<NavigationMesh> get_item_navigation_mesh(int p_item) const;
 	Transform3D get_item_navigation_mesh_transform(int p_item) const;
+	uint32_t get_item_navigation_layers(int p_item) const;
 	Vector<ShapeData> get_item_shapes(int p_item) const;
 	Ref<Texture2D> get_item_preview(int p_item) const;