@newkrok/three-particles 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@newkrok/three-particles",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Particle system for ThreeJS",
|
|
5
5
|
"main": "src/js/three-particles.js",
|
|
6
6
|
"bin": {
|
|
@@ -23,8 +23,9 @@
|
|
|
23
23
|
},
|
|
24
24
|
"homepage": "https://github.com/NewKrok/three-particles#readme",
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"
|
|
27
|
-
"
|
|
26
|
+
"easing-functions": "1.0.1",
|
|
27
|
+
"three": "0.136.0",
|
|
28
|
+
"three-noise": "^1.1.1"
|
|
28
29
|
},
|
|
29
30
|
"scripts": {
|
|
30
31
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import * as THREE from "three/build/three.module.js";
|
|
2
|
+
|
|
1
3
|
import { getCurveFunction } from "./three-particles-curves.js";
|
|
4
|
+
import { size } from "lodash";
|
|
5
|
+
|
|
6
|
+
const noiseInput = new THREE.Vector3(0, 0, 0);
|
|
2
7
|
|
|
3
|
-
const
|
|
8
|
+
const curveModifiers = [
|
|
4
9
|
// {key:"colorOverLifetime", attributeKeys:["colorR", "colorG", "colorB"]},
|
|
5
10
|
{
|
|
6
11
|
key: "opacityOverLifetime",
|
|
@@ -15,17 +20,20 @@ const modifiers = [
|
|
|
15
20
|
];
|
|
16
21
|
|
|
17
22
|
export const applyModifiers = ({
|
|
23
|
+
delta,
|
|
24
|
+
noise,
|
|
18
25
|
startValues,
|
|
26
|
+
lifetimeValues,
|
|
19
27
|
normalizedConfig,
|
|
20
28
|
attributes,
|
|
21
29
|
particleLifetimePercentage,
|
|
22
30
|
particleIndex,
|
|
23
31
|
forceUpdate = false,
|
|
24
32
|
}) => {
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
if (
|
|
28
|
-
const multiplier = getCurveFunction(
|
|
33
|
+
curveModifiers.forEach(({ key, attributeKeys, startValueKeys }) => {
|
|
34
|
+
const curveModifier = normalizedConfig[key];
|
|
35
|
+
if (curveModifier.isActive) {
|
|
36
|
+
const multiplier = getCurveFunction(curveModifier.curveFunction)(
|
|
29
37
|
particleLifetimePercentage
|
|
30
38
|
);
|
|
31
39
|
attributeKeys.forEach((attributeKey, index) => {
|
|
@@ -41,4 +49,58 @@ export const applyModifiers = ({
|
|
|
41
49
|
});
|
|
42
50
|
}
|
|
43
51
|
});
|
|
52
|
+
|
|
53
|
+
if (lifetimeValues.rotationOverLifetime) {
|
|
54
|
+
attributes.rotation.array[particleIndex] +=
|
|
55
|
+
lifetimeValues.rotationOverLifetime[particleIndex] * delta * 0.02;
|
|
56
|
+
attributes.rotation.needsUpdate = true;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (noise.isActive) {
|
|
60
|
+
const {
|
|
61
|
+
sampler,
|
|
62
|
+
strength,
|
|
63
|
+
offsets,
|
|
64
|
+
positionAmount,
|
|
65
|
+
rotationAmount,
|
|
66
|
+
sizeAmount,
|
|
67
|
+
} = noise;
|
|
68
|
+
const positionIndex = particleIndex * 3;
|
|
69
|
+
const positionArr = attributes.position.array;
|
|
70
|
+
let noiseOnPosition;
|
|
71
|
+
|
|
72
|
+
const noisePosition =
|
|
73
|
+
(particleLifetimePercentage + (offsets ? offsets[particleIndex] : 0)) *
|
|
74
|
+
10 *
|
|
75
|
+
strength;
|
|
76
|
+
const noisePower = 0.15 * strength;
|
|
77
|
+
|
|
78
|
+
noiseInput.set(noisePosition, 0, 0);
|
|
79
|
+
noiseOnPosition = sampler.get3(noiseInput);
|
|
80
|
+
positionArr[positionIndex] += noiseOnPosition * noisePower * positionAmount;
|
|
81
|
+
|
|
82
|
+
if (rotationAmount !== 0) {
|
|
83
|
+
attributes.rotation.array[particleIndex] +=
|
|
84
|
+
noiseOnPosition * noisePower * rotationAmount;
|
|
85
|
+
attributes.rotation.needsUpdate = true;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (sizeAmount !== 0) {
|
|
89
|
+
attributes.size.array[particleIndex] +=
|
|
90
|
+
noiseOnPosition * noisePower * sizeAmount;
|
|
91
|
+
attributes.size.needsUpdate = true;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
noiseInput.set(noisePosition, noisePosition, 0);
|
|
95
|
+
noiseOnPosition = sampler.get3(noiseInput);
|
|
96
|
+
positionArr[positionIndex + 1] +=
|
|
97
|
+
noiseOnPosition * noisePower * positionAmount;
|
|
98
|
+
|
|
99
|
+
noiseInput.set(noisePosition, noisePosition, noisePosition);
|
|
100
|
+
noiseOnPosition = sampler.get3(noiseInput);
|
|
101
|
+
positionArr[positionIndex + 2] +=
|
|
102
|
+
noiseOnPosition * noisePower * positionAmount;
|
|
103
|
+
|
|
104
|
+
attributes.position.needsUpdate = true;
|
|
105
|
+
}
|
|
44
106
|
};
|
|
@@ -11,7 +11,12 @@ export const patchObject = (
|
|
|
11
11
|
if (typeof objectA[key] === "object" && objectA[key] && objectB[key]) {
|
|
12
12
|
result[key] = patchObject(objectA[key], objectB[key], config);
|
|
13
13
|
} else {
|
|
14
|
-
result[key] =
|
|
14
|
+
result[key] =
|
|
15
|
+
objectB[key] === 0
|
|
16
|
+
? 0
|
|
17
|
+
: objectB[key] === false
|
|
18
|
+
? false
|
|
19
|
+
: objectB[key] || objectA[key];
|
|
15
20
|
if (config.applyToFirstObject) objectA[key] = result[key];
|
|
16
21
|
}
|
|
17
22
|
}
|
|
@@ -9,13 +9,11 @@ import {
|
|
|
9
9
|
} from "./three-particles/three-particles-utils.js";
|
|
10
10
|
|
|
11
11
|
import { CurveFunction } from "./three-particles/three-particles-curves.js";
|
|
12
|
+
import { FBM } from "three-noise/build/three-noise.module.js";
|
|
12
13
|
import ParticleSystemFragmentShader from "./three-particles/shaders/particle-system-fragment-shader.glsl.js";
|
|
13
14
|
import ParticleSystemVertexShader from "./three-particles/shaders/particle-system-vertex-shader.glsl.js";
|
|
14
15
|
import { applyModifiers } from "./three-particles/three-particles-modifiers.js";
|
|
15
16
|
|
|
16
|
-
// Float32Array is not enough accurate when we are storing timestamp in it so we just remove unnecessary time
|
|
17
|
-
const float32Helper = 1638200000000;
|
|
18
|
-
|
|
19
17
|
let createdParticleSystems = [];
|
|
20
18
|
|
|
21
19
|
export const SimulationSpace = {
|
|
@@ -36,6 +34,14 @@ export const TimeMode = {
|
|
|
36
34
|
FPS: "FPS",
|
|
37
35
|
};
|
|
38
36
|
|
|
37
|
+
export const blendingMap = {
|
|
38
|
+
"THREE.NoBlending": THREE.NoBlending,
|
|
39
|
+
"THREE.NormalBlending": THREE.NormalBlending,
|
|
40
|
+
"THREE.AdditiveBlending": THREE.AdditiveBlending,
|
|
41
|
+
"THREE.SubtractiveBlending": THREE.SubtractiveBlending,
|
|
42
|
+
"THREE.MultiplyBlending": THREE.MultiplyBlending,
|
|
43
|
+
};
|
|
44
|
+
|
|
39
45
|
export const getDefaultParticleSystemConfig = () =>
|
|
40
46
|
JSON.parse(JSON.stringify(DEFAULT_PARTICLE_SYSTEM_CONFIG));
|
|
41
47
|
|
|
@@ -88,6 +94,25 @@ const DEFAULT_PARTICLE_SYSTEM_CONFIG = {
|
|
|
88
94
|
},
|
|
89
95
|
},
|
|
90
96
|
map: null,
|
|
97
|
+
renderer: {
|
|
98
|
+
blending: THREE.THREE.NormalBlending,
|
|
99
|
+
transparent: true,
|
|
100
|
+
depthTest: true,
|
|
101
|
+
depthWrite: false,
|
|
102
|
+
},
|
|
103
|
+
velocityOverLifetime: {
|
|
104
|
+
isActive: false,
|
|
105
|
+
linear: {
|
|
106
|
+
x: { min: 0, max: 0 },
|
|
107
|
+
y: { min: 0, max: 0 },
|
|
108
|
+
z: { min: 0, max: 0 },
|
|
109
|
+
},
|
|
110
|
+
orbital: {
|
|
111
|
+
x: { min: 0, max: 0 },
|
|
112
|
+
y: { min: 0, max: 0 },
|
|
113
|
+
z: { min: 0, max: 0 },
|
|
114
|
+
},
|
|
115
|
+
},
|
|
91
116
|
sizeOverLifetime: {
|
|
92
117
|
isActive: false,
|
|
93
118
|
curveFunction: CurveFunction.LINEAR,
|
|
@@ -100,6 +125,21 @@ const DEFAULT_PARTICLE_SYSTEM_CONFIG = {
|
|
|
100
125
|
isActive: false,
|
|
101
126
|
curveFunction: CurveFunction.LINEAR,
|
|
102
127
|
},
|
|
128
|
+
rotationOverLifetime: {
|
|
129
|
+
isActive: false,
|
|
130
|
+
min: 0.0,
|
|
131
|
+
max: 0.0,
|
|
132
|
+
},
|
|
133
|
+
noise: {
|
|
134
|
+
isActive: false,
|
|
135
|
+
useRandomOffset: false,
|
|
136
|
+
strength: 1.0,
|
|
137
|
+
frequency: 0.5,
|
|
138
|
+
octaves: 1,
|
|
139
|
+
positionAmount: 1.0,
|
|
140
|
+
rotationAmount: 0.0,
|
|
141
|
+
sizeAmount: 0.0,
|
|
142
|
+
},
|
|
103
143
|
textureSheetAnimation: {
|
|
104
144
|
tiles: new THREE.Vector2(1.0, 1.0),
|
|
105
145
|
timeMode: TimeMode.LIFETIME,
|
|
@@ -132,7 +172,8 @@ const calculatePositionAndVelocity = (
|
|
|
132
172
|
{ shape, sphere, cone, circle, rectangle },
|
|
133
173
|
startSpeed,
|
|
134
174
|
position,
|
|
135
|
-
velocity
|
|
175
|
+
velocity,
|
|
176
|
+
velocityOverLifetime
|
|
136
177
|
) => {
|
|
137
178
|
switch (shape) {
|
|
138
179
|
case Shape.SPHERE:
|
|
@@ -171,6 +212,21 @@ const calculatePositionAndVelocity = (
|
|
|
171
212
|
);
|
|
172
213
|
break;
|
|
173
214
|
}
|
|
215
|
+
|
|
216
|
+
if (velocityOverLifetime.isActive) {
|
|
217
|
+
velocity.x += THREE.MathUtils.randFloat(
|
|
218
|
+
velocityOverLifetime.linear.x.min,
|
|
219
|
+
velocityOverLifetime.linear.x.max
|
|
220
|
+
);
|
|
221
|
+
velocity.y += THREE.MathUtils.randFloat(
|
|
222
|
+
velocityOverLifetime.linear.y.min,
|
|
223
|
+
velocityOverLifetime.linear.y.max
|
|
224
|
+
);
|
|
225
|
+
velocity.z += THREE.MathUtils.randFloat(
|
|
226
|
+
velocityOverLifetime.linear.z.min,
|
|
227
|
+
velocityOverLifetime.linear.z.max
|
|
228
|
+
);
|
|
229
|
+
}
|
|
174
230
|
};
|
|
175
231
|
|
|
176
232
|
export const createParticleSystem = (
|
|
@@ -187,6 +243,9 @@ export const createParticleSystem = (
|
|
|
187
243
|
worldEuler: new THREE.Euler(),
|
|
188
244
|
gravityVelocity: new THREE.Vector3(0, 0, 0),
|
|
189
245
|
startValues: {},
|
|
246
|
+
lifetimeValues: {},
|
|
247
|
+
creationTimes: [],
|
|
248
|
+
noise: null,
|
|
190
249
|
};
|
|
191
250
|
|
|
192
251
|
const normalizedConfig = patchObject(DEFAULT_PARTICLE_SYSTEM_CONFIG, config);
|
|
@@ -207,11 +266,17 @@ export const createParticleSystem = (
|
|
|
207
266
|
emission,
|
|
208
267
|
shape,
|
|
209
268
|
map,
|
|
269
|
+
renderer,
|
|
270
|
+
noise,
|
|
271
|
+
velocityOverLifetime,
|
|
210
272
|
onUpdate,
|
|
211
273
|
onComplete,
|
|
212
274
|
textureSheetAnimation,
|
|
213
275
|
} = normalizedConfig;
|
|
214
276
|
|
|
277
|
+
if (typeof renderer.blending === "string")
|
|
278
|
+
renderer.blending = blendingMap[renderer.blending];
|
|
279
|
+
|
|
215
280
|
const startPositions = Array.from(
|
|
216
281
|
{ length: maxParticles },
|
|
217
282
|
() => new THREE.Vector3()
|
|
@@ -221,6 +286,8 @@ export const createParticleSystem = (
|
|
|
221
286
|
() => new THREE.Vector3()
|
|
222
287
|
);
|
|
223
288
|
|
|
289
|
+
generalData.creationTimes = Array.from({ length: maxParticles }, () => 0);
|
|
290
|
+
|
|
224
291
|
const startValueKeys = ["startSize", "startOpacity"];
|
|
225
292
|
startValueKeys.forEach((key) => {
|
|
226
293
|
generalData.startValues[key] = Array.from({ length: maxParticles }, () =>
|
|
@@ -231,6 +298,37 @@ export const createParticleSystem = (
|
|
|
231
298
|
);
|
|
232
299
|
});
|
|
233
300
|
|
|
301
|
+
const lifetimeValueKeys = ["rotationOverLifetime"];
|
|
302
|
+
lifetimeValueKeys.forEach((key) => {
|
|
303
|
+
if (normalizedConfig[key].isActive)
|
|
304
|
+
generalData.lifetimeValues[key] = Array.from(
|
|
305
|
+
{ length: maxParticles },
|
|
306
|
+
() =>
|
|
307
|
+
THREE.MathUtils.randFloat(
|
|
308
|
+
normalizedConfig[key].min,
|
|
309
|
+
normalizedConfig[key].max
|
|
310
|
+
)
|
|
311
|
+
);
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
generalData.noise = {
|
|
315
|
+
isActive: noise.isActive,
|
|
316
|
+
strength: noise.strength,
|
|
317
|
+
positionAmount: noise.positionAmount,
|
|
318
|
+
rotationAmount: noise.rotationAmount,
|
|
319
|
+
sizeAmount: noise.sizeAmount,
|
|
320
|
+
sampler: noise.isActive
|
|
321
|
+
? new FBM({
|
|
322
|
+
seed: Math.random(),
|
|
323
|
+
scale: noise.frequency,
|
|
324
|
+
octaves: noise.octaves,
|
|
325
|
+
})
|
|
326
|
+
: null,
|
|
327
|
+
offsets: noise.useRandomOffset
|
|
328
|
+
? Array.from({ length: maxParticles }, () => Math.random() * 100)
|
|
329
|
+
: null,
|
|
330
|
+
};
|
|
331
|
+
|
|
234
332
|
const material = new THREE.ShaderMaterial({
|
|
235
333
|
uniforms: {
|
|
236
334
|
elapsed: {
|
|
@@ -251,10 +349,10 @@ export const createParticleSystem = (
|
|
|
251
349
|
},
|
|
252
350
|
vertexShader: ParticleSystemVertexShader,
|
|
253
351
|
fragmentShader: ParticleSystemFragmentShader,
|
|
254
|
-
transparent:
|
|
255
|
-
blending:
|
|
256
|
-
depthTest:
|
|
257
|
-
depthWrite:
|
|
352
|
+
transparent: renderer.transparent,
|
|
353
|
+
blending: renderer.blending,
|
|
354
|
+
depthTest: renderer.depthTest,
|
|
355
|
+
depthWrite: renderer.depthWrite,
|
|
258
356
|
});
|
|
259
357
|
|
|
260
358
|
const geometry = new THREE.BufferGeometry();
|
|
@@ -264,7 +362,8 @@ export const createParticleSystem = (
|
|
|
264
362
|
shape,
|
|
265
363
|
startSpeed,
|
|
266
364
|
startPositions[i],
|
|
267
|
-
velocities[i]
|
|
365
|
+
velocities[i],
|
|
366
|
+
velocityOverLifetime
|
|
268
367
|
);
|
|
269
368
|
|
|
270
369
|
geometry.setFromPoints(
|
|
@@ -283,7 +382,6 @@ export const createParticleSystem = (
|
|
|
283
382
|
};
|
|
284
383
|
|
|
285
384
|
createFloat32AttributesRequest("isActive", false);
|
|
286
|
-
createFloat32AttributesRequest("creationTime", 0);
|
|
287
385
|
createFloat32AttributesRequest("lifetime", 0);
|
|
288
386
|
createFloat32AttributesRequest("startLifetime", () =>
|
|
289
387
|
THREE.MathUtils.randFloat(startLifetime.min, startLifetime.max)
|
|
@@ -339,8 +437,10 @@ export const createParticleSystem = (
|
|
|
339
437
|
|
|
340
438
|
const activateParticle = ({ particleIndex, activationTime }) => {
|
|
341
439
|
geometry.attributes.isActive.array[particleIndex] = true;
|
|
342
|
-
|
|
343
|
-
|
|
440
|
+
generalData.creationTimes[particleIndex] = activationTime;
|
|
441
|
+
|
|
442
|
+
if (generalData.noise.offsets)
|
|
443
|
+
generalData.noise.offsets[particleIndex] = Math.random() * 100;
|
|
344
444
|
|
|
345
445
|
const colorRandomRatio = Math.random();
|
|
346
446
|
|
|
@@ -379,6 +479,13 @@ export const createParticleSystem = (
|
|
|
379
479
|
THREE.MathUtils.randFloat(startRotation.min, startRotation.max)
|
|
380
480
|
);
|
|
381
481
|
|
|
482
|
+
if (normalizedConfig.rotationOverLifetime.isActive)
|
|
483
|
+
generalData.lifetimeValues.rotationOverLifetime[particleIndex] =
|
|
484
|
+
THREE.MathUtils.randFloat(
|
|
485
|
+
normalizedConfig.rotationOverLifetime.min,
|
|
486
|
+
normalizedConfig.rotationOverLifetime.max
|
|
487
|
+
);
|
|
488
|
+
|
|
382
489
|
geometry.attributes.rotation.needsUpdate = true;
|
|
383
490
|
geometry.attributes.colorB.needsUpdate = true;
|
|
384
491
|
|
|
@@ -386,7 +493,8 @@ export const createParticleSystem = (
|
|
|
386
493
|
shape,
|
|
387
494
|
startSpeed,
|
|
388
495
|
startPositions[particleIndex],
|
|
389
|
-
velocities[particleIndex]
|
|
496
|
+
velocities[particleIndex],
|
|
497
|
+
velocityOverLifetime
|
|
390
498
|
);
|
|
391
499
|
const positionIndex = Math.floor(particleIndex * 3);
|
|
392
500
|
geometry.attributes.position.array[positionIndex] =
|
|
@@ -395,13 +503,16 @@ export const createParticleSystem = (
|
|
|
395
503
|
startPositions[particleIndex].y;
|
|
396
504
|
geometry.attributes.position.array[positionIndex + 2] =
|
|
397
505
|
startPositions[particleIndex].z;
|
|
398
|
-
particleSystem.geometry.attributes.position.needsUpdate = true;
|
|
399
506
|
|
|
400
507
|
geometry.attributes.lifetime.array[particleIndex] = 0;
|
|
401
508
|
geometry.attributes.lifetime.needsUpdate = true;
|
|
402
509
|
|
|
403
510
|
applyModifiers({
|
|
511
|
+
delta: 0,
|
|
512
|
+
elapsed: 0,
|
|
513
|
+
noise: generalData.noise,
|
|
404
514
|
startValues: generalData.startValues,
|
|
515
|
+
lifetimeValues: generalData.lifetimeValues,
|
|
405
516
|
normalizedConfig,
|
|
406
517
|
attributes: particleSystem.geometry.attributes,
|
|
407
518
|
particleLifetimePercentage: 0,
|
|
@@ -519,59 +630,61 @@ export const updateParticleSystems = ({ now, delta, elapsed }) => {
|
|
|
519
630
|
particleSystem.updateMatrixWorld();
|
|
520
631
|
}
|
|
521
632
|
|
|
522
|
-
|
|
523
|
-
(
|
|
524
|
-
|
|
525
|
-
|
|
633
|
+
generalData.creationTimes.forEach((entry, index) => {
|
|
634
|
+
if (particleSystem.geometry.attributes.isActive.array[index]) {
|
|
635
|
+
const particleLifetime = now - entry;
|
|
636
|
+
if (
|
|
637
|
+
particleLifetime >
|
|
638
|
+
particleSystem.geometry.attributes.startLifetime.array[index]
|
|
639
|
+
)
|
|
640
|
+
deactivateParticle(index);
|
|
641
|
+
else {
|
|
642
|
+
const velocity = velocities[index];
|
|
643
|
+
velocity.x -= gravityVelocity.x;
|
|
644
|
+
velocity.y -= gravityVelocity.y;
|
|
645
|
+
velocity.z -= gravityVelocity.z;
|
|
646
|
+
|
|
526
647
|
if (
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
const
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
velocity.x !== 0 ||
|
|
540
|
-
velocity.y !== 0 ||
|
|
541
|
-
velocity.z !== 0
|
|
542
|
-
) {
|
|
543
|
-
const positionIndex = index * 3;
|
|
544
|
-
const positionArr =
|
|
545
|
-
particleSystem.geometry.attributes.position.array;
|
|
546
|
-
if (simulationSpace === SimulationSpace.WORLD) {
|
|
547
|
-
positionArr[positionIndex] -= worldPositionChange.x;
|
|
548
|
-
positionArr[positionIndex + 1] -= worldPositionChange.y;
|
|
549
|
-
positionArr[positionIndex + 2] -= worldPositionChange.z;
|
|
550
|
-
}
|
|
551
|
-
positionArr[positionIndex] += velocity.x * delta;
|
|
552
|
-
positionArr[positionIndex + 1] += velocity.y * delta;
|
|
553
|
-
positionArr[positionIndex + 2] += velocity.z * delta;
|
|
554
|
-
particleSystem.geometry.attributes.position.needsUpdate = true;
|
|
648
|
+
gravity !== 0 ||
|
|
649
|
+
velocity.x !== 0 ||
|
|
650
|
+
velocity.y !== 0 ||
|
|
651
|
+
velocity.z !== 0
|
|
652
|
+
) {
|
|
653
|
+
const positionIndex = index * 3;
|
|
654
|
+
const positionArr =
|
|
655
|
+
particleSystem.geometry.attributes.position.array;
|
|
656
|
+
if (simulationSpace === SimulationSpace.WORLD) {
|
|
657
|
+
positionArr[positionIndex] -= worldPositionChange.x;
|
|
658
|
+
positionArr[positionIndex + 1] -= worldPositionChange.y;
|
|
659
|
+
positionArr[positionIndex + 2] -= worldPositionChange.z;
|
|
555
660
|
}
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
particleSystem.geometry.attributes.
|
|
560
|
-
|
|
561
|
-
const particleLifetimePercentage =
|
|
562
|
-
particleLifetime /
|
|
563
|
-
particleSystem.geometry.attributes.startLifetime.array[index];
|
|
564
|
-
applyModifiers({
|
|
565
|
-
startValues: generalData.startValues,
|
|
566
|
-
normalizedConfig,
|
|
567
|
-
attributes: particleSystem.geometry.attributes,
|
|
568
|
-
particleLifetimePercentage,
|
|
569
|
-
particleIndex: index,
|
|
570
|
-
});
|
|
661
|
+
positionArr[positionIndex] += velocity.x * delta;
|
|
662
|
+
positionArr[positionIndex + 1] += velocity.y * delta;
|
|
663
|
+
positionArr[positionIndex + 2] += velocity.z * delta;
|
|
664
|
+
particleSystem.geometry.attributes.position.needsUpdate = true;
|
|
571
665
|
}
|
|
666
|
+
|
|
667
|
+
particleSystem.geometry.attributes.lifetime.array[index] =
|
|
668
|
+
particleLifetime;
|
|
669
|
+
particleSystem.geometry.attributes.lifetime.needsUpdate = true;
|
|
670
|
+
|
|
671
|
+
const particleLifetimePercentage =
|
|
672
|
+
particleLifetime /
|
|
673
|
+
particleSystem.geometry.attributes.startLifetime.array[index];
|
|
674
|
+
applyModifiers({
|
|
675
|
+
delta,
|
|
676
|
+
elapsed,
|
|
677
|
+
noise: generalData.noise,
|
|
678
|
+
startValues: generalData.startValues,
|
|
679
|
+
lifetimeValues: generalData.lifetimeValues,
|
|
680
|
+
normalizedConfig,
|
|
681
|
+
attributes: particleSystem.geometry.attributes,
|
|
682
|
+
particleLifetimePercentage,
|
|
683
|
+
particleIndex: index,
|
|
684
|
+
});
|
|
572
685
|
}
|
|
573
686
|
}
|
|
574
|
-
);
|
|
687
|
+
});
|
|
575
688
|
|
|
576
689
|
if (looping || lifetime < duration * 1000) {
|
|
577
690
|
const emissionDelta = now - lastEmissionTime;
|