@recast-navigation/core 0.38.0 → 0.39.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.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License
2
2
 
3
- Copyright © 2022 Isaac Mason
3
+ Copyright © 2025 Isaac Mason
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/dist/index.mjs CHANGED
@@ -2287,43 +2287,6 @@ class NavMesh {
2287
2287
  restoreTileState(tile, data, maxDataSize) {
2288
2288
  return this.raw.restoreTileState(tile.raw, data, maxDataSize);
2289
2289
  }
2290
- /**
2291
- * Returns a triangle mesh that can be used to visualize the NavMesh.
2292
- */
2293
- getDebugNavMesh() {
2294
- const positions = [];
2295
- const indices = [];
2296
- let tri = 0;
2297
- const maxTiles = this.getMaxTiles();
2298
- for (let tileIndex = 0; tileIndex < maxTiles; tileIndex++) {
2299
- const tile = this.getTile(tileIndex);
2300
- const tileHeader = tile.header();
2301
- if (!tileHeader) continue;
2302
- const tilePolyCount = tileHeader.polyCount();
2303
- for (let tilePolyIndex = 0; tilePolyIndex < tilePolyCount; ++tilePolyIndex) {
2304
- const poly = tile.polys(tilePolyIndex);
2305
- if (poly.getType() === 1) continue;
2306
- const polyVertCount = poly.vertCount();
2307
- const polyDetail = tile.detailMeshes(tilePolyIndex);
2308
- const polyDetailTriBase = polyDetail.triBase();
2309
- const polyDetailTriCount = polyDetail.triCount();
2310
- for (let polyDetailTriIndex = 0; polyDetailTriIndex < polyDetailTriCount; ++polyDetailTriIndex) {
2311
- const detailTrisBaseIndex = (polyDetailTriBase + polyDetailTriIndex) * 4;
2312
- for (let trianglePoint = 0; trianglePoint < 3; ++trianglePoint) {
2313
- if (tile.detailTris(detailTrisBaseIndex + trianglePoint) < polyVertCount) {
2314
- const tileVertsBaseIndex = poly.verts(tile.detailTris(detailTrisBaseIndex + trianglePoint)) * 3;
2315
- positions.push(tile.verts(tileVertsBaseIndex), tile.verts(tileVertsBaseIndex + 1), tile.verts(tileVertsBaseIndex + 2));
2316
- } else {
2317
- const tileVertsBaseIndex = (polyDetail.vertBase() + tile.detailTris(detailTrisBaseIndex + trianglePoint) - poly.vertCount()) * 3;
2318
- positions.push(tile.detailVerts(tileVertsBaseIndex), tile.detailVerts(tileVertsBaseIndex + 1), tile.detailVerts(tileVertsBaseIndex + 2));
2319
- }
2320
- indices.push(tri++);
2321
- }
2322
- }
2323
- }
2324
- }
2325
- return [positions, indices];
2326
- }
2327
2290
  /**
2328
2291
  * Destroys the NavMesh.
2329
2292
  */
@@ -2332,6 +2295,107 @@ class NavMesh {
2332
2295
  Raw.Module.destroy(this.raw);
2333
2296
  }
2334
2297
  }
