@daneren2005/shared-memory-physics 1.8.0 → 1.9.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 +115 -2
- package/dist/components/navigation-component-constants.d.ts +11 -0
- package/dist/components/navigation-component.d.ts +31 -0
- package/dist/components/registry.d.ts +9 -0
- package/dist/index.d.ts +24 -2
- package/dist/index.js +1015 -311
- package/dist/index.js.map +1 -1
- package/dist/pathfinding/follow-path.d.ts +9 -0
- package/dist/pathfinding/grid-a-star.d.ts +29 -0
- package/dist/pathfinding/line-of-sight.d.ts +2 -0
- package/dist/pathfinding/min-heap.d.ts +14 -0
- package/dist/pathfinding/nav-grid.d.ts +42 -0
- package/dist/pathfinding/navigation-state.d.ts +20 -0
- package/dist/pathfinding/path-blockers.d.ts +29 -0
- package/dist/pathfinding/path-search.d.ts +27 -0
- package/dist/pathfinding/pathfinding-system.d.ts +27 -0
- package/dist/pathfinding/pathfinding-update.d.ts +36 -0
- package/dist/pathfinding/smooth-path.d.ts +3 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ reads positions straight off its entities.
|
|
|
7
7
|
|
|
8
8
|
Examples at https://daneren2005.github.io/shared-memory-physics/
|
|
9
9
|
|
|
10
|
-
The ECS (`>=1.
|
|
10
|
+
The ECS (`>=1.10.0`) and the shared-memory primitives it is built on are **peer dependencies**: a game must
|
|
11
11
|
register these components against the same copy of the ECS it builds its world with.
|
|
12
12
|
|
|
13
13
|
```sh
|
|
@@ -23,6 +23,7 @@ npm install @daneren2005/shared-memory-physics @daneren2005/shared-memory-ecs @d
|
|
|
23
23
|
| `velocity` | – | `velocityX?`, `velocityY?`, `damping?` | `Float32Array` – world units per second |
|
|
24
24
|
| `body` | `shape?`, `collideCategory?`, `collideMask?`, `sensor?`, `continuousCollisionDetection?`, `blocksPath?` | – | `Uint32Array` – what shape, what collides with |
|
|
25
25
|
| `interpolation` | `interpolate` | – | `Float32Array` – where to *draw* it |
|
|
26
|
+
| `navigation` | `navigate` | – | `Int32Array` – a goal and the path to it ([Pathfinding](#pathfinding)) |
|
|
26
27
|
|
|
27
28
|
Entity configs are flat and shared across every component, so velocity is keyed as `velocityX` / `velocityY`
|
|
28
29
|
rather than `x` / `y` (which already belong to the transform). Either velocity axis on its own is enough to
|
|
@@ -838,6 +839,11 @@ const clicked = world.findNearestSpatial(mouseX, mouseY, 0);
|
|
|
838
839
|
const nearby = world.searchSpatialAround(x, y, 100, 100);
|
|
839
840
|
```
|
|
840
841
|
|
|
842
|
+
The map defaults to `type: Float64Array`. Entity ids are never reused, so a `Float32` map, which only holds ids
|
|
843
|
+
below 2^24 (~16.7M), runs out after that many entities have *ever* been created. `Float64` covers the whole
|
|
844
|
+
uint32 eid range for about 1.4x the memory per entity. Pass `spatial: { type: Float32Array }` only if a world
|
|
845
|
+
will create fewer entities than that over its lifetime.
|
|
846
|
+
|
|
841
847
|
`searchSpatial`, `searchSpatialAround`, `findNearestSpatial`, and `findNearbySpatial` return live entities and
|
|
842
848
|
accept entity filters. Shape-aware axis-aligned bounds are stored: rotated rectangles and capsules occupy the
|
|
843
849
|
box around their actual outline. A direct transform/body edit outside the physics update must be followed by
|
|
@@ -910,9 +916,111 @@ ask it directly rather than building the sort yourself - it settles as soon as t
|
|
|
910
916
|
measured to an entity's **box**, not to its centre, so a large target is as near as its nearest edge and
|
|
911
917
|
`maxDistance` reads as a range past the hull.
|
|
912
918
|
|
|
919
|
+
## Pathfinding
|
|
920
|
+
|
|
921
|
+
Grid pathfinding for movers that need to walk around walls and buildings: an A* over tiles, run on a worker,
|
|
922
|
+
answering requests written into a `navigation` component. Bodies flagged `blocksPath` are the walls. The physics
|
|
923
|
+
still does the moving; the game reads the path back and steers velocity along it.
|
|
924
|
+
|
|
925
|
+
Register `navigationRegistry` beside `physicsRegistry`, and give movers a `navigate: true` tag:
|
|
926
|
+
|
|
927
|
+
```ts
|
|
928
|
+
import { navigationRegistry, physicsRegistry, PathfindingSystem } from '@daneren2005/shared-memory-physics';
|
|
929
|
+
|
|
930
|
+
const world = new PhysicalWorld({ ...physicsRegistry, ...navigationRegistry, ...gameRegistry });
|
|
931
|
+
world.addSystem(new PathfindingSystem(world, {
|
|
932
|
+
getInitData: () => ({ tilesWide: 128, tilesHigh: 128, cellSize: 32 }),
|
|
933
|
+
getWorker: () => new Worker(new URL('./pathfinding.worker.ts', import.meta.url), { type: 'module' }),
|
|
934
|
+
}));
|
|
935
|
+
|
|
936
|
+
world.loadEntity({ x: 48, y: 48, width: 32, height: 32, blocksPath: true }); // a wall
|
|
937
|
+
const villager = world.loadEntity({ x: 16, y: 16, width: 24, height: 24, navigate: true });
|
|
938
|
+
villager.components.navigation!.navigateTo(400, 300);
|
|
939
|
+
```
|
|
940
|
+
|
|
941
|
+
The grid's `(0, 0)` is the world's top-left corner and anything off it is blocked. A worker file is the same two
|
|
942
|
+
lines as physics', handing `createEntitySystemWorker` the update the system was given (`pathfindingUpdate` by default).
|
|
943
|
+
|
|
944
|
+
### The navigation block
|
|
945
|
+
|
|
946
|
+
Everything is in the mover's `navigation` block (an `Int32Array`), so any thread can set a goal or read a path:
|
|
947
|
+
|
|
948
|
+
| Call | Does |
|
|
949
|
+
| --- | --- |
|
|
950
|
+
| `navigateTo(block, x, y)` | Sets the goal, marks the mover active and asks for a path |
|
|
951
|
+
| `setNavigationGoal(block, x, y)` | Moves the goal without searching again; the last leg bends to it |
|
|
952
|
+
| `requestPath(block)` | Searches again for the current goal |
|
|
953
|
+
| `stopNavigating(block)` | Marks the mover inactive, so it is neither searched for nor rechecked |
|
|
954
|
+
| `isPathPending(block)` / `isUnreachable(block)` | Whether an answer is still coming / settled as no way there |
|
|
955
|
+
| `followPath(block, x, y, arriveDistance, target)` | Follower bookkeeping, below |
|
|
956
|
+
|
|
957
|
+
A request is pending while its request id is ahead of its result id; the update writes waypoints and outcome
|
|
958
|
+
first and the result id last, so a settled path is never read half written. Up to `NAVIGATION_MAX_WAYPOINTS` (32)
|
|
959
|
+
waypoints fit; a longer path is cut short and marked `PathStatus.Incomplete`. Goals and paths are transient: whoever
|
|
960
|
+
set a goal sets it again after a load.
|
|
961
|
+
|
|
962
|
+
`followPath` is what a movement system calls each step. It skips waypoints within `arriveDistance`, writes the next
|
|
963
|
+
point to head for into `target` (no allocation) and says what kind it is:
|
|
964
|
+
|
|
965
|
+
```ts
|
|
966
|
+
const step = followPath(navigation, x, y, 1, target);
|
|
967
|
+
if(step === FollowStep.Waypoint || step === FollowStep.Goal) {
|
|
968
|
+
steerToward(target);
|
|
969
|
+
} else {
|
|
970
|
+
halt(); // Waiting for a path, or Stuck at the closest reachable spot
|
|
971
|
+
}
|
|
972
|
+
```
|
|
973
|
+
|
|
974
|
+
At the end of an incomplete path it asks for the rest itself and reports `Waiting`.
|
|
975
|
+
|
|
976
|
+
### What the update does
|
|
977
|
+
|
|
978
|
+
- Only **active** movers with a pending request are searched. Searching is budgeted per run in A* tiles
|
|
979
|
+
(`iterationBudget`, default `DEFAULT_PATH_SEARCH_ITERATION_BUDGET`), not wall-clock time, so a run plays out the
|
|
980
|
+
same on any machine; the first search of a run always goes ahead and the rest wait for the next run. The
|
|
981
|
+
budget is fixed when the update is built, but `PathfindingSystem`'s `iterationBudget` (a config option and a live
|
|
982
|
+
field) overrides it from the next run on - say, a larger one when the system is on a worker, where searching
|
|
983
|
+
costs no frame time. In-process, every tile of budget is main-thread time inside `world.update`.
|
|
984
|
+
- Blockers are assumed never to move. Each is rasterised into the grid when it joins the `pathBlockers` query and
|
|
985
|
+
cleared when it leaves, and a new one re-paths only movers whose remaining path it crosses.
|
|
986
|
+
- A mover standing inside a blocker (a bed built around a sleeper) searches as if that blocker were not there, so it
|
|
987
|
+
walks out rather than being relocated past a wall.
|
|
988
|
+
- Paths are smoothed (string pulled) where the straight line is clear and no slower. A mover is placed by its
|
|
989
|
+
footprint, so one bigger than a tile only fits gaps its whole box fits.
|
|
990
|
+
|
|
991
|
+
### Configuring it
|
|
992
|
+
|
|
993
|
+
`createPathfindingUpdate` builds the update both backends run. Hooks are baked in because functions do not
|
|
994
|
+
survive `postMessage`:
|
|
995
|
+
|
|
996
|
+
```ts
|
|
997
|
+
export const pathfindingUpdate = createPathfindingUpdate<Components, PathfindingUpdateComponents, GameWorld>({
|
|
998
|
+
search: new GridAStar({ diagonal: true }),
|
|
999
|
+
// Bodies in these categories stop only movers whose collide mask takes them in, e.g. doors animals cannot open.
|
|
1000
|
+
gateCategories: DOOR,
|
|
1001
|
+
init(navigation, data, queries) {
|
|
1002
|
+
// Feed terrain in: 1.5 for a road, 0.5 for mud.
|
|
1003
|
+
setNavigationTerrainSpeed(navigation, 3, 4, 1.5);
|
|
1004
|
+
},
|
|
1005
|
+
queryChanged(world, queryName, delta) { /* the game's extra queries */ },
|
|
1006
|
+
preRun(world) { /* per-run upkeep */ },
|
|
1007
|
+
});
|
|
1008
|
+
```
|
|
1009
|
+
|
|
1010
|
+
Pass it to `PathfindingSystem` as `updateFunction`, along with `blockers: { not: ['construction'] }` (or a `filter`)
|
|
1011
|
+
to narrow what counts as a blocker, `queries` for the hooks' own data, and `optional` for extra mover components.
|
|
1012
|
+
Another system wanting the same view of the world (say, finding enclosed pens) can build matching queries with
|
|
1013
|
+
`pathBlockerQueries` and keep its own `NavGrid` with `applyRectChanges`.
|
|
1014
|
+
|
|
1015
|
+
Gates get a grid per set of gate categories a mover's mask takes in, cloned from the blockers grid the first time
|
|
1016
|
+
such a mover searches, so gates nobody collides with cost nothing.
|
|
1017
|
+
|
|
1018
|
+
The search itself is swappable: anything implementing `PathSearch` (`findPath(grid, request)`) can be passed as
|
|
1019
|
+
`search`. `NavGrid`, `GridAStar`, `sweepCost` and `smoothPath` are exported for use on their own too.
|
|
1020
|
+
|
|
913
1021
|
## Examples
|
|
914
1022
|
|
|
915
|
-
|
|
1023
|
+
Runnable examples live in [`examples/`](./examples), rendered with [Phaser](https://phaser.io) (a dev
|
|
916
1024
|
dependency - it is not part of the library) and driven by plain HTML controls beside the canvas:
|
|
917
1025
|
|
|
918
1026
|
```sh
|
|
@@ -927,6 +1035,11 @@ npm start # http://127.0.0.1:8080
|
|
|
927
1035
|
them in turn. It starts on a deliberately long 100ms physics step, so turning **interpolate rendering** off is
|
|
928
1036
|
a direct before-and-after on the same running scene: the same simulation, drawn six frames at a time instead
|
|
929
1037
|
of one.
|
|
1038
|
+
- **Pathfinding** - click to send a square through a scene built to show each pathfinding case: a U-shaped trap,
|
|
1039
|
+
a gap only small movers fit, mud and road terrain, round and angled blockers, and a door only some movers can
|
|
1040
|
+
open. Toggle diagonal movement and smoothing, resize the mover, and add walls or paint terrain while it walks.
|
|
1041
|
+
- **Pathfinding stress** - thousands of movers wandering between random goals through hundreds of obstacles, with
|
|
1042
|
+
obstacle churn re-pathing whoever a new wall crosses, and per-worker timings in the stats panel.
|
|
930
1043
|
|
|
931
1044
|
Every page has a **physics step** slider (starting at the library's own 50ms) and an **interpolate rendering**
|
|
932
1045
|
toggle, so the trade the [interpolation section](#interpolation) describes can be looked at rather than
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const NAVIGATION_REQUEST_INDEX = 0;
|
|
2
|
+
export declare const NAVIGATION_RESULT_INDEX = 1;
|
|
3
|
+
export declare const NAVIGATION_OUTCOME_INDEX = 2;
|
|
4
|
+
export declare const NAVIGATION_WAYPOINT_INDEX = 3;
|
|
5
|
+
export declare const NAVIGATION_WAYPOINT_COUNT_INDEX = 4;
|
|
6
|
+
export declare const NAVIGATION_ACTIVE_INDEX = 5;
|
|
7
|
+
export declare const NAVIGATION_GOAL_X_INDEX = 6;
|
|
8
|
+
export declare const NAVIGATION_GOAL_Y_INDEX = 7;
|
|
9
|
+
export declare const NAVIGATION_WAYPOINTS_INDEX = 8;
|
|
10
|
+
export declare const NAVIGATION_MAX_WAYPOINTS = 32;
|
|
11
|
+
export declare const NAVIGATION_SIZE: number;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ComponentDefinition } from '@daneren2005/shared-memory-ecs';
|
|
2
|
+
import { type Point } from '../pathfinding/path-search';
|
|
3
|
+
export interface NavigationComponent {
|
|
4
|
+
index: number;
|
|
5
|
+
readonly active: boolean;
|
|
6
|
+
readonly goalX: number;
|
|
7
|
+
readonly goalY: number;
|
|
8
|
+
readonly pending: boolean;
|
|
9
|
+
readonly outcome: number;
|
|
10
|
+
readonly waypointIndex: number;
|
|
11
|
+
readonly waypoints: Array<Point>;
|
|
12
|
+
navigateTo(x: number, y: number): void;
|
|
13
|
+
stop(): void;
|
|
14
|
+
}
|
|
15
|
+
export interface NavigationConfig {
|
|
16
|
+
navigate: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare const navigationDefinition: ComponentDefinition<NavigationComponent, Int32Array, NavigationConfig>;
|
|
19
|
+
export declare function navigateTo(navigation: Int32Array, x: number, y: number): void;
|
|
20
|
+
export declare function setNavigationGoal(navigation: Int32Array, x: number, y: number): void;
|
|
21
|
+
export declare function stopNavigating(navigation: Int32Array): void;
|
|
22
|
+
export declare function isNavigating(navigation: Int32Array): boolean;
|
|
23
|
+
export declare function requestPath(navigation: Int32Array): void;
|
|
24
|
+
export declare function isPathPending(navigation: Int32Array): boolean;
|
|
25
|
+
export declare function isUnreachable(navigation: Int32Array): boolean;
|
|
26
|
+
export declare function navigationGoal(navigation: Int32Array): Point;
|
|
27
|
+
export declare function waypoint(navigation: Int32Array, i: number): Point;
|
|
28
|
+
export declare function waypointX(navigation: Int32Array, i: number): number;
|
|
29
|
+
export declare function waypointY(navigation: Int32Array, i: number): number;
|
|
30
|
+
export declare function writePath(navigation: Int32Array, status: number, points: ReadonlyArray<Point>): void;
|
|
31
|
+
export default navigationDefinition;
|
|
@@ -2,6 +2,7 @@ import { type BodyComponent } from './body-component';
|
|
|
2
2
|
import { type BouncinessComponent } from './bounciness-component';
|
|
3
3
|
import { type DynamicsComponent } from './dynamics-component';
|
|
4
4
|
import { type InterpolationComponent } from './interpolation-component';
|
|
5
|
+
import { type NavigationComponent } from './navigation-component';
|
|
5
6
|
import { type PolygonComponent } from './polygon-component';
|
|
6
7
|
import { type TransformComponent } from './transform-component';
|
|
7
8
|
import { type VelocityComponent } from './velocity-component';
|
|
@@ -14,6 +15,9 @@ export declare const physicsRegistry: {
|
|
|
14
15
|
dynamics: import("@daneren2005/shared-memory-ecs").ComponentDefinition<DynamicsComponent, Float32Array<ArrayBufferLike>, import("./dynamics-component").DynamicsConfig, import("./dynamics-component").DynamicsConfig>;
|
|
15
16
|
interpolation: import("@daneren2005/shared-memory-ecs").ComponentDefinition<InterpolationComponent, Float32Array<ArrayBufferLike>, import("./interpolation-component").InterpolationConfig, object>;
|
|
16
17
|
};
|
|
18
|
+
export declare const navigationRegistry: {
|
|
19
|
+
navigation: import("@daneren2005/shared-memory-ecs").ComponentDefinition<NavigationComponent, Int32Array<ArrayBufferLike>, import("./navigation-component").NavigationConfig, object>;
|
|
20
|
+
};
|
|
17
21
|
export type PhysicsComponents = {
|
|
18
22
|
transform: TransformComponent;
|
|
19
23
|
velocity: VelocityComponent;
|
|
@@ -27,6 +31,11 @@ export type InterpolationComponents = {
|
|
|
27
31
|
transform: TransformComponent;
|
|
28
32
|
interpolation: InterpolationComponent;
|
|
29
33
|
};
|
|
34
|
+
export type NavigationComponents = {
|
|
35
|
+
navigation: NavigationComponent;
|
|
36
|
+
transform: TransformComponent;
|
|
37
|
+
body: BodyComponent;
|
|
38
|
+
};
|
|
30
39
|
export type PhysicsUpdateComponents = {
|
|
31
40
|
transform: Float32Array;
|
|
32
41
|
velocity: Float32Array;
|
package/dist/index.d.ts
CHANGED
|
@@ -20,8 +20,11 @@ export type { BouncinessComponent, BouncinessConfig, } from './components/bounci
|
|
|
20
20
|
export { default as interpolationDefinition } from './components/interpolation-component';
|
|
21
21
|
export { INTERPOLATION_X_INDEX, INTERPOLATION_Y_INDEX, INTERPOLATION_SYNCED_TICK_INDEX, INTERPOLATION_DURATION_INDEX, INTERPOLATION_TICK_INDEX, INTERPOLATION_TOTAL_DURATION_INDEX, INTERPOLATION_SYNCED_DURATION_INDEX, INTERPOLATION_REMAINING_DURATION_INDEX, INTERPOLATION_TARGET_X_INDEX, INTERPOLATION_TARGET_Y_INDEX, INTERPOLATION_SYNCED_STEP_DURATION_INDEX, INTERPOLATION_CHANNEL_INDEX, INTERPOLATION_PREVIOUS_X_INDEX, INTERPOLATION_PREVIOUS_Y_INDEX, INTERPOLATION_PREVIOUS_DURATION_INDEX, INTERPOLATION_PREVIOUS_TOTAL_DURATION_INDEX, INTERPOLATION_PREVIOUS_TICK_INDEX, INTERPOLATION_SIZE, } from './components/interpolation-component-constants';
|
|
22
22
|
export type { InterpolationComponent, InterpolationConfig, } from './components/interpolation-component';
|
|
23
|
-
export {
|
|
24
|
-
export
|
|
23
|
+
export { default as navigationDefinition, isNavigating, isPathPending, isUnreachable, navigateTo, navigationGoal, requestPath, setNavigationGoal, stopNavigating, waypoint, waypointX, waypointY, writePath, } from './components/navigation-component';
|
|
24
|
+
export { NAVIGATION_REQUEST_INDEX, NAVIGATION_RESULT_INDEX, NAVIGATION_OUTCOME_INDEX, NAVIGATION_WAYPOINT_INDEX, NAVIGATION_WAYPOINT_COUNT_INDEX, NAVIGATION_ACTIVE_INDEX, NAVIGATION_GOAL_X_INDEX, NAVIGATION_GOAL_Y_INDEX, NAVIGATION_WAYPOINTS_INDEX, NAVIGATION_MAX_WAYPOINTS, NAVIGATION_SIZE, } from './components/navigation-component-constants';
|
|
25
|
+
export type { NavigationComponent, NavigationConfig } from './components/navigation-component';
|
|
26
|
+
export { physicsRegistry, navigationRegistry } from './components/registry';
|
|
27
|
+
export type { NavigationComponents, PhysicsComponents, PhysicsUpdateComponents, InterpolationComponents, InterpolationUpdateComponents, } from './components/registry';
|
|
25
28
|
export { default as PhysicalWorld } from './world';
|
|
26
29
|
export type { PhysicalSystemWorld, PhysicalWorldData, PhysicalWorldSource, PhysicalWorldEntity, PhysicalWorldFilter, PhysicalWorldOptions, } from './world';
|
|
27
30
|
export { shapesOverlap, contactNormal, shapeHalfWidth, shapeHalfHeight, shapeIsEmpty, shapeRadius, capsuleHalfLength, capsuleCoreAngle, boundsHalfWidth, boundsHalfHeight, orientedBoxesOverlap, segmentSegmentDistanceSquared, segmentBoxDistanceSquared, pointSegmentDistanceSquared, } from './math/shapes';
|
|
@@ -45,6 +48,25 @@ export { default as physicsUpdate, createPhysicsUpdate } from './systems/physics
|
|
|
45
48
|
export type { DeathInterpolationEntity, PhysicsCallbackWorld, PhysicsGroupConfig, PhysicsUpdateFunction, PhysicsUpdateMetadata, PhysicsUpdateOptions, PhysicsWorld } from './systems/physics-update';
|
|
46
49
|
export { default as PhysicsSystem } from './systems/physics-system';
|
|
47
50
|
export type { PhysicsSystemConfig, VelocityAssignment } from './systems/physics-system';
|
|
51
|
+
export { default as NavGrid } from './pathfinding/nav-grid';
|
|
52
|
+
export type { Rect, TileRange } from './pathfinding/nav-grid';
|
|
53
|
+
export { default as GridAStar } from './pathfinding/grid-a-star';
|
|
54
|
+
export type { GridAStarOptions } from './pathfinding/grid-a-star';
|
|
55
|
+
export { default as MinHeap } from './pathfinding/min-heap';
|
|
56
|
+
export { PathStatus } from './pathfinding/path-search';
|
|
57
|
+
export type { PathRequest, PathResult, PathSearch, PathStatusValue, Point } from './pathfinding/path-search';
|
|
58
|
+
export { sweepCost } from './pathfinding/line-of-sight';
|
|
59
|
+
export { smoothPath } from './pathfinding/smooth-path';
|
|
60
|
+
export { FollowStep, followPath } from './pathfinding/follow-path';
|
|
61
|
+
export type { FollowStepValue } from './pathfinding/follow-path';
|
|
62
|
+
export { PATH_BLOCKERS_QUERY, PATH_GATES_QUERY, applyRectChanges, blockerRect, pathBlockerQueries, } from './pathfinding/path-blockers';
|
|
63
|
+
export type { PathBlockerComponents, PathBlockerDelta, PathBlockerQueryOptions } from './pathfinding/path-blockers';
|
|
64
|
+
export { applyPathBlockerChanges, applyPathGateChanges, blockingRects, createNavigationState, navigationGridFor, setNavigationTerrainSpeed, } from './pathfinding/navigation-state';
|
|
65
|
+
export type { NavigationState } from './pathfinding/navigation-state';
|
|
66
|
+
export { DEFAULT_PATH_SEARCH_ITERATION_BUDGET, createPathfindingUpdate, pathfindingUpdate } from './pathfinding/pathfinding-update';
|
|
67
|
+
export type { PathfindingInitData, PathfindingUpdateComponents, PathfindingUpdateFunction, PathfindingUpdateMetadata, PathfindingUpdateOptions, PathfindingWorld, } from './pathfinding/pathfinding-update';
|
|
68
|
+
export { default as PathfindingSystem } from './pathfinding/pathfinding-system';
|
|
69
|
+
export type { PathfindingSystemConfig } from './pathfinding/pathfinding-system';
|
|
48
70
|
export { default as interpolationUpdate } from './systems/interpolation-update';
|
|
49
71
|
export type { InterpolationWorld } from './systems/interpolation-update';
|
|
50
72
|
export { default as InterpolationSystem } from './systems/interpolation-system';
|