recast-navigation 0.13.3 → 0.15.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/README.md CHANGED
@@ -27,22 +27,12 @@ This library provides high level APIs that make it easy to get started creating
27
27
 
28
28
  ## Installation
29
29
 
30
- This package ships as both ECMAScript modules and CJS, and is compatible with Node.js and browser environments.
31
-
32
- **CDN**
33
-
34
- ```html
35
- <script type="module">
36
- import { generateSoloNavMesh } from 'https://www.unpkg.com/@recast-navigation/core@0.9.0/dist/index.mjs';
37
- </script>
38
- ```
39
-
40
- **NPM**
41
-
42
30
  ```sh
43
31
  npm install recast-navigation
44
32
  ```
45
33
 
34
+ This package ships as both ECMAScript modules and CJS, and is compatible with Node.js and browser environments.
35
+
46
36
  If you are using Vite, you may need to opt `recast-navigation` out of pre-bundling:
47
37
 
48
38
  ```js
@@ -67,7 +57,7 @@ await init();
67
57
 
68
58
  ### Generating a NavMesh
69
59
 
70
- The easiest way to generate a NavMesh is using the high level generator functions:
60
+ The easiest way to generate a NavMesh is using the high level generator functions from `recast-navigation/generators`:
71
61
 
72
62
  - `generateSoloNavMesh` - Generates a NavMesh with a single tile. You can use this for smaller environments.
73
63
  - `generateTiledNavMesh` - Generates a NavMesh with multiple tiles. You should use this for larger environments.
@@ -80,7 +70,7 @@ The input positions and indices should adhere to OpenGL conventions:
80
70
  - The `positions` and `indices` arguments should be flat arrays of numbers
81
71
 
82
72
  ```ts
83
- import { generateSoloNavMesh } from 'recast-navigation';
73
+ import { generateSoloNavMesh } from 'recast-navigation/generators';
84
74
 
