@babylonjs/core 8.4.0 → 8.4.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.
Files changed (68) hide show
  1. package/Collisions/gpuPicker.js +26 -14
  2. package/Collisions/gpuPicker.js.map +1 -1
  3. package/Engines/abstractEngine.js +2 -2
  4. package/Engines/abstractEngine.js.map +1 -1
  5. package/Materials/Textures/Loaders/EXR/exrLoader.decoder.js +24 -3
  6. package/Materials/Textures/Loaders/EXR/exrLoader.decoder.js.map +1 -1
  7. package/Materials/Textures/texture.js +1 -1
  8. package/Materials/Textures/texture.js.map +1 -1
  9. package/Materials/shadowDepthWrapper.js +6 -0
  10. package/Materials/shadowDepthWrapper.js.map +1 -1
  11. package/Materials/uniformBuffer.js +4 -0
  12. package/Materials/uniformBuffer.js.map +1 -1
  13. package/Meshes/GaussianSplatting/gaussianSplattingMesh.js +24 -7
  14. package/Meshes/GaussianSplatting/gaussianSplattingMesh.js.map +1 -1
  15. package/Meshes/geometry.js +30 -28
  16. package/Meshes/geometry.js.map +1 -1
  17. package/Meshes/mesh.vertexData.js +2 -2
  18. package/Meshes/mesh.vertexData.js.map +1 -1
  19. package/Misc/observable.d.ts +3 -2
  20. package/Misc/observable.js +5 -4
  21. package/Misc/observable.js.map +1 -1
  22. package/Particles/Queue/executionQueue.d.ts +18 -0
  23. package/Particles/Queue/executionQueue.js +28 -0
  24. package/Particles/Queue/executionQueue.js.map +1 -0
  25. package/Particles/attractor.d.ts +21 -0
  26. package/Particles/attractor.js +36 -0
  27. package/Particles/attractor.js.map +1 -0
  28. package/Particles/baseParticleSystem.d.ts +27 -13
  29. package/Particles/baseParticleSystem.js +34 -4
  30. package/Particles/baseParticleSystem.js.map +1 -1
  31. package/Particles/index.d.ts +1 -0
  32. package/Particles/index.js +1 -0
  33. package/Particles/index.js.map +1 -1
  34. package/Particles/particleSystem.d.ts +18 -0
  35. package/Particles/particleSystem.js +59 -0
  36. package/Particles/particleSystem.js.map +1 -1
  37. package/Particles/thinParticleSystem.d.ts +81 -12
  38. package/Particles/thinParticleSystem.function.d.ts +84 -0
  39. package/Particles/thinParticleSystem.function.js +340 -0
  40. package/Particles/thinParticleSystem.function.js.map +1 -0
  41. package/Particles/thinParticleSystem.js +380 -316
  42. package/Particles/thinParticleSystem.js.map +1 -1
  43. package/PostProcesses/RenderPipeline/Pipelines/lensRenderingPipeline.js +1 -0
  44. package/PostProcesses/RenderPipeline/Pipelines/lensRenderingPipeline.js.map +1 -1
  45. package/PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline.js +1 -0
  46. package/PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline.js.map +1 -1
  47. package/PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline.js +1 -0
  48. package/PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline.js.map +1 -1
  49. package/PostProcesses/RenderPipeline/Pipelines/ssrRenderingPipeline.js +1 -0
  50. package/PostProcesses/RenderPipeline/Pipelines/ssrRenderingPipeline.js.map +1 -1
  51. package/PostProcesses/RenderPipeline/Pipelines/standardRenderingPipeline.js +1 -0
  52. package/PostProcesses/RenderPipeline/Pipelines/standardRenderingPipeline.js.map +1 -1
  53. package/PostProcesses/RenderPipeline/Pipelines/taaRenderingPipeline.js +1 -0
  54. package/PostProcesses/RenderPipeline/Pipelines/taaRenderingPipeline.js.map +1 -1
  55. package/Rendering/IBLShadows/iblShadowsAccumulationPass.d.ts +2 -0
  56. package/Rendering/IBLShadows/iblShadowsAccumulationPass.js +22 -12
  57. package/Rendering/IBLShadows/iblShadowsAccumulationPass.js.map +1 -1
  58. package/Rendering/IBLShadows/iblShadowsRenderPipeline.js +1 -0
  59. package/Rendering/IBLShadows/iblShadowsRenderPipeline.js.map +1 -1
  60. package/Rendering/IBLShadows/iblShadowsSpatialBlurPass.d.ts +2 -0
  61. package/Rendering/IBLShadows/iblShadowsSpatialBlurPass.js +22 -12
  62. package/Rendering/IBLShadows/iblShadowsSpatialBlurPass.js.map +1 -1
  63. package/Rendering/IBLShadows/iblShadowsVoxelTracingPass.d.ts +2 -0
  64. package/Rendering/IBLShadows/iblShadowsVoxelTracingPass.js +28 -14
  65. package/Rendering/IBLShadows/iblShadowsVoxelTracingPass.js.map +1 -1
  66. package/ShadersWGSL/gaussianSplatting.vertex.js +1 -1
  67. package/ShadersWGSL/gaussianSplatting.vertex.js.map +1 -1
  68. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  import { FactorGradient, ColorGradient, Color3Gradient, GradientHelper } from "../Misc/gradients.js";
2
2
  import { Observable } from "../Misc/observable.js";
3
- import { Vector3, Matrix, Vector4, TmpVectors } from "../Maths/math.vector.js";
3
+ import { Vector3, Matrix, TmpVectors } from "../Maths/math.vector.js";
4
4
  import { VertexBuffer, Buffer } from "../Buffers/buffer.js";
5
5
  import { RawTexture } from "../Materials/Textures/rawTexture.js";
6
6
  import { EngineStore } from "../Engines/engineStore.js";
@@ -13,8 +13,10 @@ import "../Engines/Extensions/engine.alpha.js";
13
13
  import { addClipPlaneUniforms, prepareStringDefinesForClipPlanes, bindClipPlane } from "../Materials/clipPlaneMaterialHelper.js";
14
14
  import { BindFogParameters, BindLogDepth } from "../Materials/materialHelper.functions.js";
15
15
  import { BoxParticleEmitter } from "./EmitterTypes/boxParticleEmitter.js";
