Expose new Recast partitioning methods for navmesh generation
authorReinier de Blois <rddeblois@gmail.com>
Tue, 5 Apr 2016 18:38:42 +0000 (20:38 +0200)
committerPorteries Tristan <republicthunderbolt9@gmail.com>
Tue, 5 Apr 2016 19:39:04 +0000 (21:39 +0200)
This patch depends on D1747, which upgrades the Recast version.  It exposes the new Recast partitioning methods in the navmesh generation.

Reviewers: campbellbarton, moguri

Reviewed By: moguri

Projects: #bf_blender

Differential Revision: https://developer.blender.org/D1748

release/scripts/startup/bl_ui/properties_game.py
source/blender/editors/mesh/mesh_navmesh.c
source/blender/makesdna/DNA_scene_types.h
source/blender/makesrna/intern/rna_scene.c

index ed1253ea3bfc899c16e36925fea215efb25c885b..8baad4ea0f20520f5f7150186b020366a1ca5feb 100644 (file)
@@ -510,7 +510,11 @@ class SCENE_PT_game_navmesh(SceneButtonsPanel, Panel):
         col.label(text="Region:")
         row = col.row()
         row.prop(rd, "region_min_size")
-        row.prop(rd, "region_merge_size")
+        if rd.partitioning != 'LAYERS':
+            row.prop(rd, "region_merge_size")
+
+        col = layout.column()
+        col.prop(rd, "partitioning")
 
         col = layout.column()
         col.label(text="Polygonization:")
index 4d07d50961658dc6a68174e63d520b92a42c9b90..b95921964eb256e69f27349fd5abf98a078ce4e2 100644 (file)
@@ -245,20 +245,41 @@ static bool buildNavMesh(const RecastData *recastParams, int nverts, float *vert
                return false;
        }
 
-       /* Prepare for region partitioning, by calculating distance field along the walkable surface */
-       if (!recast_buildDistanceField(chf)) {
-               recast_destroyCompactHeightfield(chf);
+       if (recastParams->partitioning == RC_PARTITION_WATERSHED) {
+               /* Prepare for region partitioning, by calculating distance field along the walkable surface */
+               if (!recast_buildDistanceField(chf)) {
+                       recast_destroyCompactHeightfield(chf);
 
-               BKE_report(reports, RPT_ERROR, "Failed to build distance field");
-               return false;
-       }
+                       BKE_report(reports, RPT_ERROR, "Failed to build distance field");
+                       return false;
+               }
 
-       /* Partition the walkable surface into simple regions without holes */
-       if (!recast_buildRegions(chf, 0, minRegionArea, mergeRegionArea)) {
-               recast_destroyCompactHeightfield(chf);
+               /* Partition the walkable surface into simple regions without holes */
+               if (!recast_buildRegions(chf, 0, minRegionArea, mergeRegionArea)) {
+                       recast_destroyCompactHeightfield(chf);
 
-               BKE_report(reports, RPT_ERROR, "Failed to build regions");
-               return false;
+                       BKE_report(reports, RPT_ERROR, "Failed to build watershed regions");
+                       return false;
+               }
+       }
+       else if (recastParams->partitioning == RC_PARTITION_MONOTONE) {
+               /* Partition the walkable surface into simple regions without holes */
+               /* Monotone partitioning does not need distancefield. */
+               if (!recast_buildRegionsMonotone(chf, 0, minRegionArea, mergeRegionArea)) {
+                       recast_destroyCompactHeightfield(chf);
+
+                       BKE_report(reports, RPT_ERROR, "Failed to build monotone regions");
+                       return false;
+               }
+       }
+       else { /* RC_PARTITION_LAYERS */
+               /* Partition the walkable surface into simple regions without holes */
+               if (!recast_buildLayerRegions(chf, 0, minRegionArea)) {
+                       recast_destroyCompactHeightfield(chf);
+
+                       BKE_report(reports, RPT_ERROR, "Failed to build layer regions");
+                       return false;
+               }
        }
 
        /* ** Step 5: Trace and simplify region contours ** */
index fd37bde65ecfb8e1400b557b6b94c4c88885350a..a8f78f6bb343ff4d54441215dd1b2d04d89d7cfd 100644 (file)
@@ -795,9 +795,15 @@ typedef struct RecastData {
        int vertsperpoly;
        float detailsampledist;
        float detailsamplemaxerror;
-       short pad1, pad2;
+       char partitioning;
+       char pad1;
+       short pad2;
 } RecastData;
 
+#define RC_PARTITION_WATERSHED 0
+#define RC_PARTITION_MONOTONE 1
+#define RC_PARTITION_LAYERS 2
+
 typedef struct GameData {
 
        /* standalone player */
index 2af58a93305e24ed1ce51f6c623308ee61b8bf97..94223f7f7da0f6579e5084b7052f46084edf743e 100644 (file)
@@ -3565,6 +3565,13 @@ static void rna_def_scene_game_recast_data(BlenderRNA *brna)
        StructRNA *srna;
        PropertyRNA *prop;
 
+       static EnumPropertyItem rna_enum_partitioning_items[] = {
+               {RC_PARTITION_WATERSHED, "WATERSHED", 0, "Watershed", "Classic Recast partitioning method generating the nicest tessellation"},
+               {RC_PARTITION_MONOTONE, "MONOTONE", 0, "Monotone", "Fastest navmesh generation method, may create long thin polygons"},
+               {RC_PARTITION_LAYERS, "LAYERS", 0, "Layers", "Reasonably fast method that produces better triangles than monotone partitioning"},
+               {0, NULL, 0, NULL, NULL}
+       };
+
        srna = RNA_def_struct(brna, "SceneGameRecastData", NULL);
        RNA_def_struct_sdna(srna, "RecastData");
        RNA_def_struct_nested(brna, srna, "Scene");
@@ -3627,6 +3634,13 @@ static void rna_def_scene_game_recast_data(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Merged Region Size", "Minimum regions size (smaller regions will be merged)");
        RNA_def_property_update(prop, NC_SCENE, NULL);
 
+       prop = RNA_def_property(srna, "partitioning", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_bitflag_sdna(prop, NULL, "partitioning");
+       RNA_def_property_enum_items(prop, rna_enum_partitioning_items);
+       RNA_def_property_enum_default(prop, RC_PARTITION_WATERSHED);
+       RNA_def_property_ui_text(prop, "Partitioning", "Choose partitioning method");
+       RNA_def_property_update(prop, NC_SCENE, NULL);
+
        prop = RNA_def_property(srna, "edge_max_len", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "edgemaxlen");
        RNA_def_property_ui_range(prop, 0, 50, 1, 2);