@onerjs/addons 8.27.1 → 8.27.3

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.
Files changed (83) hide show
  1. package/index.d.ts +1 -0
  2. package/index.js +1 -0
  3. package/index.js.map +1 -1
  4. package/msdfText/paragraphOptions.d.ts +15 -0
  5. package/msdfText/paragraphOptions.js.map +1 -1
  6. package/msdfText/sdf/paragraph.js +1 -1
  7. package/msdfText/sdf/paragraph.js.map +1 -1
  8. package/navigation/common/config.d.ts +35 -0
  9. package/navigation/common/config.js +61 -0
  10. package/navigation/common/config.js.map +1 -0
  11. package/navigation/common/convert.d.ts +8 -0
  12. package/navigation/common/convert.js +22 -0
  13. package/navigation/common/convert.js.map +1 -0
  14. package/navigation/common/getters.d.ts +15 -0
  15. package/navigation/common/getters.js +76 -0
  16. package/navigation/common/getters.js.map +1 -0
  17. package/navigation/common/index.d.ts +6 -0
  18. package/navigation/common/index.js +7 -0
  19. package/navigation/common/index.js.map +1 -0
  20. package/navigation/common/smooth-path.d.ts +32 -0
  21. package/navigation/common/smooth-path.js +340 -0
  22. package/navigation/common/smooth-path.js.map +1 -0
  23. package/navigation/common/tile-cache.d.ts +15 -0
  24. package/navigation/common/tile-cache.js +32 -0
  25. package/navigation/common/tile-cache.js.map +1 -0
  26. package/navigation/common/utils.d.ts +17 -0
  27. package/navigation/common/utils.js +66 -0
  28. package/navigation/common/utils.js.map +1 -0
  29. package/navigation/debug/NavigationDebugger.d.ts +248 -0
  30. package/navigation/debug/NavigationDebugger.js +587 -0
  31. package/navigation/debug/NavigationDebugger.js.map +1 -0
  32. package/navigation/debug/index.d.ts +2 -0
  33. package/navigation/debug/index.js +3 -0
  34. package/navigation/debug/index.js.map +1 -0
  35. package/navigation/debug/simple-debug.d.ts +13 -0
  36. package/navigation/debug/simple-debug.js +23 -0
  37. package/navigation/debug/simple-debug.js.map +1 -0
  38. package/navigation/factory/common.d.ts +20 -0
  39. package/navigation/factory/common.js +80 -0
  40. package/navigation/factory/common.js.map +1 -0
  41. package/navigation/factory/factory.single-thread.d.ts +7 -0
  42. package/navigation/factory/factory.single-thread.js +15 -0
  43. package/navigation/factory/factory.single-thread.js.map +1 -0
  44. package/navigation/factory/factory.worker.d.ts +9 -0
  45. package/navigation/factory/factory.worker.js +40 -0
  46. package/navigation/factory/factory.worker.js.map +1 -0
  47. package/navigation/factory/index.d.ts +1 -0
  48. package/navigation/factory/index.js +3 -0
  49. package/navigation/factory/index.js.map +1 -0
  50. package/navigation/generator/generator.common.d.ts +25 -0
  51. package/navigation/generator/generator.common.js +40 -0
  52. package/navigation/generator/generator.common.js.map +1 -0
  53. package/navigation/generator/generator.single-thread.d.ts +20 -0
  54. package/navigation/generator/generator.single-thread.js +57 -0
  55. package/navigation/generator/generator.single-thread.js.map +1 -0
  56. package/navigation/generator/generator.worker.d.ts +29 -0
  57. package/navigation/generator/generator.worker.js +47 -0
  58. package/navigation/generator/generator.worker.js.map +1 -0
  59. package/navigation/generator/index.d.ts +3 -0
  60. package/navigation/generator/index.js +5 -0
  61. package/navigation/generator/index.js.map +1 -0
  62. package/navigation/generator/injection.d.ts +6 -0
  63. package/navigation/generator/injection.js +16 -0
  64. package/navigation/generator/injection.js.map +1 -0
  65. package/navigation/index.d.ts +5 -0
  66. package/navigation/index.js +7 -0
  67. package/navigation/index.js.map +1 -0
  68. package/navigation/plugin/RecastJSCrowd.d.ts +198 -0
  69. package/navigation/plugin/RecastJSCrowd.js +359 -0
  70. package/navigation/plugin/RecastJSCrowd.js.map +1 -0
  71. package/navigation/plugin/RecastNavigationJSPlugin.d.ts +419 -0
  72. package/navigation/plugin/RecastNavigationJSPlugin.js +482 -0
  73. package/navigation/plugin/RecastNavigationJSPlugin.js.map +1 -0
  74. package/navigation/plugin/index.d.ts +1 -0
  75. package/navigation/plugin/index.js +2 -0
  76. package/navigation/plugin/index.js.map +1 -0
  77. package/navigation/types.d.ts +199 -0
  78. package/navigation/types.js +11 -0
  79. package/navigation/types.js.map +1 -0
  80. package/navigation/worker/navmesh-worker.d.ts +4 -0
  81. package/navigation/worker/navmesh-worker.js +63 -0
  82. package/navigation/worker/navmesh-worker.js.map +1 -0
  83. package/package.json +2 -2
