recast-navigation 0.19.0 → 0.21.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 +26 -22
- package/generators.cjs +1 -1
- package/generators.mjs +1 -1
- package/package.json +7 -6
package/README.md
CHANGED
|
@@ -25,25 +25,33 @@ This library provides high level APIs that make it easy to get started creating
|
|
|
25
25
|
|
|
26
26
|
> **Warning** This library is still in early development. Versions in the 0.x.x range may have breaking changes.
|
|
27
27
|
|
|
28
|
+
## Examples
|
|
29
|
+
|
|
30
|
+
Go to the [examples website](https://recast-navigation-js.isaacmason.com) to see the project in action:
|
|
31
|
+
- live: [https://recast-navigation-js.isaacmason.com](https://recast-navigation-js.isaacmason.com).
|
|
32
|
+
- examples source code: [./packages/recast-navigation/.storybook/stories](./packages/recast-navigation/.storybook/stories).
|
|
33
|
+
|
|
34
|
+
Demonstrations of how to use the library in different environments (such as NodeJS, CommonJS) can be found in the [examples](./examples) directory.
|
|
35
|
+
|
|
28
36
|
## Installation
|
|
29
37
|
|
|
30
38
|
This package ships as both ECMAScript modules and CJS, and is compatible with Node.js and browser environments.
|
|
31
39
|
|
|
32
|
-
|
|
40
|
+
**NPM**
|
|
33
41
|
|
|
34
42
|
```sh
|
|
35
43
|
npm install recast-navigation
|
|
36
44
|
```
|
|
37
45
|
|
|
38
|
-
|
|
46
|
+
**Unpkg**
|
|
39
47
|
|
|
40
48
|
```html
|
|
41
49
|
<script type="importmap">
|
|
42
50
|
{
|
|
43
51
|
"imports": {
|
|
44
|
-
"@recast-navigation/core": "https://unpkg.com/@recast-navigation/core@0.
|
|
45
|
-
"@recast-navigation/generators": "https://unpkg.com/@recast-navigation/generators@0.
|
|
46
|
-
"@recast-navigation/three": "https://unpkg.com/@recast-navigation/three@0.
|
|
52
|
+
"@recast-navigation/core": "https://unpkg.com/@recast-navigation/core@0.20.0/dist/index.mjs",
|
|
53
|
+
"@recast-navigation/generators": "https://unpkg.com/@recast-navigation/generators@0.20.0/dist/index.mjs",
|
|
54
|
+
"@recast-navigation/three": "https://unpkg.com/@recast-navigation/three@0.20.0/dist/index.mjs"
|
|
47
55
|
}
|
|
48
56
|
}
|
|
49
57
|
</script>
|
|
@@ -54,7 +62,7 @@ npm install recast-navigation
|
|
|
54
62
|
</script>
|
|
55
63
|
```
|
|
56
64
|
|
|
57
|
-
|
|
65
|
+
**Usage with bundlers**
|
|
58
66
|
|
|
59
67
|
If you are using Vite, you may need to opt `recast-navigation` out of pre-bundling:
|
|
60
68
|
|
|
@@ -83,7 +91,7 @@ Documentation for the Recast and Detour c++ libraries can be found here:
|
|
|
83
91
|
- [Recast Navigation GitHub](https://github.com/recastnavigation/recastnavigation)
|
|
84
92
|
- [Recast Navigation Google Discussions](https://groups.google.com/g/recastnavigation)
|
|
85
93
|
|
|
86
|
-
The GitHub issues and Google Discussions are
|
|
94
|
+
The GitHub issues and Google Discussions are great resources for learning about the library and getting guidance on common issues.
|
|
87
95
|
|
|
88
96
|
## Usage
|
|
89
97
|
|
|
@@ -142,7 +150,9 @@ See the docs for more information on generator options: https://docs.recast-navi
|
|
|
142
150
|
|
|
143
151
|
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
|
|
144
152
|
|
|
145
|
-
|
|
153
|
+
An example of a custom NavMesh generator with custom areas can be found here: https://recast-navigation-js.isaacmason.com/?path=/story/advanced-custom-areas--compute-path
|
|
154
|
+
|
|
155
|
+
Please note that not all recast and detour functionality is exposed yet. If you require unexposed functionality, please submit an issue or a pull request.
|
|
146
156
|
|
|
147
157
|
### Querying a NavMesh
|
|
148
158
|
|
|
@@ -388,30 +398,30 @@ See the [`@recast-navigation/three` package README](https://github.com/isaac-mas
|
|
|
388
398
|
|
|
389
399
|
Many Detour APIs return a `status` property. This is a `dtStatus` enum, which is a number representing the status of the operation.
|
|
390
400
|
|
|
391
|
-
You can use the `
|
|
401
|
+
You can use the `statusToReadableString` function to convert a `dtStatus` to a human-readable string.
|
|
392
402
|
|
|
393
403
|
```ts
|
|
394
|
-
import {
|
|
404
|
+
import { statusToReadableString } from 'recast-navigation';
|
|
395
405
|
|
|
396
|
-
console.log(
|
|
406
|
+
console.log(statusToReadableString(status));
|
|
397
407
|
```
|
|
398
408
|
|
|
399
409
|
If you need to work with status codes programmatically, you can use these utilities:
|
|
400
410
|
|
|
401
411
|
```ts
|
|
402
|
-
import {
|
|
412
|
+
import { statusSucceed, statusInProgress, statusFailed, statusDetail } from 'recast-navigation';
|
|
403
413
|
|
|
404
414
|
// returns true if the status is a success
|
|
405
|
-
|
|
415
|
+
const succeeded = statusSucceed(status);
|
|
406
416
|
|
|
407
417
|
// returns true if the status is in progress
|
|
408
|
-
|
|
418
|
+
const inProgress = statusInProgress(status);
|
|
409
419
|
|
|
410
420
|
// returns true if the status is a failure
|
|
411
|
-
|
|
421
|
+
const failed = statusFailed(status);
|
|
412
422
|
|
|
413
423
|
// get the detail of the status
|
|
414
|
-
const detail =
|
|
424
|
+
const detail = statusDetail(status);
|
|
415
425
|
|
|
416
426
|
// Raw.Detour.WRONG_MAGIC;
|
|
417
427
|
// Raw.Detour.WRONG_VERSION;
|
|
@@ -459,12 +469,6 @@ const { navMesh, tileCache } = importNavMesh(
|
|
|
459
469
|
);
|
|
460
470
|
```
|
|
461
471
|
|
|
462
|
-
## Examples
|
|
463
|
-
|
|
464
|
-
Some demonstrations of how to use the library in different environments can be found in the [examples](./examples) directory.
|
|
465
|
-
|
|
466
|
-
There are also storybooks that demonstrate the library in action: [https://recast-navigation-js.isaacmason.com](https://recast-navigation-js.isaacmason.com). The source code for the storybooks can be found in [./packages/recast-navigation/.storybook/stories](./packages/recast-navigation/.storybook/stories).
|
|
467
|
-
|
|
468
472
|
## Packages
|
|
469
473
|
|
|
470
474
|
Functionality is spread across packages in the `@recast-navigation/*` organization, with the `recast-navigation` acting as an umbrella package.
|
package/generators.cjs
CHANGED
|
@@ -1,2 +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.VertsArray;f.copy(c,c.length);const m=a,u=a.length/3,b=new e.Arrays.TrisArray;b.copy(m,m.length);const{bbMin:w,bbMax:C}=t(i,a),S=e.createRcConfig({...l,...r});S.minRegionArea=S.minRegionArea*S.minRegionArea,S.mergeRegionArea=S.mergeRegionArea*S.mergeRegionArea,S.detailSampleDist=S.detailSampleDist<.9?0:S.cs*S.detailSampleDist,S.detailSampleMaxError=S.ch*S.detailSampleMaxError;const R=e.calcGridSize(w,C,S.cs);S.width=R.width,S.height=R.height;const y=e.allocHeightfield();if(n.heightfield=y,!e.createHeightfield(o,y,S.width,S.height,w,C,S.cs,S.ch))return h("Could not create heightfield");const M=new e.Arrays.TriAreasArray;if(M.resize(u),e.markWalkableTriangles(o,S.walkableSlopeAngle,f,g,b,u,M),!e.rasterizeTriangles(o,f,g,b,M,u,y,S.walkableClimb))return h("Could not rasterize triangles");M.free(),e.filterLowHangingWalkableObstacles(o,S.walkableClimb,y),e.filterLedgeSpans(o,S.walkableHeight,S.walkableClimb,y),e.filterWalkableLowHeightSpans(o,S.walkableHeight,y);const p=e.allocCompactHeightfield();if(n.compactHeightfield=p,!e.buildCompactHeightfield(o,S.walkableHeight,S.walkableClimb,y,p))return h("Failed to build compact data");if(s||(e.freeHeightfield(y),n.heightfield=void 0),!e.erodeWalkableArea(o,S.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,S.borderSize,S.minRegionArea,S.mergeRegionArea))return h("Failed to build regions");const x=e.allocContourSet();if(n.contourSet=x,!e.buildContours(o,p,S.maxSimplificationError,S.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,S.maxVertsPerPoly,A))return h("Failed to triangulate contours");const k=e.allocPolyMeshDetail();if(!e.buildPolyMeshDetail(o,A,p,S.detailSampleDist,S.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(S.walkableHeight),H.setWalkableRadius(S.walkableRadius),H.setWalkableClimb(S.walkableClimb),H.setCellSize(S.cs),H.setCellHeight(S.ch),H.setBuildBvTree(!0),r.offMeshConnections&&H.setOffMeshConnections(r.offMeshConnections);const T=e.createNavMeshData(H);if(!T.success)return h("Failed to create Detour navmesh data");const{navMeshData:v}=T;return d.initSolo(v)?{success:!0,navMesh:d,intermediates:n}:h("Failed to create Detour navmesh")},exports.generateTileCache=(l,o,n={},d=!1)=>{const h=new e.RecastBuildContext,c={type:"tilecache",buildContext:h,chunkyTriMesh:void 0,tileIntermediates:[]},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.VertsArray;C.copy(b,b.length);const S=o,R=o.length/3,y=new e.Arrays.TrisArray;y.copy(S,S.length);const{bbMin:M,bbMax:p}=t(l,o),{expectedLayersPerTile:x,maxObstacles:A,...k}={...r,...n},H=e.createRcConfig(k),T=e.calcGridSize(M,p,H.cs);H.width=T.width,H.height=T.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 v=Math.floor(H.tileSize),z=Math.floor((H.width+v-1)/v),_=Math.floor((H.height+v-1)/v);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,G=e.NavMeshParams.create({orig:F,tileWidth:H.tileSize*H.cs,tileHeight:H.tileSize*H.cs,maxTiles:O,maxPolys:W});if(!f.initTiled(G))return u("Failed to initialize tiled navmesh");const I=new e.RecastChunkyTriMesh;if(c.chunkyTriMesh=I,!I.init(C,y,R,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.ChunkIdsArray;m.resize(512);const u=I.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=I.nodes(i).n,l=I.getNodeTris(i),s=new e.Arrays.TriAreasArray;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 S=e.allocHeightfieldLayerSet();if(!e.buildHeightfieldLayers(h,b,H.borderSize,H.walkableHeight,S))return{n:0};d||(e.freeCompactHeightfield(b),a.compactHeightfield=void 0);const R=[];for(let a=0;a<S.nlayers();a++){const l=new e.Arrays.TileCacheData,r=S.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};R.push(l)}return d||(e.freeHeightfieldLayerSet(S),a.heightfieldLayerSet=void 0),c.tileIntermediates.push(a),{n:R.length,tiles:R}};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),S=Math.floor((w.width+C-1)/C),R=Math.floor((w.height+C-1)/C),y=m.tileSize*m.cs,M=l,p=r.length,x=new e.Arrays.VertsArray;x.copy(M,M.length);const A=r,k=r.length/3,H=new e.Arrays.TrisArray;H.copy(A,A.length);const T=e.vec3.fromArray(u);let v=Math.min(Math.floor(i(a(S*R))),14);v>14&&(v=14);const z=1<<v,_=1<<22-v,L=e.NavMeshParams.create({orig:T,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.TriAreasArray).resize(D.maxTrisPerChunk());const b=[g[0],g[2]],w=[f[0],f[2]],C=new e.Arrays.ChunkIdsArray;C.resize(512);const S=D.getChunksOverlappingRect(b,w,C,512);if(0===S)return{success:!0};for(let t=0;t<S;++t){const i=C.get_data(t),a=D.nodes(i).n,l=D.getNodeTris(i),s=new e.Arrays.TriAreasArray;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 R=e.allocCompactHeightfield();if(o.compactHeightfield=R,!e.buildCompactHeightfield(d,c.walkableHeight,c.walkableClimb,u,R))return r("Could not build compact heightfield");if(n||(e.freeHeightfield(o.heightfield),o.heightfield=void 0),!e.erodeWalkableArea(d,c.walkableRadius,R))return r("Could not erode walkable area");if(!e.buildDistanceField(d,R))return r("Failed to build distance field");if(!e.buildRegions(d,R,c.borderSize,c.minRegionArea,c.mergeRegionArea))return r("Failed to build regions");const y=e.allocContourSet();if(o.contourSet=y,!e.buildContours(d,R,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,R,c.detailSampleDist,c.detailSampleMaxError,A))return r("Failed to build detail mesh");n||(e.freeCompactHeightfield(R),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 T=e.createNavMeshData(H);return T.success?(d.log(e.Raw.Module.RC_LOG_PROGRESS,`>> Polymesh: ${M.nverts()} vertices ${M.npolys()} polygons`),{success:!0,data:T.navMeshData}):r("Failed to create Detour navmesh data")};d.startTimer(e.Raw.Module.RC_TIMER_TEMP);const P=[0,0,0],F=[0,0,0];for(let t=0;t<R;t++)for(let i=0;i<S;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;
|
|
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.VertsArray;f.copy(c,c.length);const m=a,u=a.length/3,b=new e.Arrays.TrisArray;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.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.TriAreasArray;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 T=e.createNavMeshData(H);if(!T.success)return h("Failed to create Detour navmesh data");const{navMeshData:v}=T;return d.initSolo(v)?{success:!0,navMesh:d,intermediates:n}:h("Failed to create Detour navmesh")},exports.generateTileCache=(l,o,n={},d=!1)=>{const h=new e.RecastBuildContext,c={type:"tilecache",buildContext:h,chunkyTriMesh:void 0,tileIntermediates:[]},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.VertsArray;C.copy(b,b.length);const R=o,S=o.length/3,y=new e.Arrays.TrisArray;y.copy(R,R.length);const{bbMin:M,bbMax:p}=t(l,o),{expectedLayersPerTile:x,maxObstacles:A,...k}={...r,...n},H=e.createRcConfig(k),T=e.calcGridSize(M,p,H.cs);H.width=T.width,H.height=T.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 v=Math.floor(H.tileSize),z=Math.floor((H.width+v-1)/v),_=Math.floor((H.height+v-1)/v);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,G=e.NavMeshParams.create({orig:F,tileWidth:H.tileSize*H.cs,tileHeight:H.tileSize*H.cs,maxTiles:O,maxPolys:W});if(!f.initTiled(G))return u("Failed to initialize tiled navmesh");const I=new e.RecastChunkyTriMesh;if(c.chunkyTriMesh=I,!I.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.ChunkIdsArray;m.resize(512);const u=I.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=I.nodes(i).n,l=I.getNodeTris(i),s=new e.Arrays.TriAreasArray;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.TileCacheData,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.VertsArray;x.copy(M,M.length);const A=r,k=r.length/3,H=new e.Arrays.TrisArray;H.copy(A,A.length);const T=e.vec3.fromArray(u);let v=Math.min(Math.floor(i(a(R*S))),14);v>14&&(v=14);const z=1<<v,_=1<<22-v,L=e.NavMeshParams.create({orig:T,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.TriAreasArray).resize(D.maxTrisPerChunk());const b=[g[0],g[2]],w=[f[0],f[2]],C=new e.Arrays.ChunkIdsArray;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.TriAreasArray;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 T=e.createNavMeshData(H);return T.success?(d.log(e.Raw.Module.RC_LOG_PROGRESS,`>> Polymesh: ${M.nverts()} vertices ${M.npolys()} polygons`),{success:!0,data:T.navMeshData}):r("Failed to create Detour navmesh data")};d.startTimer(e.Raw.Module.RC_TIMER_TEMP);const 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.statusToReadableString(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
2
|
//# sourceMappingURL=generators.cjs.map
|
package/generators.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{recastConfigDefaults as e,vec3 as t,RecastBuildContext as i,NavMesh as a,Arrays as l,createRcConfig as r,calcGridSize 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,Raw as R,allocPolyMesh as x,buildPolyMesh as p,allocPolyMeshDetail as A,buildPolyMeshDetail as k,freeCompactHeightfield as T,freeContourSet as _,NavMeshCreateParams as z,createNavMeshData as v,TileCacheMeshProcess as E,TileCache as H,DetourTileCacheParams as D,NavMeshParams as F,RecastChunkyTriMesh as L,dtStatusToReadableString as P,freeHeightfieldLayerSet as O,cloneRcConfig as I,allocHeightfieldLayerSet as G,buildHeightfieldLayers as N,getHeightfieldLayerHeights as $,getHeightfieldLayerAreas as W,getHeightfieldLayerCons as B,buildTileCacheLayer as V}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)}},X=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},Y=e=>(e--,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e),U={...e},Z=(e,t,E={},H=!1)=>{const D=new i,F={type:"solo",buildContext:D},L=new a,P=e=>(H||(F.heightfield&&(f(F.heightfield),F.heightfield=void 0),F.compactHeightfield&&(T(F.compactHeightfield),F.compactHeightfield=void 0),F.contourSet&&(_(F.contourSet),F.contourSet=void 0)),L.destroy(),{navMesh:void 0,success:!1,intermediates:F,error:e}),O=e,I=t.length,G=new l.VertsArray;G.copy(O,O.length);const N=t,$=t.length/3,W=new l.TrisArray;W.copy(N,N.length);const{bbMin:B,bbMax:V}=K(e,t),X=r({...U,...E});X.minRegionArea=X.minRegionArea*X.minRegionArea,X.mergeRegionArea=X.mergeRegionArea*X.mergeRegionArea,X.detailSampleDist=X.detailSampleDist<.9?0:X.cs*X.detailSampleDist,X.detailSampleMaxError=X.ch*X.detailSampleMaxError;const Y=s(B,V,X.cs);X.width=Y.width,X.height=Y.height;const Z=o();if(F.heightfield=Z,!n(D,Z,X.width,X.height,B,V,X.cs,X.ch))return P("Could not create heightfield");const j=new l.TriAreasArray;if(j.resize($),d(D,X.walkableSlopeAngle,G,I,W,$,j),!h(D,G,I,W,j,$,Z,X.walkableClimb))return P("Could not rasterize triangles");j.free(),c(D,X.walkableClimb,Z),m(D,X.walkableHeight,X.walkableClimb,Z),g(D,X.walkableHeight,Z);const q=u();if(F.compactHeightfield=q,!b(D,X.walkableHeight,X.walkableClimb,Z,q))return P("Failed to build compact data");if(H||(f(Z),F.heightfield=void 0),!S(D,X.walkableRadius,q))return P("Failed to erode walkable area");if(!w(D,q))return P("Failed to build distance field");if(!M(D,q,X.borderSize,X.minRegionArea,X.mergeRegionArea))return P("Failed to build regions");const J=C();if(F.contourSet=J,!y(D,q,X.maxSimplificationError,X.maxEdgeLen,J,R.Module.RC_CONTOUR_TESS_WALL_EDGES))return P("Failed to create contours");const Q=x();if(!p(D,J,X.maxVertsPerPoly,Q))return P("Failed to triangulate contours");const ee=A();if(!k(D,Q,q,X.detailSampleDist,X.detailSampleMaxError,ee))return P("Failed to build detail mesh");H||(T(q),F.compactHeightfield=void 0,_(J),F.contourSet=void 0);for(let e=0;e<Q.npolys();e++)Q.areas(e)==R.Recast.WALKABLE_AREA&&Q.setAreas(e,0),0==Q.areas(e)&&Q.setFlags(e,1);const te=new z;te.setPolyMeshCreateParams(Q),te.setPolyMeshDetailCreateParams(ee),te.setWalkableHeight(X.walkableHeight),te.setWalkableRadius(X.walkableRadius),te.setWalkableClimb(X.walkableClimb),te.setCellSize(X.cs),te.setCellHeight(X.ch),te.setBuildBvTree(!0),E.offMeshConnections&&te.setOffMeshConnections(E.offMeshConnections);const ie=v(te);if(!ie.success)return P("Failed to create Detour navmesh data");const{navMeshData:ae}=ie;return L.initSolo(ae)?{success:!0,navMesh:L,intermediates:F}:P("Failed to create Detour navmesh")},j={...e,tileSize:32,expectedLayersPerTile:4,maxObstacles:128},q=()=>new E(((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,x={type:"tilecache",buildContext:y,chunkyTriMesh:void 0,tileIntermediates:[]},p=new H,A=new a,k=()=>{if(!C)for(let e=0;e<x.tileIntermediates.length;e++){const t=x.tileIntermediates[e];t.heightfield&&(f(t.heightfield),t.heightfield=void 0),t.compactHeightfield&&(T(t.compactHeightfield),t.compactHeightfield=void 0),t.heightfieldLayerSet&&(O(t.heightfieldLayerSet),t.heightfieldLayerSet=void 0)}},_=e=>(k(),p.destroy(),A.destroy(),{success:!1,navMesh:void 0,tileCache:void 0,intermediates:x,error:e}),z=e,v=w.length,E=new l.VertsArray;E.copy(z,z.length);const P=w,U=w.length/3,Z=new l.TrisArray;Z.copy(P,P.length);const{bbMin:J,bbMax:Q}=K(e,w),{expectedLayersPerTile:ee,maxObstacles:te,...ie}={...j,...M},ae=r(ie),le=s(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=D.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 R.RecastLinearAllocator(32e3),he=new R.RecastFastLZCompressor,ce=M.tileCacheMeshProcess??q();if(!p.init(ne,de,he,ce))return _("Failed to initialize tile cache");const me=t.fromArray(J);let ge=Math.min(Math.floor(X(Y(se*oe*ee))),14);ge>14&&(ge=14);const ue=1<<ge,be=1<<22-ge,fe=F.create({orig:me,tileWidth:ae.tileSize*ae.cs,tileHeight:ae.tileSize*ae.cs,maxTiles:ue,maxPolys:be});if(!A.initTiled(fe))return _("Failed to initialize tiled navmesh");const Se=new L;if(x.chunkyTriMesh=Se,!Se.init(E,Z,U,256))return _("Failed to build chunky triangle mesh");const we=(e,t)=>{const i={tileX:e,tileY:t},a=ae.tileSize*ae.cs,r=I(ae),s=[J[0]+e*a,J[1],J[2]+t*a],w=[J[0]+(e+1)*a,Q[1],J[2]+(t+1)*a];s[0]-=r.borderSize*r.cs,s[2]-=r.borderSize*r.cs,w[0]+=r.borderSize*r.cs,w[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,w[0]),r.set_bmax(1,w[1]),r.set_bmax(2,w[2]);const M=o();if(i.heightfield=M,!n(y,M,r.width,r.height,s,w,r.cs,r.ch))return{n:0};const p=[s[0],s[2]],A=[w[0],w[2]],k=new l.ChunkIdsArray;k.resize(512);const _=Se.getChunksOverlappingRect(p,A,k,512);if(0===_)return{n:0};for(let e=0;e<_;++e){const t=k.get_data(e),i=Se.nodes(t).n,a=Se.getNodeTris(t),s=new l.TriAreasArray;s.resize(i),d(y,r.walkableSlopeAngle,E,v,a,i,s);const o=h(y,E,v,a,s,i,M,r.walkableClimb);if(s.free(),!o)return{n:0}}c(y,ae.walkableClimb,M),m(y,ae.walkableHeight,ae.walkableClimb,M),g(y,ae.walkableHeight,M);const z=u();if(!b(y,ae.walkableHeight,ae.walkableClimb,M,z))return{n:0};if(C||(f(i.heightfield),i.heightfield=void 0),!S(y,ae.walkableRadius,z))return{n:0};const H=G();if(!N(y,z,ae.borderSize,ae.walkableHeight,H))return{n:0};C||(T(z),i.compactHeightfield=void 0);const D=[];for(let i=0;i<H.nlayers();i++){const a=new l.TileCacheData,r=H.layers(i),s=new R.dtTileCacheLayerHeader;s.magic=R.Detour.TILECACHE_MAGIC,s.version=R.Detour.TILECACHE_VERSION,s.tx=e,s.ty=t,s.tlayer=i;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=$(r),h=W(r),c=B(r),m=V(he,s,d,h,c,a);if(R.Detour.statusFailed(m))return{n:0};D.push(a)}return C||(O(H),i.heightfieldLayerSet=void 0),x.tileIntermediates.push(i),{n:D.length,tiles:D}};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=p.addTile(i);R.Detour.statusFailed(r.status)&&y.log(R.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=p.buildNavMeshTilesAt(t,e,A);if(R.Detour.statusFailed(i))return _(`Failed to build nav mesh tiles at ${t}, ${e}`)}return k(),{success:!0,tileCache:p,navMesh:A,intermediates:x}},Q={...e},ee=(e,E,H={},D=!1)=>{const O=new i,G={type:"tiled",buildContext:O,chunkyTriMesh:void 0,tileIntermediates:[]},N=new a,$=()=>{if(!D){for(let e=0;e<G.tileIntermediates.length;e++){const t=G.tileIntermediates[e];t.compactHeightfield&&T(t.compactHeightfield),t.heightfield&&f(t.heightfield),t.contourSet&&_(t.contourSet)}G.chunkyTriMesh&&(G.chunkyTriMesh=void 0)}},W=e=>($(),N.destroy(),{success:!1,navMesh:void 0,intermediates:G,error:e}),B=r({...Q,...H}),{bbMin:V,bbMax:U}=K(e,E),Z=s(V,U,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=E.length,ae=new l.VertsArray;ae.copy(te,te.length);const le=E,re=E.length/3,se=new l.TrisArray;se.copy(le,le.length);const oe=t.fromArray(V);let ne=Math.min(Math.floor(X(Y(q*J))),14);ne>14&&(ne=14);const de=1<<ne,he=1<<22-ne,ce=F.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=>(O.log(R.Module.RC_LOG_ERROR,e),{success:!1,error:e}),s={tileX:e,tileY:t};G.tileIntermediates.push(s);const E=I(B),F=[...i],L=[...a];F[0]-=E.borderSize*E.cs,F[2]-=E.borderSize*E.cs,L[0]+=E.borderSize*E.cs,L[2]+=E.borderSize*E.cs,E.set_bmin(0,F[0]),E.set_bmin(1,F[1]),E.set_bmin(2,F[2]),E.set_bmax(0,L[0]),E.set_bmax(1,L[1]),E.set_bmax(2,L[2]),O.resetTimers(),O.startTimer(R.Module.RC_TIMER_TOTAL),O.log(R.Module.RC_LOG_PROGRESS,`Building tile ${G.tileIntermediates.length} at x: ${e}, y: ${t}`),O.log(R.Module.RC_LOG_PROGRESS,` - ${B.width} x ${B.height} cells`),O.log(R.Module.RC_LOG_PROGRESS,` - ${ie/1e3}fK verts, ${re/1e3}K tris`);const P=o();if(s.heightfield=P,!n(O,P,E.width,E.height,F,L,E.cs,E.ch))return r("Could not create heightfield");(new l.TriAreasArray).resize(me.maxTrisPerChunk());const N=[F[0],F[2]],$=[L[0],L[2]],W=new l.ChunkIdsArray;W.resize(512);const V=me.getChunksOverlappingRect(N,$,W,512);if(0===V)return{success:!0};for(let e=0;e<V;++e){const t=W.get_data(e),i=me.nodes(t).n,a=me.getNodeTris(t),s=new l.TriAreasArray;s.resize(i),d(O,E.walkableSlopeAngle,ae,ie,a,i,s);const o=h(O,ae,ie,a,s,i,P,E.walkableClimb);if(s.free(),!o)return r("Could not rasterize triangles")}c(O,E.walkableClimb,P),m(O,E.walkableHeight,E.walkableClimb,P),g(O,E.walkableHeight,P);const K=u();if(s.compactHeightfield=K,!b(O,E.walkableHeight,E.walkableClimb,P,K))return r("Could not build compact heightfield");if(D||(f(s.heightfield),s.heightfield=void 0),!S(O,E.walkableRadius,K))return r("Could not erode walkable area");if(!w(O,K))return r("Failed to build distance field");if(!M(O,K,E.borderSize,E.minRegionArea,E.mergeRegionArea))return r("Failed to build regions");const X=C();if(s.contourSet=X,!y(O,K,E.maxSimplificationError,E.maxEdgeLen,X,R.Module.RC_CONTOUR_TESS_WALL_EDGES))return r("Failed to create contours");const Y=x();if(!p(O,X,E.maxVertsPerPoly,Y))return r("Failed to triangulate contours");const U=A();if(!k(O,Y,K,E.detailSampleDist,E.detailSampleMaxError,U))return r("Failed to build detail mesh");D||(T(K),s.compactHeightfield=void 0,_(X),s.contourSet=void 0);for(let e=0;e<Y.npolys();e++)Y.areas(e)==R.Recast.WALKABLE_AREA&&Y.setAreas(e,0),0==Y.areas(e)&&Y.setFlags(e,1);const Z=new z;Z.setPolyMeshCreateParams(Y),Z.setPolyMeshDetailCreateParams(U),Z.setWalkableHeight(E.walkableHeight),Z.setWalkableRadius(E.walkableRadius),Z.setWalkableClimb(E.walkableClimb),Z.setCellSize(E.cs),Z.setCellHeight(E.ch),Z.setBuildBvTree(!0),H.offMeshConnections&&Z.setOffMeshConnections(H.offMeshConnections),Z.setTileX(e),Z.setTileY(t);const j=v(Z);return j.success?(O.log(R.Module.RC_LOG_PROGRESS,`>> Polymesh: ${Y.nverts()} vertices ${Y.npolys()} polygons`),{success:!0,data:j.navMeshData}):r("Failed to create Detour navmesh data")};O.startTimer(R.Module.RC_TIMER_TEMP);const ue=[0,0,0],be=[0,0,0];for(let e=0;e<J;e++)for(let t=0;t<q;t++){ue[0]=V[0]+t*ee,ue[1]=V[1],ue[2]=V[2]+e*ee,be[0]=V[0]+(t+1)*ee,be[1]=U[1],be[2]=V[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,R.Module.DT_TILE_FREE_DATA,0);R.Detour.statusFailed(a.status)&&(O.log(R.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 O.stopTimer(R.Module.RC_TIMER_TEMP),D||$(),{success:!0,navMesh:N,intermediates:G}};export{q as createDefaultTileCacheMeshProcess,X as dtIlog2,Y as dtNextPow2,Z as generateSoloNavMesh,J as generateTileCache,ee as generateTiledNavMesh,K as getBoundingBox,U as soloNavMeshGeneratorConfigDefaults,j as tileCacheGeneratorConfigDefaults,Q as tiledNavMeshGeneratorConfigDefaults};
|
|
1
|
+
import{recastConfigDefaults as e,vec3 as t,RecastBuildContext as i,NavMesh as a,Arrays as l,createRcConfig as r,calcGridSize 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,Raw as R,allocPolyMesh as x,buildPolyMesh as p,allocPolyMeshDetail as A,buildPolyMeshDetail as k,freeCompactHeightfield as T,freeContourSet as _,NavMeshCreateParams as z,createNavMeshData as v,TileCacheMeshProcess as E,TileCache as H,DetourTileCacheParams as D,NavMeshParams as F,RecastChunkyTriMesh as L,statusToReadableString as P,freeHeightfieldLayerSet as O,cloneRcConfig as I,allocHeightfieldLayerSet as G,buildHeightfieldLayers as N,getHeightfieldLayerHeights as $,getHeightfieldLayerAreas as W,getHeightfieldLayerCons as B,buildTileCacheLayer as V}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)}},X=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},Y=e=>(e--,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e),U={...e},Z=(e,t,E={},H=!1)=>{const D=new i,F={type:"solo",buildContext:D},L=new a,P=e=>(H||(F.heightfield&&(f(F.heightfield),F.heightfield=void 0),F.compactHeightfield&&(T(F.compactHeightfield),F.compactHeightfield=void 0),F.contourSet&&(_(F.contourSet),F.contourSet=void 0)),L.destroy(),{navMesh:void 0,success:!1,intermediates:F,error:e}),O=e,I=t.length,G=new l.VertsArray;G.copy(O,O.length);const N=t,$=t.length/3,W=new l.TrisArray;W.copy(N,N.length);const{bbMin:B,bbMax:V}=K(e,t),X=r({...U,...E});X.minRegionArea=X.minRegionArea*X.minRegionArea,X.mergeRegionArea=X.mergeRegionArea*X.mergeRegionArea,X.detailSampleDist=X.detailSampleDist<.9?0:X.cs*X.detailSampleDist,X.detailSampleMaxError=X.ch*X.detailSampleMaxError;const Y=s(B,V,X.cs);X.width=Y.width,X.height=Y.height;const Z=o();if(F.heightfield=Z,!n(D,Z,X.width,X.height,B,V,X.cs,X.ch))return P("Could not create heightfield");const j=new l.TriAreasArray;if(j.resize($),d(D,X.walkableSlopeAngle,G,I,W,$,j),!h(D,G,I,W,j,$,Z,X.walkableClimb))return P("Could not rasterize triangles");j.free(),c(D,X.walkableClimb,Z),m(D,X.walkableHeight,X.walkableClimb,Z),g(D,X.walkableHeight,Z);const q=u();if(F.compactHeightfield=q,!b(D,X.walkableHeight,X.walkableClimb,Z,q))return P("Failed to build compact data");if(H||(f(Z),F.heightfield=void 0),!S(D,X.walkableRadius,q))return P("Failed to erode walkable area");if(!w(D,q))return P("Failed to build distance field");if(!M(D,q,X.borderSize,X.minRegionArea,X.mergeRegionArea))return P("Failed to build regions");const J=C();if(F.contourSet=J,!y(D,q,X.maxSimplificationError,X.maxEdgeLen,J,R.Module.RC_CONTOUR_TESS_WALL_EDGES))return P("Failed to create contours");const Q=x();if(!p(D,J,X.maxVertsPerPoly,Q))return P("Failed to triangulate contours");const ee=A();if(!k(D,Q,q,X.detailSampleDist,X.detailSampleMaxError,ee))return P("Failed to build detail mesh");H||(T(q),F.compactHeightfield=void 0,_(J),F.contourSet=void 0);for(let e=0;e<Q.npolys();e++)Q.areas(e)==R.Recast.WALKABLE_AREA&&Q.setAreas(e,0),0==Q.areas(e)&&Q.setFlags(e,1);const te=new z;te.setPolyMeshCreateParams(Q),te.setPolyMeshDetailCreateParams(ee),te.setWalkableHeight(X.walkableHeight),te.setWalkableRadius(X.walkableRadius),te.setWalkableClimb(X.walkableClimb),te.setCellSize(X.cs),te.setCellHeight(X.ch),te.setBuildBvTree(!0),E.offMeshConnections&&te.setOffMeshConnections(E.offMeshConnections);const ie=v(te);if(!ie.success)return P("Failed to create Detour navmesh data");const{navMeshData:ae}=ie;return L.initSolo(ae)?{success:!0,navMesh:L,intermediates:F}:P("Failed to create Detour navmesh")},j={...e,tileSize:32,expectedLayersPerTile:4,maxObstacles:128},q=()=>new E(((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,x={type:"tilecache",buildContext:y,chunkyTriMesh:void 0,tileIntermediates:[]},p=new H,A=new a,k=()=>{if(!C)for(let e=0;e<x.tileIntermediates.length;e++){const t=x.tileIntermediates[e];t.heightfield&&(f(t.heightfield),t.heightfield=void 0),t.compactHeightfield&&(T(t.compactHeightfield),t.compactHeightfield=void 0),t.heightfieldLayerSet&&(O(t.heightfieldLayerSet),t.heightfieldLayerSet=void 0)}},_=e=>(k(),p.destroy(),A.destroy(),{success:!1,navMesh:void 0,tileCache:void 0,intermediates:x,error:e}),z=e,v=w.length,E=new l.VertsArray;E.copy(z,z.length);const P=w,U=w.length/3,Z=new l.TrisArray;Z.copy(P,P.length);const{bbMin:J,bbMax:Q}=K(e,w),{expectedLayersPerTile:ee,maxObstacles:te,...ie}={...j,...M},ae=r(ie),le=s(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=D.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 R.RecastLinearAllocator(32e3),he=new R.RecastFastLZCompressor,ce=M.tileCacheMeshProcess??q();if(!p.init(ne,de,he,ce))return _("Failed to initialize tile cache");const me=t.fromArray(J);let ge=Math.min(Math.floor(X(Y(se*oe*ee))),14);ge>14&&(ge=14);const ue=1<<ge,be=1<<22-ge,fe=F.create({orig:me,tileWidth:ae.tileSize*ae.cs,tileHeight:ae.tileSize*ae.cs,maxTiles:ue,maxPolys:be});if(!A.initTiled(fe))return _("Failed to initialize tiled navmesh");const Se=new L;if(x.chunkyTriMesh=Se,!Se.init(E,Z,U,256))return _("Failed to build chunky triangle mesh");const we=(e,t)=>{const i={tileX:e,tileY:t},a=ae.tileSize*ae.cs,r=I(ae),s=[J[0]+e*a,J[1],J[2]+t*a],w=[J[0]+(e+1)*a,Q[1],J[2]+(t+1)*a];s[0]-=r.borderSize*r.cs,s[2]-=r.borderSize*r.cs,w[0]+=r.borderSize*r.cs,w[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,w[0]),r.set_bmax(1,w[1]),r.set_bmax(2,w[2]);const M=o();if(i.heightfield=M,!n(y,M,r.width,r.height,s,w,r.cs,r.ch))return{n:0};const p=[s[0],s[2]],A=[w[0],w[2]],k=new l.ChunkIdsArray;k.resize(512);const _=Se.getChunksOverlappingRect(p,A,k,512);if(0===_)return{n:0};for(let e=0;e<_;++e){const t=k.get_data(e),i=Se.nodes(t).n,a=Se.getNodeTris(t),s=new l.TriAreasArray;s.resize(i),d(y,r.walkableSlopeAngle,E,v,a,i,s);const o=h(y,E,v,a,s,i,M,r.walkableClimb);if(s.free(),!o)return{n:0}}c(y,ae.walkableClimb,M),m(y,ae.walkableHeight,ae.walkableClimb,M),g(y,ae.walkableHeight,M);const z=u();if(!b(y,ae.walkableHeight,ae.walkableClimb,M,z))return{n:0};if(C||(f(i.heightfield),i.heightfield=void 0),!S(y,ae.walkableRadius,z))return{n:0};const H=G();if(!N(y,z,ae.borderSize,ae.walkableHeight,H))return{n:0};C||(T(z),i.compactHeightfield=void 0);const D=[];for(let i=0;i<H.nlayers();i++){const a=new l.TileCacheData,r=H.layers(i),s=new R.dtTileCacheLayerHeader;s.magic=R.Detour.TILECACHE_MAGIC,s.version=R.Detour.TILECACHE_VERSION,s.tx=e,s.ty=t,s.tlayer=i;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=$(r),h=W(r),c=B(r),m=V(he,s,d,h,c,a);if(R.Detour.statusFailed(m))return{n:0};D.push(a)}return C||(O(H),i.heightfieldLayerSet=void 0),x.tileIntermediates.push(i),{n:D.length,tiles:D}};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=p.addTile(i);R.Detour.statusFailed(r.status)&&y.log(R.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=p.buildNavMeshTilesAt(t,e,A);if(R.Detour.statusFailed(i))return _(`Failed to build nav mesh tiles at ${t}, ${e}`)}return k(),{success:!0,tileCache:p,navMesh:A,intermediates:x}},Q={...e},ee=(e,E,H={},D=!1)=>{const O=new i,G={type:"tiled",buildContext:O,chunkyTriMesh:void 0,tileIntermediates:[]},N=new a,$=()=>{if(!D){for(let e=0;e<G.tileIntermediates.length;e++){const t=G.tileIntermediates[e];t.compactHeightfield&&T(t.compactHeightfield),t.heightfield&&f(t.heightfield),t.contourSet&&_(t.contourSet)}G.chunkyTriMesh&&(G.chunkyTriMesh=void 0)}},W=e=>($(),N.destroy(),{success:!1,navMesh:void 0,intermediates:G,error:e}),B=r({...Q,...H}),{bbMin:V,bbMax:U}=K(e,E),Z=s(V,U,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=E.length,ae=new l.VertsArray;ae.copy(te,te.length);const le=E,re=E.length/3,se=new l.TrisArray;se.copy(le,le.length);const oe=t.fromArray(V);let ne=Math.min(Math.floor(X(Y(q*J))),14);ne>14&&(ne=14);const de=1<<ne,he=1<<22-ne,ce=F.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=>(O.log(R.Module.RC_LOG_ERROR,e),{success:!1,error:e}),s={tileX:e,tileY:t};G.tileIntermediates.push(s);const E=I(B),F=[...i],L=[...a];F[0]-=E.borderSize*E.cs,F[2]-=E.borderSize*E.cs,L[0]+=E.borderSize*E.cs,L[2]+=E.borderSize*E.cs,E.set_bmin(0,F[0]),E.set_bmin(1,F[1]),E.set_bmin(2,F[2]),E.set_bmax(0,L[0]),E.set_bmax(1,L[1]),E.set_bmax(2,L[2]),O.resetTimers(),O.startTimer(R.Module.RC_TIMER_TOTAL),O.log(R.Module.RC_LOG_PROGRESS,`Building tile ${G.tileIntermediates.length} at x: ${e}, y: ${t}`),O.log(R.Module.RC_LOG_PROGRESS,` - ${B.width} x ${B.height} cells`),O.log(R.Module.RC_LOG_PROGRESS,` - ${ie/1e3}fK verts, ${re/1e3}K tris`);const P=o();if(s.heightfield=P,!n(O,P,E.width,E.height,F,L,E.cs,E.ch))return r("Could not create heightfield");(new l.TriAreasArray).resize(me.maxTrisPerChunk());const N=[F[0],F[2]],$=[L[0],L[2]],W=new l.ChunkIdsArray;W.resize(512);const V=me.getChunksOverlappingRect(N,$,W,512);if(0===V)return{success:!0};for(let e=0;e<V;++e){const t=W.get_data(e),i=me.nodes(t).n,a=me.getNodeTris(t),s=new l.TriAreasArray;s.resize(i),d(O,E.walkableSlopeAngle,ae,ie,a,i,s);const o=h(O,ae,ie,a,s,i,P,E.walkableClimb);if(s.free(),!o)return r("Could not rasterize triangles")}c(O,E.walkableClimb,P),m(O,E.walkableHeight,E.walkableClimb,P),g(O,E.walkableHeight,P);const K=u();if(s.compactHeightfield=K,!b(O,E.walkableHeight,E.walkableClimb,P,K))return r("Could not build compact heightfield");if(D||(f(s.heightfield),s.heightfield=void 0),!S(O,E.walkableRadius,K))return r("Could not erode walkable area");if(!w(O,K))return r("Failed to build distance field");if(!M(O,K,E.borderSize,E.minRegionArea,E.mergeRegionArea))return r("Failed to build regions");const X=C();if(s.contourSet=X,!y(O,K,E.maxSimplificationError,E.maxEdgeLen,X,R.Module.RC_CONTOUR_TESS_WALL_EDGES))return r("Failed to create contours");const Y=x();if(!p(O,X,E.maxVertsPerPoly,Y))return r("Failed to triangulate contours");const U=A();if(!k(O,Y,K,E.detailSampleDist,E.detailSampleMaxError,U))return r("Failed to build detail mesh");D||(T(K),s.compactHeightfield=void 0,_(X),s.contourSet=void 0);for(let e=0;e<Y.npolys();e++)Y.areas(e)==R.Recast.WALKABLE_AREA&&Y.setAreas(e,0),0==Y.areas(e)&&Y.setFlags(e,1);const Z=new z;Z.setPolyMeshCreateParams(Y),Z.setPolyMeshDetailCreateParams(U),Z.setWalkableHeight(E.walkableHeight),Z.setWalkableRadius(E.walkableRadius),Z.setWalkableClimb(E.walkableClimb),Z.setCellSize(E.cs),Z.setCellHeight(E.ch),Z.setBuildBvTree(!0),H.offMeshConnections&&Z.setOffMeshConnections(H.offMeshConnections),Z.setTileX(e),Z.setTileY(t);const j=v(Z);return j.success?(O.log(R.Module.RC_LOG_PROGRESS,`>> Polymesh: ${Y.nverts()} vertices ${Y.npolys()} polygons`),{success:!0,data:j.navMeshData}):r("Failed to create Detour navmesh data")};O.startTimer(R.Module.RC_TIMER_TEMP);const ue=[0,0,0],be=[0,0,0];for(let e=0;e<J;e++)for(let t=0;t<q;t++){ue[0]=V[0]+t*ee,ue[1]=V[1],ue[2]=V[2]+e*ee,be[0]=V[0]+(t+1)*ee,be[1]=U[1],be[2]=V[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,R.Module.DT_TILE_FREE_DATA,0);R.Detour.statusFailed(a.status)&&(O.log(R.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 O.stopTimer(R.Module.RC_TIMER_TEMP),D||$(),{success:!0,navMesh:N,intermediates:G}};export{q as createDefaultTileCacheMeshProcess,X as dtIlog2,Y as dtNextPow2,Z as generateSoloNavMesh,J as generateTileCache,ee as generateTiledNavMesh,K as getBoundingBox,U as soloNavMeshGeneratorConfigDefaults,j as tileCacheGeneratorConfigDefaults,Q as tiledNavMeshGeneratorConfigDefaults};
|
|
2
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.
|
|
21
|
+
"version": "0.21.0",
|
|
22
22
|
"license": "MIT",
|
|
23
23
|
"homepage": "https://github.com/isaac-mason/recast-navigation-js",
|
|
24
24
|
"bugs": {
|
|
@@ -66,12 +66,12 @@
|
|
|
66
66
|
"lint": "eslint --ext .ts src"
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
|
-
"@recast-navigation/core": "0.
|
|
70
|
-
"@recast-navigation/generators": "0.
|
|
71
|
-
"@recast-navigation/three": "0.
|
|
69
|
+
"@recast-navigation/core": "0.21.0",
|
|
70
|
+
"@recast-navigation/generators": "0.21.0",
|
|
71
|
+
"@recast-navigation/three": "0.21.0"
|
|
72
72
|
},
|
|
73
73
|
"devDependencies": {
|
|
74
|
-
"@babel/core": "^7.
|
|
74
|
+
"@babel/core": "^7.24.4",
|
|
75
75
|
"@isaac-mason/eslint-config-typescript": "^0.0.5",
|
|
76
76
|
"@mdx-js/react": "^2.3.0",
|
|
77
77
|
"@pmndrs/assets": "^1.6.0",
|
|
@@ -103,7 +103,8 @@
|
|
|
103
103
|
"three": "^0.160.0",
|
|
104
104
|
"three-pathfinding": "^1.2.0",
|
|
105
105
|
"typescript": "^5.4.3",
|
|
106
|
-
"vitest": "^1.
|
|
106
|
+
"vitest": "^1.5.0",
|
|
107
|
+
"zustand": "^4.5.2"
|
|
107
108
|
},
|
|
108
109
|
"packageManager": "yarn@3.2.2"
|
|
109
110
|
}
|