@babylonjs/core 5.57.0 → 6.0.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.
Files changed (65) hide show
  1. package/Engines/WebGPU/Extensions/engine.multiRender.js +51 -8
  2. package/Engines/WebGPU/Extensions/engine.multiRender.js.map +1 -1
  3. package/Engines/WebGPU/webgpuHardwareTexture.d.ts +4 -3
  4. package/Engines/WebGPU/webgpuHardwareTexture.js +23 -10
  5. package/Engines/WebGPU/webgpuHardwareTexture.js.map +1 -1
  6. package/Engines/WebGPU/webgpuTextureHelper.d.ts +1 -1
  7. package/Engines/WebGPU/webgpuTextureHelper.js +6 -14
  8. package/Engines/WebGPU/webgpuTextureHelper.js.map +1 -1
  9. package/Engines/engine.d.ts +5 -6
  10. package/Engines/thinEngine.js +2 -2
  11. package/Engines/thinEngine.js.map +1 -1
  12. package/Engines/webgpuEngine.js +16 -8
  13. package/Engines/webgpuEngine.js.map +1 -1
  14. package/Lights/Shadows/shadowGenerator.d.ts +2 -0
  15. package/Lights/Shadows/shadowGenerator.js +11 -22
  16. package/Lights/Shadows/shadowGenerator.js.map +1 -1
  17. package/Maths/math.vector.js +4 -2
  18. package/Maths/math.vector.js.map +1 -1
  19. package/Meshes/abstractMesh.d.ts +13 -0
  20. package/Meshes/abstractMesh.js +20 -0
  21. package/Meshes/abstractMesh.js.map +1 -1
  22. package/Meshes/thinInstanceMesh.js +4 -1
  23. package/Meshes/thinInstanceMesh.js.map +1 -1
  24. package/Particles/solidParticleSystem.d.ts +1 -1
  25. package/Particles/solidParticleSystem.js +1 -1
  26. package/Particles/solidParticleSystem.js.map +1 -1
  27. package/Physics/physicsEngineComponent.d.ts +1 -0
  28. package/Physics/physicsEngineComponent.js +1 -0
  29. package/Physics/physicsEngineComponent.js.map +1 -1
  30. package/Physics/physicsHelper.d.ts +12 -5
  31. package/Physics/physicsHelper.js +160 -90
  32. package/Physics/physicsHelper.js.map +1 -1
  33. package/Physics/physicsRaycastResult.d.ts +9 -0
  34. package/Physics/physicsRaycastResult.js.map +1 -1
  35. package/Physics/v2/IPhysicsEnginePlugin.d.ts +120 -77
  36. package/Physics/v2/IPhysicsEnginePlugin.js +119 -48
  37. package/Physics/v2/IPhysicsEnginePlugin.js.map +1 -1
  38. package/Physics/v2/Plugins/havokPlugin.d.ts +687 -0
  39. package/Physics/v2/Plugins/havokPlugin.js +1592 -0
  40. package/Physics/v2/Plugins/havokPlugin.js.map +1 -0
  41. package/Physics/v2/Plugins/index.d.ts +1 -0
  42. package/Physics/v2/Plugins/index.js +1 -1
  43. package/Physics/v2/Plugins/index.js.map +1 -1
  44. package/Physics/v2/index.d.ts +1 -0
  45. package/Physics/v2/index.js +2 -0
  46. package/Physics/v2/index.js.map +1 -1
  47. package/Physics/v2/physicsAggregate.d.ts +9 -2
  48. package/Physics/v2/physicsAggregate.js +66 -31
  49. package/Physics/v2/physicsAggregate.js.map +1 -1
  50. package/Physics/v2/physicsBody.d.ts +51 -62
  51. package/Physics/v2/physicsBody.js +101 -128
  52. package/Physics/v2/physicsBody.js.map +1 -1
  53. package/Physics/v2/physicsConstraint.d.ts +57 -25
  54. package/Physics/v2/physicsConstraint.js +32 -15
  55. package/Physics/v2/physicsConstraint.js.map +1 -1
  56. package/Physics/v2/physicsEngine.d.ts +0 -1
  57. package/Physics/v2/physicsEngine.js +0 -1
  58. package/Physics/v2/physicsEngine.js.map +1 -1
  59. package/Physics/v2/physicsEngineComponent.d.ts +0 -10
  60. package/Physics/v2/physicsEngineComponent.js +0 -29
  61. package/Physics/v2/physicsEngineComponent.js.map +1 -1
  62. package/Physics/v2/physicsShape.d.ts +52 -11
  63. package/Physics/v2/physicsShape.js +80 -23
  64. package/Physics/v2/physicsShape.js.map +1 -1
  65. package/package.json +1 -1
