recast-navigation 0.13.2 → 0.14.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,11 @@ 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
+ #### Advanced Usage
96
+
97
+ 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
98
+
99
+ 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
100
 
107
101
  ### Querying a NavMesh
108
102
 
@@ -128,7 +122,7 @@ const path: Vector3[] = navMeshQuery.computePath(
128
122
 
129
123
  ### Crowds and Agents
130
124
 
131
- First, create a `Crowd` instance.
125
+ First, create a `Crowd`:
132
126
 
133
127
  ```ts
134
128
  import { Crowd } from 'recast-navigation';
@@ -139,17 +133,7 @@ const maxAgentRadius = 0.6;
139
133
  const crowd = new Crowd({ maxAgents, maxAgentRadius, navMesh });
140
134
  ```
141
135
 
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.
136
+ Next, create and interface with agents in the crowd.
153
137
 
154
138
  ```ts
155
139
  const initialAgentPosition = navMeshQuery.getRandomPointAround(
@@ -185,9 +169,12 @@ agent.resetMoveTarget();
185
169
  /* teleport the agent to a position */
186
170
  agent.teleport(targetPosition);
187
171
 
188
- /* update some parameters of the agent */
172
+ /* update an agent parameter */
173
+ agent.maxAcceleration = 4;
174
+
175
+ /* update multiple parameters for an agent */
189
176
  agent.updateParameters({
190
- maxAcceleration: 4.0,
177
+ maxAcceleration: 2,
191
178
  });
192
179
 
193
180
  /* set all parameters for an agent */
@@ -199,16 +186,24 @@ agent.setParameters({
199
186
  crowd.removeAgent(agent);
200
187
  ```
201
188
 
202
- ### Temporary Obstacles
189
+ To update the crowd, first set a timeStep, then call `update` each frame with the delta time.
190
+
191
+ ```ts
192
+ const dt = 1 / 60;
193
+ crowd.timeStep = dt;
194
+
195
+ // you should call this every frame
196
+ crowd.update(dt);
197
+ ```
203
198
 
204
- Recast Navigation supports creating Box and Cylinder obstacles.
199
+ ### Temporary Obstacles
205
200
 
206
- Note that in order to use obstacles, you must create a TileCache.
201
+ Recast Navigation supports temporary Box and Cylinder obstacles via a `TileCache`.
207
202
 
208
203
  `TileCache` assumes small tiles (around 32-64 squared). Using `tileSize` values outside this range may result in unexpected behaviour.
209
204
 
210
205
  ```ts
211
- import { generateTileCache } from 'recast-navigation';
206
+ import { generateTileCache } from 'recast-navigation/generators';
212
207
 
213
208
  /* create a tile cache */
214
209
  const { success, navMesh, tileCache } = generateTileCache(positions, indices, {
@@ -246,7 +241,7 @@ Off mesh connections are user-defined connections between two points on a NavMes
246
241
 
247
242
  Off mesh connections can be bidirectional or unidirectional.
248
243
 
249
- You can provide list of off mesh connections to the high level generator functions.
244
+ You can provide a list of off mesh connections to the `generateSoloNavMesh` and `generateTiledNavMesh` high level generator functions.
250
245
 
251
246
  ```ts
252
247
  const { success, navMesh } = generateSoloNavMesh(positions, indices, {
@@ -267,6 +262,43 @@ const { success, navMesh } = generateSoloNavMesh(positions, indices, {
267
262
 
268
263
  You can use `agent.state()` to determine if an agent is currently traversing an off mesh connection.
269
264
 
265
+ #### Adding Off Mesh Connections to a TileCache
266
+
267
+ To add off mesh connections to a TileCache using `generateTileCache`, you must provide a TileCacheMeshProcess implementation that creates off mesh connections. For example:
268
+
269
+ ```ts
270
+ const tileCacheMeshProcess = new TileCacheMeshProcess(
271
+ (navMeshCreateParams, polyAreas, polyFlags) => {
272
+ for (let i = 0; i < navMeshCreateParams.polyCount(); ++i) {
273
+ polyAreas.set(i, 0);
274
+ polyFlags.set(i, 1);
275
+ }
276
+
277
+ navMeshCreateParams.setOffMeshConnections([
278
+ {
279
+ startPosition: { x: 0, y: 5, z: 0 },
280
+ endPosition: { x: 2, y: 0, z: 0 },
281
+ radius: 0.5,
282
+ bidirectional: false,
283
+ area: 0,
284
+ flags: 1,
285
+ },
286
+ ]);
287
+ }
288
+ );
289
+
290
+ const tileCacheGeneratorConfig = {
291
+ // ... other config ...
292
+ tileCacheMeshProcess,
293
+ };
294
+
295
+ const { success, navMesh, tileCache } = generateTileCache(
296
+ positions,
297
+ indices,
298
+ tileCacheGeneratorConfig
299
+ );
300
+ ```
301
+
270
302
  ### Debugging
271
303
 
272
304
  You can use `getDebugNavMesh` to get a debug representation of the NavMesh.
@@ -277,30 +309,45 @@ const debugNavMesh = navMesh.getDebugNavMesh();
277
309
  const { positions, indices } = debugNavMesh;
278
310
  ```
279
311
 
280
- If you are using `@recast-navigation/three`, you can use `NavMeshHelper` and `CrowdHelper` to visualize NavMeshes and Crowds.
312
+ If you are using `@recast-navigation/three`, you can use `NavMeshHelper` and `CrowdHelper` to visualize NavMeshes, Crowds, and NavMesh generation intermediates.
281
313
 
282
- ### Exporting and Importing
314
+ 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.
283
315
 
284
- A NavMesh and TileCache can be exported and imported as a Uint8Array.
316
+ ### Importing and Exporting
317
+
318
+ A NavMesh and TileCache can be imported and exported as a Uint8Array.
319
+
320
+ See below for an example of exporting then importing a NavMesh:
285
321
 
286
322
  ```ts
287
323
  import { exportNavMesh, importNavMesh } from 'recast-navigation';
288
324
 
289
- /* exporting */
290
- const navMeshExport: Uint8Array = exportNavMesh(
291
- navMesh,
292
- tileCache // optional
293
- );
325
+ /* export */
326
+ const navMeshExport: Uint8Array = exportNavMesh(navMesh);
294
327
 
295
- /* importing */
296
- const { navMesh, tileCache } = importNavMesh(navMeshExport);
328
+ /* import */
329
+ const { navMesh } = importNavMesh(navMeshExport);
297
330
  ```
298
331
 
299
- ### Advanced Usage
332
+ To export a TileCache and NavMesh, the usage varies slightly:
300
333
 
301
- 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
334
+ ```ts
335
+ import { exportNavMesh, importNavMesh } from 'recast-navigation';
302
336
 
303
- 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.
337
+ /* exporting */
338
+ // pass both the navMesh and the tileCache
339
+ const navMeshExport: Uint8Array = exportNavMesh(navMesh, tileCache);
340
+
341
+ /* importing */
342
+ // also pass the TileCacheMeshProcess implementation for the tile cache
343
+ // if you used `generateTileCache` and didn't provide one, `createDefaultTileCacheMeshProcess` returns the default TileCacheMeshProcess `generateTileCache` uses
344
+ const tileCacheMeshProcess = createDefaultTileCacheMeshProcess();
345
+
346
+ const { navMesh, tileCache } = importNavMesh(
347
+ navMeshExport,
348
+ tileCacheMeshProcess
349
+ );
350
+ ```
304
351
 
305
352
  ## Documentation
306
353
 
@@ -352,6 +399,16 @@ The core library!
352
399
  > npm install @recast-navigation/core
353
400
  ```
354
401
 
402
+ ### [**`@recast-navigation/generators`**](https://github.com/isaac-mason/recast-navigation-js/tree/main/packages/recast-navigation-generators)
403
+
404
+ [![Version](https://img.shields.io/npm/v/@recast-navigation/generators)](https://www.npmjs.com/package/@recast-navigation/generators)
405
+
406
+ NavMesh generator implementations. Use these to get started, and as a basis for your own NavMesh generator.
407
+
408
+ ```bash
409
+ > npm install @recast-navigation/generators
410
+ ```
411
+
355
412
  ### [**`@recast-navigation/three`**](https://github.com/isaac-mason/recast-navigation-js/tree/main/packages/recast-navigation-three)
356
413
 
357
414
  [![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),{raw:R}=e.RecastConfig.create({...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},{raw:H}=e.RecastConfig.create(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,{raw:r}=new e.RecastConfig(H).clone(),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.RecastConfig.create({...o,...s}),{raw:u}=m,{bbMin:b,bbMax:w}=t(l,r),C=e.calcGridSize(b,w,u.cs);u.width=C.width,u.height=C.height,u.minRegionArea=u.minRegionArea*u.minRegionArea,u.mergeRegionArea=u.mergeRegionArea*u.mergeRegionArea,u.tileSize=Math.floor(u.tileSize),u.borderSize=u.walkableRadius+3,u.width=u.tileSize+2*u.borderSize,u.height=u.tileSize+2*u.borderSize,u.detailSampleDist=u.detailSampleDist<.9?0:u.cs*u.detailSampleDist,u.detailSampleMaxError=u.ch*u.detailSampleMaxError;const R=Math.floor(u.tileSize),S=Math.floor((C.width+R-1)/R),y=Math.floor((C.height+R-1)/R),M=u.tileSize*u.cs,p=l,x=r.length,A=new e.Arrays.FloatArray;A.copy(p,p.length);const k=r,H=r.length/3,v=new e.Arrays.IntArray;v.copy(k,k.length);const T=e.vec3.fromArray(b);let z=Math.min(Math.floor(i(a(S*y))),14);z>14&&(z=14);const _=1<<z,L=1<<22-z,D=e.NavMeshParams.create({orig:T,tileWidth:u.tileSize*u.cs,tileHeight:u.tileSize*u.cs,maxTiles:_,maxPolys:L});if(!c.initTiled(D))return f("Could not init nav mesh for tiled use");const E=new e.RecastChunkyTriMesh;if(h.chunkyTriMesh=E,!E.init(A,v,H,256))return f("Failed to build chunky triangle mesh");const P=(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{raw:c}=m.clone(),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,` - ${u.width} x ${u.height} cells`),d.log(e.Raw.Module.RC_LOG_PROGRESS,` - ${x/1e3}fK verts, ${H/1e3}K tris`);const b=e.allocHeightfield();if(o.heightfield=b,!e.createHeightfield(d,b,c.width,c.height,g,f,c.cs,c.ch))return r("Could not create heightfield");(new e.Arrays.UnsignedCharArray).resize(E.maxTrisPerChunk());const w=[g[0],g[2]],C=[f[0],f[2]],R=new e.Arrays.IntArray;R.resize(512);const S=E.getChunksOverlappingRect(w,C,R,512);if(0===S)return{success:!0};for(let t=0;t<S;++t){const i=R.get_data(t),a=E.nodes(i).n,l=E.getNodeTris(i),s=new e.Arrays.UnsignedCharArray;s.resize(a),e.markWalkableTriangles(d,c.walkableSlopeAngle,A,x,l,a,s);const o=e.rasterizeTriangles(d,A,x,l,s,a,b,c.walkableClimb);if(s.free(),!o)return r("Could not rasterize triangles")}e.filterLowHangingWalkableObstacles(d,c.walkableClimb,b),e.filterLedgeSpans(d,c.walkableHeight,c.walkableClimb,b),e.filterWalkableLowHeightSpans(d,c.walkableHeight,b);const y=e.allocCompactHeightfield();if(o.compactHeightfield=y,!e.buildCompactHeightfield(d,c.walkableHeight,c.walkableClimb,b,y))return r("Could not build compact heightfield");if(n||(e.freeHeightfield(o.heightfield),o.heightfield=void 0),!e.erodeWalkableArea(d,c.walkableRadius,y))return r("Could not erode walkable area");if(!e.buildDistanceField(d,y))return r("Failed to build distance field");if(!e.buildRegions(d,y,c.borderSize,c.minRegionArea,c.mergeRegionArea))return r("Failed to build regions");const M=e.allocContourSet();if(o.contourSet=M,!e.buildContours(d,y,c.maxSimplificationError,c.maxEdgeLen,M,e.Raw.Module.RC_CONTOUR_TESS_WALL_EDGES))return r("Failed to create contours");const p=e.allocPolyMesh();if(!e.buildPolyMesh(d,M,c.maxVertsPerPoly,p))return r("Failed to triangulate contours");const k=e.allocPolyMeshDetail();if(!e.buildPolyMeshDetail(d,p,y,c.detailSampleDist,c.detailSampleMaxError,k))return r("Failed to build detail mesh");n||(e.freeCompactHeightfield(y),o.compactHeightfield=void 0,e.freeContourSet(M),o.contourSet=void 0);for(let t=0;t<p.npolys();t++)p.areas(t)==e.Raw.Recast.WALKABLE_AREA&&p.setAreas(t,0),0==p.areas(t)&&p.setFlags(t,1);const v=new e.NavMeshCreateParams;v.setPolyMeshCreateParams(p),v.setPolyMeshDetailCreateParams(k),v.setWalkableHeight(c.walkableHeight),v.setWalkableRadius(c.walkableRadius),v.setWalkableClimb(c.walkableClimb),v.setCellSize(c.cs),v.setCellHeight(c.ch),v.setBuildBvTree(!0),s.offMeshConnections&&v.setOffMeshConnections(s.offMeshConnections),v.setTileX(t),v.setTileY(i);const T=e.createNavMeshData(v);return T.success?(d.log(e.Raw.Module.RC_LOG_PROGRESS,`>> Polymesh: ${p.nverts()} vertices ${p.npolys()} polygons`),{success:!0,data:T.navMeshData}):r("Failed to create Detour navmesh data")};d.startTimer(e.Raw.Module.RC_TIMER_TEMP);let F=[0,0,0],N=[0,0,0];for(let t=0;t<y;t++)for(let i=0;i<S;i++){F[0]=b[0]+i*M,F[1]=b[1],F[2]=b[2]+t*M,N[0]=b[0]+(i+1)*M,N[1]=w[1],N[2]=b[2]+(t+1)*M;const a=P(i,t,F,N);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,RecastConfig 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 w,buildDistanceField as S,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,allocHeightfieldLayerSet as O,buildHeightfieldLayers as G,getHeightfieldLayerHeights as N,getHeightfieldLayerAreas as $,getHeightfieldLayerCons as W,buildTileCacheLayer as B}from"@recast-navigation/core";const U=(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)}},K=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},V=e=>(e--,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e),X={...e},Y=(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}=U(e,t),{raw:K}=r.create({...X,...T});K.minRegionArea=K.minRegionArea*K.minRegionArea,K.mergeRegionArea=K.mergeRegionArea*K.mergeRegionArea,K.detailSampleDist=K.detailSampleDist<.9?0:K.cs*K.detailSampleDist,K.detailSampleMaxError=K.ch*K.detailSampleMaxError;const V=s.Recast.calcGridSize(W,B,K.cs);K.width=V.width,K.height=V.height;const Y=o();if(F.heightfield=Y,!n(H,Y,K.width,K.height,W,B,K.cs,K.ch))return L("Could not create heightfield");const Z=new l.UnsignedCharArray;if(Z.resize(N),d(H,K.walkableSlopeAngle,O,I,$,N,Z),!h(H,O,I,$,Z,N,Y,K.walkableClimb))return L("Could not rasterize triangles");Z.free(),c(H,K.walkableClimb,Y),m(H,K.walkableHeight,K.walkableClimb,Y),g(H,K.walkableHeight,Y);const j=u();if(F.compactHeightfield=j,!b(H,K.walkableHeight,K.walkableClimb,Y,j))return L("Failed to build compact data");if(E||(f(Y),F.heightfield=void 0),!w(H,K.walkableRadius,j))return L("Failed to erode walkable area");if(!S(H,j))return L("Failed to build distance field");if(!M(H,j,K.borderSize,K.minRegionArea,K.mergeRegionArea))return L("Failed to build regions");const q=C();if(F.contourSet=q,!y(H,j,K.maxSimplificationError,K.maxEdgeLen,q,s.Module.RC_CONTOUR_TESS_WALL_EDGES))return L("Failed to create contours");const J=R();if(!x(H,q,K.maxVertsPerPoly,J))return L("Failed to triangulate contours");const Q=p();if(!A(H,J,j,K.detailSampleDist,K.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(K.walkableHeight),ee.setWalkableRadius(K.walkableRadius),ee.setWalkableClimb(K.walkableClimb),ee.setCellSize(K.cs),ee.setCellHeight(K.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")},Z={...e,tileSize:32,expectedLayersPerTile:4,maxObstacles:128},j=()=>new T(((e,t,i)=>{for(let a=0;a<e.polyCount();++a)t.set(a,0),i.set(a,1)})),q=(e,S,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=S.length,T=new l.FloatArray;T.copy(_,_.length);const P=S,X=S.length/3,Y=new l.IntArray;Y.copy(P,P.length);const{bbMin:q,bbMax:J}=U(e,S),{expectedLayersPerTile:Q,maxObstacles:ee,...te}={...Z,...M},{raw:ie}=r.create(te),ae=H(q,J,ie.cs);ie.width=ae.width,ie.height=ae.height,ie.minRegionArea=ie.minRegionArea*ie.minRegionArea,ie.mergeRegionArea=ie.mergeRegionArea*ie.mergeRegionArea,ie.detailSampleDist=ie.detailSampleDist<.9?0:ie.cs*ie.detailSampleDist,ie.detailSampleMaxError=ie.ch*ie.detailSampleMaxError;const le=Math.floor(ie.tileSize),re=Math.floor((ie.width+le-1)/le),se=Math.floor((ie.height+le-1)/le);ie.borderSize=ie.walkableRadius+3,ie.width=ie.tileSize+2*ie.borderSize,ie.height=ie.tileSize+2*ie.borderSize;const oe=F.create({orig:q,cs:ie.cs,ch:ie.ch,width:ie.tileSize,height:ie.tileSize,walkableHeight:ie.walkableHeight,walkableRadius:ie.walkableRadius,walkableClimb:ie.walkableClimb,maxSimplificationError:ie.maxSimplificationError,maxTiles:re*se*Q,maxObstacles:ee}),ne=new s.RecastLinearAllocator(32e3),de=new s.RecastFastLZCompressor,he=M.tileCacheMeshProcess??j();if(!x.init(oe,ne,de,he))return z("Failed to initialize tile cache");const ce=t.fromArray(q);let me=Math.min(Math.floor(K(V(re*se*Q))),14);me>14&&(me=14);const ge=1<<me,ue=1<<22-me,be=D.create({orig:ce,tileWidth:ie.tileSize*ie.cs,tileHeight:ie.tileSize*ie.cs,maxTiles:ge,maxPolys:ue});if(!p.initTiled(be))return z("Failed to initialize tiled navmesh");const fe=new L;if(R.chunkyTriMesh=fe,!fe.init(T,Y,X,256))return z("Failed to build chunky triangle mesh");const we=(e,t)=>{const i={tileX:e,tileY:t},a=ie.tileSize*ie.cs,{raw:S}=new r(ie).clone(),M=[q[0]+e*a,q[1],q[2]+t*a],x=[q[0]+(e+1)*a,J[1],q[2]+(t+1)*a];M[0]-=S.borderSize*S.cs,M[2]-=S.borderSize*S.cs,x[0]+=S.borderSize*S.cs,x[2]+=S.borderSize*S.cs,S.set_bmin(0,M[0]),S.set_bmin(1,M[1]),S.set_bmin(2,M[2]),S.set_bmax(0,x[0]),S.set_bmax(1,x[1]),S.set_bmax(2,x[2]);const p=o();if(i.heightfield=p,!n(y,p,S.width,S.height,M,x,S.cs,S.ch))return{n:0};const A=[M[0],M[2]],z=[x[0],x[2]],_=new l.IntArray;_.resize(512);const E=fe.getChunksOverlappingRect(A,z,_,512);if(0===E)return{n:0};for(let e=0;e<E;++e){const t=_.get_data(e),i=fe.nodes(t).n,a=fe.getNodeTris(t),r=new l.UnsignedCharArray;r.resize(i),d(y,S.walkableSlopeAngle,T,v,a,i,r);const s=h(y,T,v,a,r,i,p,S.walkableClimb);if(r.free(),!s)return{n:0}}c(y,ie.walkableClimb,p),m(y,ie.walkableHeight,ie.walkableClimb,p),g(y,ie.walkableHeight,p);const H=u();if(!b(y,ie.walkableHeight,ie.walkableClimb,p,H))return{n:0};if(C||(f(i.heightfield),i.heightfield=void 0),!w(y,ie.walkableRadius,H))return{n:0};const F=O();if(!G(y,H,ie.borderSize,ie.walkableHeight,F))return{n:0};C||(k(H),i.compactHeightfield=void 0);const D=[];for(let i=0;i<F.nlayers();i++){const a=new l.UnsignedCharArray,r=F.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=N(r),c=$(r),m=W(r),g=B(de,o,h,c,m,a);if(s.Detour.statusFailed(g))return{n:0};D.push(a)}return C||(I(F),i.heightfieldLayerSet=void 0),R.tileIntermediates.push(i),{n:D.length,tiles:D}};for(let e=0;e<se;++e)for(let t=0;t<re;++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<se;e++)for(let t=0;t<re;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}},J={...e},Q=(e,T,E={},F=!1)=>{const I=new i,O={type:"tiled",buildContext:I,chunkyTriMesh:void 0,tileIntermediates:[]},G=new a,N=()=>{if(!F){for(let e=0;e<O.tileIntermediates.length;e++){const t=O.tileIntermediates[e];t.compactHeightfield&&k(t.compactHeightfield),t.heightfield&&f(t.heightfield),t.contourSet&&z(t.contourSet)}O.chunkyTriMesh&&(O.chunkyTriMesh=void 0)}},$=e=>(N(),G.destroy(),{success:!1,navMesh:void 0,intermediates:O,error:e}),W=r.create({...J,...E}),{raw:B}=W,{bbMin:X,bbMax:Y}=U(e,T),Z=H(X,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),Q=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(X);let ne=Math.min(Math.floor(K(V(q*Q))),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(!G.initTiled(ce))return $("Could not init nav mesh for tiled use");const me=new L;if(O.chunkyTriMesh=me,!me.init(ae,se,re,256))return $("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};O.tileIntermediates.push(T);const{raw:H}=W.clone(),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 ${O.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 G=[D[0],D[2]],N=[L[0],L[2]],$=new l.IntArray;$.resize(512);const U=me.getChunksOverlappingRect(G,N,$,512);if(0===U)return{success:!0};for(let e=0;e<U;++e){const t=$.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),!w(I,H.walkableRadius,K))return r("Could not erode walkable area");if(!S(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<Q;e++)for(let t=0;t<q;t++){ue[0]=X[0]+t*ee,ue[1]=X[1],ue[2]=X[2]+e*ee,be[0]=X[0]+(t+1)*ee,be[1]=Y[1],be[2]=X[2]+(e+1)*ee;const i=ge(t,e,ue,be);if(i.success&&i.data){G.removeTile(G.getTileRefAt(t,e,0));const a=G.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||N(),{success:!0,navMesh:G,intermediates:O}};export{j as createDefaultTileCacheMeshProcess,K as dtIlog2,V as dtNextPow2,Y as generateSoloNavMesh,q as generateTileCache,Q as generateTiledNavMesh,U as getBoundingBox,X as soloNavMeshGeneratorConfigDefaults,Z as tileCacheGeneratorConfigDefaults,J 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.2",
21
+ "version": "0.14.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.2",
60
- "@recast-navigation/three": "0.13.2"
68
+ "@recast-navigation/core": "0.14.0",
69
+ "@recast-navigation/generators": "0.14.0",
70
+ "@recast-navigation/three": "0.14.0"
61
71
  },
62
72
  "devDependencies": {
63
73
  "@babel/core": "^7.22.11",
@@ -65,19 +75,19 @@
65
75
  "@pmndrs/assets": "^1.6.0",
66
76
  "@react-three/csg": "^3.1.0",
67
77
  "@react-three/drei": "^9.87.1",
68
- "@react-three/fiber": "^8.14.4",
69
- "@rollup/plugin-commonjs": "^25.0.4",
78
+ "@react-three/fiber": "^8.14.5",
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",
73
- "@rollup/plugin-typescript": "^11.1.2",
83
+ "@rollup/plugin-typescript": "^11.1.5",
74
84
  "@storybook/addon-actions": "^7.4.5",
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
  }