85
75
  const positions = [
86
76
  /* flat array of positions */
@@ -102,7 +92,13 @@ const { success, navMesh } = generateSoloNavMesh(
102
92
  );
103
93
  ```
104
94
 
105
- If you need to do something more advanced, you can use the lower level API to create your own NavMesh generator. See the [Advanced Usage](https://github.com/isaac-mason/recast-navigation-js#advanced-usage) section for more information.
95
+ See the docs for more information on generator options: https://docs.recast-navigation-js.isaacmason.com/modules/generators.html
96
+
97
+ #### Advanced Usage
98
+
99
+ This library provides low-level APIs that aim to match the recast and detour c++ api, allowing you to create custom navigation mesh generators based on your specific needs. You can use the NavMesh generators provided by `@recast-navigation/generators` as a basis: https://github.com/isaac-mason/recast-navigation-js/tree/main/packages/recast-navigation-generators/src/generators
100
+
101
+ Please note that this functionality is experimental, and not all everything is exposed. Familiarity with the recast and detour C++ libraries is required. If you require unexposed functionality, please submit an issue or a pull request.
106
102
 
107
103
  ### Querying a NavMesh
108
104
 
@@ -128,7 +124,7 @@ const path: Vector3[] = navMeshQuery.computePath(
128
124
 
129
125
  ### Crowds and Agents
130
126
 
131
- First, create a `Crowd` instance.
127
+ First, create a `Crowd`:
132
128
 
133
129
  ```ts
134
130
  import { Crowd } from 'recast-navigation';
@@ -139,17 +135,7 @@ const maxAgentRadius = 0.6;
139
135
  const crowd = new Crowd({ maxAgents, maxAgentRadius, navMesh });
140
136
  ```
141
137
 
142
- To update the crowd, first set a timeStep, then call `update` each frame with the delta time.
143
-
144
- ```ts
145
- const dt = 1 / 60;
146
- crowd.timeStep = dt;
147
-
148
- // you should call this every frame
149
- crowd.update(dt);
150
- ```
151
-
152
- Next, you can create and interface with agents in the crowd.
138
+ Next, create and interface with agents in the crowd.
153
139
 
154
140
  ```ts
155
141
  const initialAgentPosition = navMeshQuery.getRandomPointAround(
@@ -202,16 +188,24 @@ agent.setParameters({
202
188
  crowd.removeAgent(agent);
203
189
  ```
204
190
 
205
- ### Temporary Obstacles
191
+ To update the crowd, first set a timeStep, then call `update` each frame with the delta time.
192
+
193
+ ```ts
194
+ const dt = 1 / 60;
195
+ crowd.timeStep = dt;
196
+
197
+ // you should call this every frame
198
+ crowd.update(dt);
199
+ ```
206
200
 
207
- Recast Navigation supports creating Box and Cylinder obstacles.
201
+ ### Temporary Obstacles
208
202
 
209
- Note that in order to use obstacles, you must create a TileCache.
203
+ Recast Navigation supports temporary Box and Cylinder obstacles via a `TileCache`.
210
204
 
211
205
  `TileCache` assumes small tiles (around 32-64 squared). Using `tileSize` values outside this range may result in unexpected behaviour.
212
206
 
213
207
  ```ts
214
- import { generateTileCache } from 'recast-navigation';
208
+ import { generateTileCache } from 'recast-navigation/generators';
215
209
 
216
210
  /* create a tile cache */
217
211
  const { success, navMesh, tileCache } = generateTileCache(positions, indices, {
@@ -249,7 +243,7 @@ Off mesh connections are user-defined connections between two points on a NavMes
249
243
 
250
244
  Off mesh connections can be bidirectional or unidirectional.
251
245
 
252
- You can provide list of off mesh connections to the high level generator functions.
246
+ You can provide a list of off mesh connections to the `generateSoloNavMesh` and `generateTiledNavMesh` high level generator functions.
253
247
 
254
248
  ```ts
255
249
  const { success, navMesh } = generateSoloNavMesh(positions, indices, {
@@ -270,6 +264,43 @@ const { success, navMesh } = generateSoloNavMesh(positions, indices, {
270
264
 
271
265
  You can use `agent.state()` to determine if an agent is currently traversing an off mesh connection.
272
266
 
267
+ #### Adding Off Mesh Connections to a TileCache
268
+
269
+ To add off mesh connections to a TileCache using `generateTileCache`, you must provide a TileCacheMeshProcess implementation that creates off mesh connections. For example:
270
+
271
+ ```ts
272
+ const tileCacheMeshProcess = new TileCacheMeshProcess(
273
+ (navMeshCreateParams, polyAreas, polyFlags) => {
274
+ for (let i = 0; i < navMeshCreateParams.polyCount(); ++i) {
275
+ polyAreas.set(i, 0);
276
+ polyFlags.set(i, 1);
277
+ }
278
+
279
+ navMeshCreateParams.setOffMeshConnections([
280
+ {
281
+ startPosition: { x: 0, y: 5, z: 0 },
282
+ endPosition: { x: 2, y: 0, z: 0 },
283
+ radius: 0.5,
284
+ bidirectional: false,
285
+ area: 0,
286
+ flags: 1,
287
+ },
288
+ ]);
289
+ }
290
+ );
291
+
292
+ const tileCacheGeneratorConfig = {
293
+ // ... other config ...
294
+ tileCacheMeshProcess,
295
+ };
296
+
297
+ const { success, navMesh, tileCache } = generateTileCache(
298
+ positions,
299
+ indices,
300
+ tileCacheGeneratorConfig
301
+ );
302
+ ```
303
+
273
304
  ### Debugging
274
305
 
275
306
  You can use `getDebugNavMesh` to get a debug representation of the NavMesh.
@@ -280,30 +311,45 @@ const debugNavMesh = navMesh.getDebugNavMesh();
280
311
  const { positions, indices } = debugNavMesh;
281
312
  ```
282
313
 
283
- If you are using `@recast-navigation/three`, you can use `NavMeshHelper` and `CrowdHelper` to visualize NavMeshes and Crowds.
314
+ If you are using three.js, you can use `NavMeshHelper` and `CrowdHelper` to visualize NavMeshes, Crowds, and NavMesh generation intermediates.
284
315
 
285
- ### Exporting and Importing
316
+ See the [`@recast-navigation/three` package README](https://github.com/isaac-mason/recast-navigation-js/tree/main/packages/recast-navigation-three/README.md) for usage information.
286
317
 
287
- A NavMesh and TileCache can be exported and imported as a Uint8Array.
318
+ ### Importing and Exporting
319
+
320
+ A NavMesh and TileCache can be imported and exported as a Uint8Array.
321
+
322
+ See below for an example of exporting then importing a NavMesh:
288
323
 
289
324
  ```ts
290
325
  import { exportNavMesh, importNavMesh } from 'recast-navigation';
291
326
 
292
- /* exporting */
293
- const navMeshExport: Uint8Array = exportNavMesh(
294
- navMesh,
295
- tileCache // optional
296
- );
327
+ /* export */
328
+ const navMeshExport: Uint8Array = exportNavMesh(navMesh);
297
329
 
298
- /* importing */
299
- const { navMesh, tileCache } = importNavMesh(navMeshExport);
330
+ /* import */
331
+ const { navMesh } = importNavMesh(navMeshExport);
300
332
  ```
301
333
 
302
- ### Advanced Usage
334
+ To export a TileCache and NavMesh, the usage varies slightly:
303
335
 
304
- This library provides low-level APIs that aim to match the recast and detour c++ api, allowing you to create custom navigation mesh generators based on your specific needs. See: https://github.com/isaac-mason/recast-navigation-js/tree/main/packages/recast-navigation-core/src/generators
336
+ ```ts
337
+ import { exportNavMesh, importNavMesh } from 'recast-navigation';
305
338
 
306
- Please note that this functionality is experimental, and not all everything is exposed. Familiarity with the recast and detour C++ libraries is required. If you require unexposed functionality, please submit an issue or a pull request.
339
+ /* exporting */
340
+ // pass both the navMesh and the tileCache
341
+ const navMeshExport: Uint8Array = exportNavMesh(navMesh, tileCache);
342
+
343
+ /* importing */
344
+ // also pass the TileCacheMeshProcess implementation for the tile cache
345
+ // if you used `generateTileCache` and didn't provide one, `createDefaultTileCacheMeshProcess` returns the default TileCacheMeshProcess `generateTileCache` uses
346
+ const tileCacheMeshProcess = createDefaultTileCacheMeshProcess();
347
+
348
+ const { navMesh, tileCache } = importNavMesh(
349
+ navMeshExport,
350
+ tileCacheMeshProcess
351
+ );
352
+ ```
307
353
 
308
354
  ## Documentation
309
355
 
@@ -355,6 +401,16 @@ The core library!
355
401
  > npm install @recast-navigation/core
356
402
  ```
357
403
 
404
+ ### [**`@recast-navigation/generators`**](https://github.com/isaac-mason/recast-navigation-js/tree/main/packages/recast-navigation-generators)
405
+
406
+ [![Version](https://img.shields.io/npm/v/@recast-navigation/generators)](https://www.npmjs.com/package/@recast-navigation/generators)
407
+
408
+ NavMesh generator implementations. Use these to get started, and as a basis for your own NavMesh generator.
409
+
410
+ ```bash
411
+ > npm install @recast-navigation/generators
412
+ ```
413
+
358
414
  ### [**`@recast-navigation/three`**](https://github.com/isaac-mason/recast-navigation-js/tree/main/packages/recast-navigation-three)
359
415
 
360
416
  [![Version](https://img.shields.io/npm/v/@recast-navigation/three)](https://www.npmjs.com/package/@recast-navigation/three)
package/generators.cjs ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";var e=require("@recast-navigation/core");const t=(t,i)=>{const a={x:1/0,y:1/0,z:1/0},l={x:-1/0,y:-1/0,z:-1/0};for(let e=0;e<i.length;e++){const r=i[e],s=t[3*r],o=t[3*r+1],n=t[3*r+2];a.x=Math.min(a.x,s),a.y=Math.min(a.y,o),a.z=Math.min(a.z,n),l.x=Math.max(l.x,s),l.y=Math.max(l.y,o),l.z=Math.max(l.z,n)}return{bbMin:e.vec3.toArray(a),bbMax:e.vec3.toArray(l)}},i=e=>{let t=0,i=0;return t=Number(e>65535)<<4,e>>=t,i=Number(e>255)<<3,e>>=i,t|=i,i=Number(e>15)<<2,e>>=i,t|=i,i=Number(e>3)<<1,t|=i,t|=(e>>=i)>>1,t},a=e=>(e--,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e),l={...e.recastConfigDefaults},r={...e.recastConfigDefaults,tileSize:32,expectedLayersPerTile:4,maxObstacles:128},s=()=>new e.TileCacheMeshProcess(((e,t,i)=>{for(let a=0;a<e.polyCount();++a)t.set(a,0),i.set(a,1)})),o={...e.recastConfigDefaults};exports.createDefaultTileCacheMeshProcess=s,exports.dtIlog2=i,exports.dtNextPow2=a,exports.generateSoloNavMesh=(i,a,r={},s=!1)=>{const o=new e.RecastBuildContext,n={type:"solo",buildContext:o},d=new e.NavMesh,h=t=>(s||(n.heightfield&&(e.freeHeightfield(n.heightfield),n.heightfield=void 0),n.compactHeightfield&&(e.freeCompactHeightfield(n.compactHeightfield),n.compactHeightfield=void 0),n.contourSet&&(e.freeContourSet(n.contourSet),n.contourSet=void 0)),d.destroy(),{navMesh:void 0,success:!1,intermediates:n,error:t}),c=i,g=a.length,f=new e.Arrays.FloatArray;f.copy(c,c.length);const m=a,u=a.length/3,b=new e.Arrays.IntArray;b.copy(m,m.length);const{bbMin:w,bbMax:C}=t(i,a),R=e.createRcConfig({...l,...r});R.minRegionArea=R.minRegionArea*R.minRegionArea,R.mergeRegionArea=R.mergeRegionArea*R.mergeRegionArea,R.detailSampleDist=R.detailSampleDist<.9?0:R.cs*R.detailSampleDist,R.detailSampleMaxError=R.ch*R.detailSampleMaxError;const S=e.Raw.Recast.calcGridSize(w,C,R.cs);R.width=S.width,R.height=S.height;const y=e.allocHeightfield();if(n.heightfield=y,!e.createHeightfield(o,y,R.width,R.height,w,C,R.cs,R.ch))return h("Could not create heightfield");const M=new e.Arrays.UnsignedCharArray;if(M.resize(u),e.markWalkableTriangles(o,R.walkableSlopeAngle,f,g,b,u,M),!e.rasterizeTriangles(o,f,g,b,M,u,y,R.walkableClimb))return h("Could not rasterize triangles");M.free(),e.filterLowHangingWalkableObstacles(o,R.walkableClimb,y),e.filterLedgeSpans(o,R.walkableHeight,R.walkableClimb,y),e.filterWalkableLowHeightSpans(o,R.walkableHeight,y);const p=e.allocCompactHeightfield();if(n.compactHeightfield=p,!e.buildCompactHeightfield(o,R.walkableHeight,R.walkableClimb,y,p))return h("Failed to build compact data");if(s||(e.freeHeightfield(y),n.heightfield=void 0),!e.erodeWalkableArea(o,R.walkableRadius,p))return h("Failed to erode walkable area");if(!e.buildDistanceField(o,p))return h("Failed to build distance field");if(!e.buildRegions(o,p,R.borderSize,R.minRegionArea,R.mergeRegionArea))return h("Failed to build regions");const x=e.allocContourSet();if(n.contourSet=x,!e.buildContours(o,p,R.maxSimplificationError,R.maxEdgeLen,x,e.Raw.Module.RC_CONTOUR_TESS_WALL_EDGES))return h("Failed to create contours");const A=e.allocPolyMesh();if(!e.buildPolyMesh(o,x,R.maxVertsPerPoly,A))return h("Failed to triangulate contours");const k=e.allocPolyMeshDetail();if(!e.buildPolyMeshDetail(o,A,p,R.detailSampleDist,R.detailSampleMaxError,k))return h("Failed to build detail mesh");s||(e.freeCompactHeightfield(p),n.compactHeightfield=void 0,e.freeContourSet(x),n.contourSet=void 0);for(let t=0;t<A.npolys();t++)A.areas(t)==e.Raw.Recast.WALKABLE_AREA&&A.setAreas(t,0),0==A.areas(t)&&A.setFlags(t,1);const H=new e.NavMeshCreateParams;H.setPolyMeshCreateParams(A),H.setPolyMeshDetailCreateParams(k),H.setWalkableHeight(R.walkableHeight),H.setWalkableRadius(R.walkableRadius),H.setWalkableClimb(R.walkableClimb),H.setCellSize(R.cs),H.setCellHeight(R.ch),H.setBuildBvTree(!0),r.offMeshConnections&&H.setOffMeshConnections(r.offMeshConnections);const v=e.createNavMeshData(H);if(!v.success)return h("Failed to create Detour navmesh data");const{navMeshData:T}=v;return d.initSolo(T)?{success:!0,navMesh:d,intermediates:n}:h("Failed to create Detour navmesh")},exports.generateTileCache=(l,o,n={},d=!1)=>{const h=new e.RecastBuildContext;let c={type:"tilecache",buildContext:h,chunkyTriMesh:void 0,tileIntermediates:[]};const g=new e.TileCache,f=new e.NavMesh,m=()=>{if(!d)for(let t=0;t<c.tileIntermediates.length;t++){const i=c.tileIntermediates[t];i.heightfield&&(e.freeHeightfield(i.heightfield),i.heightfield=void 0),i.compactHeightfield&&(e.freeCompactHeightfield(i.compactHeightfield),i.compactHeightfield=void 0),i.heightfieldLayerSet&&(e.freeHeightfieldLayerSet(i.heightfieldLayerSet),i.heightfieldLayerSet=void 0)}},u=e=>(m(),g.destroy(),f.destroy(),{success:!1,navMesh:void 0,tileCache:void 0,intermediates:c,error:e}),b=l,w=o.length,C=new e.Arrays.FloatArray;C.copy(b,b.length);const R=o,S=o.length/3,y=new e.Arrays.IntArray;y.copy(R,R.length);const{bbMin:M,bbMax:p}=t(l,o),{expectedLayersPerTile:x,maxObstacles:A,...k}={...r,...n},H=e.createRcConfig(k),v=e.calcGridSize(M,p,H.cs);H.width=v.width,H.height=v.height,H.minRegionArea=H.minRegionArea*H.minRegionArea,H.mergeRegionArea=H.mergeRegionArea*H.mergeRegionArea,H.detailSampleDist=H.detailSampleDist<.9?0:H.cs*H.detailSampleDist,H.detailSampleMaxError=H.ch*H.detailSampleMaxError;const T=Math.floor(H.tileSize),z=Math.floor((H.width+T-1)/T),_=Math.floor((H.height+T-1)/T);H.borderSize=H.walkableRadius+3,H.width=H.tileSize+2*H.borderSize,H.height=H.tileSize+2*H.borderSize;const L=e.DetourTileCacheParams.create({orig:M,cs:H.cs,ch:H.ch,width:H.tileSize,height:H.tileSize,walkableHeight:H.walkableHeight,walkableRadius:H.walkableRadius,walkableClimb:H.walkableClimb,maxSimplificationError:H.maxSimplificationError,maxTiles:z*_*x,maxObstacles:A}),D=new e.Raw.RecastLinearAllocator(32e3),E=new e.Raw.RecastFastLZCompressor,P=n.tileCacheMeshProcess??s();if(!g.init(L,D,E,P))return u("Failed to initialize tile cache");const F=e.vec3.fromArray(M);let N=Math.min(Math.floor(i(a(z*_*x))),14);N>14&&(N=14);const O=1<<N,W=1<<22-N,I=e.NavMeshParams.create({orig:F,tileWidth:H.tileSize*H.cs,tileHeight:H.tileSize*H.cs,maxTiles:O,maxPolys:W});if(!f.initTiled(I))return u("Failed to initialize tiled navmesh");const G=new e.RecastChunkyTriMesh;if(c.chunkyTriMesh=G,!G.init(C,y,S,256))return u("Failed to build chunky triangle mesh");const $=(t,i)=>{const a={tileX:t,tileY:i},l=H.tileSize*H.cs,r=e.cloneRcConfig(H),s=[M[0]+t*l,M[1],M[2]+i*l],o=[M[0]+(t+1)*l,p[1],M[2]+(i+1)*l];s[0]-=r.borderSize*r.cs,s[2]-=r.borderSize*r.cs,o[0]+=r.borderSize*r.cs,o[2]+=r.borderSize*r.cs,r.set_bmin(0,s[0]),r.set_bmin(1,s[1]),r.set_bmin(2,s[2]),r.set_bmax(0,o[0]),r.set_bmax(1,o[1]),r.set_bmax(2,o[2]);const n=e.allocHeightfield();if(a.heightfield=n,!e.createHeightfield(h,n,r.width,r.height,s,o,r.cs,r.ch))return{n:0};const g=[s[0],s[2]],f=[o[0],o[2]],m=new e.Arrays.IntArray;m.resize(512);const u=G.getChunksOverlappingRect(g,f,m,512);if(0===u)return{n:0};for(let t=0;t<u;++t){const i=m.get_data(t),a=G.nodes(i).n,l=G.getNodeTris(i),s=new e.Arrays.UnsignedCharArray;s.resize(a),e.markWalkableTriangles(h,r.walkableSlopeAngle,C,w,l,a,s);const o=e.rasterizeTriangles(h,C,w,l,s,a,n,r.walkableClimb);if(s.free(),!o)return{n:0}}e.filterLowHangingWalkableObstacles(h,H.walkableClimb,n),e.filterLedgeSpans(h,H.walkableHeight,H.walkableClimb,n),e.filterWalkableLowHeightSpans(h,H.walkableHeight,n);const b=e.allocCompactHeightfield();if(!e.buildCompactHeightfield(h,H.walkableHeight,H.walkableClimb,n,b))return{n:0};if(d||(e.freeHeightfield(a.heightfield),a.heightfield=void 0),!e.erodeWalkableArea(h,H.walkableRadius,b))return{n:0};const R=e.allocHeightfieldLayerSet();if(!e.buildHeightfieldLayers(h,b,H.borderSize,H.walkableHeight,R))return{n:0};d||(e.freeCompactHeightfield(b),a.compactHeightfield=void 0);const S=[];for(let a=0;a<R.nlayers();a++){const l=new e.Arrays.UnsignedCharArray,r=R.layers(a),s=new e.Raw.dtTileCacheLayerHeader;s.magic=e.Raw.Detour.TILECACHE_MAGIC,s.version=e.Raw.Detour.TILECACHE_VERSION,s.tx=t,s.ty=i,s.tlayer=a;const o=r.bmin(),n=r.bmax();s.set_bmin(0,o.x),s.set_bmin(1,o.y),s.set_bmin(2,o.z),s.set_bmax(0,n.x),s.set_bmax(1,n.y),s.set_bmax(2,n.z),s.width=r.width(),s.height=r.height(),s.minx=r.minx(),s.maxx=r.maxx(),s.miny=r.miny(),s.maxy=r.maxy(),s.hmin=r.hmin(),s.hmax=r.hmax();const d=e.getHeightfieldLayerHeights(r),h=e.getHeightfieldLayerAreas(r),c=e.getHeightfieldLayerCons(r),g=e.buildTileCacheLayer(E,s,d,h,c,l);if(e.Raw.Detour.statusFailed(g))return{n:0};S.push(l)}return d||(e.freeHeightfieldLayerSet(R),a.heightfieldLayerSet=void 0),c.tileIntermediates.push(a),{n:S.length,tiles:S}};for(let t=0;t<_;++t)for(let i=0;i<z;++i){const{n:a,tiles:l}=$(i,t);if(a>0&&l)for(let r=0;r<a;r++){const a=l[r],s=g.addTile(a);e.Raw.Detour.statusFailed(s.status)&&h.log(e.Raw.Module.RC_LOG_WARNING,`Failed to add tile to tile cache - tx: ${i}, ty: ${t}`)}}for(let t=0;t<_;t++)for(let i=0;i<z;i++){const a=g.buildNavMeshTilesAt(i,t,f);if(e.Raw.Detour.statusFailed(a))return u(`Failed to build nav mesh tiles at ${i}, ${t}`)}return m(),{success:!0,tileCache:g,navMesh:f,intermediates:c}},exports.generateTiledNavMesh=(l,r,s={},n=!1)=>{const d=new e.RecastBuildContext,h={type:"tiled",buildContext:d,chunkyTriMesh:void 0,tileIntermediates:[]},c=new e.NavMesh,g=()=>{if(!n){for(let t=0;t<h.tileIntermediates.length;t++){const i=h.tileIntermediates[t];i.compactHeightfield&&e.freeCompactHeightfield(i.compactHeightfield),i.heightfield&&e.freeHeightfield(i.heightfield),i.contourSet&&e.freeContourSet(i.contourSet)}h.chunkyTriMesh&&(h.chunkyTriMesh=void 0)}},f=e=>(g(),c.destroy(),{success:!1,navMesh:void 0,intermediates:h,error:e}),m=e.createRcConfig({...o,...s}),{bbMin:u,bbMax:b}=t(l,r),w=e.calcGridSize(u,b,m.cs);m.width=w.width,m.height=w.height,m.minRegionArea=m.minRegionArea*m.minRegionArea,m.mergeRegionArea=m.mergeRegionArea*m.mergeRegionArea,m.tileSize=Math.floor(m.tileSize),m.borderSize=m.walkableRadius+3,m.width=m.tileSize+2*m.borderSize,m.height=m.tileSize+2*m.borderSize,m.detailSampleDist=m.detailSampleDist<.9?0:m.cs*m.detailSampleDist,m.detailSampleMaxError=m.ch*m.detailSampleMaxError;const C=Math.floor(m.tileSize),R=Math.floor((w.width+C-1)/C),S=Math.floor((w.height+C-1)/C),y=m.tileSize*m.cs,M=l,p=r.length,x=new e.Arrays.FloatArray;x.copy(M,M.length);const A=r,k=r.length/3,H=new e.Arrays.IntArray;H.copy(A,A.length);const v=e.vec3.fromArray(u);let T=Math.min(Math.floor(i(a(R*S))),14);T>14&&(T=14);const z=1<<T,_=1<<22-T,L=e.NavMeshParams.create({orig:v,tileWidth:m.tileSize*m.cs,tileHeight:m.tileSize*m.cs,maxTiles:z,maxPolys:_});if(!c.initTiled(L))return f("Could not init nav mesh for tiled use");const D=new e.RecastChunkyTriMesh;if(h.chunkyTriMesh=D,!D.init(x,H,k,256))return f("Failed to build chunky triangle mesh");const E=(t,i,a,l)=>{const r=t=>(d.log(e.Raw.Module.RC_LOG_ERROR,t),{success:!1,error:t}),o={tileX:t,tileY:i};h.tileIntermediates.push(o);const c=e.cloneRcConfig(m),g=[...a],f=[...l];g[0]-=c.borderSize*c.cs,g[2]-=c.borderSize*c.cs,f[0]+=c.borderSize*c.cs,f[2]+=c.borderSize*c.cs,c.set_bmin(0,g[0]),c.set_bmin(1,g[1]),c.set_bmin(2,g[2]),c.set_bmax(0,f[0]),c.set_bmax(1,f[1]),c.set_bmax(2,f[2]),d.resetTimers(),d.startTimer(e.Raw.Module.RC_TIMER_TOTAL),d.log(e.Raw.Module.RC_LOG_PROGRESS,`Building tile ${h.tileIntermediates.length} at x: ${t}, y: ${i}`),d.log(e.Raw.Module.RC_LOG_PROGRESS,` - ${m.width} x ${m.height} cells`),d.log(e.Raw.Module.RC_LOG_PROGRESS,` - ${p/1e3}fK verts, ${k/1e3}K tris`);const u=e.allocHeightfield();if(o.heightfield=u,!e.createHeightfield(d,u,c.width,c.height,g,f,c.cs,c.ch))return r("Could not create heightfield");(new e.Arrays.UnsignedCharArray).resize(D.maxTrisPerChunk());const b=[g[0],g[2]],w=[f[0],f[2]],C=new e.Arrays.IntArray;C.resize(512);const R=D.getChunksOverlappingRect(b,w,C,512);if(0===R)return{success:!0};for(let t=0;t<R;++t){const i=C.get_data(t),a=D.nodes(i).n,l=D.getNodeTris(i),s=new e.Arrays.UnsignedCharArray;s.resize(a),e.markWalkableTriangles(d,c.walkableSlopeAngle,x,p,l,a,s);const o=e.rasterizeTriangles(d,x,p,l,s,a,u,c.walkableClimb);if(s.free(),!o)return r("Could not rasterize triangles")}e.filterLowHangingWalkableObstacles(d,c.walkableClimb,u),e.filterLedgeSpans(d,c.walkableHeight,c.walkableClimb,u),e.filterWalkableLowHeightSpans(d,c.walkableHeight,u);const S=e.allocCompactHeightfield();if(o.compactHeightfield=S,!e.buildCompactHeightfield(d,c.walkableHeight,c.walkableClimb,u,S))return r("Could not build compact heightfield");if(n||(e.freeHeightfield(o.heightfield),o.heightfield=void 0),!e.erodeWalkableArea(d,c.walkableRadius,S))return r("Could not erode walkable area");if(!e.buildDistanceField(d,S))return r("Failed to build distance field");if(!e.buildRegions(d,S,c.borderSize,c.minRegionArea,c.mergeRegionArea))return r("Failed to build regions");const y=e.allocContourSet();if(o.contourSet=y,!e.buildContours(d,S,c.maxSimplificationError,c.maxEdgeLen,y,e.Raw.Module.RC_CONTOUR_TESS_WALL_EDGES))return r("Failed to create contours");const M=e.allocPolyMesh();if(!e.buildPolyMesh(d,y,c.maxVertsPerPoly,M))return r("Failed to triangulate contours");const A=e.allocPolyMeshDetail();if(!e.buildPolyMeshDetail(d,M,S,c.detailSampleDist,c.detailSampleMaxError,A))return r("Failed to build detail mesh");n||(e.freeCompactHeightfield(S),o.compactHeightfield=void 0,e.freeContourSet(y),o.contourSet=void 0);for(let t=0;t<M.npolys();t++)M.areas(t)==e.Raw.Recast.WALKABLE_AREA&&M.setAreas(t,0),0==M.areas(t)&&M.setFlags(t,1);const H=new e.NavMeshCreateParams;H.setPolyMeshCreateParams(M),H.setPolyMeshDetailCreateParams(A),H.setWalkableHeight(c.walkableHeight),H.setWalkableRadius(c.walkableRadius),H.setWalkableClimb(c.walkableClimb),H.setCellSize(c.cs),H.setCellHeight(c.ch),H.setBuildBvTree(!0),s.offMeshConnections&&H.setOffMeshConnections(s.offMeshConnections),H.setTileX(t),H.setTileY(i);const v=e.createNavMeshData(H);return v.success?(d.log(e.Raw.Module.RC_LOG_PROGRESS,`>> Polymesh: ${M.nverts()} vertices ${M.npolys()} polygons`),{success:!0,data:v.navMeshData}):r("Failed to create Detour navmesh data")};d.startTimer(e.Raw.Module.RC_TIMER_TEMP);let P=[0,0,0],F=[0,0,0];for(let t=0;t<S;t++)for(let i=0;i<R;i++){P[0]=u[0]+i*y,P[1]=u[1],P[2]=u[2]+t*y,F[0]=u[0]+(i+1)*y,F[1]=b[1],F[2]=u[2]+(t+1)*y;const a=E(i,t,P,F);if(a.success&&a.data){c.removeTile(c.getTileRefAt(i,t,0));const l=c.addTile(a.data,e.Raw.Module.DT_TILE_FREE_DATA,0);e.Raw.Detour.statusFailed(l.status)&&(d.log(e.Raw.Module.RC_LOG_WARNING,`Failed to add tile to nav mesh\n\ttx: ${i}, ty: ${t},status: ${e.dtStatusToReadableString(l.status)} (${l.status})`),a.data.free())}}return d.stopTimer(e.Raw.Module.RC_TIMER_TEMP),n||g(),{success:!0,navMesh:c,intermediates:h}},exports.getBoundingBox=t,exports.soloNavMeshGeneratorConfigDefaults=l,exports.tileCacheGeneratorConfigDefaults=r,exports.tiledNavMeshGeneratorConfigDefaults=o;
2
+ //# sourceMappingURL=generators.cjs.map
@@ -0,0 +1 @@
1
+ export * from '@recast-navigation/generators';
package/generators.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import{recastConfigDefaults as e,vec3 as t,RecastBuildContext as i,NavMesh as a,Arrays as l,createRcConfig as r,Raw as s,allocHeightfield as o,createHeightfield as n,markWalkableTriangles as d,rasterizeTriangles as h,filterLowHangingWalkableObstacles as c,filterLedgeSpans as m,filterWalkableLowHeightSpans as g,allocCompactHeightfield as u,buildCompactHeightfield as b,freeHeightfield as f,erodeWalkableArea as S,buildDistanceField as w,buildRegions as M,allocContourSet as C,buildContours as y,allocPolyMesh as R,buildPolyMesh as x,allocPolyMeshDetail as p,buildPolyMeshDetail as A,freeCompactHeightfield as k,freeContourSet as z,NavMeshCreateParams as _,createNavMeshData as v,TileCacheMeshProcess as T,TileCache as E,calcGridSize as H,DetourTileCacheParams as F,NavMeshParams as D,RecastChunkyTriMesh as L,dtStatusToReadableString as P,freeHeightfieldLayerSet as I,cloneRcConfig as O,allocHeightfieldLayerSet as G,buildHeightfieldLayers as N,getHeightfieldLayerHeights as $,getHeightfieldLayerAreas as W,getHeightfieldLayerCons as B,buildTileCacheLayer as U}from"@recast-navigation/core";const K=(e,i)=>{const a={x:1/0,y:1/0,z:1/0},l={x:-1/0,y:-1/0,z:-1/0};for(let t=0;t<i.length;t++){const r=i[t],s=e[3*r],o=e[3*r+1],n=e[3*r+2];a.x=Math.min(a.x,s),a.y=Math.min(a.y,o),a.z=Math.min(a.z,n),l.x=Math.max(l.x,s),l.y=Math.max(l.y,o),l.z=Math.max(l.z,n)}return{bbMin:t.toArray(a),bbMax:t.toArray(l)}},V=e=>{let t=0,i=0;return t=Number(e>65535)<<4,e>>=t,i=Number(e>255)<<3,e>>=i,t|=i,i=Number(e>15)<<2,e>>=i,t|=i,i=Number(e>3)<<1,t|=i,t|=(e>>=i)>>1,t},X=e=>(e--,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e),Y={...e},Z=(e,t,T={},E=!1)=>{const H=new i,F={type:"solo",buildContext:H},D=new a,L=e=>(E||(F.heightfield&&(f(F.heightfield),F.heightfield=void 0),F.compactHeightfield&&(k(F.compactHeightfield),F.compactHeightfield=void 0),F.contourSet&&(z(F.contourSet),F.contourSet=void 0)),D.destroy(),{navMesh:void 0,success:!1,intermediates:F,error:e}),P=e,I=t.length,O=new l.FloatArray;O.copy(P,P.length);const G=t,N=t.length/3,$=new l.IntArray;$.copy(G,G.length);const{bbMin:W,bbMax:B}=K(e,t),U=r({...Y,...T});U.minRegionArea=U.minRegionArea*U.minRegionArea,U.mergeRegionArea=U.mergeRegionArea*U.mergeRegionArea,U.detailSampleDist=U.detailSampleDist<.9?0:U.cs*U.detailSampleDist,U.detailSampleMaxError=U.ch*U.detailSampleMaxError;const V=s.Recast.calcGridSize(W,B,U.cs);U.width=V.width,U.height=V.height;const X=o();if(F.heightfield=X,!n(H,X,U.width,U.height,W,B,U.cs,U.ch))return L("Could not create heightfield");const Z=new l.UnsignedCharArray;if(Z.resize(N),d(H,U.walkableSlopeAngle,O,I,$,N,Z),!h(H,O,I,$,Z,N,X,U.walkableClimb))return L("Could not rasterize triangles");Z.free(),c(H,U.walkableClimb,X),m(H,U.walkableHeight,U.walkableClimb,X),g(H,U.walkableHeight,X);const j=u();if(F.compactHeightfield=j,!b(H,U.walkableHeight,U.walkableClimb,X,j))return L("Failed to build compact data");if(E||(f(X),F.heightfield=void 0),!S(H,U.walkableRadius,j))return L("Failed to erode walkable area");if(!w(H,j))return L("Failed to build distance field");if(!M(H,j,U.borderSize,U.minRegionArea,U.mergeRegionArea))return L("Failed to build regions");const q=C();if(F.contourSet=q,!y(H,j,U.maxSimplificationError,U.maxEdgeLen,q,s.Module.RC_CONTOUR_TESS_WALL_EDGES))return L("Failed to create contours");const J=R();if(!x(H,q,U.maxVertsPerPoly,J))return L("Failed to triangulate contours");const Q=p();if(!A(H,J,j,U.detailSampleDist,U.detailSampleMaxError,Q))return L("Failed to build detail mesh");E||(k(j),F.compactHeightfield=void 0,z(q),F.contourSet=void 0);for(let e=0;e<J.npolys();e++)J.areas(e)==s.Recast.WALKABLE_AREA&&J.setAreas(e,0),0==J.areas(e)&&J.setFlags(e,1);const ee=new _;ee.setPolyMeshCreateParams(J),ee.setPolyMeshDetailCreateParams(Q),ee.setWalkableHeight(U.walkableHeight),ee.setWalkableRadius(U.walkableRadius),ee.setWalkableClimb(U.walkableClimb),ee.setCellSize(U.cs),ee.setCellHeight(U.ch),ee.setBuildBvTree(!0),T.offMeshConnections&&ee.setOffMeshConnections(T.offMeshConnections);const te=v(ee);if(!te.success)return L("Failed to create Detour navmesh data");const{navMeshData:ie}=te;return D.initSolo(ie)?{success:!0,navMesh:D,intermediates:F}:L("Failed to create Detour navmesh")},j={...e,tileSize:32,expectedLayersPerTile:4,maxObstacles:128},q=()=>new T(((e,t,i)=>{for(let a=0;a<e.polyCount();++a)t.set(a,0),i.set(a,1)})),J=(e,w,M={},C=!1)=>{const y=new i;let R={type:"tilecache",buildContext:y,chunkyTriMesh:void 0,tileIntermediates:[]};const x=new E,p=new a,A=()=>{if(!C)for(let e=0;e<R.tileIntermediates.length;e++){const t=R.tileIntermediates[e];t.heightfield&&(f(t.heightfield),t.heightfield=void 0),t.compactHeightfield&&(k(t.compactHeightfield),t.compactHeightfield=void 0),t.heightfieldLayerSet&&(I(t.heightfieldLayerSet),t.heightfieldLayerSet=void 0)}},z=e=>(A(),x.destroy(),p.destroy(),{success:!1,navMesh:void 0,tileCache:void 0,intermediates:R,error:e}),_=e,v=w.length,T=new l.FloatArray;T.copy(_,_.length);const P=w,Y=w.length/3,Z=new l.IntArray;Z.copy(P,P.length);const{bbMin:J,bbMax:Q}=K(e,w),{expectedLayersPerTile:ee,maxObstacles:te,...ie}={...j,...M},ae=r(ie),le=H(J,Q,ae.cs);ae.width=le.width,ae.height=le.height,ae.minRegionArea=ae.minRegionArea*ae.minRegionArea,ae.mergeRegionArea=ae.mergeRegionArea*ae.mergeRegionArea,ae.detailSampleDist=ae.detailSampleDist<.9?0:ae.cs*ae.detailSampleDist,ae.detailSampleMaxError=ae.ch*ae.detailSampleMaxError;const re=Math.floor(ae.tileSize),se=Math.floor((ae.width+re-1)/re),oe=Math.floor((ae.height+re-1)/re);ae.borderSize=ae.walkableRadius+3,ae.width=ae.tileSize+2*ae.borderSize,ae.height=ae.tileSize+2*ae.borderSize;const ne=F.create({orig:J,cs:ae.cs,ch:ae.ch,width:ae.tileSize,height:ae.tileSize,walkableHeight:ae.walkableHeight,walkableRadius:ae.walkableRadius,walkableClimb:ae.walkableClimb,maxSimplificationError:ae.maxSimplificationError,maxTiles:se*oe*ee,maxObstacles:te}),de=new s.RecastLinearAllocator(32e3),he=new s.RecastFastLZCompressor,ce=M.tileCacheMeshProcess??q();if(!x.init(ne,de,he,ce))return z("Failed to initialize tile cache");const me=t.fromArray(J);let ge=Math.min(Math.floor(V(X(se*oe*ee))),14);ge>14&&(ge=14);const ue=1<<ge,be=1<<22-ge,fe=D.create({orig:me,tileWidth:ae.tileSize*ae.cs,tileHeight:ae.tileSize*ae.cs,maxTiles:ue,maxPolys:be});if(!p.initTiled(fe))return z("Failed to initialize tiled navmesh");const Se=new L;if(R.chunkyTriMesh=Se,!Se.init(T,Z,Y,256))return z("Failed to build chunky triangle mesh");const we=(e,t)=>{const i={tileX:e,tileY:t},a=ae.tileSize*ae.cs,r=O(ae),w=[J[0]+e*a,J[1],J[2]+t*a],M=[J[0]+(e+1)*a,Q[1],J[2]+(t+1)*a];w[0]-=r.borderSize*r.cs,w[2]-=r.borderSize*r.cs,M[0]+=r.borderSize*r.cs,M[2]+=r.borderSize*r.cs,r.set_bmin(0,w[0]),r.set_bmin(1,w[1]),r.set_bmin(2,w[2]),r.set_bmax(0,M[0]),r.set_bmax(1,M[1]),r.set_bmax(2,M[2]);const x=o();if(i.heightfield=x,!n(y,x,r.width,r.height,w,M,r.cs,r.ch))return{n:0};const p=[w[0],w[2]],A=[M[0],M[2]],z=new l.IntArray;z.resize(512);const _=Se.getChunksOverlappingRect(p,A,z,512);if(0===_)return{n:0};for(let e=0;e<_;++e){const t=z.get_data(e),i=Se.nodes(t).n,a=Se.getNodeTris(t),s=new l.UnsignedCharArray;s.resize(i),d(y,r.walkableSlopeAngle,T,v,a,i,s);const o=h(y,T,v,a,s,i,x,r.walkableClimb);if(s.free(),!o)return{n:0}}c(y,ae.walkableClimb,x),m(y,ae.walkableHeight,ae.walkableClimb,x),g(y,ae.walkableHeight,x);const E=u();if(!b(y,ae.walkableHeight,ae.walkableClimb,x,E))return{n:0};if(C||(f(i.heightfield),i.heightfield=void 0),!S(y,ae.walkableRadius,E))return{n:0};const H=G();if(!N(y,E,ae.borderSize,ae.walkableHeight,H))return{n:0};C||(k(E),i.compactHeightfield=void 0);const F=[];for(let i=0;i<H.nlayers();i++){const a=new l.UnsignedCharArray,r=H.layers(i),o=new s.dtTileCacheLayerHeader;o.magic=s.Detour.TILECACHE_MAGIC,o.version=s.Detour.TILECACHE_VERSION,o.tx=e,o.ty=t,o.tlayer=i;const n=r.bmin(),d=r.bmax();o.set_bmin(0,n.x),o.set_bmin(1,n.y),o.set_bmin(2,n.z),o.set_bmax(0,d.x),o.set_bmax(1,d.y),o.set_bmax(2,d.z),o.width=r.width(),o.height=r.height(),o.minx=r.minx(),o.maxx=r.maxx(),o.miny=r.miny(),o.maxy=r.maxy(),o.hmin=r.hmin(),o.hmax=r.hmax();const h=$(r),c=W(r),m=B(r),g=U(he,o,h,c,m,a);if(s.Detour.statusFailed(g))return{n:0};F.push(a)}return C||(I(H),i.heightfieldLayerSet=void 0),R.tileIntermediates.push(i),{n:F.length,tiles:F}};for(let e=0;e<oe;++e)for(let t=0;t<se;++t){const{n:i,tiles:a}=we(t,e);if(i>0&&a)for(let l=0;l<i;l++){const i=a[l],r=x.addTile(i);s.Detour.statusFailed(r.status)&&y.log(s.Module.RC_LOG_WARNING,`Failed to add tile to tile cache - tx: ${t}, ty: ${e}`)}}for(let e=0;e<oe;e++)for(let t=0;t<se;t++){const i=x.buildNavMeshTilesAt(t,e,p);if(s.Detour.statusFailed(i))return z(`Failed to build nav mesh tiles at ${t}, ${e}`)}return A(),{success:!0,tileCache:x,navMesh:p,intermediates:R}},Q={...e},ee=(e,T,E={},F=!1)=>{const I=new i,G={type:"tiled",buildContext:I,chunkyTriMesh:void 0,tileIntermediates:[]},N=new a,$=()=>{if(!F){for(let e=0;e<G.tileIntermediates.length;e++){const t=G.tileIntermediates[e];t.compactHeightfield&&k(t.compactHeightfield),t.heightfield&&f(t.heightfield),t.contourSet&&z(t.contourSet)}G.chunkyTriMesh&&(G.chunkyTriMesh=void 0)}},W=e=>($(),N.destroy(),{success:!1,navMesh:void 0,intermediates:G,error:e}),B=r({...Q,...E}),{bbMin:U,bbMax:Y}=K(e,T),Z=H(U,Y,B.cs);B.width=Z.width,B.height=Z.height,B.minRegionArea=B.minRegionArea*B.minRegionArea,B.mergeRegionArea=B.mergeRegionArea*B.mergeRegionArea,B.tileSize=Math.floor(B.tileSize),B.borderSize=B.walkableRadius+3,B.width=B.tileSize+2*B.borderSize,B.height=B.tileSize+2*B.borderSize,B.detailSampleDist=B.detailSampleDist<.9?0:B.cs*B.detailSampleDist,B.detailSampleMaxError=B.ch*B.detailSampleMaxError;const j=Math.floor(B.tileSize),q=Math.floor((Z.width+j-1)/j),J=Math.floor((Z.height+j-1)/j),ee=B.tileSize*B.cs,te=e,ie=T.length,ae=new l.FloatArray;ae.copy(te,te.length);const le=T,re=T.length/3,se=new l.IntArray;se.copy(le,le.length);const oe=t.fromArray(U);let ne=Math.min(Math.floor(V(X(q*J))),14);ne>14&&(ne=14);const de=1<<ne,he=1<<22-ne,ce=D.create({orig:oe,tileWidth:B.tileSize*B.cs,tileHeight:B.tileSize*B.cs,maxTiles:de,maxPolys:he});if(!N.initTiled(ce))return W("Could not init nav mesh for tiled use");const me=new L;if(G.chunkyTriMesh=me,!me.init(ae,se,re,256))return W("Failed to build chunky triangle mesh");const ge=(e,t,i,a)=>{const r=e=>(I.log(s.Module.RC_LOG_ERROR,e),{success:!1,error:e}),T={tileX:e,tileY:t};G.tileIntermediates.push(T);const H=O(B),D=[...i],L=[...a];D[0]-=H.borderSize*H.cs,D[2]-=H.borderSize*H.cs,L[0]+=H.borderSize*H.cs,L[2]+=H.borderSize*H.cs,H.set_bmin(0,D[0]),H.set_bmin(1,D[1]),H.set_bmin(2,D[2]),H.set_bmax(0,L[0]),H.set_bmax(1,L[1]),H.set_bmax(2,L[2]),I.resetTimers(),I.startTimer(s.Module.RC_TIMER_TOTAL),I.log(s.Module.RC_LOG_PROGRESS,`Building tile ${G.tileIntermediates.length} at x: ${e}, y: ${t}`),I.log(s.Module.RC_LOG_PROGRESS,` - ${B.width} x ${B.height} cells`),I.log(s.Module.RC_LOG_PROGRESS,` - ${ie/1e3}fK verts, ${re/1e3}K tris`);const P=o();if(T.heightfield=P,!n(I,P,H.width,H.height,D,L,H.cs,H.ch))return r("Could not create heightfield");(new l.UnsignedCharArray).resize(me.maxTrisPerChunk());const N=[D[0],D[2]],$=[L[0],L[2]],W=new l.IntArray;W.resize(512);const U=me.getChunksOverlappingRect(N,$,W,512);if(0===U)return{success:!0};for(let e=0;e<U;++e){const t=W.get_data(e),i=me.nodes(t).n,a=me.getNodeTris(t),s=new l.UnsignedCharArray;s.resize(i),d(I,H.walkableSlopeAngle,ae,ie,a,i,s);const o=h(I,ae,ie,a,s,i,P,H.walkableClimb);if(s.free(),!o)return r("Could not rasterize triangles")}c(I,H.walkableClimb,P),m(I,H.walkableHeight,H.walkableClimb,P),g(I,H.walkableHeight,P);const K=u();if(T.compactHeightfield=K,!b(I,H.walkableHeight,H.walkableClimb,P,K))return r("Could not build compact heightfield");if(F||(f(T.heightfield),T.heightfield=void 0),!S(I,H.walkableRadius,K))return r("Could not erode walkable area");if(!w(I,K))return r("Failed to build distance field");if(!M(I,K,H.borderSize,H.minRegionArea,H.mergeRegionArea))return r("Failed to build regions");const V=C();if(T.contourSet=V,!y(I,K,H.maxSimplificationError,H.maxEdgeLen,V,s.Module.RC_CONTOUR_TESS_WALL_EDGES))return r("Failed to create contours");const X=R();if(!x(I,V,H.maxVertsPerPoly,X))return r("Failed to triangulate contours");const Y=p();if(!A(I,X,K,H.detailSampleDist,H.detailSampleMaxError,Y))return r("Failed to build detail mesh");F||(k(K),T.compactHeightfield=void 0,z(V),T.contourSet=void 0);for(let e=0;e<X.npolys();e++)X.areas(e)==s.Recast.WALKABLE_AREA&&X.setAreas(e,0),0==X.areas(e)&&X.setFlags(e,1);const Z=new _;Z.setPolyMeshCreateParams(X),Z.setPolyMeshDetailCreateParams(Y),Z.setWalkableHeight(H.walkableHeight),Z.setWalkableRadius(H.walkableRadius),Z.setWalkableClimb(H.walkableClimb),Z.setCellSize(H.cs),Z.setCellHeight(H.ch),Z.setBuildBvTree(!0),E.offMeshConnections&&Z.setOffMeshConnections(E.offMeshConnections),Z.setTileX(e),Z.setTileY(t);const j=v(Z);return j.success?(I.log(s.Module.RC_LOG_PROGRESS,`>> Polymesh: ${X.nverts()} vertices ${X.npolys()} polygons`),{success:!0,data:j.navMeshData}):r("Failed to create Detour navmesh data")};I.startTimer(s.Module.RC_TIMER_TEMP);let ue=[0,0,0],be=[0,0,0];for(let e=0;e<J;e++)for(let t=0;t<q;t++){ue[0]=U[0]+t*ee,ue[1]=U[1],ue[2]=U[2]+e*ee,be[0]=U[0]+(t+1)*ee,be[1]=Y[1],be[2]=U[2]+(e+1)*ee;const i=ge(t,e,ue,be);if(i.success&&i.data){N.removeTile(N.getTileRefAt(t,e,0));const a=N.addTile(i.data,s.Module.DT_TILE_FREE_DATA,0);s.Detour.statusFailed(a.status)&&(I.log(s.Module.RC_LOG_WARNING,`Failed to add tile to nav mesh\n\ttx: ${t}, ty: ${e},status: ${P(a.status)} (${a.status})`),i.data.free())}}return I.stopTimer(s.Module.RC_TIMER_TEMP),F||$(),{success:!0,navMesh:N,intermediates:G}};export{q as createDefaultTileCacheMeshProcess,V as dtIlog2,X as dtNextPow2,Z as generateSoloNavMesh,J as generateTileCache,ee as generateTiledNavMesh,K as getBoundingBox,Y as soloNavMeshGeneratorConfigDefaults,j as tileCacheGeneratorConfigDefaults,Q as tiledNavMeshGeneratorConfigDefaults};
2
+ //# sourceMappingURL=generators.mjs.map
package/package.json CHANGED
@@ -18,7 +18,7 @@
18
18
  "email": "isaac@isaacmason.com",
19
19
  "url": "https://isaacmason.com/"
20
20
  },
21
- "version": "0.13.3",
21
+ "version": "0.15.0",
22
22
  "license": "MIT",
23
23
  "homepage": "https://github.com/isaac-mason/recast-navigation-js",
24
24
  "bugs": {
@@ -33,6 +33,11 @@
33
33
  "import": "./index.mjs",
34
34
  "require": "./index.cjs"
35
35
  },
36
+ "./generators": {
37
+ "types": "./generators.d.ts",
38
+ "import": "./generators.mjs",
39
+ "require": "./generators.cjs"
40
+ },
36
41
  "./three": {
37
42
  "types": "./three.d.ts",
38
43
  "import": "./three.mjs",
@@ -43,6 +48,9 @@
43
48
  "index.mjs",
44
49
  "index.cjs",
45
50
  "index.d.ts",
51
+ "generators.mjs",
52
+ "generators.cjs",
53
+ "generators.d.ts",
46
54
  "three.mjs",
47
55
  "three.cjs",
48
56
  "three.d.ts",
@@ -50,14 +58,16 @@
50
58
  "README.md"
51
59
  ],
52
60
  "scripts": {
53
- "clean": "(rm index.mjs index.cjs index.d.ts three.mjs three.cjs three.d.ts || true)",
61
+ "clean": "(rm index.mjs index.cjs index.d.ts generators.mjs generators.cjs generators.d.ts three.mjs three.cjs three.d.ts || true)",
54
62
  "build": "yarn clean && rollup --config rollup.config.js --bundleConfigAsCjs",
55
63
  "storybook": "storybook dev -p 6006",
56
- "build-storybook": "storybook build"
64
+ "build-storybook": "storybook build",
65
+ "test": "vitest run"
57
66
  },
58
67
  "dependencies": {
59
- "@recast-navigation/core": "0.13.3",
60
- "@recast-navigation/three": "0.13.3"
68
+ "@recast-navigation/core": "0.15.0",
69
+ "@recast-navigation/generators": "0.15.0",
70
+ "@recast-navigation/three": "0.15.0"
61
71
  },
62
72
  "devDependencies": {
63
73
  "@babel/core": "^7.22.11",
@@ -66,7 +76,7 @@
66
76
  "@react-three/csg": "^3.1.0",
67
77
  "@react-three/drei": "^9.87.1",
68
78
  "@react-three/fiber": "^8.14.5",
69
- "@rollup/plugin-commonjs": "^25.0.4",
79
+ "@rollup/plugin-commonjs": "^25.0.7",
70
80
  "@rollup/plugin-multi-entry": "^6.0.0",
71
81
  "@rollup/plugin-node-resolve": "^15.0.1",
72
82
  "@rollup/plugin-terser": "^0.4.3",
@@ -75,9 +85,9 @@
75
85
  "@storybook/addon-essentials": "^7.4.5",
76
86
  "@storybook/addon-interactions": "^7.4.5",
77
87
  "@storybook/addon-links": "^7.4.5",
78
- "@storybook/addon-mdx-gfm": "^7.4.5",
88
+ "@storybook/addon-mdx-gfm": "^7.5.1",
79
89
  "@storybook/react": "^7.4.5",
80
- "@storybook/react-vite": "^7.4.5",
90
+ "@storybook/react-vite": "^7.5.1",
81
91
  "@types/react": "^18.2.11",
82
92
  "@types/react-dom": "^18.2.8",
83
93
  "@types/three": "^0.155.0",
@@ -91,7 +101,8 @@
91
101
  "storybook": "^7.4.5",
92
102
  "suspend-react": "^0.1.3",
93
103
  "three": "^0.156.1",
94
- "three-pathfinding": "^1.2.0"
104
+ "three-pathfinding": "^1.2.0",
105
+ "vitest": "^0.34.6"
95
106
  },
96
107
  "packageManager": "yarn@3.2.2"
97
108
  }