16
- import { Clamp, Lerp, RandomRange } from "../Maths/math.scalar.functions.js";
16
+ import { Lerp } from "../Maths/math.scalar.functions.js";
17
17
  import { PrepareSamplersForImageProcessing, PrepareUniformsForImageProcessing } from "../Materials/imageProcessingConfiguration.functions.js";
18
+ import { _CreateAngleData, _CreateAngleGradientsData, _CreateColorData, _CreateColorGradientsData, _CreateCustomDirectionData, _CreateCustomPositionData, _CreateDirectionData, _CreateDragData, _CreateEmitPowerData, _CreateIsLocalData, _CreateLifeGradientsData, _CreateLifetimeData, _CreateLimitVelocityGradients, _CreateNoiseData, _CreatePositionData, _CreateRampData, _CreateSheetData, _CreateSizeData, _CreateSizeGradientsData, _CreateStartSizeGradientsData, _CreateVelocityGradients, _ProcessAngularSpeed, _ProcessAngularSpeedGradients, _ProcessColor, _ProcessColorGradients, _ProcessDirection, _ProcessDragGradients, _ProcessGravity, _ProcessLimitVelocityGradients, _ProcessNoise, _ProcessPosition, _ProcessRemapGradients, _ProcessSizeGradients, _ProcessVelocityGradients, } from "./thinParticleSystem.function.js";
19
+ import { _ConnectAfter, _ConnectBefore, _RemoveFromQueue } from "./Queue/executionQueue.js";
18
20
  /**
19
21
  * This represents a thin particle system in Babylon.
20
22
  * Particles are often small sprites used to simulate hard-to-reproduce phenomena like fire, smoke, water, or abstract visual effects like magic glitter and faery dust.
@@ -23,6 +25,44 @@ import { PrepareSamplersForImageProcessing, PrepareUniformsForImageProcessing }
23
25
  * @example https://doc.babylonjs.com/features/featuresDeepDive/particles/particle_system/particle_system_intro
24
26
  */
25
27
  export class ThinParticleSystem extends BaseParticleSystem {
28
+ /**
29
+ * This function can be defined to specify initial direction for every new particle.
30
+ * It by default use the emitterType defined function
31
+ */
32
+ get startDirectionFunction() {
33
+ return this._startDirectionFunction;
34
+ }
35
+ set startDirectionFunction(value) {
36
+ if (this._startDirectionFunction === value) {
37
+ return;
38
+ }
39
+ this._startDirectionFunction = value;
40
+ if (value) {
41
+ this._directionProcessing.process = _CreateCustomDirectionData;
42
+ }
43
+ else {
44
+ this._directionProcessing.process = _CreateDirectionData;
45
+ }
46
+ }
47
+ /**
48
+ * This function can be defined to specify initial position for every new particle.
49
+ * It by default use the emitterType defined function
50
+ */
51
+ get startPositionFunction() {
52
+ return this._startPositionFunction;
53
+ }
54
+ set startPositionFunction(value) {
55
+ if (this._startPositionFunction === value) {
56
+ return;
57
+ }
58
+ this._startPositionFunction = value;
59
+ if (value) {
60
+ this._positionCreation.process = _CreateCustomPositionData;
61
+ }
62
+ else {
63
+ this._positionCreation.process = _CreatePositionData;
64
+ }
65
+ }
26
66
  /**
27
67
  * Sets a callback that will be triggered when the system is disposed
28
68
  */
@@ -44,6 +84,47 @@ export class ThinParticleSystem extends BaseParticleSystem {
44
84
  }
45
85
  this._useRampGradients = value;
46
86
  this._resetEffect();
87
+ if (value) {
88
+ this._rampCreation = {
89
+ process: _CreateRampData,
90
+ previousItem: null,
91
+ nextItem: null,
92
+ };
93
+ _ConnectAfter(this._rampCreation, this._colorCreation);
94
+ this._remapGradientProcessing = {
95
+ process: _ProcessRemapGradients,
96
+ previousItem: null,
97
+ nextItem: null,
98
+ };
99
+ _ConnectAfter(this._remapGradientProcessing, this._gravityProcessing);
100
+ }
101
+ else {
102
+ _RemoveFromQueue(this._rampCreation);
103
+ _RemoveFromQueue(this._remapGradientProcessing);
104
+ }
105
+ }
106
+ /**
107
+ * Specifies if the particles are updated in emitter local space or world space
108
+ */
109
+ get isLocal() {
110
+ return this._isLocal;
111
+ }
112
+ set isLocal(value) {
113
+ if (this._isLocal === value) {
114
+ return;
115
+ }
116
+ this._isLocal = value;
117
+ if (value) {
118
+ this._isLocalCreation = {
119
+ process: _CreateIsLocalData,
120
+ previousItem: null,
121
+ nextItem: null,
122
+ };
123
+ _ConnectAfter(this._isLocalCreation, this._positionCreation);
124
+ }
125
+ else {
126
+ _RemoveFromQueue(this._isLocalCreation);
127
+ }
47
128
  }
48
129
  /**
49
130
  * Gets the current list of active particles
@@ -57,6 +138,27 @@ export class ThinParticleSystem extends BaseParticleSystem {
57
138
  get shaderLanguage() {
58
139
  return this._shaderLanguage;
59
140
  }
141
+ /** @internal */
142
+ get _isAnimationSheetEnabled() {
143
+ return this._animationSheetEnabled;
144
+ }
145
+ set _isAnimationSheetEnabled(value) {
146
+ if (this._animationSheetEnabled === value) {
147
+ return;
148
+ }
149
+ this._animationSheetEnabled = value;
150
+ if (value) {
151
+ this._sheetCreation = {
152
+ process: _CreateSheetData,
153
+ previousItem: null,
154
+ nextItem: null,
155
+ };
156
+ _ConnectAfter(this._sheetCreation, this._colorCreation);
157
+ }
158
+ else {
159
+ _RemoveFromQueue(this._sheetCreation);
160
+ }
161
+ }
60
162
  /**
61
163
  * Gets the number of particles active at the same time.
62
164
  * @returns The number of active particles.
@@ -128,6 +230,32 @@ export class ThinParticleSystem extends BaseParticleSystem {
128
230
  get indexBuffer() {
129
231
  return this._indexBuffer;
130
232
  }
233
+ get noiseTexture() {
234
+ return this._noiseTexture;
235
+ }
236
+ set noiseTexture(value) {
237
+ if (this.noiseTexture === value) {
238
+ return;
239
+ }
240
+ this._noiseTexture = value;
241
+ if (!value) {
242
+ _RemoveFromQueue(this._noiseCreation);
243
+ _RemoveFromQueue(this._noiseProcessing);
244
+ return;
245
+ }
246
+ this._noiseCreation = {
247
+ process: _CreateNoiseData,
248
+ previousItem: null,
249
+ nextItem: null,
250
+ };
251
+ _ConnectAfter(this._noiseCreation, this._colorCreation);
252
+ this._noiseProcessing = {
253
+ process: _ProcessNoise,
254
+ previousItem: null,
255
+ nextItem: null,
256
+ };
257
+ _ConnectAfter(this._noiseProcessing, this._positionProcessing);
258
+ }
131
259
  /**
132
260
  * Instantiates a particle system.
133
261
  * Particles are often small sprites used to simulate hard-to-reproduce phenomena like fire, smoke, water, or abstract visual effects like magic glitter and faery dust.
@@ -140,7 +268,10 @@ export class ThinParticleSystem extends BaseParticleSystem {
140
268
  */
