Pārlūkot izejas kodu

Improve NavigationMesh typing, parameter validation and documentation

Haoyu Qiu 4 gadi atpakaļ
vecāks
revīzija
f4a6737eed

+ 74 - 9
doc/classes/NavigationMesh.xml

@@ -1,8 +1,10 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <class name="NavigationMesh" inherits="Resource" version="3.4">
 	<brief_description>
+		A mesh to approximate the walkable areas and obstacles.
 	</brief_description>
 	<description>
+		A navigation mesh is a collection of polygons that define which areas of an environment are traversable to aid agents in pathfinding through complicated spaces.
 	</description>
 	<tutorials>
 		<link title="3D Navmesh Demo">https://godotengine.org/asset-library/asset/124</link>
@@ -12,39 +14,46 @@
 			<return type="void" />
 			<argument index="0" name="polygon" type="PoolIntArray" />
 			<description>
+				Adds a polygon using the indices of the vertices you get when calling [method get_vertices].
 			</description>
 		</method>
 		<method name="clear_polygons">
 			<return type="void" />
 			<description>
+				Clears the array of polygons, but it doesn't clear the array of vertices.
 			</description>
 		</method>
 		<method name="create_from_mesh">
 			<return type="void" />
 			<argument index="0" name="mesh" type="Mesh" />
 			<description>
+				Initializes the navigation mesh by setting the vertices and indices according to a [Mesh].
 			</description>
 		</method>
 		<method name="get_collision_mask_bit" qualifiers="const">
 			<return type="bool" />
 			<argument index="0" name="bit" type="int" />
 			<description>
+				Returns whether the specified [code]bit[/code] of the [member geometry/collision_mask] is set.
 			</description>
 		</method>
 		<method name="get_polygon">
 			<return type="PoolIntArray" />
 			<argument index="0" name="idx" type="int" />
 			<description>
+				Returns a [PoolIntArray] containing the indices of the vertices of a created polygon.
 			</description>
 		</method>
 		<method name="get_polygon_count" qualifiers="const">
 			<return type="int" />
 			<description>
+				Returns the number of polygons in the navigation mesh.
 			</description>
 		</method>
 		<method name="get_vertices" qualifiers="const">
 			<return type="PoolVector3Array" />
 			<description>
+				Returns a [PoolVector3Array] containing all the vertices being used to create the polygons.
 			</description>
 		</method>
 		<method name="set_collision_mask_bit">
@@ -52,71 +61,127 @@
 			<argument index="0" name="bit" type="int" />
 			<argument index="1" name="value" type="bool" />
 			<description>
+				If [code]value[/code] is [code]true[/code], sets the specified [code]bit[/code] in the [member geometry/collision_mask].
+				If [code]value[/code] is [code]false[/code], clears the specified [code]bit[/code] in the [member geometry/collision_mask].
 			</description>
 		</method>
 		<method name="set_vertices">
 			<return type="void" />
 			<argument index="0" name="vertices" type="PoolVector3Array" />
 			<description>
+				Sets the vertices that can be then indexed to create polygons with the [method add_polygon] method.
 			</description>
 		</method>
 	</methods>
 	<members>
 		<member name="agent/height" type="float" setter="set_agent_height" getter="get_agent_height" default="2.0">
+			The minimum floor to ceiling height that will still allow the floor area to be considered walkable.
+			[b]Note:[/b] While baking, this value will be rounded up to the nearest multiple of [member cell/height].
 		</member>
 		<member name="agent/max_climb" type="float" setter="set_agent_max_climb" getter="get_agent_max_climb" default="0.9">
+			The minimum ledge height that is considered to still be traversable.
+			[b]Note:[/b] While baking, this value will be rounded down to the nearest multiple of [member cell/height].
 		</member>
 		<member name="agent/max_slope" type="float" setter="set_agent_max_slope" getter="get_agent_max_slope" default="45.0">
+			The maximum slope that is considered walkable, in degrees.
 		</member>
 		<member name="agent/radius" type="float" setter="set_agent_radius" getter="get_agent_radius" default="0.6">
+			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="cell/height" type="float" setter="set_cell_height" getter="get_cell_height" default="0.2">
+			The Y axis cell size to use for fields.
 		</member>
 		<member name="cell/size" type="float" setter="set_cell_size" getter="get_cell_size" default="0.3">
