recast-navigation 0.18.1 → 0.19.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 +71 -7
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
# recast-navigation-js
|
|
9
9
|
|
|
10
|
-
### [
|
|
10
|
+
### [Examples](https://recast-navigation-js.isaacmason.com) | [NavMesh Generator Website](https://navmesh.isaacmason.com/)
|
|
11
11
|
|
|
12
12
|
- 📐 NavMesh generation
|
|
13
13
|
- 🧭 Pathfinding
|
|
@@ -256,29 +256,52 @@ const { success, navMesh, tileCache } = generateTileCache(positions, indices, {
|
|
|
256
256
|
/* ... */
|
|
257
257
|
tileSize: 16,
|
|
258
258
|
});
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
You can use `addCylinderObstacle`, `addBoxObstacle`, and `removeObstacle` to add and remove obstacles from the TileCache.
|
|
262
|
+
|
|
263
|
+
After adding or removing obstacles you can call `tileCache.update(navMesh)` to rebuild navmesh tiles.
|
|
264
|
+
|
|
265
|
+
Adding or removing an obstacle will internally create an "obstacle request". TileCache supports queuing up to 64 obstacle requests. If the requests queue is full, calls to `addCylinderObstacle` and `addBoxObstacle` will fail and return a `dtStatus` status code `DT_BUFFER_TOO_SMALL`.
|
|
266
|
+
|
|
267
|
+
The `tileCache.update` method returns `upToDate`, whether the tile cache is fully up to date with obstacle requests and tile rebuilds. If the tile cache isn't up to date another call will continue processing obstacle requests and tile rebuilds; otherwise it will have no effect.
|
|
268
|
+
|
|
269
|
+
If not many obstacle requests occur between updates, an easy pattern is to call `tileCache.update` periodically, such as every game update.
|
|
270
|
+
|
|
271
|
+
If many obstacle requests have been made and you need to avoid reaching the 64 obstacle request limit, you can call `tileCache.update` multiple times, bailing out when `upToDate` is true or after a maximum number of updates.
|
|
259
272
|
|
|
273
|
+
```ts
|
|
260
274
|
/* add a Box obstacle to the NavMesh */
|
|
261
275
|
const position = { x: 0, y: 0, z: 0 };
|
|
262
276
|
const extent = { x: 1, y: 1, z: 1 };
|
|
263
277
|
const angle = 0;
|
|
264
|
-
const
|
|
278
|
+
const addBoxObstacleResult = tileCache.addBoxObstacle(position, extent, angle);
|
|
279
|
+
const boxObstacle = addBoxObstacleResult.obstacle;
|
|
265
280
|
|
|
266
281
|
/* add a Cylinder obstacle to the NavMesh */
|
|
267
282
|
const radius = 1;
|
|
268
283
|
const height = 1;
|
|
269
|
-
const
|
|
284
|
+
const addCylinderObstacleResult = tileCache.addCylinderObstacle(
|
|
270
285
|
position,
|
|
271
286
|
radius,
|
|
272
287
|
height,
|
|
273
288
|
angle
|
|
274
289
|
);
|
|
290
|
+
const cylinderObstacle = addCylinderObstacleResult.obstacle;
|
|
291
|
+
|
|
292
|
+
/* remove the obstacles from the NavMesh */
|
|
293
|
+
const removeObstacleResult = tileCache.removeObstacle(boxObstacle);
|
|
275
294
|
|
|
276
|
-
/* update
|
|
295
|
+
/* update to reflect obstacle changes */
|
|
296
|
+
// if few obstacles are added/removed between updates, you could call tileCache.update every game update
|
|
277
297
|
tileCache.update(navMesh);
|
|
278
298
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
299
|
+
// if your obstacle requests affect many tiles, you may need to call update multiple times
|
|
300
|
+
const maxTileCacheUpdates = 5
|
|
301
|
+
for (let i = 0; i < maxTileCacheUpdates; i++) {
|
|
302
|
+
const { upToDate } = tileCache.update(navMesh);
|
|
303
|
+
if (upToDate) break;
|
|
304
|
+
}
|
|
282
305
|
```
|
|
283
306
|
|
|
284
307
|
### Off Mesh Connections
|
|
@@ -347,6 +370,8 @@ const { success, navMesh, tileCache } = generateTileCache(
|
|
|
347
370
|
|
|
348
371
|
### Debugging
|
|
349
372
|
|
|
373
|
+
#### Debug Nav Mesh
|
|
374
|
+
|
|
350
375
|
You can use `getDebugNavMesh` to get a debug representation of the NavMesh.
|
|
351
376
|
|
|
352
377
|
```ts
|
|
@@ -359,6 +384,45 @@ If you are using three.js, you can use `NavMeshHelper` and `CrowdHelper` to visu
|
|
|
359
384
|
|
|
360
385
|
See the [`@recast-navigation/three` package README](https://github.com/isaac-mason/recast-navigation-js/tree/main/packages/recast-navigation-three/README.md) for usage information.
|
|
361
386
|
|
|
387
|
+
#### Detour Status Codes
|
|
388
|
+
|
|
389
|
+
Many Detour APIs return a `status` property. This is a `dtStatus` enum, which is a number representing the status of the operation.
|
|
390
|
+
|
|
391
|
+
You can use the `dtStatusToReadableString` function to convert a `dtStatus` to a human-readable string.
|
|
392
|
+
|
|
393
|
+
```ts
|
|
394
|
+
import { dtStatusToReadableString } from 'recast-navigation';
|
|
395
|
+
|
|
396
|
+
console.log(dtStatusToReadableString(status));
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
If you need to work with status codes programmatically, you can use these utilities:
|
|
400
|
+
|
|
401
|
+
```ts
|
|
402
|
+
import { Raw } from 'recast-navigation';
|
|
403
|
+
|
|
404
|
+
// returns true if the status is a success
|
|
405
|
+
Raw.Detour.statusSucceed(status);
|
|
406
|
+
|
|
407
|
+
// returns true if the status is in progress
|
|
408
|
+
Raw.Detour.statusInProgress(status);
|
|
409
|
+
|
|
410
|
+
// returns true if the status is a failure
|
|
411
|
+
Raw.Detour.statusFailed(status);
|
|
412
|
+
|
|
413
|
+
// get the detail of the status
|
|
414
|
+
const detail = Raw.Detour.statusDetail(status);
|
|
415
|
+
|
|
416
|
+
// Raw.Detour.WRONG_MAGIC;
|
|
417
|
+
// Raw.Detour.WRONG_VERSION;
|
|
418
|
+
// Raw.Detour.OUT_OF_MEMORY;
|
|
419
|
+
// Raw.Detour.INVALID_PARAM;
|
|
420
|
+
// Raw.Detour.BUFFER_TOO_SMALL;
|
|
421
|
+
// Raw.Detour.OUT_OF_NODES;
|
|
422
|
+
// Raw.Detour.PARTIAL_RESULT;
|
|
423
|
+
// Raw.Detour.ALREADY_OCCUPIED;
|
|
424
|
+
```
|
|
425
|
+
|
|
362
426
|
### Importing and Exporting
|
|
363
427
|
|
|
364
428
|
A NavMesh and TileCache can be imported and exported as a Uint8Array.
|
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.19.0",
|
|
22
22
|
"license": "MIT",
|
|
23
23
|
"homepage": "https://github.com/isaac-mason/recast-navigation-js",
|
|
24
24
|
"bugs": {
|
|
@@ -66,9 +66,9 @@
|
|
|
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.19.0",
|
|
70
|
+
"@recast-navigation/generators": "0.19.0",
|
|
71
|
+
"@recast-navigation/three": "0.19.0"
|
|
72
72
|
},
|
|
73
73
|
"devDependencies": {
|
|
74
74
|
"@babel/core": "^7.23.9",
|
|
@@ -88,14 +88,14 @@
|
|
|
88
88
|
"@storybook/addon-mdx-gfm": "^8.0.1",
|
|
89
89
|
"@storybook/react": "^8.0.1",
|
|
90
90
|
"@storybook/react-vite": "^8.0.1",
|
|
91
|
-
"@types/react": "^18.2.
|
|
91
|
+
"@types/react": "^18.2.73",
|
|
92
92
|
"@types/react-dom": "^18.2.8",
|
|
93
93
|
"@types/three": "^0.160.0",
|
|
94
94
|
"eslint": "^8.56.0",
|
|
95
95
|
"leva": "^0.9.35",
|
|
96
96
|
"react": "^18.2.0",
|
|
97
97
|
"react-dom": "^18.2.0",
|
|
98
|
-
"rollup": "^4.
|
|
98
|
+
"rollup": "^4.14.0",
|
|
99
99
|
"rollup-plugin-copy": "^3.4.0",
|
|
100
100
|
"rollup-plugin-filesize": "^10.0.0",
|
|
101
101
|
"storybook": "^8.0.1",
|
|
@@ -103,7 +103,7 @@
|
|
|
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.4.0"
|
|
107
107
|
},
|
|
108
108
|
"packageManager": "yarn@3.2.2"
|
|
109
109
|
}
|