@@ -0,0 +1,359 @@
1
+ import { Vector3 } from "@onerjs/core/Maths/math.vector.js";
2
+ import { Epsilon } from "@onerjs/core/Maths/math.constants.js";
3
+ import { Observable } from "@onerjs/core/Misc/observable.js";
4
+ import { ToCrowdAgentParams } from "../common/config.js";
5
+ import { GetRecast } from "../factory/common.js";
6
+ /**
7
+ * Recast Detour crowd implementation
8
+ * This class provides methods to manage a crowd of agents, allowing them to navigate a navigation mesh.
9
+ * It supports adding agents, updating their parameters, moving them to destinations, and checking their states.
10
+ * The crowd is updated in the scene's animation loop, and it notifies observers when agents reach their destinations.
11
+ */
12
+ export class RecastJSCrowd {
13
+ /**
14
+ * Recast plugin
15
+ */
16
+ get navigationPlugin() {
17
+ return this._navigationPlugin;
18
+ }
19
+ /**
20
+ * Link to the detour crowd
21
+ */
22
+ get recastCrowd() {
23
+ return this._recastCrowd;
24
+ }
25
+ /**
26
+ * One transform per agent
27
+ */
28
+ get transforms() {
29
+ return this._transforms;
30
+ }
31
+ /**
32
+ * All agents created
33
+ */
34
+ get agents() {
35
+ return Object.freeze(this._agents);
36
+ }
37
+ /**
38
+ * Agents reach radius
39
+ */
40
+ get reachRadii() {
41
+ return Object.freeze(this._reachRadii);
42
+ }
43
+ /**
44
+ * Constructor
45
+ * @param plugin recastJS plugin
46
+ * @param maxAgents the maximum agent count in the crowd
47
+ * @param maxAgentRadius the maximum radius an agent can have
48
+ * @param scene to attach the crowd to
49
+ * @returns the crowd you can add agents to
50
+ */
51
+ constructor(plugin, maxAgents, maxAgentRadius, scene) {
52
+ this._transforms = [];
53
+ this._agents = [];
54
+ this._reachRadii = [];
55
+ /**
56
+ * true when a destination is active for an agent and notifier hasn't been notified of reach
57
+ */
58
+ this._agentDestinationArmed = new Array();
59
+ /**
60
+ * agent current target
61
+ */
62
+ this._agentDestination = new Array();
63
+ /**
64
+ * Observer for crowd updates
65
+ */
66
+ this._onBeforeAnimationsObserver = null;
67
+ /**
68
+ * Fires each time an agent is in reach radius of its destination
69
+ */
70
+ this.onReachTargetObservable = new Observable();
71
+ this._navigationPlugin = plugin;
72
+ if (!plugin.navMesh) {
73
+ throw new Error("There is no NavMesh generated.");
74
+ }
75
+ this._recastCrowd = new (GetRecast().Crowd)(plugin.navMesh, {
76
+ maxAgents,
77
+ maxAgentRadius,
78
+ });
79
+ this._scene = scene;
80
+ this._engine = scene.getEngine();
81
+ this._onBeforeAnimationsObserver = scene.onBeforeAnimationsObservable.add(() => {
82
+ this.update(this._engine.getDeltaTime() * 0.001 * plugin.timeFactor);
83
+ });
84
+ }
85
+ /**
86
+ * Add a new agent to the crowd with the specified parameter a corresponding transformNode.
87
+ * You can attach anything to that node. The node position is updated in the scene update tick.
88
+ * @param pos world position that will be constrained by the navigation mesh
89
+ * @param parameters agent parameters
90
+ * @param transform hooked to the agent that will be update by the scene
91
+ * @returns agent index
92
+ */
93
+ addAgent(pos, parameters, transform) {
94
+ const agentParams = ToCrowdAgentParams(parameters);
95
+ const agent = this._recastCrowd.addAgent({ x: pos.x, y: pos.y, z: pos.z }, agentParams);
96
+ this._transforms.push(transform);
97
+ this._agents.push(agent.agentIndex);
98
+ this._reachRadii.push(parameters.reachRadius ? parameters.reachRadius : parameters.radius);
99
+ this._agentDestinationArmed.push(false);
100
+ this._agentDestination.push(new Vector3(0, 0, 0));
101
+ return agent.agentIndex;
102
+ }
103
+ /**
104
+ * Returns the agent position in world space
105
+ * @param index agent index returned by addAgent
106
+ * @returns world space position
107
+ */
108
+ getAgentPosition(index) {
109
+ const agentPos = this._recastCrowd.getAgent(index)?.position() ?? Vector3.ZeroReadOnly;
110
+ return new Vector3(agentPos.x, agentPos.y, agentPos.z);
111
+ }
112
+ /**
113
+ * Returns the agent position result in world space
114
+ * @param index agent index returned by addAgent
115
+ * @param result output world space position
116
+ */
117
+ getAgentPositionToRef(index, result) {
118
+ const agentPos = this._recastCrowd.getAgent(index)?.position() ?? Vector3.ZeroReadOnly;
119
+ result.set(agentPos.x, agentPos.y, agentPos.z);
120
+ }
121
+ /**
122
+ * Returns the agent velocity in world space
123
+ * @param index agent index returned by addAgent
124
+ * @returns world space velocity
125
+ */
126
+ getAgentVelocity(index) {
127
+ const agentVel = this._recastCrowd.getAgent(index)?.velocity() ?? Vector3.ZeroReadOnly;
128
+ return new Vector3(agentVel.x, agentVel.y, agentVel.z);
129
+ }
130
+ /**
131
+ * Returns the agent velocity result in world space
132
+ * @param index agent index returned by addAgent
133
+ * @param result output world space velocity
134
+ */
135
+ getAgentVelocityToRef(index, result) {
136
+ const agentVel = this._recastCrowd.getAgent(index)?.velocity() ?? Vector3.ZeroReadOnly;
137
+ result.set(agentVel.x, agentVel.y, agentVel.z);
138
+ }
139
+ /**
140
+ * Returns the agent next target point on the path
141
+ * @param index agent index returned by addAgent
142
+ * @returns world space position
143
+ */
144
+ getAgentNextTargetPath(index) {
145
+ const pathTargetPos = this._recastCrowd.getAgent(index)?.nextTargetInPath() ?? Vector3.ZeroReadOnly;
146
+ return new Vector3(pathTargetPos.x, pathTargetPos.y, pathTargetPos.z);
147
+ }
148
+ /**
149
+ * Returns the agent next target point on the path
150
+ * @param index agent index returned by addAgent
151
+ * @param result output world space position
152
+ */
153
+ getAgentNextTargetPathToRef(index, result) {
154
+ const pathTargetPos = this._recastCrowd.getAgent(index)?.nextTargetInPath() ?? Vector3.ZeroReadOnly;
155
+ result.set(pathTargetPos.x, pathTargetPos.y, pathTargetPos.z);
156
+ }
157
+ /**
158
+ * Gets the agent state
159
+ * @param index agent index returned by addAgent
160
+ * @returns agent state, 0 = DT_CROWDAGENT_STATE_INVALID, 1 = DT_CROWDAGENT_STATE_WALKING, 2 = DT_CROWDAGENT_STATE_OFFMESH
161
+ */
162
+ getAgentState(index) {
163
+ return this._recastCrowd.getAgent(index)?.state() ?? 0; // invalid
164
+ }
165
+ /**
166
+ * returns true if the agent in over an off mesh link connection
167
+ * @param index agent index returned by addAgent
168
+ * @returns true if over an off mesh link connection
169
+ */
170
+ overOffmeshConnection(index) {
171
+ return this._recastCrowd.getAgent(index)?.overOffMeshConnection() ?? false;
172
+ }
173
+ /**
174
+ * Asks a particular agent to go to a destination. That destination is constrained by the navigation mesh
175
+ * @param index agent index returned by addAgent
176
+ * @param destination targeted world position
177
+ */
178
+ agentGoto(index, destination) {
179
+ this._recastCrowd.getAgent(index)?.requestMoveTarget(destination);
180
+ // arm observer
181
+ const item = this._agents.indexOf(index);
182
+ if (item > -1) {
183
+ this._agentDestinationArmed[item] = true;
184
+ this._agentDestination[item].set(destination.x, destination.y, destination.z);
185
+ }
186
+ }
187
+ /**
188
+ * Teleport the agent to a new position
189
+ * @param index agent index returned by addAgent
190
+ * @param destination targeted world position
191
+ */
192
+ agentTeleport(index, destination) {
193
+ this._recastCrowd.getAgent(index)?.teleport(destination);
194
+ }
195
+ /**
196
+ * Update agent parameters
197
+ * @param index agent index returned by addAgent
198
+ * @param parameters agent parameters
199
+ */
200
+ updateAgentParameters(index, parameters) {
201
+ const agent = this._recastCrowd.getAgent(index);
202
+ if (!agent) {
203
+ return;
204
+ }
205
+ const agentParams = agent.parameters();
206
+ if (!agentParams) {
207
+ return;
208
+ }
209
+ if (parameters.radius !== undefined) {
210
+ agentParams.radius = parameters.radius;
211
+ }
212
+ if (parameters.height !== undefined) {
213
+ agentParams.height = parameters.height;
214
+ }
215
+ if (parameters.maxAcceleration !== undefined) {
216
+ agentParams.maxAcceleration = parameters.maxAcceleration;
217
+ }
218
+ if (parameters.maxSpeed !== undefined) {
219
+ agentParams.maxSpeed = parameters.maxSpeed;
220
+ }
221
+ if (parameters.collisionQueryRange !== undefined) {
222
+ agentParams.collisionQueryRange = parameters.collisionQueryRange;
223
+ }
224
+ if (parameters.pathOptimizationRange !== undefined) {
225
+ agentParams.pathOptimizationRange = parameters.pathOptimizationRange;
226
+ }
227
+ if (parameters.separationWeight !== undefined) {
228
+ agentParams.separationWeight = parameters.separationWeight;
229
+ }
230
+ agent.updateParameters(agentParams);
231
+ }
232
+ /**
233
+ * remove a particular agent previously created
234
+ * @param index agent index returned by addAgent
235
+ */
236
+ removeAgent(index) {
237
+ this._recastCrowd.removeAgent(index);
238
+ const item = this._agents.indexOf(index);
239
+ if (item > -1) {
240
+ this._agents.splice(item, 1);
241
+ this._transforms.splice(item, 1);
242
+ this._reachRadii.splice(item, 1);
243
+ this._agentDestinationArmed.splice(item, 1);
244
+ this._agentDestination.splice(item, 1);
245
+ }
246
+ }
247
+ /**
248
+ * get the list of all agents attached to this crowd
249
+ * @returns list of agent indices
250
+ */
251
+ getAgents() {
252
+ return this._agents;
253
+ }
254
+ /**
255
+ * Tick update done by the Scene. Agent position/velocity/acceleration is updated by this function
256
+ * @param deltaTime in seconds
257
+ */
258
+ update(deltaTime) {
259
+ this._recastCrowd.update(deltaTime);
260
+ if (deltaTime <= Epsilon) {
261
+ return;
262
+ }
263
+ // update crowd
264
+ const timeStep = this._navigationPlugin.getTimeStep();
265
+ const maxStepCount = this._navigationPlugin.getMaximumSubStepCount();
266
+ if (timeStep <= Epsilon) {
267
+ this._recastCrowd.update(deltaTime);
268
+ }
269
+ else {
270
+ let iterationCount = Math.floor(deltaTime / timeStep);
271
+ if (maxStepCount && iterationCount > maxStepCount) {
272
+ iterationCount = maxStepCount;
273
+ }
274
+ if (iterationCount < 1) {
275
+ iterationCount = 1;
276
+ }
277
+ const step = deltaTime / iterationCount;
278
+ for (let i = 0; i < iterationCount; i++) {
279
+ this._recastCrowd.update(step);
280
+ }
281
+ }
282
+ // update transforms
283
+ for (let index = 0; index < this._agents.length; index++) {
284
+ // update transform position
285
+ const agentIndex = this._agents[index];
286
+ const agentPosition = this.getAgentPosition(agentIndex);
287
+ this._transforms[index].position = agentPosition;
288
+ // check agent reach destination
289
+ if (this._agentDestinationArmed[index]) {
290
+ const dx = agentPosition.x - this._agentDestination[index].x;
291
+ const dz = agentPosition.z - this._agentDestination[index].z;
292
+ const radius = this._reachRadii[index];
293
+ const groundY = this._agentDestination[index].y - this._reachRadii[index];
294
+ const ceilingY = this._agentDestination[index].y + this._reachRadii[index];
295
+ const distanceXZSquared = dx * dx + dz * dz;
296
+ if (agentPosition.y > groundY && agentPosition.y < ceilingY && distanceXZSquared < radius * radius) {
297
+ this._agentDestinationArmed[index] = false;
298
+ this.onReachTargetObservable.notifyObservers({
299
+ agentIndex: agentIndex,
300
+ destination: this._agentDestination[index],
301
+ });
302
+ }
303
+ }
304
+ }
305
+ }
306
+ /**
307
+ * Set the Bounding box extent for doing spatial queries (getClosestPoint, getRandomPointAround, ...)
308
+ * The queries will try to find a solution within those bounds
309
+ * default is (1,1,1)
310
+ * @param extent x,y,z value that define the extent around the queries point of reference
311
+ */
312
+ setDefaultQueryExtent(extent) {
313
+ this._navigationPlugin.setDefaultQueryExtent(extent);
314
+ }
315
+ /**
316
+ * Get the Bounding box extent specified by setDefaultQueryExtent
317
+ * @returns the box extent values
318
+ */
319
+ getDefaultQueryExtent() {
320
+ const p = this._navigationPlugin.getDefaultQueryExtent();
321
+ return new Vector3(p.x, p.y, p.z);
322
+ }
323
+ /**
324
+ * Get the Bounding box extent result specified by setDefaultQueryExtent
325
+ * @param result output the box extent values
326
+ */
327
+ getDefaultQueryExtentToRef(result) {
328
+ const p = this._navigationPlugin.getDefaultQueryExtent();
329
+ result.set(p.x, p.y, p.z);
330
+ }
331
+ /**
332
+ * Get the next corner points composing the path (max 4 points)
333
+ * @param index agent index returned by addAgent
334
+ * @returns array containing world position composing the path
335
+ */
336
+ getCorners(index) {
337
+ const corners = this._recastCrowd.getAgent(index)?.corners();
338
+ if (!corners) {
339
+ return [];
340
+ }
341
+ const positions = [];
342
+ for (let i = 0; i < corners.length; i++) {
343
+ positions.push(new Vector3(corners[i].x, corners[i].y, corners[i].z));
344
+ }
345
+ return positions;
346
+ }
347
+ /**
348
+ * Release all resources
349
+ */
350
+ dispose() {
351
+ this._recastCrowd.destroy();
352
+ if (this._onBeforeAnimationsObserver) {
353
+ this._scene.onBeforeAnimationsObservable.remove(this._onBeforeAnimationsObserver);
354
+ this._onBeforeAnimationsObserver = null;
355
+ }
356
+ this.onReachTargetObservable.clear();
357
+ }
358
+ }
359
+ //# sourceMappingURL=RecastJSCrowd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecastJSCrowd.js","sourceRoot":"","sources":["../../../../../dev/addons/src/navigation/plugin/RecastJSCrowd.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Crowd } from \"@recast-navigation/core\";\n\nimport type { Nullable } from \"core/types\";\nimport type { IVector3Like } from \"core/Maths/math.like\";\nimport type { TransformNode } from \"core/Meshes/transformNode\";\nimport type { ICrowd } from \"core/Navigation/INavigationEngine\";\nimport { Vector3 } from \"core/Maths/math.vector\";\nimport { Epsilon } from \"core/Maths/math.constants\";\nimport type { Observer } from \"core/Misc/observable\";\nimport { Observable } from \"core/Misc/observable\";\nimport type { Scene } from \"core/scene\";\n\nimport type { RecastNavigationJSPluginV2 } from \"./RecastNavigationJSPlugin\";\nimport type { AbstractEngine } from \"core/Engines/abstractEngine\";\nimport { ToCrowdAgentParams } from \"../common/config\";\nimport type { IAgentParametersV2 } from \"../types\";\nimport { GetRecast } from \"../factory/common\";\n\n/**\n * Recast Detour crowd implementation\n * This class provides methods to manage a crowd of agents, allowing them to navigate a navigation mesh.\n * It supports adding agents, updating their parameters, moving them to destinations, and checking their states.\n * The crowd is updated in the scene's animation loop, and it notifies observers when agents reach their destinations.\n */\nexport class RecastJSCrowd implements ICrowd {\n /**\n * Recast plugin\n */\n public get navigationPlugin(): RecastNavigationJSPluginV2 {\n return this._navigationPlugin;\n }\n\n /**\n * Link to the detour crowd\n */\n public get recastCrowd(): Crowd {\n return this._recastCrowd;\n }\n\n /**\n * One transform per agent\n */\n public get transforms(): TransformNode[] {\n return this._transforms;\n }\n\n /**\n * All agents created\n */\n public get agents(): readonly number[] {\n return Object.freeze(this._agents);\n }\n\n /**\n * Agents reach radius\n */\n public get reachRadii(): readonly number[] {\n return Object.freeze(this._reachRadii);\n }\n\n private _navigationPlugin: RecastNavigationJSPluginV2;\n private _recastCrowd: Crowd;\n private _transforms: TransformNode[] = [];\n private _agents: number[] = [];\n private _reachRadii: number[] = [];\n\n /**\n * true when a destination is active for an agent and notifier hasn't been notified of reach\n */\n private _agentDestinationArmed: boolean[] = new Array<boolean>();\n /**\n * agent current target\n */\n private _agentDestination: Vector3[] = new Array<Vector3>();\n /**\n * Link to the scene is kept to unregister the crowd from the scene\n */\n private _scene: Scene;\n\n private _engine: AbstractEngine;\n\n /**\n * Observer for crowd updates\n */\n private _onBeforeAnimationsObserver: Nullable<Observer<Scene>> = null;\n\n /**\n * Fires each time an agent is in reach radius of its destination\n */\n public onReachTargetObservable = new Observable<{\n /**\n *\n */\n agentIndex: number;\n /**\n *\n */\n destination: Vector3;\n }>();\n\n /**\n * Constructor\n * @param plugin recastJS plugin\n * @param maxAgents the maximum agent count in the crowd\n * @param maxAgentRadius the maximum radius an agent can have\n * @param scene to attach the crowd to\n * @returns the crowd you can add agents to\n */\n public constructor(plugin: RecastNavigationJSPluginV2, maxAgents: number, maxAgentRadius: number, scene: Scene) {\n this._navigationPlugin = plugin;\n\n if (!plugin.navMesh) {\n throw new Error(\"There is no NavMesh generated.\");\n }\n\n this._recastCrowd = new (GetRecast().Crowd)(plugin.navMesh, {\n maxAgents,\n maxAgentRadius,\n });\n\n this._scene = scene;\n this._engine = scene.getEngine();\n\n this._onBeforeAnimationsObserver = scene.onBeforeAnimationsObservable.add(() => {\n this.update(this._engine.getDeltaTime() * 0.001 * plugin.timeFactor);\n });\n }\n\n /**\n * Add a new agent to the crowd with the specified parameter a corresponding transformNode.\n * You can attach anything to that node. The node position is updated in the scene update tick.\n * @param pos world position that will be constrained by the navigation mesh\n * @param parameters agent parameters\n * @param transform hooked to the agent that will be update by the scene\n * @returns agent index\n */\n public addAgent(pos: IVector3Like, parameters: IAgentParametersV2, transform: TransformNode): number {\n const agentParams = ToCrowdAgentParams(parameters);\n\n const agent = this._recastCrowd.addAgent({ x: pos.x, y: pos.y, z: pos.z }, agentParams);\n\n this._transforms.push(transform);\n this._agents.push(agent.agentIndex);\n this._reachRadii.push(parameters.reachRadius ? parameters.reachRadius : parameters.radius);\n this._agentDestinationArmed.push(false);\n this._agentDestination.push(new Vector3(0, 0, 0));\n\n return agent.agentIndex;\n }\n\n /**\n * Returns the agent position in world space\n * @param index agent index returned by addAgent\n * @returns world space position\n */\n public getAgentPosition(index: number): Vector3 {\n const agentPos = this._recastCrowd.getAgent(index)?.position() ?? Vector3.ZeroReadOnly;\n return new Vector3(agentPos.x, agentPos.y, agentPos.z);\n }\n\n /**\n * Returns the agent position result in world space\n * @param index agent index returned by addAgent\n * @param result output world space position\n */\n public getAgentPositionToRef(index: number, result: Vector3): void {\n const agentPos = this._recastCrowd.getAgent(index)?.position() ?? Vector3.ZeroReadOnly;\n result.set(agentPos.x, agentPos.y, agentPos.z);\n }\n\n /**\n * Returns the agent velocity in world space\n * @param index agent index returned by addAgent\n * @returns world space velocity\n */\n public getAgentVelocity(index: number): Vector3 {\n const agentVel = this._recastCrowd.getAgent(index)?.velocity() ?? Vector3.ZeroReadOnly;\n return new Vector3(agentVel.x, agentVel.y, agentVel.z);\n }\n\n /**\n * Returns the agent velocity result in world space\n * @param index agent index returned by addAgent\n * @param result output world space velocity\n */\n public getAgentVelocityToRef(index: number, result: Vector3): void {\n const agentVel = this._recastCrowd.getAgent(index)?.velocity() ?? Vector3.ZeroReadOnly;\n result.set(agentVel.x, agentVel.y, agentVel.z);\n }\n\n /**\n * Returns the agent next target point on the path\n * @param index agent index returned by addAgent\n * @returns world space position\n */\n public getAgentNextTargetPath(index: number): Vector3 {\n const pathTargetPos = this._recastCrowd.getAgent(index)?.nextTargetInPath() ?? Vector3.ZeroReadOnly;\n return new Vector3(pathTargetPos.x, pathTargetPos.y, pathTargetPos.z);\n }\n\n /**\n * Returns the agent next target point on the path\n * @param index agent index returned by addAgent\n * @param result output world space position\n */\n public getAgentNextTargetPathToRef(index: number, result: Vector3): void {\n const pathTargetPos = this._recastCrowd.getAgent(index)?.nextTargetInPath() ?? Vector3.ZeroReadOnly;\n result.set(pathTargetPos.x, pathTargetPos.y, pathTargetPos.z);\n }\n\n /**\n * Gets the agent state\n * @param index agent index returned by addAgent\n * @returns agent state, 0 = DT_CROWDAGENT_STATE_INVALID, 1 = DT_CROWDAGENT_STATE_WALKING, 2 = DT_CROWDAGENT_STATE_OFFMESH\n */\n public getAgentState(index: number): number {\n return this._recastCrowd.getAgent(index)?.state() ?? 0; // invalid\n }\n\n /**\n * returns true if the agent in over an off mesh link connection\n * @param index agent index returned by addAgent\n * @returns true if over an off mesh link connection\n */\n public overOffmeshConnection(index: number): boolean {\n return this._recastCrowd.getAgent(index)?.overOffMeshConnection() ?? false;\n }\n\n /**\n * Asks a particular agent to go to a destination. That destination is constrained by the navigation mesh\n * @param index agent index returned by addAgent\n * @param destination targeted world position\n */\n public agentGoto(index: number, destination: IVector3Like): void {\n this._recastCrowd.getAgent(index)?.requestMoveTarget(destination);\n\n // arm observer\n const item = this._agents.indexOf(index);\n if (item > -1) {\n this._agentDestinationArmed[item] = true;\n this._agentDestination[item].set(destination.x, destination.y, destination.z);\n }\n }\n\n /**\n * Teleport the agent to a new position\n * @param index agent index returned by addAgent\n * @param destination targeted world position\n */\n public agentTeleport(index: number, destination: IVector3Like): void {\n this._recastCrowd.getAgent(index)?.teleport(destination);\n }\n\n /**\n * Update agent parameters\n * @param index agent index returned by addAgent\n * @param parameters agent parameters\n */\n public updateAgentParameters(index: number, parameters: IAgentParametersV2): void {\n const agent = this._recastCrowd.getAgent(index);\n if (!agent) {\n return;\n }\n\n const agentParams = agent.parameters();\n\n if (!agentParams) {\n return;\n }\n\n if (parameters.radius !== undefined) {\n agentParams.radius = parameters.radius;\n }\n if (parameters.height !== undefined) {\n agentParams.height = parameters.height;\n }\n if (parameters.maxAcceleration !== undefined) {\n agentParams.maxAcceleration = parameters.maxAcceleration;\n }\n if (parameters.maxSpeed !== undefined) {\n agentParams.maxSpeed = parameters.maxSpeed;\n }\n if (parameters.collisionQueryRange !== undefined) {\n agentParams.collisionQueryRange = parameters.collisionQueryRange;\n }\n if (parameters.pathOptimizationRange !== undefined) {\n agentParams.pathOptimizationRange = parameters.pathOptimizationRange;\n }\n if (parameters.separationWeight !== undefined) {\n agentParams.separationWeight = parameters.separationWeight;\n }\n\n agent.updateParameters(agentParams);\n }\n\n /**\n * remove a particular agent previously created\n * @param index agent index returned by addAgent\n */\n public removeAgent(index: number): void {\n this._recastCrowd.removeAgent(index);\n\n const item = this._agents.indexOf(index);\n if (item > -1) {\n this._agents.splice(item, 1);\n this._transforms.splice(item, 1);\n this._reachRadii.splice(item, 1);\n this._agentDestinationArmed.splice(item, 1);\n this._agentDestination.splice(item, 1);\n }\n }\n\n /**\n * get the list of all agents attached to this crowd\n * @returns list of agent indices\n */\n public getAgents(): number[] {\n return this._agents;\n }\n\n /**\n * Tick update done by the Scene. Agent position/velocity/acceleration is updated by this function\n * @param deltaTime in seconds\n */\n public update(deltaTime: number): void {\n this._recastCrowd.update(deltaTime);\n\n if (deltaTime <= Epsilon) {\n return;\n }\n\n // update crowd\n const timeStep = this._navigationPlugin.getTimeStep();\n const maxStepCount = this._navigationPlugin.getMaximumSubStepCount();\n if (timeStep <= Epsilon) {\n this._recastCrowd.update(deltaTime);\n } else {\n let iterationCount = Math.floor(deltaTime / timeStep);\n if (maxStepCount && iterationCount > maxStepCount) {\n iterationCount = maxStepCount;\n }\n if (iterationCount < 1) {\n iterationCount = 1;\n }\n\n const step = deltaTime / iterationCount;\n for (let i = 0; i < iterationCount; i++) {\n this._recastCrowd.update(step);\n }\n }\n\n // update transforms\n for (let index = 0; index < this._agents.length; index++) {\n // update transform position\n const agentIndex = this._agents[index];\n const agentPosition = this.getAgentPosition(agentIndex);\n this._transforms[index].position = agentPosition;\n // check agent reach destination\n if (this._agentDestinationArmed[index]) {\n const dx = agentPosition.x - this._agentDestination[index].x;\n const dz = agentPosition.z - this._agentDestination[index].z;\n const radius = this._reachRadii[index];\n const groundY = this._agentDestination[index].y - this._reachRadii[index];\n const ceilingY = this._agentDestination[index].y + this._reachRadii[index];\n const distanceXZSquared = dx * dx + dz * dz;\n if (agentPosition.y > groundY && agentPosition.y < ceilingY && distanceXZSquared < radius * radius) {\n this._agentDestinationArmed[index] = false;\n this.onReachTargetObservable.notifyObservers({\n agentIndex: agentIndex,\n destination: this._agentDestination[index],\n });\n }\n }\n }\n }\n\n /**\n * Set the Bounding box extent for doing spatial queries (getClosestPoint, getRandomPointAround, ...)\n * The queries will try to find a solution within those bounds\n * default is (1,1,1)\n * @param extent x,y,z value that define the extent around the queries point of reference\n */\n setDefaultQueryExtent(extent: IVector3Like): void {\n this._navigationPlugin.setDefaultQueryExtent(extent);\n }\n\n /**\n * Get the Bounding box extent specified by setDefaultQueryExtent\n * @returns the box extent values\n */\n getDefaultQueryExtent(): Vector3 {\n const p = this._navigationPlugin.getDefaultQueryExtent();\n return new Vector3(p.x, p.y, p.z);\n }\n\n /**\n * Get the Bounding box extent result specified by setDefaultQueryExtent\n * @param result output the box extent values\n */\n getDefaultQueryExtentToRef(result: Vector3): void {\n const p = this._navigationPlugin.getDefaultQueryExtent();\n result.set(p.x, p.y, p.z);\n }\n\n /**\n * Get the next corner points composing the path (max 4 points)\n * @param index agent index returned by addAgent\n * @returns array containing world position composing the path\n */\n public getCorners(index: number): Vector3[] {\n const corners = this._recastCrowd.getAgent(index)?.corners();\n if (!corners) {\n return [];\n }\n\n const positions = [];\n for (let i = 0; i < corners.length; i++) {\n positions.push(new Vector3(corners[i].x, corners[i].y, corners[i].z));\n }\n return positions;\n }\n\n /**\n * Release all resources\n */\n public dispose(): void {\n this._recastCrowd.destroy();\n\n if (this._onBeforeAnimationsObserver) {\n this._scene.onBeforeAnimationsObservable.remove(this._onBeforeAnimationsObserver);\n this._onBeforeAnimationsObserver = null;\n }\n\n this.onReachTargetObservable.clear();\n }\n}\n"]}