+			The XZ plane cell size to use for fields.
 		</member>
 		<member name="detail/sample_distance" type="float" setter="set_detail_sample_distance" getter="get_detail_sample_distance" default="6.0">
+			The sampling distance to use when generating the detail mesh, in cell unit.
 		</member>
 		<member name="detail/sample_max_error" type="float" setter="set_detail_sample_max_error" getter="get_detail_sample_max_error" default="1.0">
+			The maximum distance the detail mesh surface should deviate from heightfield, in cell unit.
 		</member>
 		<member name="edge/max_error" type="float" setter="set_edge_max_error" getter="get_edge_max_error" default="1.3">
+			The maximum distance a simplfied contour's border edges should deviate the original raw contour.
 		</member>
 		<member name="edge/max_length" type="float" setter="set_edge_max_length" getter="get_edge_max_length" default="12.0">
+			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/filter_walkable_low_height_spans" type="bool" setter="set_filter_walkable_low_height_spans" getter="get_filter_walkable_low_height_spans" default="false">
+			If [code]true[/code], marks walkable spans as not walkable if the clearance above the span is less than [member agent/height].
 		</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>
 		<member name="filter/low_hanging_obstacles" type="bool" setter="set_filter_low_hanging_obstacles" getter="get_filter_low_hanging_obstacles" default="false">
+			If [code]true[/code], marks non-walkable spans as walkable if their maximum is within [member agent/max_climb] of a walkable neighbor.
 		</member>
 		<member name="geometry/collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask">
+			The physics layers to scan for static colliders.
+			Only used when [member geometry/parsed_geometry_type] is [constant PARSED_GEOMETRY_STATIC_COLLIDERS] or [constant PARSED_GEOMETRY_BOTH].
 		</member>
-		<member name="geometry/parsed_geometry_type" type="int" setter="set_parsed_geometry_type" getter="get_parsed_geometry_type" default="0">
+		<member name="geometry/parsed_geometry_type" type="int" setter="set_parsed_geometry_type" getter="get_parsed_geometry_type" enum="NavigationMesh.ParsedGeometryType" default="0">
+			Determines which type of nodes will be parsed as geometry. See [enum ParsedGeometryType] for possible values.
 		</member>
-		<member name="geometry/source_geometry_mode" type="int" setter="set_source_geometry_mode" getter="get_source_geometry_mode" default="0">
+		<member name="geometry/source_geometry_mode" type="int" setter="set_source_geometry_mode" getter="get_source_geometry_mode" enum="NavigationMesh.SourceGeometryMode" default="0">
+			The source of the geometry used when baking. See [enum SourceGeometryMode] for possible values.
 		</member>
 		<member name="geometry/source_group_name" type="String" setter="set_source_group_name" getter="get_source_group_name">
+			The name of the group to scan for geometry.
+			Only used when [member geometry/source_geometry_mode] is [constant SOURCE_GEOMETRY_GROUPS_WITH_CHILDREN] or [constant SOURCE_GEOMETRY_GROUPS_EXPLICIT].
 		</member>
 		<member name="polygon/verts_per_poly" type="float" setter="set_verts_per_poly" getter="get_verts_per_poly" default="6.0">
+			The maximum number of vertices allowed for polygons generated during the contour to polygon conversion process.
 		</member>
 		<member name="region/merge_size" type="float" setter="set_region_merge_size" getter="get_region_merge_size" default="20.0">
+			Any regions with a size smaller than this will be merged with larger regions if possible.
+			[b]Note:[/b] This value will be squared to calculate the number of cells. For example, a value of 20 will set the number of cells to 400.
 		</member>
 		<member name="region/min_size" type="float" setter="set_region_min_size" getter="get_region_min_size" default="8.0">
+			The minimum size of a region for it to be created.
+			[b]Note:[/b] This value will be squared to calculate the minimum number of cells allowed to form isolated island areas. For example, a value of 8 will set the number of cells to 64.
 		</member>
-		<member name="sample_partition_type/sample_partition_type" type="int" setter="set_sample_partition_type" getter="get_sample_partition_type" default="0">
+		<member name="sample_partition_type/sample_partition_type" type="int" setter="set_sample_partition_type" getter="get_sample_partition_type" enum="NavigationMesh.SamplePartitionType" default="0">
+			Partitioning algorithm for creating the navigation mesh polys. See [enum SamplePartitionType] for possible values.
 		</member>
 	</members>
 	<constants>