2298
+ /**
2299
+ * Gets the positions and indices of the nav mesh.
2300
+ * @param navMesh the nav mesh
2301
+ * @param flags poly flags to filter by, defaults to undefined to include all polys
2302
+ * @returns the positions and indices of the nav mesh
2303
+ */
2304
+ const getNavMeshPositionsAndIndices = (navMesh, flags) => {
2305
+ const positions = [];
2306
+ const indices = [];
2307
+ let tri = 0;
2308
+ const maxTiles = navMesh.getMaxTiles();
2309
+ for (let tileIndex = 0; tileIndex < maxTiles; tileIndex++) {
2310
+ const tile = navMesh.getTile(tileIndex);
2311
+ const tileHeader = tile.header();
2312
+ if (!tileHeader) continue;
2313
+ const tilePolyCount = tileHeader.polyCount();
2314
+ for (let tilePolyIndex = 0; tilePolyIndex < tilePolyCount; ++tilePolyIndex) {
2315
+ const poly = tile.polys(tilePolyIndex);
2316
+ if (flags !== undefined && (poly.flags() & flags) === 0) continue;
2317
+ if (poly.getType() === 1) continue;
2318
+ const polyVertCount = poly.vertCount();
2319
+ const polyDetail = tile.detailMeshes(tilePolyIndex);
2320
+ const polyDetailTriBase = polyDetail.triBase();
2321
+ const polyDetailTriCount = polyDetail.triCount();
2322
+ for (let polyDetailTriIndex = 0; polyDetailTriIndex < polyDetailTriCount; ++polyDetailTriIndex) {
2323
+ const detailTrisBaseIndex = (polyDetailTriBase + polyDetailTriIndex) * 4;
2324
+ for (let trianglePoint = 0; trianglePoint < 3; ++trianglePoint) {
2325
+ if (tile.detailTris(detailTrisBaseIndex + trianglePoint) < polyVertCount) {
2326
+ const tileVertsBaseIndex = poly.verts(tile.detailTris(detailTrisBaseIndex + trianglePoint)) * 3;
2327
+ positions.push(tile.verts(tileVertsBaseIndex), tile.verts(tileVertsBaseIndex + 1), tile.verts(tileVertsBaseIndex + 2));
2328
+ } else {
2329
+ const tileVertsBaseIndex = (polyDetail.vertBase() + tile.detailTris(detailTrisBaseIndex + trianglePoint) - poly.vertCount()) * 3;
2330
+ positions.push(tile.detailVerts(tileVertsBaseIndex), tile.detailVerts(tileVertsBaseIndex + 1), tile.detailVerts(tileVertsBaseIndex + 2));
2331
+ }
2332
+ indices.push(tri++);
2333
+ }
2334
+ }
2335
+ }
2336
+ }
2337
+ return [positions, indices];
2338
+ };
2339
+ /**
2340
+ * Disables all polys not connected to provided start poly refs.
2341
+ * @param navMesh the nav mesh to prune
2342
+ * @param startPolyRefs poly refs to start the flood fill from, can be retrieved with `navMeshQuery.findNearestPoly`
2343
+ *
2344
+ * @example
2345
+ * ```ts
2346
+ * const navMeshQuery = new NavMeshQuery(navMesh);
2347
+ *
2348
+ * const nearestPolyResult = navMeshQuery.findNearestPoly(point, {
2349
+ * halfExtents: { x: 2, y: 2, z: 2 },
2350
+ * });
2351
+ *
2352
+ * if (!nearestPolyResult.success) return;
2353
+ *
2354
+ * floodFillPruneNavMesh(navMesh, [nearestPolyResult.nearestRef]);
2355
+ * ```
2356
+ */
2357
+ const floodFillPruneNavMesh = (navMesh, startPolyRefs) => {
2358
+ /* find all polys connected to the nearest poly */
2359
+ const visited = new Set();
2360
+ const openList = [];
2361
+ for (const startPolyRef of startPolyRefs) {
2362
+ visited.add(startPolyRef);
2363
+ openList.push(startPolyRef);
2364
+ }
2365
+ while (openList.length > 0) {
2366
+ const ref = openList.pop();
2367
+ // get current poly and tile
2368
+ const {
2369
+ poly,
2370
+ tile
2371
+ } = navMesh.getTileAndPolyByRefUnsafe(ref);
2372
+ // visit linked polys
2373
+ for (let i = poly.firstLink(); i !== Detour.DT_NULL_LINK; i = tile.links(i).next()) {
2374
+ const neiRef = tile.links(i).ref();
2375
+ // skip invalid and already visited
2376
+ if (!neiRef || visited.has(neiRef)) continue;
2377
+ // mark as visited
2378
+ visited.add(neiRef);
2379
+ // visit neighbours
2380
+ openList.push(neiRef);
2381
+ }
2382
+ }
2383
+ /* disable unvisited polys */
2384
+ for (let tileIndex = 0; tileIndex < navMesh.getMaxTiles(); tileIndex++) {
2385
+ const tile = navMesh.getTile(tileIndex);
2386
+ if (!tile || !tile.header()) continue;
2387
+ const tileHeader = tile.header();
2388
+ const base = navMesh.getPolyRefBase(tile);
2389
+ for (let i = 0; i < tileHeader.polyCount(); i++) {
2390
+ const ref = base | i;
2391
+ if (!visited.has(ref)) {
2392
+ // set flag to 0
2393
+ // this could also be a custom 'disabled' area flag if using custom areas
2394
+ navMesh.setPolyFlags(ref, 0);
2395
+ }
2396
+ }
2397
+ }
2398
+ };
2335
2399
 
