@recast-navigation/three 0.6.0 → 0.7.1

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
@@ -15,68 +15,103 @@ Three.js glue for [`recast-navigation`](https://github.com/isaac-mason/recast-na
15
15
  To use the three.js glue, you can either use the `three` entrypoint in `recast-navigation`:
16
16
 
17
17
  ```ts
18
- import * as RecastNavigationThree from 'recast-navigation/three';
18
+ import { ... } from 'recast-navigation/three';
19
19
  ```
20
20
 
21
21
  Or you can use this package directly:
22
22
 
23
23
  ```ts
24
- import * as RecastNavigationThree from '@recast-navigation/three';
24
+ import { ... } from '@recast-navigation/three';
25
25
  ```
26
26
 
27
- ### `threeToSoloNavMesh` and `threeToTiledNavMesh`
27
+ ### Generating a NavMesh
28
28
 
29
- This package exports functions that convert arrays of `Mesh` objects to a solo or tiled navmesh.
29
+ This package provides convenience functions for generating nav meshes from THREE.Mesh objects.
30
30
 
31
31
  ```ts
32
+ import { threeToSoloNavMesh, threeToTiledNavMesh, threeToTileCache } from 'recast-navigation/three';
32
33
  import * as THREE from 'three';
33
- import { NavMesh } from 'recast-navigation';
34
- import { threeToSoloNavMesh, threeToTiledNavMesh } from 'recast-navigation/three';
35
34
 
36
35
  const scene = new THREE.Scene();
37
36
 
38
37
  /* add meshes to the scene */
39
38
  // ...
40
39
 
41
- const meshes: Mesh[] = [];
40
+ const meshes: THREE.Mesh[] = [];
42
41
 
43
42
  scene.traverse((child) => {
44
- if (child instanceof Mesh) {
43
+ if (child instanceof THREE.Mesh) {
45
44
  meshes.push(child);
46
45
  }
47
46
  });
48
47
 
49
48
  /* solo navmesh */
50
- const { navMesh }: NavMesh = threeToSoloNavMesh(meshes, { /* navmesh config */ }});
49
+ const { navMesh } = threeToSoloNavMesh(meshes, {
50
+ // ... nav mesh generation config ...
51
+ }});
51
52
 
52
53
  /* tiled navmesh */
53
- const { navMesh, tileCache } = threeToTiledNavMesh(meshes, { tileSize: 16 }});
54
+ const { navMesh } = threeToTiledNavMesh(meshes, {
55
+ tileSize: 16,
56
+ // ... nav mesh generation config ...
57
+ }});
58
+
59
+ /* tile cache with support for temporary obstacles */
60
+ const { navMesh, tileCache } = threeToTileCache(meshes, {
61
+ tileSize: 16,
62
+ // ... nav mesh generation config ...
63
+ }});
54
64
  ```
55
65
 
56
- ### `NavMeshHelper`, `TileCacheHelper`, `CrowdHelper`
66
+ ### Helpers
67
+
68
+ This package provides helpers for visualizing various recast-navigation objects in three.js.
69
+
70
+ #### `NavMeshHelper`
57
71
 
58
72
  ```ts
59
- import {
60
- CrowdHelper,
61
- NavMeshHelper,
62
- TileCacheHelper,
63
- } from 'recast-navigation/three';
73
+ import { NavMeshHelper } from 'recast-navigation/three';
64
74
 
65
75
  const navMeshHelper = new NavMeshHelper({ navMesh });
66
- const tileCacheHelper = new TileCacheHelper({ tileCache });
67
- const crowdHelper = new CrowdHelper({ crowd });
68
-
69
- const scene = new THREE.Scene();
70
76
 
71
77
  scene.add(navMeshHelper);
72
- scene.add(tileCacheHelper);
73
- scene.add(crowdHelper);
74
78
 
79
+ // update the helper when the navmesh changes
75
80
  navMeshHelper.update();
81
+ ```
82
+
83
+ #### `TileCacheHelper`
84
+
85
+ Visualises obstacles in a `TileCache`.
86
+
87
+ ```ts
88
+ import { TileCacheHelper } from 'recast-navigation/three';
89
+
90
+ const tileCacheHelper = new TileCacheHelper({ tileCache });
91
+
92
+ scene.add(tileCacheHelper);
93
+
94
+ // update the helper after adding or removing obstacles
76
95
  tileCacheHelper.update();
96
+ ```
97
+
98
+ #### `CrowdHelper`
99
+
100
+ Visualises agents in a `Crowd`.
101
+
102
+ ```ts
103
+ import { CrowdHelper } from 'recast-navigation/three';
104
+
105
+ const crowdHelper = new CrowdHelper({ crowd });
106
+
107
+ scene.add(crowdHelper);
108
+
109
+ // update the helper after updating the crowd
77
110
  crowdHelper.update();
78
111
  ```
79
112
 
113
+ #### Custom Materials
114
+
80
115
  You can optionally provide custom materials to the helpers.
81
116
 
82
117
  ```ts
package/dist/index.es.js CHANGED
@@ -1,2 +1,2 @@
1
- import{Object3D as e,MeshBasicMaterial as t,Vector3 as s,CapsuleGeometry as o,Mesh as a,Matrix4 as i,Color as r,BoxGeometry as n,InstancedMesh as h,DynamicDrawUsage as l,BufferGeometry as c,BufferAttribute as g,CylinderGeometry as d}from"three";import{generateSoloNavMesh as p,generateTiledNavMesh as w}from"@recast-navigation/core";class f extends e{agentMeshes=new Map;recastCrowd;agentMaterial;constructor({crowd:e,agentMaterial:s}){super(),this.recastCrowd=e,this.agentMaterial=s??new t({color:"red"}),this.update()}update(){const e=this.recastCrowd.getAgents(),t=new Set(this.agentMeshes.keys());for(const o of e){t.delete(o);const e=this.recastCrowd.getAgentPosition(o),a=this.recastCrowd.getAgentVelocity(o),i=this.recastCrowd.getAgentParameters(o);let r=this.agentMeshes.get(o);void 0===r&&(r=this.createAgentMesh(i),this.add(r),this.agentMeshes.set(o,r)),r.position.set(e.x,e.y+i.height/2,e.z),r.lookAt((new s).copy(r.position).add(a))}for(const e of t){const t=this.agentMeshes.get(e);t&&(this.remove(t),this.agentMeshes.delete(e))}}createAgentMesh(e){const t=new o(e.radius,e.height-2*e.radius);return new a(t,this.agentMaterial)}}const m=new i;class u extends e{heightfields;highlightWalkable;defaultColor;walkableColor;material;constructor({heightfields:e,highlightWalkable:s=!1,material:o=new t,defaultColor:a="blue",walkableColor:i="green"}){super(),this.heightfields=e,this.highlightWalkable=s,this.material=o,this.defaultColor=new r(a),this.walkableColor=new r(i),this.update()}update(){this.clear();for(const e of this.heightfields){const t=e.bmin(),s=e.cs(),o=e.ch(),a=e.width(),i=e.height(),r=[];for(let n=0;n<i;++n)for(let i=0;i<a;++i){const h=t.x+i*s,l=t.z+n*s;let c=e.spans(i+n*a);for(;c;){const e=h,a=t.y+c.smin()*o,i=l,n=h+s,g=t.y+c.smax()*o,d=l+s;r.push({position:[(n+e)/2,(g+a)/2,(d+i)/2],walkable:this.highlightWalkable&&0!==c.area()}),c=c.next()}}const c=new n(s,o,s),g=new h(c,this.material,r.length);g.instanceMatrix.setUsage(l);for(let e=0;e<r.length;e++){const{position:t,walkable:s}=r[e];g.setMatrixAt(e,m.setPosition(...t)),g.setColorAt(e,s?this.walkableColor:this.defaultColor)}g.instanceMatrix.needsUpdate=!0,g.instanceColor&&(g.instanceColor.needsUpdate=!0),this.add(g)}}}class M extends e{navMesh;navMeshMaterial;mesh;geometry;constructor({navMesh:e,navMeshMaterial:s}){super(),this.navMesh=e,this.navMeshMaterial=s||new t({color:"orange",transparent:!0,opacity:.7}),this.geometry=new c,this.update(),this.mesh=new a(this.geometry,this.navMeshMaterial),this.add(this.mesh)}update(){const[e,t]=this.navMesh.getDebugNavMesh();this.geometry.setAttribute("position",new g(Float32Array.from(e),3)),this.geometry.setIndex(new g(Uint32Array.from(t),1)),this.geometry.computeVertexNormals()}}class y extends e{tileCache;obstacleMeshes=new Map;obstacleMaterial;constructor({tileCache:e,obstacleMaterial:s}){super(),this.tileCache=e,this.obstacleMaterial=s||new t({color:"red",wireframe:!0,wireframeLinewidth:2}),this.update()}update(){const e=new Set(this.obstacleMeshes.keys());for(const[,t]of this.tileCache.obstacles){let s=this.obstacleMeshes.get(t);if(e.delete(t),!s){const{position:e}=t,s=new a(void 0,this.obstacleMaterial);if(s.position.copy(e),"box"===t.type){const{extent:e,angle:o}=t;s.geometry=new n(2*e.x,2*e.y,2*e.z),s.rotation.y=o}else{if("cylinder"!==t.type)throw new Error(`Unknown obstacle type: ${t}`);{const{radius:e,height:o}=t;s.geometry=new d(e,e,o,16),s.position.y+=o/2}}this.add(s),this.obstacleMeshes.set(t,s)}}for(const t of e){const e=this.obstacleMeshes.get(t);e&&(this.remove(e),this.obstacleMeshes.delete(t))}}}const b=new s,x=e=>{const t=[];for(const s of e){const e=s.geometry.attributes.position;if(!e||3!==e.itemSize)continue;let o=s,a=s.geometry.getIndex()?.array;if(!a){o=o.clone(),o.geometry=s.geometry.clone();const t=[];for(let s=0;s<e.count;s++)t.push(s);o.geometry.setIndex(t)}t.push(o)}const s=[],o=[],a={};let i=0;for(const e of t){e.updateMatrixWorld();const t=e.geometry.attributes.position.array,r=e.geometry.getIndex().array;for(let n=0;n<r.length;n++){const h=3*r[n],l=b.set(t[h],t[h+1],t[h+2]);e.localToWorld(l);const c=`${l.x}_${l.y}_${l.z}`;let g=a[c];g||(a[c]=g=i,s.push(l.x,l.y,l.z),i++),o.push(g)}}return[Float32Array.from(s),Uint32Array.from(o)]},C=(e,t={},s=!1)=>{const[o,a]=x(e);return p(o,a,t,s)},k=(e,t={},s=!1)=>{const[o,a]=x(e);return w(o,a,t,s)};export{f as CrowdHelper,u as HeightfieldHelper,M as NavMeshHelper,y as TileCacheHelper,x as getPositionsAndIndices,C as threeToSoloNavMesh,k as threeToTiledNavMesh};
1
+ import{Object3D as e,MeshBasicMaterial as t,Vector3 as s,CapsuleGeometry as o,Mesh as a,Matrix4 as i,Color as n,BoxGeometry as r,InstancedMesh as h,DynamicDrawUsage as l,BufferGeometry as c,BufferAttribute as g,CylinderGeometry as d}from"three";import{generateSoloNavMesh as p,generateTiledNavMesh as u,generateTileCache as f}from"@recast-navigation/core";class m extends e{agentMeshes=new Map;recastCrowd;agentMaterial;constructor({crowd:e,agentMaterial:s}){super(),this.recastCrowd=e,this.agentMaterial=s??new t({color:"red"}),this.update()}update(){const e=this.recastCrowd.getAgents(),t=new Set(this.agentMeshes.keys());for(const o of e){t.delete(o.agentIndex);const e=o.position(),a=o.velocity(),i=o.parameters();let n=this.agentMeshes.get(o.agentIndex);void 0===n&&(n=this.createAgentMesh(i),this.add(n),this.agentMeshes.set(o.agentIndex,n)),n.position.set(e.x,e.y+i.height/2,e.z),n.lookAt((new s).copy(n.position).add(a))}for(const e of t){const t=this.agentMeshes.get(e);t&&(this.remove(t),this.agentMeshes.delete(e))}}createAgentMesh(e){const t=new o(e.radius,e.height-2*e.radius);return new a(t,this.agentMaterial)}}const w=new i;class M extends e{heightfields;highlightWalkable;defaultColor;walkableColor;material;constructor({heightfields:e,highlightWalkable:s=!1,material:o=new t,defaultColor:a="blue",walkableColor:i="green"}){super(),this.heightfields=e,this.highlightWalkable=s,this.material=o,this.defaultColor=new n(a),this.walkableColor=new n(i),this.update()}update(){this.clear();for(const e of this.heightfields){const t=e.bmin(),s=e.cs(),o=e.ch(),a=e.width(),i=e.height(),n=[];for(let r=0;r<i;++r)for(let i=0;i<a;++i){const h=t.x+i*s,l=t.z+r*s;let c=e.spans(i+r*a);for(;c;){const e=h,a=t.y+c.smin()*o,i=l,r=h+s,g=t.y+c.smax()*o,d=l+s;n.push({position:[(r+e)/2,(g+a)/2,(d+i)/2],walkable:this.highlightWalkable&&0!==c.area()}),c=c.next()}}const c=new r(s,o,s),g=new h(c,this.material,n.length);g.instanceMatrix.setUsage(l);for(let e=0;e<n.length;e++){const{position:t,walkable:s}=n[e];g.setMatrixAt(e,w.setPosition(...t)),g.setColorAt(e,s?this.walkableColor:this.defaultColor)}g.instanceMatrix.needsUpdate=!0,g.instanceColor&&(g.instanceColor.needsUpdate=!0),this.add(g)}}}class y extends e{navMesh;navMeshMaterial;mesh;geometry;constructor({navMesh:e,navMeshMaterial:s}){super(),this.navMesh=e,this.geometry=new c,this.navMeshMaterial=s||new t({color:"orange",transparent:!0,opacity:.7}),this.update(),this.mesh=new a(this.geometry,this.navMeshMaterial),this.add(this.mesh)}update(){const[e,t]=this.navMesh.getDebugNavMesh();this.geometry.setAttribute("position",new g(Float32Array.from(e),3)),this.geometry.setIndex(new g(Uint32Array.from(t),1)),this.geometry.computeVertexNormals()}}class b extends e{tileCache;obstacleMeshes=new Map;obstacleMaterial;constructor({tileCache:e,obstacleMaterial:s}){super(),this.tileCache=e,this.obstacleMaterial=s||new t({color:"red",wireframe:!0,wireframeLinewidth:2}),this.update()}update(){const e=new Set(this.obstacleMeshes.keys());for(const[,t]of this.tileCache.obstacles){let s=this.obstacleMeshes.get(t);if(e.delete(t),!s){const{position:e}=t,s=new a(void 0,this.obstacleMaterial);if(s.position.copy(e),"box"===t.type){const{extent:e,angle:o}=t;s.geometry=new r(2*e.x,2*e.y,2*e.z),s.rotation.y=o}else{if("cylinder"!==t.type)throw new Error(`Unknown obstacle type: ${t}`);{const{radius:e,height:o}=t;s.geometry=new d(e,e,o,16),s.position.y+=o/2}}this.add(s),this.obstacleMeshes.set(t,s)}}for(const t of e){const e=this.obstacleMeshes.get(t);e&&(this.remove(e),this.obstacleMeshes.delete(t))}}}const x=new s,C=e=>{const t=[];for(const s of e){const e=s.geometry.attributes.position;if(!e||3!==e.itemSize)continue;let o=s,a=s.geometry.getIndex()?.array;if(!a){o=o.clone(),o.geometry=s.geometry.clone();const t=[];for(let s=0;s<e.count;s++)t.push(s);o.geometry.setIndex(t)}t.push(o)}const s=[],o=[],a={};let i=0;for(const e of t){e.updateMatrixWorld();const t=e.geometry.attributes.position.array,n=e.geometry.getIndex().array;for(let r=0;r<n.length;r++){const h=3*n[r],l=x.set(t[h],t[h+1],t[h+2]);e.localToWorld(l);const c=`${l.x}_${l.y}_${l.z}`;let g=a[c];g||(a[c]=g=i,s.push(l.x,l.y,l.z),i++),o.push(g)}}return[Float32Array.from(s),Uint32Array.from(o)]},v=(e,t={},s=!1)=>{const[o,a]=C(e);return p(o,a,t,s)},k=(e,t={},s=!1)=>{const[o,a]=C(e);return u(o,a,t,s)},A=(e,t={},s=!1)=>{const[o,a]=C(e);return f(o,a,t,s)};export{m as CrowdHelper,M as HeightfieldHelper,y as NavMeshHelper,b as TileCacheHelper,C as getPositionsAndIndices,v as threeToSoloNavMesh,A as threeToTileCache,k as threeToTiledNavMesh};
2
2
  //# sourceMappingURL=index.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../src/helpers/crowd-helper.ts","../src/helpers/heightfield-helper.ts","../src/helpers/nav-mesh-helper.ts","../src/helpers/tile-cache-helper.ts","../src/utils/three-to-nav-mesh.ts"],"sourcesContent":["import { Crowd, CrowdAgentParams } from '@recast-navigation/core';\nimport {\n CapsuleGeometry,\n Material,\n Mesh,\n MeshBasicMaterial,\n Object3D,\n Vector3\n} from 'three';\n\nexport type CrowdHelperParams = {\n crowd: Crowd;\n agentMaterial?: Material;\n};\n\nexport class CrowdHelper extends Object3D {\n agentMeshes: Map<number, Mesh> = new Map();\n\n recastCrowd: Crowd;\n\n agentMaterial: Material;\n\n constructor({ crowd, agentMaterial }: CrowdHelperParams) {\n super()\n\n this.recastCrowd = crowd;\n \n this.agentMaterial = agentMaterial ?? new MeshBasicMaterial({ color: 'red' });\n\n this.update();\n }\n\n /**\n * Update the three debug view of the crowd agents.\n * \n * This should be called after updating the crowd.\n */\n update() {\n const agentsIndices = this.recastCrowd.getAgents();\n\n const unseen = new Set(this.agentMeshes.keys());\n\n for (const i of agentsIndices) {\n unseen.delete(i);\n\n const position = this.recastCrowd.getAgentPosition(i);\n const velocity = this.recastCrowd.getAgentVelocity(i);\n const agentParams = this.recastCrowd.getAgentParameters(i);\n\n let agentMesh = this.agentMeshes.get(i);\n\n if (agentMesh === undefined) {\n agentMesh = this.createAgentMesh(agentParams);\n \n this.add(agentMesh);\n this.agentMeshes.set(i, agentMesh);\n }\n\n agentMesh.position.set(\n position.x,\n position.y + agentParams.height / 2,\n position.z\n );\n agentMesh.lookAt(\n new Vector3().copy(agentMesh.position).add(velocity as Vector3)\n ); \n }\n\n for (const agentId of unseen) {\n const agentMesh = this.agentMeshes.get(agentId);\n\n if (agentMesh) {\n this.remove(agentMesh);\n this.agentMeshes.delete(agentId);\n }\n }\n }\n\n private createAgentMesh(agentParams: CrowdAgentParams): Mesh {\n const geometry = new CapsuleGeometry(\n agentParams.radius,\n agentParams.height - agentParams.radius * 2\n );\n\n return new Mesh(geometry, this.agentMaterial);\n }\n}\n","import { RecastHeightfield, RecastSpan } from '@recast-navigation/core';\nimport {\n BoxGeometry,\n Color,\n ColorRepresentation,\n DynamicDrawUsage,\n InstancedMesh,\n Material,\n Matrix4,\n MeshBasicMaterial,\n Object3D,\n Vector3Tuple,\n} from 'three';\n\nconst tmpMatrix4 = new Matrix4();\n\nexport type HeightfieldHelperParams = {\n heightfields: RecastHeightfield[];\n\n /**\n * @default false\n */\n highlightWalkable?: boolean;\n\n /**\n * @default 'blue'\n */\n defaultColor?: ColorRepresentation;\n\n /**\n * @default 'green'\n */\n walkableColor?: ColorRepresentation;\n\n /**\n * @default MeshBasicMaterial\n */\n material?: Material;\n};\n\nexport class HeightfieldHelper extends Object3D {\n heightfields: RecastHeightfield[];\n\n highlightWalkable: boolean;\n\n defaultColor: Color;\n\n walkableColor: Color;\n\n material: Material;\n\n constructor({\n heightfields,\n highlightWalkable = false,\n material = new MeshBasicMaterial(),\n defaultColor = 'blue',\n walkableColor = 'green',\n }: HeightfieldHelperParams) {\n super();\n\n this.heightfields = heightfields;\n this.highlightWalkable = highlightWalkable;\n this.material = material;\n this.defaultColor = new Color(defaultColor);\n this.walkableColor = new Color(walkableColor);\n\n this.update();\n }\n\n update(): void {\n this.clear();\n\n for (const hf of this.heightfields) {\n const orig = hf.bmin();\n const cs = hf.cs();\n const ch = hf.ch();\n\n const width = hf.width();\n const height = hf.height();\n\n const boxes: {\n position: Vector3Tuple;\n walkable: boolean;\n }[] = [];\n\n for (let y = 0; y < height; ++y) {\n for (let x = 0; x < width; ++x) {\n const fx = orig.x + x * cs;\n const fz = orig.z + y * cs;\n\n let span: RecastSpan | null = hf.spans(x + y * width);\n\n while (span) {\n const minX = fx;\n const minY = orig.y + span.smin() * ch;\n const minZ = fz;\n\n const maxX = fx + cs;\n const maxY = orig.y + span.smax() * ch;\n const maxZ = fz + cs;\n\n boxes.push({\n position: [\n (maxX + minX) / 2,\n (maxY + minY) / 2,\n (maxZ + minZ) / 2,\n ],\n walkable: this.highlightWalkable && span.area() !== 0,\n });\n\n span = span.next();\n }\n }\n }\n\n const geometry = new BoxGeometry(cs, ch, cs);\n\n const instancedMesh = new InstancedMesh(\n geometry,\n this.material,\n boxes.length\n );\n instancedMesh.instanceMatrix.setUsage(DynamicDrawUsage);\n\n for (let i = 0; i < boxes.length; i++) {\n const { position, walkable } = boxes[i];\n\n instancedMesh.setMatrixAt(i, tmpMatrix4.setPosition(...position));\n instancedMesh.setColorAt(\n i,\n walkable ? this.walkableColor : this.defaultColor\n );\n }\n\n instancedMesh.instanceMatrix.needsUpdate = true;\n\n if (instancedMesh.instanceColor) {\n instancedMesh.instanceColor.needsUpdate = true;\n }\n\n this.add(instancedMesh);\n }\n }\n}\n","import { NavMesh } from '@recast-navigation/core';\nimport {\n BufferAttribute,\n BufferGeometry,\n Material,\n Mesh,\n MeshBasicMaterial,\n Object3D,\n} from 'three';\n\nexport type NavMeshHelperParams = {\n navMesh: NavMesh;\n navMeshMaterial?: Material;\n};\n\nexport class NavMeshHelper extends Object3D {\n navMesh: NavMesh;\n\n navMeshMaterial: Material;\n\n mesh: Mesh;\n\n geometry: BufferGeometry;\n\n constructor({ navMesh, navMeshMaterial }: NavMeshHelperParams) {\n super();\n\n this.navMesh = navMesh;\n\n this.navMeshMaterial = navMeshMaterial\n ? navMeshMaterial\n : new MeshBasicMaterial({\n color: 'orange',\n transparent: true,\n opacity: 0.7,\n });\n\n this.geometry = new BufferGeometry();\n\n this.update();\n\n this.mesh = new Mesh(this.geometry, this.navMeshMaterial);\n\n this.add(this.mesh);\n }\n\n /**\n * Update the three debug nav mesh.\n *\n * This should be called after updating the nav mesh.\n */\n update() {\n const [positions, indices] = this.navMesh.getDebugNavMesh();\n\n this.geometry.setAttribute(\n 'position',\n new BufferAttribute(Float32Array.from(positions), 3)\n );\n\n this.geometry.setIndex(new BufferAttribute(Uint32Array.from(indices), 1));\n\n this.geometry.computeVertexNormals();\n }\n}\n","import { Obstacle, TileCache } from '@recast-navigation/core';\nimport {\n BoxGeometry,\n CylinderGeometry,\n Material,\n Mesh,\n MeshBasicMaterial,\n Object3D,\n Vector3,\n} from 'three';\n\nexport type TileCacheHelperParams = {\n tileCache: TileCache;\n obstacleMaterial?: Material;\n};\n\nexport class TileCacheHelper extends Object3D {\n tileCache: TileCache;\n\n obstacleMeshes: Map<Obstacle, Mesh> = new Map();\n\n obstacleMaterial: Material;\n\n constructor({ tileCache, obstacleMaterial }: TileCacheHelperParams) {\n super();\n\n this.tileCache = tileCache;\n\n this.obstacleMaterial = obstacleMaterial\n ? obstacleMaterial\n : new MeshBasicMaterial({\n color: 'red',\n wireframe: true,\n wireframeLinewidth: 2,\n });\n\n this.update();\n }\n\n /**\n * Update the obstacle meshes.\n *\n * This should be called after adding or removing obstacles.\n */\n update() {\n const unseen = new Set(this.obstacleMeshes.keys());\n\n for (const [, obstacle] of this.tileCache.obstacles) {\n let obstacleMesh = this.obstacleMeshes.get(obstacle);\n\n unseen.delete(obstacle);\n\n if (!obstacleMesh) {\n const { position } = obstacle;\n\n const mesh = new Mesh(undefined, this.obstacleMaterial);\n\n mesh.position.copy(position as Vector3);\n\n if (obstacle.type === 'box') {\n const { extent, angle } = obstacle;\n\n mesh.geometry = new BoxGeometry(\n extent.x * 2,\n extent.y * 2,\n extent.z * 2\n );\n\n mesh.rotation.y = angle;\n } else if (obstacle.type === 'cylinder') {\n const { radius, height } = obstacle;\n\n mesh.geometry = new CylinderGeometry(radius, radius, height, 16);\n\n mesh.position.y += height / 2;\n } else {\n throw new Error(`Unknown obstacle type: ${obstacle}`);\n }\n\n this.add(mesh);\n this.obstacleMeshes.set(obstacle, mesh);\n }\n }\n\n for (const obstacle of unseen) {\n const obstacleMesh = this.obstacleMeshes.get(obstacle);\n\n if (obstacleMesh) {\n this.remove(obstacleMesh);\n this.obstacleMeshes.delete(obstacle);\n }\n }\n }\n}\n","import {\n generateSoloNavMesh,\n generateTiledNavMesh,\n SoloNavMeshGeneratorConfig,\n TiledNavMeshGeneratorConfig,\n} from '@recast-navigation/core';\nimport { BufferAttribute, Mesh, Vector3 } from 'three';\n\nconst tmpVec3 = new Vector3();\n\nexport const getPositionsAndIndices = (\n meshes: Mesh[]\n): [positions: Float32Array, indices: Uint32Array] => {\n const meshesToMerge: Mesh[] = [];\n\n for (const mesh of meshes) {\n const positionAttribute = mesh.geometry.attributes\n .position as BufferAttribute;\n\n if (!positionAttribute || positionAttribute.itemSize !== 3) {\n continue;\n }\n\n let meshToMerge = mesh;\n let index: ArrayLike<number> | undefined = mesh.geometry.getIndex()?.array;\n\n if (!index) {\n meshToMerge = meshToMerge.clone();\n meshToMerge.geometry = mesh.geometry.clone();\n\n // this will become indexed when merging with other meshes\n const ascendingIndex: number[] = [];\n for (let i = 0; i < positionAttribute.count; i++) {\n ascendingIndex.push(i);\n }\n\n meshToMerge.geometry.setIndex(ascendingIndex);\n }\n\n meshesToMerge.push(meshToMerge);\n }\n\n const mergedPositions: number[] = [];\n const mergedIndices: number[] = [];\n\n const positionToIndex: { [hash: string]: number } = {};\n let indexCounter = 0;\n\n for (const mesh of meshesToMerge) {\n mesh.updateMatrixWorld();\n\n const positions = mesh.geometry.attributes.position.array;\n const index = mesh.geometry.getIndex()!.array;\n\n for (let i = 0; i < index.length; i++) {\n const pt = index[i] * 3;\n\n const pos = tmpVec3.set(\n positions[pt],\n positions[pt + 1],\n positions[pt + 2]\n );\n mesh.localToWorld(pos);\n\n const key = `${pos.x}_${pos.y}_${pos.z}`;\n let idx = positionToIndex[key];\n\n if (!idx) {\n positionToIndex[key] = idx = indexCounter;\n mergedPositions.push(pos.x, pos.y, pos.z);\n indexCounter++;\n }\n\n mergedIndices.push(idx);\n }\n }\n\n return [Float32Array.from(mergedPositions), Uint32Array.from(mergedIndices)];\n};\n\nexport const threeToSoloNavMesh = (\n meshes: Mesh[],\n navMeshGeneratorConfig: Partial<SoloNavMeshGeneratorConfig> = {},\n keepIntermediates = false\n) => {\n const [positions, indices] = getPositionsAndIndices(meshes);\n\n return generateSoloNavMesh(\n positions,\n indices,\n navMeshGeneratorConfig,\n keepIntermediates\n );\n};\n\nexport const threeToTiledNavMesh = (\n meshes: Mesh[],\n navMeshGeneratorConfig: Partial<TiledNavMeshGeneratorConfig> = {},\n keepIntermediates = false\n) => {\n const [positions, indices] = getPositionsAndIndices(meshes);\n\n return generateTiledNavMesh(\n positions,\n indices,\n navMeshGeneratorConfig,\n keepIntermediates\n );\n};\n"],"names":["CrowdHelper","Object3D","agentMeshes","Map","recastCrowd","agentMaterial","constructor","crowd","super","this","MeshBasicMaterial","color","update","agentsIndices","getAgents","unseen","Set","keys","i","delete","position","getAgentPosition","velocity","getAgentVelocity","agentParams","getAgentParameters","agentMesh","get","undefined","createAgentMesh","add","set","x","y","height","z","lookAt","Vector3","copy","agentId","remove","geometry","CapsuleGeometry","radius","Mesh","tmpMatrix4","Matrix4","HeightfieldHelper","heightfields","highlightWalkable","defaultColor","walkableColor","material","Color","clear","hf","orig","bmin","cs","ch","width","boxes","fx","fz","span","spans","minX","minY","smin","minZ","maxX","maxY","smax","maxZ","push","walkable","area","next","BoxGeometry","instancedMesh","InstancedMesh","length","instanceMatrix","setUsage","DynamicDrawUsage","setMatrixAt","setPosition","setColorAt","needsUpdate","instanceColor","NavMeshHelper","navMesh","navMeshMaterial","mesh","transparent","opacity","BufferGeometry","positions","indices","getDebugNavMesh","setAttribute","BufferAttribute","Float32Array","from","setIndex","Uint32Array","computeVertexNormals","TileCacheHelper","tileCache","obstacleMeshes","obstacleMaterial","wireframe","wireframeLinewidth","obstacle","obstacles","obstacleMesh","type","extent","angle","rotation","Error","CylinderGeometry","tmpVec3","getPositionsAndIndices","meshes","meshesToMerge","positionAttribute","attributes","itemSize","meshToMerge","index","getIndex","array","clone","ascendingIndex","count","mergedPositions","mergedIndices","positionToIndex","indexCounter","updateMatrixWorld","pt","pos","localToWorld","key","idx","threeToSoloNavMesh","navMeshGeneratorConfig","keepIntermediates","generateSoloNavMesh","threeToTiledNavMesh","generateTiledNavMesh"],"mappings":"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"}
1
+ {"version":3,"file":"index.es.js","sources":["../src/helpers/crowd-helper.ts","../src/helpers/heightfield-helper.ts","../src/helpers/nav-mesh-helper.ts","../src/helpers/tile-cache-helper.ts","../src/utils/get-positions-and-indices.ts","../src/utils/generators.ts"],"sourcesContent":["import { Crowd, CrowdAgentParams } from '@recast-navigation/core';\nimport {\n CapsuleGeometry,\n Material,\n Mesh,\n MeshBasicMaterial,\n Object3D,\n Vector3,\n} from 'three';\n\nexport type CrowdHelperParams = {\n crowd: Crowd;\n agentMaterial?: Material;\n};\n\nexport class CrowdHelper extends Object3D {\n agentMeshes: Map<number, Mesh> = new Map();\n\n recastCrowd: Crowd;\n\n agentMaterial: Material;\n\n constructor({ crowd, agentMaterial }: CrowdHelperParams) {\n super();\n\n this.recastCrowd = crowd;\n\n this.agentMaterial =\n agentMaterial ?? new MeshBasicMaterial({ color: 'red' });\n\n this.update();\n }\n\n /**\n * Update the three debug view of the crowd agents.\n *\n * This should be called after updating the crowd.\n */\n update() {\n const agents = this.recastCrowd.getAgents();\n\n const unseen = new Set(this.agentMeshes.keys());\n\n for (const agent of agents) {\n unseen.delete(agent.agentIndex);\n\n const position = agent.position();\n const velocity = agent.velocity();\n const agentParams = agent.parameters();\n\n let agentMesh = this.agentMeshes.get(agent.agentIndex);\n\n if (agentMesh === undefined) {\n agentMesh = this.createAgentMesh(agentParams);\n\n this.add(agentMesh);\n this.agentMeshes.set(agent.agentIndex, agentMesh);\n }\n\n agentMesh.position.set(\n position.x,\n position.y + agentParams.height / 2,\n position.z\n );\n agentMesh.lookAt(\n new Vector3().copy(agentMesh.position).add(velocity as Vector3)\n );\n }\n\n for (const agentId of unseen) {\n const agentMesh = this.agentMeshes.get(agentId);\n\n if (agentMesh) {\n this.remove(agentMesh);\n this.agentMeshes.delete(agentId);\n }\n }\n }\n\n private createAgentMesh(agentParams: CrowdAgentParams): Mesh {\n const geometry = new CapsuleGeometry(\n agentParams.radius,\n agentParams.height - agentParams.radius * 2\n );\n\n return new Mesh(geometry, this.agentMaterial);\n }\n}\n","import { RecastHeightfield, RecastSpan } from '@recast-navigation/core';\nimport {\n BoxGeometry,\n Color,\n ColorRepresentation,\n DynamicDrawUsage,\n InstancedMesh,\n Material,\n Matrix4,\n MeshBasicMaterial,\n Object3D,\n Vector3Tuple,\n} from 'three';\n\nconst tmpMatrix4 = new Matrix4();\n\nexport type HeightfieldHelperParams = {\n heightfields: RecastHeightfield[];\n\n /**\n * @default false\n */\n highlightWalkable?: boolean;\n\n /**\n * @default 'blue'\n */\n defaultColor?: ColorRepresentation;\n\n /**\n * @default 'green'\n */\n walkableColor?: ColorRepresentation;\n\n /**\n * @default MeshBasicMaterial\n */\n material?: Material;\n};\n\nexport class HeightfieldHelper extends Object3D {\n heightfields: RecastHeightfield[];\n\n highlightWalkable: boolean;\n\n defaultColor: Color;\n\n walkableColor: Color;\n\n material: Material;\n\n constructor({\n heightfields,\n highlightWalkable = false,\n material = new MeshBasicMaterial(),\n defaultColor = 'blue',\n walkableColor = 'green',\n }: HeightfieldHelperParams) {\n super();\n\n this.heightfields = heightfields;\n this.highlightWalkable = highlightWalkable;\n this.material = material;\n this.defaultColor = new Color(defaultColor);\n this.walkableColor = new Color(walkableColor);\n\n this.update();\n }\n\n update(): void {\n this.clear();\n\n for (const hf of this.heightfields) {\n const orig = hf.bmin();\n const cs = hf.cs();\n const ch = hf.ch();\n\n const width = hf.width();\n const height = hf.height();\n\n const boxes: {\n position: Vector3Tuple;\n walkable: boolean;\n }[] = [];\n\n for (let y = 0; y < height; ++y) {\n for (let x = 0; x < width; ++x) {\n const fx = orig.x + x * cs;\n const fz = orig.z + y * cs;\n\n let span: RecastSpan | null = hf.spans(x + y * width);\n\n while (span) {\n const minX = fx;\n const minY = orig.y + span.smin() * ch;\n const minZ = fz;\n\n const maxX = fx + cs;\n const maxY = orig.y + span.smax() * ch;\n const maxZ = fz + cs;\n\n boxes.push({\n position: [\n (maxX + minX) / 2,\n (maxY + minY) / 2,\n (maxZ + minZ) / 2,\n ],\n walkable: this.highlightWalkable && span.area() !== 0,\n });\n\n span = span.next();\n }\n }\n }\n\n const geometry = new BoxGeometry(cs, ch, cs);\n\n const instancedMesh = new InstancedMesh(\n geometry,\n this.material,\n boxes.length\n );\n instancedMesh.instanceMatrix.setUsage(DynamicDrawUsage);\n\n for (let i = 0; i < boxes.length; i++) {\n const { position, walkable } = boxes[i];\n\n instancedMesh.setMatrixAt(i, tmpMatrix4.setPosition(...position));\n instancedMesh.setColorAt(\n i,\n walkable ? this.walkableColor : this.defaultColor\n );\n }\n\n instancedMesh.instanceMatrix.needsUpdate = true;\n\n if (instancedMesh.instanceColor) {\n instancedMesh.instanceColor.needsUpdate = true;\n }\n\n this.add(instancedMesh);\n }\n }\n}\n","import { NavMesh } from '@recast-navigation/core';\nimport {\n BufferAttribute,\n BufferGeometry,\n Material,\n Mesh,\n MeshBasicMaterial,\n Object3D,\n} from 'three';\n\nexport type NavMeshHelperParams = {\n navMesh: NavMesh;\n navMeshMaterial?: Material;\n};\n\nexport class NavMeshHelper extends Object3D {\n navMesh: NavMesh;\n\n navMeshMaterial: Material;\n\n mesh: Mesh;\n\n geometry: BufferGeometry;\n\n constructor({ navMesh, navMeshMaterial }: NavMeshHelperParams) {\n super();\n\n this.navMesh = navMesh;\n\n this.geometry = new BufferGeometry();\n\n this.navMeshMaterial = navMeshMaterial\n ? navMeshMaterial\n : new MeshBasicMaterial({\n color: 'orange',\n transparent: true,\n opacity: 0.7,\n });\n\n this.update();\n\n this.mesh = new Mesh(this.geometry, this.navMeshMaterial);\n\n this.add(this.mesh);\n }\n\n /**\n * Update the three debug nav mesh.\n *\n * This should be called after updating the nav mesh.\n */\n update() {\n const [positions, indices] = this.navMesh.getDebugNavMesh();\n\n this.geometry.setAttribute(\n 'position',\n new BufferAttribute(Float32Array.from(positions), 3)\n );\n this.geometry.setIndex(new BufferAttribute(Uint32Array.from(indices), 1));\n this.geometry.computeVertexNormals();\n }\n}\n","import { Obstacle, TileCache } from '@recast-navigation/core';\nimport {\n BoxGeometry,\n CylinderGeometry,\n Material,\n Mesh,\n MeshBasicMaterial,\n Object3D,\n Vector3,\n} from 'three';\n\nexport type TileCacheHelperParams = {\n tileCache: TileCache;\n obstacleMaterial?: Material;\n};\n\nexport class TileCacheHelper extends Object3D {\n tileCache: TileCache;\n\n obstacleMeshes: Map<Obstacle, Mesh> = new Map();\n\n obstacleMaterial: Material;\n\n constructor({ tileCache, obstacleMaterial }: TileCacheHelperParams) {\n super();\n\n this.tileCache = tileCache;\n\n this.obstacleMaterial = obstacleMaterial\n ? obstacleMaterial\n : new MeshBasicMaterial({\n color: 'red',\n wireframe: true,\n wireframeLinewidth: 2,\n });\n\n this.update();\n }\n\n /**\n * Update the obstacle meshes.\n *\n * This should be called after adding or removing obstacles.\n */\n update() {\n const unseen = new Set(this.obstacleMeshes.keys());\n\n for (const [, obstacle] of this.tileCache.obstacles) {\n let obstacleMesh = this.obstacleMeshes.get(obstacle);\n\n unseen.delete(obstacle);\n\n if (!obstacleMesh) {\n const { position } = obstacle;\n\n const mesh = new Mesh(undefined, this.obstacleMaterial);\n\n mesh.position.copy(position as Vector3);\n\n if (obstacle.type === 'box') {\n const { extent, angle } = obstacle;\n\n mesh.geometry = new BoxGeometry(\n extent.x * 2,\n extent.y * 2,\n extent.z * 2\n );\n\n mesh.rotation.y = angle;\n } else if (obstacle.type === 'cylinder') {\n const { radius, height } = obstacle;\n\n mesh.geometry = new CylinderGeometry(radius, radius, height, 16);\n\n mesh.position.y += height / 2;\n } else {\n throw new Error(`Unknown obstacle type: ${obstacle}`);\n }\n\n this.add(mesh);\n this.obstacleMeshes.set(obstacle, mesh);\n }\n }\n\n for (const obstacle of unseen) {\n const obstacleMesh = this.obstacleMeshes.get(obstacle);\n\n if (obstacleMesh) {\n this.remove(obstacleMesh);\n this.obstacleMeshes.delete(obstacle);\n }\n }\n }\n}\n","import { BufferAttribute, Mesh, Vector3 } from 'three';\n\nconst tmpVec3 = new Vector3();\n\nexport const getPositionsAndIndices = (\n meshes: Mesh[]\n): [positions: Float32Array, indices: Uint32Array] => {\n const meshesToMerge: Mesh[] = [];\n\n for (const mesh of meshes) {\n const positionAttribute = mesh.geometry.attributes\n .position as BufferAttribute;\n\n if (!positionAttribute || positionAttribute.itemSize !== 3) {\n continue;\n }\n\n let meshToMerge = mesh;\n let index: ArrayLike<number> | undefined = mesh.geometry.getIndex()?.array;\n\n if (!index) {\n meshToMerge = meshToMerge.clone();\n meshToMerge.geometry = mesh.geometry.clone();\n\n // this will become indexed when merging with other meshes\n const ascendingIndex: number[] = [];\n for (let i = 0; i < positionAttribute.count; i++) {\n ascendingIndex.push(i);\n }\n\n meshToMerge.geometry.setIndex(ascendingIndex);\n }\n\n meshesToMerge.push(meshToMerge);\n }\n\n const mergedPositions: number[] = [];\n const mergedIndices: number[] = [];\n\n const positionToIndex: { [hash: string]: number } = {};\n let indexCounter = 0;\n\n for (const mesh of meshesToMerge) {\n mesh.updateMatrixWorld();\n\n const positions = mesh.geometry.attributes.position.array;\n const index = mesh.geometry.getIndex()!.array;\n\n for (let i = 0; i < index.length; i++) {\n const pt = index[i] * 3;\n\n const pos = tmpVec3.set(\n positions[pt],\n positions[pt + 1],\n positions[pt + 2]\n );\n mesh.localToWorld(pos);\n\n const key = `${pos.x}_${pos.y}_${pos.z}`;\n let idx = positionToIndex[key];\n\n if (!idx) {\n positionToIndex[key] = idx = indexCounter;\n mergedPositions.push(pos.x, pos.y, pos.z);\n indexCounter++;\n }\n\n mergedIndices.push(idx);\n }\n }\n\n return [Float32Array.from(mergedPositions), Uint32Array.from(mergedIndices)];\n};\n","import {\n generateSoloNavMesh,\n generateTileCache,\n SoloNavMeshGeneratorConfig,\n TileCacheGeneratorConfig,\n generateTiledNavMesh,\n TiledNavMeshGeneratorConfig\n} from '@recast-navigation/core';\nimport { Mesh } from 'three';\nimport { getPositionsAndIndices } from './get-positions-and-indices';\n\nexport const threeToSoloNavMesh = (\n meshes: Mesh[],\n navMeshGeneratorConfig: Partial<SoloNavMeshGeneratorConfig> = {},\n keepIntermediates = false\n) => {\n const [positions, indices] = getPositionsAndIndices(meshes);\n\n return generateSoloNavMesh(\n positions,\n indices,\n navMeshGeneratorConfig,\n keepIntermediates\n );\n};\n\nexport const threeToTiledNavMesh = (\n meshes: Mesh[],\n navMeshGeneratorConfig: Partial<TiledNavMeshGeneratorConfig> = {},\n keepIntermediates = false\n) => {\n const [positions, indices] = getPositionsAndIndices(meshes);\n\n return generateTiledNavMesh(\n positions,\n indices,\n navMeshGeneratorConfig,\n keepIntermediates\n );\n};\n\nexport const threeToTileCache = (\n meshes: Mesh[],\n navMeshGeneratorConfig: Partial<TileCacheGeneratorConfig> = {},\n keepIntermediates = false\n) => {\n const [positions, indices] = getPositionsAndIndices(meshes);\n\n return generateTileCache(\n positions,\n indices,\n navMeshGeneratorConfig,\n keepIntermediates\n );\n};\n"],"names":["CrowdHelper","Object3D","agentMeshes","Map","recastCrowd","agentMaterial","constructor","crowd","super","this","MeshBasicMaterial","color","update","agents","getAgents","unseen","Set","keys","agent","delete","agentIndex","position","velocity","agentParams","parameters","agentMesh","get","undefined","createAgentMesh","add","set","x","y","height","z","lookAt","Vector3","copy","agentId","remove","geometry","CapsuleGeometry","radius","Mesh","tmpMatrix4","Matrix4","HeightfieldHelper","heightfields","highlightWalkable","defaultColor","walkableColor","material","Color","clear","hf","orig","bmin","cs","ch","width","boxes","fx","fz","span","spans","minX","minY","smin","minZ","maxX","maxY","smax","maxZ","push","walkable","area","next","BoxGeometry","instancedMesh","InstancedMesh","length","instanceMatrix","setUsage","DynamicDrawUsage","i","setMatrixAt","setPosition","setColorAt","needsUpdate","instanceColor","NavMeshHelper","navMesh","navMeshMaterial","mesh","BufferGeometry","transparent","opacity","positions","indices","getDebugNavMesh","setAttribute","BufferAttribute","Float32Array","from","setIndex","Uint32Array","computeVertexNormals","TileCacheHelper","tileCache","obstacleMeshes","obstacleMaterial","wireframe","wireframeLinewidth","obstacle","obstacles","obstacleMesh","type","extent","angle","rotation","Error","CylinderGeometry","tmpVec3","getPositionsAndIndices","meshes","meshesToMerge","positionAttribute","attributes","itemSize","meshToMerge","index","getIndex","array","clone","ascendingIndex","count","mergedPositions","mergedIndices","positionToIndex","indexCounter","updateMatrixWorld","pt","pos","localToWorld","key","idx","threeToSoloNavMesh","navMeshGeneratorConfig","keepIntermediates","generateSoloNavMesh","threeToTiledNavMesh","generateTiledNavMesh","threeToTileCache","generateTileCache"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { SoloNavMeshGeneratorConfig, TileCacheGeneratorConfig } from '@recast-navigation/core';
2
+ import { Mesh } from 'three';
3
+ export declare const threeToSoloNavMesh: (meshes: Mesh[], navMeshGeneratorConfig?: Partial<SoloNavMeshGeneratorConfig>, keepIntermediates?: boolean) => import("@recast-navigation/core").SoloNavMeshGeneratorResult;
4
+ export declare const threeToTiledNavMesh: (meshes: Mesh[], navMeshGeneratorConfig?: Pretty<import("@recast-navigation/core").RecastConfigType>, keepIntermediates?: boolean) => import("@recast-navigation/core").TiledNavMeshGeneratorResult;
5
+ export declare const threeToTileCache: (meshes: Mesh[], navMeshGeneratorConfig?: Partial<TileCacheGeneratorConfig>, keepIntermediates?: boolean) => import("@recast-navigation/core").TileCacheGeneratorResult;
@@ -0,0 +1,2 @@
1
+ import { Mesh } from 'three';
2
+ export declare const getPositionsAndIndices: (meshes: Mesh[]) => [positions: Float32Array, indices: Uint32Array];
@@ -1 +1,2 @@
1
- export * from './three-to-nav-mesh';
1
+ export * from './generators';
2
+ export * from './get-positions-and-indices';
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "email": "isaac@isaacmason.com",
7
7
  "url": "https://isaacmason.com/"
8
8
  },
9
- "version": "0.6.0",
9
+ "version": "0.7.1",
10
10
  "license": "MIT",
11
11
  "homepage": "https://github.com/isaac-mason/recast-navigation-js",
12
12
  "bugs": {
@@ -24,13 +24,14 @@
24
24
  "build": "rollup --config rollup.config.js --bundleConfigAsCjs"
25
25
  },
26
26
  "dependencies": {
27
- "@recast-navigation/core": "0.6.0"
27
+ "@recast-navigation/core": "0.7.1"
28
28
  },
29
29
  "peerDependencies": {
30
+ "@types/three": "0.x.x",
30
31
  "three": "0.x.x"
31
32
  },
32
33
  "devDependencies": {
33
- "@rollup/plugin-commonjs": "^24.0.1",
34
+ "@rollup/plugin-commonjs": "^25.0.4",
34
35
  "@rollup/plugin-node-resolve": "^15.0.1",
35
36
  "@rollup/plugin-terser": "^0.4.3",
36
37
  "@rollup/plugin-typescript": "^11.1.2",
@@ -40,7 +41,7 @@
40
41
  "eslint": "^8.5.0",
41
42
  "eslint-config-airbnb": "^18.2.1",
42
43
  "eslint-config-airbnb-base": "^15.0.0",
43
- "eslint-config-prettier": "^8.3.0",
44
+ "eslint-config-prettier": "^9.0.0",
44
45
  "eslint-import-resolver-typescript": "^3.5.5",
45
46
  "eslint-plugin-es": "^4.1.0",
46
47
  "eslint-plugin-import": "^2.28.0",
@@ -1,5 +0,0 @@
1
- import { SoloNavMeshGeneratorConfig, TiledNavMeshGeneratorConfig } from '@recast-navigation/core';
2
- import { Mesh } from 'three';
3
- export declare const getPositionsAndIndices: (meshes: Mesh[]) => [positions: Float32Array, indices: Uint32Array];
4
- export declare const threeToSoloNavMesh: (meshes: Mesh[], navMeshGeneratorConfig?: Partial<SoloNavMeshGeneratorConfig>, keepIntermediates?: boolean) => import("@recast-navigation/core").SoloNavMeshGeneratorResult;
5
- export declare const threeToTiledNavMesh: (meshes: Mesh[], navMeshGeneratorConfig?: Partial<TiledNavMeshGeneratorConfig>, keepIntermediates?: boolean) => import("@recast-navigation/core").TiledNavMeshGeneratorResult;