@@ -1,2 +1,3 @@
1
1
  import "./joinedPhysicsEngineComponent";
2
2
  import "./v1/physicsEngineComponent";
3
+ import "./v2/physicsEngineComponent";
@@ -1,4 +1,5 @@
1
1
  // back compat
2
2
  import "./joinedPhysicsEngineComponent.js";
3
3
  import "./v1/physicsEngineComponent.js";
4
+ import "./v2/physicsEngineComponent.js";
4
5
  //# sourceMappingURL=physicsEngineComponent.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"physicsEngineComponent.js","sourceRoot":"","sources":["../../../../lts/core/generated/Physics/physicsEngineComponent.ts"],"names":[],"mappings":"AAAA,cAAc;AAEd,OAAO,gCAAgC,CAAC;AACxC,OAAO,6BAA6B,CAAC","sourcesContent":["// back compat\r\n\r\nimport \"./joinedPhysicsEngineComponent\";\r\nimport \"./v1/physicsEngineComponent\";\r\n"]}
1
+ {"version":3,"file":"physicsEngineComponent.js","sourceRoot":"","sources":["../../../../lts/core/generated/Physics/physicsEngineComponent.ts"],"names":[],"mappings":"AAAA,cAAc;AAEd,OAAO,gCAAgC,CAAC;AACxC,OAAO,6BAA6B,CAAC;AACrC,OAAO,6BAA6B,CAAC","sourcesContent":["// back compat\r\n\r\nimport \"./joinedPhysicsEngineComponent\";\r\nimport \"./v1/physicsEngineComponent\";\r\nimport \"./v2/physicsEngineComponent\";\r\n"]}
@@ -35,6 +35,7 @@ export declare class PhysicsHelper {
35
35
  * @returns A physics radial explosion event, or null
36
36
  */
37
37
  applyRadialExplosionForce(origin: Vector3, radiusOrEventOptions: number | PhysicsRadialExplosionEventOptions, strength?: number, falloff?: PhysicsRadialImpulseFalloff): Nullable<PhysicsRadialExplosionEvent>;
38
+ private _applicationForBodies;
38
39
  /**
39
40
  * Creates a gravitational field
40
41
  * @param origin the origin of the gravitational field
@@ -88,11 +89,13 @@ declare class PhysicsRadialExplosionEvent {
88
89
  private _getHitData;
89
90
  /**
90
91
  * Returns the force and contact point of the body or false, if the body is not affected by the force/impulse.
91
- * @param body A physics body
92
+ * @param body A physics body where the transform node is an AbstractMesh
92
93
  * @param origin the origin of the explosion
93
- * @returns A physics force and contact point, or null
94
+ * @param data the data of the hit
95
+ * @param instanceIndex the instance index of the body
96
+ * @returns if there was a hit
94
97
  */
95
- getBodyHitData(body: PhysicsBody, origin: Vector3, data: PhysicsHitData): boolean;
98
+ getBodyHitData(body: PhysicsBody, origin: Vector3, data: PhysicsHitData, instanceIndex?: number): boolean;
96
99
  /**
97
100
  * Returns the force and contact point of the impostor or false, if the impostor is not affected by the force/impulse.
98
101
  * @param impostor A physics imposter
@@ -172,7 +175,7 @@ declare class PhysicsUpdraftEvent {
172
175
  private _cylinder;
173
176
  private _cylinderPosition;
174
177
  private _dataFetched;
175
- private static hitData;
178
+ private static _HitData;
176
179
  /**
177
180
  * Initializes the physics updraft event
178
181
  * @param _scene BabylonJS scene
@@ -380,6 +383,10 @@ export interface PhysicsHitData {
380
383
  * The distance from the origin to the contact point
381
384
  */
382
385
  distanceFromOrigin: number;
386
+ /**
387
+ * For an instanced physics body (mesh with thin instances), the index of the thin instance the hit applies to
388
+ */
389
+ instanceIndex?: number;
383
390
  }
