public virtual RecastBuilderResult build(InputGeom geom, RecastBuilderConfig bcfg) { RecastConfig cfg = bcfg.cfg; Context ctx = new Context(); CompactHeightfield chf = buildCompactHeightfield(geom, bcfg, ctx); // Partition the heightfield so that we can use simple algorithm later // to triangulate the walkable areas. // There are 3 martitioning methods, each with some pros and cons: // 1) Watershed partitioning // - the classic Recast partitioning // - creates the nicest tessellation // - usually slowest // - partitions the heightfield into nice regions without holes or // overlaps // - the are some corner cases where this method creates produces holes // and overlaps // - holes may appear when a small obstacles is close to large open area // (triangulation can handle this) // - overlaps may occur if you have narrow spiral corridors (i.e // stairs), this make triangulation to fail // * generally the best choice if you precompute the nacmesh, use this // if you have large open areas // 2) Monotone partioning // - fastest // - partitions the heightfield into regions without holes and overlaps // (guaranteed) // - creates long thin polygons, which sometimes causes paths with // detours // * use this if you want fast navmesh generation // 3) Layer partitoining // - quite fast // - partitions the heighfield into non-overlapping regions // - relies on the triangulation code to cope with holes (thus slower // than monotone partitioning) // - produces better triangles than monotone partitioning // - does not have the corner cases of watershed partitioning // - can be slow and create a bit ugly tessellation (still better than // monotone) // if you have large open areas with small obstacles (not a problem if // you use tiles) // * good choice to use for tiled navmesh with medium and small sized // tiles if (cfg.partitionType == PartitionType.WATERSHED) { // Prepare for region partitioning, by calculating distance field // along the walkable surface. RecastRegion.buildDistanceField(ctx, chf); // Partition the walkable surface into simple regions without holes. RecastRegion.buildRegions(ctx, chf, bcfg.borderSize, cfg.minRegionArea, cfg.mergeRegionArea); } else if (cfg.partitionType == PartitionType.MONOTONE) { // Partition the walkable surface into simple regions without holes. // Monotone partitioning does not need distancefield. RecastRegion.buildRegionsMonotone(ctx, chf, bcfg.borderSize, cfg.minRegionArea, cfg.mergeRegionArea); } else { // Partition the walkable surface into simple regions without holes. RecastRegion.buildLayerRegions(ctx, chf, bcfg.borderSize, cfg.minRegionArea); } // // Step 5. Trace and simplify region contours. // // Create contours. ContourSet cset = RecastContour.buildContours(ctx, chf, cfg.maxSimplificationError, cfg.maxEdgeLen, RecastConstants.RC_CONTOUR_TESS_WALL_EDGES); // // Step 6. Build polygons mesh from contours. // PolyMesh pmesh = RecastMesh.buildPolyMesh(ctx, cset, cfg.maxVertsPerPoly); // // Step 7. Create detail mesh which allows to access approximate height // on each polygon. // PolyMeshDetail dmesh = RecastMeshDetail.buildPolyMeshDetail(ctx, pmesh, chf, cfg.detailSampleDist, cfg.detailSampleMaxError); return(new RecastBuilderResult(this, pmesh, dmesh)); }
public RecastBuilderResult(RecastBuilder outerInstance, PolyMesh pmesh, PolyMeshDetail dmesh) { this.outerInstance = outerInstance; this.pmesh = pmesh; this.dmesh = dmesh; }