-		<constant name="SAMPLE_PARTITION_WATERSHED" value="0">
+		<constant name="SAMPLE_PARTITION_WATERSHED" value="0" enum="SamplePartitionType">
+			Watershed partitioning. Generally the best choice if you precompute the navigation mesh, use this if you have large open areas.
 		</constant>
-		<constant name="SAMPLE_PARTITION_MONOTONE" value="1">
+		<constant name="SAMPLE_PARTITION_MONOTONE" value="1" enum="SamplePartitionType">
+			Monotone partitioning. Use this if you want fast navigation mesh generation.
 		</constant>
-		<constant name="SAMPLE_PARTITION_LAYERS" value="2">
+		<constant name="SAMPLE_PARTITION_LAYERS" value="2" enum="SamplePartitionType">
+			Layer partitioning. Good choice to use for tiled navigation mesh with medium and small sized tiles.
 		</constant>
-		<constant name="PARSED_GEOMETRY_MESH_INSTANCES" value="0">
+		<constant name="SAMPLE_PARTITION_MAX" value="3" enum="SamplePartitionType">
+			Represents the size of the [enum SamplePartitionType] enum.
 		</constant>
-		<constant name="PARSED_GEOMETRY_STATIC_COLLIDERS" value="1">
+		<constant name="PARSED_GEOMETRY_MESH_INSTANCES" value="0" enum="ParsedGeometryType">
+			Parses mesh instances as geometry. This includes [MeshInstance], [CSGShape], and [GridMap] nodes.
 		</constant>
-		<constant name="PARSED_GEOMETRY_BOTH" value="2">
+		<constant name="PARSED_GEOMETRY_STATIC_COLLIDERS" value="1" enum="ParsedGeometryType">
+			Parses [StaticBody] colliders as geometry. The collider should be in any of the layers specified by [member geometry/collision_mask].
+		</constant>
+		<constant name="PARSED_GEOMETRY_BOTH" value="2" enum="ParsedGeometryType">
+			Both [constant PARSED_GEOMETRY_MESH_INSTANCES] and [constant PARSED_GEOMETRY_STATIC_COLLIDERS].
+		</constant>
+		<constant name="PARSED_GEOMETRY_MAX" value="3" enum="ParsedGeometryType">
+			Represents the size of the [enum ParsedGeometryType] enum.
+		</constant>
+		<constant name="SOURCE_GEOMETRY_NAVMESH_CHILDREN" value="0" enum="SourceGeometryMode">
+			Scans the child nodes of [NavigationMeshInstance] recursively for geometry.
+		</constant>
+		<constant name="SOURCE_GEOMETRY_GROUPS_WITH_CHILDREN" value="1" enum="SourceGeometryMode">
+			Scans nodes in a group and their child nodes recursively for geometry. The group is specified by [member geometry/source_group_name].
+		</constant>
+		<constant name="SOURCE_GEOMETRY_GROUPS_EXPLICIT" value="2" enum="SourceGeometryMode">
+			Uses nodes in a group for geometry. The group is specified by [member geometry/source_group_name].
+		</constant>
+		<constant name="SOURCE_GEOMETRY_MAX" value="3" enum="SourceGeometryMode">
+			Represents the size of the [enum SourceGeometryMode] enum.
 		</constant>
 	</constants>
 </class>

+ 4 - 0
doc/classes/NavigationMeshInstance.xml

@@ -1,8 +1,10 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <class name="NavigationMeshInstance" inherits="Spatial" version="3.4">
 	<brief_description>
+		Node that instances navigation meshes into a scenario.
 	</brief_description>
 	<description>
+		NavigationMeshInstance is a node that takes a [NavigationMesh] resource and adds it to the current scenario by creating an instance of it.
 	</description>
 	<tutorials>
 	</tutorials>
@@ -10,8 +12,10 @@
 	</methods>
 	<members>
 		<member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="true">
+			If [code]true[/code], the navigation mesh will be used by [Navigation].
 		</member>
 		<member name="navmesh" type="NavigationMesh" setter="set_navigation_mesh" getter="get_navigation_mesh">