2336
2400
  const getRandomSeed = () => {
2337
2401
  return Raw.Module.FastRand.prototype.getSeed();
@@ -3205,4 +3269,4 @@ const importTileCache = (data, tileCacheMeshProcess) => {
3205
3269
  };
3206
3270
  };
3207
3271
 
3208
- export { ChunkIdsArray, Crowd, CrowdAgent, DebugDrawerUtils, Detour, DetourBVNode, DetourLink, DetourMeshHeader, DetourMeshTile, DetourOffMeshConnection, DetourPoly, DetourPolyDetail, DetourTileCacheParams, FloatArray, IntArray, NavMesh, NavMeshCalcTileLocResult, NavMeshCreateParams, NavMeshGetTilesAtResult, NavMeshParams, NavMeshQuery, NavMeshRemoveTileResult, NavMeshStoreTileStateResult, QueryFilter, Raw, Recast, RecastBuildContext, RecastChunkyTriMesh, RecastCompactCell, RecastCompactHeightfield, RecastCompactSpan, RecastContour, RecastContourSet, RecastHeightfield, RecastHeightfieldLayer, RecastHeightfieldLayerSet, RecastPolyMesh, RecastPolyMeshDetail, RecastSpan, RecastSpanPool, TileCache, TileCacheData, TileCacheMeshProcess, TriangleAreasArray, TrianglesArray, UnsignedCharArray, UnsignedIntArray, UnsignedShortArray, VerticesArray, allocCompactHeightfield, allocContourSet, allocHeightfield, allocHeightfieldLayerSet, allocPolyMesh, allocPolyMeshDetail, array, buildCompactHeightfield, buildContours, buildDistanceField, buildHeightfieldLayers, buildLayerRegions, buildPolyMesh, buildPolyMeshDetail, buildRegions, buildRegionsMonotone, buildTileCacheLayer, calcBounds, calcGridSize, clearUnwalkableTriangles, cloneRcConfig, copyPolyMesh, createHeightfield, createNavMeshData, createRcConfig, crowdAgentParamsDefaults, erodeWalkableArea, exportNavMesh, exportTileCache, filterLedgeSpans, filterLowHangingWalkableObstacles, filterWalkableLowHeightSpans, freeCompactHeightfield, freeContourSet, freeHeightfield, freeHeightfieldLayerSet, freePolyMesh, freePolyMeshDetail, getCon, getDirForOffset, getDirOffsetX, getDirOffsetY, getHeightFieldSpanCount, getHeightfieldLayerAreas, getHeightfieldLayerCons, getHeightfieldLayerHeights, getRandomSeed, importNavMesh, importTileCache, init, markBoxArea, markConvexPolyArea, markCylinderArea, markWalkableTriangles, medianFilterWalkableArea, mergePolyMeshDetails, mergePolyMeshes, rasterizeTriangles, recastConfigDefaults, setCon, setRandomSeed, statusDetail, statusFailed, statusInProgress, statusSucceed, statusToReadableString, vec3 };
3272
+ export { ChunkIdsArray, Crowd, CrowdAgent, DebugDrawerUtils, Detour, DetourBVNode, DetourLink, DetourMeshHeader, DetourMeshTile, DetourOffMeshConnection, DetourPoly, DetourPolyDetail, DetourTileCacheParams, FloatArray, IntArray, NavMesh, NavMeshCalcTileLocResult, NavMeshCreateParams, NavMeshGetTilesAtResult, NavMeshParams, NavMeshQuery, NavMeshRemoveTileResult, NavMeshStoreTileStateResult, QueryFilter, Raw, Recast, RecastBuildContext, RecastChunkyTriMesh, RecastCompactCell, RecastCompactHeightfield, RecastCompactSpan, RecastContour, RecastContourSet, RecastHeightfield, RecastHeightfieldLayer, RecastHeightfieldLayerSet, RecastPolyMesh, RecastPolyMeshDetail, RecastSpan, RecastSpanPool, TileCache, TileCacheData, TileCacheMeshProcess, TriangleAreasArray, TrianglesArray, UnsignedCharArray, UnsignedIntArray, UnsignedShortArray, VerticesArray, allocCompactHeightfield, allocContourSet, allocHeightfield, allocHeightfieldLayerSet, allocPolyMesh, allocPolyMeshDetail, array, buildCompactHeightfield, buildContours, buildDistanceField, buildHeightfieldLayers, buildLayerRegions, buildPolyMesh, buildPolyMeshDetail, buildRegions, buildRegionsMonotone, buildTileCacheLayer, calcBounds, calcGridSize, clearUnwalkableTriangles, cloneRcConfig, copyPolyMesh, createHeightfield, createNavMeshData, createRcConfig, crowdAgentParamsDefaults, erodeWalkableArea, exportNavMesh, exportTileCache, filterLedgeSpans, filterLowHangingWalkableObstacles, filterWalkableLowHeightSpans, floodFillPruneNavMesh, freeCompactHeightfield, freeContourSet, freeHeightfield, freeHeightfieldLayerSet, freePolyMesh, freePolyMeshDetail, getCon, getDirForOffset, getDirOffsetX, getDirOffsetY, getHeightFieldSpanCount, getHeightfieldLayerAreas, getHeightfieldLayerCons, getHeightfieldLayerHeights, getNavMeshPositionsAndIndices, getRandomSeed, importNavMesh, importTileCache, init, markBoxArea, markConvexPolyArea, markCylinderArea, markWalkableTriangles, medianFilterWalkableArea, mergePolyMeshDetails, mergePolyMeshes, rasterizeTriangles, recastConfigDefaults, setCon, setRandomSeed, statusDetail, statusFailed, statusInProgress, statusSucceed, statusToReadableString, vec3 };
@@ -267,12 +267,34 @@ export declare class NavMesh {
267
267
  * @returns
268
268
  */
269
269
  restoreTileState(tile: DetourMeshTile, data: number[], maxDataSize: number): number;
270
- /**
271
- * Returns a triangle mesh that can be used to visualize the NavMesh.
272
- */
273
- getDebugNavMesh(): [positions: number[], indices: number[]];
274
270
  /**
275
271
  * Destroys the NavMesh.
276
272
  */
277
273
  destroy(): void;
278
274
  }
