@babylonjs/core 8.4.1 → 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.
- package/Collisions/gpuPicker.js +26 -15
- package/Collisions/gpuPicker.js.map +1 -1
- package/Engines/abstractEngine.js +2 -2
- package/Engines/abstractEngine.js.map +1 -1
- package/Materials/Textures/Loaders/EXR/exrLoader.decoder.js +24 -3
- package/Materials/Textures/Loaders/EXR/exrLoader.decoder.js.map +1 -1
- package/Materials/Textures/texture.js +1 -1
- package/Materials/Textures/texture.js.map +1 -1
- package/Meshes/geometry.js +30 -28
- package/Meshes/geometry.js.map +1 -1
- package/Meshes/mesh.vertexData.js +2 -2
- package/Meshes/mesh.vertexData.js.map +1 -1
- package/Particles/Queue/executionQueue.d.ts +18 -0
- package/Particles/Queue/executionQueue.js +28 -0
- package/Particles/Queue/executionQueue.js.map +1 -0
- package/Particles/attractor.d.ts +21 -0
- package/Particles/attractor.js +36 -0
- package/Particles/attractor.js.map +1 -0
- package/Particles/baseParticleSystem.d.ts +27 -13
- package/Particles/baseParticleSystem.js +34 -4
- package/Particles/baseParticleSystem.js.map +1 -1
- package/Particles/index.d.ts +1 -0
- package/Particles/index.js +1 -0
- package/Particles/index.js.map +1 -1
- package/Particles/particleSystem.d.ts +18 -0
- package/Particles/particleSystem.js +59 -0
- package/Particles/particleSystem.js.map +1 -1
- package/Particles/thinParticleSystem.d.ts +81 -12
- package/Particles/thinParticleSystem.function.d.ts +84 -0
- package/Particles/thinParticleSystem.function.js +340 -0
- package/Particles/thinParticleSystem.function.js.map +1 -0
- package/Particles/thinParticleSystem.js +380 -316
- package/Particles/thinParticleSystem.js.map +1 -1
- package/PostProcesses/RenderPipeline/Pipelines/lensRenderingPipeline.js +1 -0
- package/PostProcesses/RenderPipeline/Pipelines/lensRenderingPipeline.js.map +1 -1
- package/PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline.js +1 -0
- package/PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline.js.map +1 -1
- package/PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline.js +1 -0
- package/PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline.js.map +1 -1
- package/PostProcesses/RenderPipeline/Pipelines/ssrRenderingPipeline.js +1 -0
- package/PostProcesses/RenderPipeline/Pipelines/ssrRenderingPipeline.js.map +1 -1
- package/PostProcesses/RenderPipeline/Pipelines/standardRenderingPipeline.js +1 -0
- package/PostProcesses/RenderPipeline/Pipelines/standardRenderingPipeline.js.map +1 -1
- package/PostProcesses/RenderPipeline/Pipelines/taaRenderingPipeline.js +1 -0
- package/PostProcesses/RenderPipeline/Pipelines/taaRenderingPipeline.js.map +1 -1
- package/Rendering/IBLShadows/iblShadowsAccumulationPass.d.ts +2 -0
- package/Rendering/IBLShadows/iblShadowsAccumulationPass.js +22 -12
- package/Rendering/IBLShadows/iblShadowsAccumulationPass.js.map +1 -1
- package/Rendering/IBLShadows/iblShadowsRenderPipeline.js +1 -0
- package/Rendering/IBLShadows/iblShadowsRenderPipeline.js.map +1 -1
- package/Rendering/IBLShadows/iblShadowsSpatialBlurPass.d.ts +2 -0
- package/Rendering/IBLShadows/iblShadowsSpatialBlurPass.js +22 -12
- package/Rendering/IBLShadows/iblShadowsSpatialBlurPass.js.map +1 -1
- package/Rendering/IBLShadows/iblShadowsVoxelTracingPass.d.ts +2 -0
- package/Rendering/IBLShadows/iblShadowsVoxelTracingPass.js +28 -14
- package/Rendering/IBLShadows/iblShadowsVoxelTracingPass.js.map +1 -1
- 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,
|
|
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 {
|
|
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
|
-
|
|
183
|
-
|
|
184
|
-
this.
|
|
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
|
-
|
|
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
|
-
|
|
468
|
+
this._noiseTextureSize = this.noiseTexture.getSize();
|
|
257
469
|
this.noiseTexture.getContent()?.then((data) => {
|
|
258
|
-
|
|
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
|
-
|
|
476
|
+
this._tempScaledUpdateSpeed = this._scaledUpdateSpeed;
|
|
265
477
|
const previousAge = particle.age;
|
|
266
|
-
particle.age +=
|
|
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
|
-
|
|
483
|
+
this._tempScaledUpdateSpeed = (oldDiff * this._tempScaledUpdateSpeed) / diff;
|
|
272
484
|
particle.age = particle.lifeTime;
|
|
273
485
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
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
|
-
|
|
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
|