141
269
  constructor(name, capacity, sceneOrEngine, customEffect = null, isAnimationSheetEnabled = false, epsilon = 0.01) {
142
270
  super(name);
271
+ /** @internal */
143
272
  this._emitterInverseWorldMatrix = Matrix.Identity();
273
+ this._startDirectionFunction = null;
274
+ this._startPositionFunction = null;
144
275
  /**
145
276
  * @internal
146
277
  */
@@ -153,18 +284,27 @@ export class ThinParticleSystem extends BaseParticleSystem {
153
284
  * An event triggered when the system is stopped
154
285
  */
155
286
  this.onStoppedObservable = new Observable();
287
+ /** @internal */
288
+ this._noiseTextureSize = null;
289
+ /** @internal */
290
+ this._noiseTextureData = null;
156
291
  this._particles = new Array();
157
292
  this._stockParticles = new Array();
158
293
  this._newPartsExcess = 0;
159
294
  this._vertexBuffers = {};
295
+ /** @internal */
160
296
  this._scaledColorStep = new Color4(0, 0, 0, 0);
297
+ /** @internal */
161
298
  this._colorDiff = new Color4(0, 0, 0, 0);
299
+ /** @internal */
162
300
  this._scaledDirection = Vector3.Zero();
301
+ /** @internal */
163
302
  this._scaledGravity = Vector3.Zero();
164
303
  this._currentRenderId = -1;
165
304
  this._useInstancing = false;
166
305
  this._started = false;
167
306
  this._stopped = false;
307
+ /** @internal */
168
308
  this._actualFrame = 0;
169
309
  /** @internal */
170
310
  this._currentEmitRate1 = 0;
@@ -178,10 +318,10 @@ export class ThinParticleSystem extends BaseParticleSystem {
178
318
  this.updateInAnimate = true;
179
319
  this._rawTextureWidth = 256;
180
320
  this._useRampGradients = false;
181
- /**
182
- * Specifies if the particles are updated in emitter local space or world space
183
- */
184
- this.isLocal = false;
321
+ this._updateQueueStart = null;
322
+ this._startSizeCreation = null;
323
+ this._createQueueStart = null;
324
+ this._isLocal = false;
185
325
  /** Indicates that the particle system is CPU based */
186
326
  this.isGPU = false;
187
327
  /** Shader language used by the material */
@@ -247,152 +387,109 @@ export class ThinParticleSystem extends BaseParticleSystem {
247
387
  this._createVertexBuffers();
248
388
  // Default emitter type
249
389
  this.particleEmitterType = new BoxParticleEmitter();
250
- let noiseTextureData = null;
390
+ // Creation queue
391
+ this._lifeTimeCreation = {
392
+ process: _CreateLifetimeData,
393
+ previousItem: null,
394
+ nextItem: null,
395
+ };
396
+ this._positionCreation = {
397
+ process: _CreatePositionData,
398
+ previousItem: null,
399
+ nextItem: null,
400
+ };
401
+ _ConnectAfter(this._positionCreation, this._lifeTimeCreation);
402
+ this._directionCreation = {
403
+ process: _CreateDirectionData,
404
+ previousItem: null,
405
+ nextItem: null,
406
+ };
407
+ _ConnectAfter(this._directionCreation, this._positionCreation);
408
+ this._emitPowerCreation = {
409
+ process: _CreateEmitPowerData,
410
+ previousItem: null,
411
+ nextItem: null,
412
+ };
413
+ _ConnectAfter(this._emitPowerCreation, this._directionCreation);
414
+ this._sizeCreation = {
415
+ process: _CreateSizeData,
416
+ previousItem: null,
417
+ nextItem: null,
418
+ };
419
+ _ConnectAfter(this._sizeCreation, this._emitPowerCreation);
420
+ this._angleCreation = {
421
+ process: _CreateAngleData,
422
+ previousItem: null,
423
+ nextItem: null,
424
+ };
425
+ _ConnectAfter(this._angleCreation, this._sizeCreation);
426
+ this._colorCreation = {
427
+ process: _CreateColorData,
428
+ previousItem: null,
429
+ nextItem: null,
430
+ };
431
+ _ConnectAfter(this._colorCreation, this._angleCreation);
432
+ this._createQueueStart = this._lifeTimeCreation;
433
+ // Processing queue
434
+ this._colorProcessing = {
435
+ process: _ProcessColor,
436
+ previousItem: null,
437
+ nextItem: null,
438
+ };
439
+ this._angularSpeedProcessing = {
440
+ process: _ProcessAngularSpeed,
441
+ previousItem: null,
442
+ nextItem: null,
443
+ };
444
+ _ConnectAfter(this._angularSpeedProcessing, this._colorProcessing);
445
+ this._directionProcessing = {
446
+ process: _ProcessDirection,
447
+ previousItem: null,
448
+ nextItem: null,
449
+ };
450
+ _ConnectAfter(this._directionProcessing, this._angularSpeedProcessing);
451
+ this._positionProcessing = {
452
+ process: _ProcessPosition,
453
+ previousItem: null,
454
+ nextItem: null,
455
+ };
456
+ _ConnectAfter(this._positionProcessing, this._directionProcessing);
457
+ this._gravityProcessing = {
458
+ process: _ProcessGravity,
459
+ previousItem: null,
460
+ nextItem: null,
461
+ };
462
+ _ConnectAfter(this._gravityProcessing, this._positionProcessing);
463
+ this._updateQueueStart = this._colorProcessing;
251
464
  // Update
252
465
  this.updateFunction = (particles) => {
253
- let noiseTextureSize = null;
254
466
  if (this.noiseTexture) {
255
467
  // We need to get texture data back to CPU
256
- noiseTextureSize = this.noiseTexture.getSize();
468
+ this._noiseTextureSize = this.noiseTexture.getSize();
257
469
  this.noiseTexture.getContent()?.then((data) => {
258
- noiseTextureData = data;
470
+ this._noiseTextureData = data;
259
471
  });
260
472
  }
261
473
  const sameParticleArray = particles === this._particles;
262
474
  for (let index = 0; index < particles.length; index++) {
263
475
  const particle = particles[index];
264
- let scaledUpdateSpeed = this._scaledUpdateSpeed;
476
+ this._tempScaledUpdateSpeed = this._scaledUpdateSpeed;
265
477
  const previousAge = particle.age;
266
- particle.age += scaledUpdateSpeed;
478
+ particle.age += this._tempScaledUpdateSpeed;
267
479
  // Evaluate step to death
268
480
  if (particle.age > particle.lifeTime) {
269
481
  const diff = particle.age - previousAge;
270
482
  const oldDiff = particle.lifeTime - previousAge;
271
- scaledUpdateSpeed = (oldDiff * scaledUpdateSpeed) / diff;
483
+ this._tempScaledUpdateSpeed = (oldDiff * this._tempScaledUpdateSpeed) / diff;
272
484
  particle.age = particle.lifeTime;
273
485
  }
274
- const ratio = particle.age / particle.lifeTime;
275
- // Color
276
- if (this._colorGradients && this._colorGradients.length > 0) {
277
- GradientHelper.GetCurrentGradient(ratio, this._colorGradients, (currentGradient, nextGradient, scale) => {
278
- if (currentGradient !== particle._currentColorGradient) {
279
- particle._currentColor1.copyFrom(particle._currentColor2);
280
- nextGradient.getColorToRef(particle._currentColor2);
281
- particle._currentColorGradient = currentGradient;
282
- }
283
- Color4.LerpToRef(particle._currentColor1, particle._currentColor2, scale, particle.color);
284
- });
285
- }
286
- else {
287
- particle.colorStep.scaleToRef(scaledUpdateSpeed, this._scaledColorStep);
288
- particle.color.addInPlace(this._scaledColorStep);
289
- if (particle.color.a < 0) {
290
- particle.color.a = 0;
291
- }
292
- }
293
- // Angular speed
294
- if (this._angularSpeedGradients && this._angularSpeedGradients.length > 0) {
295
- GradientHelper.GetCurrentGradient(ratio, this._angularSpeedGradients, (currentGradient, nextGradient, scale) => {
296
- if (currentGradient !== particle._currentAngularSpeedGradient) {
297
- particle._currentAngularSpeed1 = particle._currentAngularSpeed2;
298
- particle._currentAngularSpeed2 = nextGradient.getFactor();
299
- particle._currentAngularSpeedGradient = currentGradient;
300
- }
301
- particle.angularSpeed = Lerp(particle._currentAngularSpeed1, particle._currentAngularSpeed2, scale);
302
- });
303
- }
304
- particle.angle += particle.angularSpeed * scaledUpdateSpeed;
305
- // Direction
306
- let directionScale = scaledUpdateSpeed;
307
- /// Velocity
308
- if (this._velocityGradients && this._velocityGradients.length > 0) {
309
- GradientHelper.GetCurrentGradient(ratio, this._velocityGradients, (currentGradient, nextGradient, scale) => {
310
- if (currentGradient !== particle._currentVelocityGradient) {
311
- particle._currentVelocity1 = particle._currentVelocity2;
312
- particle._currentVelocity2 = nextGradient.getFactor();
313
- particle._currentVelocityGradient = currentGradient;
314
- }
315
- directionScale *= Lerp(particle._currentVelocity1, particle._currentVelocity2, scale);
316
- });
317
- }
318
- particle.direction.scaleToRef(directionScale, this._scaledDirection);
319
- /// Limit velocity
320
- if (this._limitVelocityGradients && this._limitVelocityGradients.length > 0) {
321
- GradientHelper.GetCurrentGradient(ratio, this._limitVelocityGradients, (currentGradient, nextGradient, scale) => {
322
- if (currentGradient !== particle._currentLimitVelocityGradient) {
323
- particle._currentLimitVelocity1 = particle._currentLimitVelocity2;
324
- particle._currentLimitVelocity2 = nextGradient.getFactor();
325
- particle._currentLimitVelocityGradient = currentGradient;
326
- }
327
- const limitVelocity = Lerp(particle._currentLimitVelocity1, particle._currentLimitVelocity2, scale);
328
- const currentVelocity = particle.direction.length();
329
- if (currentVelocity > limitVelocity) {
330
- particle.direction.scaleInPlace(this.limitVelocityDamping);
331
- }
332
- });
333
- }
334
- /// Drag
335
- if (this._dragGradients && this._dragGradients.length > 0) {
336
- GradientHelper.GetCurrentGradient(ratio, this._dragGradients, (currentGradient, nextGradient, scale) => {
337
- if (currentGradient !== particle._currentDragGradient) {
338
- particle._currentDrag1 = particle._currentDrag2;
339
- particle._currentDrag2 = nextGradient.getFactor();
340
- particle._currentDragGradient = currentGradient;
341
- }
342
- const drag = Lerp(particle._currentDrag1, particle._currentDrag2, scale);
343
- this._scaledDirection.scaleInPlace(1.0 - drag);
344
- });
345
- }
346
- if (this.isLocal && particle._localPosition) {
347
- particle._localPosition.addInPlace(this._scaledDirection);
348
- Vector3.TransformCoordinatesToRef(particle._localPosition, this._emitterWorldMatrix, particle.position);
349
- }
350
- else {
351
- particle.position.addInPlace(this._scaledDirection);
352
- }
353
- // Noise
354
- if (noiseTextureData && noiseTextureSize && particle._randomNoiseCoordinates1) {
355
- const fetchedColorR = this._fetchR(particle._randomNoiseCoordinates1.x, particle._randomNoiseCoordinates1.y, noiseTextureSize.width, noiseTextureSize.height, noiseTextureData);
356
- const fetchedColorG = this._fetchR(particle._randomNoiseCoordinates1.z, particle._randomNoiseCoordinates2.x, noiseTextureSize.width, noiseTextureSize.height, noiseTextureData);
357
- const fetchedColorB = this._fetchR(particle._randomNoiseCoordinates2.y, particle._randomNoiseCoordinates2.z, noiseTextureSize.width, noiseTextureSize.height, noiseTextureData);
358
- const force = TmpVectors.Vector3[0];
359
- const scaledForce = TmpVectors.Vector3[1];
360
- force.copyFromFloats((2 * fetchedColorR - 1) * this.noiseStrength.x, (2 * fetchedColorG - 1) * this.noiseStrength.y, (2 * fetchedColorB - 1) * this.noiseStrength.z);
361
- force.scaleToRef(scaledUpdateSpeed, scaledForce);
362
- particle.direction.addInPlace(scaledForce);
363
- }
364
- // Gravity
365
- this.gravity.scaleToRef(scaledUpdateSpeed, this._scaledGravity);
366
- particle.direction.addInPlace(this._scaledGravity);
367
- // Size
368
- if (this._sizeGradients && this._sizeGradients.length > 0) {
369
- GradientHelper.GetCurrentGradient(ratio, this._sizeGradients, (currentGradient, nextGradient, scale) => {
370
- if (currentGradient !== particle._currentSizeGradient) {
371
- particle._currentSize1 = particle._currentSize2;
372
- particle._currentSize2 = nextGradient.getFactor();
373
- particle._currentSizeGradient = currentGradient;
374
- }
375
- particle.size = Lerp(particle._currentSize1, particle._currentSize2, scale);
376
- });
377
- }
378
- // Remap data
379
- if (this._useRampGradients) {
380
- if (this._colorRemapGradients && this._colorRemapGradients.length > 0) {
381
- GradientHelper.GetCurrentGradient(ratio, this._colorRemapGradients, (currentGradient, nextGradient, scale) => {
382
- const min = Lerp(currentGradient.factor1, nextGradient.factor1, scale);
383
- const max = Lerp(currentGradient.factor2, nextGradient.factor2, scale);
384
- particle.remapData.x = min;
385
- particle.remapData.y = max - min;
386
- });
387
- }
388
- if (this._alphaRemapGradients && this._alphaRemapGradients.length > 0) {
389
- GradientHelper.GetCurrentGradient(ratio, this._alphaRemapGradients, (currentGradient, nextGradient, scale) => {
390
- const min = Lerp(currentGradient.factor1, nextGradient.factor1, scale);
391
- const max = Lerp(currentGradient.factor2, nextGradient.factor2, scale);
392
- particle.remapData.z = min;
393
- particle.remapData.w = max - min;
394
- });
395
- }
486
+ this._ratio = particle.age / particle.lifeTime;
487
+ this._directionScale = this._tempScaledUpdateSpeed;
488
+ // Processing queue
489
+ let currentQueueItem = this._updateQueueStart;
490
+ while (currentQueueItem) {
491
+ currentQueueItem.process(particle, this);
492
+ currentQueueItem = currentQueueItem.nextItem;
396
493
  }
397
494
  if (this._isAnimationSheetEnabled) {
398
495
  particle.updateCellIndex();
@@ -456,6 +553,41 @@ export class ThinParticleSystem extends BaseParticleSystem {
456
553
  index++;
457
554
  }
458
555
  }
556
+ _syncLifeTimeCreation() {
557
+ if (this.targetStopDuration && this._lifeTimeGradients && this._lifeTimeGradients.length > 0) {
558
+ this._lifeTimeCreation.process = _CreateLifeGradientsData;
559
+ return;
560
+ }
561
+ this._lifeTimeCreation.process = _CreateLifetimeData;
562
+ }
563
+ _syncStartSizeCreation() {
564
+ if (this._startSizeGradients && this._startSizeGradients[0] && this.targetStopDuration) {
565
+ if (!this._startSizeCreation) {
566
+ this._startSizeCreation = {
567
+ process: _CreateStartSizeGradientsData,
568
+ previousItem: null,
569
+ nextItem: null,
570
+ };
571
+ _ConnectAfter(this._startSizeCreation, this._sizeCreation);
572
+ }
573
+ return;
574
+ }
575
+ if (this._startSizeCreation) {
576
+ _RemoveFromQueue(this._startSizeCreation);
577
+ this._startSizeCreation = null;
578
+ }
579
+ }
580
+ get targetStopDuration() {
581
+ return this._targetStopDuration;
582
+ }
583
+ set targetStopDuration(value) {
584
+ if (this.targetStopDuration === value) {
585
+ return;
586
+ }
587
+ this._targetStopDuration = value;
588
+ this._syncLifeTimeCreation();
589
+ this._syncStartSizeCreation();
590
+ }
459
591
  /**
460
592
  * Adds a new life time gradient
461
593
  * @param gradient defines the gradient to use (between 0 and 1)
@@ -468,6 +600,7 @@ export class ThinParticleSystem extends BaseParticleSystem {
468
600
  this._lifeTimeGradients = [];
469
601
  }
470
602
  this._addFactorGradient(this._lifeTimeGradients, gradient, factor, factor2);
603
+ this._syncLifeTimeCreation();
471
604
  return this;
472
605
  }
473
606
  /**
@@ -477,6 +610,7 @@ export class ThinParticleSystem extends BaseParticleSystem {
477
610
  */
478
611
  removeLifeTimeGradient(gradient) {
479
612
  this._removeFactorGradient(this._lifeTimeGradients, gradient);
613
+ this._syncLifeTimeCreation();
480
614
  return this;
481
615
  }
482
616
  /**
@@ -490,6 +624,15 @@ export class ThinParticleSystem extends BaseParticleSystem {
490
624
  if (!this._sizeGradients) {
491
625
  this._sizeGradients = [];
492
626
  }
627
+ if (this._sizeGradients.length === 0) {
628
+ this._sizeCreation.process = _CreateSizeGradientsData;
629
+ this._sizeGradientProcessing = {
630
+ process: _ProcessSizeGradients,
631
+ previousItem: null,
632
+ nextItem: null,
633
+ };
634
+ _ConnectBefore(this._sizeGradientProcessing, this._gravityProcessing);
635
+ }
493
636
  this._addFactorGradient(this._sizeGradients, gradient, factor, factor2);
494
637
  return this;
495
638
  }
@@ -500,6 +643,10 @@ export class ThinParticleSystem extends BaseParticleSystem {
500
643
  */
501
644
  removeSizeGradient(gradient) {
502
645
  this._removeFactorGradient(this._sizeGradients, gradient);
646
+ if (this._sizeGradients?.length === 0) {
647
+ _RemoveFromQueue(this._sizeGradientProcessing);
648
+ this._sizeCreation.process = _CreateSizeData;
649
+ }
503
650
  return this;
504
651
  }
505
652
  /**
@@ -559,6 +706,15 @@ export class ThinParticleSystem extends BaseParticleSystem {
559
706
  if (!this._angularSpeedGradients) {
560
707
  this._angularSpeedGradients = [];
561
708
  }
709
+ if (this._angularSpeedGradients.length === 0) {
710
+ this._angleCreation.process = _CreateAngleGradientsData;
711
+ this._angularSpeedGradientProcessing = {
712
+ process: _ProcessAngularSpeedGradients,
713
+ previousItem: null,
714
+ nextItem: null,
715
+ };
716
+ _ConnectBefore(this._angularSpeedGradientProcessing, this._angularSpeedProcessing);
717
+ }
562
718
  this._addFactorGradient(this._angularSpeedGradients, gradient, factor, factor2);
563
719
  return this;
564
720
  }
@@ -569,6 +725,10 @@ export class ThinParticleSystem extends BaseParticleSystem {
569
725
  */
570
726
  removeAngularSpeedGradient(gradient) {
571
727
  this._removeFactorGradient(this._angularSpeedGradients, gradient);
728
+ if (this._angularSpeedGradients?.length === 0) {
729
+ this._angleCreation.process = _CreateAngleData;
730
+ _RemoveFromQueue(this._angularSpeedGradientProcessing);
731
+ }
572
732
  return this;
573
733
  }
574
734
  /**
@@ -582,6 +742,20 @@ export class ThinParticleSystem extends BaseParticleSystem {
582
742
  if (!this._velocityGradients) {
583
743
  this._velocityGradients = [];
584
744
  }
745
+ if (this._velocityGradients.length === 0) {
746
+ this._velocityCreation = {
747
+ process: _CreateVelocityGradients,
748
+ previousItem: null,
749
+ nextItem: null,
750
+ };
751
+ _ConnectAfter(this._velocityCreation, this._angleCreation);
752
+ this._velocityGradientProcessing = {
753
+ process: _ProcessVelocityGradients,
754
+ previousItem: null,
755
+ nextItem: null,
756
+ };
757
+ _ConnectBefore(this._velocityGradientProcessing, this._directionProcessing);
758
+ }
585
759
  this._addFactorGradient(this._velocityGradients, gradient, factor, factor2);
586
760
  return this;
587
761
  }
@@ -592,6 +766,10 @@ export class ThinParticleSystem extends BaseParticleSystem {
592
766
  */
593
767
  removeVelocityGradient(gradient) {
594
768
  this._removeFactorGradient(this._velocityGradients, gradient);
769
+ if (this._velocityGradients?.length === 0) {
770
+ _RemoveFromQueue(this._velocityCreation);
771
+ _RemoveFromQueue(this._velocityGradientProcessing);
772
+ }
595
773
  return this;
596
774
  }
597
775
  /**
@@ -605,6 +783,20 @@ export class ThinParticleSystem extends BaseParticleSystem {
605
783
  if (!this._limitVelocityGradients) {
606
784
  this._limitVelocityGradients = [];
607
785
  }
786
+ if (this._limitVelocityGradients.length === 0) {
787
+ this._limitVelocityCreation = {
788
+ process: _CreateLimitVelocityGradients,
789
+ previousItem: null,
790
+ nextItem: null,
791
+ };
792
+ _ConnectAfter(this._limitVelocityCreation, this._angleCreation);
793
+ this._limitVelocityGradientProcessing = {
794
+ process: _ProcessLimitVelocityGradients,
795
+ previousItem: null,
796
+ nextItem: null,
797
+ };
798
+ _ConnectAfter(this._limitVelocityGradientProcessing, this._directionProcessing);
799
+ }
608
800
  this._addFactorGradient(this._limitVelocityGradients, gradient, factor, factor2);
609
801
  return this;
610
802
  }
@@ -615,6 +807,10 @@ export class ThinParticleSystem extends BaseParticleSystem {
615
807
  */
616
808
  removeLimitVelocityGradient(gradient) {
617
809
  this._removeFactorGradient(this._limitVelocityGradients, gradient);
810
+ if (this._limitVelocityGradients?.length === 0) {
811
+ _RemoveFromQueue(this._limitVelocityCreation);
812
+ _RemoveFromQueue(this._limitVelocityGradientProcessing);
813
+ }
618
814
  return this;
619
815
  }
620
816
  /**
@@ -628,6 +824,20 @@ export class ThinParticleSystem extends BaseParticleSystem {
628
824
  if (!this._dragGradients) {
629
825
  this._dragGradients = [];
630
826
  }
827
+ if (this._dragGradients.length === 0) {
828
+ this._dragCreation = {
829
+ process: _CreateDragData,
830
+ previousItem: null,
831
+ nextItem: null,
832
+ };
833
+ _ConnectBefore(this._dragCreation, this._colorCreation);
834
+ this._dragGradientProcessing = {
835
+ process: _ProcessDragGradients,
836
+ previousItem: null,
837
+ nextItem: null,
838
+ };
839
+ _ConnectBefore(this._dragGradientProcessing, this._positionProcessing);
840
+ }
631
841
  this._addFactorGradient(this._dragGradients, gradient, factor, factor2);
632
842
  return this;
633
843
  }
@@ -638,6 +848,10 @@ export class ThinParticleSystem extends BaseParticleSystem {
638
848
  */
639
849
  removeDragGradient(gradient) {
640
850
  this._removeFactorGradient(this._dragGradients, gradient);
851
+ if (this._dragGradients?.length === 0) {
852
+ _RemoveFromQueue(this._dragCreation);
853
+ _RemoveFromQueue(this._dragGradientProcessing);
854
+ }
641
855
  return this;
642
856
  }
643
857
  /**
@@ -675,6 +889,7 @@ export class ThinParticleSystem extends BaseParticleSystem {
675
889
  this._startSizeGradients = [];
676
890
  }
677
891
  this._addFactorGradient(this._startSizeGradients, gradient, factor, factor2);
892
+ this._syncStartSizeCreation();
678
893
  return this;
679
894
  }
680
895
  /**
@@ -684,6 +899,7 @@ export class ThinParticleSystem extends BaseParticleSystem {
684
899
  */
685
900
  removeStartSizeGradient(gradient) {
686
901
  this._removeFactorGradient(this._startSizeGradients, gradient);
902
+ this._syncStartSizeCreation();
687
903
  return this;
688
904
  }
689
905
  _createRampGradientTexture() {
@@ -774,6 +990,10 @@ export class ThinParticleSystem extends BaseParticleSystem {
774
990
  if (!this._colorGradients) {
775
991
  this._colorGradients = [];
776
992
  }
993
+ if (this._colorGradients.length === 0) {
994
+ this._colorCreation.process = _CreateColorGradientsData;
995
+ this._colorProcessing.process = _ProcessColorGradients;
996
+ }
777
997
  const colorGradient = new ColorGradient(gradient, color1, color2);
778
998
  this._colorGradients.push(colorGradient);
779
999
  this._colorGradients.sort((a, b) => {
@@ -804,6 +1024,10 @@ export class ThinParticleSystem extends BaseParticleSystem {
804
1024
  }
805
1025
  index++;
806
1026
  }
1027
+ if (this._colorGradients.length === 0) {
1028
+ this._colorCreation.process = _CreateColorData;
1029
+ this._colorProcessing.process = _ProcessColor;
1030
+ }
807
1031
  return this;
808
1032
  }
809
1033
  /**
@@ -819,6 +1043,7 @@ export class ThinParticleSystem extends BaseParticleSystem {
819
1043
  }
820
1044
  this._drawWrappers = [];
821
1045
  }
1046
+ /** @internal */
822
1047
  _fetchR(u, v, width, height, pixels) {
823
1048
  u = Math.abs(u) * 0.5 + 0.5;
824
1049
  v = Math.abs(v) * 0.5 + 0.5;
@@ -1122,6 +1347,25 @@ export class ThinParticleSystem extends BaseParticleSystem {
1122
1347
  _prepareParticle(particle) {
1123
1348
  //Do nothing
1124
1349
  }
1350
+ _createNewOnes(newParticles) {
1351
+ // Add new ones
1352
+ let particle;
1353
+ for (let index = 0; index < newParticles; index++) {
1354
+ if (this._particles.length === this._capacity) {
1355
+ break;
1356
+ }
1357
+ particle = this._createParticle();
1358
+ this._particles.push(particle);
1359
+ // Creation queue
1360
+ let currentQueueItem = this._createQueueStart;
1361
+ while (currentQueueItem) {
1362
+ currentQueueItem.process(particle, this);
1363
+ currentQueueItem = currentQueueItem.nextItem;
1364
+ }
1365
+ // Update the position of the attached sub-emitters to match their attached particle
1366
+ particle._inheritParticleInfoToSubEmitters();
1367
+ }
1368
+ }
1125
1369
  _update(newParticles) {
1126
1370
  // Update current
1127
1371
  this._alive = this._particles.length > 0;
@@ -1135,187 +1379,7 @@ export class ThinParticleSystem extends BaseParticleSystem {
1135
1379
  }
1136
1380
  this._emitterWorldMatrix.invertToRef(this._emitterInverseWorldMatrix);
1137
1381
  this.updateFunction(this._particles);
1138
- // Add new ones
1139
- let particle;
1140
- for (let index = 0; index < newParticles; index++) {
1141
- if (this._particles.length === this._capacity) {
1142
- break;
1143
- }
1144
- particle = this._createParticle();
1145
- this._particles.push(particle);
1146
- // Life time
1147
- if (this.targetStopDuration && this._lifeTimeGradients && this._lifeTimeGradients.length > 0) {
1148
- const ratio = Clamp(this._actualFrame / this.targetStopDuration);
1149
- GradientHelper.GetCurrentGradient(ratio, this._lifeTimeGradients, (currentGradient, nextGradient) => {
1150
- const factorGradient1 = currentGradient;
1151
- const factorGradient2 = nextGradient;
1152
- const lifeTime1 = factorGradient1.getFactor();
1153
- const lifeTime2 = factorGradient2.getFactor();
1154
- const gradient = (ratio - factorGradient1.gradient) / (factorGradient2.gradient - factorGradient1.gradient);
1155
- particle.lifeTime = Lerp(lifeTime1, lifeTime2, gradient);
1156
- });
1157
- }
1158
- else {
1159
- particle.lifeTime = RandomRange(this.minLifeTime, this.maxLifeTime);
1160
- }
1161
- // Emitter
1162
- const emitPower = RandomRange(this.minEmitPower, this.maxEmitPower);
1163
- if (this.startPositionFunction) {
1164
- this.startPositionFunction(this._emitterWorldMatrix, particle.position, particle, this.isLocal);
1165
- }
1166
- else {
1167
- this.particleEmitterType.startPositionFunction(this._emitterWorldMatrix, particle.position, particle, this.isLocal);
1168
- }
1169
- if (this.isLocal) {
1170
- if (!particle._localPosition) {
1171
- particle._localPosition = particle.position.clone();
1172
- }
1173
- else {
1174
- particle._localPosition.copyFrom(particle.position);
1175
- }
1176
- Vector3.TransformCoordinatesToRef(particle._localPosition, this._emitterWorldMatrix, particle.position);
1177
- }
1178
- if (this.startDirectionFunction) {
1179
- this.startDirectionFunction(this._emitterWorldMatrix, particle.direction, particle, this.isLocal);
1180
- }
1181
- else {
1182
- this.particleEmitterType.startDirectionFunction(this._emitterWorldMatrix, particle.direction, particle, this.isLocal, this._emitterInverseWorldMatrix);
1183
- }
1184
- if (emitPower === 0) {
1185
- if (!particle._initialDirection) {
1186
- particle._initialDirection = particle.direction.clone();
1187
- }
1188
- else {
1189
- particle._initialDirection.copyFrom(particle.direction);
1190
- }
1191
- }
1192
- else {
1193
- particle._initialDirection = null;
1194
- }
1195
- particle.direction.scaleInPlace(emitPower);
1196
- // Size
1197
- if (!this._sizeGradients || this._sizeGradients.length === 0) {
1198
- particle.size = RandomRange(this.minSize, this.maxSize);
1199
- }
1200
- else {
1201
- particle._currentSizeGradient = this._sizeGradients[0];
1202
- particle._currentSize1 = particle._currentSizeGradient.getFactor();
1203
- particle.size = particle._currentSize1;
1204
- if (this._sizeGradients.length > 1) {
1205
- particle._currentSize2 = this._sizeGradients[1].getFactor();
1206
- }
1207
- else {
1208
- particle._currentSize2 = particle._currentSize1;
1209
- }
1210
- }
1211
- // Size and scale
1212
- particle.scale.copyFromFloats(RandomRange(this.minScaleX, this.maxScaleX), RandomRange(this.minScaleY, this.maxScaleY));
1213
- // Adjust scale by start size
1214
- if (this._startSizeGradients && this._startSizeGradients[0] && this.targetStopDuration) {
1215
- const ratio = this._actualFrame / this.targetStopDuration;
1216
- GradientHelper.GetCurrentGradient(ratio, this._startSizeGradients, (currentGradient, nextGradient, scale) => {
1217
- if (currentGradient !== this._currentStartSizeGradient) {
1218
- this._currentStartSize1 = this._currentStartSize2;
1219
- this._currentStartSize2 = nextGradient.getFactor();
1220
- this._currentStartSizeGradient = currentGradient;
1221
- }
1222
- const value = Lerp(this._currentStartSize1, this._currentStartSize2, scale);
1223
- particle.scale.scaleInPlace(value);
1224
- });
1225
- }
1226
- // Angle
1227
- if (!this._angularSpeedGradients || this._angularSpeedGradients.length === 0) {
1228
- particle.angularSpeed = RandomRange(this.minAngularSpeed, this.maxAngularSpeed);
1229
- }
1230
- else {
1231
- particle._currentAngularSpeedGradient = this._angularSpeedGradients[0];
1232
- particle.angularSpeed = particle._currentAngularSpeedGradient.getFactor();
1233
- particle._currentAngularSpeed1 = particle.angularSpeed;
1234
- if (this._angularSpeedGradients.length > 1) {
1235
- particle._currentAngularSpeed2 = this._angularSpeedGradients[1].getFactor();
1236
- }
1237
- else {
1238
- particle._currentAngularSpeed2 = particle._currentAngularSpeed1;
1239
- }
1240
- }
1241
- particle.angle = RandomRange(this.minInitialRotation, this.maxInitialRotation);
1242
- // Velocity
1243
- if (this._velocityGradients && this._velocityGradients.length > 0) {
1244
- particle._currentVelocityGradient = this._velocityGradients[0];
1245
- particle._currentVelocity1 = particle._currentVelocityGradient.getFactor();
1246
- if (this._velocityGradients.length > 1) {
1247
- particle._currentVelocity2 = this._velocityGradients[1].getFactor();
1248
- }
1249
- else {
1250
- particle._currentVelocity2 = particle._currentVelocity1;
1251
- }
1252
- }
1253
- // Limit velocity
1254
- if (this._limitVelocityGradients && this._limitVelocityGradients.length > 0) {
1255
- particle._currentLimitVelocityGradient = this._limitVelocityGradients[0];
1256
- particle._currentLimitVelocity1 = particle._currentLimitVelocityGradient.getFactor();
1257
- if (this._limitVelocityGradients.length > 1) {
1258
- particle._currentLimitVelocity2 = this._limitVelocityGradients[1].getFactor();
1259
- }
1260
- else {
1261
- particle._currentLimitVelocity2 = particle._currentLimitVelocity1;
1262
- }
1263
- }
1264
- // Drag
1265
- if (this._dragGradients && this._dragGradients.length > 0) {
1266
- particle._currentDragGradient = this._dragGradients[0];
1267
- particle._currentDrag1 = particle._currentDragGradient.getFactor();
1268
- if (this._dragGradients.length > 1) {
1269
- particle._currentDrag2 = this._dragGradients[1].getFactor();
1270
- }
1271
- else {
1272
- particle._currentDrag2 = particle._currentDrag1;
1273
- }
1274
- }
1275
- // Color
1276
- if (!this._colorGradients || this._colorGradients.length === 0) {
1277
- const step = RandomRange(0, 1.0);
1278
- Color4.LerpToRef(this.color1, this.color2, step, particle.color);
1279
- this.colorDead.subtractToRef(particle.color, this._colorDiff);
1280
- this._colorDiff.scaleToRef(1.0 / particle.lifeTime, particle.colorStep);
1281
- }
1282
- else {
1283
- particle._currentColorGradient = this._colorGradients[0];
1284
- particle._currentColorGradient.getColorToRef(particle.color);
1285
- particle._currentColor1.copyFrom(particle.color);
1286
- if (this._colorGradients.length > 1) {
1287
- this._colorGradients[1].getColorToRef(particle._currentColor2);
1288
- }
1289
- else {
1290
- particle._currentColor2.copyFrom(particle.color);
1291
- }
1292
- }
1293
- // Sheet
1294
- if (this._isAnimationSheetEnabled) {
1295
- particle._initialStartSpriteCellID = this.startSpriteCellID;
1296
- particle._initialEndSpriteCellID = this.endSpriteCellID;
1297
- particle._initialSpriteCellLoop = this.spriteCellLoop;
1298
- }
1299
- // Inherited Velocity
1300
- particle.direction.addInPlace(this._inheritedVelocityOffset);
1301
- // Ramp
1302
- if (this._useRampGradients) {
1303
- particle.remapData = new Vector4(0, 1, 0, 1);
1304
- }
1305
- // Noise texture coordinates
1306
- if (this.noiseTexture) {
1307
- if (particle._randomNoiseCoordinates1) {
1308
- particle._randomNoiseCoordinates1.copyFromFloats(Math.random(), Math.random(), Math.random());
1309
- particle._randomNoiseCoordinates2.copyFromFloats(Math.random(), Math.random(), Math.random());
1310
- }
1311
- else {
1312
- particle._randomNoiseCoordinates1 = new Vector3(Math.random(), Math.random(), Math.random());
1313
- particle._randomNoiseCoordinates2 = new Vector3(Math.random(), Math.random(), Math.random());
1314
- }
1315
- }
1316
- // Update the position of the attached sub-emitters to match their attached particle
1317
- particle._inheritParticleInfoToSubEmitters();
1318
- }
1382
+ this._createNewOnes(newParticles);
1319
1383
  }
1320
1384
  /**
1321
1385
  * @internal