275
+ /**
276
+ * Gets the positions and indices of the nav mesh.
277
+ * @param navMesh the nav mesh
278
+ * @param flags poly flags to filter by, defaults to undefined to include all polys
279
+ * @returns the positions and indices of the nav mesh
280
+ */
281
+ export declare const getNavMeshPositionsAndIndices: (navMesh: NavMesh, flags?: number) => [positions: number[], indices: number[]];
282
+ /**
283
+ * Disables all polys not connected to provided start poly refs.
284
+ * @param navMesh the nav mesh to prune
285
+ * @param startPolyRefs poly refs to start the flood fill from, can be retrieved with `navMeshQuery.findNearestPoly`
286
+ *
287
+ * @example
288
+ * ```ts
289
+ * const navMeshQuery = new NavMeshQuery(navMesh);
290
+ *
291
+ * const nearestPolyResult = navMeshQuery.findNearestPoly(point, {
292
+ * halfExtents: { x: 2, y: 2, z: 2 },
293
+ * });
294
+ *
295
+ * if (!nearestPolyResult.success) return;
296
+ *
297
+ * floodFillPruneNavMesh(navMesh, [nearestPolyResult.nearestRef]);
298
+ * ```
299
+ */
300
+ export declare const floodFillPruneNavMesh: (navMesh: NavMesh, startPolyRefs: number[]) => void;
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.38.0",
9
+ "version": "0.39.0",
10
10
  "license": "MIT",
11
11
  "homepage": "https://github.com/isaac-mason/recast-navigation-js",
12
12
  "bugs": {
@@ -27,7 +27,7 @@
27
27
  "lint": "eslint src"
28
28
  },
29
29
  "dependencies": {
30
- "@recast-navigation/wasm": "0.38.0"
30
+ "@recast-navigation/wasm": "0.39.0"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@babel/core": "^7.24.5",
@@ -38,7 +38,6 @@
38
38
  "@rollup/plugin-commonjs": "^25.0.7",
39
39
  "@rollup/plugin-node-resolve": "^15.0.1",
40
40
  "@rollup/plugin-typescript": "^11.1.6",
41
- "@types/three": "^0.169.0",
42
41
  "babel-loader": "^9.1.3",
43
42
  "eslint": "^9.6.0",
44
43
  "prettier": "^3.1.0",