@babylonjs/core 5.45.0 → 5.45.2
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/thinEngine.js +2 -2
- package/Engines/thinEngine.js.map +1 -1
- package/Inputs/scene.inputManager.js +12 -1
- package/Inputs/scene.inputManager.js.map +1 -1
- package/Materials/Node/Blocks/Fragment/perturbNormalBlock.d.ts +7 -0
- package/Materials/Node/Blocks/Fragment/perturbNormalBlock.js +30 -1
- package/Materials/Node/Blocks/Fragment/perturbNormalBlock.js.map +1 -1
- package/Materials/Textures/texture.d.ts +2 -2
- package/Materials/Textures/texture.js +2 -2
- package/Materials/Textures/texture.js.map +1 -1
- package/Materials/Textures/videoTexture.d.ts +1 -0
- package/Materials/Textures/videoTexture.js +19 -8
- package/Materials/Textures/videoTexture.js.map +1 -1
- package/Materials/clipPlaneMaterialHelper.js +22 -19
- package/Materials/clipPlaneMaterialHelper.js.map +1 -1
- package/Misc/khronosTextureContainer2.js +3 -5
- package/Misc/khronosTextureContainer2.js.map +1 -1
- package/Physics/index.d.ts +1 -0
- package/Physics/index.js +1 -0
- package/Physics/index.js.map +1 -1
- package/Physics/physicsHelper.d.ts +452 -1
- package/Physics/physicsHelper.js +877 -2
- package/Physics/physicsHelper.js.map +1 -1
- package/Physics/v1/index.d.ts +0 -1
- package/Physics/v1/index.js +0 -1
- package/Physics/v1/index.js.map +1 -1
- package/Physics/v2/IPhysicsEnginePlugin.d.ts +8 -1
- package/Physics/v2/IPhysicsEnginePlugin.js.map +1 -1
- package/Physics/v2/index.d.ts +1 -0
- package/Physics/v2/index.js +1 -0
- package/Physics/v2/index.js.map +1 -1
- package/Physics/v2/physicsAggregate.d.ts +39 -19
- package/Physics/v2/physicsAggregate.js +61 -5
- package/Physics/v2/physicsAggregate.js.map +1 -1
- package/Physics/v2/physicsBody.d.ts +37 -1
- package/Physics/v2/physicsBody.js +71 -1
- package/Physics/v2/physicsBody.js.map +1 -1
- package/Physics/v2/physicsEngine.d.ts +7 -2
- package/Physics/v2/physicsEngine.js +9 -2
- package/Physics/v2/physicsEngine.js.map +1 -1
- package/Physics/v2/physicsShape.d.ts +30 -44
- package/Physics/v2/physicsShape.js +30 -44
- package/Physics/v2/physicsShape.js.map +1 -1
- package/Shaders/ShadersInclude/bumpFragment.js +1 -0
- package/Shaders/ShadersInclude/bumpFragment.js.map +1 -1
- package/Shaders/ShadersInclude/bumpFragmentMainFunctions.js +4 -1
- package/Shaders/ShadersInclude/bumpFragmentMainFunctions.js.map +1 -1
- package/Shaders/sprites.fragment.js +1 -1
- package/Shaders/sprites.fragment.js.map +1 -1
- package/assetContainer.js +1 -1
- package/assetContainer.js.map +1 -1
- package/package.json +1 -1
- package/Physics/v1/physicsHelper.d.ts +0 -411
- package/Physics/v1/physicsHelper.js +0 -709
- package/Physics/v1/physicsHelper.js.map +0 -1
package/Physics/physicsHelper.js
CHANGED
|
@@ -1,3 +1,878 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { Logger } from "../Misc/logger.js";
|
|
2
|
+
import { Vector3 } from "../Maths/math.vector.js";
|
|
3
|
+
import { CreateSphere } from "../Meshes/Builders/sphereBuilder.js";
|
|
4
|
+
import { CreateCylinder } from "../Meshes/Builders/cylinderBuilder.js";
|
|
5
|
+
import { Ray } from "../Culling/ray.js";
|
|
6
|
+
/**
|
|
7
|
+
* A helper for physics simulations
|
|
8
|
+
* @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine#further-functionality-of-the-impostor-class
|
|
9
|
+
*/
|
|
10
|
+
export class PhysicsHelper {
|
|
11
|
+
/**
|
|
12
|
+
* Initializes the Physics helper
|
|
13
|
+
* @param scene Babylon.js scene
|
|
14
|
+
*/
|
|
15
|
+
constructor(scene) {
|
|
16
|
+
this._hitData = { force: new Vector3(), contactPoint: new Vector3(), distanceFromOrigin: 0 };
|
|
17
|
+
this._scene = scene;
|
|
18
|
+
this._physicsEngine = this._scene.getPhysicsEngine();
|
|
19
|
+
if (!this._physicsEngine) {
|
|
20
|
+
Logger.Warn("Physics engine not enabled. Please enable the physics before you can use the methods.");
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Applies a radial explosion impulse
|
|
26
|
+
* @param origin the origin of the explosion
|
|
27
|
+
* @param radiusOrEventOptions the radius or the options of radial explosion
|
|
28
|
+
* @param strength the explosion strength
|
|
29
|
+
* @param falloff possible options: Constant & Linear. Defaults to Constant
|
|
30
|
+
* @returns A physics radial explosion event, or null
|
|
31
|
+
*/
|
|
32
|
+
applyRadialExplosionImpulse(origin, radiusOrEventOptions, strength, falloff) {
|
|
33
|
+
if (!this._physicsEngine) {
|
|
34
|
+
Logger.Warn("Physics engine not enabled. Please enable the physics before you call this method.");
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
if (this._physicsEngine.getPluginVersion() === 1 && this._physicsEngine.getImpostors().length === 0) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
if (this._physicsEngine.getPluginVersion() === 2 && this._physicsEngine.getBodies().length === 0) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
let useCallback = false;
|
|
44
|
+
if (typeof radiusOrEventOptions === "number") {
|
|
45
|
+
const r = radiusOrEventOptions;
|
|
46
|
+
radiusOrEventOptions = new PhysicsRadialExplosionEventOptions();
|
|
47
|
+
radiusOrEventOptions.radius = r;
|
|
48
|
+
radiusOrEventOptions.strength = strength !== null && strength !== void 0 ? strength : radiusOrEventOptions.strength;
|
|
49
|
+
radiusOrEventOptions.falloff = falloff !== null && falloff !== void 0 ? falloff : radiusOrEventOptions.falloff;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
useCallback = !!(radiusOrEventOptions.affectedImpostorsCallback || radiusOrEventOptions.affectedBodiesCallback);
|
|
53
|
+
}
|
|
54
|
+
const event = new PhysicsRadialExplosionEvent(this._scene, radiusOrEventOptions);
|
|
55
|
+
const hitData = this._hitData;
|
|
56
|
+
if (this._physicsEngine.getPluginVersion() === 1) {
|
|
57
|
+
const affectedImpostorsWithData = Array();
|
|
58
|
+
const impostors = this._physicsEngine.getImpostors();
|
|
59
|
+
impostors.forEach((impostor) => {
|
|
60
|
+
if (!event.getImpostorHitData(impostor, origin, hitData)) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
impostor.applyImpulse(hitData.force, hitData.contactPoint);
|
|
64
|
+
if (useCallback) {
|
|
65
|
+
affectedImpostorsWithData.push({
|
|
66
|
+
impostor: impostor,
|
|
67
|
+
hitData: this._copyPhysicsHitData(hitData),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
event.triggerAffectedImpostorsCallback(affectedImpostorsWithData);
|
|
72
|
+
}
|
|
73
|
+
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
|
+
}
|
|
87
|
+
});
|
|
88
|
+
event.triggerAffectedBodiesCallback(affectedBodiesWithData);
|
|
89
|
+
}
|
|
90
|
+
event.dispose(false);
|
|
91
|
+
return event;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Applies a radial explosion force
|
|
95
|
+
* @param origin the origin of the explosion
|
|
96
|
+
* @param radiusOrEventOptions the radius or the options of radial explosion
|
|
97
|
+
* @param strength the explosion strength
|
|
98
|
+
* @param falloff possible options: Constant & Linear. Defaults to Constant
|
|
99
|
+
* @returns A physics radial explosion event, or null
|
|
100
|
+
*/
|
|
101
|
+
applyRadialExplosionForce(origin, radiusOrEventOptions, strength, falloff) {
|
|
102
|
+
if (!this._physicsEngine) {
|
|
103
|
+
Logger.Warn("Physics engine not enabled. Please enable the physics before you call the PhysicsHelper.");
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
if (this._physicsEngine.getPluginVersion() === 1 && this._physicsEngine.getImpostors().length === 0) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
if (this._physicsEngine.getPluginVersion() === 2 && this._physicsEngine.getBodies().length === 0) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
let useCallback = false;
|
|
113
|
+
if (typeof radiusOrEventOptions === "number") {
|
|
114
|
+
const r = radiusOrEventOptions;
|
|
115
|
+
radiusOrEventOptions = new PhysicsRadialExplosionEventOptions();
|
|
116
|
+
radiusOrEventOptions.radius = r;
|
|
117
|
+
radiusOrEventOptions.strength = strength !== null && strength !== void 0 ? strength : radiusOrEventOptions.strength;
|
|
118
|
+
radiusOrEventOptions.falloff = falloff !== null && falloff !== void 0 ? falloff : radiusOrEventOptions.falloff;
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
useCallback = !!(radiusOrEventOptions.affectedImpostorsCallback || radiusOrEventOptions.affectedBodiesCallback);
|
|
122
|
+
}
|
|
123
|
+
const event = new PhysicsRadialExplosionEvent(this._scene, radiusOrEventOptions);
|
|
124
|
+
const hitData = this._hitData;
|
|
125
|
+
if (this._physicsEngine.getPluginVersion() === 1) {
|
|
126
|
+
const affectedImpostorsWithData = Array();
|
|
127
|
+
const impostors = this._physicsEngine.getImpostors();
|
|
128
|
+
impostors.forEach((impostor) => {
|
|
129
|
+
if (!event.getImpostorHitData(impostor, origin, hitData)) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
impostor.applyForce(hitData.force, hitData.contactPoint);
|
|
133
|
+
if (useCallback) {
|
|
134
|
+
affectedImpostorsWithData.push({
|
|
135
|
+
impostor: impostor,
|
|
136
|
+
hitData: this._copyPhysicsHitData(hitData),
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
event.triggerAffectedImpostorsCallback(affectedImpostorsWithData);
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
const affectedBodiesWithData = Array();
|
|
144
|
+
const bodies = this._physicsEngine.getBodies();
|
|
145
|
+
bodies.forEach((body) => {
|
|
146
|
+
if (!event.getBodyHitData(body, origin, hitData)) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
body.applyForce(hitData.force, hitData.contactPoint);
|
|
150
|
+
if (useCallback) {
|
|
151
|
+
affectedBodiesWithData.push({
|
|
152
|
+
body: body,
|
|
153
|
+
hitData: this._copyPhysicsHitData(hitData),
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
event.triggerAffectedBodiesCallback(affectedBodiesWithData);
|
|
158
|
+
}
|
|
159
|
+
event.dispose(false);
|
|
160
|
+
return event;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Creates a gravitational field
|
|
164
|
+
* @param origin the origin of the gravitational field
|
|
165
|
+
* @param radiusOrEventOptions the radius or the options of radial gravitational field
|
|
166
|
+
* @param strength the gravitational field strength
|
|
167
|
+
* @param falloff possible options: Constant & Linear. Defaults to Constant
|
|
168
|
+
* @returns A physics gravitational field event, or null
|
|
169
|
+
*/
|
|
170
|
+
gravitationalField(origin, radiusOrEventOptions, strength, falloff) {
|
|
171
|
+
if (!this._physicsEngine) {
|
|
172
|
+
Logger.Warn("Physics engine not enabled. Please enable the physics before you call the PhysicsHelper.");
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
if (this._physicsEngine.getPluginVersion() === 1 && this._physicsEngine.getImpostors().length === 0) {
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
if (this._physicsEngine.getPluginVersion() === 2 && this._physicsEngine.getBodies().length === 0) {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
if (typeof radiusOrEventOptions === "number") {
|
|
182
|
+
const r = radiusOrEventOptions;
|
|
183
|
+
radiusOrEventOptions = new PhysicsRadialExplosionEventOptions();
|
|
184
|
+
radiusOrEventOptions.radius = r;
|
|
185
|
+
radiusOrEventOptions.strength = strength !== null && strength !== void 0 ? strength : radiusOrEventOptions.strength;
|
|
186
|
+
radiusOrEventOptions.falloff = falloff !== null && falloff !== void 0 ? falloff : radiusOrEventOptions.falloff;
|
|
187
|
+
}
|
|
188
|
+
const event = new PhysicsGravitationalFieldEvent(this, this._scene, origin, radiusOrEventOptions);
|
|
189
|
+
event.dispose(false);
|
|
190
|
+
return event;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Creates a physics updraft event
|
|
194
|
+
* @param origin the origin of the updraft
|
|
195
|
+
* @param radiusOrEventOptions the radius or the options of the updraft
|
|
196
|
+
* @param strength the strength of the updraft
|
|
197
|
+
* @param height the height of the updraft
|
|
198
|
+
* @param updraftMode possible options: Center & Perpendicular. Defaults to Center
|
|
199
|
+
* @returns A physics updraft event, or null
|
|
200
|
+
*/
|
|
201
|
+
updraft(origin, radiusOrEventOptions, strength, height, updraftMode) {
|
|
202
|
+
if (!this._physicsEngine) {
|
|
203
|
+
Logger.Warn("Physics engine not enabled. Please enable the physics before you call the PhysicsHelper.");
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
if (this._physicsEngine.getPluginVersion() === 1 && this._physicsEngine.getImpostors().length === 0) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
if (this._physicsEngine.getPluginVersion() === 2 && this._physicsEngine.getBodies().length === 0) {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
if (typeof radiusOrEventOptions === "number") {
|
|
213
|
+
const r = radiusOrEventOptions;
|
|
214
|
+
radiusOrEventOptions = new PhysicsUpdraftEventOptions();
|
|
215
|
+
radiusOrEventOptions.radius = r;
|
|
216
|
+
radiusOrEventOptions.strength = strength !== null && strength !== void 0 ? strength : radiusOrEventOptions.strength;
|
|
217
|
+
radiusOrEventOptions.height = height !== null && height !== void 0 ? height : radiusOrEventOptions.height;
|
|
218
|
+
radiusOrEventOptions.updraftMode = updraftMode !== null && updraftMode !== void 0 ? updraftMode : radiusOrEventOptions.updraftMode;
|
|
219
|
+
}
|
|
220
|
+
const event = new PhysicsUpdraftEvent(this._scene, origin, radiusOrEventOptions);
|
|
221
|
+
event.dispose(false);
|
|
222
|
+
return event;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Creates a physics vortex event
|
|
226
|
+
* @param origin the of the vortex
|
|
227
|
+
* @param radiusOrEventOptions the radius or the options of the vortex
|
|
228
|
+
* @param strength the strength of the vortex
|
|
229
|
+
* @param height the height of the vortex
|
|
230
|
+
* @returns a Physics vortex event, or null
|
|
231
|
+
* A physics vortex event or null
|
|
232
|
+
*/
|
|
233
|
+
vortex(origin, radiusOrEventOptions, strength, height) {
|
|
234
|
+
if (!this._physicsEngine) {
|
|
235
|
+
Logger.Warn("Physics engine not enabled. Please enable the physics before you call the PhysicsHelper.");
|
|
236
|
+
return null;
|
|
237
|
+
}
|
|
238
|
+
if (this._physicsEngine.getPluginVersion() === 1 && this._physicsEngine.getImpostors().length === 0) {
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
if (this._physicsEngine.getPluginVersion() === 2 && this._physicsEngine.getBodies().length === 0) {
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
if (typeof radiusOrEventOptions === "number") {
|
|
245
|
+
const r = radiusOrEventOptions;
|
|
246
|
+
radiusOrEventOptions = new PhysicsVortexEventOptions();
|
|
247
|
+
radiusOrEventOptions.radius = r;
|
|
248
|
+
radiusOrEventOptions.strength = strength !== null && strength !== void 0 ? strength : radiusOrEventOptions.strength;
|
|
249
|
+
radiusOrEventOptions.height = height !== null && height !== void 0 ? height : radiusOrEventOptions.height;
|
|
250
|
+
}
|
|
251
|
+
const event = new PhysicsVortexEvent(this._scene, origin, radiusOrEventOptions);
|
|
252
|
+
event.dispose(false);
|
|
253
|
+
return event;
|
|
254
|
+
}
|
|
255
|
+
_copyPhysicsHitData(data) {
|
|
256
|
+
return { force: data.force.clone(), contactPoint: data.contactPoint.clone(), distanceFromOrigin: data.distanceFromOrigin };
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Represents a physics radial explosion event
|
|
261
|
+
*/
|
|
262
|
+
class PhysicsRadialExplosionEvent {
|
|
263
|
+
/**
|
|
264
|
+
* Initializes a radial explosion event
|
|
265
|
+
* @param _scene BabylonJS scene
|
|
266
|
+
* @param _options The options for the vortex event
|
|
267
|
+
*/
|
|
268
|
+
constructor(_scene, _options) {
|
|
269
|
+
this._scene = _scene;
|
|
270
|
+
this._options = _options;
|
|
271
|
+
this._dataFetched = false; // check if the data has been fetched. If not, do cleanup
|
|
272
|
+
this._options = { ...new PhysicsRadialExplosionEventOptions(), ...this._options };
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Returns the data related to the radial explosion event (sphere).
|
|
276
|
+
* @returns The radial explosion event data
|
|
277
|
+
*/
|
|
278
|
+
getData() {
|
|
279
|
+
this._dataFetched = true;
|
|
280
|
+
return {
|
|
281
|
+
sphere: this._sphere,
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
_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) {
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
const distanceFromOrigin = Vector3.Distance(origin, contactPoint);
|
|
293
|
+
if (distanceFromOrigin > this._options.radius) {
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
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;
|
|
300
|
+
data.distanceFromOrigin = distanceFromOrigin;
|
|
301
|
+
return true;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* 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
|
|
306
|
+
* @param origin the origin of the explosion
|
|
307
|
+
* @returns A physics force and contact point, or null
|
|
308
|
+
*/
|
|
309
|
+
getBodyHitData(body, origin, data) {
|
|
310
|
+
if (body.transformNode.getClassName() !== "Mesh" && body.transformNode.getClassName() !== "InstancedMesh") {
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
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;
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Returns the force and contact point of the impostor or false, if the impostor is not affected by the force/impulse.
|
|
323
|
+
* @param impostor A physics imposter
|
|
324
|
+
* @param origin the origin of the explosion
|
|
325
|
+
* @returns A physics force and contact point, or null
|
|
326
|
+
*/
|
|
327
|
+
getImpostorHitData(impostor, origin, data) {
|
|
328
|
+
if (impostor.mass === 0) {
|
|
329
|
+
return false;
|
|
330
|
+
}
|
|
331
|
+
if (impostor.object.getClassName() !== "Mesh" && impostor.object.getClassName() !== "InstancedMesh") {
|
|
332
|
+
return false;
|
|
333
|
+
}
|
|
334
|
+
const mesh = impostor.object;
|
|
335
|
+
if (!this._intersectsWithSphere(mesh, origin, this._options.radius)) {
|
|
336
|
+
return false;
|
|
337
|
+
}
|
|
338
|
+
const impostorObjectCenter = impostor.getObjectCenter();
|
|
339
|
+
this._getHitData(mesh, impostorObjectCenter, origin, data);
|
|
340
|
+
return true;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Triggers affected impostors callbacks
|
|
344
|
+
* @param affectedImpostorsWithData defines the list of affected impostors (including associated data)
|
|
345
|
+
*/
|
|
346
|
+
triggerAffectedImpostorsCallback(affectedImpostorsWithData) {
|
|
347
|
+
if (this._options.affectedImpostorsCallback) {
|
|
348
|
+
this._options.affectedImpostorsCallback(affectedImpostorsWithData);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Triggers affected bodies callbacks
|
|
353
|
+
* @param affectedBodiesWithData defines the list of affected bodies (including associated data)
|
|
354
|
+
*/
|
|
355
|
+
triggerAffectedBodiesCallback(affectedBodiesWithData) {
|
|
356
|
+
if (this._options.affectedBodiesCallback) {
|
|
357
|
+
this._options.affectedBodiesCallback(affectedBodiesWithData);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Disposes the sphere.
|
|
362
|
+
* @param force Specifies if the sphere should be disposed by force
|
|
363
|
+
*/
|
|
364
|
+
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);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
/*** Helpers ***/
|
|
377
|
+
_prepareSphere() {
|
|
378
|
+
if (!this._sphere) {
|
|
379
|
+
this._sphere = CreateSphere("radialExplosionEventSphere", this._options.sphere, this._scene);
|
|
380
|
+
this._sphere.isVisible = false;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
_intersectsWithSphere(mesh, origin, radius) {
|
|
384
|
+
this._prepareSphere();
|
|
385
|
+
this._sphere.position = origin;
|
|
386
|
+
this._sphere.scaling.setAll(radius * 2);
|
|
387
|
+
this._sphere._updateBoundingInfo();
|
|
388
|
+
this._sphere.computeWorldMatrix(true);
|
|
389
|
+
return this._sphere.intersectsMesh(mesh, true);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Represents a gravitational field event
|
|
394
|
+
*/
|
|
395
|
+
class PhysicsGravitationalFieldEvent {
|
|
396
|
+
/**
|
|
397
|
+
* Initializes the physics gravitational field event
|
|
398
|
+
* @param _physicsHelper A physics helper
|
|
399
|
+
* @param _scene BabylonJS scene
|
|
400
|
+
* @param _origin The origin position of the gravitational field event
|
|
401
|
+
* @param _options The options for the vortex event
|
|
402
|
+
*/
|
|
403
|
+
constructor(_physicsHelper, _scene, _origin, _options) {
|
|
404
|
+
this._physicsHelper = _physicsHelper;
|
|
405
|
+
this._scene = _scene;
|
|
406
|
+
this._origin = _origin;
|
|
407
|
+
this._options = _options;
|
|
408
|
+
this._dataFetched = false; // check if the has been fetched the data. If not, do cleanup
|
|
409
|
+
this._options = { ...new PhysicsRadialExplosionEventOptions(), ...this._options };
|
|
410
|
+
this._tickCallback = this._tick.bind(this);
|
|
411
|
+
this._options.strength = this._options.strength * -1;
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Returns the data related to the gravitational field event (sphere).
|
|
415
|
+
* @returns A gravitational field event
|
|
416
|
+
*/
|
|
417
|
+
getData() {
|
|
418
|
+
this._dataFetched = true;
|
|
419
|
+
return {
|
|
420
|
+
sphere: this._sphere,
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Enables the gravitational field.
|
|
425
|
+
*/
|
|
426
|
+
enable() {
|
|
427
|
+
this._tickCallback.call(this);
|
|
428
|
+
this._scene.registerBeforeRender(this._tickCallback);
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Disables the gravitational field.
|
|
432
|
+
*/
|
|
433
|
+
disable() {
|
|
434
|
+
this._scene.unregisterBeforeRender(this._tickCallback);
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Disposes the sphere.
|
|
438
|
+
* @param force The force to dispose from the gravitational field event
|
|
439
|
+
*/
|
|
440
|
+
dispose(force = true) {
|
|
441
|
+
if (force) {
|
|
442
|
+
this._sphere.dispose();
|
|
443
|
+
}
|
|
444
|
+
else {
|
|
445
|
+
setTimeout(() => {
|
|
446
|
+
if (!this._dataFetched) {
|
|
447
|
+
this._sphere.dispose();
|
|
448
|
+
}
|
|
449
|
+
}, 0);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
_tick() {
|
|
453
|
+
// Since the params won't change, we fetch the event only once
|
|
454
|
+
if (this._sphere) {
|
|
455
|
+
this._physicsHelper.applyRadialExplosionForce(this._origin, this._options);
|
|
456
|
+
}
|
|
457
|
+
else {
|
|
458
|
+
const radialExplosionEvent = this._physicsHelper.applyRadialExplosionForce(this._origin, this._options);
|
|
459
|
+
if (radialExplosionEvent) {
|
|
460
|
+
this._sphere = radialExplosionEvent.getData().sphere.clone("radialExplosionEventSphereClone");
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Represents a physics updraft event
|
|
467
|
+
*/
|
|
468
|
+
class PhysicsUpdraftEvent {
|
|
469
|
+
/**
|
|
470
|
+
* Initializes the physics updraft event
|
|
471
|
+
* @param _scene BabylonJS scene
|
|
472
|
+
* @param _origin The origin position of the updraft
|
|
473
|
+
* @param _options The options for the updraft event
|
|
474
|
+
*/
|
|
475
|
+
constructor(_scene, _origin, _options) {
|
|
476
|
+
this._scene = _scene;
|
|
477
|
+
this._origin = _origin;
|
|
478
|
+
this._options = _options;
|
|
479
|
+
this._originTop = Vector3.Zero(); // the most upper part of the cylinder
|
|
480
|
+
this._originDirection = Vector3.Zero(); // used if the updraftMode is perpendicular
|
|
481
|
+
this._cylinderPosition = Vector3.Zero(); // to keep the cylinders position, because normally the origin is in the center and not on the bottom
|
|
482
|
+
this._dataFetched = false; // check if the has been fetched the data. If not, do cleanup
|
|
483
|
+
this._physicsEngine = this._scene.getPhysicsEngine();
|
|
484
|
+
this._options = { ...new PhysicsUpdraftEventOptions(), ...this._options };
|
|
485
|
+
this._origin.addToRef(new Vector3(0, this._options.height / 2, 0), this._cylinderPosition);
|
|
486
|
+
this._origin.addToRef(new Vector3(0, this._options.height, 0), this._originTop);
|
|
487
|
+
if (this._options.updraftMode === PhysicsUpdraftMode.Perpendicular) {
|
|
488
|
+
this._originDirection = this._origin.subtract(this._originTop).normalize();
|
|
489
|
+
}
|
|
490
|
+
this._tickCallback = this._tick.bind(this);
|
|
491
|
+
this._prepareCylinder();
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Returns the data related to the updraft event (cylinder).
|
|
495
|
+
* @returns A physics updraft event
|
|
496
|
+
*/
|
|
497
|
+
getData() {
|
|
498
|
+
this._dataFetched = true;
|
|
499
|
+
return {
|
|
500
|
+
cylinder: this._cylinder,
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* Enables the updraft.
|
|
505
|
+
*/
|
|
506
|
+
enable() {
|
|
507
|
+
this._tickCallback.call(this);
|
|
508
|
+
this._scene.registerBeforeRender(this._tickCallback);
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Disables the updraft.
|
|
512
|
+
*/
|
|
513
|
+
disable() {
|
|
514
|
+
this._scene.unregisterBeforeRender(this._tickCallback);
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* Disposes the cylinder.
|
|
518
|
+
* @param force Specifies if the updraft should be disposed by force
|
|
519
|
+
*/
|
|
520
|
+
dispose(force = true) {
|
|
521
|
+
if (!this._cylinder) {
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
if (force) {
|
|
525
|
+
this._cylinder.dispose();
|
|
526
|
+
}
|
|
527
|
+
else {
|
|
528
|
+
setTimeout(() => {
|
|
529
|
+
if (!this._dataFetched) {
|
|
530
|
+
this._cylinder.dispose();
|
|
531
|
+
}
|
|
532
|
+
}, 0);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
_getHitData(center, data) {
|
|
536
|
+
let direction;
|
|
537
|
+
if (this._options.updraftMode === PhysicsUpdraftMode.Perpendicular) {
|
|
538
|
+
direction = this._originDirection;
|
|
539
|
+
}
|
|
540
|
+
else {
|
|
541
|
+
direction = center.subtract(this._originTop);
|
|
542
|
+
}
|
|
543
|
+
const distanceFromOrigin = Vector3.Distance(this._origin, center);
|
|
544
|
+
const multiplier = this._options.strength * -1;
|
|
545
|
+
const force = direction.multiplyByFloats(multiplier, multiplier, multiplier);
|
|
546
|
+
data.force = force;
|
|
547
|
+
data.contactPoint = center;
|
|
548
|
+
data.distanceFromOrigin = distanceFromOrigin;
|
|
549
|
+
}
|
|
550
|
+
_getBodyHitData(body, data) {
|
|
551
|
+
if (body.transformNode.getClassName() !== "Mesh" && body.transformNode.getClassName() !== "InstancedMesh") {
|
|
552
|
+
return false;
|
|
553
|
+
}
|
|
554
|
+
const bodyObject = body.transformNode;
|
|
555
|
+
if (!this._intersectsWithCylinder(bodyObject)) {
|
|
556
|
+
return false;
|
|
557
|
+
}
|
|
558
|
+
const center = body.getObjectCenter();
|
|
559
|
+
this._getHitData(center, data);
|
|
560
|
+
return true;
|
|
561
|
+
}
|
|
562
|
+
_getImpostorHitData(impostor, data) {
|
|
563
|
+
if (impostor.mass === 0) {
|
|
564
|
+
return false;
|
|
565
|
+
}
|
|
566
|
+
const impostorObject = impostor.object;
|
|
567
|
+
if (!this._intersectsWithCylinder(impostorObject)) {
|
|
568
|
+
return false;
|
|
569
|
+
}
|
|
570
|
+
const center = impostor.getObjectCenter();
|
|
571
|
+
this._getHitData(center, data);
|
|
572
|
+
return true;
|
|
573
|
+
}
|
|
574
|
+
_tick() {
|
|
575
|
+
const hitData = PhysicsUpdraftEvent.hitData;
|
|
576
|
+
if (this._physicsEngine.getPluginVersion() === 1) {
|
|
577
|
+
this._physicsEngine.getImpostors().forEach((impostor) => {
|
|
578
|
+
if (!this._getImpostorHitData(impostor, hitData)) {
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
impostor.applyForce(hitData.force, hitData.contactPoint);
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
else {
|
|
585
|
+
// V2
|
|
586
|
+
this._physicsEngine.getBodies().forEach((body) => {
|
|
587
|
+
if (!this._getBodyHitData(body, hitData)) {
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
body.applyForce(hitData.force, hitData.contactPoint);
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
/*** Helpers ***/
|
|
595
|
+
_prepareCylinder() {
|
|
596
|
+
if (!this._cylinder) {
|
|
597
|
+
this._cylinder = CreateCylinder("updraftEventCylinder", {
|
|
598
|
+
height: this._options.height,
|
|
599
|
+
diameter: this._options.radius * 2,
|
|
600
|
+
}, this._scene);
|
|
601
|
+
this._cylinder.isVisible = false;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
_intersectsWithCylinder(mesh) {
|
|
605
|
+
this._cylinder.position = this._cylinderPosition;
|
|
606
|
+
return this._cylinder.intersectsMesh(mesh, true);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
PhysicsUpdraftEvent.hitData = { force: new Vector3(), contactPoint: new Vector3(), distanceFromOrigin: 0 };
|
|
610
|
+
/**
|
|
611
|
+
* Represents a physics vortex event
|
|
612
|
+
*/
|
|
613
|
+
class PhysicsVortexEvent {
|
|
614
|
+
/**
|
|
615
|
+
* Initializes the physics vortex event
|
|
616
|
+
* @param _scene The BabylonJS scene
|
|
617
|
+
* @param _origin The origin position of the vortex
|
|
618
|
+
* @param _options The options for the vortex event
|
|
619
|
+
*/
|
|
620
|
+
constructor(_scene, _origin, _options) {
|
|
621
|
+
this._scene = _scene;
|
|
622
|
+
this._origin = _origin;
|
|
623
|
+
this._options = _options;
|
|
624
|
+
this._originTop = Vector3.Zero(); // the most upper part of the cylinder
|
|
625
|
+
this._cylinderPosition = Vector3.Zero(); // to keep the cylinders position, because normally the origin is in the center and not on the bottom
|
|
626
|
+
this._dataFetched = false; // check if the has been fetched the data. If not, do cleanup
|
|
627
|
+
this._physicsEngine = this._scene.getPhysicsEngine();
|
|
628
|
+
this._options = { ...new PhysicsVortexEventOptions(), ...this._options };
|
|
629
|
+
this._origin.addToRef(new Vector3(0, this._options.height / 2, 0), this._cylinderPosition);
|
|
630
|
+
this._origin.addToRef(new Vector3(0, this._options.height, 0), this._originTop);
|
|
631
|
+
this._tickCallback = this._tick.bind(this);
|
|
632
|
+
this._prepareCylinder();
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
635
|
+
* Returns the data related to the vortex event (cylinder).
|
|
636
|
+
* @returns The physics vortex event data
|
|
637
|
+
*/
|
|
638
|
+
getData() {
|
|
639
|
+
this._dataFetched = true;
|
|
640
|
+
return {
|
|
641
|
+
cylinder: this._cylinder,
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* Enables the vortex.
|
|
646
|
+
*/
|
|
647
|
+
enable() {
|
|
648
|
+
this._tickCallback.call(this);
|
|
649
|
+
this._scene.registerBeforeRender(this._tickCallback);
|
|
650
|
+
}
|
|
651
|
+
/**
|
|
652
|
+
* Disables the cortex.
|
|
653
|
+
*/
|
|
654
|
+
disable() {
|
|
655
|
+
this._scene.unregisterBeforeRender(this._tickCallback);
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* Disposes the sphere.
|
|
659
|
+
* @param force
|
|
660
|
+
*/
|
|
661
|
+
dispose(force = true) {
|
|
662
|
+
if (force) {
|
|
663
|
+
this._cylinder.dispose();
|
|
664
|
+
}
|
|
665
|
+
else {
|
|
666
|
+
setTimeout(() => {
|
|
667
|
+
if (!this._dataFetched) {
|
|
668
|
+
this._cylinder.dispose();
|
|
669
|
+
}
|
|
670
|
+
}, 0);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
_getHitData(mesh, center, data) {
|
|
674
|
+
const originOnPlane = PhysicsVortexEvent.originOnPlane;
|
|
675
|
+
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) {
|
|
681
|
+
return false;
|
|
682
|
+
}
|
|
683
|
+
const absoluteDistanceFromOrigin = hit.distance / this._options.radius;
|
|
684
|
+
let directionToOrigin = contactPoint.normalize();
|
|
685
|
+
if (absoluteDistanceFromOrigin > this._options.centripetalForceThreshold) {
|
|
686
|
+
directionToOrigin = directionToOrigin.negate();
|
|
687
|
+
}
|
|
688
|
+
let forceX;
|
|
689
|
+
let forceY;
|
|
690
|
+
let forceZ;
|
|
691
|
+
if (absoluteDistanceFromOrigin > this._options.centripetalForceThreshold) {
|
|
692
|
+
forceX = directionToOrigin.x * this._options.centripetalForceMultiplier;
|
|
693
|
+
forceY = directionToOrigin.y * this._options.updraftForceMultiplier;
|
|
694
|
+
forceZ = directionToOrigin.z * this._options.centripetalForceMultiplier;
|
|
695
|
+
}
|
|
696
|
+
else {
|
|
697
|
+
const perpendicularDirection = Vector3.Cross(originOnPlane, center).normalize();
|
|
698
|
+
forceX = (perpendicularDirection.x + directionToOrigin.x) * this._options.centrifugalForceMultiplier;
|
|
699
|
+
forceY = this._originTop.y * this._options.updraftForceMultiplier;
|
|
700
|
+
forceZ = (perpendicularDirection.z + directionToOrigin.z) * this._options.centrifugalForceMultiplier;
|
|
701
|
+
}
|
|
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;
|
|
706
|
+
data.distanceFromOrigin = absoluteDistanceFromOrigin;
|
|
707
|
+
return true;
|
|
708
|
+
}
|
|
709
|
+
_getBodyHitData(body, data) {
|
|
710
|
+
if (body.transformNode.getClassName() !== "Mesh" && body.transformNode.getClassName() !== "InstancedMesh") {
|
|
711
|
+
return false;
|
|
712
|
+
}
|
|
713
|
+
const bodyObject = body.transformNode;
|
|
714
|
+
if (!this._intersectsWithCylinder(bodyObject)) {
|
|
715
|
+
return false;
|
|
716
|
+
}
|
|
717
|
+
const bodyCenter = body.getObjectCenter();
|
|
718
|
+
this._getHitData(bodyObject, bodyCenter, data);
|
|
719
|
+
return true;
|
|
720
|
+
}
|
|
721
|
+
_getImpostorHitData(impostor, data) {
|
|
722
|
+
if (impostor.mass === 0) {
|
|
723
|
+
return false;
|
|
724
|
+
}
|
|
725
|
+
if (impostor.object.getClassName() !== "Mesh" && impostor.object.getClassName() !== "InstancedMesh") {
|
|
726
|
+
return false;
|
|
727
|
+
}
|
|
728
|
+
const impostorObject = impostor.object;
|
|
729
|
+
if (!this._intersectsWithCylinder(impostorObject)) {
|
|
730
|
+
return false;
|
|
731
|
+
}
|
|
732
|
+
const impostorObjectCenter = impostor.getObjectCenter();
|
|
733
|
+
this._getHitData(impostorObject, impostorObjectCenter, data);
|
|
734
|
+
return true;
|
|
735
|
+
}
|
|
736
|
+
_tick() {
|
|
737
|
+
const hitData = PhysicsVortexEvent.hitData;
|
|
738
|
+
if (this._physicsEngine.getPluginVersion() === 1) {
|
|
739
|
+
this._physicsEngine.getImpostors().forEach((impostor) => {
|
|
740
|
+
if (!this._getImpostorHitData(impostor, hitData)) {
|
|
741
|
+
return;
|
|
742
|
+
}
|
|
743
|
+
impostor.applyForce(hitData.force, hitData.contactPoint);
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
else {
|
|
747
|
+
this._physicsEngine.getBodies().forEach((body) => {
|
|
748
|
+
if (!this._getBodyHitData(body, hitData)) {
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
body.applyForce(hitData.force, hitData.contactPoint);
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
/*** Helpers ***/
|
|
756
|
+
_prepareCylinder() {
|
|
757
|
+
if (!this._cylinder) {
|
|
758
|
+
this._cylinder = CreateCylinder("vortexEventCylinder", {
|
|
759
|
+
height: this._options.height,
|
|
760
|
+
diameter: this._options.radius * 2,
|
|
761
|
+
}, this._scene);
|
|
762
|
+
this._cylinder.isVisible = false;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
_intersectsWithCylinder(mesh) {
|
|
766
|
+
this._cylinder.position = this._cylinderPosition;
|
|
767
|
+
return this._cylinder.intersectsMesh(mesh, true);
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
PhysicsVortexEvent.originOnPlane = Vector3.Zero();
|
|
771
|
+
PhysicsVortexEvent.hitData = { force: new Vector3(), contactPoint: new Vector3(), distanceFromOrigin: 0 };
|
|
772
|
+
/**
|
|
773
|
+
* Options fot the radial explosion event
|
|
774
|
+
* @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine#further-functionality-of-the-impostor-class
|
|
775
|
+
*/
|
|
776
|
+
export class PhysicsRadialExplosionEventOptions {
|
|
777
|
+
constructor() {
|
|
778
|
+
/**
|
|
779
|
+
* The radius of the sphere for the radial explosion.
|
|
780
|
+
*/
|
|
781
|
+
this.radius = 5;
|
|
782
|
+
/**
|
|
783
|
+
* The strength of the explosion.
|
|
784
|
+
*/
|
|
785
|
+
this.strength = 10;
|
|
786
|
+
/**
|
|
787
|
+
* The strength of the force in correspondence to the distance of the affected object
|
|
788
|
+
*/
|
|
789
|
+
this.falloff = PhysicsRadialImpulseFalloff.Constant;
|
|
790
|
+
/**
|
|
791
|
+
* Sphere options for the radial explosion.
|
|
792
|
+
*/
|
|
793
|
+
this.sphere = { segments: 32, diameter: 1 };
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
/**
|
|
797
|
+
* Options fot the updraft event
|
|
798
|
+
* @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine#further-functionality-of-the-impostor-class
|
|
799
|
+
*/
|
|
800
|
+
export class PhysicsUpdraftEventOptions {
|
|
801
|
+
constructor() {
|
|
802
|
+
/**
|
|
803
|
+
* The radius of the cylinder for the vortex
|
|
804
|
+
*/
|
|
805
|
+
this.radius = 5;
|
|
806
|
+
/**
|
|
807
|
+
* The strength of the updraft.
|
|
808
|
+
*/
|
|
809
|
+
this.strength = 10;
|
|
810
|
+
/**
|
|
811
|
+
* The height of the cylinder for the updraft.
|
|
812
|
+
*/
|
|
813
|
+
this.height = 10;
|
|
814
|
+
/**
|
|
815
|
+
* The mode for the the updraft.
|
|
816
|
+
*/
|
|
817
|
+
this.updraftMode = PhysicsUpdraftMode.Center;
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* Options fot the vortex event
|
|
822
|
+
* @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine#further-functionality-of-the-impostor-class
|
|
823
|
+
*/
|
|
824
|
+
export class PhysicsVortexEventOptions {
|
|
825
|
+
constructor() {
|
|
826
|
+
/**
|
|
827
|
+
* The radius of the cylinder for the vortex
|
|
828
|
+
*/
|
|
829
|
+
this.radius = 5;
|
|
830
|
+
/**
|
|
831
|
+
* The strength of the vortex.
|
|
832
|
+
*/
|
|
833
|
+
this.strength = 10;
|
|
834
|
+
/**
|
|
835
|
+
* The height of the cylinder for the vortex.
|
|
836
|
+
*/
|
|
837
|
+
this.height = 10;
|
|
838
|
+
/**
|
|
839
|
+
* At which distance, relative to the radius the centripetal forces should kick in? Range: 0-1
|
|
840
|
+
*/
|
|
841
|
+
this.centripetalForceThreshold = 0.7;
|
|
842
|
+
/**
|
|
843
|
+
* This multiplier determines with how much force the objects will be pushed sideways/around the vortex, when below the threshold.
|
|
844
|
+
*/
|
|
845
|
+
this.centripetalForceMultiplier = 5;
|
|
846
|
+
/**
|
|
847
|
+
* This multiplier determines with how much force the objects will be pushed sideways/around the vortex, when above the threshold.
|
|
848
|
+
*/
|
|
849
|
+
this.centrifugalForceMultiplier = 0.5;
|
|
850
|
+
/**
|
|
851
|
+
* This multiplier determines with how much force the objects will be pushed upwards, when in the vortex.
|
|
852
|
+
*/
|
|
853
|
+
this.updraftForceMultiplier = 0.02;
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* The strength of the force in correspondence to the distance of the affected object
|
|
858
|
+
* @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine#further-functionality-of-the-impostor-class
|
|
859
|
+
*/
|
|
860
|
+
export var PhysicsRadialImpulseFalloff;
|
|
861
|
+
(function (PhysicsRadialImpulseFalloff) {
|
|
862
|
+
/** Defines that impulse is constant in strength across it's whole radius */
|
|
863
|
+
PhysicsRadialImpulseFalloff[PhysicsRadialImpulseFalloff["Constant"] = 0] = "Constant";
|
|
864
|
+
/** Defines that impulse gets weaker if it's further from the origin */
|
|
865
|
+
PhysicsRadialImpulseFalloff[PhysicsRadialImpulseFalloff["Linear"] = 1] = "Linear";
|
|
866
|
+
})(PhysicsRadialImpulseFalloff || (PhysicsRadialImpulseFalloff = {}));
|
|
867
|
+
/**
|
|
868
|
+
* The strength of the force in correspondence to the distance of the affected object
|
|
869
|
+
* @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine#further-functionality-of-the-impostor-class
|
|
870
|
+
*/
|
|
871
|
+
export var PhysicsUpdraftMode;
|
|
872
|
+
(function (PhysicsUpdraftMode) {
|
|
873
|
+
/** Defines that the upstream forces will pull towards the top center of the cylinder */
|
|
874
|
+
PhysicsUpdraftMode[PhysicsUpdraftMode["Center"] = 0] = "Center";
|
|
875
|
+
/** Defines that once a impostor is inside the cylinder, it will shoot out perpendicular from the ground of the cylinder */
|
|
876
|
+
PhysicsUpdraftMode[PhysicsUpdraftMode["Perpendicular"] = 1] = "Perpendicular";
|
|
877
|
+
})(PhysicsUpdraftMode || (PhysicsUpdraftMode = {}));
|
|
3
878
|
//# sourceMappingURL=physicsHelper.js.map
|