+			The [NavigationMesh] resource for the instance.
 		</member>
 	</members>
 	<constants>

+ 2 - 2
modules/recast/navigation_mesh_generator.cpp

@@ -132,7 +132,7 @@ void EditorNavigationMeshGenerator::_add_faces(const PoolVector3Array &p_faces,
 	}
 }
 
-void EditorNavigationMeshGenerator::_parse_geometry(Transform p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, int p_generate_from, uint32_t p_collision_mask, bool p_recurse_children) {
+void EditorNavigationMeshGenerator::_parse_geometry(Transform p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, NavigationMesh::ParsedGeometryType p_generate_from, uint32_t p_collision_mask, bool p_recurse_children) {
 	if (Object::cast_to<MeshInstance>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) {
 		MeshInstance *mesh_instance = Object::cast_to<MeshInstance>(p_node);
 		Ref<Mesh> mesh = mesh_instance->get_mesh();
@@ -454,7 +454,7 @@ void EditorNavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p
 
 	Transform navmesh_xform = Object::cast_to<Spatial>(p_node)->get_transform().affine_inverse();
 	for (const List<Node *>::Element *E = parse_nodes.front(); E; E = E->next()) {
-		int geometry_type = p_nav_mesh->get_parsed_geometry_type();
+		NavigationMesh::ParsedGeometryType geometry_type = p_nav_mesh->get_parsed_geometry_type();
 		uint32_t collision_mask = p_nav_mesh->get_collision_mask();
 		bool recurse_children = p_nav_mesh->get_source_geometry_mode() != NavigationMesh::SOURCE_GEOMETRY_GROUPS_EXPLICIT;
 		_parse_geometry(navmesh_xform, E->get(), vertices, indices, geometry_type, collision_mask, recurse_children);

+ 1 - 1
modules/recast/navigation_mesh_generator.h

@@ -47,7 +47,7 @@ protected:
 	static void _add_vertex(const Vector3 &p_vec3, Vector<float> &p_verticies);
 	static void _add_mesh(const Ref<Mesh> &p_mesh, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices);
 	static void _add_faces(const PoolVector3Array &p_faces, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices);
-	static void _parse_geometry(Transform p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, int p_generate_from, uint32_t p_collision_mask, bool p_recurse_children);
+	static void _parse_geometry(Transform p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, NavigationMesh::ParsedGeometryType p_generate_from, uint32_t p_collision_mask, bool p_recurse_children);
 
 	static void _convert_detail_mesh_to_native_navigation_mesh(const rcPolyMeshDetail *p_detail_mesh, Ref<NavigationMesh> p_nav_mesh);
 	static void _build_recast_navigation_mesh(Ref<NavigationMesh> p_nav_mesh, EditorProgress *ep,

+ 40 - 20
scene/3d/navigation_mesh.cpp

@@ -66,22 +66,22 @@ void NavigationMesh::create_from_mesh(const Ref<Mesh> &p_mesh) {
 	}
 }
 
-void NavigationMesh::set_sample_partition_type(int p_value) {
-	ERR_FAIL_COND(p_value >= SAMPLE_PARTITION_MAX);
-	partition_type = static_cast<SamplePartitionType>(p_value);
+void NavigationMesh::set_sample_partition_type(SamplePartitionType p_value) {
+	ERR_FAIL_INDEX(p_value, SAMPLE_PARTITION_MAX);
+	partition_type = p_value;
 }
 
-int NavigationMesh::get_sample_partition_type() const {
-	return static_cast<int>(partition_type);
+NavigationMesh::SamplePartitionType NavigationMesh::get_sample_partition_type() const {
+	return partition_type;
 }
 
-void NavigationMesh::set_parsed_geometry_type(int p_value) {
-	ERR_FAIL_COND(p_value >= PARSED_GEOMETRY_MAX);
-	parsed_geometry_type = static_cast<ParsedGeometryType>(p_value);
+void NavigationMesh::set_parsed_geometry_type(ParsedGeometryType p_value) {
+	ERR_FAIL_INDEX(p_value, PARSED_GEOMETRY_MAX);
+	parsed_geometry_type = p_value;
 	_change_notify();
 }
 
-int NavigationMesh::get_parsed_geometry_type() const {
+NavigationMesh::ParsedGeometryType NavigationMesh::get_parsed_geometry_type() const {
 	return parsed_geometry_type;
 }
 
@@ -109,13 +109,13 @@ bool NavigationMesh::get_collision_mask_bit(int p_bit) const {
 	return get_collision_mask() & (1 << p_bit);
 }
 
-void NavigationMesh::set_source_geometry_mode(int p_geometry_mode) {
+void NavigationMesh::set_source_geometry_mode(SourceGeometryMode p_geometry_mode) {
 	ERR_FAIL_INDEX(p_geometry_mode, SOURCE_GEOMETRY_MAX);
-	source_geometry_mode = static_cast<SourceGeometryMode>(p_geometry_mode);
+	source_geometry_mode = p_geometry_mode;
 	_change_notify();
 }
 
-int NavigationMesh::get_source_geometry_mode() const {
+NavigationMesh::SourceGeometryMode NavigationMesh::get_source_geometry_mode() const {
 	return source_geometry_mode;
 }
 
@@ -128,6 +128,7 @@ StringName NavigationMesh::get_source_group_name() const {
 }
 
 void NavigationMesh::set_cell_size(float p_value) {
+	ERR_FAIL_COND(p_value <= 0);
 	cell_size = p_value;
 }
 
@@ -136,6 +137,7 @@ float NavigationMesh::get_cell_size() const {
 }
 
 void NavigationMesh::set_cell_height(float p_value) {
+	ERR_FAIL_COND(p_value <= 0);
 	cell_height = p_value;
 }
 
@@ -144,6 +146,7 @@ float NavigationMesh::get_cell_height() const {
 }
 
 void NavigationMesh::set_agent_height(float p_value) {
+	ERR_FAIL_COND(p_value < 0);
 	agent_height = p_value;
 }
 
@@ -152,6 +155,7 @@ float NavigationMesh::get_agent_height() const {
 }
 
 void NavigationMesh::set_agent_radius(float p_value) {
+	ERR_FAIL_COND(p_value < 0);
 	agent_radius = p_value;
 }
 
@@ -160,6 +164,7 @@ float NavigationMesh::get_agent_radius() {
 }
 
 void NavigationMesh::set_agent_max_climb(float p_value) {
+	ERR_FAIL_COND(p_value < 0);
 	agent_max_climb = p_value;
 }
 
@@ -168,6 +173,7 @@ float NavigationMesh::get_agent_max_climb() const {
 }
 
 void NavigationMesh::set_agent_max_slope(float p_value) {
+	ERR_FAIL_COND(p_value < 0 || p_value > 90);
 	agent_max_slope = p_value;
 }
 
@@ -176,6 +182,7 @@ float NavigationMesh::get_agent_max_slope() const {
 }
 
 void NavigationMesh::set_region_min_size(float p_value) {
+	ERR_FAIL_COND(p_value < 0);
 	region_min_size = p_value;
 }
 
@@ -184,6 +191,7 @@ float NavigationMesh::get_region_min_size() const {
 }
 
 void NavigationMesh::set_region_merge_size(float p_value) {
+	ERR_FAIL_COND(p_value < 0);
 	region_merge_size = p_value;
 }
 
@@ -192,6 +200,7 @@ float NavigationMesh::get_region_merge_size() const {
 }
 
 void NavigationMesh::set_edge_max_length(float p_value) {
+	ERR_FAIL_COND(p_value < 0);
 	edge_max_length = p_value;
 }
 
@@ -200,6 +209,7 @@ float NavigationMesh::get_edge_max_length() const {
 }
 
 void NavigationMesh::set_edge_max_error(float p_value) {
+	ERR_FAIL_COND(p_value < 0);
 	edge_max_error = p_value;
 }
 
@@ -208,6 +218,7 @@ float NavigationMesh::get_edge_max_error() const {
 }
 
 void NavigationMesh::set_verts_per_poly(float p_value) {
+	ERR_FAIL_COND(p_value < 3);
 	verts_per_poly = p_value;
 }
 
@@ -216,6 +227,7 @@ float NavigationMesh::get_verts_per_poly() const {
 }
 
 void NavigationMesh::set_detail_sample_distance(float p_value) {
+	ERR_FAIL_COND(p_value < 0);
 	detail_sample_distance = p_value;
 }
 
@@ -224,6 +236,7 @@ float NavigationMesh::get_detail_sample_distance() const {
 }
 
 void NavigationMesh::set_detail_sample_max_error(float p_value) {
+	ERR_FAIL_COND(p_value < 0);
 	detail_sample_max_error = p_value;
 }
 
@@ -461,14 +474,6 @@ void NavigationMesh::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("_set_polygons", "polygons"), &NavigationMesh::_set_polygons);
 	ClassDB::bind_method(D_METHOD("_get_polygons"), &NavigationMesh::_get_polygons);
 
-	BIND_CONSTANT(SAMPLE_PARTITION_WATERSHED);
-	BIND_CONSTANT(SAMPLE_PARTITION_MONOTONE);
-	BIND_CONSTANT(SAMPLE_PARTITION_LAYERS);
-
-	BIND_CONSTANT(PARSED_GEOMETRY_MESH_INSTANCES);
-	BIND_CONSTANT(PARSED_GEOMETRY_STATIC_COLLIDERS);
-	BIND_CONSTANT(PARSED_GEOMETRY_BOTH);
-
 	ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_vertices", "get_vertices");
 	ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "polygons", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_polygons", "_get_polygons");
 
@@ -495,6 +500,21 @@ 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/filter_walkable_low_height_spans"), "set_filter_walkable_low_height_spans", "get_filter_walkable_low_height_spans");
+
+	BIND_ENUM_CONSTANT(SAMPLE_PARTITION_WATERSHED);
+	BIND_ENUM_CONSTANT(SAMPLE_PARTITION_MONOTONE);
+	BIND_ENUM_CONSTANT(SAMPLE_PARTITION_LAYERS);
+	BIND_ENUM_CONSTANT(SAMPLE_PARTITION_MAX);
+
+	BIND_ENUM_CONSTANT(PARSED_GEOMETRY_MESH_INSTANCES);
+	BIND_ENUM_CONSTANT(PARSED_GEOMETRY_STATIC_COLLIDERS);
+	BIND_ENUM_CONSTANT(PARSED_GEOMETRY_BOTH);
+	BIND_ENUM_CONSTANT(PARSED_GEOMETRY_MAX);
+
+	BIND_ENUM_CONSTANT(SOURCE_GEOMETRY_NAVMESH_CHILDREN);
+	BIND_ENUM_CONSTANT(SOURCE_GEOMETRY_GROUPS_WITH_CHILDREN);
+	BIND_ENUM_CONSTANT(SOURCE_GEOMETRY_GROUPS_EXPLICIT);
+	BIND_ENUM_CONSTANT(SOURCE_GEOMETRY_MAX);
 }
 
 void NavigationMesh::_validate_property(PropertyInfo &property) const {

+ 10 - 6
scene/3d/navigation_mesh.h

@@ -110,11 +110,11 @@ protected:
 
 public:
 	// Recast settings
-	void set_sample_partition_type(int p_value);
-	int get_sample_partition_type() const;
+	void set_sample_partition_type(SamplePartitionType p_value);
+	SamplePartitionType get_sample_partition_type() const;
 
-	void set_parsed_geometry_type(int p_value);
-	int get_parsed_geometry_type() const;
+	void set_parsed_geometry_type(ParsedGeometryType p_value);
+	ParsedGeometryType get_parsed_geometry_type() const;
 
 	void set_collision_mask(uint32_t p_mask);
 	uint32_t get_collision_mask() const;
@@ -122,8 +122,8 @@ public:
 	void set_collision_mask_bit(int p_bit, bool p_value);
 	bool get_collision_mask_bit(int p_bit) const;
 
-	void set_source_geometry_mode(int p_geometry_mode);
-	int get_source_geometry_mode() const;
+	void set_source_geometry_mode(SourceGeometryMode p_geometry_mode);
+	SourceGeometryMode get_source_geometry_mode() const;
 
 	void set_source_group_name(StringName p_group_name);
 	StringName get_source_group_name() const;
@@ -191,6 +191,10 @@ public:
 	NavigationMesh();
 };
 
+VARIANT_ENUM_CAST(NavigationMesh::SamplePartitionType);
+VARIANT_ENUM_CAST(NavigationMesh::ParsedGeometryType);
+VARIANT_ENUM_CAST(NavigationMesh::SourceGeometryMode);
+
 class Navigation;
 
 class NavigationMeshInstance : public Spatial {