384
391
  /**
385
392
  * Interface for radial explosion event data
@@ -409,7 +416,7 @@ export interface PhysicsUpdraftEventData {
409
416
  /**
410
417
  * A cylinder used for the updraft event
411
418
  */
412
- cylinder: Mesh;
419
+ cylinder?: Mesh;
413
420
  }
414
421
  /**
415
422
  * Interface for vortex event data
@@ -1,8 +1,57 @@
1
1
  import { Logger } from "../Misc/logger.js";
2
- import { Vector3 } from "../Maths/math.vector.js";
2
+ import { TmpVectors, Vector3 } from "../Maths/math.vector.js";
3
3
  import { CreateSphere } from "../Meshes/Builders/sphereBuilder.js";
4
4
  import { CreateCylinder } from "../Meshes/Builders/cylinderBuilder.js";
5
5
  import { Ray } from "../Culling/ray.js";
6
+ import { PhysicsMotionType } from "./v2/IPhysicsEnginePlugin.js";
7
+ class HelperTools {
8
+ /*
9
+ * Gets the hit contact point between a mesh and a ray. The method varies between
10
+ * the different plugin versions; V1 uses a mesh intersection, V2 uses the physics body instance/object center (to avoid a raycast and improve perf).
11
+ */
12
+ static GetContactPointToRef(mesh, origin, direction, result, instanceIndex) {
13
+ const engine = mesh.getScene().getPhysicsEngine();
14
+ const pluginVersion = engine === null || engine === void 0 ? void 0 : engine.getPluginVersion();
15
+ if (pluginVersion === 1) {
16
+ const ray = new Ray(origin, direction);
17
+ const hit = ray.intersectsMesh(mesh);
18
+ if (hit.hit && hit.pickedPoint) {
19
+ result.copyFrom(hit.pickedPoint);
20
+ return true;
21
+ }
22
+ }
23
+ else if (pluginVersion === 2) {
24
+ mesh.physicsBody.getObjectCenterWorldToRef(result, instanceIndex);
25
+ return true;
26
+ }
27
+ return false;
28
+ }
29
+ /**
30
+ * Checks if a body will be affected by forces
31
+ * @param body the body to check
32
+ * @param instanceIndex for instanced bodies, the index of the instance to check
33
+ * @returns
34
+ */
35
+ static HasAppliedForces(body, instanceIndex) {
36
+ var _a, _b, _c;
37
+ return (body.getMotionType(instanceIndex) === PhysicsMotionType.STATIC ||
38
+ ((_b = (_a = body.getMassProperties(instanceIndex)) === null || _a === void 0 ? void 0 : _a.mass) !== null && _b !== void 0 ? _b : 0) === 0 ||
39
+ ((_c = body.transformNode) === null || _c === void 0 ? void 0 : _c.getTotalVertices()) === 0);
40
+ }
41
+ /**
42
+ * Checks if a point is inside a cylinder
43
+ * @param point point to check
44
+ * @param origin cylinder origin on the bottom
45
+ * @param radius cylinder radius
46
+ * @param height cylinder height
47
+ * @returns
48
+ */
49
+ static IsInsideCylinder(point, origin, radius, height) {
50
+ const distance = TmpVectors.Vector3[0];
51
+ point.subtractToRef(origin, distance);
52
+ return Math.abs(distance.x) <= radius && Math.abs(distance.z) <= radius && distance.y >= 0 && distance.y <= height;
53
+ }
54
+ }
6
55
  /**
7
56
  * A helper for physics simulations
8
57
  * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine#further-functionality-of-the-impostor-class
@@ -71,21 +120,9 @@ export class PhysicsHelper {
71
120
  event.triggerAffectedImpostorsCallback(affectedImpostorsWithData);
72
121
  }
73
122
  else {
74
- const affectedBodiesWithData = Array();
75
- const bodies = this._physicsEngine.getBodies();
76
- bodies.forEach((body) => {
77
- if (!event.getBodyHitData(body, origin, hitData)) {
78
- return;
79
- }
80
- body.applyImpulse(hitData.force, hitData.contactPoint);
81
- if (useCallback) {
82
- affectedBodiesWithData.push({
83
- body: body,
84
- hitData: this._copyPhysicsHitData(hitData),
85
- });
86
- }
123
+ this._applicationForBodies(event, origin, hitData, useCallback, (body, hitData) => {
124
+ body.applyImpulse(hitData.force, hitData.contactPoint, hitData.instanceIndex);
87
125
  });
88
- event.triggerAffectedBodiesCallback(affectedBodiesWithData);
89
126
  }
90
127
  event.dispose(false);
91
128
  return event;
@@ -140,13 +177,22 @@ export class PhysicsHelper {
140
177
  event.triggerAffectedImpostorsCallback(affectedImpostorsWithData);
141
178
  }
142
179
  else {
143
- const affectedBodiesWithData = Array();
144
- const bodies = this._physicsEngine.getBodies();
145
- bodies.forEach((body) => {
146
- if (!event.getBodyHitData(body, origin, hitData)) {
180
+ this._applicationForBodies(event, origin, hitData, useCallback, (body, hitData) => {
181
+ body.applyForce(hitData.force, hitData.contactPoint, hitData.instanceIndex);
182
+ });
183
+ }
184
+ event.dispose(false);
185
+ return event;
186
+ }
187
+ _applicationForBodies(event, origin, hitData, useCallback, fnApplication) {
188
+ const affectedBodiesWithData = Array();
189
+ const bodies = this._physicsEngine.getBodies();
190
+ for (const body of bodies) {
191
+ body.iterateOverAllInstances((body, instanceIndex) => {
192
+ if (!event.getBodyHitData(body, origin, hitData, instanceIndex)) {
147
193
  return;
148
194
  }
149
- body.applyForce(hitData.force, hitData.contactPoint);
195
+ fnApplication(body, hitData);
150
196
  if (useCallback) {
151
197
  affectedBodiesWithData.push({
152
198
  body: body,
@@ -154,10 +200,8 @@ export class PhysicsHelper {
154
200
  });
155
201
  }
156
202
  });
157
- event.triggerAffectedBodiesCallback(affectedBodiesWithData);
158
203
  }
159
- event.dispose(false);
160
- return event;
204
+ event.triggerAffectedBodiesCallback(affectedBodiesWithData);
161
205
  }
162
206
  /**
163
207
  * Creates a gravitational field
@@ -253,7 +297,7 @@ export class PhysicsHelper {
253
297
  return event;
254
298
  }
255
299
  _copyPhysicsHitData(data) {
256
- return { force: data.force.clone(), contactPoint: data.contactPoint.clone(), distanceFromOrigin: data.distanceFromOrigin };
300
+ return { force: data.force.clone(), contactPoint: data.contactPoint.clone(), distanceFromOrigin: data.distanceFromOrigin, instanceIndex: data.instanceIndex };
257
301
  }
258
302
  }
259
303
  /**
@@ -282,11 +326,11 @@ class PhysicsRadialExplosionEvent {
282
326
  };
283
327
  }
284
328
  _getHitData(mesh, center, origin, data) {
285
- const direction = center.subtract(origin);
286
- const ray = new Ray(origin, direction, this._options.radius);
287
- const hit = ray.intersectsMesh(mesh);
288
- const contactPoint = hit.pickedPoint;
289
- if (!contactPoint) {
329
+ const direction = TmpVectors.Vector3[0];
330
+ direction.copyFrom(center).subtractInPlace(origin);
331
+ const contactPoint = TmpVectors.Vector3[1];
332
+ const hasContactPoint = HelperTools.GetContactPointToRef(mesh, origin, direction, contactPoint, data.instanceIndex);
333
+ if (!hasContactPoint) {
290
334
  return false;
291
335
  }
292
336
  const distanceFromOrigin = Vector3.Distance(origin, contactPoint);
@@ -294,29 +338,30 @@ class PhysicsRadialExplosionEvent {
294
338
  return false;
295
339
  }
296
340
  const multiplier = this._options.falloff === PhysicsRadialImpulseFalloff.Constant ? this._options.strength : this._options.strength * (1 - distanceFromOrigin / this._options.radius);
297
- const force = direction.multiplyByFloats(multiplier, multiplier, multiplier);
298
- data.force = force;
299
- data.contactPoint = contactPoint;
341
+ // Direction x multiplier equals force
342
+ direction.scaleInPlace(multiplier);
343
+ data.force.copyFrom(direction);
344
+ data.contactPoint.copyFrom(contactPoint);
300
345
  data.distanceFromOrigin = distanceFromOrigin;
301
346
  return true;
302
347
  }
303
348
  /**
304
349
  * Returns the force and contact point of the body or false, if the body is not affected by the force/impulse.
305
- * @param body A physics body
350
+ * @param body A physics body where the transform node is an AbstractMesh
306
351
  * @param origin the origin of the explosion
307
- * @returns A physics force and contact point, or null
352
+ * @param data the data of the hit
353
+ * @param instanceIndex the instance index of the body
354
+ * @returns if there was a hit
308
355
  */
