@newkrok/three-particles 2.6.5 → 2.7.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/dist/index.d.ts +73 -1
- package/dist/index.js +123 -5
- 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
|
@@ -116,6 +116,23 @@ declare const enum LifeTimeCurve {
|
|
|
116
116
|
*/
|
|
117
117
|
EASING = "EASING"
|
|
118
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Defines when a sub-emitter is triggered relative to a particle's lifecycle.
|
|
121
|
+
*
|
|
122
|
+
* @enum {string}
|
|
123
|
+
*/
|
|
124
|
+
declare const enum SubEmitterTrigger {
|
|
125
|
+
/**
|
|
126
|
+
* Trigger the sub-emitter when a particle is born (activated).
|
|
127
|
+
* Useful for trail effects that start immediately with each particle.
|
|
128
|
+
*/
|
|
129
|
+
BIRTH = "BIRTH",
|
|
130
|
+
/**
|
|
131
|
+
* Trigger the sub-emitter when a particle dies (reaches end of lifetime).
|
|
132
|
+
* Useful for cascading effects like explosions spawning smoke.
|
|
133
|
+
*/
|
|
134
|
+
DEATH = "DEATH"
|
|
135
|
+
}
|
|
119
136
|
|
|
120
137
|
/**
|
|
121
138
|
* A fixed numerical value.
|
|
@@ -701,6 +718,41 @@ type VelocityOverLifetime = {
|
|
|
701
718
|
z?: Constant | RandomBetweenTwoConstants | LifetimeCurve;
|
|
702
719
|
};
|
|
703
720
|
};
|
|
721
|
+
/**
|
|
722
|
+
* Configuration for a sub-emitter that spawns child particle systems
|
|
723
|
+
* based on parent particle lifecycle events.
|
|
724
|
+
*
|
|
725
|
+
* @example
|
|
726
|
+
* ```typescript
|
|
727
|
+
* const subEmitter: SubEmitterConfig = {
|
|
728
|
+
* trigger: SubEmitterTrigger.DEATH,
|
|
729
|
+
* config: { startLifeTime: 0.5, startSpeed: 2, emission: { rateOverTime: 20 } },
|
|
730
|
+
* inheritVelocity: 0.5,
|
|
731
|
+
* maxInstances: 16,
|
|
732
|
+
* };
|
|
733
|
+
* ```
|
|
734
|
+
*/
|
|
735
|
+
type SubEmitterConfig = {
|
|
736
|
+
/** The particle system configuration used when spawning the sub-emitter. */
|
|
737
|
+
config: ParticleSystemConfig;
|
|
738
|
+
/**
|
|
739
|
+
* When to trigger the sub-emitter.
|
|
740
|
+
* @default SubEmitterTrigger.DEATH
|
|
741
|
+
*/
|
|
742
|
+
trigger?: SubEmitterTrigger;
|
|
743
|
+
/**
|
|
744
|
+
* Multiplier (0–1) for inheriting the parent particle's velocity.
|
|
745
|
+
* 0 = no inheritance, 1 = full velocity inheritance.
|
|
746
|
+
* @default 0
|
|
747
|
+
*/
|
|
748
|
+
inheritVelocity?: number;
|
|
749
|
+
/**
|
|
750
|
+
* Maximum number of concurrent sub-emitter instances for this configuration.
|
|
751
|
+
* Older completed instances are cleaned up to make room for new ones.
|
|
752
|
+
* @default 32
|
|
753
|
+
*/
|
|
754
|
+
maxInstances?: number;
|
|
755
|
+
};
|
|
704
756
|
/**
|
|
705
757
|
* Configuration object for the particle system.
|
|
706
758
|
* Defines all aspects of the particle system, including its appearance, behavior, and runtime events.
|
|
@@ -1188,6 +1240,22 @@ type ParticleSystemConfig = {
|
|
|
1188
1240
|
* }
|
|
1189
1241
|
*/
|
|
1190
1242
|
textureSheetAnimation?: TextureSheetAnimation;
|
|
1243
|
+
/**
|
|
1244
|
+
* Sub-emitters that spawn child particle systems on particle lifecycle events.
|
|
1245
|
+
* Each sub-emitter is triggered when a particle is born or dies, creating a new
|
|
1246
|
+
* particle system at the parent particle's position.
|
|
1247
|
+
*
|
|
1248
|
+
* @example
|
|
1249
|
+
* ```typescript
|
|
1250
|
+
* subEmitters: [
|
|
1251
|
+
* {
|
|
1252
|
+
* trigger: SubEmitterTrigger.DEATH,
|
|
1253
|
+
* config: { startLifeTime: 0.5, startSpeed: 1, emission: { rateOverTime: 10 } },
|
|
1254
|
+
* },
|
|
1255
|
+
* ]
|
|
1256
|
+
* ```
|
|
1257
|
+
*/
|
|
1258
|
+
subEmitters?: Array<SubEmitterConfig>;
|
|
1191
1259
|
/**
|
|
1192
1260
|
* Called on every update frame with particle system data.
|
|
1193
1261
|
*/
|
|
@@ -1288,6 +1356,10 @@ type ParticleSystemInstance = {
|
|
|
1288
1356
|
activationTime: number;
|
|
1289
1357
|
position: Required<Point3D>;
|
|
1290
1358
|
}) => void;
|
|
1359
|
+
/** Called when a particle dies to trigger death sub-emitters */
|
|
1360
|
+
onParticleDeath?: (particleIndex: number, positionArr: THREE.TypedArray, velocity: THREE.Vector3, now: number) => void;
|
|
1361
|
+
/** Called when a particle is born to trigger birth sub-emitters */
|
|
1362
|
+
onParticleBirth?: (particleIndex: number, positionArr: THREE.TypedArray, velocity: THREE.Vector3, now: number) => void;
|
|
1291
1363
|
};
|
|
1292
1364
|
/**
|
|
1293
1365
|
* Represents a particle system instance, providing methods to control and manage its lifecycle.
|
|
@@ -1779,4 +1851,4 @@ declare const getDefaultParticleSystemConfig: () => any;
|
|
|
1779
1851
|
declare const createParticleSystem: (config?: ParticleSystemConfig, externalNow?: number) => ParticleSystem;
|
|
1780
1852
|
declare const updateParticleSystems: (cycleData: CycleData) => void;
|
|
1781
1853
|
|
|
1782
|
-
export { type BezierCurve, type BezierPoint, type Box, type Burst, type BurstState, type Circle, type Cone, type Constant, type CurveBase, type CurveFunction, CurveFunctionId, type CycleData, type EasingCurve, type Emission, EmitFrom, type GeneralData, LifeTimeCurve, type LifetimeCurve, type MinMaxColor, type Noise, type NoiseConfig, type NormalizedParticleSystemConfig, type ParticleSystem, type ParticleSystemConfig, type ParticleSystemInstance, type Point3D, type RandomBetweenTwoConstants, type Rectangle, type Renderer, type Rgb, Shape, type ShapeConfig, SimulationSpace, type Sphere, type TextureSheetAnimation, TimeMode, type Transform, type VelocityOverLifetime, applyModifiers, blendingMap, calculateRandomPositionAndVelocityOnBox, calculateRandomPositionAndVelocityOnCircle, calculateRandomPositionAndVelocityOnCone, calculateRandomPositionAndVelocityOnRectangle, calculateRandomPositionAndVelocityOnSphere, calculateValue, createBezierCurveFunction, createDefaultParticleTexture, createParticleSystem, getBezierCacheSize, getCurveFunction, getCurveFunctionFromConfig, getDefaultParticleSystemConfig, isLifeTimeCurve, removeBezierCurveFunction, updateParticleSystems };
|
|
1854
|
+
export { type BezierCurve, type BezierPoint, type Box, type Burst, type BurstState, type Circle, type Cone, type Constant, type CurveBase, type CurveFunction, CurveFunctionId, type CycleData, type EasingCurve, type Emission, EmitFrom, type GeneralData, LifeTimeCurve, type LifetimeCurve, type MinMaxColor, type Noise, type NoiseConfig, type NormalizedParticleSystemConfig, type ParticleSystem, type ParticleSystemConfig, type ParticleSystemInstance, type Point3D, type RandomBetweenTwoConstants, type Rectangle, type Renderer, type Rgb, Shape, type ShapeConfig, SimulationSpace, type Sphere, type SubEmitterConfig, SubEmitterTrigger, type TextureSheetAnimation, TimeMode, type Transform, type VelocityOverLifetime, applyModifiers, blendingMap, calculateRandomPositionAndVelocityOnBox, calculateRandomPositionAndVelocityOnCircle, calculateRandomPositionAndVelocityOnCone, calculateRandomPositionAndVelocityOnRectangle, calculateRandomPositionAndVelocityOnSphere, calculateValue, createBezierCurveFunction, createDefaultParticleTexture, createParticleSystem, getBezierCacheSize, getCurveFunction, getCurveFunctionFromConfig, getDefaultParticleSystemConfig, isLifeTimeCurve, removeBezierCurveFunction, updateParticleSystems };
|
package/dist/index.js
CHANGED
|
@@ -160,6 +160,11 @@ var LifeTimeCurve = /* @__PURE__ */ ((LifeTimeCurve2) => {
|
|
|
160
160
|
LifeTimeCurve2["EASING"] = "EASING";
|
|
161
161
|
return LifeTimeCurve2;
|
|
162
162
|
})(LifeTimeCurve || {});
|
|
163
|
+
var SubEmitterTrigger = /* @__PURE__ */ ((SubEmitterTrigger2) => {
|
|
164
|
+
SubEmitterTrigger2["BIRTH"] = "BIRTH";
|
|
165
|
+
SubEmitterTrigger2["DEATH"] = "DEATH";
|
|
166
|
+
return SubEmitterTrigger2;
|
|
167
|
+
})(SubEmitterTrigger || {});
|
|
163
168
|
var calculateRandomPositionAndVelocityOnSphere = (position, quaternion, velocity, speed, {
|
|
164
169
|
radius,
|
|
165
170
|
radiusThickness,
|
|
@@ -589,6 +594,7 @@ var particle_system_vertex_shader_glsl_default = ParticleSystemVertexShader;
|
|
|
589
594
|
// src/js/effects/three-particles/three-particles.ts
|
|
590
595
|
var _particleSystemId = 0;
|
|
591
596
|
var createdParticleSystems = [];
|
|
597
|
+
var _subEmitterPosition = new THREE3.Vector3();
|
|
592
598
|
var _lastWorldPositionSnapshot = new THREE3.Vector3();
|
|
593
599
|
var _distanceStep = { x: 0, y: 0, z: 0 };
|
|
594
600
|
var _tempPosition = { x: 0, y: 0, z: 0 };
|
|
@@ -903,7 +909,8 @@ var createParticleSystem = (config = DEFAULT_PARTICLE_SYSTEM_CONFIG, externalNow
|
|
|
903
909
|
velocityOverLifetime,
|
|
904
910
|
onUpdate,
|
|
905
911
|
onComplete,
|
|
906
|
-
textureSheetAnimation
|
|
912
|
+
textureSheetAnimation,
|
|
913
|
+
subEmitters
|
|
907
914
|
} = normalizedConfig;
|
|
908
915
|
if (typeof renderer?.blending === "string")
|
|
909
916
|
renderer.blending = blendingMap[renderer.blending];
|
|
@@ -1311,6 +1318,68 @@ var createParticleSystem = (config = DEFAULT_PARTICLE_SYSTEM_CONFIG, externalNow
|
|
|
1311
1318
|
particleIndex
|
|
1312
1319
|
});
|
|
1313
1320
|
};
|
|
1321
|
+
const subEmitterArr = subEmitters ?? [];
|
|
1322
|
+
const deathSubEmitters = subEmitterArr.filter(
|
|
1323
|
+
(s) => (s.trigger ?? "DEATH" /* DEATH */) === "DEATH" /* DEATH */
|
|
1324
|
+
);
|
|
1325
|
+
const birthSubEmitters = subEmitterArr.filter(
|
|
1326
|
+
(s) => s.trigger === "BIRTH" /* BIRTH */
|
|
1327
|
+
);
|
|
1328
|
+
const subEmitterInstancesMap = /* @__PURE__ */ new Map();
|
|
1329
|
+
for (const cfg of subEmitterArr) {
|
|
1330
|
+
subEmitterInstancesMap.set(cfg, []);
|
|
1331
|
+
}
|
|
1332
|
+
const cleanupCompletedInstances = (instances) => {
|
|
1333
|
+
for (let i = instances.length - 1; i >= 0; i--) {
|
|
1334
|
+
const sub = instances[i];
|
|
1335
|
+
const points = sub.instance;
|
|
1336
|
+
const isActiveArr = points.geometry?.attributes?.isActive?.array;
|
|
1337
|
+
if (!isActiveArr) {
|
|
1338
|
+
sub.dispose();
|
|
1339
|
+
instances.splice(i, 1);
|
|
1340
|
+
continue;
|
|
1341
|
+
}
|
|
1342
|
+
let hasActive = false;
|
|
1343
|
+
for (let j = 0; j < isActiveArr.length; j++) {
|
|
1344
|
+
if (isActiveArr[j]) {
|
|
1345
|
+
hasActive = true;
|
|
1346
|
+
break;
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
if (!hasActive) {
|
|
1350
|
+
sub.dispose();
|
|
1351
|
+
instances.splice(i, 1);
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
};
|
|
1355
|
+
const spawnSubEmitters = (configs, position, velocity, spawnNow) => {
|
|
1356
|
+
for (const subConfig of configs) {
|
|
1357
|
+
const instances = subEmitterInstancesMap.get(subConfig);
|
|
1358
|
+
const maxInst = subConfig.maxInstances ?? 32;
|
|
1359
|
+
if (instances.length >= maxInst) {
|
|
1360
|
+
cleanupCompletedInstances(instances);
|
|
1361
|
+
if (instances.length >= maxInst) continue;
|
|
1362
|
+
}
|
|
1363
|
+
const inheritVelocity = subConfig.inheritVelocity ?? 0;
|
|
1364
|
+
const subSystem = createParticleSystem(
|
|
1365
|
+
{
|
|
1366
|
+
...subConfig.config,
|
|
1367
|
+
looping: false,
|
|
1368
|
+
transform: {
|
|
1369
|
+
...subConfig.config.transform,
|
|
1370
|
+
position: new THREE3.Vector3(position.x, position.y, position.z)
|
|
1371
|
+
},
|
|
1372
|
+
...inheritVelocity > 0 ? {
|
|
1373
|
+
startSpeed: (typeof subConfig.config.startSpeed === "number" ? subConfig.config.startSpeed : typeof subConfig.config.startSpeed === "object" && subConfig.config.startSpeed !== null && "min" in subConfig.config.startSpeed ? subConfig.config.startSpeed.min ?? 0 : 0) + velocity.length() * inheritVelocity
|
|
1374
|
+
} : {}
|
|
1375
|
+
},
|
|
1376
|
+
spawnNow
|
|
1377
|
+
);
|
|
1378
|
+
const parentObj = (wrapper || particleSystem).parent;
|
|
1379
|
+
if (parentObj) parentObj.add(subSystem.instance);
|
|
1380
|
+
instances.push(subSystem);
|
|
1381
|
+
}
|
|
1382
|
+
};
|
|
1314
1383
|
let particleSystem = new THREE3.Points(geometry, material);
|
|
1315
1384
|
particleSystem.position.copy(transform.position);
|
|
1316
1385
|
particleSystem.rotation.x = THREE3.MathUtils.degToRad(transform.rotation.x);
|
|
@@ -1323,6 +1392,36 @@ var createParticleSystem = (config = DEFAULT_PARTICLE_SYSTEM_CONFIG, externalNow
|
|
|
1323
1392
|
wrapper = new Gyroscope();
|
|
1324
1393
|
wrapper.add(particleSystem);
|
|
1325
1394
|
}
|
|
1395
|
+
const hasDeathSubEmitters = deathSubEmitters.length > 0;
|
|
1396
|
+
const hasBirthSubEmitters = birthSubEmitters.length > 0;
|
|
1397
|
+
const onParticleDeath = hasDeathSubEmitters ? (particleIndex, positionArr, velocity, deathNow) => {
|
|
1398
|
+
const posIdx = particleIndex * 3;
|
|
1399
|
+
_subEmitterPosition.set(
|
|
1400
|
+
positionArr[posIdx],
|
|
1401
|
+
positionArr[posIdx + 1],
|
|
1402
|
+
positionArr[posIdx + 2]
|
|
1403
|
+
);
|
|
1404
|
+
spawnSubEmitters(
|
|
1405
|
+
deathSubEmitters,
|
|
1406
|
+
_subEmitterPosition,
|
|
1407
|
+
velocity,
|
|
1408
|
+
deathNow
|
|
1409
|
+
);
|
|
1410
|
+
} : void 0;
|
|
1411
|
+
const onParticleBirth = hasBirthSubEmitters ? (particleIndex, positionArr, velocity, birthNow) => {
|
|
1412
|
+
const posIdx = particleIndex * 3;
|
|
1413
|
+
_subEmitterPosition.set(
|
|
1414
|
+
positionArr[posIdx],
|
|
1415
|
+
positionArr[posIdx + 1],
|
|
1416
|
+
positionArr[posIdx + 2]
|
|
1417
|
+
);
|
|
1418
|
+
spawnSubEmitters(
|
|
1419
|
+
birthSubEmitters,
|
|
1420
|
+
_subEmitterPosition,
|
|
1421
|
+
velocity,
|
|
1422
|
+
birthNow
|
|
1423
|
+
);
|
|
1424
|
+
} : void 0;
|
|
1326
1425
|
const instanceData = {
|
|
1327
1426
|
particleSystem,
|
|
1328
1427
|
wrapper,
|
|
@@ -1342,12 +1441,20 @@ var createParticleSystem = (config = DEFAULT_PARTICLE_SYSTEM_CONFIG, externalNow
|
|
|
1342
1441
|
velocities,
|
|
1343
1442
|
freeList,
|
|
1344
1443
|
deactivateParticle,
|
|
1345
|
-
activateParticle
|
|
1444
|
+
activateParticle,
|
|
1445
|
+
onParticleDeath,
|
|
1446
|
+
onParticleBirth
|
|
1346
1447
|
};
|
|
1347
1448
|
createdParticleSystems.push(instanceData);
|
|
1348
1449
|
const resumeEmitter = () => generalData.isEnabled = true;
|
|
1349
1450
|
const pauseEmitter = () => generalData.isEnabled = false;
|
|
1350
|
-
const dispose = () =>
|
|
1451
|
+
const dispose = () => {
|
|
1452
|
+
for (const instances of subEmitterInstancesMap.values()) {
|
|
1453
|
+
for (const sub of instances) sub.dispose();
|
|
1454
|
+
instances.length = 0;
|
|
1455
|
+
}
|
|
1456
|
+
destroyParticleSystem(particleSystem);
|
|
1457
|
+
};
|
|
1351
1458
|
const update = (cycleData) => updateParticleSystemInstance(instanceData, cycleData);
|
|
1352
1459
|
return {
|
|
1353
1460
|
instance: wrapper || particleSystem,
|
|
@@ -1377,7 +1484,9 @@ var updateParticleSystemInstance = (props, { now, delta, elapsed }) => {
|
|
|
1377
1484
|
deactivateParticle,
|
|
1378
1485
|
activateParticle,
|
|
1379
1486
|
simulationSpace,
|
|
1380
|
-
gravity
|
|
1487
|
+
gravity,
|
|
1488
|
+
onParticleDeath,
|
|
1489
|
+
onParticleBirth
|
|
1381
1490
|
} = props;
|
|
1382
1491
|
const lifetime = now - creationTime;
|
|
1383
1492
|
const normalizedLifetime = lifetime % (duration * 1e3);
|
|
@@ -1439,6 +1548,8 @@ var updateParticleSystemInstance = (props, { now, delta, elapsed }) => {
|
|
|
1439
1548
|
if (isActiveArr[index]) {
|
|
1440
1549
|
const particleLifetime = now - creationTimes[index];
|
|
1441
1550
|
if (particleLifetime > startLifetimeArr[index]) {
|
|
1551
|
+
if (onParticleDeath)
|
|
1552
|
+
onParticleDeath(index, positionArr, velocities[index], now);
|
|
1442
1553
|
deactivateParticle(index);
|
|
1443
1554
|
} else {
|
|
1444
1555
|
const velocity = velocities[index];
|
|
@@ -1550,6 +1661,13 @@ var updateParticleSystemInstance = (props, { now, delta, elapsed }) => {
|
|
|
1550
1661
|
activationTime: now,
|
|
1551
1662
|
position: _tempPosition
|
|
1552
1663
|
});
|
|
1664
|
+
if (onParticleBirth)
|
|
1665
|
+
onParticleBirth(
|
|
1666
|
+
particleIndex,
|
|
1667
|
+
attributes.position.array,
|
|
1668
|
+
velocities[particleIndex],
|
|
1669
|
+
now
|
|
1670
|
+
);
|
|
1553
1671
|
props.lastEmissionTime = now;
|
|
1554
1672
|
}
|
|
1555
1673
|
}
|
|
@@ -1573,6 +1691,6 @@ var updateParticleSystems = (cycleData) => {
|
|
|
1573
1691
|
);
|
|
1574
1692
|
};
|
|
1575
1693
|
|
|
1576
|
-
export { CurveFunctionId, EmitFrom, LifeTimeCurve, Shape, SimulationSpace, TimeMode, applyModifiers, blendingMap, calculateRandomPositionAndVelocityOnBox, calculateRandomPositionAndVelocityOnCircle, calculateRandomPositionAndVelocityOnCone, calculateRandomPositionAndVelocityOnRectangle, calculateRandomPositionAndVelocityOnSphere, calculateValue, createBezierCurveFunction, createDefaultParticleTexture, createParticleSystem, getBezierCacheSize, getCurveFunction, getCurveFunctionFromConfig, getDefaultParticleSystemConfig, isLifeTimeCurve, removeBezierCurveFunction, updateParticleSystems };
|
|
1694
|
+
export { CurveFunctionId, EmitFrom, LifeTimeCurve, Shape, SimulationSpace, SubEmitterTrigger, TimeMode, applyModifiers, blendingMap, calculateRandomPositionAndVelocityOnBox, calculateRandomPositionAndVelocityOnCircle, calculateRandomPositionAndVelocityOnCone, calculateRandomPositionAndVelocityOnRectangle, calculateRandomPositionAndVelocityOnSphere, calculateValue, createBezierCurveFunction, createDefaultParticleTexture, createParticleSystem, getBezierCacheSize, getCurveFunction, getCurveFunctionFromConfig, getDefaultParticleSystemConfig, isLifeTimeCurve, removeBezierCurveFunction, updateParticleSystems };
|
|
1577
1695
|
//# sourceMappingURL=index.js.map
|
|
1578
1696
|
//# sourceMappingURL=index.js.map
|