@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.
- package/Engines/WebGPU/Extensions/engine.multiRender.js +51 -8
- package/Engines/WebGPU/Extensions/engine.multiRender.js.map +1 -1
- package/Engines/WebGPU/webgpuHardwareTexture.d.ts +4 -3
- package/Engines/WebGPU/webgpuHardwareTexture.js +23 -10
- package/Engines/WebGPU/webgpuHardwareTexture.js.map +1 -1
- package/Engines/WebGPU/webgpuTextureHelper.d.ts +1 -1
- package/Engines/WebGPU/webgpuTextureHelper.js +6 -14
- package/Engines/WebGPU/webgpuTextureHelper.js.map +1 -1
- package/Engines/engine.d.ts +5 -6
- package/Engines/thinEngine.js +2 -2
- package/Engines/thinEngine.js.map +1 -1
- package/Engines/webgpuEngine.js +16 -8
- package/Engines/webgpuEngine.js.map +1 -1
- package/Lights/Shadows/shadowGenerator.d.ts +2 -0
- package/Lights/Shadows/shadowGenerator.js +11 -22
- package/Lights/Shadows/shadowGenerator.js.map +1 -1
- package/Maths/math.vector.js +4 -2
- package/Maths/math.vector.js.map +1 -1
- package/Meshes/abstractMesh.d.ts +13 -0
- package/Meshes/abstractMesh.js +20 -0
- package/Meshes/abstractMesh.js.map +1 -1
- package/Meshes/thinInstanceMesh.js +4 -1
- package/Meshes/thinInstanceMesh.js.map +1 -1
- package/Particles/solidParticleSystem.d.ts +1 -1
- package/Particles/solidParticleSystem.js +1 -1
- package/Particles/solidParticleSystem.js.map +1 -1
- package/Physics/physicsEngineComponent.d.ts +1 -0
- package/Physics/physicsEngineComponent.js +1 -0
- package/Physics/physicsEngineComponent.js.map +1 -1
- package/Physics/physicsHelper.d.ts +12 -5
- package/Physics/physicsHelper.js +160 -90
- package/Physics/physicsHelper.js.map +1 -1
- package/Physics/physicsRaycastResult.d.ts +9 -0
- package/Physics/physicsRaycastResult.js.map +1 -1
- package/Physics/v2/IPhysicsEnginePlugin.d.ts +120 -77
- package/Physics/v2/IPhysicsEnginePlugin.js +119 -48
- package/Physics/v2/IPhysicsEnginePlugin.js.map +1 -1
- package/Physics/v2/Plugins/havokPlugin.d.ts +687 -0
- package/Physics/v2/Plugins/havokPlugin.js +1592 -0
- package/Physics/v2/Plugins/havokPlugin.js.map +1 -0
- package/Physics/v2/Plugins/index.d.ts +1 -0
- package/Physics/v2/Plugins/index.js +1 -1
- package/Physics/v2/Plugins/index.js.map +1 -1
- package/Physics/v2/index.d.ts +1 -0
- package/Physics/v2/index.js +2 -0
- package/Physics/v2/index.js.map +1 -1
- package/Physics/v2/physicsAggregate.d.ts +9 -2
- package/Physics/v2/physicsAggregate.js +66 -31
- package/Physics/v2/physicsAggregate.js.map +1 -1
- package/Physics/v2/physicsBody.d.ts +51 -62
- package/Physics/v2/physicsBody.js +101 -128
- package/Physics/v2/physicsBody.js.map +1 -1
- package/Physics/v2/physicsConstraint.d.ts +57 -25
- package/Physics/v2/physicsConstraint.js +32 -15
- package/Physics/v2/physicsConstraint.js.map +1 -1
- package/Physics/v2/physicsEngine.d.ts +0 -1
- package/Physics/v2/physicsEngine.js +0 -1
- package/Physics/v2/physicsEngine.js.map +1 -1
- package/Physics/v2/physicsEngineComponent.d.ts +0 -10
- package/Physics/v2/physicsEngineComponent.js +0 -29
- package/Physics/v2/physicsEngineComponent.js.map +1 -1
- package/Physics/v2/physicsShape.d.ts +52 -11
- package/Physics/v2/physicsShape.js +80 -23
- package/Physics/v2/physicsShape.js.map +1 -1
- package/package.json +1 -1
|
@@ -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
|
-
* @
|
|
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
|
|
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
|
|
419
|
+
cylinder?: Mesh;
|
|
413
420
|
}
|
|
414
421
|
/**
|
|
415
422
|
* Interface for vortex event data
|
package/Physics/physicsHelper.js
CHANGED
|
@@ -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
|
-
|
|
75
|
-
|
|
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
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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
|
|
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.
|
|
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 =
|
|
286
|
-
|
|
287
|
-
const
|
|
288
|
-
const
|
|
289
|
-
if (!
|
|
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
|
-
|
|
298
|
-
|
|
299
|
-
data.
|
|
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
|
-
* @
|
|
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
|
-
|
|
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
|
-
|
|
315
|
-
|
|
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 (
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
this.
|
|
372
|
-
|
|
373
|
-
|
|
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.
|
|
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
|
|
547
|
-
data.contactPoint
|
|
601
|
+
data.force.copyFrom(force);
|
|
602
|
+
data.contactPoint.copyFrom(center);
|
|
548
603
|
data.distanceFromOrigin = distanceFromOrigin;
|
|
549
604
|
}
|
|
550
|
-
_getBodyHitData(body, data) {
|
|
551
|
-
if (
|
|
605
|
+
_getBodyHitData(body, data, instanceIndex) {
|
|
606
|
+
if (HelperTools.HasAppliedForces(body)) {
|
|
552
607
|
return false;
|
|
553
608
|
}
|
|
554
|
-
const
|
|
555
|
-
if (!this.
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
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.
|
|
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.
|
|
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 =
|
|
677
|
-
|
|
678
|
-
const
|
|
679
|
-
const
|
|
680
|
-
if (!
|
|
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
|
|
684
|
-
|
|
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
|
|
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
|
-
|
|
703
|
-
force
|
|
704
|
-
|
|
705
|
-
data.
|
|
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 (
|
|
777
|
+
_getBodyHitData(body, data, instanceIndex) {
|
|
778
|
+
if (HelperTools.HasAppliedForces(body, instanceIndex)) {
|
|
711
779
|
return false;
|
|
712
780
|
}
|
|
713
781
|
const bodyObject = body.transformNode;
|
|
714
|
-
|
|
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
|
-
|
|
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
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
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
|
}
|