309
- getBodyHitData(body, origin, data) {
310
- if (body.transformNode.getClassName() !== "Mesh" && body.transformNode.getClassName() !== "InstancedMesh") {
356
+ getBodyHitData(body, origin, data, instanceIndex) {
357
+ // No force will be applied in these cases, so we skip calculation
358
+ if (HelperTools.HasAppliedForces(body, instanceIndex)) {
311
359
  return false;
312
360
  }
313
361
  const mesh = body.transformNode;
314
- if (!this._intersectsWithSphere(mesh, origin, this._options.radius)) {
315
- return false;
316
- }
317
- const bodyObjectCenter = body.getObjectCenter();
318
- this._getHitData(mesh, bodyObjectCenter, origin, data);
319
- return true;
362
+ const bodyObjectCenter = body.getObjectCenterWorld(instanceIndex);
363
+ data.instanceIndex = instanceIndex;
364
+ return this._getHitData(mesh, bodyObjectCenter, origin, data);
320
365
  }
321
366
  /**
322
367
  * Returns the force and contact point of the impostor or false, if the impostor is not affected by the force/impulse.
@@ -362,15 +407,17 @@ class PhysicsRadialExplosionEvent {
362
407
  * @param force Specifies if the sphere should be disposed by force
363
408
  */
364
409
  dispose(force = true) {
365
- if (force) {
366
- this._sphere.dispose();
367
- }
368
- else {
369
- setTimeout(() => {
370
- if (!this._dataFetched) {
371
- this._sphere.dispose();
372
- }
373
- }, 0);
410
+ if (this._sphere) {
411
+ if (force) {
412
+ this._sphere.dispose();
413
+ }
414
+ else {
415
+ setTimeout(() => {
416
+ if (!this._dataFetched) {
417
+ this._sphere.dispose();
418
+ }
419
+ }, 0);
420
+ }
374
421
  }
375
422
  }
376
423
  /*** Helpers ***/
@@ -438,6 +485,9 @@ class PhysicsGravitationalFieldEvent {
438
485
  * @param force The force to dispose from the gravitational field event
439
486
  */
440
487
  dispose(force = true) {
488
+ if (!this._sphere) {
489
+ return;
490
+ }
441
491
  if (force) {
442
492
  this._sphere.dispose();
443
493
  }
@@ -450,6 +500,7 @@ class PhysicsGravitationalFieldEvent {
450
500
  }
451
501
  }
452
502
  _tick() {
503
+ var _a;
453
504
  // Since the params won't change, we fetch the event only once
454
505
  if (this._sphere) {
455
506
  this._physicsHelper.applyRadialExplosionForce(this._origin, this._options);
@@ -457,7 +508,7 @@ class PhysicsGravitationalFieldEvent {
457
508
  else {
458
509
  const radialExplosionEvent = this._physicsHelper.applyRadialExplosionForce(this._origin, this._options);
459
510
  if (radialExplosionEvent) {
460
- this._sphere = radialExplosionEvent.getData().sphere.clone("radialExplosionEventSphereClone");
511
+ this._sphere = (_a = radialExplosionEvent.getData().sphere) === null || _a === void 0 ? void 0 : _a.clone("radialExplosionEventSphereClone");
461
512
  }
462
513
  }
463
514
  }
@@ -488,7 +539,9 @@ class PhysicsUpdraftEvent {
488
539
  this._originDirection = this._origin.subtract(this._originTop).normalize();
489
540
  }
490
541
  this._tickCallback = this._tick.bind(this);
491
- this._prepareCylinder();
542
+ if (this._physicsEngine.getPluginVersion() === 1) {
543
+ this._prepareCylinder();
544
+ }
492
545
  }
493
546
  /**
494
547
  * Returns the data related to the updraft event (cylinder).
@@ -523,11 +576,13 @@ class PhysicsUpdraftEvent {
523
576
  }
524
577
  if (force) {
525
578
  this._cylinder.dispose();
579
+ this._cylinder = undefined;
526
580
  }
527
581
  else {
528
582
  setTimeout(() => {
529
- if (!this._dataFetched) {
583
+ if (!this._dataFetched && this._cylinder) {
530
584
  this._cylinder.dispose();
585
+ this._cylinder = undefined;
531
586
  }
532
587
  }, 0);
533
588
  }
@@ -543,19 +598,19 @@ class PhysicsUpdraftEvent {
543
598
  const distanceFromOrigin = Vector3.Distance(this._origin, center);
544
599
  const multiplier = this._options.strength * -1;
545
600
  const force = direction.multiplyByFloats(multiplier, multiplier, multiplier);
546
- data.force = force;
547
- data.contactPoint = center;
601
+ data.force.copyFrom(force);
602
+ data.contactPoint.copyFrom(center);
548
603
  data.distanceFromOrigin = distanceFromOrigin;
549
604
  }
550
- _getBodyHitData(body, data) {
551
- if (body.transformNode.getClassName() !== "Mesh" && body.transformNode.getClassName() !== "InstancedMesh") {
605
+ _getBodyHitData(body, data, instanceIndex) {
606
+ if (HelperTools.HasAppliedForces(body)) {
552
607
  return false;
553
608
  }
554
- const bodyObject = body.transformNode;
555
- if (!this._intersectsWithCylinder(bodyObject)) {
609
+ const center = body.getObjectCenterWorld(instanceIndex);
610
+ if (!HelperTools.IsInsideCylinder(center, this._origin, this._options.radius, this._options.height)) {
556
611
  return false;
557
612
  }
558
- const center = body.getObjectCenter();
613
+ data.instanceIndex = instanceIndex;
559
614
  this._getHitData(center, data);
560
615
  return true;
561
616
  }
@@ -572,7 +627,7 @@ class PhysicsUpdraftEvent {
572
627
  return true;
573
628
  }
574
629
  _tick() {
575
- const hitData = PhysicsUpdraftEvent.hitData;
630
+ const hitData = PhysicsUpdraftEvent._HitData;
576
631
  if (this._physicsEngine.getPluginVersion() === 1) {
577
632
  this._physicsEngine.getImpostors().forEach((impostor) => {
578
633
  if (!this._getImpostorHitData(impostor, hitData)) {
@@ -584,10 +639,12 @@ class PhysicsUpdraftEvent {
584
639
  else {
585
640
  // V2
586
641
  this._physicsEngine.getBodies().forEach((body) => {
587
- if (!this._getBodyHitData(body, hitData)) {
588
- return;
589
- }
590
- body.applyForce(hitData.force, hitData.contactPoint);
642
+ body.iterateOverAllInstances((body, instanceIndex) => {
643
+ if (!this._getBodyHitData(body, hitData, instanceIndex)) {
644
+ return;
645
+ }
646
+ body.applyForce(hitData.force, hitData.contactPoint, hitData.instanceIndex);
647
+ });
591
648
  });
592
649
  }
593
650
  }
@@ -602,11 +659,14 @@ class PhysicsUpdraftEvent {
602
659
  }
603
660
  }
604
661
  _intersectsWithCylinder(mesh) {
662
+ if (!this._cylinder) {
663
+ return false;
664
+ }
605
665
  this._cylinder.position = this._cylinderPosition;
606
666
  return this._cylinder.intersectsMesh(mesh, true);
607
667
  }
608
668
  }
609
- PhysicsUpdraftEvent.hitData = { force: new Vector3(), contactPoint: new Vector3(), distanceFromOrigin: 0 };
669
+ PhysicsUpdraftEvent._HitData = { force: new Vector3(), contactPoint: new Vector3(), distanceFromOrigin: 0 };
610
670
  /**
611
671
  * Represents a physics vortex event
612
672
  */
@@ -629,7 +689,9 @@ class PhysicsVortexEvent {
629
689
  this._origin.addToRef(new Vector3(0, this._options.height / 2, 0), this._cylinderPosition);
630
690
  this._origin.addToRef(new Vector3(0, this._options.height, 0), this._originTop);
631
691
  this._tickCallback = this._tick.bind(this);
632
- this._prepareCylinder();
692
+ if (this._physicsEngine.getPluginVersion() === 1) {
693
+ this._prepareCylinder();
694
+ }
633
695
  }
634
696
  /**
635
697
  * Returns the data related to the vortex event (cylinder).
@@ -659,6 +721,9 @@ class PhysicsVortexEvent {
659
721
  * @param force
660
722
  */
661
723
  dispose(force = true) {
724
+ if (!this._cylinder) {
725
+ return;
726
+ }
662
727
  if (force) {
663
728
  this._cylinder.dispose();
664
729
  }
@@ -673,17 +738,19 @@ class PhysicsVortexEvent {
673
738
  _getHitData(mesh, center, data) {
674
739
  const originOnPlane = PhysicsVortexEvent.originOnPlane;
675
740
  originOnPlane.set(this._origin.x, center.y, this._origin.z); // the distance to the origin as if both objects were on a plane (Y-axis)
676
- const originToImpostorDirection = center.subtract(originOnPlane);
677
- const ray = new Ray(originOnPlane, originToImpostorDirection, this._options.radius);
678
- const hit = ray.intersectsMesh(mesh);
679
- const contactPoint = hit.pickedPoint;
680
- if (!contactPoint) {
741
+ const originToImpostorDirection = TmpVectors.Vector3[0];
742
+ center.subtractToRef(originOnPlane, originToImpostorDirection);
743
+ const contactPoint = TmpVectors.Vector3[1];
744
+ const hasContactPoint = HelperTools.GetContactPointToRef(mesh, originOnPlane, originToImpostorDirection, contactPoint, data.instanceIndex);
745
+ if (!hasContactPoint) {
681
746
  return false;
682
747
  }
683
- const absoluteDistanceFromOrigin = hit.distance / this._options.radius;
684
- let directionToOrigin = contactPoint.normalize();
748
+ const distance = Vector3.Distance(contactPoint, originOnPlane);
749
+ const absoluteDistanceFromOrigin = distance / this._options.radius;
750
+ const directionToOrigin = TmpVectors.Vector3[2];
751
+ contactPoint.normalizeToRef(directionToOrigin);
685
752
  if (absoluteDistanceFromOrigin > this._options.centripetalForceThreshold) {
686
- directionToOrigin = directionToOrigin.negate();
753
+ directionToOrigin.negateInPlace();
687
754
  }
688
755
  let forceX;
689
756
  let forceY;
@@ -699,24 +766,25 @@ class PhysicsVortexEvent {
699
766
  forceY = this._originTop.y * this._options.updraftForceMultiplier;
700
767
  forceZ = (perpendicularDirection.z + directionToOrigin.z) * this._options.centrifugalForceMultiplier;
701
768
  }
702
- let force = new Vector3(forceX, forceY, forceZ);
703
- force = force.multiplyByFloats(this._options.strength, this._options.strength, this._options.strength);
704
- data.force = force;
705
- data.contactPoint = center;
769
+ const force = TmpVectors.Vector3[3];
770
+ force.set(forceX, forceY, forceZ);
771
+ force.scaleInPlace(this._options.strength);
772
+ data.force.copyFrom(force);
773
+ data.contactPoint.copyFrom(center);
706
774
  data.distanceFromOrigin = absoluteDistanceFromOrigin;
707
775
  return true;
708
776
  }
709
- _getBodyHitData(body, data) {
710
- if (body.transformNode.getClassName() !== "Mesh" && body.transformNode.getClassName() !== "InstancedMesh") {
777
+ _getBodyHitData(body, data, instanceIndex) {
778
+ if (HelperTools.HasAppliedForces(body, instanceIndex)) {
711
779
  return false;
712
780
  }
713
781
  const bodyObject = body.transformNode;
714
- if (!this._intersectsWithCylinder(bodyObject)) {
782
+ const bodyCenter = body.getObjectCenterWorld(instanceIndex);
783
+ if (!HelperTools.IsInsideCylinder(bodyCenter, this._origin, this._options.radius, this._options.height)) {
715
784
  return false;
716
785
  }
717
- const bodyCenter = body.getObjectCenter();
718
- this._getHitData(bodyObject, bodyCenter, data);
719
- return true;
786
+ data.instanceIndex = instanceIndex;
787
+ return this._getHitData(bodyObject, bodyCenter, data);
720
788
  }
721
789
  _getImpostorHitData(impostor, data) {
722
790
  if (impostor.mass === 0) {
@@ -745,10 +813,12 @@ class PhysicsVortexEvent {
745
813
  }
746
814
  else {
747
815
  this._physicsEngine.getBodies().forEach((body) => {
748
- if (!this._getBodyHitData(body, hitData)) {
749
- return;
750
- }
751
- body.applyForce(hitData.force, hitData.contactPoint);
816
+ body.iterateOverAllInstances((body, instanceIndex) => {
817
+ if (!this._getBodyHitData(body, hitData, instanceIndex)) {
818
+ return;
819
+ }
820
+ body.applyForce(hitData.force, hitData.contactPoint, hitData.instanceIndex);
821
+ });
752
822
  });
753
823
  }
754
824
  }