@recast-navigation/generators 0.21.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NavMesh, RecastBuildContext, RecastChunkyTriMesh, RecastCompactHeightfield, RecastConfig, RecastHeightfield, RecastHeightfieldLayerSet, TileCache, TileCacheMeshProcess } from '@recast-navigation/core';
|
|
2
2
|
import { Pretty } from '../types';
|
|
3
|
-
|
|
3
|
+
type TileCacheRecastConfig = Omit<RecastConfig, 'minRegionArea' | 'maxEdgeLen'>;
|
|
4
|
+
export type TileCacheGeneratorConfig = Pretty<TileCacheRecastConfig & {
|
|
4
5
|
/**
|
|
5
6
|
* How many layers (or "floors") each navmesh tile is expected to have.
|
|
6
7
|
*/
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/generators/common.ts","../src/generators/generate-solo-nav-mesh.ts","../src/generators/generate-tile-cache.ts","../src/generators/generate-tiled-nav-mesh.ts"],"sourcesContent":["import { OffMeshConnectionParams, vec3 } from '@recast-navigation/core';\n\nexport const getBoundingBox = (\n positions: ArrayLike<number>,\n indices: ArrayLike<number>\n) => {\n const bbMin = { x: Infinity, y: Infinity, z: Infinity };\n const bbMax = { x: -Infinity, y: -Infinity, z: -Infinity };\n\n for (let i = 0; i < indices.length; i++) {\n const ind = indices[i];\n\n const x = positions[ind * 3];\n const y = positions[ind * 3 + 1];\n const z = positions[ind * 3 + 2];\n\n bbMin.x = Math.min(bbMin.x, x);\n bbMin.y = Math.min(bbMin.y, y);\n bbMin.z = Math.min(bbMin.z, z);\n\n bbMax.x = Math.max(bbMax.x, x);\n bbMax.y = Math.max(bbMax.y, y);\n bbMax.z = Math.max(bbMax.z, z);\n }\n\n return {\n bbMin: vec3.toArray(bbMin),\n bbMax: vec3.toArray(bbMax),\n };\n};\n\nexport const dtIlog2 = (v: number) => {\n let r = 0;\n let shift = 0;\n\n r = Number(v > 0xffff) << 4;\n v >>= r;\n\n shift = Number(v > 0xff) << 3;\n v >>= shift;\n r |= shift;\n\n shift = Number(v > 0xf) << 2;\n v >>= shift;\n r |= shift;\n\n shift = Number(v > 0x3) << 1;\n v >>= shift;\n r |= shift;\n r |= v >> 1;\n\n return r;\n};\n\nexport const dtNextPow2 = (v: number) => {\n v--;\n v |= v >> 1;\n v |= v >> 2;\n v |= v >> 4;\n v |= v >> 8;\n v |= v >> 16;\n v++;\n return v;\n};\n\nexport type OffMeshConnectionGeneratorParams = {\n offMeshConnections?: OffMeshConnectionParams[];\n};\n","import {\n Arrays,\n NavMesh,\n NavMeshCreateParams,\n Raw,\n RecastBuildContext,\n RecastCompactHeightfield,\n RecastConfig,\n RecastContourSet,\n RecastHeightfield,\n allocCompactHeightfield,\n allocContourSet,\n allocHeightfield,\n allocPolyMesh,\n allocPolyMeshDetail,\n buildCompactHeightfield,\n buildContours,\n buildDistanceField,\n buildPolyMesh,\n buildPolyMeshDetail,\n buildRegions,\n calcGridSize,\n createHeightfield,\n createNavMeshData,\n createRcConfig,\n erodeWalkableArea,\n filterLedgeSpans,\n filterLowHangingWalkableObstacles,\n filterWalkableLowHeightSpans,\n freeCompactHeightfield,\n freeContourSet,\n freeHeightfield,\n markWalkableTriangles,\n rasterizeTriangles,\n recastConfigDefaults,\n} from '@recast-navigation/core';\nimport { Pretty } from '../types';\nimport { OffMeshConnectionGeneratorParams, getBoundingBox } from './common';\n\nexport type SoloNavMeshGeneratorConfig = Pretty<\n Omit<RecastConfig, 'tileSize'> & OffMeshConnectionGeneratorParams\n>;\n\nexport const soloNavMeshGeneratorConfigDefaults: SoloNavMeshGeneratorConfig = {\n ...recastConfigDefaults,\n};\n\nexport type SoloNavMeshGeneratorIntermediates = {\n type: 'solo';\n buildContext: RecastBuildContext;\n heightfield?: RecastHeightfield;\n compactHeightfield?: RecastCompactHeightfield;\n contourSet?: RecastContourSet;\n};\n\ntype SoloNavMeshGeneratorSuccessResult = {\n navMesh: NavMesh;\n success: true;\n intermediates: SoloNavMeshGeneratorIntermediates;\n};\n\ntype SoloNavMeshGeneratorFailResult = {\n navMesh: undefined;\n success: false;\n intermediates: SoloNavMeshGeneratorIntermediates;\n error: string;\n};\n\nexport type SoloNavMeshGeneratorResult =\n | SoloNavMeshGeneratorSuccessResult\n | SoloNavMeshGeneratorFailResult;\n\n/**\n * Builds a Solo NavMesh from the given positions and indices.\n * @param positions a flat array of positions\n * @param indices a flat array of indices\n * @param navMeshGeneratorConfig optional configuration for the NavMesh generator\n * @param keepIntermediates if true intermediates will be returned\n */\nexport const generateSoloNavMesh = (\n positions: ArrayLike<number>,\n indices: ArrayLike<number>,\n navMeshGeneratorConfig: Partial<SoloNavMeshGeneratorConfig> = {},\n keepIntermediates = false\n): SoloNavMeshGeneratorResult => {\n const buildContext = new RecastBuildContext();\n\n const intermediates: SoloNavMeshGeneratorIntermediates = {\n type: 'solo',\n buildContext,\n };\n\n const navMesh = new NavMesh();\n\n const cleanup = () => {\n if (keepIntermediates) return;\n\n if (intermediates.heightfield) {\n freeHeightfield(intermediates.heightfield);\n intermediates.heightfield = undefined;\n }\n if (intermediates.compactHeightfield) {\n freeCompactHeightfield(intermediates.compactHeightfield);\n intermediates.compactHeightfield = undefined;\n }\n if (intermediates.contourSet) {\n freeContourSet(intermediates.contourSet);\n intermediates.contourSet = undefined;\n }\n };\n\n const fail = (error: string): SoloNavMeshGeneratorFailResult => {\n cleanup();\n\n navMesh.destroy();\n\n return {\n navMesh: undefined,\n success: false,\n intermediates,\n error,\n };\n };\n\n const verts = positions as number[];\n const nVerts = indices.length;\n const vertsArray = new Arrays.VertsArray();\n vertsArray.copy(verts, verts.length);\n\n const tris = indices as number[];\n const nTris = indices.length / 3;\n const trisArray = new Arrays.TrisArray();\n trisArray.copy(tris, tris.length);\n\n const { bbMin, bbMax } = getBoundingBox(positions, indices);\n\n //\n // Step 1. Initialize build config.\n //\n const config = createRcConfig({\n ...soloNavMeshGeneratorConfigDefaults,\n ...navMeshGeneratorConfig,\n });\n\n config.minRegionArea = config.minRegionArea * config.minRegionArea; // Note: area = size*size\n config.mergeRegionArea = config.mergeRegionArea * config.mergeRegionArea; // Note: area = size*size\n config.detailSampleDist =\n config.detailSampleDist < 0.9 ? 0 : config.cs * config.detailSampleDist;\n config.detailSampleMaxError = config.ch * config.detailSampleMaxError;\n\n const gridSize = calcGridSize(bbMin, bbMax, config.cs);\n config.width = gridSize.width;\n config.height = gridSize.height;\n\n //\n // Step 2. Rasterize input polygon soup.\n //\n // Allocate voxel heightfield where we rasterize our input data to.\n const heightfield = allocHeightfield();\n intermediates.heightfield = heightfield;\n\n if (\n !createHeightfield(\n buildContext,\n heightfield,\n config.width,\n config.height,\n bbMin,\n bbMax,\n config.cs,\n config.ch\n )\n ) {\n return fail('Could not create heightfield');\n }\n\n // Find triangles which are walkable based on their slope and rasterize them.\n // If your input data is multiple meshes, you can transform them here, calculate\n // the are type for each of the meshes and rasterize them.\n const triAreasArray = new Arrays.TriAreasArray();\n triAreasArray.resize(nTris);\n\n markWalkableTriangles(\n buildContext,\n config.walkableSlopeAngle,\n vertsArray,\n nVerts,\n trisArray,\n nTris,\n triAreasArray\n );\n\n if (\n !rasterizeTriangles(\n buildContext,\n vertsArray,\n nVerts,\n trisArray,\n triAreasArray,\n nTris,\n heightfield,\n config.walkableClimb\n )\n ) {\n return fail('Could not rasterize triangles');\n }\n\n triAreasArray.free();\n\n //\n // Step 3. Filter walkables surfaces.\n //\n // Once all geoemtry is rasterized, we do initial pass of filtering to\n // remove unwanted overhangs caused by the conservative rasterization\n // as well as filter spans where the character cannot possibly stand.\n filterLowHangingWalkableObstacles(\n buildContext,\n config.walkableClimb,\n heightfield\n );\n filterLedgeSpans(\n buildContext,\n config.walkableHeight,\n config.walkableClimb,\n heightfield\n );\n filterWalkableLowHeightSpans(\n buildContext,\n config.walkableHeight,\n heightfield\n );\n\n //\n // Step 4. Partition walkable surface to simple regions.\n //\n // Compact the heightfield so that it is faster to handle from now on.\n // This will result more cache coherent data as well as the neighbours\n // between walkable cells will be calculated.\n const compactHeightfield = allocCompactHeightfield();\n intermediates.compactHeightfield = compactHeightfield;\n\n if (\n !buildCompactHeightfield(\n buildContext,\n config.walkableHeight,\n config.walkableClimb,\n heightfield,\n compactHeightfield\n )\n ) {\n return fail('Failed to build compact data');\n }\n\n if (!keepIntermediates) {\n freeHeightfield(heightfield);\n intermediates.heightfield = undefined;\n }\n\n // Erode the walkable area by agent radius.\n if (\n !erodeWalkableArea(buildContext, config.walkableRadius, compactHeightfield)\n ) {\n return fail('Failed to erode walkable area');\n }\n\n // (Optional) Mark areas\n // markConvexPolyArea(...)\n\n // Prepare for region partitioning, by calculating Distance field along the walkable surface.\n if (!buildDistanceField(buildContext, compactHeightfield)) {\n return fail('Failed to build distance field');\n }\n\n // Partition the walkable surface into simple regions without holes.\n if (\n !buildRegions(\n buildContext,\n compactHeightfield,\n config.borderSize,\n config.minRegionArea,\n config.mergeRegionArea\n )\n ) {\n return fail('Failed to build regions');\n }\n\n //\n // Step 5. Trace and simplify region contours.\n //\n const contourSet = allocContourSet();\n intermediates.contourSet = contourSet;\n\n if (\n !buildContours(\n buildContext,\n compactHeightfield,\n config.maxSimplificationError,\n config.maxEdgeLen,\n contourSet,\n Raw.Module.RC_CONTOUR_TESS_WALL_EDGES\n )\n ) {\n return fail('Failed to create contours');\n }\n\n //\n // Step 6. Build polygons mesh from contours.\n //\n const polyMesh = allocPolyMesh();\n if (\n !buildPolyMesh(buildContext, contourSet, config.maxVertsPerPoly, polyMesh)\n ) {\n return fail('Failed to triangulate contours');\n }\n\n //\n // Step 7. Create detail mesh which allows to access approximate height on each polygon.\n //\n const polyMeshDetail = allocPolyMeshDetail();\n if (\n !buildPolyMeshDetail(\n buildContext,\n polyMesh,\n compactHeightfield,\n config.detailSampleDist,\n config.detailSampleMaxError,\n polyMeshDetail\n )\n ) {\n return fail('Failed to build detail mesh');\n }\n\n if (!keepIntermediates) {\n freeCompactHeightfield(compactHeightfield);\n intermediates.compactHeightfield = undefined;\n\n freeContourSet(contourSet);\n intermediates.contourSet = undefined;\n }\n\n //\n // Step 8. Create Detour data from Recast poly mesh.\n //\n for (let i = 0; i < polyMesh.npolys(); i++) {\n if (polyMesh.areas(i) == Raw.Recast.WALKABLE_AREA) {\n polyMesh.setAreas(i, 0);\n }\n if (polyMesh.areas(i) == 0) {\n polyMesh.setFlags(i, 1);\n }\n }\n\n const navMeshCreateParams = new NavMeshCreateParams();\n\n navMeshCreateParams.setPolyMeshCreateParams(polyMesh);\n navMeshCreateParams.setPolyMeshDetailCreateParams(polyMeshDetail);\n\n navMeshCreateParams.setWalkableHeight(config.walkableHeight);\n navMeshCreateParams.setWalkableRadius(config.walkableRadius);\n navMeshCreateParams.setWalkableClimb(config.walkableClimb);\n\n navMeshCreateParams.setCellSize(config.cs);\n navMeshCreateParams.setCellHeight(config.ch);\n\n navMeshCreateParams.setBuildBvTree(true);\n\n if (navMeshGeneratorConfig.offMeshConnections) {\n navMeshCreateParams.setOffMeshConnections(\n navMeshGeneratorConfig.offMeshConnections\n );\n }\n\n const createNavMeshDataResult = createNavMeshData(navMeshCreateParams);\n\n if (!createNavMeshDataResult.success) {\n return fail('Failed to create Detour navmesh data');\n }\n\n const { navMeshData } = createNavMeshDataResult;\n\n if (!navMesh.initSolo(navMeshData)) {\n return fail('Failed to create Detour navmesh');\n }\n\n return {\n success: true,\n navMesh,\n intermediates,\n };\n};\n","import {\n Arrays,\n DetourTileCacheParams,\n NavMesh,\n NavMeshParams,\n Raw,\n RecastBuildContext,\n RecastChunkyTriMesh,\n RecastCompactHeightfield,\n RecastConfig,\n RecastHeightfield,\n RecastHeightfieldLayerSet,\n TileCache,\n TileCacheMeshProcess,\n Vector2Tuple,\n Vector3Tuple,\n allocCompactHeightfield,\n allocHeightfield,\n allocHeightfieldLayerSet,\n buildCompactHeightfield,\n buildHeightfieldLayers,\n buildTileCacheLayer,\n calcGridSize,\n cloneRcConfig,\n createHeightfield,\n createRcConfig,\n erodeWalkableArea,\n filterLedgeSpans,\n filterLowHangingWalkableObstacles,\n filterWalkableLowHeightSpans,\n freeCompactHeightfield,\n freeHeightfield,\n freeHeightfieldLayerSet,\n getHeightfieldLayerAreas,\n getHeightfieldLayerCons,\n getHeightfieldLayerHeights,\n markWalkableTriangles,\n rasterizeTriangles,\n recastConfigDefaults,\n vec3,\n} from '@recast-navigation/core';\nimport type R from '@recast-navigation/wasm';\nimport { Pretty } from '../types';\nimport { dtIlog2, dtNextPow2, getBoundingBox } from './common';\n\nexport type TileCacheGeneratorConfig = Pretty<\n RecastConfig & {\n /**\n * How many layers (or \"floors\") each navmesh tile is expected to have.\n */\n expectedLayersPerTile: number;\n\n /**\n * The max number of obstacles\n */\n maxObstacles: number;\n\n /**\n * The tile cache mesh process implementation.\n * If not provided, a default one is created via `createDefaultTileCacheMeshProcess()`\n * @default createDefaultTileCacheMeshProcess()\n */\n tileCacheMeshProcess?: TileCacheMeshProcess;\n }\n>;\n\nexport const tileCacheGeneratorConfigDefaults: TileCacheGeneratorConfig = {\n ...recastConfigDefaults,\n tileSize: 32,\n expectedLayersPerTile: 4,\n maxObstacles: 128,\n};\n\nexport type TileCacheGeneratorTileIntermediates = {\n tileX: number;\n tileY: number;\n heightfield?: RecastHeightfield;\n compactHeightfield?: RecastCompactHeightfield;\n heightfieldLayerSet?: RecastHeightfieldLayerSet;\n};\n\nexport type TileCacheGeneratorIntermediates = {\n type: 'tilecache';\n buildContext: RecastBuildContext;\n chunkyTriMesh?: RecastChunkyTriMesh;\n tileIntermediates: TileCacheGeneratorTileIntermediates[];\n};\n\ntype TileCacheGeneratorSuccessResult = {\n tileCache: TileCache;\n navMesh: NavMesh;\n success: true;\n intermediates: TileCacheGeneratorIntermediates;\n};\n\ntype TileCacheGeneratorFailResult = {\n tileCache: undefined;\n navMesh: undefined;\n success: false;\n error: string;\n intermediates: TileCacheGeneratorIntermediates;\n};\n\nexport type TileCacheGeneratorResult =\n | TileCacheGeneratorSuccessResult\n | TileCacheGeneratorFailResult;\n\nexport const createDefaultTileCacheMeshProcess = () =>\n new TileCacheMeshProcess((navMeshCreateParams, polyAreas, polyFlags) => {\n for (let i = 0; i < navMeshCreateParams.polyCount(); ++i) {\n polyAreas.set(i, 0);\n polyFlags.set(i, 1);\n }\n });\n\n/**\n * Builds a TileCache and NavMesh from the given positions and indices.\n * TileCache assumes small tiles (around 32-64 squared) and does some tricks to make the update fast.\n * @param positions a flat array of positions\n * @param indices a flat array of indices\n * @param navMeshConfig optional configuration for the NavMesh\n * @param keepIntermediates if true intermediates will be returned\n */\nexport const generateTileCache = (\n positions: ArrayLike<number>,\n indices: ArrayLike<number>,\n navMeshGeneratorConfig: Partial<TileCacheGeneratorConfig> = {},\n keepIntermediates = false\n): TileCacheGeneratorResult => {\n const buildContext = new RecastBuildContext();\n\n const intermediates: TileCacheGeneratorIntermediates = {\n type: 'tilecache',\n buildContext,\n chunkyTriMesh: undefined,\n tileIntermediates: [],\n };\n\n const tileCache = new TileCache();\n const navMesh = new NavMesh();\n\n const cleanup = () => {\n if (!keepIntermediates) {\n for (let i = 0; i < intermediates.tileIntermediates.length; i++) {\n const tileIntermediate = intermediates.tileIntermediates[i];\n\n if (tileIntermediate.heightfield) {\n freeHeightfield(tileIntermediate.heightfield);\n tileIntermediate.heightfield = undefined;\n }\n\n if (tileIntermediate.compactHeightfield) {\n freeCompactHeightfield(tileIntermediate.compactHeightfield);\n tileIntermediate.compactHeightfield = undefined;\n }\n\n if (tileIntermediate.heightfieldLayerSet) {\n freeHeightfieldLayerSet(tileIntermediate.heightfieldLayerSet);\n tileIntermediate.heightfieldLayerSet = undefined;\n }\n }\n }\n };\n\n const fail = (error: string): TileCacheGeneratorFailResult => {\n cleanup();\n\n tileCache.destroy();\n navMesh.destroy();\n\n return {\n success: false,\n navMesh: undefined,\n tileCache: undefined,\n intermediates,\n error,\n };\n };\n\n const verts = positions as number[];\n const nVerts = indices.length;\n const vertsArray = new Arrays.VertsArray();\n vertsArray.copy(verts, verts.length);\n\n const tris = indices as number[];\n const nTris = indices.length / 3;\n const trisArray = new Arrays.TrisArray();\n trisArray.copy(tris, tris.length);\n\n const { bbMin, bbMax } = getBoundingBox(positions, indices);\n\n const { expectedLayersPerTile, maxObstacles, ...recastConfig } = {\n ...tileCacheGeneratorConfigDefaults,\n ...navMeshGeneratorConfig,\n };\n\n //\n // Step 1. Initialize build config.\n //\n const config = createRcConfig(recastConfig);\n\n const gridSize = calcGridSize(bbMin, bbMax, config.cs);\n config.width = gridSize.width;\n config.height = gridSize.height;\n\n config.minRegionArea = config.minRegionArea * config.minRegionArea; // Note: area = size*size\n config.mergeRegionArea = config.mergeRegionArea * config.mergeRegionArea; // Note: area = size*size\n config.detailSampleDist =\n config.detailSampleDist < 0.9 ? 0 : config.cs * config.detailSampleDist;\n config.detailSampleMaxError = config.ch * config.detailSampleMaxError;\n\n const tileSize = Math.floor(config.tileSize);\n const tileWidth = Math.floor((config.width + tileSize - 1) / tileSize);\n const tileHeight = Math.floor((config.height + tileSize - 1) / tileSize);\n\n // Generation params\n config.borderSize = config.walkableRadius + 3; // Reserve enough padding.\n config.width = config.tileSize + config.borderSize * 2;\n config.height = config.tileSize + config.borderSize * 2;\n\n // Tile cache params\n const tileCacheParams = DetourTileCacheParams.create({\n orig: bbMin,\n cs: config.cs,\n ch: config.ch,\n width: config.tileSize,\n height: config.tileSize,\n walkableHeight: config.walkableHeight,\n walkableRadius: config.walkableRadius,\n walkableClimb: config.walkableClimb,\n maxSimplificationError: config.maxSimplificationError,\n maxTiles: tileWidth * tileHeight * expectedLayersPerTile,\n maxObstacles,\n });\n\n const allocator = new Raw.RecastLinearAllocator(32000);\n const compressor = new Raw.RecastFastLZCompressor();\n\n const tileCacheMeshProcess =\n navMeshGeneratorConfig.tileCacheMeshProcess ??\n createDefaultTileCacheMeshProcess();\n\n if (\n !tileCache.init(\n tileCacheParams,\n allocator,\n compressor,\n tileCacheMeshProcess\n )\n ) {\n return fail('Failed to initialize tile cache');\n }\n\n const orig = vec3.fromArray(bbMin);\n\n // Max tiles and max polys affect how the tile IDs are caculated.\n // There are 22 bits available for identifying a tile and a polygon.\n let tileBits = Math.min(\n Math.floor(\n dtIlog2(dtNextPow2(tileWidth * tileHeight * expectedLayersPerTile))\n ),\n 14\n );\n if (tileBits > 14) {\n tileBits = 14;\n }\n const polyBits = 22 - tileBits;\n\n const maxTiles = 1 << tileBits;\n const maxPolysPerTile = 1 << polyBits;\n\n const navMeshParams = NavMeshParams.create({\n orig,\n tileWidth: config.tileSize * config.cs,\n tileHeight: config.tileSize * config.cs,\n maxTiles,\n maxPolys: maxPolysPerTile,\n });\n\n if (!navMesh.initTiled(navMeshParams)) {\n return fail('Failed to initialize tiled navmesh');\n }\n\n const chunkyTriMesh = new RecastChunkyTriMesh();\n intermediates.chunkyTriMesh = chunkyTriMesh;\n\n if (!chunkyTriMesh.init(vertsArray, trisArray, nTris, 256)) {\n return fail('Failed to build chunky triangle mesh');\n }\n\n const rasterizeTileLayers = (tileX: number, tileY: number) => {\n // Tile intermediates\n const tileIntermediates: TileCacheGeneratorTileIntermediates = {\n tileX,\n tileY,\n };\n\n // Tile bounds\n const tcs = config.tileSize * config.cs;\n\n const tileConfig = cloneRcConfig(config);\n\n const tileBoundsMin: Vector3Tuple = [\n bbMin[0] + tileX * tcs,\n bbMin[1],\n bbMin[2] + tileY * tcs,\n ];\n\n const tileBoundsMax: Vector3Tuple = [\n bbMin[0] + (tileX + 1) * tcs,\n bbMax[1],\n bbMin[2] + (tileY + 1) * tcs,\n ];\n\n tileBoundsMin[0] -= tileConfig.borderSize * tileConfig.cs;\n tileBoundsMin[2] -= tileConfig.borderSize * tileConfig.cs;\n tileBoundsMax[0] += tileConfig.borderSize * tileConfig.cs;\n tileBoundsMax[2] += tileConfig.borderSize * tileConfig.cs;\n\n tileConfig.set_bmin(0, tileBoundsMin[0]);\n tileConfig.set_bmin(1, tileBoundsMin[1]);\n tileConfig.set_bmin(2, tileBoundsMin[2]);\n\n tileConfig.set_bmax(0, tileBoundsMax[0]);\n tileConfig.set_bmax(1, tileBoundsMax[1]);\n tileConfig.set_bmax(2, tileBoundsMax[2]);\n\n // Allocate voxel heightfield where we rasterize our input data to.\n const heightfield = allocHeightfield();\n tileIntermediates.heightfield = heightfield;\n\n if (\n !createHeightfield(\n buildContext,\n heightfield,\n tileConfig.width,\n tileConfig.height,\n tileBoundsMin,\n tileBoundsMax,\n tileConfig.cs,\n tileConfig.ch\n )\n ) {\n return { n: 0 };\n }\n\n const tbmin: Vector2Tuple = [tileBoundsMin[0], tileBoundsMin[2]];\n const tbmax: Vector2Tuple = [tileBoundsMax[0], tileBoundsMax[2]];\n\n // TODO: Make grow when returning too many items.\n const maxChunkIds = 512;\n const chunkIdsArray = new Arrays.ChunkIdsArray();\n chunkIdsArray.resize(maxChunkIds);\n\n const nChunksOverlapping = chunkyTriMesh.getChunksOverlappingRect(\n tbmin,\n tbmax,\n chunkIdsArray,\n maxChunkIds\n );\n\n if (nChunksOverlapping === 0) {\n return { n: 0 };\n }\n\n for (let i = 0; i < nChunksOverlapping; ++i) {\n const nodeId = chunkIdsArray.get_data(i);\n const node = chunkyTriMesh.nodes(nodeId);\n const nNodeTris = node.n;\n\n const nodeTrisArray = chunkyTriMesh.getNodeTris(nodeId);\n\n const triAreasArray = new Arrays.TriAreasArray();\n triAreasArray.resize(nNodeTris);\n\n // Find triangles which are walkable based on their slope and rasterize them.\n // If your input data is multiple meshes, you can transform them here, calculate\n // the are type for each of the meshes and rasterize them.\n markWalkableTriangles(\n buildContext,\n tileConfig.walkableSlopeAngle,\n vertsArray,\n nVerts,\n nodeTrisArray,\n nNodeTris,\n triAreasArray\n );\n\n const success = rasterizeTriangles(\n buildContext,\n vertsArray,\n nVerts,\n nodeTrisArray,\n triAreasArray,\n nNodeTris,\n heightfield,\n tileConfig.walkableClimb\n );\n\n triAreasArray.free();\n\n if (!success) {\n return { n: 0 };\n }\n }\n\n // Once all geometry is rasterized, we do initial pass of filtering to\n // remove unwanted overhangs caused by the conservative rasterization\n // as well as filter spans where the character cannot possibly stand.\n filterLowHangingWalkableObstacles(\n buildContext,\n config.walkableClimb,\n heightfield\n );\n filterLedgeSpans(\n buildContext,\n config.walkableHeight,\n config.walkableClimb,\n heightfield\n );\n filterWalkableLowHeightSpans(\n buildContext,\n config.walkableHeight,\n heightfield\n );\n\n const compactHeightfield = allocCompactHeightfield();\n if (\n !buildCompactHeightfield(\n buildContext,\n config.walkableHeight,\n config.walkableClimb,\n heightfield,\n compactHeightfield\n )\n ) {\n return { n: 0 };\n }\n\n if (!keepIntermediates) {\n freeHeightfield(tileIntermediates.heightfield);\n tileIntermediates.heightfield = undefined;\n }\n\n // Erode the walkable area by agent radius\n if (\n !erodeWalkableArea(\n buildContext,\n config.walkableRadius,\n compactHeightfield\n )\n ) {\n return { n: 0 };\n }\n\n const heightfieldLayerSet = allocHeightfieldLayerSet();\n if (\n !buildHeightfieldLayers(\n buildContext,\n compactHeightfield,\n config.borderSize,\n config.walkableHeight,\n heightfieldLayerSet\n )\n ) {\n return { n: 0 };\n }\n\n if (!keepIntermediates) {\n freeCompactHeightfield(compactHeightfield);\n tileIntermediates.compactHeightfield = undefined;\n }\n\n const tiles: R.UnsignedCharArray[] = [];\n\n for (let i = 0; i < heightfieldLayerSet.nlayers(); i++) {\n const tile = new Arrays.TileCacheData();\n const heightfieldLayer = heightfieldLayerSet.layers(i);\n\n // Store header\n const header = new Raw.dtTileCacheLayerHeader();\n header.magic = Raw.Detour.TILECACHE_MAGIC;\n header.version = Raw.Detour.TILECACHE_VERSION;\n\n // Tile layer location in the navmesh\n header.tx = tileX;\n header.ty = tileY;\n header.tlayer = i;\n\n const heightfieldLayerBin = heightfieldLayer.bmin();\n const heightfieldLayerBmax = heightfieldLayer.bmax();\n header.set_bmin(0, heightfieldLayerBin.x);\n header.set_bmin(1, heightfieldLayerBin.y);\n header.set_bmin(2, heightfieldLayerBin.z);\n\n header.set_bmax(0, heightfieldLayerBmax.x);\n header.set_bmax(1, heightfieldLayerBmax.y);\n header.set_bmax(2, heightfieldLayerBmax.z);\n\n // Tile info\n header.width = heightfieldLayer.width();\n header.height = heightfieldLayer.height();\n header.minx = heightfieldLayer.minx();\n header.maxx = heightfieldLayer.maxx();\n header.miny = heightfieldLayer.miny();\n header.maxy = heightfieldLayer.maxy();\n header.hmin = heightfieldLayer.hmin();\n header.hmax = heightfieldLayer.hmax();\n\n const heights = getHeightfieldLayerHeights(heightfieldLayer);\n const areas = getHeightfieldLayerAreas(heightfieldLayer);\n const cons = getHeightfieldLayerCons(heightfieldLayer);\n\n const status = buildTileCacheLayer(\n compressor,\n header,\n heights,\n areas,\n cons,\n tile\n );\n\n if (Raw.Detour.statusFailed(status)) {\n return { n: 0 };\n }\n\n tiles.push(tile);\n }\n\n if (!keepIntermediates) {\n freeHeightfieldLayerSet(heightfieldLayerSet);\n tileIntermediates.heightfieldLayerSet = undefined;\n }\n\n intermediates.tileIntermediates.push(tileIntermediates);\n\n return { n: tiles.length, tiles };\n };\n\n // Preprocess tiles\n for (let y = 0; y < tileHeight; ++y) {\n for (let x = 0; x < tileWidth; ++x) {\n const { n, tiles: newTiles } = rasterizeTileLayers(x, y);\n\n if (n > 0 && newTiles) {\n for (let i = 0; i < n; i++) {\n const tileCacheData = newTiles[i];\n\n const addResult = tileCache.addTile(tileCacheData);\n\n if (Raw.Detour.statusFailed(addResult.status)) {\n buildContext.log(\n Raw.Module.RC_LOG_WARNING,\n `Failed to add tile to tile cache - tx: ${x}, ty: ${y}`\n );\n continue;\n }\n }\n }\n }\n }\n\n // Build initial meshes\n for (let y = 0; y < tileHeight; y++) {\n for (let x = 0; x < tileWidth; x++) {\n const dtStatus = tileCache.buildNavMeshTilesAt(x, y, navMesh);\n\n if (Raw.Detour.statusFailed(dtStatus)) {\n return fail(`Failed to build nav mesh tiles at ${x}, ${y}`);\n }\n }\n }\n\n cleanup();\n\n return {\n success: true,\n tileCache,\n navMesh,\n intermediates,\n };\n};\n","import {\n Arrays,\n NavMesh,\n NavMeshCreateParams,\n NavMeshParams,\n Raw,\n RecastBuildContext,\n RecastChunkyTriMesh,\n RecastCompactHeightfield,\n RecastConfig,\n RecastContourSet,\n RecastHeightfield,\n Vector2Tuple,\n Vector3Tuple,\n allocCompactHeightfield,\n allocContourSet,\n allocHeightfield,\n allocPolyMesh,\n allocPolyMeshDetail,\n buildCompactHeightfield,\n buildContours,\n buildDistanceField,\n buildPolyMesh,\n buildPolyMeshDetail,\n buildRegions,\n calcGridSize,\n cloneRcConfig,\n createHeightfield,\n createNavMeshData,\n createRcConfig,\n statusToReadableString,\n erodeWalkableArea,\n filterLedgeSpans,\n filterLowHangingWalkableObstacles,\n filterWalkableLowHeightSpans,\n freeCompactHeightfield,\n freeContourSet,\n freeHeightfield,\n markWalkableTriangles,\n rasterizeTriangles,\n recastConfigDefaults,\n vec3,\n} from '@recast-navigation/core';\nimport type R from '@recast-navigation/wasm';\nimport { Pretty } from '../types';\nimport {\n OffMeshConnectionGeneratorParams,\n dtIlog2,\n dtNextPow2,\n getBoundingBox,\n} from './common';\n\nexport type TiledNavMeshGeneratorConfig = Pretty<\n RecastConfig & OffMeshConnectionGeneratorParams\n>;\n\nexport const tiledNavMeshGeneratorConfigDefaults: TiledNavMeshGeneratorConfig =\n {\n ...recastConfigDefaults,\n };\n\nexport type TiledNavMeshGeneratorIntermediates = {\n type: 'tiled';\n buildContext: RecastBuildContext;\n chunkyTriMesh?: RecastChunkyTriMesh;\n tileIntermediates: {\n tileX: number;\n tileY: number;\n heightfield?: RecastHeightfield;\n compactHeightfield?: RecastCompactHeightfield;\n contourSet?: RecastContourSet;\n }[];\n};\n\ntype TiledNavMeshGeneratorSuccessResult = {\n navMesh: NavMesh;\n success: true;\n intermediates: TiledNavMeshGeneratorIntermediates;\n};\n\ntype TiledNavMeshGeneratorFailResult = {\n navMesh: undefined;\n success: false;\n intermediates: TiledNavMeshGeneratorIntermediates;\n error: string;\n};\n\nexport type TiledNavMeshGeneratorResult =\n | TiledNavMeshGeneratorSuccessResult\n | TiledNavMeshGeneratorFailResult;\n\n/**\n * Builds a Tiled NavMesh\n * @param positions a flat array of positions\n * @param indices a flat array of indices\n * @param navMeshGeneratorConfig optional configuration for the NavMesh generator\n * @param keepIntermediates if true intermediates will be returned\n */\nexport const generateTiledNavMesh = (\n positions: ArrayLike<number>,\n indices: ArrayLike<number>,\n navMeshGeneratorConfig: Partial<TiledNavMeshGeneratorConfig> = {},\n keepIntermediates = false\n): TiledNavMeshGeneratorResult => {\n const buildContext = new RecastBuildContext();\n\n const intermediates: TiledNavMeshGeneratorIntermediates = {\n type: 'tiled',\n buildContext,\n chunkyTriMesh: undefined,\n tileIntermediates: [],\n };\n\n const navMesh = new NavMesh();\n\n const cleanup = () => {\n if (keepIntermediates) return;\n\n for (let i = 0; i < intermediates.tileIntermediates.length; i++) {\n const tileIntermediate = intermediates.tileIntermediates[i];\n\n if (tileIntermediate.compactHeightfield) {\n freeCompactHeightfield(tileIntermediate.compactHeightfield);\n }\n\n if (tileIntermediate.heightfield) {\n freeHeightfield(tileIntermediate.heightfield);\n }\n\n if (tileIntermediate.contourSet) {\n freeContourSet(tileIntermediate.contourSet);\n }\n }\n\n if (intermediates.chunkyTriMesh) {\n intermediates.chunkyTriMesh = undefined;\n }\n };\n\n const fail = (error: string): TiledNavMeshGeneratorFailResult => {\n cleanup();\n\n navMesh.destroy();\n\n return {\n success: false,\n navMesh: undefined,\n intermediates,\n error,\n };\n };\n\n //\n // Initialize build config.\n //\n const config = createRcConfig({\n ...tiledNavMeshGeneratorConfigDefaults,\n ...navMeshGeneratorConfig,\n });\n\n /* get input bounding box */\n const { bbMin, bbMax } = getBoundingBox(positions, indices);\n\n /* grid size */\n const gridSize = calcGridSize(bbMin, bbMax, config.cs);\n config.width = gridSize.width;\n config.height = gridSize.height;\n\n config.minRegionArea = config.minRegionArea * config.minRegionArea; // Note: area = size*size\n config.mergeRegionArea = config.mergeRegionArea * config.mergeRegionArea; // Note: area = size*size\n config.tileSize = Math.floor(config.tileSize);\n config.borderSize = config.walkableRadius + 3; // Reserve enough padding.\n config.width = config.tileSize + config.borderSize * 2;\n config.height = config.tileSize + config.borderSize * 2;\n config.detailSampleDist =\n config.detailSampleDist < 0.9 ? 0 : config.cs * config.detailSampleDist;\n config.detailSampleMaxError = config.ch * config.detailSampleMaxError;\n\n // tile size\n const tileSize = Math.floor(config.tileSize);\n const tileWidth = Math.floor((gridSize.width + tileSize - 1) / tileSize);\n const tileHeight = Math.floor((gridSize.height + tileSize - 1) / tileSize);\n const tcs = config.tileSize * config.cs;\n\n /* verts */\n const verts = positions as number[];\n const nVerts = indices.length;\n const vertsArray = new Arrays.VertsArray();\n vertsArray.copy(verts, verts.length);\n\n /* tris */\n const tris = indices as number[];\n const nTris = indices.length / 3;\n const trisArray = new Arrays.TrisArray();\n trisArray.copy(tris, tris.length);\n\n /* Create dtNavMeshParams, initialise nav mesh for tiled use */\n const orig = vec3.fromArray(bbMin);\n\n // Max tiles and max polys affect how the tile IDs are caculated.\n // There are 22 bits available for identifying a tile and a polygon.\n let tileBits = Math.min(\n Math.floor(dtIlog2(dtNextPow2(tileWidth * tileHeight))),\n 14\n );\n if (tileBits > 14) tileBits = 14;\n const polyBits = 22 - tileBits;\n\n const maxTiles = 1 << tileBits;\n const maxPolysPerTile = 1 << polyBits;\n\n const navMeshParams = NavMeshParams.create({\n orig,\n tileWidth: config.tileSize * config.cs,\n tileHeight: config.tileSize * config.cs,\n maxTiles,\n maxPolys: maxPolysPerTile,\n });\n\n if (!navMesh.initTiled(navMeshParams)) {\n return fail('Could not init nav mesh for tiled use');\n }\n\n /* create chunky tri mesh */\n const chunkyTriMesh = new RecastChunkyTriMesh();\n intermediates.chunkyTriMesh = chunkyTriMesh;\n\n if (!chunkyTriMesh.init(vertsArray, trisArray, nTris, 256)) {\n return fail('Failed to build chunky triangle mesh');\n }\n\n /** @internal */\n const buildTileMesh = (\n tileX: number,\n tileY: number,\n tileBoundsMin: Vector3Tuple,\n tileBoundsMax: Vector3Tuple\n ):\n | { success: true; data?: R.UnsignedCharArray }\n | { success: false; error: string } => {\n const failTileMesh = (error: string) => {\n buildContext.log(Raw.Module.RC_LOG_ERROR, error);\n\n return { success: false as const, error };\n };\n\n const tileIntermediate: {\n tileX: number;\n tileY: number;\n heightfield?: RecastHeightfield;\n compactHeightfield?: RecastCompactHeightfield;\n contourSet?: RecastContourSet;\n } = { tileX, tileY };\n\n intermediates.tileIntermediates.push(tileIntermediate);\n\n const tileConfig = cloneRcConfig(config);\n\n // Expand the heightfield bounding box by border size to find the extents of geometry we need to build this tile.\n //\n // This is done in order to make sure that the navmesh tiles connect correctly at the borders,\n // and the obstacles close to the border work correctly with the dilation process.\n // No polygons (or contours) will be created on the border area.\n //\n // IMPORTANT!\n //\n // :''''''''':\n // : +-----+ :\n // : | | :\n // : | |<--- tile to build\n // : | | :\n // : +-----+ :<-- geometry needed\n // :.........:\n //\n // You should use this bounding box to query your input geometry.\n //\n // For example if you build a navmesh for terrain, and want the navmesh tiles to match the terrain tile size\n // you will need to pass in data from neighbour terrain tiles too! In a simple case, just pass in all the 8 neighbours,\n // or use the bounding box below to only pass in a sliver of each of the 8 neighbours.\n\n const expandedTileBoundsMin = [...tileBoundsMin] as Vector3Tuple;\n const expandedTileBoundsMax = [...tileBoundsMax] as Vector3Tuple;\n\n expandedTileBoundsMin[0] -= tileConfig.borderSize * tileConfig.cs;\n expandedTileBoundsMin[2] -= tileConfig.borderSize * tileConfig.cs;\n\n expandedTileBoundsMax[0] += tileConfig.borderSize * tileConfig.cs;\n expandedTileBoundsMax[2] += tileConfig.borderSize * tileConfig.cs;\n\n tileConfig.set_bmin(0, expandedTileBoundsMin[0]);\n tileConfig.set_bmin(1, expandedTileBoundsMin[1]);\n tileConfig.set_bmin(2, expandedTileBoundsMin[2]);\n\n tileConfig.set_bmax(0, expandedTileBoundsMax[0]);\n tileConfig.set_bmax(1, expandedTileBoundsMax[1]);\n tileConfig.set_bmax(2, expandedTileBoundsMax[2]);\n\n // Reset build timer\n buildContext.resetTimers();\n\n // Start the build process\n buildContext.startTimer(Raw.Module.RC_TIMER_TOTAL);\n\n buildContext.log(\n Raw.Module.RC_LOG_PROGRESS,\n `Building tile ${intermediates.tileIntermediates.length} at x: ${tileX}, y: ${tileY}`\n );\n buildContext.log(\n Raw.Module.RC_LOG_PROGRESS,\n ` - ${config.width} x ${config.height} cells`\n );\n buildContext.log(\n Raw.Module.RC_LOG_PROGRESS,\n ` - ${nVerts / 1000}fK verts, ${nTris / 1000}K tris`\n );\n\n // Allocate voxel heightfield where we rasterize our input data to.\n const heightfield = allocHeightfield();\n tileIntermediate.heightfield = heightfield;\n\n if (\n !createHeightfield(\n buildContext,\n heightfield,\n tileConfig.width,\n tileConfig.height,\n expandedTileBoundsMin,\n expandedTileBoundsMax,\n tileConfig.cs,\n tileConfig.ch\n )\n ) {\n return failTileMesh('Could not create heightfield');\n }\n\n // Allocate array that can hold triangle flags.\n // If you have multiple meshes you need to process, allocate\n // and array which can hold the max number of triangles you need to process.\n const triAreas = new Arrays.TriAreasArray();\n triAreas.resize(chunkyTriMesh.maxTrisPerChunk());\n\n const tbmin: Vector2Tuple = [\n expandedTileBoundsMin[0],\n expandedTileBoundsMin[2],\n ];\n const tbmax: Vector2Tuple = [\n expandedTileBoundsMax[0],\n expandedTileBoundsMax[2],\n ];\n\n // TODO: Make grow when returning too many items.\n const maxChunkIds = 512;\n const chunkIdsArray = new Arrays.ChunkIdsArray();\n chunkIdsArray.resize(maxChunkIds);\n\n const nChunksOverlapping = chunkyTriMesh.getChunksOverlappingRect(\n tbmin,\n tbmax,\n chunkIdsArray,\n maxChunkIds\n );\n\n if (nChunksOverlapping === 0) {\n return { success: true };\n }\n\n for (let i = 0; i < nChunksOverlapping; ++i) {\n const nodeId = chunkIdsArray.get_data(i);\n const node = chunkyTriMesh.nodes(nodeId);\n const nNodeTris = node.n;\n\n const nodeTrisArray = chunkyTriMesh.getNodeTris(nodeId);\n\n const triAreasArray = new Arrays.TriAreasArray();\n triAreasArray.resize(nNodeTris);\n\n // Find triangles which are walkable based on their slope and rasterize them.\n // If your input data is multiple meshes, you can transform them here, calculate\n // the are type for each of the meshes and rasterize them.\n markWalkableTriangles(\n buildContext,\n tileConfig.walkableSlopeAngle,\n vertsArray,\n nVerts,\n nodeTrisArray,\n nNodeTris,\n triAreasArray\n );\n\n const success = rasterizeTriangles(\n buildContext,\n vertsArray,\n nVerts,\n nodeTrisArray,\n triAreasArray,\n nNodeTris,\n heightfield,\n tileConfig.walkableClimb\n );\n\n triAreasArray.free();\n\n if (!success) {\n return failTileMesh('Could not rasterize triangles');\n }\n }\n\n // Once all geometry is rasterized, we do initial pass of filtering to\n // remove unwanted overhangs caused by the conservative rasterization\n // as well as filter spans where the character cannot possibly stand.\n filterLowHangingWalkableObstacles(\n buildContext,\n tileConfig.walkableClimb,\n heightfield\n );\n filterLedgeSpans(\n buildContext,\n tileConfig.walkableHeight,\n tileConfig.walkableClimb,\n heightfield\n );\n filterWalkableLowHeightSpans(\n buildContext,\n tileConfig.walkableHeight,\n heightfield\n );\n\n // Compact the heightfield so that it is faster to handle from now on.\n // This will result more cache coherent data as well as the neighbours\n // between walkable cells will be calculated.\n const compactHeightfield = allocCompactHeightfield();\n tileIntermediate.compactHeightfield = compactHeightfield;\n\n if (\n !buildCompactHeightfield(\n buildContext,\n tileConfig.walkableHeight,\n tileConfig.walkableClimb,\n heightfield,\n compactHeightfield\n )\n ) {\n return failTileMesh('Could not build compact heightfield');\n }\n\n if (!keepIntermediates) {\n freeHeightfield(tileIntermediate.heightfield);\n tileIntermediate.heightfield = undefined;\n }\n\n // Erode the walkable area by agent radius\n if (\n !erodeWalkableArea(\n buildContext,\n tileConfig.walkableRadius,\n compactHeightfield\n )\n ) {\n return failTileMesh('Could not erode walkable area');\n }\n\n // (Optional) Mark areas\n // markConvexPolyArea(...)\n\n // Prepare for region partitioning, by calculating Distance field along the walkable surface.\n if (!buildDistanceField(buildContext, compactHeightfield)) {\n return failTileMesh('Failed to build distance field');\n }\n\n // Partition the walkable surface into simple regions without holes.\n if (\n !buildRegions(\n buildContext,\n compactHeightfield,\n tileConfig.borderSize,\n tileConfig.minRegionArea,\n tileConfig.mergeRegionArea\n )\n ) {\n return failTileMesh('Failed to build regions');\n }\n\n //\n // Trace and simplify region contours.\n //\n const contourSet = allocContourSet();\n tileIntermediate.contourSet = contourSet;\n\n if (\n !buildContours(\n buildContext,\n compactHeightfield,\n tileConfig.maxSimplificationError,\n tileConfig.maxEdgeLen,\n contourSet,\n Raw.Module.RC_CONTOUR_TESS_WALL_EDGES\n )\n ) {\n return failTileMesh('Failed to create contours');\n }\n\n //\n // Build polygons mesh from contours.\n //\n const polyMesh = allocPolyMesh();\n if (\n !buildPolyMesh(\n buildContext,\n contourSet,\n tileConfig.maxVertsPerPoly,\n polyMesh\n )\n ) {\n return failTileMesh('Failed to triangulate contours');\n }\n\n //\n // Create detail mesh which allows to access approximate height on each polygon.\n //\n const polyMeshDetail = allocPolyMeshDetail();\n if (\n !buildPolyMeshDetail(\n buildContext,\n polyMesh,\n compactHeightfield,\n tileConfig.detailSampleDist,\n tileConfig.detailSampleMaxError,\n polyMeshDetail\n )\n ) {\n return failTileMesh('Failed to build detail mesh');\n }\n\n if (!keepIntermediates) {\n freeCompactHeightfield(compactHeightfield);\n tileIntermediate.compactHeightfield = undefined;\n\n freeContourSet(contourSet);\n tileIntermediate.contourSet = undefined;\n }\n\n // Update poly flags from areas.\n for (let i = 0; i < polyMesh.npolys(); i++) {\n if (polyMesh.areas(i) == Raw.Recast.WALKABLE_AREA) {\n polyMesh.setAreas(i, 0);\n }\n if (polyMesh.areas(i) == 0) {\n polyMesh.setFlags(i, 1);\n }\n }\n\n const navMeshCreateParams = new NavMeshCreateParams();\n\n navMeshCreateParams.setPolyMeshCreateParams(polyMesh);\n navMeshCreateParams.setPolyMeshDetailCreateParams(polyMeshDetail);\n\n navMeshCreateParams.setWalkableHeight(tileConfig.walkableHeight);\n navMeshCreateParams.setWalkableRadius(tileConfig.walkableRadius);\n navMeshCreateParams.setWalkableClimb(tileConfig.walkableClimb);\n\n navMeshCreateParams.setCellSize(tileConfig.cs);\n navMeshCreateParams.setCellHeight(tileConfig.ch);\n\n navMeshCreateParams.setBuildBvTree(true);\n\n if (navMeshGeneratorConfig.offMeshConnections) {\n navMeshCreateParams.setOffMeshConnections(\n navMeshGeneratorConfig.offMeshConnections\n );\n }\n\n navMeshCreateParams.setTileX(tileX);\n navMeshCreateParams.setTileY(tileY);\n\n const createNavMeshDataResult = createNavMeshData(navMeshCreateParams);\n\n if (!createNavMeshDataResult.success) {\n return failTileMesh('Failed to create Detour navmesh data');\n }\n\n buildContext.log(\n Raw.Module.RC_LOG_PROGRESS,\n `>> Polymesh: ${polyMesh.nverts()} vertices ${polyMesh.npolys()} polygons`\n );\n\n return { success: true, data: createNavMeshDataResult.navMeshData };\n };\n\n buildContext.startTimer(Raw.Module.RC_TIMER_TEMP);\n\n const lastBuiltTileBmin: Vector3Tuple = [0, 0, 0];\n const lastBuiltTileBmax: Vector3Tuple = [0, 0, 0];\n\n for (let y = 0; y < tileHeight; y++) {\n for (let x = 0; x < tileWidth; x++) {\n lastBuiltTileBmin[0] = bbMin[0] + x * tcs;\n lastBuiltTileBmin[1] = bbMin[1];\n lastBuiltTileBmin[2] = bbMin[2] + y * tcs;\n\n lastBuiltTileBmax[0] = bbMin[0] + (x + 1) * tcs;\n lastBuiltTileBmax[1] = bbMax[1];\n lastBuiltTileBmax[2] = bbMin[2] + (y + 1) * tcs;\n\n const result = buildTileMesh(x, y, lastBuiltTileBmin, lastBuiltTileBmax);\n\n if (result.success && result.data) {\n navMesh.removeTile(navMesh.getTileRefAt(x, y, 0));\n\n const addTileResult = navMesh.addTile(\n result.data,\n Raw.Module.DT_TILE_FREE_DATA,\n 0\n );\n\n if (Raw.Detour.statusFailed(addTileResult.status)) {\n buildContext.log(\n Raw.Module.RC_LOG_WARNING,\n `Failed to add tile to nav mesh` +\n '\\n\\t' +\n `tx: ${x}, ty: ${y},` +\n `status: ${statusToReadableString(addTileResult.status)} (${\n addTileResult.status\n })`\n );\n\n result.data.free();\n }\n }\n }\n }\n\n buildContext.stopTimer(Raw.Module.RC_TIMER_TEMP);\n\n if (!keepIntermediates) {\n cleanup();\n }\n\n return {\n success: true,\n navMesh,\n intermediates,\n };\n};\n"],"names":["getBoundingBox","positions","indices","bbMin","x","Infinity","y","z","bbMax","i","length","ind","Math","min","max","vec3","toArray","dtIlog2","v","r","shift","Number","dtNextPow2","soloNavMeshGeneratorConfigDefaults","recastConfigDefaults","tileCacheGeneratorConfigDefaults","tileSize","expectedLayersPerTile","maxObstacles","createDefaultTileCacheMeshProcess","TileCacheMeshProcess","navMeshCreateParams","polyAreas","polyFlags","polyCount","set","tiledNavMeshGeneratorConfigDefaults","navMeshGeneratorConfig","keepIntermediates","buildContext","RecastBuildContext","intermediates","type","navMesh","NavMesh","fail","error","heightfield","freeHeightfield","undefined","compactHeightfield","freeCompactHeightfield","contourSet","freeContourSet","destroy","success","verts","nVerts","vertsArray","Arrays","VertsArray","copy","tris","nTris","trisArray","TrisArray","config","createRcConfig","minRegionArea","mergeRegionArea","detailSampleDist","cs","detailSampleMaxError","ch","gridSize","calcGridSize","width","height","allocHeightfield","createHeightfield","triAreasArray","TriAreasArray","resize","markWalkableTriangles","walkableSlopeAngle","rasterizeTriangles","walkableClimb","free","filterLowHangingWalkableObstacles","filterLedgeSpans","walkableHeight","filterWalkableLowHeightSpans","allocCompactHeightfield","buildCompactHeightfield","erodeWalkableArea","walkableRadius","buildDistanceField","buildRegions","borderSize","allocContourSet","buildContours","maxSimplificationError","maxEdgeLen","Raw","Module","RC_CONTOUR_TESS_WALL_EDGES","polyMesh","allocPolyMesh","buildPolyMesh","maxVertsPerPoly","polyMeshDetail","allocPolyMeshDetail","buildPolyMeshDetail","npolys","areas","Recast","WALKABLE_AREA","setAreas","setFlags","NavMeshCreateParams","setPolyMeshCreateParams","setPolyMeshDetailCreateParams","setWalkableHeight","setWalkableRadius","setWalkableClimb","setCellSize","setCellHeight","setBuildBvTree","offMeshConnections","setOffMeshConnections","createNavMeshDataResult","createNavMeshData","navMeshData","initSolo","chunkyTriMesh","tileIntermediates","tileCache","TileCache","cleanup","tileIntermediate","heightfieldLayerSet","freeHeightfieldLayerSet","recastConfig","floor","tileWidth","tileHeight","tileCacheParams","DetourTileCacheParams","create","orig","maxTiles","allocator","RecastLinearAllocator","compressor","RecastFastLZCompressor","tileCacheMeshProcess","init","fromArray","tileBits","maxPolysPerTile","navMeshParams","NavMeshParams","maxPolys","initTiled","RecastChunkyTriMesh","rasterizeTileLayers","tileX","tileY","tcs","tileConfig","cloneRcConfig","tileBoundsMin","tileBoundsMax","set_bmin","set_bmax","n","tbmin","tbmax","chunkIdsArray","ChunkIdsArray","nChunksOverlapping","getChunksOverlappingRect","nodeId","get_data","nNodeTris","nodes","nodeTrisArray","getNodeTris","allocHeightfieldLayerSet","buildHeightfieldLayers","tiles","nlayers","tile","TileCacheData","heightfieldLayer","layers","header","dtTileCacheLayerHeader","magic","Detour","TILECACHE_MAGIC","version","TILECACHE_VERSION","tx","ty","tlayer","heightfieldLayerBin","bmin","heightfieldLayerBmax","bmax","minx","maxx","miny","maxy","hmin","hmax","heights","getHeightfieldLayerHeights","getHeightfieldLayerAreas","cons","getHeightfieldLayerCons","status","buildTileCacheLayer","statusFailed","push","newTiles","tileCacheData","addResult","addTile","log","RC_LOG_WARNING","dtStatus","buildNavMeshTilesAt","buildTileMesh","failTileMesh","RC_LOG_ERROR","expandedTileBoundsMin","expandedTileBoundsMax","resetTimers","startTimer","RC_TIMER_TOTAL","RC_LOG_PROGRESS","maxTrisPerChunk","setTileX","setTileY","nverts","data","RC_TIMER_TEMP","lastBuiltTileBmin","lastBuiltTileBmax","result","removeTile","getTileRefAt","addTileResult","DT_TILE_FREE_DATA","statusToReadableString","stopTimer"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/generators/common.ts","../src/generators/generate-solo-nav-mesh.ts","../src/generators/generate-tile-cache.ts","../src/generators/generate-tiled-nav-mesh.ts"],"sourcesContent":["import { OffMeshConnectionParams, vec3 } from '@recast-navigation/core';\n\nexport const getBoundingBox = (\n positions: ArrayLike<number>,\n indices: ArrayLike<number>\n) => {\n const bbMin = { x: Infinity, y: Infinity, z: Infinity };\n const bbMax = { x: -Infinity, y: -Infinity, z: -Infinity };\n\n for (let i = 0; i < indices.length; i++) {\n const ind = indices[i];\n\n const x = positions[ind * 3];\n const y = positions[ind * 3 + 1];\n const z = positions[ind * 3 + 2];\n\n bbMin.x = Math.min(bbMin.x, x);\n bbMin.y = Math.min(bbMin.y, y);\n bbMin.z = Math.min(bbMin.z, z);\n\n bbMax.x = Math.max(bbMax.x, x);\n bbMax.y = Math.max(bbMax.y, y);\n bbMax.z = Math.max(bbMax.z, z);\n }\n\n return {\n bbMin: vec3.toArray(bbMin),\n bbMax: vec3.toArray(bbMax),\n };\n};\n\nexport const dtIlog2 = (v: number) => {\n let r = 0;\n let shift = 0;\n\n r = Number(v > 0xffff) << 4;\n v >>= r;\n\n shift = Number(v > 0xff) << 3;\n v >>= shift;\n r |= shift;\n\n shift = Number(v > 0xf) << 2;\n v >>= shift;\n r |= shift;\n\n shift = Number(v > 0x3) << 1;\n v >>= shift;\n r |= shift;\n r |= v >> 1;\n\n return r;\n};\n\nexport const dtNextPow2 = (v: number) => {\n v--;\n v |= v >> 1;\n v |= v >> 2;\n v |= v >> 4;\n v |= v >> 8;\n v |= v >> 16;\n v++;\n return v;\n};\n\nexport type OffMeshConnectionGeneratorParams = {\n offMeshConnections?: OffMeshConnectionParams[];\n};\n","import {\n Arrays,\n NavMesh,\n NavMeshCreateParams,\n Raw,\n RecastBuildContext,\n RecastCompactHeightfield,\n RecastConfig,\n RecastContourSet,\n RecastHeightfield,\n allocCompactHeightfield,\n allocContourSet,\n allocHeightfield,\n allocPolyMesh,\n allocPolyMeshDetail,\n buildCompactHeightfield,\n buildContours,\n buildDistanceField,\n buildPolyMesh,\n buildPolyMeshDetail,\n buildRegions,\n calcGridSize,\n createHeightfield,\n createNavMeshData,\n createRcConfig,\n erodeWalkableArea,\n filterLedgeSpans,\n filterLowHangingWalkableObstacles,\n filterWalkableLowHeightSpans,\n freeCompactHeightfield,\n freeContourSet,\n freeHeightfield,\n markWalkableTriangles,\n rasterizeTriangles,\n recastConfigDefaults,\n} from '@recast-navigation/core';\nimport { Pretty } from '../types';\nimport { OffMeshConnectionGeneratorParams, getBoundingBox } from './common';\n\nexport type SoloNavMeshGeneratorConfig = Pretty<\n Omit<RecastConfig, 'tileSize'> & OffMeshConnectionGeneratorParams\n>;\n\nexport const soloNavMeshGeneratorConfigDefaults: SoloNavMeshGeneratorConfig = {\n ...recastConfigDefaults,\n};\n\nexport type SoloNavMeshGeneratorIntermediates = {\n type: 'solo';\n buildContext: RecastBuildContext;\n heightfield?: RecastHeightfield;\n compactHeightfield?: RecastCompactHeightfield;\n contourSet?: RecastContourSet;\n};\n\ntype SoloNavMeshGeneratorSuccessResult = {\n navMesh: NavMesh;\n success: true;\n intermediates: SoloNavMeshGeneratorIntermediates;\n};\n\ntype SoloNavMeshGeneratorFailResult = {\n navMesh: undefined;\n success: false;\n intermediates: SoloNavMeshGeneratorIntermediates;\n error: string;\n};\n\nexport type SoloNavMeshGeneratorResult =\n | SoloNavMeshGeneratorSuccessResult\n | SoloNavMeshGeneratorFailResult;\n\n/**\n * Builds a Solo NavMesh from the given positions and indices.\n * @param positions a flat array of positions\n * @param indices a flat array of indices\n * @param navMeshGeneratorConfig optional configuration for the NavMesh generator\n * @param keepIntermediates if true intermediates will be returned\n */\nexport const generateSoloNavMesh = (\n positions: ArrayLike<number>,\n indices: ArrayLike<number>,\n navMeshGeneratorConfig: Partial<SoloNavMeshGeneratorConfig> = {},\n keepIntermediates = false\n): SoloNavMeshGeneratorResult => {\n const buildContext = new RecastBuildContext();\n\n const intermediates: SoloNavMeshGeneratorIntermediates = {\n type: 'solo',\n buildContext,\n };\n\n const navMesh = new NavMesh();\n\n const cleanup = () => {\n if (keepIntermediates) return;\n\n if (intermediates.heightfield) {\n freeHeightfield(intermediates.heightfield);\n intermediates.heightfield = undefined;\n }\n if (intermediates.compactHeightfield) {\n freeCompactHeightfield(intermediates.compactHeightfield);\n intermediates.compactHeightfield = undefined;\n }\n if (intermediates.contourSet) {\n freeContourSet(intermediates.contourSet);\n intermediates.contourSet = undefined;\n }\n };\n\n const fail = (error: string): SoloNavMeshGeneratorFailResult => {\n cleanup();\n\n navMesh.destroy();\n\n return {\n navMesh: undefined,\n success: false,\n intermediates,\n error,\n };\n };\n\n const verts = positions as number[];\n const nVerts = indices.length;\n const vertsArray = new Arrays.VertsArray();\n vertsArray.copy(verts, verts.length);\n\n const tris = indices as number[];\n const nTris = indices.length / 3;\n const trisArray = new Arrays.TrisArray();\n trisArray.copy(tris, tris.length);\n\n const { bbMin, bbMax } = getBoundingBox(positions, indices);\n\n //\n // Step 1. Initialize build config.\n //\n const config = createRcConfig({\n ...soloNavMeshGeneratorConfigDefaults,\n ...navMeshGeneratorConfig,\n });\n\n config.minRegionArea = config.minRegionArea * config.minRegionArea; // Note: area = size*size\n config.mergeRegionArea = config.mergeRegionArea * config.mergeRegionArea; // Note: area = size*size\n config.detailSampleDist =\n config.detailSampleDist < 0.9 ? 0 : config.cs * config.detailSampleDist;\n config.detailSampleMaxError = config.ch * config.detailSampleMaxError;\n\n const gridSize = calcGridSize(bbMin, bbMax, config.cs);\n config.width = gridSize.width;\n config.height = gridSize.height;\n\n //\n // Step 2. Rasterize input polygon soup.\n //\n // Allocate voxel heightfield where we rasterize our input data to.\n const heightfield = allocHeightfield();\n intermediates.heightfield = heightfield;\n\n if (\n !createHeightfield(\n buildContext,\n heightfield,\n config.width,\n config.height,\n bbMin,\n bbMax,\n config.cs,\n config.ch\n )\n ) {\n return fail('Could not create heightfield');\n }\n\n // Find triangles which are walkable based on their slope and rasterize them.\n // If your input data is multiple meshes, you can transform them here, calculate\n // the are type for each of the meshes and rasterize them.\n const triAreasArray = new Arrays.TriAreasArray();\n triAreasArray.resize(nTris);\n\n markWalkableTriangles(\n buildContext,\n config.walkableSlopeAngle,\n vertsArray,\n nVerts,\n trisArray,\n nTris,\n triAreasArray\n );\n\n if (\n !rasterizeTriangles(\n buildContext,\n vertsArray,\n nVerts,\n trisArray,\n triAreasArray,\n nTris,\n heightfield,\n config.walkableClimb\n )\n ) {\n return fail('Could not rasterize triangles');\n }\n\n triAreasArray.free();\n\n //\n // Step 3. Filter walkables surfaces.\n //\n // Once all geoemtry is rasterized, we do initial pass of filtering to\n // remove unwanted overhangs caused by the conservative rasterization\n // as well as filter spans where the character cannot possibly stand.\n filterLowHangingWalkableObstacles(\n buildContext,\n config.walkableClimb,\n heightfield\n );\n filterLedgeSpans(\n buildContext,\n config.walkableHeight,\n config.walkableClimb,\n heightfield\n );\n filterWalkableLowHeightSpans(\n buildContext,\n config.walkableHeight,\n heightfield\n );\n\n //\n // Step 4. Partition walkable surface to simple regions.\n //\n // Compact the heightfield so that it is faster to handle from now on.\n // This will result more cache coherent data as well as the neighbours\n // between walkable cells will be calculated.\n const compactHeightfield = allocCompactHeightfield();\n intermediates.compactHeightfield = compactHeightfield;\n\n if (\n !buildCompactHeightfield(\n buildContext,\n config.walkableHeight,\n config.walkableClimb,\n heightfield,\n compactHeightfield\n )\n ) {\n return fail('Failed to build compact data');\n }\n\n if (!keepIntermediates) {\n freeHeightfield(heightfield);\n intermediates.heightfield = undefined;\n }\n\n // Erode the walkable area by agent radius.\n if (\n !erodeWalkableArea(buildContext, config.walkableRadius, compactHeightfield)\n ) {\n return fail('Failed to erode walkable area');\n }\n\n // (Optional) Mark areas\n // markConvexPolyArea(...)\n\n // Prepare for region partitioning, by calculating Distance field along the walkable surface.\n if (!buildDistanceField(buildContext, compactHeightfield)) {\n return fail('Failed to build distance field');\n }\n\n // Partition the walkable surface into simple regions without holes.\n if (\n !buildRegions(\n buildContext,\n compactHeightfield,\n config.borderSize,\n config.minRegionArea,\n config.mergeRegionArea\n )\n ) {\n return fail('Failed to build regions');\n }\n\n //\n // Step 5. Trace and simplify region contours.\n //\n const contourSet = allocContourSet();\n intermediates.contourSet = contourSet;\n\n if (\n !buildContours(\n buildContext,\n compactHeightfield,\n config.maxSimplificationError,\n config.maxEdgeLen,\n contourSet,\n Raw.Module.RC_CONTOUR_TESS_WALL_EDGES\n )\n ) {\n return fail('Failed to create contours');\n }\n\n //\n // Step 6. Build polygons mesh from contours.\n //\n const polyMesh = allocPolyMesh();\n if (\n !buildPolyMesh(buildContext, contourSet, config.maxVertsPerPoly, polyMesh)\n ) {\n return fail('Failed to triangulate contours');\n }\n\n //\n // Step 7. Create detail mesh which allows to access approximate height on each polygon.\n //\n const polyMeshDetail = allocPolyMeshDetail();\n if (\n !buildPolyMeshDetail(\n buildContext,\n polyMesh,\n compactHeightfield,\n config.detailSampleDist,\n config.detailSampleMaxError,\n polyMeshDetail\n )\n ) {\n return fail('Failed to build detail mesh');\n }\n\n if (!keepIntermediates) {\n freeCompactHeightfield(compactHeightfield);\n intermediates.compactHeightfield = undefined;\n\n freeContourSet(contourSet);\n intermediates.contourSet = undefined;\n }\n\n //\n // Step 8. Create Detour data from Recast poly mesh.\n //\n for (let i = 0; i < polyMesh.npolys(); i++) {\n if (polyMesh.areas(i) == Raw.Recast.WALKABLE_AREA) {\n polyMesh.setAreas(i, 0);\n }\n if (polyMesh.areas(i) == 0) {\n polyMesh.setFlags(i, 1);\n }\n }\n\n const navMeshCreateParams = new NavMeshCreateParams();\n\n navMeshCreateParams.setPolyMeshCreateParams(polyMesh);\n navMeshCreateParams.setPolyMeshDetailCreateParams(polyMeshDetail);\n\n navMeshCreateParams.setWalkableHeight(config.walkableHeight);\n navMeshCreateParams.setWalkableRadius(config.walkableRadius);\n navMeshCreateParams.setWalkableClimb(config.walkableClimb);\n\n navMeshCreateParams.setCellSize(config.cs);\n navMeshCreateParams.setCellHeight(config.ch);\n\n navMeshCreateParams.setBuildBvTree(true);\n\n if (navMeshGeneratorConfig.offMeshConnections) {\n navMeshCreateParams.setOffMeshConnections(\n navMeshGeneratorConfig.offMeshConnections\n );\n }\n\n const createNavMeshDataResult = createNavMeshData(navMeshCreateParams);\n\n if (!createNavMeshDataResult.success) {\n return fail('Failed to create Detour navmesh data');\n }\n\n const { navMeshData } = createNavMeshDataResult;\n\n if (!navMesh.initSolo(navMeshData)) {\n return fail('Failed to create Detour navmesh');\n }\n\n return {\n success: true,\n navMesh,\n intermediates,\n };\n};\n","import {\n Arrays,\n DetourTileCacheParams,\n NavMesh,\n NavMeshParams,\n Raw,\n RecastBuildContext,\n RecastChunkyTriMesh,\n RecastCompactHeightfield,\n RecastConfig,\n RecastHeightfield,\n RecastHeightfieldLayerSet,\n TileCache,\n TileCacheMeshProcess,\n Vector2Tuple,\n Vector3Tuple,\n allocCompactHeightfield,\n allocHeightfield,\n allocHeightfieldLayerSet,\n buildCompactHeightfield,\n buildHeightfieldLayers,\n buildTileCacheLayer,\n calcGridSize,\n cloneRcConfig,\n createHeightfield,\n createRcConfig,\n erodeWalkableArea,\n filterLedgeSpans,\n filterLowHangingWalkableObstacles,\n filterWalkableLowHeightSpans,\n freeCompactHeightfield,\n freeHeightfield,\n freeHeightfieldLayerSet,\n getHeightfieldLayerAreas,\n getHeightfieldLayerCons,\n getHeightfieldLayerHeights,\n markWalkableTriangles,\n rasterizeTriangles,\n recastConfigDefaults,\n vec3,\n} from '@recast-navigation/core';\nimport type R from '@recast-navigation/wasm';\nimport { Pretty } from '../types';\nimport { dtIlog2, dtNextPow2, getBoundingBox } from './common';\n\ntype TileCacheRecastConfig = Omit<RecastConfig, 'minRegionArea' | 'maxEdgeLen'>;\n\nexport type TileCacheGeneratorConfig = Pretty<\n TileCacheRecastConfig & {\n /**\n * How many layers (or \"floors\") each navmesh tile is expected to have.\n */\n expectedLayersPerTile: number;\n\n /**\n * The max number of obstacles\n */\n maxObstacles: number;\n\n /**\n * The tile cache mesh process implementation.\n * If not provided, a default one is created via `createDefaultTileCacheMeshProcess()`\n * @default createDefaultTileCacheMeshProcess()\n */\n tileCacheMeshProcess?: TileCacheMeshProcess;\n }\n>;\n\nexport const tileCacheGeneratorConfigDefaults: TileCacheGeneratorConfig = {\n ...recastConfigDefaults,\n tileSize: 32,\n expectedLayersPerTile: 4,\n maxObstacles: 128,\n};\n\nexport type TileCacheGeneratorTileIntermediates = {\n tileX: number;\n tileY: number;\n heightfield?: RecastHeightfield;\n compactHeightfield?: RecastCompactHeightfield;\n heightfieldLayerSet?: RecastHeightfieldLayerSet;\n};\n\nexport type TileCacheGeneratorIntermediates = {\n type: 'tilecache';\n buildContext: RecastBuildContext;\n chunkyTriMesh?: RecastChunkyTriMesh;\n tileIntermediates: TileCacheGeneratorTileIntermediates[];\n};\n\ntype TileCacheGeneratorSuccessResult = {\n tileCache: TileCache;\n navMesh: NavMesh;\n success: true;\n intermediates: TileCacheGeneratorIntermediates;\n};\n\ntype TileCacheGeneratorFailResult = {\n tileCache: undefined;\n navMesh: undefined;\n success: false;\n error: string;\n intermediates: TileCacheGeneratorIntermediates;\n};\n\nexport type TileCacheGeneratorResult =\n | TileCacheGeneratorSuccessResult\n | TileCacheGeneratorFailResult;\n\nexport const createDefaultTileCacheMeshProcess = () =>\n new TileCacheMeshProcess((navMeshCreateParams, polyAreas, polyFlags) => {\n for (let i = 0; i < navMeshCreateParams.polyCount(); ++i) {\n polyAreas.set(i, 0);\n polyFlags.set(i, 1);\n }\n });\n\n/**\n * Builds a TileCache and NavMesh from the given positions and indices.\n * TileCache assumes small tiles (around 32-64 squared) and does some tricks to make the update fast.\n * @param positions a flat array of positions\n * @param indices a flat array of indices\n * @param navMeshConfig optional configuration for the NavMesh\n * @param keepIntermediates if true intermediates will be returned\n */\nexport const generateTileCache = (\n positions: ArrayLike<number>,\n indices: ArrayLike<number>,\n navMeshGeneratorConfig: Partial<TileCacheGeneratorConfig> = {},\n keepIntermediates = false\n): TileCacheGeneratorResult => {\n const buildContext = new RecastBuildContext();\n\n const intermediates: TileCacheGeneratorIntermediates = {\n type: 'tilecache',\n buildContext,\n chunkyTriMesh: undefined,\n tileIntermediates: [],\n };\n\n const tileCache = new TileCache();\n const navMesh = new NavMesh();\n\n const cleanup = () => {\n if (!keepIntermediates) {\n for (let i = 0; i < intermediates.tileIntermediates.length; i++) {\n const tileIntermediate = intermediates.tileIntermediates[i];\n\n if (tileIntermediate.heightfield) {\n freeHeightfield(tileIntermediate.heightfield);\n tileIntermediate.heightfield = undefined;\n }\n\n if (tileIntermediate.compactHeightfield) {\n freeCompactHeightfield(tileIntermediate.compactHeightfield);\n tileIntermediate.compactHeightfield = undefined;\n }\n\n if (tileIntermediate.heightfieldLayerSet) {\n freeHeightfieldLayerSet(tileIntermediate.heightfieldLayerSet);\n tileIntermediate.heightfieldLayerSet = undefined;\n }\n }\n }\n };\n\n const fail = (error: string): TileCacheGeneratorFailResult => {\n cleanup();\n\n tileCache.destroy();\n navMesh.destroy();\n\n return {\n success: false,\n navMesh: undefined,\n tileCache: undefined,\n intermediates,\n error,\n };\n };\n\n const verts = positions as number[];\n const nVerts = indices.length;\n const vertsArray = new Arrays.VertsArray();\n vertsArray.copy(verts, verts.length);\n\n const tris = indices as number[];\n const nTris = indices.length / 3;\n const trisArray = new Arrays.TrisArray();\n trisArray.copy(tris, tris.length);\n\n const { bbMin, bbMax } = getBoundingBox(positions, indices);\n\n const { expectedLayersPerTile, maxObstacles, ...recastConfig } = {\n ...tileCacheGeneratorConfigDefaults,\n ...navMeshGeneratorConfig,\n };\n\n //\n // Step 1. Initialize build config.\n //\n const config = createRcConfig(recastConfig);\n\n const gridSize = calcGridSize(bbMin, bbMax, config.cs);\n config.width = gridSize.width;\n config.height = gridSize.height;\n\n config.minRegionArea = config.minRegionArea * config.minRegionArea; // Note: area = size*size\n config.mergeRegionArea = config.mergeRegionArea * config.mergeRegionArea; // Note: area = size*size\n config.detailSampleDist =\n config.detailSampleDist < 0.9 ? 0 : config.cs * config.detailSampleDist;\n config.detailSampleMaxError = config.ch * config.detailSampleMaxError;\n\n const tileSize = Math.floor(config.tileSize);\n const tileWidth = Math.floor((config.width + tileSize - 1) / tileSize);\n const tileHeight = Math.floor((config.height + tileSize - 1) / tileSize);\n\n // Generation params\n config.borderSize = config.walkableRadius + 3; // Reserve enough padding.\n config.width = config.tileSize + config.borderSize * 2;\n config.height = config.tileSize + config.borderSize * 2;\n\n // Tile cache params\n const tileCacheParams = DetourTileCacheParams.create({\n orig: bbMin,\n cs: config.cs,\n ch: config.ch,\n width: config.tileSize,\n height: config.tileSize,\n walkableHeight: config.walkableHeight,\n walkableRadius: config.walkableRadius,\n walkableClimb: config.walkableClimb,\n maxSimplificationError: config.maxSimplificationError,\n maxTiles: tileWidth * tileHeight * expectedLayersPerTile,\n maxObstacles,\n });\n\n const allocator = new Raw.RecastLinearAllocator(32000);\n const compressor = new Raw.RecastFastLZCompressor();\n\n const tileCacheMeshProcess =\n navMeshGeneratorConfig.tileCacheMeshProcess ??\n createDefaultTileCacheMeshProcess();\n\n if (\n !tileCache.init(\n tileCacheParams,\n allocator,\n compressor,\n tileCacheMeshProcess\n )\n ) {\n return fail('Failed to initialize tile cache');\n }\n\n const orig = vec3.fromArray(bbMin);\n\n // Max tiles and max polys affect how the tile IDs are caculated.\n // There are 22 bits available for identifying a tile and a polygon.\n let tileBits = Math.min(\n Math.floor(\n dtIlog2(dtNextPow2(tileWidth * tileHeight * expectedLayersPerTile))\n ),\n 14\n );\n if (tileBits > 14) {\n tileBits = 14;\n }\n const polyBits = 22 - tileBits;\n\n const maxTiles = 1 << tileBits;\n const maxPolysPerTile = 1 << polyBits;\n\n const navMeshParams = NavMeshParams.create({\n orig,\n tileWidth: config.tileSize * config.cs,\n tileHeight: config.tileSize * config.cs,\n maxTiles,\n maxPolys: maxPolysPerTile,\n });\n\n if (!navMesh.initTiled(navMeshParams)) {\n return fail('Failed to initialize tiled navmesh');\n }\n\n const chunkyTriMesh = new RecastChunkyTriMesh();\n intermediates.chunkyTriMesh = chunkyTriMesh;\n\n if (!chunkyTriMesh.init(vertsArray, trisArray, nTris, 256)) {\n return fail('Failed to build chunky triangle mesh');\n }\n\n const rasterizeTileLayers = (tileX: number, tileY: number) => {\n // Tile intermediates\n const tileIntermediates: TileCacheGeneratorTileIntermediates = {\n tileX,\n tileY,\n };\n\n // Tile bounds\n const tcs = config.tileSize * config.cs;\n\n const tileConfig = cloneRcConfig(config);\n\n const tileBoundsMin: Vector3Tuple = [\n bbMin[0] + tileX * tcs,\n bbMin[1],\n bbMin[2] + tileY * tcs,\n ];\n\n const tileBoundsMax: Vector3Tuple = [\n bbMin[0] + (tileX + 1) * tcs,\n bbMax[1],\n bbMin[2] + (tileY + 1) * tcs,\n ];\n\n tileBoundsMin[0] -= tileConfig.borderSize * tileConfig.cs;\n tileBoundsMin[2] -= tileConfig.borderSize * tileConfig.cs;\n tileBoundsMax[0] += tileConfig.borderSize * tileConfig.cs;\n tileBoundsMax[2] += tileConfig.borderSize * tileConfig.cs;\n\n tileConfig.set_bmin(0, tileBoundsMin[0]);\n tileConfig.set_bmin(1, tileBoundsMin[1]);\n tileConfig.set_bmin(2, tileBoundsMin[2]);\n\n tileConfig.set_bmax(0, tileBoundsMax[0]);\n tileConfig.set_bmax(1, tileBoundsMax[1]);\n tileConfig.set_bmax(2, tileBoundsMax[2]);\n\n // Allocate voxel heightfield where we rasterize our input data to.\n const heightfield = allocHeightfield();\n tileIntermediates.heightfield = heightfield;\n\n if (\n !createHeightfield(\n buildContext,\n heightfield,\n tileConfig.width,\n tileConfig.height,\n tileBoundsMin,\n tileBoundsMax,\n tileConfig.cs,\n tileConfig.ch\n )\n ) {\n return { n: 0 };\n }\n\n const tbmin: Vector2Tuple = [tileBoundsMin[0], tileBoundsMin[2]];\n const tbmax: Vector2Tuple = [tileBoundsMax[0], tileBoundsMax[2]];\n\n // TODO: Make grow when returning too many items.\n const maxChunkIds = 512;\n const chunkIdsArray = new Arrays.ChunkIdsArray();\n chunkIdsArray.resize(maxChunkIds);\n\n const nChunksOverlapping = chunkyTriMesh.getChunksOverlappingRect(\n tbmin,\n tbmax,\n chunkIdsArray,\n maxChunkIds\n );\n\n if (nChunksOverlapping === 0) {\n return { n: 0 };\n }\n\n for (let i = 0; i < nChunksOverlapping; ++i) {\n const nodeId = chunkIdsArray.get_data(i);\n const node = chunkyTriMesh.nodes(nodeId);\n const nNodeTris = node.n;\n\n const nodeTrisArray = chunkyTriMesh.getNodeTris(nodeId);\n\n const triAreasArray = new Arrays.TriAreasArray();\n triAreasArray.resize(nNodeTris);\n\n // Find triangles which are walkable based on their slope and rasterize them.\n // If your input data is multiple meshes, you can transform them here, calculate\n // the are type for each of the meshes and rasterize them.\n markWalkableTriangles(\n buildContext,\n tileConfig.walkableSlopeAngle,\n vertsArray,\n nVerts,\n nodeTrisArray,\n nNodeTris,\n triAreasArray\n );\n\n const success = rasterizeTriangles(\n buildContext,\n vertsArray,\n nVerts,\n nodeTrisArray,\n triAreasArray,\n nNodeTris,\n heightfield,\n tileConfig.walkableClimb\n );\n\n triAreasArray.free();\n\n if (!success) {\n return { n: 0 };\n }\n }\n\n // Once all geometry is rasterized, we do initial pass of filtering to\n // remove unwanted overhangs caused by the conservative rasterization\n // as well as filter spans where the character cannot possibly stand.\n filterLowHangingWalkableObstacles(\n buildContext,\n config.walkableClimb,\n heightfield\n );\n filterLedgeSpans(\n buildContext,\n config.walkableHeight,\n config.walkableClimb,\n heightfield\n );\n filterWalkableLowHeightSpans(\n buildContext,\n config.walkableHeight,\n heightfield\n );\n\n const compactHeightfield = allocCompactHeightfield();\n if (\n !buildCompactHeightfield(\n buildContext,\n config.walkableHeight,\n config.walkableClimb,\n heightfield,\n compactHeightfield\n )\n ) {\n return { n: 0 };\n }\n\n if (!keepIntermediates) {\n freeHeightfield(tileIntermediates.heightfield);\n tileIntermediates.heightfield = undefined;\n }\n\n // Erode the walkable area by agent radius\n if (\n !erodeWalkableArea(\n buildContext,\n config.walkableRadius,\n compactHeightfield\n )\n ) {\n return { n: 0 };\n }\n\n const heightfieldLayerSet = allocHeightfieldLayerSet();\n if (\n !buildHeightfieldLayers(\n buildContext,\n compactHeightfield,\n config.borderSize,\n config.walkableHeight,\n heightfieldLayerSet\n )\n ) {\n return { n: 0 };\n }\n\n if (!keepIntermediates) {\n freeCompactHeightfield(compactHeightfield);\n tileIntermediates.compactHeightfield = undefined;\n }\n\n const tiles: R.UnsignedCharArray[] = [];\n\n for (let i = 0; i < heightfieldLayerSet.nlayers(); i++) {\n const tile = new Arrays.TileCacheData();\n const heightfieldLayer = heightfieldLayerSet.layers(i);\n\n // Store header\n const header = new Raw.dtTileCacheLayerHeader();\n header.magic = Raw.Detour.TILECACHE_MAGIC;\n header.version = Raw.Detour.TILECACHE_VERSION;\n\n // Tile layer location in the navmesh\n header.tx = tileX;\n header.ty = tileY;\n header.tlayer = i;\n\n const heightfieldLayerBin = heightfieldLayer.bmin();\n const heightfieldLayerBmax = heightfieldLayer.bmax();\n header.set_bmin(0, heightfieldLayerBin.x);\n header.set_bmin(1, heightfieldLayerBin.y);\n header.set_bmin(2, heightfieldLayerBin.z);\n\n header.set_bmax(0, heightfieldLayerBmax.x);\n header.set_bmax(1, heightfieldLayerBmax.y);\n header.set_bmax(2, heightfieldLayerBmax.z);\n\n // Tile info\n header.width = heightfieldLayer.width();\n header.height = heightfieldLayer.height();\n header.minx = heightfieldLayer.minx();\n header.maxx = heightfieldLayer.maxx();\n header.miny = heightfieldLayer.miny();\n header.maxy = heightfieldLayer.maxy();\n header.hmin = heightfieldLayer.hmin();\n header.hmax = heightfieldLayer.hmax();\n\n const heights = getHeightfieldLayerHeights(heightfieldLayer);\n const areas = getHeightfieldLayerAreas(heightfieldLayer);\n const cons = getHeightfieldLayerCons(heightfieldLayer);\n\n const status = buildTileCacheLayer(\n compressor,\n header,\n heights,\n areas,\n cons,\n tile\n );\n\n if (Raw.Detour.statusFailed(status)) {\n return { n: 0 };\n }\n\n tiles.push(tile);\n }\n\n if (!keepIntermediates) {\n freeHeightfieldLayerSet(heightfieldLayerSet);\n tileIntermediates.heightfieldLayerSet = undefined;\n }\n\n intermediates.tileIntermediates.push(tileIntermediates);\n\n return { n: tiles.length, tiles };\n };\n\n // Preprocess tiles\n for (let y = 0; y < tileHeight; ++y) {\n for (let x = 0; x < tileWidth; ++x) {\n const { n, tiles: newTiles } = rasterizeTileLayers(x, y);\n\n if (n > 0 && newTiles) {\n for (let i = 0; i < n; i++) {\n const tileCacheData = newTiles[i];\n\n const addResult = tileCache.addTile(tileCacheData);\n\n if (Raw.Detour.statusFailed(addResult.status)) {\n buildContext.log(\n Raw.Module.RC_LOG_WARNING,\n `Failed to add tile to tile cache - tx: ${x}, ty: ${y}`\n );\n continue;\n }\n }\n }\n }\n }\n\n // Build initial meshes\n for (let y = 0; y < tileHeight; y++) {\n for (let x = 0; x < tileWidth; x++) {\n const dtStatus = tileCache.buildNavMeshTilesAt(x, y, navMesh);\n\n if (Raw.Detour.statusFailed(dtStatus)) {\n return fail(`Failed to build nav mesh tiles at ${x}, ${y}`);\n }\n }\n }\n\n cleanup();\n\n return {\n success: true,\n tileCache,\n navMesh,\n intermediates,\n };\n};\n","import {\n Arrays,\n NavMesh,\n NavMeshCreateParams,\n NavMeshParams,\n Raw,\n RecastBuildContext,\n RecastChunkyTriMesh,\n RecastCompactHeightfield,\n RecastConfig,\n RecastContourSet,\n RecastHeightfield,\n Vector2Tuple,\n Vector3Tuple,\n allocCompactHeightfield,\n allocContourSet,\n allocHeightfield,\n allocPolyMesh,\n allocPolyMeshDetail,\n buildCompactHeightfield,\n buildContours,\n buildDistanceField,\n buildPolyMesh,\n buildPolyMeshDetail,\n buildRegions,\n calcGridSize,\n cloneRcConfig,\n createHeightfield,\n createNavMeshData,\n createRcConfig,\n statusToReadableString,\n erodeWalkableArea,\n filterLedgeSpans,\n filterLowHangingWalkableObstacles,\n filterWalkableLowHeightSpans,\n freeCompactHeightfield,\n freeContourSet,\n freeHeightfield,\n markWalkableTriangles,\n rasterizeTriangles,\n recastConfigDefaults,\n vec3,\n} from '@recast-navigation/core';\nimport type R from '@recast-navigation/wasm';\nimport { Pretty } from '../types';\nimport {\n OffMeshConnectionGeneratorParams,\n dtIlog2,\n dtNextPow2,\n getBoundingBox,\n} from './common';\n\nexport type TiledNavMeshGeneratorConfig = Pretty<\n RecastConfig & OffMeshConnectionGeneratorParams\n>;\n\nexport const tiledNavMeshGeneratorConfigDefaults: TiledNavMeshGeneratorConfig =\n {\n ...recastConfigDefaults,\n };\n\nexport type TiledNavMeshGeneratorIntermediates = {\n type: 'tiled';\n buildContext: RecastBuildContext;\n chunkyTriMesh?: RecastChunkyTriMesh;\n tileIntermediates: {\n tileX: number;\n tileY: number;\n heightfield?: RecastHeightfield;\n compactHeightfield?: RecastCompactHeightfield;\n contourSet?: RecastContourSet;\n }[];\n};\n\ntype TiledNavMeshGeneratorSuccessResult = {\n navMesh: NavMesh;\n success: true;\n intermediates: TiledNavMeshGeneratorIntermediates;\n};\n\ntype TiledNavMeshGeneratorFailResult = {\n navMesh: undefined;\n success: false;\n intermediates: TiledNavMeshGeneratorIntermediates;\n error: string;\n};\n\nexport type TiledNavMeshGeneratorResult =\n | TiledNavMeshGeneratorSuccessResult\n | TiledNavMeshGeneratorFailResult;\n\n/**\n * Builds a Tiled NavMesh\n * @param positions a flat array of positions\n * @param indices a flat array of indices\n * @param navMeshGeneratorConfig optional configuration for the NavMesh generator\n * @param keepIntermediates if true intermediates will be returned\n */\nexport const generateTiledNavMesh = (\n positions: ArrayLike<number>,\n indices: ArrayLike<number>,\n navMeshGeneratorConfig: Partial<TiledNavMeshGeneratorConfig> = {},\n keepIntermediates = false\n): TiledNavMeshGeneratorResult => {\n const buildContext = new RecastBuildContext();\n\n const intermediates: TiledNavMeshGeneratorIntermediates = {\n type: 'tiled',\n buildContext,\n chunkyTriMesh: undefined,\n tileIntermediates: [],\n };\n\n const navMesh = new NavMesh();\n\n const cleanup = () => {\n if (keepIntermediates) return;\n\n for (let i = 0; i < intermediates.tileIntermediates.length; i++) {\n const tileIntermediate = intermediates.tileIntermediates[i];\n\n if (tileIntermediate.compactHeightfield) {\n freeCompactHeightfield(tileIntermediate.compactHeightfield);\n }\n\n if (tileIntermediate.heightfield) {\n freeHeightfield(tileIntermediate.heightfield);\n }\n\n if (tileIntermediate.contourSet) {\n freeContourSet(tileIntermediate.contourSet);\n }\n }\n\n if (intermediates.chunkyTriMesh) {\n intermediates.chunkyTriMesh = undefined;\n }\n };\n\n const fail = (error: string): TiledNavMeshGeneratorFailResult => {\n cleanup();\n\n navMesh.destroy();\n\n return {\n success: false,\n navMesh: undefined,\n intermediates,\n error,\n };\n };\n\n //\n // Initialize build config.\n //\n const config = createRcConfig({\n ...tiledNavMeshGeneratorConfigDefaults,\n ...navMeshGeneratorConfig,\n });\n\n /* get input bounding box */\n const { bbMin, bbMax } = getBoundingBox(positions, indices);\n\n /* grid size */\n const gridSize = calcGridSize(bbMin, bbMax, config.cs);\n config.width = gridSize.width;\n config.height = gridSize.height;\n\n config.minRegionArea = config.minRegionArea * config.minRegionArea; // Note: area = size*size\n config.mergeRegionArea = config.mergeRegionArea * config.mergeRegionArea; // Note: area = size*size\n config.tileSize = Math.floor(config.tileSize);\n config.borderSize = config.walkableRadius + 3; // Reserve enough padding.\n config.width = config.tileSize + config.borderSize * 2;\n config.height = config.tileSize + config.borderSize * 2;\n config.detailSampleDist =\n config.detailSampleDist < 0.9 ? 0 : config.cs * config.detailSampleDist;\n config.detailSampleMaxError = config.ch * config.detailSampleMaxError;\n\n // tile size\n const tileSize = Math.floor(config.tileSize);\n const tileWidth = Math.floor((gridSize.width + tileSize - 1) / tileSize);\n const tileHeight = Math.floor((gridSize.height + tileSize - 1) / tileSize);\n const tcs = config.tileSize * config.cs;\n\n /* verts */\n const verts = positions as number[];\n const nVerts = indices.length;\n const vertsArray = new Arrays.VertsArray();\n vertsArray.copy(verts, verts.length);\n\n /* tris */\n const tris = indices as number[];\n const nTris = indices.length / 3;\n const trisArray = new Arrays.TrisArray();\n trisArray.copy(tris, tris.length);\n\n /* Create dtNavMeshParams, initialise nav mesh for tiled use */\n const orig = vec3.fromArray(bbMin);\n\n // Max tiles and max polys affect how the tile IDs are caculated.\n // There are 22 bits available for identifying a tile and a polygon.\n let tileBits = Math.min(\n Math.floor(dtIlog2(dtNextPow2(tileWidth * tileHeight))),\n 14\n );\n if (tileBits > 14) tileBits = 14;\n const polyBits = 22 - tileBits;\n\n const maxTiles = 1 << tileBits;\n const maxPolysPerTile = 1 << polyBits;\n\n const navMeshParams = NavMeshParams.create({\n orig,\n tileWidth: config.tileSize * config.cs,\n tileHeight: config.tileSize * config.cs,\n maxTiles,\n maxPolys: maxPolysPerTile,\n });\n\n if (!navMesh.initTiled(navMeshParams)) {\n return fail('Could not init nav mesh for tiled use');\n }\n\n /* create chunky tri mesh */\n const chunkyTriMesh = new RecastChunkyTriMesh();\n intermediates.chunkyTriMesh = chunkyTriMesh;\n\n if (!chunkyTriMesh.init(vertsArray, trisArray, nTris, 256)) {\n return fail('Failed to build chunky triangle mesh');\n }\n\n /** @internal */\n const buildTileMesh = (\n tileX: number,\n tileY: number,\n tileBoundsMin: Vector3Tuple,\n tileBoundsMax: Vector3Tuple\n ):\n | { success: true; data?: R.UnsignedCharArray }\n | { success: false; error: string } => {\n const failTileMesh = (error: string) => {\n buildContext.log(Raw.Module.RC_LOG_ERROR, error);\n\n return { success: false as const, error };\n };\n\n const tileIntermediate: {\n tileX: number;\n tileY: number;\n heightfield?: RecastHeightfield;\n compactHeightfield?: RecastCompactHeightfield;\n contourSet?: RecastContourSet;\n } = { tileX, tileY };\n\n intermediates.tileIntermediates.push(tileIntermediate);\n\n const tileConfig = cloneRcConfig(config);\n\n // Expand the heightfield bounding box by border size to find the extents of geometry we need to build this tile.\n //\n // This is done in order to make sure that the navmesh tiles connect correctly at the borders,\n // and the obstacles close to the border work correctly with the dilation process.\n // No polygons (or contours) will be created on the border area.\n //\n // IMPORTANT!\n //\n // :''''''''':\n // : +-----+ :\n // : | | :\n // : | |<--- tile to build\n // : | | :\n // : +-----+ :<-- geometry needed\n // :.........:\n //\n // You should use this bounding box to query your input geometry.\n //\n // For example if you build a navmesh for terrain, and want the navmesh tiles to match the terrain tile size\n // you will need to pass in data from neighbour terrain tiles too! In a simple case, just pass in all the 8 neighbours,\n // or use the bounding box below to only pass in a sliver of each of the 8 neighbours.\n\n const expandedTileBoundsMin = [...tileBoundsMin] as Vector3Tuple;\n const expandedTileBoundsMax = [...tileBoundsMax] as Vector3Tuple;\n\n expandedTileBoundsMin[0] -= tileConfig.borderSize * tileConfig.cs;\n expandedTileBoundsMin[2] -= tileConfig.borderSize * tileConfig.cs;\n\n expandedTileBoundsMax[0] += tileConfig.borderSize * tileConfig.cs;\n expandedTileBoundsMax[2] += tileConfig.borderSize * tileConfig.cs;\n\n tileConfig.set_bmin(0, expandedTileBoundsMin[0]);\n tileConfig.set_bmin(1, expandedTileBoundsMin[1]);\n tileConfig.set_bmin(2, expandedTileBoundsMin[2]);\n\n tileConfig.set_bmax(0, expandedTileBoundsMax[0]);\n tileConfig.set_bmax(1, expandedTileBoundsMax[1]);\n tileConfig.set_bmax(2, expandedTileBoundsMax[2]);\n\n // Reset build timer\n buildContext.resetTimers();\n\n // Start the build process\n buildContext.startTimer(Raw.Module.RC_TIMER_TOTAL);\n\n buildContext.log(\n Raw.Module.RC_LOG_PROGRESS,\n `Building tile ${intermediates.tileIntermediates.length} at x: ${tileX}, y: ${tileY}`\n );\n buildContext.log(\n Raw.Module.RC_LOG_PROGRESS,\n ` - ${config.width} x ${config.height} cells`\n );\n buildContext.log(\n Raw.Module.RC_LOG_PROGRESS,\n ` - ${nVerts / 1000}fK verts, ${nTris / 1000}K tris`\n );\n\n // Allocate voxel heightfield where we rasterize our input data to.\n const heightfield = allocHeightfield();\n tileIntermediate.heightfield = heightfield;\n\n if (\n !createHeightfield(\n buildContext,\n heightfield,\n tileConfig.width,\n tileConfig.height,\n expandedTileBoundsMin,\n expandedTileBoundsMax,\n tileConfig.cs,\n tileConfig.ch\n )\n ) {\n return failTileMesh('Could not create heightfield');\n }\n\n // Allocate array that can hold triangle flags.\n // If you have multiple meshes you need to process, allocate\n // and array which can hold the max number of triangles you need to process.\n const triAreas = new Arrays.TriAreasArray();\n triAreas.resize(chunkyTriMesh.maxTrisPerChunk());\n\n const tbmin: Vector2Tuple = [\n expandedTileBoundsMin[0],\n expandedTileBoundsMin[2],\n ];\n const tbmax: Vector2Tuple = [\n expandedTileBoundsMax[0],\n expandedTileBoundsMax[2],\n ];\n\n // TODO: Make grow when returning too many items.\n const maxChunkIds = 512;\n const chunkIdsArray = new Arrays.ChunkIdsArray();\n chunkIdsArray.resize(maxChunkIds);\n\n const nChunksOverlapping = chunkyTriMesh.getChunksOverlappingRect(\n tbmin,\n tbmax,\n chunkIdsArray,\n maxChunkIds\n );\n\n if (nChunksOverlapping === 0) {\n return { success: true };\n }\n\n for (let i = 0; i < nChunksOverlapping; ++i) {\n const nodeId = chunkIdsArray.get_data(i);\n const node = chunkyTriMesh.nodes(nodeId);\n const nNodeTris = node.n;\n\n const nodeTrisArray = chunkyTriMesh.getNodeTris(nodeId);\n\n const triAreasArray = new Arrays.TriAreasArray();\n triAreasArray.resize(nNodeTris);\n\n // Find triangles which are walkable based on their slope and rasterize them.\n // If your input data is multiple meshes, you can transform them here, calculate\n // the are type for each of the meshes and rasterize them.\n markWalkableTriangles(\n buildContext,\n tileConfig.walkableSlopeAngle,\n vertsArray,\n nVerts,\n nodeTrisArray,\n nNodeTris,\n triAreasArray\n );\n\n const success = rasterizeTriangles(\n buildContext,\n vertsArray,\n nVerts,\n nodeTrisArray,\n triAreasArray,\n nNodeTris,\n heightfield,\n tileConfig.walkableClimb\n );\n\n triAreasArray.free();\n\n if (!success) {\n return failTileMesh('Could not rasterize triangles');\n }\n }\n\n // Once all geometry is rasterized, we do initial pass of filtering to\n // remove unwanted overhangs caused by the conservative rasterization\n // as well as filter spans where the character cannot possibly stand.\n filterLowHangingWalkableObstacles(\n buildContext,\n tileConfig.walkableClimb,\n heightfield\n );\n filterLedgeSpans(\n buildContext,\n tileConfig.walkableHeight,\n tileConfig.walkableClimb,\n heightfield\n );\n filterWalkableLowHeightSpans(\n buildContext,\n tileConfig.walkableHeight,\n heightfield\n );\n\n // Compact the heightfield so that it is faster to handle from now on.\n // This will result more cache coherent data as well as the neighbours\n // between walkable cells will be calculated.\n const compactHeightfield = allocCompactHeightfield();\n tileIntermediate.compactHeightfield = compactHeightfield;\n\n if (\n !buildCompactHeightfield(\n buildContext,\n tileConfig.walkableHeight,\n tileConfig.walkableClimb,\n heightfield,\n compactHeightfield\n )\n ) {\n return failTileMesh('Could not build compact heightfield');\n }\n\n if (!keepIntermediates) {\n freeHeightfield(tileIntermediate.heightfield);\n tileIntermediate.heightfield = undefined;\n }\n\n // Erode the walkable area by agent radius\n if (\n !erodeWalkableArea(\n buildContext,\n tileConfig.walkableRadius,\n compactHeightfield\n )\n ) {\n return failTileMesh('Could not erode walkable area');\n }\n\n // (Optional) Mark areas\n // markConvexPolyArea(...)\n\n // Prepare for region partitioning, by calculating Distance field along the walkable surface.\n if (!buildDistanceField(buildContext, compactHeightfield)) {\n return failTileMesh('Failed to build distance field');\n }\n\n // Partition the walkable surface into simple regions without holes.\n if (\n !buildRegions(\n buildContext,\n compactHeightfield,\n tileConfig.borderSize,\n tileConfig.minRegionArea,\n tileConfig.mergeRegionArea\n )\n ) {\n return failTileMesh('Failed to build regions');\n }\n\n //\n // Trace and simplify region contours.\n //\n const contourSet = allocContourSet();\n tileIntermediate.contourSet = contourSet;\n\n if (\n !buildContours(\n buildContext,\n compactHeightfield,\n tileConfig.maxSimplificationError,\n tileConfig.maxEdgeLen,\n contourSet,\n Raw.Module.RC_CONTOUR_TESS_WALL_EDGES\n )\n ) {\n return failTileMesh('Failed to create contours');\n }\n\n //\n // Build polygons mesh from contours.\n //\n const polyMesh = allocPolyMesh();\n if (\n !buildPolyMesh(\n buildContext,\n contourSet,\n tileConfig.maxVertsPerPoly,\n polyMesh\n )\n ) {\n return failTileMesh('Failed to triangulate contours');\n }\n\n //\n // Create detail mesh which allows to access approximate height on each polygon.\n //\n const polyMeshDetail = allocPolyMeshDetail();\n if (\n !buildPolyMeshDetail(\n buildContext,\n polyMesh,\n compactHeightfield,\n tileConfig.detailSampleDist,\n tileConfig.detailSampleMaxError,\n polyMeshDetail\n )\n ) {\n return failTileMesh('Failed to build detail mesh');\n }\n\n if (!keepIntermediates) {\n freeCompactHeightfield(compactHeightfield);\n tileIntermediate.compactHeightfield = undefined;\n\n freeContourSet(contourSet);\n tileIntermediate.contourSet = undefined;\n }\n\n // Update poly flags from areas.\n for (let i = 0; i < polyMesh.npolys(); i++) {\n if (polyMesh.areas(i) == Raw.Recast.WALKABLE_AREA) {\n polyMesh.setAreas(i, 0);\n }\n if (polyMesh.areas(i) == 0) {\n polyMesh.setFlags(i, 1);\n }\n }\n\n const navMeshCreateParams = new NavMeshCreateParams();\n\n navMeshCreateParams.setPolyMeshCreateParams(polyMesh);\n navMeshCreateParams.setPolyMeshDetailCreateParams(polyMeshDetail);\n\n navMeshCreateParams.setWalkableHeight(tileConfig.walkableHeight);\n navMeshCreateParams.setWalkableRadius(tileConfig.walkableRadius);\n navMeshCreateParams.setWalkableClimb(tileConfig.walkableClimb);\n\n navMeshCreateParams.setCellSize(tileConfig.cs);\n navMeshCreateParams.setCellHeight(tileConfig.ch);\n\n navMeshCreateParams.setBuildBvTree(true);\n\n if (navMeshGeneratorConfig.offMeshConnections) {\n navMeshCreateParams.setOffMeshConnections(\n navMeshGeneratorConfig.offMeshConnections\n );\n }\n\n navMeshCreateParams.setTileX(tileX);\n navMeshCreateParams.setTileY(tileY);\n\n const createNavMeshDataResult = createNavMeshData(navMeshCreateParams);\n\n if (!createNavMeshDataResult.success) {\n return failTileMesh('Failed to create Detour navmesh data');\n }\n\n buildContext.log(\n Raw.Module.RC_LOG_PROGRESS,\n `>> Polymesh: ${polyMesh.nverts()} vertices ${polyMesh.npolys()} polygons`\n );\n\n return { success: true, data: createNavMeshDataResult.navMeshData };\n };\n\n buildContext.startTimer(Raw.Module.RC_TIMER_TEMP);\n\n const lastBuiltTileBmin: Vector3Tuple = [0, 0, 0];\n const lastBuiltTileBmax: Vector3Tuple = [0, 0, 0];\n\n for (let y = 0; y < tileHeight; y++) {\n for (let x = 0; x < tileWidth; x++) {\n lastBuiltTileBmin[0] = bbMin[0] + x * tcs;\n lastBuiltTileBmin[1] = bbMin[1];\n lastBuiltTileBmin[2] = bbMin[2] + y * tcs;\n\n lastBuiltTileBmax[0] = bbMin[0] + (x + 1) * tcs;\n lastBuiltTileBmax[1] = bbMax[1];\n lastBuiltTileBmax[2] = bbMin[2] + (y + 1) * tcs;\n\n const result = buildTileMesh(x, y, lastBuiltTileBmin, lastBuiltTileBmax);\n\n if (result.success && result.data) {\n navMesh.removeTile(navMesh.getTileRefAt(x, y, 0));\n\n const addTileResult = navMesh.addTile(\n result.data,\n Raw.Module.DT_TILE_FREE_DATA,\n 0\n );\n\n if (Raw.Detour.statusFailed(addTileResult.status)) {\n buildContext.log(\n Raw.Module.RC_LOG_WARNING,\n `Failed to add tile to nav mesh` +\n '\\n\\t' +\n `tx: ${x}, ty: ${y},` +\n `status: ${statusToReadableString(addTileResult.status)} (${\n addTileResult.status\n })`\n );\n\n result.data.free();\n }\n }\n }\n }\n\n buildContext.stopTimer(Raw.Module.RC_TIMER_TEMP);\n\n if (!keepIntermediates) {\n cleanup();\n }\n\n return {\n success: true,\n navMesh,\n intermediates,\n };\n};\n"],"names":["getBoundingBox","positions","indices","bbMin","x","Infinity","y","z","bbMax","i","length","ind","Math","min","max","vec3","toArray","dtIlog2","v","r","shift","Number","dtNextPow2","soloNavMeshGeneratorConfigDefaults","recastConfigDefaults","tileCacheGeneratorConfigDefaults","tileSize","expectedLayersPerTile","maxObstacles","createDefaultTileCacheMeshProcess","TileCacheMeshProcess","navMeshCreateParams","polyAreas","polyFlags","polyCount","set","tiledNavMeshGeneratorConfigDefaults","navMeshGeneratorConfig","keepIntermediates","buildContext","RecastBuildContext","intermediates","type","navMesh","NavMesh","fail","error","heightfield","freeHeightfield","undefined","compactHeightfield","freeCompactHeightfield","contourSet","freeContourSet","destroy","success","verts","nVerts","vertsArray","Arrays","VertsArray","copy","tris","nTris","trisArray","TrisArray","config","createRcConfig","minRegionArea","mergeRegionArea","detailSampleDist","cs","detailSampleMaxError","ch","gridSize","calcGridSize","width","height","allocHeightfield","createHeightfield","triAreasArray","TriAreasArray","resize","markWalkableTriangles","walkableSlopeAngle","rasterizeTriangles","walkableClimb","free","filterLowHangingWalkableObstacles","filterLedgeSpans","walkableHeight","filterWalkableLowHeightSpans","allocCompactHeightfield","buildCompactHeightfield","erodeWalkableArea","walkableRadius","buildDistanceField","buildRegions","borderSize","allocContourSet","buildContours","maxSimplificationError","maxEdgeLen","Raw","Module","RC_CONTOUR_TESS_WALL_EDGES","polyMesh","allocPolyMesh","buildPolyMesh","maxVertsPerPoly","polyMeshDetail","allocPolyMeshDetail","buildPolyMeshDetail","npolys","areas","Recast","WALKABLE_AREA","setAreas","setFlags","NavMeshCreateParams","setPolyMeshCreateParams","setPolyMeshDetailCreateParams","setWalkableHeight","setWalkableRadius","setWalkableClimb","setCellSize","setCellHeight","setBuildBvTree","offMeshConnections","setOffMeshConnections","createNavMeshDataResult","createNavMeshData","navMeshData","initSolo","chunkyTriMesh","tileIntermediates","tileCache","TileCache","cleanup","tileIntermediate","heightfieldLayerSet","freeHeightfieldLayerSet","recastConfig","floor","tileWidth","tileHeight","tileCacheParams","DetourTileCacheParams","create","orig","maxTiles","allocator","RecastLinearAllocator","compressor","RecastFastLZCompressor","tileCacheMeshProcess","init","fromArray","tileBits","maxPolysPerTile","navMeshParams","NavMeshParams","maxPolys","initTiled","RecastChunkyTriMesh","rasterizeTileLayers","tileX","tileY","tcs","tileConfig","cloneRcConfig","tileBoundsMin","tileBoundsMax","set_bmin","set_bmax","n","tbmin","tbmax","chunkIdsArray","ChunkIdsArray","nChunksOverlapping","getChunksOverlappingRect","nodeId","get_data","nNodeTris","nodes","nodeTrisArray","getNodeTris","allocHeightfieldLayerSet","buildHeightfieldLayers","tiles","nlayers","tile","TileCacheData","heightfieldLayer","layers","header","dtTileCacheLayerHeader","magic","Detour","TILECACHE_MAGIC","version","TILECACHE_VERSION","tx","ty","tlayer","heightfieldLayerBin","bmin","heightfieldLayerBmax","bmax","minx","maxx","miny","maxy","hmin","hmax","heights","getHeightfieldLayerHeights","getHeightfieldLayerAreas","cons","getHeightfieldLayerCons","status","buildTileCacheLayer","statusFailed","push","newTiles","tileCacheData","addResult","addTile","log","RC_LOG_WARNING","dtStatus","buildNavMeshTilesAt","buildTileMesh","failTileMesh","RC_LOG_ERROR","expandedTileBoundsMin","expandedTileBoundsMax","resetTimers","startTimer","RC_TIMER_TOTAL","RC_LOG_PROGRESS","maxTrisPerChunk","setTileX","setTileY","nverts","data","RC_TIMER_TEMP","lastBuiltTileBmin","lastBuiltTileBmax","result","removeTile","getTileRefAt","addTileResult","DT_TILE_FREE_DATA","statusToReadableString","stopTimer"],"mappings":"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"}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/generators/common.ts","../src/generators/generate-solo-nav-mesh.ts","../src/generators/generate-tile-cache.ts","../src/generators/generate-tiled-nav-mesh.ts"],"sourcesContent":["import { OffMeshConnectionParams, vec3 } from '@recast-navigation/core';\n\nexport const getBoundingBox = (\n positions: ArrayLike<number>,\n indices: ArrayLike<number>\n) => {\n const bbMin = { x: Infinity, y: Infinity, z: Infinity };\n const bbMax = { x: -Infinity, y: -Infinity, z: -Infinity };\n\n for (let i = 0; i < indices.length; i++) {\n const ind = indices[i];\n\n const x = positions[ind * 3];\n const y = positions[ind * 3 + 1];\n const z = positions[ind * 3 + 2];\n\n bbMin.x = Math.min(bbMin.x, x);\n bbMin.y = Math.min(bbMin.y, y);\n bbMin.z = Math.min(bbMin.z, z);\n\n bbMax.x = Math.max(bbMax.x, x);\n bbMax.y = Math.max(bbMax.y, y);\n bbMax.z = Math.max(bbMax.z, z);\n }\n\n return {\n bbMin: vec3.toArray(bbMin),\n bbMax: vec3.toArray(bbMax),\n };\n};\n\nexport const dtIlog2 = (v: number) => {\n let r = 0;\n let shift = 0;\n\n r = Number(v > 0xffff) << 4;\n v >>= r;\n\n shift = Number(v > 0xff) << 3;\n v >>= shift;\n r |= shift;\n\n shift = Number(v > 0xf) << 2;\n v >>= shift;\n r |= shift;\n\n shift = Number(v > 0x3) << 1;\n v >>= shift;\n r |= shift;\n r |= v >> 1;\n\n return r;\n};\n\nexport const dtNextPow2 = (v: number) => {\n v--;\n v |= v >> 1;\n v |= v >> 2;\n v |= v >> 4;\n v |= v >> 8;\n v |= v >> 16;\n v++;\n return v;\n};\n\nexport type OffMeshConnectionGeneratorParams = {\n offMeshConnections?: OffMeshConnectionParams[];\n};\n","import {\n Arrays,\n NavMesh,\n NavMeshCreateParams,\n Raw,\n RecastBuildContext,\n RecastCompactHeightfield,\n RecastConfig,\n RecastContourSet,\n RecastHeightfield,\n allocCompactHeightfield,\n allocContourSet,\n allocHeightfield,\n allocPolyMesh,\n allocPolyMeshDetail,\n buildCompactHeightfield,\n buildContours,\n buildDistanceField,\n buildPolyMesh,\n buildPolyMeshDetail,\n buildRegions,\n calcGridSize,\n createHeightfield,\n createNavMeshData,\n createRcConfig,\n erodeWalkableArea,\n filterLedgeSpans,\n filterLowHangingWalkableObstacles,\n filterWalkableLowHeightSpans,\n freeCompactHeightfield,\n freeContourSet,\n freeHeightfield,\n markWalkableTriangles,\n rasterizeTriangles,\n recastConfigDefaults,\n} from '@recast-navigation/core';\nimport { Pretty } from '../types';\nimport { OffMeshConnectionGeneratorParams, getBoundingBox } from './common';\n\nexport type SoloNavMeshGeneratorConfig = Pretty<\n Omit<RecastConfig, 'tileSize'> & OffMeshConnectionGeneratorParams\n>;\n\nexport const soloNavMeshGeneratorConfigDefaults: SoloNavMeshGeneratorConfig = {\n ...recastConfigDefaults,\n};\n\nexport type SoloNavMeshGeneratorIntermediates = {\n type: 'solo';\n buildContext: RecastBuildContext;\n heightfield?: RecastHeightfield;\n compactHeightfield?: RecastCompactHeightfield;\n contourSet?: RecastContourSet;\n};\n\ntype SoloNavMeshGeneratorSuccessResult = {\n navMesh: NavMesh;\n success: true;\n intermediates: SoloNavMeshGeneratorIntermediates;\n};\n\ntype SoloNavMeshGeneratorFailResult = {\n navMesh: undefined;\n success: false;\n intermediates: SoloNavMeshGeneratorIntermediates;\n error: string;\n};\n\nexport type SoloNavMeshGeneratorResult =\n | SoloNavMeshGeneratorSuccessResult\n | SoloNavMeshGeneratorFailResult;\n\n/**\n * Builds a Solo NavMesh from the given positions and indices.\n * @param positions a flat array of positions\n * @param indices a flat array of indices\n * @param navMeshGeneratorConfig optional configuration for the NavMesh generator\n * @param keepIntermediates if true intermediates will be returned\n */\nexport const generateSoloNavMesh = (\n positions: ArrayLike<number>,\n indices: ArrayLike<number>,\n navMeshGeneratorConfig: Partial<SoloNavMeshGeneratorConfig> = {},\n keepIntermediates = false\n): SoloNavMeshGeneratorResult => {\n const buildContext = new RecastBuildContext();\n\n const intermediates: SoloNavMeshGeneratorIntermediates = {\n type: 'solo',\n buildContext,\n };\n\n const navMesh = new NavMesh();\n\n const cleanup = () => {\n if (keepIntermediates) return;\n\n if (intermediates.heightfield) {\n freeHeightfield(intermediates.heightfield);\n intermediates.heightfield = undefined;\n }\n if (intermediates.compactHeightfield) {\n freeCompactHeightfield(intermediates.compactHeightfield);\n intermediates.compactHeightfield = undefined;\n }\n if (intermediates.contourSet) {\n freeContourSet(intermediates.contourSet);\n intermediates.contourSet = undefined;\n }\n };\n\n const fail = (error: string): SoloNavMeshGeneratorFailResult => {\n cleanup();\n\n navMesh.destroy();\n\n return {\n navMesh: undefined,\n success: false,\n intermediates,\n error,\n };\n };\n\n const verts = positions as number[];\n const nVerts = indices.length;\n const vertsArray = new Arrays.VertsArray();\n vertsArray.copy(verts, verts.length);\n\n const tris = indices as number[];\n const nTris = indices.length / 3;\n const trisArray = new Arrays.TrisArray();\n trisArray.copy(tris, tris.length);\n\n const { bbMin, bbMax } = getBoundingBox(positions, indices);\n\n //\n // Step 1. Initialize build config.\n //\n const config = createRcConfig({\n ...soloNavMeshGeneratorConfigDefaults,\n ...navMeshGeneratorConfig,\n });\n\n config.minRegionArea = config.minRegionArea * config.minRegionArea; // Note: area = size*size\n config.mergeRegionArea = config.mergeRegionArea * config.mergeRegionArea; // Note: area = size*size\n config.detailSampleDist =\n config.detailSampleDist < 0.9 ? 0 : config.cs * config.detailSampleDist;\n config.detailSampleMaxError = config.ch * config.detailSampleMaxError;\n\n const gridSize = calcGridSize(bbMin, bbMax, config.cs);\n config.width = gridSize.width;\n config.height = gridSize.height;\n\n //\n // Step 2. Rasterize input polygon soup.\n //\n // Allocate voxel heightfield where we rasterize our input data to.\n const heightfield = allocHeightfield();\n intermediates.heightfield = heightfield;\n\n if (\n !createHeightfield(\n buildContext,\n heightfield,\n config.width,\n config.height,\n bbMin,\n bbMax,\n config.cs,\n config.ch\n )\n ) {\n return fail('Could not create heightfield');\n }\n\n // Find triangles which are walkable based on their slope and rasterize them.\n // If your input data is multiple meshes, you can transform them here, calculate\n // the are type for each of the meshes and rasterize them.\n const triAreasArray = new Arrays.TriAreasArray();\n triAreasArray.resize(nTris);\n\n markWalkableTriangles(\n buildContext,\n config.walkableSlopeAngle,\n vertsArray,\n nVerts,\n trisArray,\n nTris,\n triAreasArray\n );\n\n if (\n !rasterizeTriangles(\n buildContext,\n vertsArray,\n nVerts,\n trisArray,\n triAreasArray,\n nTris,\n heightfield,\n config.walkableClimb\n )\n ) {\n return fail('Could not rasterize triangles');\n }\n\n triAreasArray.free();\n\n //\n // Step 3. Filter walkables surfaces.\n //\n // Once all geoemtry is rasterized, we do initial pass of filtering to\n // remove unwanted overhangs caused by the conservative rasterization\n // as well as filter spans where the character cannot possibly stand.\n filterLowHangingWalkableObstacles(\n buildContext,\n config.walkableClimb,\n heightfield\n );\n filterLedgeSpans(\n buildContext,\n config.walkableHeight,\n config.walkableClimb,\n heightfield\n );\n filterWalkableLowHeightSpans(\n buildContext,\n config.walkableHeight,\n heightfield\n );\n\n //\n // Step 4. Partition walkable surface to simple regions.\n //\n // Compact the heightfield so that it is faster to handle from now on.\n // This will result more cache coherent data as well as the neighbours\n // between walkable cells will be calculated.\n const compactHeightfield = allocCompactHeightfield();\n intermediates.compactHeightfield = compactHeightfield;\n\n if (\n !buildCompactHeightfield(\n buildContext,\n config.walkableHeight,\n config.walkableClimb,\n heightfield,\n compactHeightfield\n )\n ) {\n return fail('Failed to build compact data');\n }\n\n if (!keepIntermediates) {\n freeHeightfield(heightfield);\n intermediates.heightfield = undefined;\n }\n\n // Erode the walkable area by agent radius.\n if (\n !erodeWalkableArea(buildContext, config.walkableRadius, compactHeightfield)\n ) {\n return fail('Failed to erode walkable area');\n }\n\n // (Optional) Mark areas\n // markConvexPolyArea(...)\n\n // Prepare for region partitioning, by calculating Distance field along the walkable surface.\n if (!buildDistanceField(buildContext, compactHeightfield)) {\n return fail('Failed to build distance field');\n }\n\n // Partition the walkable surface into simple regions without holes.\n if (\n !buildRegions(\n buildContext,\n compactHeightfield,\n config.borderSize,\n config.minRegionArea,\n config.mergeRegionArea\n )\n ) {\n return fail('Failed to build regions');\n }\n\n //\n // Step 5. Trace and simplify region contours.\n //\n const contourSet = allocContourSet();\n intermediates.contourSet = contourSet;\n\n if (\n !buildContours(\n buildContext,\n compactHeightfield,\n config.maxSimplificationError,\n config.maxEdgeLen,\n contourSet,\n Raw.Module.RC_CONTOUR_TESS_WALL_EDGES\n )\n ) {\n return fail('Failed to create contours');\n }\n\n //\n // Step 6. Build polygons mesh from contours.\n //\n const polyMesh = allocPolyMesh();\n if (\n !buildPolyMesh(buildContext, contourSet, config.maxVertsPerPoly, polyMesh)\n ) {\n return fail('Failed to triangulate contours');\n }\n\n //\n // Step 7. Create detail mesh which allows to access approximate height on each polygon.\n //\n const polyMeshDetail = allocPolyMeshDetail();\n if (\n !buildPolyMeshDetail(\n buildContext,\n polyMesh,\n compactHeightfield,\n config.detailSampleDist,\n config.detailSampleMaxError,\n polyMeshDetail\n )\n ) {\n return fail('Failed to build detail mesh');\n }\n\n if (!keepIntermediates) {\n freeCompactHeightfield(compactHeightfield);\n intermediates.compactHeightfield = undefined;\n\n freeContourSet(contourSet);\n intermediates.contourSet = undefined;\n }\n\n //\n // Step 8. Create Detour data from Recast poly mesh.\n //\n for (let i = 0; i < polyMesh.npolys(); i++) {\n if (polyMesh.areas(i) == Raw.Recast.WALKABLE_AREA) {\n polyMesh.setAreas(i, 0);\n }\n if (polyMesh.areas(i) == 0) {\n polyMesh.setFlags(i, 1);\n }\n }\n\n const navMeshCreateParams = new NavMeshCreateParams();\n\n navMeshCreateParams.setPolyMeshCreateParams(polyMesh);\n navMeshCreateParams.setPolyMeshDetailCreateParams(polyMeshDetail);\n\n navMeshCreateParams.setWalkableHeight(config.walkableHeight);\n navMeshCreateParams.setWalkableRadius(config.walkableRadius);\n navMeshCreateParams.setWalkableClimb(config.walkableClimb);\n\n navMeshCreateParams.setCellSize(config.cs);\n navMeshCreateParams.setCellHeight(config.ch);\n\n navMeshCreateParams.setBuildBvTree(true);\n\n if (navMeshGeneratorConfig.offMeshConnections) {\n navMeshCreateParams.setOffMeshConnections(\n navMeshGeneratorConfig.offMeshConnections\n );\n }\n\n const createNavMeshDataResult = createNavMeshData(navMeshCreateParams);\n\n if (!createNavMeshDataResult.success) {\n return fail('Failed to create Detour navmesh data');\n }\n\n const { navMeshData } = createNavMeshDataResult;\n\n if (!navMesh.initSolo(navMeshData)) {\n return fail('Failed to create Detour navmesh');\n }\n\n return {\n success: true,\n navMesh,\n intermediates,\n };\n};\n","import {\n Arrays,\n DetourTileCacheParams,\n NavMesh,\n NavMeshParams,\n Raw,\n RecastBuildContext,\n RecastChunkyTriMesh,\n RecastCompactHeightfield,\n RecastConfig,\n RecastHeightfield,\n RecastHeightfieldLayerSet,\n TileCache,\n TileCacheMeshProcess,\n Vector2Tuple,\n Vector3Tuple,\n allocCompactHeightfield,\n allocHeightfield,\n allocHeightfieldLayerSet,\n buildCompactHeightfield,\n buildHeightfieldLayers,\n buildTileCacheLayer,\n calcGridSize,\n cloneRcConfig,\n createHeightfield,\n createRcConfig,\n erodeWalkableArea,\n filterLedgeSpans,\n filterLowHangingWalkableObstacles,\n filterWalkableLowHeightSpans,\n freeCompactHeightfield,\n freeHeightfield,\n freeHeightfieldLayerSet,\n getHeightfieldLayerAreas,\n getHeightfieldLayerCons,\n getHeightfieldLayerHeights,\n markWalkableTriangles,\n rasterizeTriangles,\n recastConfigDefaults,\n vec3,\n} from '@recast-navigation/core';\nimport type R from '@recast-navigation/wasm';\nimport { Pretty } from '../types';\nimport { dtIlog2, dtNextPow2, getBoundingBox } from './common';\n\nexport type TileCacheGeneratorConfig = Pretty<\n RecastConfig & {\n /**\n * How many layers (or \"floors\") each navmesh tile is expected to have.\n */\n expectedLayersPerTile: number;\n\n /**\n * The max number of obstacles\n */\n maxObstacles: number;\n\n /**\n * The tile cache mesh process implementation.\n * If not provided, a default one is created via `createDefaultTileCacheMeshProcess()`\n * @default createDefaultTileCacheMeshProcess()\n */\n tileCacheMeshProcess?: TileCacheMeshProcess;\n }\n>;\n\nexport const tileCacheGeneratorConfigDefaults: TileCacheGeneratorConfig = {\n ...recastConfigDefaults,\n tileSize: 32,\n expectedLayersPerTile: 4,\n maxObstacles: 128,\n};\n\nexport type TileCacheGeneratorTileIntermediates = {\n tileX: number;\n tileY: number;\n heightfield?: RecastHeightfield;\n compactHeightfield?: RecastCompactHeightfield;\n heightfieldLayerSet?: RecastHeightfieldLayerSet;\n};\n\nexport type TileCacheGeneratorIntermediates = {\n type: 'tilecache';\n buildContext: RecastBuildContext;\n chunkyTriMesh?: RecastChunkyTriMesh;\n tileIntermediates: TileCacheGeneratorTileIntermediates[];\n};\n\ntype TileCacheGeneratorSuccessResult = {\n tileCache: TileCache;\n navMesh: NavMesh;\n success: true;\n intermediates: TileCacheGeneratorIntermediates;\n};\n\ntype TileCacheGeneratorFailResult = {\n tileCache: undefined;\n navMesh: undefined;\n success: false;\n error: string;\n intermediates: TileCacheGeneratorIntermediates;\n};\n\nexport type TileCacheGeneratorResult =\n | TileCacheGeneratorSuccessResult\n | TileCacheGeneratorFailResult;\n\nexport const createDefaultTileCacheMeshProcess = () =>\n new TileCacheMeshProcess((navMeshCreateParams, polyAreas, polyFlags) => {\n for (let i = 0; i < navMeshCreateParams.polyCount(); ++i) {\n polyAreas.set(i, 0);\n polyFlags.set(i, 1);\n }\n });\n\n/**\n * Builds a TileCache and NavMesh from the given positions and indices.\n * TileCache assumes small tiles (around 32-64 squared) and does some tricks to make the update fast.\n * @param positions a flat array of positions\n * @param indices a flat array of indices\n * @param navMeshConfig optional configuration for the NavMesh\n * @param keepIntermediates if true intermediates will be returned\n */\nexport const generateTileCache = (\n positions: ArrayLike<number>,\n indices: ArrayLike<number>,\n navMeshGeneratorConfig: Partial<TileCacheGeneratorConfig> = {},\n keepIntermediates = false\n): TileCacheGeneratorResult => {\n const buildContext = new RecastBuildContext();\n\n const intermediates: TileCacheGeneratorIntermediates = {\n type: 'tilecache',\n buildContext,\n chunkyTriMesh: undefined,\n tileIntermediates: [],\n };\n\n const tileCache = new TileCache();\n const navMesh = new NavMesh();\n\n const cleanup = () => {\n if (!keepIntermediates) {\n for (let i = 0; i < intermediates.tileIntermediates.length; i++) {\n const tileIntermediate = intermediates.tileIntermediates[i];\n\n if (tileIntermediate.heightfield) {\n freeHeightfield(tileIntermediate.heightfield);\n tileIntermediate.heightfield = undefined;\n }\n\n if (tileIntermediate.compactHeightfield) {\n freeCompactHeightfield(tileIntermediate.compactHeightfield);\n tileIntermediate.compactHeightfield = undefined;\n }\n\n if (tileIntermediate.heightfieldLayerSet) {\n freeHeightfieldLayerSet(tileIntermediate.heightfieldLayerSet);\n tileIntermediate.heightfieldLayerSet = undefined;\n }\n }\n }\n };\n\n const fail = (error: string): TileCacheGeneratorFailResult => {\n cleanup();\n\n tileCache.destroy();\n navMesh.destroy();\n\n return {\n success: false,\n navMesh: undefined,\n tileCache: undefined,\n intermediates,\n error,\n };\n };\n\n const verts = positions as number[];\n const nVerts = indices.length;\n const vertsArray = new Arrays.VertsArray();\n vertsArray.copy(verts, verts.length);\n\n const tris = indices as number[];\n const nTris = indices.length / 3;\n const trisArray = new Arrays.TrisArray();\n trisArray.copy(tris, tris.length);\n\n const { bbMin, bbMax } = getBoundingBox(positions, indices);\n\n const { expectedLayersPerTile, maxObstacles, ...recastConfig } = {\n ...tileCacheGeneratorConfigDefaults,\n ...navMeshGeneratorConfig,\n };\n\n //\n // Step 1. Initialize build config.\n //\n const config = createRcConfig(recastConfig);\n\n const gridSize = calcGridSize(bbMin, bbMax, config.cs);\n config.width = gridSize.width;\n config.height = gridSize.height;\n\n config.minRegionArea = config.minRegionArea * config.minRegionArea; // Note: area = size*size\n config.mergeRegionArea = config.mergeRegionArea * config.mergeRegionArea; // Note: area = size*size\n config.detailSampleDist =\n config.detailSampleDist < 0.9 ? 0 : config.cs * config.detailSampleDist;\n config.detailSampleMaxError = config.ch * config.detailSampleMaxError;\n\n const tileSize = Math.floor(config.tileSize);\n const tileWidth = Math.floor((config.width + tileSize - 1) / tileSize);\n const tileHeight = Math.floor((config.height + tileSize - 1) / tileSize);\n\n // Generation params\n config.borderSize = config.walkableRadius + 3; // Reserve enough padding.\n config.width = config.tileSize + config.borderSize * 2;\n config.height = config.tileSize + config.borderSize * 2;\n\n // Tile cache params\n const tileCacheParams = DetourTileCacheParams.create({\n orig: bbMin,\n cs: config.cs,\n ch: config.ch,\n width: config.tileSize,\n height: config.tileSize,\n walkableHeight: config.walkableHeight,\n walkableRadius: config.walkableRadius,\n walkableClimb: config.walkableClimb,\n maxSimplificationError: config.maxSimplificationError,\n maxTiles: tileWidth * tileHeight * expectedLayersPerTile,\n maxObstacles,\n });\n\n const allocator = new Raw.RecastLinearAllocator(32000);\n const compressor = new Raw.RecastFastLZCompressor();\n\n const tileCacheMeshProcess =\n navMeshGeneratorConfig.tileCacheMeshProcess ??\n createDefaultTileCacheMeshProcess();\n\n if (\n !tileCache.init(\n tileCacheParams,\n allocator,\n compressor,\n tileCacheMeshProcess\n )\n ) {\n return fail('Failed to initialize tile cache');\n }\n\n const orig = vec3.fromArray(bbMin);\n\n // Max tiles and max polys affect how the tile IDs are caculated.\n // There are 22 bits available for identifying a tile and a polygon.\n let tileBits = Math.min(\n Math.floor(\n dtIlog2(dtNextPow2(tileWidth * tileHeight * expectedLayersPerTile))\n ),\n 14\n );\n if (tileBits > 14) {\n tileBits = 14;\n }\n const polyBits = 22 - tileBits;\n\n const maxTiles = 1 << tileBits;\n const maxPolysPerTile = 1 << polyBits;\n\n const navMeshParams = NavMeshParams.create({\n orig,\n tileWidth: config.tileSize * config.cs,\n tileHeight: config.tileSize * config.cs,\n maxTiles,\n maxPolys: maxPolysPerTile,\n });\n\n if (!navMesh.initTiled(navMeshParams)) {\n return fail('Failed to initialize tiled navmesh');\n }\n\n const chunkyTriMesh = new RecastChunkyTriMesh();\n intermediates.chunkyTriMesh = chunkyTriMesh;\n\n if (!chunkyTriMesh.init(vertsArray, trisArray, nTris, 256)) {\n return fail('Failed to build chunky triangle mesh');\n }\n\n const rasterizeTileLayers = (tileX: number, tileY: number) => {\n // Tile intermediates\n const tileIntermediates: TileCacheGeneratorTileIntermediates = {\n tileX,\n tileY,\n };\n\n // Tile bounds\n const tcs = config.tileSize * config.cs;\n\n const tileConfig = cloneRcConfig(config);\n\n const tileBoundsMin: Vector3Tuple = [\n bbMin[0] + tileX * tcs,\n bbMin[1],\n bbMin[2] + tileY * tcs,\n ];\n\n const tileBoundsMax: Vector3Tuple = [\n bbMin[0] + (tileX + 1) * tcs,\n bbMax[1],\n bbMin[2] + (tileY + 1) * tcs,\n ];\n\n tileBoundsMin[0] -= tileConfig.borderSize * tileConfig.cs;\n tileBoundsMin[2] -= tileConfig.borderSize * tileConfig.cs;\n tileBoundsMax[0] += tileConfig.borderSize * tileConfig.cs;\n tileBoundsMax[2] += tileConfig.borderSize * tileConfig.cs;\n\n tileConfig.set_bmin(0, tileBoundsMin[0]);\n tileConfig.set_bmin(1, tileBoundsMin[1]);\n tileConfig.set_bmin(2, tileBoundsMin[2]);\n\n tileConfig.set_bmax(0, tileBoundsMax[0]);\n tileConfig.set_bmax(1, tileBoundsMax[1]);\n tileConfig.set_bmax(2, tileBoundsMax[2]);\n\n // Allocate voxel heightfield where we rasterize our input data to.\n const heightfield = allocHeightfield();\n tileIntermediates.heightfield = heightfield;\n\n if (\n !createHeightfield(\n buildContext,\n heightfield,\n tileConfig.width,\n tileConfig.height,\n tileBoundsMin,\n tileBoundsMax,\n tileConfig.cs,\n tileConfig.ch\n )\n ) {\n return { n: 0 };\n }\n\n const tbmin: Vector2Tuple = [tileBoundsMin[0], tileBoundsMin[2]];\n const tbmax: Vector2Tuple = [tileBoundsMax[0], tileBoundsMax[2]];\n\n // TODO: Make grow when returning too many items.\n const maxChunkIds = 512;\n const chunkIdsArray = new Arrays.ChunkIdsArray();\n chunkIdsArray.resize(maxChunkIds);\n\n const nChunksOverlapping = chunkyTriMesh.getChunksOverlappingRect(\n tbmin,\n tbmax,\n chunkIdsArray,\n maxChunkIds\n );\n\n if (nChunksOverlapping === 0) {\n return { n: 0 };\n }\n\n for (let i = 0; i < nChunksOverlapping; ++i) {\n const nodeId = chunkIdsArray.get_data(i);\n const node = chunkyTriMesh.nodes(nodeId);\n const nNodeTris = node.n;\n\n const nodeTrisArray = chunkyTriMesh.getNodeTris(nodeId);\n\n const triAreasArray = new Arrays.TriAreasArray();\n triAreasArray.resize(nNodeTris);\n\n // Find triangles which are walkable based on their slope and rasterize them.\n // If your input data is multiple meshes, you can transform them here, calculate\n // the are type for each of the meshes and rasterize them.\n markWalkableTriangles(\n buildContext,\n tileConfig.walkableSlopeAngle,\n vertsArray,\n nVerts,\n nodeTrisArray,\n nNodeTris,\n triAreasArray\n );\n\n const success = rasterizeTriangles(\n buildContext,\n vertsArray,\n nVerts,\n nodeTrisArray,\n triAreasArray,\n nNodeTris,\n heightfield,\n tileConfig.walkableClimb\n );\n\n triAreasArray.free();\n\n if (!success) {\n return { n: 0 };\n }\n }\n\n // Once all geometry is rasterized, we do initial pass of filtering to\n // remove unwanted overhangs caused by the conservative rasterization\n // as well as filter spans where the character cannot possibly stand.\n filterLowHangingWalkableObstacles(\n buildContext,\n config.walkableClimb,\n heightfield\n );\n filterLedgeSpans(\n buildContext,\n config.walkableHeight,\n config.walkableClimb,\n heightfield\n );\n filterWalkableLowHeightSpans(\n buildContext,\n config.walkableHeight,\n heightfield\n );\n\n const compactHeightfield = allocCompactHeightfield();\n if (\n !buildCompactHeightfield(\n buildContext,\n config.walkableHeight,\n config.walkableClimb,\n heightfield,\n compactHeightfield\n )\n ) {\n return { n: 0 };\n }\n\n if (!keepIntermediates) {\n freeHeightfield(tileIntermediates.heightfield);\n tileIntermediates.heightfield = undefined;\n }\n\n // Erode the walkable area by agent radius\n if (\n !erodeWalkableArea(\n buildContext,\n config.walkableRadius,\n compactHeightfield\n )\n ) {\n return { n: 0 };\n }\n\n const heightfieldLayerSet = allocHeightfieldLayerSet();\n if (\n !buildHeightfieldLayers(\n buildContext,\n compactHeightfield,\n config.borderSize,\n config.walkableHeight,\n heightfieldLayerSet\n )\n ) {\n return { n: 0 };\n }\n\n if (!keepIntermediates) {\n freeCompactHeightfield(compactHeightfield);\n tileIntermediates.compactHeightfield = undefined;\n }\n\n const tiles: R.UnsignedCharArray[] = [];\n\n for (let i = 0; i < heightfieldLayerSet.nlayers(); i++) {\n const tile = new Arrays.TileCacheData();\n const heightfieldLayer = heightfieldLayerSet.layers(i);\n\n // Store header\n const header = new Raw.dtTileCacheLayerHeader();\n header.magic = Raw.Detour.TILECACHE_MAGIC;\n header.version = Raw.Detour.TILECACHE_VERSION;\n\n // Tile layer location in the navmesh\n header.tx = tileX;\n header.ty = tileY;\n header.tlayer = i;\n\n const heightfieldLayerBin = heightfieldLayer.bmin();\n const heightfieldLayerBmax = heightfieldLayer.bmax();\n header.set_bmin(0, heightfieldLayerBin.x);\n header.set_bmin(1, heightfieldLayerBin.y);\n header.set_bmin(2, heightfieldLayerBin.z);\n\n header.set_bmax(0, heightfieldLayerBmax.x);\n header.set_bmax(1, heightfieldLayerBmax.y);\n header.set_bmax(2, heightfieldLayerBmax.z);\n\n // Tile info\n header.width = heightfieldLayer.width();\n header.height = heightfieldLayer.height();\n header.minx = heightfieldLayer.minx();\n header.maxx = heightfieldLayer.maxx();\n header.miny = heightfieldLayer.miny();\n header.maxy = heightfieldLayer.maxy();\n header.hmin = heightfieldLayer.hmin();\n header.hmax = heightfieldLayer.hmax();\n\n const heights = getHeightfieldLayerHeights(heightfieldLayer);\n const areas = getHeightfieldLayerAreas(heightfieldLayer);\n const cons = getHeightfieldLayerCons(heightfieldLayer);\n\n const status = buildTileCacheLayer(\n compressor,\n header,\n heights,\n areas,\n cons,\n tile\n );\n\n if (Raw.Detour.statusFailed(status)) {\n return { n: 0 };\n }\n\n tiles.push(tile);\n }\n\n if (!keepIntermediates) {\n freeHeightfieldLayerSet(heightfieldLayerSet);\n tileIntermediates.heightfieldLayerSet = undefined;\n }\n\n intermediates.tileIntermediates.push(tileIntermediates);\n\n return { n: tiles.length, tiles };\n };\n\n // Preprocess tiles\n for (let y = 0; y < tileHeight; ++y) {\n for (let x = 0; x < tileWidth; ++x) {\n const { n, tiles: newTiles } = rasterizeTileLayers(x, y);\n\n if (n > 0 && newTiles) {\n for (let i = 0; i < n; i++) {\n const tileCacheData = newTiles[i];\n\n const addResult = tileCache.addTile(tileCacheData);\n\n if (Raw.Detour.statusFailed(addResult.status)) {\n buildContext.log(\n Raw.Module.RC_LOG_WARNING,\n `Failed to add tile to tile cache - tx: ${x}, ty: ${y}`\n );\n continue;\n }\n }\n }\n }\n }\n\n // Build initial meshes\n for (let y = 0; y < tileHeight; y++) {\n for (let x = 0; x < tileWidth; x++) {\n const dtStatus = tileCache.buildNavMeshTilesAt(x, y, navMesh);\n\n if (Raw.Detour.statusFailed(dtStatus)) {\n return fail(`Failed to build nav mesh tiles at ${x}, ${y}`);\n }\n }\n }\n\n cleanup();\n\n return {\n success: true,\n tileCache,\n navMesh,\n intermediates,\n };\n};\n","import {\n Arrays,\n NavMesh,\n NavMeshCreateParams,\n NavMeshParams,\n Raw,\n RecastBuildContext,\n RecastChunkyTriMesh,\n RecastCompactHeightfield,\n RecastConfig,\n RecastContourSet,\n RecastHeightfield,\n Vector2Tuple,\n Vector3Tuple,\n allocCompactHeightfield,\n allocContourSet,\n allocHeightfield,\n allocPolyMesh,\n allocPolyMeshDetail,\n buildCompactHeightfield,\n buildContours,\n buildDistanceField,\n buildPolyMesh,\n buildPolyMeshDetail,\n buildRegions,\n calcGridSize,\n cloneRcConfig,\n createHeightfield,\n createNavMeshData,\n createRcConfig,\n statusToReadableString,\n erodeWalkableArea,\n filterLedgeSpans,\n filterLowHangingWalkableObstacles,\n filterWalkableLowHeightSpans,\n freeCompactHeightfield,\n freeContourSet,\n freeHeightfield,\n markWalkableTriangles,\n rasterizeTriangles,\n recastConfigDefaults,\n vec3,\n} from '@recast-navigation/core';\nimport type R from '@recast-navigation/wasm';\nimport { Pretty } from '../types';\nimport {\n OffMeshConnectionGeneratorParams,\n dtIlog2,\n dtNextPow2,\n getBoundingBox,\n} from './common';\n\nexport type TiledNavMeshGeneratorConfig = Pretty<\n RecastConfig & OffMeshConnectionGeneratorParams\n>;\n\nexport const tiledNavMeshGeneratorConfigDefaults: TiledNavMeshGeneratorConfig =\n {\n ...recastConfigDefaults,\n };\n\nexport type TiledNavMeshGeneratorIntermediates = {\n type: 'tiled';\n buildContext: RecastBuildContext;\n chunkyTriMesh?: RecastChunkyTriMesh;\n tileIntermediates: {\n tileX: number;\n tileY: number;\n heightfield?: RecastHeightfield;\n compactHeightfield?: RecastCompactHeightfield;\n contourSet?: RecastContourSet;\n }[];\n};\n\ntype TiledNavMeshGeneratorSuccessResult = {\n navMesh: NavMesh;\n success: true;\n intermediates: TiledNavMeshGeneratorIntermediates;\n};\n\ntype TiledNavMeshGeneratorFailResult = {\n navMesh: undefined;\n success: false;\n intermediates: TiledNavMeshGeneratorIntermediates;\n error: string;\n};\n\nexport type TiledNavMeshGeneratorResult =\n | TiledNavMeshGeneratorSuccessResult\n | TiledNavMeshGeneratorFailResult;\n\n/**\n * Builds a Tiled NavMesh\n * @param positions a flat array of positions\n * @param indices a flat array of indices\n * @param navMeshGeneratorConfig optional configuration for the NavMesh generator\n * @param keepIntermediates if true intermediates will be returned\n */\nexport const generateTiledNavMesh = (\n positions: ArrayLike<number>,\n indices: ArrayLike<number>,\n navMeshGeneratorConfig: Partial<TiledNavMeshGeneratorConfig> = {},\n keepIntermediates = false\n): TiledNavMeshGeneratorResult => {\n const buildContext = new RecastBuildContext();\n\n const intermediates: TiledNavMeshGeneratorIntermediates = {\n type: 'tiled',\n buildContext,\n chunkyTriMesh: undefined,\n tileIntermediates: [],\n };\n\n const navMesh = new NavMesh();\n\n const cleanup = () => {\n if (keepIntermediates) return;\n\n for (let i = 0; i < intermediates.tileIntermediates.length; i++) {\n const tileIntermediate = intermediates.tileIntermediates[i];\n\n if (tileIntermediate.compactHeightfield) {\n freeCompactHeightfield(tileIntermediate.compactHeightfield);\n }\n\n if (tileIntermediate.heightfield) {\n freeHeightfield(tileIntermediate.heightfield);\n }\n\n if (tileIntermediate.contourSet) {\n freeContourSet(tileIntermediate.contourSet);\n }\n }\n\n if (intermediates.chunkyTriMesh) {\n intermediates.chunkyTriMesh = undefined;\n }\n };\n\n const fail = (error: string): TiledNavMeshGeneratorFailResult => {\n cleanup();\n\n navMesh.destroy();\n\n return {\n success: false,\n navMesh: undefined,\n intermediates,\n error,\n };\n };\n\n //\n // Initialize build config.\n //\n const config = createRcConfig({\n ...tiledNavMeshGeneratorConfigDefaults,\n ...navMeshGeneratorConfig,\n });\n\n /* get input bounding box */\n const { bbMin, bbMax } = getBoundingBox(positions, indices);\n\n /* grid size */\n const gridSize = calcGridSize(bbMin, bbMax, config.cs);\n config.width = gridSize.width;\n config.height = gridSize.height;\n\n config.minRegionArea = config.minRegionArea * config.minRegionArea; // Note: area = size*size\n config.mergeRegionArea = config.mergeRegionArea * config.mergeRegionArea; // Note: area = size*size\n config.tileSize = Math.floor(config.tileSize);\n config.borderSize = config.walkableRadius + 3; // Reserve enough padding.\n config.width = config.tileSize + config.borderSize * 2;\n config.height = config.tileSize + config.borderSize * 2;\n config.detailSampleDist =\n config.detailSampleDist < 0.9 ? 0 : config.cs * config.detailSampleDist;\n config.detailSampleMaxError = config.ch * config.detailSampleMaxError;\n\n // tile size\n const tileSize = Math.floor(config.tileSize);\n const tileWidth = Math.floor((gridSize.width + tileSize - 1) / tileSize);\n const tileHeight = Math.floor((gridSize.height + tileSize - 1) / tileSize);\n const tcs = config.tileSize * config.cs;\n\n /* verts */\n const verts = positions as number[];\n const nVerts = indices.length;\n const vertsArray = new Arrays.VertsArray();\n vertsArray.copy(verts, verts.length);\n\n /* tris */\n const tris = indices as number[];\n const nTris = indices.length / 3;\n const trisArray = new Arrays.TrisArray();\n trisArray.copy(tris, tris.length);\n\n /* Create dtNavMeshParams, initialise nav mesh for tiled use */\n const orig = vec3.fromArray(bbMin);\n\n // Max tiles and max polys affect how the tile IDs are caculated.\n // There are 22 bits available for identifying a tile and a polygon.\n let tileBits = Math.min(\n Math.floor(dtIlog2(dtNextPow2(tileWidth * tileHeight))),\n 14\n );\n if (tileBits > 14) tileBits = 14;\n const polyBits = 22 - tileBits;\n\n const maxTiles = 1 << tileBits;\n const maxPolysPerTile = 1 << polyBits;\n\n const navMeshParams = NavMeshParams.create({\n orig,\n tileWidth: config.tileSize * config.cs,\n tileHeight: config.tileSize * config.cs,\n maxTiles,\n maxPolys: maxPolysPerTile,\n });\n\n if (!navMesh.initTiled(navMeshParams)) {\n return fail('Could not init nav mesh for tiled use');\n }\n\n /* create chunky tri mesh */\n const chunkyTriMesh = new RecastChunkyTriMesh();\n intermediates.chunkyTriMesh = chunkyTriMesh;\n\n if (!chunkyTriMesh.init(vertsArray, trisArray, nTris, 256)) {\n return fail('Failed to build chunky triangle mesh');\n }\n\n /** @internal */\n const buildTileMesh = (\n tileX: number,\n tileY: number,\n tileBoundsMin: Vector3Tuple,\n tileBoundsMax: Vector3Tuple\n ):\n | { success: true; data?: R.UnsignedCharArray }\n | { success: false; error: string } => {\n const failTileMesh = (error: string) => {\n buildContext.log(Raw.Module.RC_LOG_ERROR, error);\n\n return { success: false as const, error };\n };\n\n const tileIntermediate: {\n tileX: number;\n tileY: number;\n heightfield?: RecastHeightfield;\n compactHeightfield?: RecastCompactHeightfield;\n contourSet?: RecastContourSet;\n } = { tileX, tileY };\n\n intermediates.tileIntermediates.push(tileIntermediate);\n\n const tileConfig = cloneRcConfig(config);\n\n // Expand the heightfield bounding box by border size to find the extents of geometry we need to build this tile.\n //\n // This is done in order to make sure that the navmesh tiles connect correctly at the borders,\n // and the obstacles close to the border work correctly with the dilation process.\n // No polygons (or contours) will be created on the border area.\n //\n // IMPORTANT!\n //\n // :''''''''':\n // : +-----+ :\n // : | | :\n // : | |<--- tile to build\n // : | | :\n // : +-----+ :<-- geometry needed\n // :.........:\n //\n // You should use this bounding box to query your input geometry.\n //\n // For example if you build a navmesh for terrain, and want the navmesh tiles to match the terrain tile size\n // you will need to pass in data from neighbour terrain tiles too! In a simple case, just pass in all the 8 neighbours,\n // or use the bounding box below to only pass in a sliver of each of the 8 neighbours.\n\n const expandedTileBoundsMin = [...tileBoundsMin] as Vector3Tuple;\n const expandedTileBoundsMax = [...tileBoundsMax] as Vector3Tuple;\n\n expandedTileBoundsMin[0] -= tileConfig.borderSize * tileConfig.cs;\n expandedTileBoundsMin[2] -= tileConfig.borderSize * tileConfig.cs;\n\n expandedTileBoundsMax[0] += tileConfig.borderSize * tileConfig.cs;\n expandedTileBoundsMax[2] += tileConfig.borderSize * tileConfig.cs;\n\n tileConfig.set_bmin(0, expandedTileBoundsMin[0]);\n tileConfig.set_bmin(1, expandedTileBoundsMin[1]);\n tileConfig.set_bmin(2, expandedTileBoundsMin[2]);\n\n tileConfig.set_bmax(0, expandedTileBoundsMax[0]);\n tileConfig.set_bmax(1, expandedTileBoundsMax[1]);\n tileConfig.set_bmax(2, expandedTileBoundsMax[2]);\n\n // Reset build timer\n buildContext.resetTimers();\n\n // Start the build process\n buildContext.startTimer(Raw.Module.RC_TIMER_TOTAL);\n\n buildContext.log(\n Raw.Module.RC_LOG_PROGRESS,\n `Building tile ${intermediates.tileIntermediates.length} at x: ${tileX}, y: ${tileY}`\n );\n buildContext.log(\n Raw.Module.RC_LOG_PROGRESS,\n ` - ${config.width} x ${config.height} cells`\n );\n buildContext.log(\n Raw.Module.RC_LOG_PROGRESS,\n ` - ${nVerts / 1000}fK verts, ${nTris / 1000}K tris`\n );\n\n // Allocate voxel heightfield where we rasterize our input data to.\n const heightfield = allocHeightfield();\n tileIntermediate.heightfield = heightfield;\n\n if (\n !createHeightfield(\n buildContext,\n heightfield,\n tileConfig.width,\n tileConfig.height,\n expandedTileBoundsMin,\n expandedTileBoundsMax,\n tileConfig.cs,\n tileConfig.ch\n )\n ) {\n return failTileMesh('Could not create heightfield');\n }\n\n // Allocate array that can hold triangle flags.\n // If you have multiple meshes you need to process, allocate\n // and array which can hold the max number of triangles you need to process.\n const triAreas = new Arrays.TriAreasArray();\n triAreas.resize(chunkyTriMesh.maxTrisPerChunk());\n\n const tbmin: Vector2Tuple = [\n expandedTileBoundsMin[0],\n expandedTileBoundsMin[2],\n ];\n const tbmax: Vector2Tuple = [\n expandedTileBoundsMax[0],\n expandedTileBoundsMax[2],\n ];\n\n // TODO: Make grow when returning too many items.\n const maxChunkIds = 512;\n const chunkIdsArray = new Arrays.ChunkIdsArray();\n chunkIdsArray.resize(maxChunkIds);\n\n const nChunksOverlapping = chunkyTriMesh.getChunksOverlappingRect(\n tbmin,\n tbmax,\n chunkIdsArray,\n maxChunkIds\n );\n\n if (nChunksOverlapping === 0) {\n return { success: true };\n }\n\n for (let i = 0; i < nChunksOverlapping; ++i) {\n const nodeId = chunkIdsArray.get_data(i);\n const node = chunkyTriMesh.nodes(nodeId);\n const nNodeTris = node.n;\n\n const nodeTrisArray = chunkyTriMesh.getNodeTris(nodeId);\n\n const triAreasArray = new Arrays.TriAreasArray();\n triAreasArray.resize(nNodeTris);\n\n // Find triangles which are walkable based on their slope and rasterize them.\n // If your input data is multiple meshes, you can transform them here, calculate\n // the are type for each of the meshes and rasterize them.\n markWalkableTriangles(\n buildContext,\n tileConfig.walkableSlopeAngle,\n vertsArray,\n nVerts,\n nodeTrisArray,\n nNodeTris,\n triAreasArray\n );\n\n const success = rasterizeTriangles(\n buildContext,\n vertsArray,\n nVerts,\n nodeTrisArray,\n triAreasArray,\n nNodeTris,\n heightfield,\n tileConfig.walkableClimb\n );\n\n triAreasArray.free();\n\n if (!success) {\n return failTileMesh('Could not rasterize triangles');\n }\n }\n\n // Once all geometry is rasterized, we do initial pass of filtering to\n // remove unwanted overhangs caused by the conservative rasterization\n // as well as filter spans where the character cannot possibly stand.\n filterLowHangingWalkableObstacles(\n buildContext,\n tileConfig.walkableClimb,\n heightfield\n );\n filterLedgeSpans(\n buildContext,\n tileConfig.walkableHeight,\n tileConfig.walkableClimb,\n heightfield\n );\n filterWalkableLowHeightSpans(\n buildContext,\n tileConfig.walkableHeight,\n heightfield\n );\n\n // Compact the heightfield so that it is faster to handle from now on.\n // This will result more cache coherent data as well as the neighbours\n // between walkable cells will be calculated.\n const compactHeightfield = allocCompactHeightfield();\n tileIntermediate.compactHeightfield = compactHeightfield;\n\n if (\n !buildCompactHeightfield(\n buildContext,\n tileConfig.walkableHeight,\n tileConfig.walkableClimb,\n heightfield,\n compactHeightfield\n )\n ) {\n return failTileMesh('Could not build compact heightfield');\n }\n\n if (!keepIntermediates) {\n freeHeightfield(tileIntermediate.heightfield);\n tileIntermediate.heightfield = undefined;\n }\n\n // Erode the walkable area by agent radius\n if (\n !erodeWalkableArea(\n buildContext,\n tileConfig.walkableRadius,\n compactHeightfield\n )\n ) {\n return failTileMesh('Could not erode walkable area');\n }\n\n // (Optional) Mark areas\n // markConvexPolyArea(...)\n\n // Prepare for region partitioning, by calculating Distance field along the walkable surface.\n if (!buildDistanceField(buildContext, compactHeightfield)) {\n return failTileMesh('Failed to build distance field');\n }\n\n // Partition the walkable surface into simple regions without holes.\n if (\n !buildRegions(\n buildContext,\n compactHeightfield,\n tileConfig.borderSize,\n tileConfig.minRegionArea,\n tileConfig.mergeRegionArea\n )\n ) {\n return failTileMesh('Failed to build regions');\n }\n\n //\n // Trace and simplify region contours.\n //\n const contourSet = allocContourSet();\n tileIntermediate.contourSet = contourSet;\n\n if (\n !buildContours(\n buildContext,\n compactHeightfield,\n tileConfig.maxSimplificationError,\n tileConfig.maxEdgeLen,\n contourSet,\n Raw.Module.RC_CONTOUR_TESS_WALL_EDGES\n )\n ) {\n return failTileMesh('Failed to create contours');\n }\n\n //\n // Build polygons mesh from contours.\n //\n const polyMesh = allocPolyMesh();\n if (\n !buildPolyMesh(\n buildContext,\n contourSet,\n tileConfig.maxVertsPerPoly,\n polyMesh\n )\n ) {\n return failTileMesh('Failed to triangulate contours');\n }\n\n //\n // Create detail mesh which allows to access approximate height on each polygon.\n //\n const polyMeshDetail = allocPolyMeshDetail();\n if (\n !buildPolyMeshDetail(\n buildContext,\n polyMesh,\n compactHeightfield,\n tileConfig.detailSampleDist,\n tileConfig.detailSampleMaxError,\n polyMeshDetail\n )\n ) {\n return failTileMesh('Failed to build detail mesh');\n }\n\n if (!keepIntermediates) {\n freeCompactHeightfield(compactHeightfield);\n tileIntermediate.compactHeightfield = undefined;\n\n freeContourSet(contourSet);\n tileIntermediate.contourSet = undefined;\n }\n\n // Update poly flags from areas.\n for (let i = 0; i < polyMesh.npolys(); i++) {\n if (polyMesh.areas(i) == Raw.Recast.WALKABLE_AREA) {\n polyMesh.setAreas(i, 0);\n }\n if (polyMesh.areas(i) == 0) {\n polyMesh.setFlags(i, 1);\n }\n }\n\n const navMeshCreateParams = new NavMeshCreateParams();\n\n navMeshCreateParams.setPolyMeshCreateParams(polyMesh);\n navMeshCreateParams.setPolyMeshDetailCreateParams(polyMeshDetail);\n\n navMeshCreateParams.setWalkableHeight(tileConfig.walkableHeight);\n navMeshCreateParams.setWalkableRadius(tileConfig.walkableRadius);\n navMeshCreateParams.setWalkableClimb(tileConfig.walkableClimb);\n\n navMeshCreateParams.setCellSize(tileConfig.cs);\n navMeshCreateParams.setCellHeight(tileConfig.ch);\n\n navMeshCreateParams.setBuildBvTree(true);\n\n if (navMeshGeneratorConfig.offMeshConnections) {\n navMeshCreateParams.setOffMeshConnections(\n navMeshGeneratorConfig.offMeshConnections\n );\n }\n\n navMeshCreateParams.setTileX(tileX);\n navMeshCreateParams.setTileY(tileY);\n\n const createNavMeshDataResult = createNavMeshData(navMeshCreateParams);\n\n if (!createNavMeshDataResult.success) {\n return failTileMesh('Failed to create Detour navmesh data');\n }\n\n buildContext.log(\n Raw.Module.RC_LOG_PROGRESS,\n `>> Polymesh: ${polyMesh.nverts()} vertices ${polyMesh.npolys()} polygons`\n );\n\n return { success: true, data: createNavMeshDataResult.navMeshData };\n };\n\n buildContext.startTimer(Raw.Module.RC_TIMER_TEMP);\n\n const lastBuiltTileBmin: Vector3Tuple = [0, 0, 0];\n const lastBuiltTileBmax: Vector3Tuple = [0, 0, 0];\n\n for (let y = 0; y < tileHeight; y++) {\n for (let x = 0; x < tileWidth; x++) {\n lastBuiltTileBmin[0] = bbMin[0] + x * tcs;\n lastBuiltTileBmin[1] = bbMin[1];\n lastBuiltTileBmin[2] = bbMin[2] + y * tcs;\n\n lastBuiltTileBmax[0] = bbMin[0] + (x + 1) * tcs;\n lastBuiltTileBmax[1] = bbMax[1];\n lastBuiltTileBmax[2] = bbMin[2] + (y + 1) * tcs;\n\n const result = buildTileMesh(x, y, lastBuiltTileBmin, lastBuiltTileBmax);\n\n if (result.success && result.data) {\n navMesh.removeTile(navMesh.getTileRefAt(x, y, 0));\n\n const addTileResult = navMesh.addTile(\n result.data,\n Raw.Module.DT_TILE_FREE_DATA,\n 0\n );\n\n if (Raw.Detour.statusFailed(addTileResult.status)) {\n buildContext.log(\n Raw.Module.RC_LOG_WARNING,\n `Failed to add tile to nav mesh` +\n '\\n\\t' +\n `tx: ${x}, ty: ${y},` +\n `status: ${statusToReadableString(addTileResult.status)} (${\n addTileResult.status\n })`\n );\n\n result.data.free();\n }\n }\n }\n }\n\n buildContext.stopTimer(Raw.Module.RC_TIMER_TEMP);\n\n if (!keepIntermediates) {\n cleanup();\n }\n\n return {\n success: true,\n navMesh,\n intermediates,\n };\n};\n"],"names":["getBoundingBox","positions","indices","bbMin","x","Infinity","y","z","bbMax","i","length","ind","Math","min","max","vec3","toArray","dtIlog2","v","r","shift","Number","dtNextPow2","soloNavMeshGeneratorConfigDefaults","recastConfigDefaults","generateSoloNavMesh","navMeshGeneratorConfig","keepIntermediates","buildContext","RecastBuildContext","intermediates","type","navMesh","NavMesh","fail","error","heightfield","freeHeightfield","undefined","compactHeightfield","freeCompactHeightfield","contourSet","freeContourSet","destroy","success","verts","nVerts","vertsArray","Arrays","VertsArray","copy","tris","nTris","trisArray","TrisArray","config","createRcConfig","minRegionArea","mergeRegionArea","detailSampleDist","cs","detailSampleMaxError","ch","gridSize","calcGridSize","width","height","allocHeightfield","createHeightfield","triAreasArray","TriAreasArray","resize","markWalkableTriangles","walkableSlopeAngle","rasterizeTriangles","walkableClimb","free","filterLowHangingWalkableObstacles","filterLedgeSpans","walkableHeight","filterWalkableLowHeightSpans","allocCompactHeightfield","buildCompactHeightfield","erodeWalkableArea","walkableRadius","buildDistanceField","buildRegions","borderSize","allocContourSet","buildContours","maxSimplificationError","maxEdgeLen","Raw","Module","RC_CONTOUR_TESS_WALL_EDGES","polyMesh","allocPolyMesh","buildPolyMesh","maxVertsPerPoly","polyMeshDetail","allocPolyMeshDetail","buildPolyMeshDetail","npolys","areas","Recast","WALKABLE_AREA","setAreas","setFlags","navMeshCreateParams","NavMeshCreateParams","setPolyMeshCreateParams","setPolyMeshDetailCreateParams","setWalkableHeight","setWalkableRadius","setWalkableClimb","setCellSize","setCellHeight","setBuildBvTree","offMeshConnections","setOffMeshConnections","createNavMeshDataResult","createNavMeshData","navMeshData","initSolo","tileCacheGeneratorConfigDefaults","tileSize","expectedLayersPerTile","maxObstacles","createDefaultTileCacheMeshProcess","TileCacheMeshProcess","polyAreas","polyFlags","polyCount","set","generateTileCache","chunkyTriMesh","tileIntermediates","tileCache","TileCache","cleanup","tileIntermediate","heightfieldLayerSet","freeHeightfieldLayerSet","recastConfig","floor","tileWidth","tileHeight","tileCacheParams","DetourTileCacheParams","create","orig","maxTiles","allocator","RecastLinearAllocator","compressor","RecastFastLZCompressor","tileCacheMeshProcess","init","fromArray","tileBits","maxPolysPerTile","navMeshParams","NavMeshParams","maxPolys","initTiled","RecastChunkyTriMesh","rasterizeTileLayers","tileX","tileY","tcs","tileConfig","cloneRcConfig","tileBoundsMin","tileBoundsMax","set_bmin","set_bmax","n","tbmin","tbmax","chunkIdsArray","ChunkIdsArray","nChunksOverlapping","getChunksOverlappingRect","nodeId","get_data","nNodeTris","nodes","nodeTrisArray","getNodeTris","allocHeightfieldLayerSet","buildHeightfieldLayers","tiles","nlayers","tile","TileCacheData","heightfieldLayer","layers","header","dtTileCacheLayerHeader","magic","Detour","TILECACHE_MAGIC","version","TILECACHE_VERSION","tx","ty","tlayer","heightfieldLayerBin","bmin","heightfieldLayerBmax","bmax","minx","maxx","miny","maxy","hmin","hmax","heights","getHeightfieldLayerHeights","getHeightfieldLayerAreas","cons","getHeightfieldLayerCons","status","buildTileCacheLayer","statusFailed","push","newTiles","tileCacheData","addResult","addTile","log","RC_LOG_WARNING","dtStatus","buildNavMeshTilesAt","tiledNavMeshGeneratorConfigDefaults","generateTiledNavMesh","buildTileMesh","failTileMesh","RC_LOG_ERROR","expandedTileBoundsMin","expandedTileBoundsMax","resetTimers","startTimer","RC_TIMER_TOTAL","RC_LOG_PROGRESS","maxTrisPerChunk","setTileX","setTileY","nverts","data","RC_TIMER_TEMP","lastBuiltTileBmin","lastBuiltTileBmax","result","removeTile","getTileRefAt","addTileResult","DT_TILE_FREE_DATA","statusToReadableString","stopTimer"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/generators/common.ts","../src/generators/generate-solo-nav-mesh.ts","../src/generators/generate-tile-cache.ts","../src/generators/generate-tiled-nav-mesh.ts"],"sourcesContent":["import { OffMeshConnectionParams, vec3 } from '@recast-navigation/core';\n\nexport const getBoundingBox = (\n positions: ArrayLike<number>,\n indices: ArrayLike<number>\n) => {\n const bbMin = { x: Infinity, y: Infinity, z: Infinity };\n const bbMax = { x: -Infinity, y: -Infinity, z: -Infinity };\n\n for (let i = 0; i < indices.length; i++) {\n const ind = indices[i];\n\n const x = positions[ind * 3];\n const y = positions[ind * 3 + 1];\n const z = positions[ind * 3 + 2];\n\n bbMin.x = Math.min(bbMin.x, x);\n bbMin.y = Math.min(bbMin.y, y);\n bbMin.z = Math.min(bbMin.z, z);\n\n bbMax.x = Math.max(bbMax.x, x);\n bbMax.y = Math.max(bbMax.y, y);\n bbMax.z = Math.max(bbMax.z, z);\n }\n\n return {\n bbMin: vec3.toArray(bbMin),\n bbMax: vec3.toArray(bbMax),\n };\n};\n\nexport const dtIlog2 = (v: number) => {\n let r = 0;\n let shift = 0;\n\n r = Number(v > 0xffff) << 4;\n v >>= r;\n\n shift = Number(v > 0xff) << 3;\n v >>= shift;\n r |= shift;\n\n shift = Number(v > 0xf) << 2;\n v >>= shift;\n r |= shift;\n\n shift = Number(v > 0x3) << 1;\n v >>= shift;\n r |= shift;\n r |= v >> 1;\n\n return r;\n};\n\nexport const dtNextPow2 = (v: number) => {\n v--;\n v |= v >> 1;\n v |= v >> 2;\n v |= v >> 4;\n v |= v >> 8;\n v |= v >> 16;\n v++;\n return v;\n};\n\nexport type OffMeshConnectionGeneratorParams = {\n offMeshConnections?: OffMeshConnectionParams[];\n};\n","import {\n Arrays,\n NavMesh,\n NavMeshCreateParams,\n Raw,\n RecastBuildContext,\n RecastCompactHeightfield,\n RecastConfig,\n RecastContourSet,\n RecastHeightfield,\n allocCompactHeightfield,\n allocContourSet,\n allocHeightfield,\n allocPolyMesh,\n allocPolyMeshDetail,\n buildCompactHeightfield,\n buildContours,\n buildDistanceField,\n buildPolyMesh,\n buildPolyMeshDetail,\n buildRegions,\n calcGridSize,\n createHeightfield,\n createNavMeshData,\n createRcConfig,\n erodeWalkableArea,\n filterLedgeSpans,\n filterLowHangingWalkableObstacles,\n filterWalkableLowHeightSpans,\n freeCompactHeightfield,\n freeContourSet,\n freeHeightfield,\n markWalkableTriangles,\n rasterizeTriangles,\n recastConfigDefaults,\n} from '@recast-navigation/core';\nimport { Pretty } from '../types';\nimport { OffMeshConnectionGeneratorParams, getBoundingBox } from './common';\n\nexport type SoloNavMeshGeneratorConfig = Pretty<\n Omit<RecastConfig, 'tileSize'> & OffMeshConnectionGeneratorParams\n>;\n\nexport const soloNavMeshGeneratorConfigDefaults: SoloNavMeshGeneratorConfig = {\n ...recastConfigDefaults,\n};\n\nexport type SoloNavMeshGeneratorIntermediates = {\n type: 'solo';\n buildContext: RecastBuildContext;\n heightfield?: RecastHeightfield;\n compactHeightfield?: RecastCompactHeightfield;\n contourSet?: RecastContourSet;\n};\n\ntype SoloNavMeshGeneratorSuccessResult = {\n navMesh: NavMesh;\n success: true;\n intermediates: SoloNavMeshGeneratorIntermediates;\n};\n\ntype SoloNavMeshGeneratorFailResult = {\n navMesh: undefined;\n success: false;\n intermediates: SoloNavMeshGeneratorIntermediates;\n error: string;\n};\n\nexport type SoloNavMeshGeneratorResult =\n | SoloNavMeshGeneratorSuccessResult\n | SoloNavMeshGeneratorFailResult;\n\n/**\n * Builds a Solo NavMesh from the given positions and indices.\n * @param positions a flat array of positions\n * @param indices a flat array of indices\n * @param navMeshGeneratorConfig optional configuration for the NavMesh generator\n * @param keepIntermediates if true intermediates will be returned\n */\nexport const generateSoloNavMesh = (\n positions: ArrayLike<number>,\n indices: ArrayLike<number>,\n navMeshGeneratorConfig: Partial<SoloNavMeshGeneratorConfig> = {},\n keepIntermediates = false\n): SoloNavMeshGeneratorResult => {\n const buildContext = new RecastBuildContext();\n\n const intermediates: SoloNavMeshGeneratorIntermediates = {\n type: 'solo',\n buildContext,\n };\n\n const navMesh = new NavMesh();\n\n const cleanup = () => {\n if (keepIntermediates) return;\n\n if (intermediates.heightfield) {\n freeHeightfield(intermediates.heightfield);\n intermediates.heightfield = undefined;\n }\n if (intermediates.compactHeightfield) {\n freeCompactHeightfield(intermediates.compactHeightfield);\n intermediates.compactHeightfield = undefined;\n }\n if (intermediates.contourSet) {\n freeContourSet(intermediates.contourSet);\n intermediates.contourSet = undefined;\n }\n };\n\n const fail = (error: string): SoloNavMeshGeneratorFailResult => {\n cleanup();\n\n navMesh.destroy();\n\n return {\n navMesh: undefined,\n success: false,\n intermediates,\n error,\n };\n };\n\n const verts = positions as number[];\n const nVerts = indices.length;\n const vertsArray = new Arrays.VertsArray();\n vertsArray.copy(verts, verts.length);\n\n const tris = indices as number[];\n const nTris = indices.length / 3;\n const trisArray = new Arrays.TrisArray();\n trisArray.copy(tris, tris.length);\n\n const { bbMin, bbMax } = getBoundingBox(positions, indices);\n\n //\n // Step 1. Initialize build config.\n //\n const config = createRcConfig({\n ...soloNavMeshGeneratorConfigDefaults,\n ...navMeshGeneratorConfig,\n });\n\n config.minRegionArea = config.minRegionArea * config.minRegionArea; // Note: area = size*size\n config.mergeRegionArea = config.mergeRegionArea * config.mergeRegionArea; // Note: area = size*size\n config.detailSampleDist =\n config.detailSampleDist < 0.9 ? 0 : config.cs * config.detailSampleDist;\n config.detailSampleMaxError = config.ch * config.detailSampleMaxError;\n\n const gridSize = calcGridSize(bbMin, bbMax, config.cs);\n config.width = gridSize.width;\n config.height = gridSize.height;\n\n //\n // Step 2. Rasterize input polygon soup.\n //\n // Allocate voxel heightfield where we rasterize our input data to.\n const heightfield = allocHeightfield();\n intermediates.heightfield = heightfield;\n\n if (\n !createHeightfield(\n buildContext,\n heightfield,\n config.width,\n config.height,\n bbMin,\n bbMax,\n config.cs,\n config.ch\n )\n ) {\n return fail('Could not create heightfield');\n }\n\n // Find triangles which are walkable based on their slope and rasterize them.\n // If your input data is multiple meshes, you can transform them here, calculate\n // the are type for each of the meshes and rasterize them.\n const triAreasArray = new Arrays.TriAreasArray();\n triAreasArray.resize(nTris);\n\n markWalkableTriangles(\n buildContext,\n config.walkableSlopeAngle,\n vertsArray,\n nVerts,\n trisArray,\n nTris,\n triAreasArray\n );\n\n if (\n !rasterizeTriangles(\n buildContext,\n vertsArray,\n nVerts,\n trisArray,\n triAreasArray,\n nTris,\n heightfield,\n config.walkableClimb\n )\n ) {\n return fail('Could not rasterize triangles');\n }\n\n triAreasArray.free();\n\n //\n // Step 3. Filter walkables surfaces.\n //\n // Once all geoemtry is rasterized, we do initial pass of filtering to\n // remove unwanted overhangs caused by the conservative rasterization\n // as well as filter spans where the character cannot possibly stand.\n filterLowHangingWalkableObstacles(\n buildContext,\n config.walkableClimb,\n heightfield\n );\n filterLedgeSpans(\n buildContext,\n config.walkableHeight,\n config.walkableClimb,\n heightfield\n );\n filterWalkableLowHeightSpans(\n buildContext,\n config.walkableHeight,\n heightfield\n );\n\n //\n // Step 4. Partition walkable surface to simple regions.\n //\n // Compact the heightfield so that it is faster to handle from now on.\n // This will result more cache coherent data as well as the neighbours\n // between walkable cells will be calculated.\n const compactHeightfield = allocCompactHeightfield();\n intermediates.compactHeightfield = compactHeightfield;\n\n if (\n !buildCompactHeightfield(\n buildContext,\n config.walkableHeight,\n config.walkableClimb,\n heightfield,\n compactHeightfield\n )\n ) {\n return fail('Failed to build compact data');\n }\n\n if (!keepIntermediates) {\n freeHeightfield(heightfield);\n intermediates.heightfield = undefined;\n }\n\n // Erode the walkable area by agent radius.\n if (\n !erodeWalkableArea(buildContext, config.walkableRadius, compactHeightfield)\n ) {\n return fail('Failed to erode walkable area');\n }\n\n // (Optional) Mark areas\n // markConvexPolyArea(...)\n\n // Prepare for region partitioning, by calculating Distance field along the walkable surface.\n if (!buildDistanceField(buildContext, compactHeightfield)) {\n return fail('Failed to build distance field');\n }\n\n // Partition the walkable surface into simple regions without holes.\n if (\n !buildRegions(\n buildContext,\n compactHeightfield,\n config.borderSize,\n config.minRegionArea,\n config.mergeRegionArea\n )\n ) {\n return fail('Failed to build regions');\n }\n\n //\n // Step 5. Trace and simplify region contours.\n //\n const contourSet = allocContourSet();\n intermediates.contourSet = contourSet;\n\n if (\n !buildContours(\n buildContext,\n compactHeightfield,\n config.maxSimplificationError,\n config.maxEdgeLen,\n contourSet,\n Raw.Module.RC_CONTOUR_TESS_WALL_EDGES\n )\n ) {\n return fail('Failed to create contours');\n }\n\n //\n // Step 6. Build polygons mesh from contours.\n //\n const polyMesh = allocPolyMesh();\n if (\n !buildPolyMesh(buildContext, contourSet, config.maxVertsPerPoly, polyMesh)\n ) {\n return fail('Failed to triangulate contours');\n }\n\n //\n // Step 7. Create detail mesh which allows to access approximate height on each polygon.\n //\n const polyMeshDetail = allocPolyMeshDetail();\n if (\n !buildPolyMeshDetail(\n buildContext,\n polyMesh,\n compactHeightfield,\n config.detailSampleDist,\n config.detailSampleMaxError,\n polyMeshDetail\n )\n ) {\n return fail('Failed to build detail mesh');\n }\n\n if (!keepIntermediates) {\n freeCompactHeightfield(compactHeightfield);\n intermediates.compactHeightfield = undefined;\n\n freeContourSet(contourSet);\n intermediates.contourSet = undefined;\n }\n\n //\n // Step 8. Create Detour data from Recast poly mesh.\n //\n for (let i = 0; i < polyMesh.npolys(); i++) {\n if (polyMesh.areas(i) == Raw.Recast.WALKABLE_AREA) {\n polyMesh.setAreas(i, 0);\n }\n if (polyMesh.areas(i) == 0) {\n polyMesh.setFlags(i, 1);\n }\n }\n\n const navMeshCreateParams = new NavMeshCreateParams();\n\n navMeshCreateParams.setPolyMeshCreateParams(polyMesh);\n navMeshCreateParams.setPolyMeshDetailCreateParams(polyMeshDetail);\n\n navMeshCreateParams.setWalkableHeight(config.walkableHeight);\n navMeshCreateParams.setWalkableRadius(config.walkableRadius);\n navMeshCreateParams.setWalkableClimb(config.walkableClimb);\n\n navMeshCreateParams.setCellSize(config.cs);\n navMeshCreateParams.setCellHeight(config.ch);\n\n navMeshCreateParams.setBuildBvTree(true);\n\n if (navMeshGeneratorConfig.offMeshConnections) {\n navMeshCreateParams.setOffMeshConnections(\n navMeshGeneratorConfig.offMeshConnections\n );\n }\n\n const createNavMeshDataResult = createNavMeshData(navMeshCreateParams);\n\n if (!createNavMeshDataResult.success) {\n return fail('Failed to create Detour navmesh data');\n }\n\n const { navMeshData } = createNavMeshDataResult;\n\n if (!navMesh.initSolo(navMeshData)) {\n return fail('Failed to create Detour navmesh');\n }\n\n return {\n success: true,\n navMesh,\n intermediates,\n };\n};\n","import {\n Arrays,\n DetourTileCacheParams,\n NavMesh,\n NavMeshParams,\n Raw,\n RecastBuildContext,\n RecastChunkyTriMesh,\n RecastCompactHeightfield,\n RecastConfig,\n RecastHeightfield,\n RecastHeightfieldLayerSet,\n TileCache,\n TileCacheMeshProcess,\n Vector2Tuple,\n Vector3Tuple,\n allocCompactHeightfield,\n allocHeightfield,\n allocHeightfieldLayerSet,\n buildCompactHeightfield,\n buildHeightfieldLayers,\n buildTileCacheLayer,\n calcGridSize,\n cloneRcConfig,\n createHeightfield,\n createRcConfig,\n erodeWalkableArea,\n filterLedgeSpans,\n filterLowHangingWalkableObstacles,\n filterWalkableLowHeightSpans,\n freeCompactHeightfield,\n freeHeightfield,\n freeHeightfieldLayerSet,\n getHeightfieldLayerAreas,\n getHeightfieldLayerCons,\n getHeightfieldLayerHeights,\n markWalkableTriangles,\n rasterizeTriangles,\n recastConfigDefaults,\n vec3,\n} from '@recast-navigation/core';\nimport type R from '@recast-navigation/wasm';\nimport { Pretty } from '../types';\nimport { dtIlog2, dtNextPow2, getBoundingBox } from './common';\n\ntype TileCacheRecastConfig = Omit<RecastConfig, 'minRegionArea' | 'maxEdgeLen'>;\n\nexport type TileCacheGeneratorConfig = Pretty<\n TileCacheRecastConfig & {\n /**\n * How many layers (or \"floors\") each navmesh tile is expected to have.\n */\n expectedLayersPerTile: number;\n\n /**\n * The max number of obstacles\n */\n maxObstacles: number;\n\n /**\n * The tile cache mesh process implementation.\n * If not provided, a default one is created via `createDefaultTileCacheMeshProcess()`\n * @default createDefaultTileCacheMeshProcess()\n */\n tileCacheMeshProcess?: TileCacheMeshProcess;\n }\n>;\n\nexport const tileCacheGeneratorConfigDefaults: TileCacheGeneratorConfig = {\n ...recastConfigDefaults,\n tileSize: 32,\n expectedLayersPerTile: 4,\n maxObstacles: 128,\n};\n\nexport type TileCacheGeneratorTileIntermediates = {\n tileX: number;\n tileY: number;\n heightfield?: RecastHeightfield;\n compactHeightfield?: RecastCompactHeightfield;\n heightfieldLayerSet?: RecastHeightfieldLayerSet;\n};\n\nexport type TileCacheGeneratorIntermediates = {\n type: 'tilecache';\n buildContext: RecastBuildContext;\n chunkyTriMesh?: RecastChunkyTriMesh;\n tileIntermediates: TileCacheGeneratorTileIntermediates[];\n};\n\ntype TileCacheGeneratorSuccessResult = {\n tileCache: TileCache;\n navMesh: NavMesh;\n success: true;\n intermediates: TileCacheGeneratorIntermediates;\n};\n\ntype TileCacheGeneratorFailResult = {\n tileCache: undefined;\n navMesh: undefined;\n success: false;\n error: string;\n intermediates: TileCacheGeneratorIntermediates;\n};\n\nexport type TileCacheGeneratorResult =\n | TileCacheGeneratorSuccessResult\n | TileCacheGeneratorFailResult;\n\nexport const createDefaultTileCacheMeshProcess = () =>\n new TileCacheMeshProcess((navMeshCreateParams, polyAreas, polyFlags) => {\n for (let i = 0; i < navMeshCreateParams.polyCount(); ++i) {\n polyAreas.set(i, 0);\n polyFlags.set(i, 1);\n }\n });\n\n/**\n * Builds a TileCache and NavMesh from the given positions and indices.\n * TileCache assumes small tiles (around 32-64 squared) and does some tricks to make the update fast.\n * @param positions a flat array of positions\n * @param indices a flat array of indices\n * @param navMeshConfig optional configuration for the NavMesh\n * @param keepIntermediates if true intermediates will be returned\n */\nexport const generateTileCache = (\n positions: ArrayLike<number>,\n indices: ArrayLike<number>,\n navMeshGeneratorConfig: Partial<TileCacheGeneratorConfig> = {},\n keepIntermediates = false\n): TileCacheGeneratorResult => {\n const buildContext = new RecastBuildContext();\n\n const intermediates: TileCacheGeneratorIntermediates = {\n type: 'tilecache',\n buildContext,\n chunkyTriMesh: undefined,\n tileIntermediates: [],\n };\n\n const tileCache = new TileCache();\n const navMesh = new NavMesh();\n\n const cleanup = () => {\n if (!keepIntermediates) {\n for (let i = 0; i < intermediates.tileIntermediates.length; i++) {\n const tileIntermediate = intermediates.tileIntermediates[i];\n\n if (tileIntermediate.heightfield) {\n freeHeightfield(tileIntermediate.heightfield);\n tileIntermediate.heightfield = undefined;\n }\n\n if (tileIntermediate.compactHeightfield) {\n freeCompactHeightfield(tileIntermediate.compactHeightfield);\n tileIntermediate.compactHeightfield = undefined;\n }\n\n if (tileIntermediate.heightfieldLayerSet) {\n freeHeightfieldLayerSet(tileIntermediate.heightfieldLayerSet);\n tileIntermediate.heightfieldLayerSet = undefined;\n }\n }\n }\n };\n\n const fail = (error: string): TileCacheGeneratorFailResult => {\n cleanup();\n\n tileCache.destroy();\n navMesh.destroy();\n\n return {\n success: false,\n navMesh: undefined,\n tileCache: undefined,\n intermediates,\n error,\n };\n };\n\n const verts = positions as number[];\n const nVerts = indices.length;\n const vertsArray = new Arrays.VertsArray();\n vertsArray.copy(verts, verts.length);\n\n const tris = indices as number[];\n const nTris = indices.length / 3;\n const trisArray = new Arrays.TrisArray();\n trisArray.copy(tris, tris.length);\n\n const { bbMin, bbMax } = getBoundingBox(positions, indices);\n\n const { expectedLayersPerTile, maxObstacles, ...recastConfig } = {\n ...tileCacheGeneratorConfigDefaults,\n ...navMeshGeneratorConfig,\n };\n\n //\n // Step 1. Initialize build config.\n //\n const config = createRcConfig(recastConfig);\n\n const gridSize = calcGridSize(bbMin, bbMax, config.cs);\n config.width = gridSize.width;\n config.height = gridSize.height;\n\n config.minRegionArea = config.minRegionArea * config.minRegionArea; // Note: area = size*size\n config.mergeRegionArea = config.mergeRegionArea * config.mergeRegionArea; // Note: area = size*size\n config.detailSampleDist =\n config.detailSampleDist < 0.9 ? 0 : config.cs * config.detailSampleDist;\n config.detailSampleMaxError = config.ch * config.detailSampleMaxError;\n\n const tileSize = Math.floor(config.tileSize);\n const tileWidth = Math.floor((config.width + tileSize - 1) / tileSize);\n const tileHeight = Math.floor((config.height + tileSize - 1) / tileSize);\n\n // Generation params\n config.borderSize = config.walkableRadius + 3; // Reserve enough padding.\n config.width = config.tileSize + config.borderSize * 2;\n config.height = config.tileSize + config.borderSize * 2;\n\n // Tile cache params\n const tileCacheParams = DetourTileCacheParams.create({\n orig: bbMin,\n cs: config.cs,\n ch: config.ch,\n width: config.tileSize,\n height: config.tileSize,\n walkableHeight: config.walkableHeight,\n walkableRadius: config.walkableRadius,\n walkableClimb: config.walkableClimb,\n maxSimplificationError: config.maxSimplificationError,\n maxTiles: tileWidth * tileHeight * expectedLayersPerTile,\n maxObstacles,\n });\n\n const allocator = new Raw.RecastLinearAllocator(32000);\n const compressor = new Raw.RecastFastLZCompressor();\n\n const tileCacheMeshProcess =\n navMeshGeneratorConfig.tileCacheMeshProcess ??\n createDefaultTileCacheMeshProcess();\n\n if (\n !tileCache.init(\n tileCacheParams,\n allocator,\n compressor,\n tileCacheMeshProcess\n )\n ) {\n return fail('Failed to initialize tile cache');\n }\n\n const orig = vec3.fromArray(bbMin);\n\n // Max tiles and max polys affect how the tile IDs are caculated.\n // There are 22 bits available for identifying a tile and a polygon.\n let tileBits = Math.min(\n Math.floor(\n dtIlog2(dtNextPow2(tileWidth * tileHeight * expectedLayersPerTile))\n ),\n 14\n );\n if (tileBits > 14) {\n tileBits = 14;\n }\n const polyBits = 22 - tileBits;\n\n const maxTiles = 1 << tileBits;\n const maxPolysPerTile = 1 << polyBits;\n\n const navMeshParams = NavMeshParams.create({\n orig,\n tileWidth: config.tileSize * config.cs,\n tileHeight: config.tileSize * config.cs,\n maxTiles,\n maxPolys: maxPolysPerTile,\n });\n\n if (!navMesh.initTiled(navMeshParams)) {\n return fail('Failed to initialize tiled navmesh');\n }\n\n const chunkyTriMesh = new RecastChunkyTriMesh();\n intermediates.chunkyTriMesh = chunkyTriMesh;\n\n if (!chunkyTriMesh.init(vertsArray, trisArray, nTris, 256)) {\n return fail('Failed to build chunky triangle mesh');\n }\n\n const rasterizeTileLayers = (tileX: number, tileY: number) => {\n // Tile intermediates\n const tileIntermediates: TileCacheGeneratorTileIntermediates = {\n tileX,\n tileY,\n };\n\n // Tile bounds\n const tcs = config.tileSize * config.cs;\n\n const tileConfig = cloneRcConfig(config);\n\n const tileBoundsMin: Vector3Tuple = [\n bbMin[0] + tileX * tcs,\n bbMin[1],\n bbMin[2] + tileY * tcs,\n ];\n\n const tileBoundsMax: Vector3Tuple = [\n bbMin[0] + (tileX + 1) * tcs,\n bbMax[1],\n bbMin[2] + (tileY + 1) * tcs,\n ];\n\n tileBoundsMin[0] -= tileConfig.borderSize * tileConfig.cs;\n tileBoundsMin[2] -= tileConfig.borderSize * tileConfig.cs;\n tileBoundsMax[0] += tileConfig.borderSize * tileConfig.cs;\n tileBoundsMax[2] += tileConfig.borderSize * tileConfig.cs;\n\n tileConfig.set_bmin(0, tileBoundsMin[0]);\n tileConfig.set_bmin(1, tileBoundsMin[1]);\n tileConfig.set_bmin(2, tileBoundsMin[2]);\n\n tileConfig.set_bmax(0, tileBoundsMax[0]);\n tileConfig.set_bmax(1, tileBoundsMax[1]);\n tileConfig.set_bmax(2, tileBoundsMax[2]);\n\n // Allocate voxel heightfield where we rasterize our input data to.\n const heightfield = allocHeightfield();\n tileIntermediates.heightfield = heightfield;\n\n if (\n !createHeightfield(\n buildContext,\n heightfield,\n tileConfig.width,\n tileConfig.height,\n tileBoundsMin,\n tileBoundsMax,\n tileConfig.cs,\n tileConfig.ch\n )\n ) {\n return { n: 0 };\n }\n\n const tbmin: Vector2Tuple = [tileBoundsMin[0], tileBoundsMin[2]];\n const tbmax: Vector2Tuple = [tileBoundsMax[0], tileBoundsMax[2]];\n\n // TODO: Make grow when returning too many items.\n const maxChunkIds = 512;\n const chunkIdsArray = new Arrays.ChunkIdsArray();\n chunkIdsArray.resize(maxChunkIds);\n\n const nChunksOverlapping = chunkyTriMesh.getChunksOverlappingRect(\n tbmin,\n tbmax,\n chunkIdsArray,\n maxChunkIds\n );\n\n if (nChunksOverlapping === 0) {\n return { n: 0 };\n }\n\n for (let i = 0; i < nChunksOverlapping; ++i) {\n const nodeId = chunkIdsArray.get_data(i);\n const node = chunkyTriMesh.nodes(nodeId);\n const nNodeTris = node.n;\n\n const nodeTrisArray = chunkyTriMesh.getNodeTris(nodeId);\n\n const triAreasArray = new Arrays.TriAreasArray();\n triAreasArray.resize(nNodeTris);\n\n // Find triangles which are walkable based on their slope and rasterize them.\n // If your input data is multiple meshes, you can transform them here, calculate\n // the are type for each of the meshes and rasterize them.\n markWalkableTriangles(\n buildContext,\n tileConfig.walkableSlopeAngle,\n vertsArray,\n nVerts,\n nodeTrisArray,\n nNodeTris,\n triAreasArray\n );\n\n const success = rasterizeTriangles(\n buildContext,\n vertsArray,\n nVerts,\n nodeTrisArray,\n triAreasArray,\n nNodeTris,\n heightfield,\n tileConfig.walkableClimb\n );\n\n triAreasArray.free();\n\n if (!success) {\n return { n: 0 };\n }\n }\n\n // Once all geometry is rasterized, we do initial pass of filtering to\n // remove unwanted overhangs caused by the conservative rasterization\n // as well as filter spans where the character cannot possibly stand.\n filterLowHangingWalkableObstacles(\n buildContext,\n config.walkableClimb,\n heightfield\n );\n filterLedgeSpans(\n buildContext,\n config.walkableHeight,\n config.walkableClimb,\n heightfield\n );\n filterWalkableLowHeightSpans(\n buildContext,\n config.walkableHeight,\n heightfield\n );\n\n const compactHeightfield = allocCompactHeightfield();\n if (\n !buildCompactHeightfield(\n buildContext,\n config.walkableHeight,\n config.walkableClimb,\n heightfield,\n compactHeightfield\n )\n ) {\n return { n: 0 };\n }\n\n if (!keepIntermediates) {\n freeHeightfield(tileIntermediates.heightfield);\n tileIntermediates.heightfield = undefined;\n }\n\n // Erode the walkable area by agent radius\n if (\n !erodeWalkableArea(\n buildContext,\n config.walkableRadius,\n compactHeightfield\n )\n ) {\n return { n: 0 };\n }\n\n const heightfieldLayerSet = allocHeightfieldLayerSet();\n if (\n !buildHeightfieldLayers(\n buildContext,\n compactHeightfield,\n config.borderSize,\n config.walkableHeight,\n heightfieldLayerSet\n )\n ) {\n return { n: 0 };\n }\n\n if (!keepIntermediates) {\n freeCompactHeightfield(compactHeightfield);\n tileIntermediates.compactHeightfield = undefined;\n }\n\n const tiles: R.UnsignedCharArray[] = [];\n\n for (let i = 0; i < heightfieldLayerSet.nlayers(); i++) {\n const tile = new Arrays.TileCacheData();\n const heightfieldLayer = heightfieldLayerSet.layers(i);\n\n // Store header\n const header = new Raw.dtTileCacheLayerHeader();\n header.magic = Raw.Detour.TILECACHE_MAGIC;\n header.version = Raw.Detour.TILECACHE_VERSION;\n\n // Tile layer location in the navmesh\n header.tx = tileX;\n header.ty = tileY;\n header.tlayer = i;\n\n const heightfieldLayerBin = heightfieldLayer.bmin();\n const heightfieldLayerBmax = heightfieldLayer.bmax();\n header.set_bmin(0, heightfieldLayerBin.x);\n header.set_bmin(1, heightfieldLayerBin.y);\n header.set_bmin(2, heightfieldLayerBin.z);\n\n header.set_bmax(0, heightfieldLayerBmax.x);\n header.set_bmax(1, heightfieldLayerBmax.y);\n header.set_bmax(2, heightfieldLayerBmax.z);\n\n // Tile info\n header.width = heightfieldLayer.width();\n header.height = heightfieldLayer.height();\n header.minx = heightfieldLayer.minx();\n header.maxx = heightfieldLayer.maxx();\n header.miny = heightfieldLayer.miny();\n header.maxy = heightfieldLayer.maxy();\n header.hmin = heightfieldLayer.hmin();\n header.hmax = heightfieldLayer.hmax();\n\n const heights = getHeightfieldLayerHeights(heightfieldLayer);\n const areas = getHeightfieldLayerAreas(heightfieldLayer);\n const cons = getHeightfieldLayerCons(heightfieldLayer);\n\n const status = buildTileCacheLayer(\n compressor,\n header,\n heights,\n areas,\n cons,\n tile\n );\n\n if (Raw.Detour.statusFailed(status)) {\n return { n: 0 };\n }\n\n tiles.push(tile);\n }\n\n if (!keepIntermediates) {\n freeHeightfieldLayerSet(heightfieldLayerSet);\n tileIntermediates.heightfieldLayerSet = undefined;\n }\n\n intermediates.tileIntermediates.push(tileIntermediates);\n\n return { n: tiles.length, tiles };\n };\n\n // Preprocess tiles\n for (let y = 0; y < tileHeight; ++y) {\n for (let x = 0; x < tileWidth; ++x) {\n const { n, tiles: newTiles } = rasterizeTileLayers(x, y);\n\n if (n > 0 && newTiles) {\n for (let i = 0; i < n; i++) {\n const tileCacheData = newTiles[i];\n\n const addResult = tileCache.addTile(tileCacheData);\n\n if (Raw.Detour.statusFailed(addResult.status)) {\n buildContext.log(\n Raw.Module.RC_LOG_WARNING,\n `Failed to add tile to tile cache - tx: ${x}, ty: ${y}`\n );\n continue;\n }\n }\n }\n }\n }\n\n // Build initial meshes\n for (let y = 0; y < tileHeight; y++) {\n for (let x = 0; x < tileWidth; x++) {\n const dtStatus = tileCache.buildNavMeshTilesAt(x, y, navMesh);\n\n if (Raw.Detour.statusFailed(dtStatus)) {\n return fail(`Failed to build nav mesh tiles at ${x}, ${y}`);\n }\n }\n }\n\n cleanup();\n\n return {\n success: true,\n tileCache,\n navMesh,\n intermediates,\n };\n};\n","import {\n Arrays,\n NavMesh,\n NavMeshCreateParams,\n NavMeshParams,\n Raw,\n RecastBuildContext,\n RecastChunkyTriMesh,\n RecastCompactHeightfield,\n RecastConfig,\n RecastContourSet,\n RecastHeightfield,\n Vector2Tuple,\n Vector3Tuple,\n allocCompactHeightfield,\n allocContourSet,\n allocHeightfield,\n allocPolyMesh,\n allocPolyMeshDetail,\n buildCompactHeightfield,\n buildContours,\n buildDistanceField,\n buildPolyMesh,\n buildPolyMeshDetail,\n buildRegions,\n calcGridSize,\n cloneRcConfig,\n createHeightfield,\n createNavMeshData,\n createRcConfig,\n statusToReadableString,\n erodeWalkableArea,\n filterLedgeSpans,\n filterLowHangingWalkableObstacles,\n filterWalkableLowHeightSpans,\n freeCompactHeightfield,\n freeContourSet,\n freeHeightfield,\n markWalkableTriangles,\n rasterizeTriangles,\n recastConfigDefaults,\n vec3,\n} from '@recast-navigation/core';\nimport type R from '@recast-navigation/wasm';\nimport { Pretty } from '../types';\nimport {\n OffMeshConnectionGeneratorParams,\n dtIlog2,\n dtNextPow2,\n getBoundingBox,\n} from './common';\n\nexport type TiledNavMeshGeneratorConfig = Pretty<\n RecastConfig & OffMeshConnectionGeneratorParams\n>;\n\nexport const tiledNavMeshGeneratorConfigDefaults: TiledNavMeshGeneratorConfig =\n {\n ...recastConfigDefaults,\n };\n\nexport type TiledNavMeshGeneratorIntermediates = {\n type: 'tiled';\n buildContext: RecastBuildContext;\n chunkyTriMesh?: RecastChunkyTriMesh;\n tileIntermediates: {\n tileX: number;\n tileY: number;\n heightfield?: RecastHeightfield;\n compactHeightfield?: RecastCompactHeightfield;\n contourSet?: RecastContourSet;\n }[];\n};\n\ntype TiledNavMeshGeneratorSuccessResult = {\n navMesh: NavMesh;\n success: true;\n intermediates: TiledNavMeshGeneratorIntermediates;\n};\n\ntype TiledNavMeshGeneratorFailResult = {\n navMesh: undefined;\n success: false;\n intermediates: TiledNavMeshGeneratorIntermediates;\n error: string;\n};\n\nexport type TiledNavMeshGeneratorResult =\n | TiledNavMeshGeneratorSuccessResult\n | TiledNavMeshGeneratorFailResult;\n\n/**\n * Builds a Tiled NavMesh\n * @param positions a flat array of positions\n * @param indices a flat array of indices\n * @param navMeshGeneratorConfig optional configuration for the NavMesh generator\n * @param keepIntermediates if true intermediates will be returned\n */\nexport const generateTiledNavMesh = (\n positions: ArrayLike<number>,\n indices: ArrayLike<number>,\n navMeshGeneratorConfig: Partial<TiledNavMeshGeneratorConfig> = {},\n keepIntermediates = false\n): TiledNavMeshGeneratorResult => {\n const buildContext = new RecastBuildContext();\n\n const intermediates: TiledNavMeshGeneratorIntermediates = {\n type: 'tiled',\n buildContext,\n chunkyTriMesh: undefined,\n tileIntermediates: [],\n };\n\n const navMesh = new NavMesh();\n\n const cleanup = () => {\n if (keepIntermediates) return;\n\n for (let i = 0; i < intermediates.tileIntermediates.length; i++) {\n const tileIntermediate = intermediates.tileIntermediates[i];\n\n if (tileIntermediate.compactHeightfield) {\n freeCompactHeightfield(tileIntermediate.compactHeightfield);\n }\n\n if (tileIntermediate.heightfield) {\n freeHeightfield(tileIntermediate.heightfield);\n }\n\n if (tileIntermediate.contourSet) {\n freeContourSet(tileIntermediate.contourSet);\n }\n }\n\n if (intermediates.chunkyTriMesh) {\n intermediates.chunkyTriMesh = undefined;\n }\n };\n\n const fail = (error: string): TiledNavMeshGeneratorFailResult => {\n cleanup();\n\n navMesh.destroy();\n\n return {\n success: false,\n navMesh: undefined,\n intermediates,\n error,\n };\n };\n\n //\n // Initialize build config.\n //\n const config = createRcConfig({\n ...tiledNavMeshGeneratorConfigDefaults,\n ...navMeshGeneratorConfig,\n });\n\n /* get input bounding box */\n const { bbMin, bbMax } = getBoundingBox(positions, indices);\n\n /* grid size */\n const gridSize = calcGridSize(bbMin, bbMax, config.cs);\n config.width = gridSize.width;\n config.height = gridSize.height;\n\n config.minRegionArea = config.minRegionArea * config.minRegionArea; // Note: area = size*size\n config.mergeRegionArea = config.mergeRegionArea * config.mergeRegionArea; // Note: area = size*size\n config.tileSize = Math.floor(config.tileSize);\n config.borderSize = config.walkableRadius + 3; // Reserve enough padding.\n config.width = config.tileSize + config.borderSize * 2;\n config.height = config.tileSize + config.borderSize * 2;\n config.detailSampleDist =\n config.detailSampleDist < 0.9 ? 0 : config.cs * config.detailSampleDist;\n config.detailSampleMaxError = config.ch * config.detailSampleMaxError;\n\n // tile size\n const tileSize = Math.floor(config.tileSize);\n const tileWidth = Math.floor((gridSize.width + tileSize - 1) / tileSize);\n const tileHeight = Math.floor((gridSize.height + tileSize - 1) / tileSize);\n const tcs = config.tileSize * config.cs;\n\n /* verts */\n const verts = positions as number[];\n const nVerts = indices.length;\n const vertsArray = new Arrays.VertsArray();\n vertsArray.copy(verts, verts.length);\n\n /* tris */\n const tris = indices as number[];\n const nTris = indices.length / 3;\n const trisArray = new Arrays.TrisArray();\n trisArray.copy(tris, tris.length);\n\n /* Create dtNavMeshParams, initialise nav mesh for tiled use */\n const orig = vec3.fromArray(bbMin);\n\n // Max tiles and max polys affect how the tile IDs are caculated.\n // There are 22 bits available for identifying a tile and a polygon.\n let tileBits = Math.min(\n Math.floor(dtIlog2(dtNextPow2(tileWidth * tileHeight))),\n 14\n );\n if (tileBits > 14) tileBits = 14;\n const polyBits = 22 - tileBits;\n\n const maxTiles = 1 << tileBits;\n const maxPolysPerTile = 1 << polyBits;\n\n const navMeshParams = NavMeshParams.create({\n orig,\n tileWidth: config.tileSize * config.cs,\n tileHeight: config.tileSize * config.cs,\n maxTiles,\n maxPolys: maxPolysPerTile,\n });\n\n if (!navMesh.initTiled(navMeshParams)) {\n return fail('Could not init nav mesh for tiled use');\n }\n\n /* create chunky tri mesh */\n const chunkyTriMesh = new RecastChunkyTriMesh();\n intermediates.chunkyTriMesh = chunkyTriMesh;\n\n if (!chunkyTriMesh.init(vertsArray, trisArray, nTris, 256)) {\n return fail('Failed to build chunky triangle mesh');\n }\n\n /** @internal */\n const buildTileMesh = (\n tileX: number,\n tileY: number,\n tileBoundsMin: Vector3Tuple,\n tileBoundsMax: Vector3Tuple\n ):\n | { success: true; data?: R.UnsignedCharArray }\n | { success: false; error: string } => {\n const failTileMesh = (error: string) => {\n buildContext.log(Raw.Module.RC_LOG_ERROR, error);\n\n return { success: false as const, error };\n };\n\n const tileIntermediate: {\n tileX: number;\n tileY: number;\n heightfield?: RecastHeightfield;\n compactHeightfield?: RecastCompactHeightfield;\n contourSet?: RecastContourSet;\n } = { tileX, tileY };\n\n intermediates.tileIntermediates.push(tileIntermediate);\n\n const tileConfig = cloneRcConfig(config);\n\n // Expand the heightfield bounding box by border size to find the extents of geometry we need to build this tile.\n //\n // This is done in order to make sure that the navmesh tiles connect correctly at the borders,\n // and the obstacles close to the border work correctly with the dilation process.\n // No polygons (or contours) will be created on the border area.\n //\n // IMPORTANT!\n //\n // :''''''''':\n // : +-----+ :\n // : | | :\n // : | |<--- tile to build\n // : | | :\n // : +-----+ :<-- geometry needed\n // :.........:\n //\n // You should use this bounding box to query your input geometry.\n //\n // For example if you build a navmesh for terrain, and want the navmesh tiles to match the terrain tile size\n // you will need to pass in data from neighbour terrain tiles too! In a simple case, just pass in all the 8 neighbours,\n // or use the bounding box below to only pass in a sliver of each of the 8 neighbours.\n\n const expandedTileBoundsMin = [...tileBoundsMin] as Vector3Tuple;\n const expandedTileBoundsMax = [...tileBoundsMax] as Vector3Tuple;\n\n expandedTileBoundsMin[0] -= tileConfig.borderSize * tileConfig.cs;\n expandedTileBoundsMin[2] -= tileConfig.borderSize * tileConfig.cs;\n\n expandedTileBoundsMax[0] += tileConfig.borderSize * tileConfig.cs;\n expandedTileBoundsMax[2] += tileConfig.borderSize * tileConfig.cs;\n\n tileConfig.set_bmin(0, expandedTileBoundsMin[0]);\n tileConfig.set_bmin(1, expandedTileBoundsMin[1]);\n tileConfig.set_bmin(2, expandedTileBoundsMin[2]);\n\n tileConfig.set_bmax(0, expandedTileBoundsMax[0]);\n tileConfig.set_bmax(1, expandedTileBoundsMax[1]);\n tileConfig.set_bmax(2, expandedTileBoundsMax[2]);\n\n // Reset build timer\n buildContext.resetTimers();\n\n // Start the build process\n buildContext.startTimer(Raw.Module.RC_TIMER_TOTAL);\n\n buildContext.log(\n Raw.Module.RC_LOG_PROGRESS,\n `Building tile ${intermediates.tileIntermediates.length} at x: ${tileX}, y: ${tileY}`\n );\n buildContext.log(\n Raw.Module.RC_LOG_PROGRESS,\n ` - ${config.width} x ${config.height} cells`\n );\n buildContext.log(\n Raw.Module.RC_LOG_PROGRESS,\n ` - ${nVerts / 1000}fK verts, ${nTris / 1000}K tris`\n );\n\n // Allocate voxel heightfield where we rasterize our input data to.\n const heightfield = allocHeightfield();\n tileIntermediate.heightfield = heightfield;\n\n if (\n !createHeightfield(\n buildContext,\n heightfield,\n tileConfig.width,\n tileConfig.height,\n expandedTileBoundsMin,\n expandedTileBoundsMax,\n tileConfig.cs,\n tileConfig.ch\n )\n ) {\n return failTileMesh('Could not create heightfield');\n }\n\n // Allocate array that can hold triangle flags.\n // If you have multiple meshes you need to process, allocate\n // and array which can hold the max number of triangles you need to process.\n const triAreas = new Arrays.TriAreasArray();\n triAreas.resize(chunkyTriMesh.maxTrisPerChunk());\n\n const tbmin: Vector2Tuple = [\n expandedTileBoundsMin[0],\n expandedTileBoundsMin[2],\n ];\n const tbmax: Vector2Tuple = [\n expandedTileBoundsMax[0],\n expandedTileBoundsMax[2],\n ];\n\n // TODO: Make grow when returning too many items.\n const maxChunkIds = 512;\n const chunkIdsArray = new Arrays.ChunkIdsArray();\n chunkIdsArray.resize(maxChunkIds);\n\n const nChunksOverlapping = chunkyTriMesh.getChunksOverlappingRect(\n tbmin,\n tbmax,\n chunkIdsArray,\n maxChunkIds\n );\n\n if (nChunksOverlapping === 0) {\n return { success: true };\n }\n\n for (let i = 0; i < nChunksOverlapping; ++i) {\n const nodeId = chunkIdsArray.get_data(i);\n const node = chunkyTriMesh.nodes(nodeId);\n const nNodeTris = node.n;\n\n const nodeTrisArray = chunkyTriMesh.getNodeTris(nodeId);\n\n const triAreasArray = new Arrays.TriAreasArray();\n triAreasArray.resize(nNodeTris);\n\n // Find triangles which are walkable based on their slope and rasterize them.\n // If your input data is multiple meshes, you can transform them here, calculate\n // the are type for each of the meshes and rasterize them.\n markWalkableTriangles(\n buildContext,\n tileConfig.walkableSlopeAngle,\n vertsArray,\n nVerts,\n nodeTrisArray,\n nNodeTris,\n triAreasArray\n );\n\n const success = rasterizeTriangles(\n buildContext,\n vertsArray,\n nVerts,\n nodeTrisArray,\n triAreasArray,\n nNodeTris,\n heightfield,\n tileConfig.walkableClimb\n );\n\n triAreasArray.free();\n\n if (!success) {\n return failTileMesh('Could not rasterize triangles');\n }\n }\n\n // Once all geometry is rasterized, we do initial pass of filtering to\n // remove unwanted overhangs caused by the conservative rasterization\n // as well as filter spans where the character cannot possibly stand.\n filterLowHangingWalkableObstacles(\n buildContext,\n tileConfig.walkableClimb,\n heightfield\n );\n filterLedgeSpans(\n buildContext,\n tileConfig.walkableHeight,\n tileConfig.walkableClimb,\n heightfield\n );\n filterWalkableLowHeightSpans(\n buildContext,\n tileConfig.walkableHeight,\n heightfield\n );\n\n // Compact the heightfield so that it is faster to handle from now on.\n // This will result more cache coherent data as well as the neighbours\n // between walkable cells will be calculated.\n const compactHeightfield = allocCompactHeightfield();\n tileIntermediate.compactHeightfield = compactHeightfield;\n\n if (\n !buildCompactHeightfield(\n buildContext,\n tileConfig.walkableHeight,\n tileConfig.walkableClimb,\n heightfield,\n compactHeightfield\n )\n ) {\n return failTileMesh('Could not build compact heightfield');\n }\n\n if (!keepIntermediates) {\n freeHeightfield(tileIntermediate.heightfield);\n tileIntermediate.heightfield = undefined;\n }\n\n // Erode the walkable area by agent radius\n if (\n !erodeWalkableArea(\n buildContext,\n tileConfig.walkableRadius,\n compactHeightfield\n )\n ) {\n return failTileMesh('Could not erode walkable area');\n }\n\n // (Optional) Mark areas\n // markConvexPolyArea(...)\n\n // Prepare for region partitioning, by calculating Distance field along the walkable surface.\n if (!buildDistanceField(buildContext, compactHeightfield)) {\n return failTileMesh('Failed to build distance field');\n }\n\n // Partition the walkable surface into simple regions without holes.\n if (\n !buildRegions(\n buildContext,\n compactHeightfield,\n tileConfig.borderSize,\n tileConfig.minRegionArea,\n tileConfig.mergeRegionArea\n )\n ) {\n return failTileMesh('Failed to build regions');\n }\n\n //\n // Trace and simplify region contours.\n //\n const contourSet = allocContourSet();\n tileIntermediate.contourSet = contourSet;\n\n if (\n !buildContours(\n buildContext,\n compactHeightfield,\n tileConfig.maxSimplificationError,\n tileConfig.maxEdgeLen,\n contourSet,\n Raw.Module.RC_CONTOUR_TESS_WALL_EDGES\n )\n ) {\n return failTileMesh('Failed to create contours');\n }\n\n //\n // Build polygons mesh from contours.\n //\n const polyMesh = allocPolyMesh();\n if (\n !buildPolyMesh(\n buildContext,\n contourSet,\n tileConfig.maxVertsPerPoly,\n polyMesh\n )\n ) {\n return failTileMesh('Failed to triangulate contours');\n }\n\n //\n // Create detail mesh which allows to access approximate height on each polygon.\n //\n const polyMeshDetail = allocPolyMeshDetail();\n if (\n !buildPolyMeshDetail(\n buildContext,\n polyMesh,\n compactHeightfield,\n tileConfig.detailSampleDist,\n tileConfig.detailSampleMaxError,\n polyMeshDetail\n )\n ) {\n return failTileMesh('Failed to build detail mesh');\n }\n\n if (!keepIntermediates) {\n freeCompactHeightfield(compactHeightfield);\n tileIntermediate.compactHeightfield = undefined;\n\n freeContourSet(contourSet);\n tileIntermediate.contourSet = undefined;\n }\n\n // Update poly flags from areas.\n for (let i = 0; i < polyMesh.npolys(); i++) {\n if (polyMesh.areas(i) == Raw.Recast.WALKABLE_AREA) {\n polyMesh.setAreas(i, 0);\n }\n if (polyMesh.areas(i) == 0) {\n polyMesh.setFlags(i, 1);\n }\n }\n\n const navMeshCreateParams = new NavMeshCreateParams();\n\n navMeshCreateParams.setPolyMeshCreateParams(polyMesh);\n navMeshCreateParams.setPolyMeshDetailCreateParams(polyMeshDetail);\n\n navMeshCreateParams.setWalkableHeight(tileConfig.walkableHeight);\n navMeshCreateParams.setWalkableRadius(tileConfig.walkableRadius);\n navMeshCreateParams.setWalkableClimb(tileConfig.walkableClimb);\n\n navMeshCreateParams.setCellSize(tileConfig.cs);\n navMeshCreateParams.setCellHeight(tileConfig.ch);\n\n navMeshCreateParams.setBuildBvTree(true);\n\n if (navMeshGeneratorConfig.offMeshConnections) {\n navMeshCreateParams.setOffMeshConnections(\n navMeshGeneratorConfig.offMeshConnections\n );\n }\n\n navMeshCreateParams.setTileX(tileX);\n navMeshCreateParams.setTileY(tileY);\n\n const createNavMeshDataResult = createNavMeshData(navMeshCreateParams);\n\n if (!createNavMeshDataResult.success) {\n return failTileMesh('Failed to create Detour navmesh data');\n }\n\n buildContext.log(\n Raw.Module.RC_LOG_PROGRESS,\n `>> Polymesh: ${polyMesh.nverts()} vertices ${polyMesh.npolys()} polygons`\n );\n\n return { success: true, data: createNavMeshDataResult.navMeshData };\n };\n\n buildContext.startTimer(Raw.Module.RC_TIMER_TEMP);\n\n const lastBuiltTileBmin: Vector3Tuple = [0, 0, 0];\n const lastBuiltTileBmax: Vector3Tuple = [0, 0, 0];\n\n for (let y = 0; y < tileHeight; y++) {\n for (let x = 0; x < tileWidth; x++) {\n lastBuiltTileBmin[0] = bbMin[0] + x * tcs;\n lastBuiltTileBmin[1] = bbMin[1];\n lastBuiltTileBmin[2] = bbMin[2] + y * tcs;\n\n lastBuiltTileBmax[0] = bbMin[0] + (x + 1) * tcs;\n lastBuiltTileBmax[1] = bbMax[1];\n lastBuiltTileBmax[2] = bbMin[2] + (y + 1) * tcs;\n\n const result = buildTileMesh(x, y, lastBuiltTileBmin, lastBuiltTileBmax);\n\n if (result.success && result.data) {\n navMesh.removeTile(navMesh.getTileRefAt(x, y, 0));\n\n const addTileResult = navMesh.addTile(\n result.data,\n Raw.Module.DT_TILE_FREE_DATA,\n 0\n );\n\n if (Raw.Detour.statusFailed(addTileResult.status)) {\n buildContext.log(\n Raw.Module.RC_LOG_WARNING,\n `Failed to add tile to nav mesh` +\n '\\n\\t' +\n `tx: ${x}, ty: ${y},` +\n `status: ${statusToReadableString(addTileResult.status)} (${\n addTileResult.status\n })`\n );\n\n result.data.free();\n }\n }\n }\n }\n\n buildContext.stopTimer(Raw.Module.RC_TIMER_TEMP);\n\n if (!keepIntermediates) {\n cleanup();\n }\n\n return {\n success: true,\n navMesh,\n intermediates,\n };\n};\n"],"names":["getBoundingBox","positions","indices","bbMin","x","Infinity","y","z","bbMax","i","length","ind","Math","min","max","vec3","toArray","dtIlog2","v","r","shift","Number","dtNextPow2","soloNavMeshGeneratorConfigDefaults","recastConfigDefaults","generateSoloNavMesh","navMeshGeneratorConfig","keepIntermediates","buildContext","RecastBuildContext","intermediates","type","navMesh","NavMesh","fail","error","heightfield","freeHeightfield","undefined","compactHeightfield","freeCompactHeightfield","contourSet","freeContourSet","destroy","success","verts","nVerts","vertsArray","Arrays","VertsArray","copy","tris","nTris","trisArray","TrisArray","config","createRcConfig","minRegionArea","mergeRegionArea","detailSampleDist","cs","detailSampleMaxError","ch","gridSize","calcGridSize","width","height","allocHeightfield","createHeightfield","triAreasArray","TriAreasArray","resize","markWalkableTriangles","walkableSlopeAngle","rasterizeTriangles","walkableClimb","free","filterLowHangingWalkableObstacles","filterLedgeSpans","walkableHeight","filterWalkableLowHeightSpans","allocCompactHeightfield","buildCompactHeightfield","erodeWalkableArea","walkableRadius","buildDistanceField","buildRegions","borderSize","allocContourSet","buildContours","maxSimplificationError","maxEdgeLen","Raw","Module","RC_CONTOUR_TESS_WALL_EDGES","polyMesh","allocPolyMesh","buildPolyMesh","maxVertsPerPoly","polyMeshDetail","allocPolyMeshDetail","buildPolyMeshDetail","npolys","areas","Recast","WALKABLE_AREA","setAreas","setFlags","navMeshCreateParams","NavMeshCreateParams","setPolyMeshCreateParams","setPolyMeshDetailCreateParams","setWalkableHeight","setWalkableRadius","setWalkableClimb","setCellSize","setCellHeight","setBuildBvTree","offMeshConnections","setOffMeshConnections","createNavMeshDataResult","createNavMeshData","navMeshData","initSolo","tileCacheGeneratorConfigDefaults","tileSize","expectedLayersPerTile","maxObstacles","createDefaultTileCacheMeshProcess","TileCacheMeshProcess","polyAreas","polyFlags","polyCount","set","generateTileCache","chunkyTriMesh","tileIntermediates","tileCache","TileCache","cleanup","tileIntermediate","heightfieldLayerSet","freeHeightfieldLayerSet","recastConfig","floor","tileWidth","tileHeight","tileCacheParams","DetourTileCacheParams","create","orig","maxTiles","allocator","RecastLinearAllocator","compressor","RecastFastLZCompressor","tileCacheMeshProcess","init","fromArray","tileBits","maxPolysPerTile","navMeshParams","NavMeshParams","maxPolys","initTiled","RecastChunkyTriMesh","rasterizeTileLayers","tileX","tileY","tcs","tileConfig","cloneRcConfig","tileBoundsMin","tileBoundsMax","set_bmin","set_bmax","n","tbmin","tbmax","chunkIdsArray","ChunkIdsArray","nChunksOverlapping","getChunksOverlappingRect","nodeId","get_data","nNodeTris","nodes","nodeTrisArray","getNodeTris","allocHeightfieldLayerSet","buildHeightfieldLayers","tiles","nlayers","tile","TileCacheData","heightfieldLayer","layers","header","dtTileCacheLayerHeader","magic","Detour","TILECACHE_MAGIC","version","TILECACHE_VERSION","tx","ty","tlayer","heightfieldLayerBin","bmin","heightfieldLayerBmax","bmax","minx","maxx","miny","maxy","hmin","hmax","heights","getHeightfieldLayerHeights","getHeightfieldLayerAreas","cons","getHeightfieldLayerCons","status","buildTileCacheLayer","statusFailed","push","newTiles","tileCacheData","addResult","addTile","log","RC_LOG_WARNING","dtStatus","buildNavMeshTilesAt","tiledNavMeshGeneratorConfigDefaults","generateTiledNavMesh","buildTileMesh","failTileMesh","RC_LOG_ERROR","expandedTileBoundsMin","expandedTileBoundsMax","resetTimers","startTimer","RC_TIMER_TOTAL","RC_LOG_PROGRESS","maxTrisPerChunk","setTileX","setTileY","nverts","data","RC_TIMER_TEMP","lastBuiltTileBmin","lastBuiltTileBmax","result","removeTile","getTileRefAt","addTileResult","DT_TILE_FREE_DATA","statusToReadableString","stopTimer"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"email": "isaac@isaacmason.com",
|
|
7
7
|
"url": "https://isaacmason.com/"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.23.0",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"homepage": "https://github.com/isaac-mason/recast-navigation-js",
|
|
12
12
|
"bugs": {
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"lint": "eslint --ext .ts src"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@recast-navigation/core": "0.
|
|
30
|
-
"@recast-navigation/wasm": "0.
|
|
29
|
+
"@recast-navigation/core": "0.23.0",
|
|
30
|
+
"@recast-navigation/wasm": "0.23.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@isaac-mason/eslint-config-typescript": "^0.0.5",
|