@newkrok/three-particles 2.15.0 → 2.15.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/dist/index.d.ts +6 -0
- package/dist/index.js +147 -29
- package/dist/index.js.map +1 -1
- package/dist/three-particles.min.js +1 -1
- package/dist/three-particles.min.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1801,6 +1801,12 @@ type ParticleSystemInstance = {
|
|
|
1801
1801
|
trailAlphaAttr?: THREE.BufferAttribute;
|
|
1802
1802
|
/** Trail geometry color attribute */
|
|
1803
1803
|
trailColorAttr?: THREE.BufferAttribute;
|
|
1804
|
+
/** Trail geometry next-position attribute (cached to avoid repeated getAttribute) */
|
|
1805
|
+
trailNextAttr?: THREE.BufferAttribute;
|
|
1806
|
+
/** Trail geometry half-width attribute (cached) */
|
|
1807
|
+
trailHalfWidthAttr?: THREE.BufferAttribute;
|
|
1808
|
+
/** Trail geometry UV attribute (cached) */
|
|
1809
|
+
trailUVAttr?: THREE.BufferAttribute;
|
|
1804
1810
|
/** Trail width curve function */
|
|
1805
1811
|
trailWidthCurveFn?: CurveFunction;
|
|
1806
1812
|
/** Trail opacity curve function */
|
package/dist/index.js
CHANGED
|
@@ -1171,6 +1171,10 @@ var _particleSystemId = 0;
|
|
|
1171
1171
|
var createdParticleSystems = [];
|
|
1172
1172
|
var _subEmitterPosition = new THREE4.Vector3();
|
|
1173
1173
|
var _lastWorldPositionSnapshot = new THREE4.Vector3();
|
|
1174
|
+
var _localForceFieldPos = new THREE4.Vector3();
|
|
1175
|
+
var _localForceFieldDir = new THREE4.Vector3();
|
|
1176
|
+
var _inverseQuat = new THREE4.Quaternion();
|
|
1177
|
+
var _localForceFields = [];
|
|
1174
1178
|
new THREE4.Vector3();
|
|
1175
1179
|
new THREE4.Vector3();
|
|
1176
1180
|
new THREE4.Vector3();
|
|
@@ -2148,6 +2152,9 @@ var createParticleSystem = (config = DEFAULT_PARTICLE_SYSTEM_CONFIG, externalNow
|
|
|
2148
2152
|
let trailPositionAttr;
|
|
2149
2153
|
let trailAlphaAttr;
|
|
2150
2154
|
let trailColorAttr;
|
|
2155
|
+
let trailNextAttr;
|
|
2156
|
+
let trailHalfWidthAttr;
|
|
2157
|
+
let trailUVAttr;
|
|
2151
2158
|
let trailIndexAttr;
|
|
2152
2159
|
let trailWidthCurveFn;
|
|
2153
2160
|
let trailOpacityCurveFn;
|
|
@@ -2187,15 +2194,15 @@ var createParticleSystem = (config = DEFAULT_PARTICLE_SYSTEM_CONFIG, externalNow
|
|
|
2187
2194
|
}
|
|
2188
2195
|
trailPositionAttr = new THREE4.BufferAttribute(trailPositions, 3);
|
|
2189
2196
|
trailPositionAttr.setUsage(THREE4.DynamicDrawUsage);
|
|
2190
|
-
|
|
2197
|
+
trailNextAttr = new THREE4.BufferAttribute(trailNextPositions, 3);
|
|
2191
2198
|
trailNextAttr.setUsage(THREE4.DynamicDrawUsage);
|
|
2192
2199
|
trailAlphaAttr = new THREE4.BufferAttribute(trailAlphas, 1);
|
|
2193
2200
|
trailAlphaAttr.setUsage(THREE4.DynamicDrawUsage);
|
|
2194
2201
|
trailColorAttr = new THREE4.BufferAttribute(trailColors, 4);
|
|
2195
2202
|
trailColorAttr.setUsage(THREE4.DynamicDrawUsage);
|
|
2196
|
-
|
|
2203
|
+
trailHalfWidthAttr = new THREE4.BufferAttribute(trailHalfWidths, 1);
|
|
2197
2204
|
trailHalfWidthAttr.setUsage(THREE4.DynamicDrawUsage);
|
|
2198
|
-
|
|
2205
|
+
trailUVAttr = new THREE4.BufferAttribute(trailUVs, 2);
|
|
2199
2206
|
trailUVAttr.setUsage(THREE4.DynamicDrawUsage);
|
|
2200
2207
|
trailIndexAttr = new THREE4.BufferAttribute(trailIndices, 1);
|
|
2201
2208
|
trailGeometry.setAttribute("position", trailPositionAttr);
|
|
@@ -2377,6 +2384,9 @@ var createParticleSystem = (config = DEFAULT_PARTICLE_SYSTEM_CONFIG, externalNow
|
|
|
2377
2384
|
trailPositionAttr,
|
|
2378
2385
|
trailAlphaAttr,
|
|
2379
2386
|
trailColorAttr,
|
|
2387
|
+
trailNextAttr,
|
|
2388
|
+
trailHalfWidthAttr,
|
|
2389
|
+
trailUVAttr,
|
|
2380
2390
|
trailWidthCurveFn,
|
|
2381
2391
|
trailOpacityCurveFn,
|
|
2382
2392
|
trailColorOverTrailFns,
|
|
@@ -2527,6 +2537,37 @@ var updateParticleSystemInstance = (props, { now, delta, elapsed }) => {
|
|
|
2527
2537
|
);
|
|
2528
2538
|
particleSystem.worldToLocal(gravityVelocity);
|
|
2529
2539
|
}
|
|
2540
|
+
if (hasForceFields) {
|
|
2541
|
+
_inverseQuat.copy(worldQuaternion).invert();
|
|
2542
|
+
_localForceFields.length = normalizedForceFields.length;
|
|
2543
|
+
for (let i = 0; i < normalizedForceFields.length; i++) {
|
|
2544
|
+
const src = normalizedForceFields[i];
|
|
2545
|
+
let dst = _localForceFields[i];
|
|
2546
|
+
if (!dst) {
|
|
2547
|
+
dst = {
|
|
2548
|
+
isActive: true,
|
|
2549
|
+
type: "POINT" /* POINT */,
|
|
2550
|
+
position: new THREE4.Vector3(),
|
|
2551
|
+
direction: new THREE4.Vector3(),
|
|
2552
|
+
strength: 0,
|
|
2553
|
+
range: 0,
|
|
2554
|
+
falloff: "LINEAR" /* LINEAR */
|
|
2555
|
+
};
|
|
2556
|
+
_localForceFields[i] = dst;
|
|
2557
|
+
}
|
|
2558
|
+
dst.isActive = src.isActive;
|
|
2559
|
+
dst.type = src.type;
|
|
2560
|
+
dst.strength = src.strength;
|
|
2561
|
+
dst.range = src.range;
|
|
2562
|
+
dst.falloff = src.falloff;
|
|
2563
|
+
_localForceFieldPos.copy(src.position);
|
|
2564
|
+
particleSystem.worldToLocal(_localForceFieldPos);
|
|
2565
|
+
dst.position.copy(_localForceFieldPos);
|
|
2566
|
+
_localForceFieldDir.copy(src.direction);
|
|
2567
|
+
_localForceFieldDir.applyQuaternion(_inverseQuat);
|
|
2568
|
+
dst.direction.copy(_localForceFieldDir);
|
|
2569
|
+
}
|
|
2570
|
+
}
|
|
2530
2571
|
const creationTimes = generalData.creationTimes;
|
|
2531
2572
|
const isActiveArr = ma.isActive.array;
|
|
2532
2573
|
const startLifetimeArr = ma.startLifetime.array;
|
|
@@ -2554,7 +2595,7 @@ var updateParticleSystemInstance = (props, { now, delta, elapsed }) => {
|
|
|
2554
2595
|
if (hasForceFields) {
|
|
2555
2596
|
applyForceFields({
|
|
2556
2597
|
particleSystemId: generalData.particleSystemId,
|
|
2557
|
-
forceFields:
|
|
2598
|
+
forceFields: _localForceFields,
|
|
2558
2599
|
velocity,
|
|
2559
2600
|
positionArr,
|
|
2560
2601
|
positionIndex: index * 3,
|
|
@@ -2774,13 +2815,16 @@ var updateTrailGeometry = (props, now) => {
|
|
|
2774
2815
|
trailPositionAttr,
|
|
2775
2816
|
trailAlphaAttr,
|
|
2776
2817
|
trailColorAttr,
|
|
2818
|
+
trailNextAttr: trailNextAttrCached,
|
|
2819
|
+
trailHalfWidthAttr: trailHalfWidthAttrCached,
|
|
2820
|
+
trailUVAttr: trailUVAttrCached,
|
|
2777
2821
|
trailWidthCurveFn,
|
|
2778
2822
|
trailOpacityCurveFn,
|
|
2779
2823
|
trailColorOverTrailFns,
|
|
2780
2824
|
trailConfig,
|
|
2781
2825
|
mappedAttributes: ma
|
|
2782
2826
|
} = props;
|
|
2783
|
-
if (!trailPositionAttr || !trailAlphaAttr || !trailColorAttr || !trailWidthCurveFn || !trailOpacityCurveFn || !trailConfig || !generalData.positionHistory || !generalData.positionHistoryIndex || !generalData.positionHistoryCount)
|
|
2827
|
+
if (!trailPositionAttr || !trailAlphaAttr || !trailColorAttr || !trailNextAttrCached || !trailHalfWidthAttrCached || !trailUVAttrCached || !trailWidthCurveFn || !trailOpacityCurveFn || !trailConfig || !generalData.positionHistory || !generalData.positionHistoryIndex || !generalData.positionHistoryCount)
|
|
2784
2828
|
return;
|
|
2785
2829
|
const trailLength = trailConfig.length;
|
|
2786
2830
|
const positionHistory = generalData.positionHistory;
|
|
@@ -2806,10 +2850,9 @@ var updateTrailGeometry = (props, now) => {
|
|
|
2806
2850
|
const trailPosArr = trailPositionAttr.array;
|
|
2807
2851
|
const trailAlphaArr = trailAlphaAttr.array;
|
|
2808
2852
|
const trailColorArr = trailColorAttr.array;
|
|
2809
|
-
const
|
|
2810
|
-
const
|
|
2811
|
-
const
|
|
2812
|
-
const trailHalfWidthArr = trailMesh.geometry.getAttribute("trailHalfWidth").array;
|
|
2853
|
+
const trailNextArr = trailNextAttrCached.array;
|
|
2854
|
+
const trailUVArr = trailUVAttrCached.array;
|
|
2855
|
+
const trailHalfWidthArr = trailHalfWidthAttrCached.array;
|
|
2813
2856
|
const verticesPerParticle = trailLength * 2;
|
|
2814
2857
|
const creationTimesLength = generalData.creationTimes.length;
|
|
2815
2858
|
let hasUpdates = false;
|
|
@@ -3038,6 +3081,13 @@ var updateTrailGeometry = (props, now) => {
|
|
|
3038
3081
|
nx = finalPts[(s + 1) * 3];
|
|
3039
3082
|
ny = finalPts[(s + 1) * 3 + 1];
|
|
3040
3083
|
nz = finalPts[(s + 1) * 3 + 2];
|
|
3084
|
+
} else if (finalCount >= 2) {
|
|
3085
|
+
const prevX = finalPts[(s - 1) * 3];
|
|
3086
|
+
const prevY = finalPts[(s - 1) * 3 + 1];
|
|
3087
|
+
const prevZ = finalPts[(s - 1) * 3 + 2];
|
|
3088
|
+
nx = hx + (hx - prevX);
|
|
3089
|
+
ny = hy + (hy - prevY);
|
|
3090
|
+
nz = hz + (hz - prevZ);
|
|
3041
3091
|
} else {
|
|
3042
3092
|
nx = hx;
|
|
3043
3093
|
ny = hy + 1e-3;
|
|
@@ -3046,14 +3096,24 @@ var updateTrailGeometry = (props, now) => {
|
|
|
3046
3096
|
const t = finalCount > 1 ? s / (finalCount - 1) : 0;
|
|
3047
3097
|
let timeFade = 1;
|
|
3048
3098
|
if (maxTime > 0 && sampleTimes && effectiveCount > 0) {
|
|
3049
|
-
const rawS = useSmoothing ? Math.min(
|
|
3050
|
-
Math.floor(s / Math.max(finalCount - 1, 1) * (rawCount - 1)),
|
|
3051
|
-
rawCount - 1
|
|
3052
|
-
) : Math.min(s, rawCount - 1);
|
|
3053
|
-
const sampleSlot = (historyIndex[index] - 1 - rawS + trailLength * 2) % trailLength;
|
|
3054
3099
|
const sampleBase = index * trailLength;
|
|
3055
|
-
|
|
3056
|
-
|
|
3100
|
+
if (useSmoothing && rawCount >= 2) {
|
|
3101
|
+
const rawF = s / Math.max(finalCount - 1, 1) * (rawCount - 1);
|
|
3102
|
+
const rawLo = Math.min(Math.floor(rawF), rawCount - 1);
|
|
3103
|
+
const rawHi = Math.min(rawLo + 1, rawCount - 1);
|
|
3104
|
+
const frac = rawF - rawLo;
|
|
3105
|
+
const slotLo = (historyIndex[index] - 1 - rawLo + trailLength * 2) % trailLength;
|
|
3106
|
+
const slotHi = (historyIndex[index] - 1 - rawHi + trailLength * 2) % trailLength;
|
|
3107
|
+
const ageLo = now - sampleTimes[sampleBase + slotLo];
|
|
3108
|
+
const ageHi = now - sampleTimes[sampleBase + slotHi];
|
|
3109
|
+
const age = ageLo + (ageHi - ageLo) * frac;
|
|
3110
|
+
timeFade = 1 - Math.min(age / maxTimeMs, 1);
|
|
3111
|
+
} else {
|
|
3112
|
+
const rawS = Math.min(s, rawCount - 1);
|
|
3113
|
+
const sampleSlot = (historyIndex[index] - 1 - rawS + trailLength * 2) % trailLength;
|
|
3114
|
+
const age = now - sampleTimes[sampleBase + sampleSlot];
|
|
3115
|
+
timeFade = 1 - Math.min(age / maxTimeMs, 1);
|
|
3116
|
+
}
|
|
3057
3117
|
}
|
|
3058
3118
|
const widthScale = trailWidthCurveFn(t);
|
|
3059
3119
|
const opacityScale = trailOpacityCurveFn(t);
|
|
@@ -3286,16 +3346,34 @@ var updateTrailGeometry = (props, now) => {
|
|
|
3286
3346
|
nx = _rawPoints[(s + 1) * 3];
|
|
3287
3347
|
ny = _rawPoints[(s + 1) * 3 + 1];
|
|
3288
3348
|
nz = _rawPoints[(s + 1) * 3 + 2];
|
|
3349
|
+
} else if (filledCount >= 2) {
|
|
3350
|
+
const prevX = _rawPoints[(s - 1) * 3];
|
|
3351
|
+
const prevY = _rawPoints[(s - 1) * 3 + 1];
|
|
3352
|
+
const prevZ = _rawPoints[(s - 1) * 3 + 2];
|
|
3353
|
+
nx = ptx + (ptx - prevX);
|
|
3354
|
+
ny = pty + (pty - prevY);
|
|
3355
|
+
nz = ptz + (ptz - prevZ);
|
|
3289
3356
|
} else {
|
|
3290
3357
|
nx = ptx;
|
|
3291
3358
|
ny = pty + 1e-3;
|
|
3292
3359
|
nz = ptz;
|
|
3293
3360
|
}
|
|
3294
3361
|
const t = filledCount > 1 ? s / (filledCount - 1) : 0;
|
|
3362
|
+
let ribbonTimeFade = 1;
|
|
3363
|
+
if (maxTime > 0 && controlCount >= 2) {
|
|
3364
|
+
const ctrlF = t * (controlCount - 1);
|
|
3365
|
+
const ctrlLo = Math.min(Math.floor(ctrlF), controlCount - 1);
|
|
3366
|
+
const ctrlHi = Math.min(ctrlLo + 1, controlCount - 1);
|
|
3367
|
+
const frac = ctrlF - ctrlLo;
|
|
3368
|
+
const ageLo = now - generalData.creationTimes[_ribbonIndices[ctrlLo]];
|
|
3369
|
+
const ageHi = now - generalData.creationTimes[_ribbonIndices[ctrlHi]];
|
|
3370
|
+
const age = ageLo + (ageHi - ageLo) * frac;
|
|
3371
|
+
ribbonTimeFade = 1 - Math.min(age / maxTimeMs, 1);
|
|
3372
|
+
}
|
|
3295
3373
|
const widthScale = trailWidthCurveFn(t);
|
|
3296
3374
|
const opacityScale = trailOpacityCurveFn(t);
|
|
3297
3375
|
const halfWidth = trailConfig.width * widthScale * 0.5;
|
|
3298
|
-
const alpha = leaderCa * opacityScale;
|
|
3376
|
+
const alpha = leaderCa * opacityScale * ribbonTimeFade;
|
|
3299
3377
|
const fr = trailColorOverTrailFns ? leaderCr * trailColorOverTrailFns.r(t) : leaderCr;
|
|
3300
3378
|
const fg = trailColorOverTrailFns ? leaderCg * trailColorOverTrailFns.g(t) : leaderCg;
|
|
3301
3379
|
const fb = trailColorOverTrailFns ? leaderCb * trailColorOverTrailFns.b(t) : leaderCb;
|
|
@@ -3325,6 +3403,55 @@ var updateTrailGeometry = (props, now) => {
|
|
|
3325
3403
|
trailColorArr
|
|
3326
3404
|
);
|
|
3327
3405
|
}
|
|
3406
|
+
if (useTwistPrevention && prevNormal && filledCount >= 2) {
|
|
3407
|
+
const nIdx = leader * 3;
|
|
3408
|
+
const tx = _rawPoints[3] - _rawPoints[0];
|
|
3409
|
+
const ty = _rawPoints[4] - _rawPoints[1];
|
|
3410
|
+
const tz = _rawPoints[5] - _rawPoints[2];
|
|
3411
|
+
const tLen = Math.sqrt(tx * tx + ty * ty + tz * tz);
|
|
3412
|
+
if (tLen > 1e-4) {
|
|
3413
|
+
const ntx = tx / tLen;
|
|
3414
|
+
const nty = ty / tLen;
|
|
3415
|
+
const ntz = tz / tLen;
|
|
3416
|
+
let upx = 0, upy = 1, upz = 0;
|
|
3417
|
+
const dot = ntx * upx + nty * upy + ntz * upz;
|
|
3418
|
+
if (Math.abs(dot) > 0.999) {
|
|
3419
|
+
upx = 1;
|
|
3420
|
+
upy = 0;
|
|
3421
|
+
upz = 0;
|
|
3422
|
+
}
|
|
3423
|
+
let cnx = nty * upz - ntz * upy;
|
|
3424
|
+
let cny = ntz * upx - ntx * upz;
|
|
3425
|
+
let cnz = ntx * upy - nty * upx;
|
|
3426
|
+
const cnLen = Math.sqrt(cnx * cnx + cny * cny + cnz * cnz);
|
|
3427
|
+
if (cnLen > 1e-4) {
|
|
3428
|
+
cnx /= cnLen;
|
|
3429
|
+
cny /= cnLen;
|
|
3430
|
+
cnz /= cnLen;
|
|
3431
|
+
}
|
|
3432
|
+
const prevNx = prevNormal[nIdx];
|
|
3433
|
+
const prevNy = prevNormal[nIdx + 1];
|
|
3434
|
+
const prevNz = prevNormal[nIdx + 2];
|
|
3435
|
+
const hasPrev = prevNx !== 0 || prevNy !== 0 || prevNz !== 0;
|
|
3436
|
+
if (hasPrev) {
|
|
3437
|
+
const normalDot = cnx * prevNx + cny * prevNy + cnz * prevNz;
|
|
3438
|
+
if (normalDot < 0) {
|
|
3439
|
+
for (let s = 0; s < Math.min(filledCount, trailLength); s++) {
|
|
3440
|
+
const aIdx = leaderVertBase + s * 2;
|
|
3441
|
+
const hw = trailHalfWidthArr[aIdx];
|
|
3442
|
+
trailHalfWidthArr[aIdx] = -hw;
|
|
3443
|
+
trailHalfWidthArr[aIdx + 1] = -hw;
|
|
3444
|
+
}
|
|
3445
|
+
cnx = -cnx;
|
|
3446
|
+
cny = -cny;
|
|
3447
|
+
cnz = -cnz;
|
|
3448
|
+
}
|
|
3449
|
+
}
|
|
3450
|
+
prevNormal[nIdx] = cnx;
|
|
3451
|
+
prevNormal[nIdx + 1] = cny;
|
|
3452
|
+
prevNormal[nIdx + 2] = cnz;
|
|
3453
|
+
}
|
|
3454
|
+
}
|
|
3328
3455
|
for (let ri = 1; ri < _ribbonCount; ri++) {
|
|
3329
3456
|
const pIdx = _ribbonIndices[ri];
|
|
3330
3457
|
const pVertBase = pIdx * verticesPerParticle;
|
|
@@ -3355,18 +3482,9 @@ var updateTrailGeometry = (props, now) => {
|
|
|
3355
3482
|
trailPositionAttr.needsUpdate = true;
|
|
3356
3483
|
trailAlphaAttr.needsUpdate = true;
|
|
3357
3484
|
trailColorAttr.needsUpdate = true;
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
const hwAttr = trailMesh.geometry.getAttribute(
|
|
3362
|
-
"trailHalfWidth"
|
|
3363
|
-
);
|
|
3364
|
-
nextAttr.needsUpdate = true;
|
|
3365
|
-
hwAttr.needsUpdate = true;
|
|
3366
|
-
const uvAttr = trailMesh.geometry.getAttribute(
|
|
3367
|
-
"trailUV"
|
|
3368
|
-
);
|
|
3369
|
-
uvAttr.needsUpdate = true;
|
|
3485
|
+
trailNextAttrCached.needsUpdate = true;
|
|
3486
|
+
trailHalfWidthAttrCached.needsUpdate = true;
|
|
3487
|
+
trailUVAttrCached.needsUpdate = true;
|
|
3370
3488
|
}
|
|
3371
3489
|
};
|
|
3372
3490
|
var updateParticleSystems = (cycleData) => {
|