Add triangulation partition option to 2D navigation mesh baking

Adds triangulation partition option to 2D navigation mesh baking as an alternative to the existing convex partition option.
This commit is contained in:
smix8 2024-05-30 15:01:57 +02:00
parent 3978628c6c
commit 110b2dc61a
4 changed files with 66 additions and 4 deletions

View File

@ -193,6 +193,9 @@
<member name="parsed_geometry_type" type="int" setter="set_parsed_geometry_type" getter="get_parsed_geometry_type" enum="NavigationPolygon.ParsedGeometryType" default="2">
Determines which type of nodes will be parsed as geometry. See [enum ParsedGeometryType] for possible values.
</member>
<member name="sample_partition_type" type="int" setter="set_sample_partition_type" getter="get_sample_partition_type" enum="NavigationPolygon.SamplePartitionType" default="0">
Partitioning algorithm for creating the navigation mesh polys. See [enum SamplePartitionType] for possible values.
</member>
<member name="source_geometry_group_name" type="StringName" setter="set_source_geometry_group_name" getter="get_source_geometry_group_name" default="&amp;&quot;navigation_polygon_source_geometry_group&quot;">
The group name of nodes that should be parsed for baking source geometry.
Only used when [member source_geometry_mode] is [constant SOURCE_GEOMETRY_GROUPS_WITH_CHILDREN] or [constant SOURCE_GEOMETRY_GROUPS_EXPLICIT].
@ -202,6 +205,15 @@
</member>
</members>
<constants>
<constant name="SAMPLE_PARTITION_CONVEX_PARTITION" value="0" enum="SamplePartitionType">
Convex partitioning that yields navigation mesh with convex polygons.
</constant>
<constant name="SAMPLE_PARTITION_TRIANGULATE" value="1" enum="SamplePartitionType">
Triangulation partitioning that yields navigation mesh with triangle polygons.
</constant>
<constant name="SAMPLE_PARTITION_MAX" value="2" enum="SamplePartitionType">
Represents the size of the [enum SamplePartitionType] enum.
</constant>
<constant name="PARSED_GEOMETRY_MESH_INSTANCES" value="0" enum="ParsedGeometryType">
Parses mesh instances as obstruction geometry. This includes [Polygon2D], [MeshInstance2D], [MultiMeshInstance2D], and [TileMap] nodes.
Meshes are only parsed when they use a 2D vertices surface format.

View File

@ -1042,10 +1042,32 @@ void NavMeshGenerator2D::generator_bake_from_source_geometry_data(Ref<Navigation
}
TPPLPartition tpart;
if (tpart.ConvexPartition_HM(&tppl_in_polygon, &tppl_out_polygon) == 0) { //failed!
ERR_PRINT("NavigationPolygon Convex partition failed. Unable to create a valid NavigationMesh from defined polygon outline paths.");
p_navigation_mesh->clear();
return;
NavigationPolygon::SamplePartitionType sample_partition_type = p_navigation_mesh->get_sample_partition_type();
switch (sample_partition_type) {
case NavigationPolygon::SamplePartitionType::SAMPLE_PARTITION_CONVEX_PARTITION:
if (tpart.ConvexPartition_HM(&tppl_in_polygon, &tppl_out_polygon) == 0) {
ERR_PRINT("NavigationPolygon polygon convex partition failed. Unable to create a valid navigation mesh polygon layout from provided source geometry.");
p_navigation_mesh->set_vertices(Vector<Vector2>());
p_navigation_mesh->clear_polygons();
return;
}
break;
case NavigationPolygon::SamplePartitionType::SAMPLE_PARTITION_TRIANGULATE:
if (tpart.Triangulate_EC(&tppl_in_polygon, &tppl_out_polygon) == 0) {
ERR_PRINT("NavigationPolygon polygon triangulation failed. Unable to create a valid navigation mesh polygon layout from provided source geometry.");
p_navigation_mesh->set_vertices(Vector<Vector2>());
p_navigation_mesh->clear_polygons();
return;
}
break;
default: {
ERR_PRINT("NavigationPolygon polygon partitioning failed. Unrecognized partition type.");
p_navigation_mesh->set_vertices(Vector<Vector2>());
p_navigation_mesh->clear_polygons();
return;
}
}
Vector<Vector2> new_vertices;

View File

@ -400,6 +400,15 @@ real_t NavigationPolygon::get_border_size() const {
return border_size;
}
void NavigationPolygon::set_sample_partition_type(SamplePartitionType p_value) {
ERR_FAIL_INDEX(p_value, SAMPLE_PARTITION_MAX);
partition_type = p_value;
}
NavigationPolygon::SamplePartitionType NavigationPolygon::get_sample_partition_type() const {
return partition_type;
}
void NavigationPolygon::set_parsed_geometry_type(ParsedGeometryType p_geometry_type) {
ERR_FAIL_INDEX(p_geometry_type, PARSED_GEOMETRY_MAX);
parsed_geometry_type = p_geometry_type;
@ -514,6 +523,9 @@ void NavigationPolygon::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_border_size", "border_size"), &NavigationPolygon::set_border_size);
ClassDB::bind_method(D_METHOD("get_border_size"), &NavigationPolygon::get_border_size);
ClassDB::bind_method(D_METHOD("set_sample_partition_type", "sample_partition_type"), &NavigationPolygon::set_sample_partition_type);
ClassDB::bind_method(D_METHOD("get_sample_partition_type"), &NavigationPolygon::get_sample_partition_type);
ClassDB::bind_method(D_METHOD("set_parsed_geometry_type", "geometry_type"), &NavigationPolygon::set_parsed_geometry_type);
ClassDB::bind_method(D_METHOD("get_parsed_geometry_type"), &NavigationPolygon::get_parsed_geometry_type);
@ -543,6 +555,8 @@ void NavigationPolygon::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "polygons", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_polygons", "_get_polygons");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "outlines", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_outlines", "_get_outlines");
ADD_GROUP("Sampling", "sample_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "sample_partition_type", PROPERTY_HINT_ENUM, "Convex Partition,Triangulate"), "set_sample_partition_type", "get_sample_partition_type");
ADD_GROUP("Geometry", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "parsed_geometry_type", PROPERTY_HINT_ENUM, "Mesh Instances,Static Colliders,Meshes and Static Colliders"), "set_parsed_geometry_type", "get_parsed_geometry_type");
ADD_PROPERTY(PropertyInfo(Variant::INT, "parsed_collision_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_parsed_collision_mask", "get_parsed_collision_mask");
@ -559,6 +573,10 @@ void NavigationPolygon::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "baking_rect"), "set_baking_rect", "get_baking_rect");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "baking_rect_offset"), "set_baking_rect_offset", "get_baking_rect_offset");
BIND_ENUM_CONSTANT(SAMPLE_PARTITION_CONVEX_PARTITION);
BIND_ENUM_CONSTANT(SAMPLE_PARTITION_TRIANGULATE);
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);

View File

@ -74,6 +74,11 @@ public:
Rect2 _edit_get_rect() const;
bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
#endif
enum SamplePartitionType {
SAMPLE_PARTITION_CONVEX_PARTITION = 0,
SAMPLE_PARTITION_TRIANGULATE,
SAMPLE_PARTITION_MAX
};
enum ParsedGeometryType {
PARSED_GEOMETRY_MESH_INSTANCES = 0,
@ -91,6 +96,7 @@ public:
real_t agent_radius = 10.0f;
SamplePartitionType partition_type = SAMPLE_PARTITION_CONVEX_PARTITION;
ParsedGeometryType parsed_geometry_type = PARSED_GEOMETRY_BOTH;
uint32_t parsed_collision_mask = 0xFFFFFFFF;
@ -120,6 +126,9 @@ public:
Vector<int> get_polygon(int p_idx);
void clear_polygons();
void set_sample_partition_type(SamplePartitionType p_value);
SamplePartitionType get_sample_partition_type() const;
void set_parsed_geometry_type(ParsedGeometryType p_geometry_type);
ParsedGeometryType get_parsed_geometry_type() const;
@ -161,6 +170,7 @@ public:
~NavigationPolygon() {}
};
VARIANT_ENUM_CAST(NavigationPolygon::SamplePartitionType);
VARIANT_ENUM_CAST(NavigationPolygon::ParsedGeometryType);
VARIANT_ENUM_CAST(NavigationPolygon::SourceGeometryMode);