@flighthq/particles 0.1.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/applyParticleCollisions.d.ts +12 -0
- package/dist/applyParticleCollisions.d.ts.map +1 -0
- package/dist/applyParticleCollisions.js +175 -0
- package/dist/applyParticleCollisions.js.map +1 -0
- package/dist/applyParticleForces.d.ts +13 -0
- package/dist/applyParticleForces.d.ts.map +1 -0
- package/dist/applyParticleForces.js +129 -0
- package/dist/applyParticleForces.js.map +1 -0
- package/dist/curve.d.ts +35 -0
- package/dist/curve.d.ts.map +1 -0
- package/dist/curve.js +227 -0
- package/dist/curve.js.map +1 -0
- package/dist/emitParticleBurst.d.ts +15 -0
- package/dist/emitParticleBurst.d.ts.map +1 -0
- package/dist/emitParticleBurst.js +114 -0
- package/dist/emitParticleBurst.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/particleEmitterConfig.d.ts +4 -0
- package/dist/particleEmitterConfig.d.ts.map +1 -0
- package/dist/particleEmitterConfig.js +53 -0
- package/dist/particleEmitterConfig.js.map +1 -0
- package/dist/particleEmitterSignals.d.ts +20 -0
- package/dist/particleEmitterSignals.d.ts.map +1 -0
- package/dist/particleEmitterSignals.js +33 -0
- package/dist/particleEmitterSignals.js.map +1 -0
- package/dist/particleEmitterState.d.ts +7 -0
- package/dist/particleEmitterState.d.ts.map +1 -0
- package/dist/particleEmitterState.js +38 -0
- package/dist/particleEmitterState.js.map +1 -0
- package/dist/particleObjectsState.d.ts +4 -0
- package/dist/particleObjectsState.d.ts.map +1 -0
- package/dist/particleObjectsState.js +24 -0
- package/dist/particleObjectsState.js.map +1 -0
- package/dist/prewarmParticleEmitter.d.ts +5 -0
- package/dist/prewarmParticleEmitter.d.ts.map +1 -0
- package/dist/prewarmParticleEmitter.js +13 -0
- package/dist/prewarmParticleEmitter.js.map +1 -0
- package/dist/stepParticleEmitter.d.ts +38 -0
- package/dist/stepParticleEmitter.d.ts.map +1 -0
- package/dist/stepParticleEmitter.js +57 -0
- package/dist/stepParticleEmitter.js.map +1 -0
- package/dist/updateParticleEmitter.d.ts +8 -0
- package/dist/updateParticleEmitter.d.ts.map +1 -0
- package/dist/updateParticleEmitter.js +315 -0
- package/dist/updateParticleEmitter.js.map +1 -0
- package/dist/updateParticleObjects.d.ts +8 -0
- package/dist/updateParticleObjects.d.ts.map +1 -0
- package/dist/updateParticleObjects.js +151 -0
- package/dist/updateParticleObjects.js.map +1 -0
- package/dist/validateParticleEmitterConfig.d.ts +15 -0
- package/dist/validateParticleEmitterConfig.d.ts.map +1 -0
- package/dist/validateParticleEmitterConfig.js +206 -0
- package/dist/validateParticleEmitterConfig.js.map +1 -0
- package/package.json +42 -0
- package/src/applyParticleCollisions.test.ts +191 -0
- package/src/applyParticleForces.test.ts +174 -0
- package/src/curve.test.ts +327 -0
- package/src/deterministic.test.ts +54 -0
- package/src/emitParticleBurst.test.ts +103 -0
- package/src/particleEmitterConfig.test.ts +65 -0
- package/src/particleEmitterSignals.test.ts +125 -0
- package/src/particleEmitterState.test.ts +113 -0
- package/src/particleObjectsState.test.ts +34 -0
- package/src/prewarmParticleEmitter.test.ts +68 -0
- package/src/stepParticleEmitter.test.ts +113 -0
- package/src/updateParticleEmitter.test.ts +631 -0
- package/src/updateParticleObjects.test.ts +340 -0
- package/src/validateParticleEmitterConfig.test.ts +118 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ParticleEmitter } from '@flighthq/types';
|
|
2
|
+
import type { ParticleEmitterConfig, ParticleEmitterState } from '@flighthq/types';
|
|
3
|
+
/** Emit `count` particles immediately at an arbitrary point (in the emitter's
|
|
4
|
+
* simulation space), independent of the emitter's own spawn rate, bursts, or
|
|
5
|
+
* duration. Returns the number actually spawned (capped by `maxParticles`).
|
|
6
|
+
*
|
|
7
|
+
* This is the building block for sub-emitters: call it from an `onDeath` /
|
|
8
|
+
* `onSpawn` callback to spawn a child effect at the event position (explosions,
|
|
9
|
+
* debris, impact sparks), or once per live particle for trails. The child
|
|
10
|
+
* emitter/state/config are completely independent of the parent.
|
|
11
|
+
*
|
|
12
|
+
* Spawn randomness is drawn from `state.random`, so a seeded child state keeps
|
|
13
|
+
* sub-emitter output deterministic. */
|
|
14
|
+
export declare function emitParticleBurst(emitter: ParticleEmitter, state: ParticleEmitterState, config: Readonly<ParticleEmitterConfig>, count: number, x: number, y: number): number;
|
|
15
|
+
//# sourceMappingURL=emitParticleBurst.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emitParticleBurst.d.ts","sourceRoot":"","sources":["../src/emitParticleBurst.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAQnF;;;;;;;;;;wCAUwC;AACxC,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,oBAAoB,EAC3B,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC,EACvC,KAAK,EAAE,MAAM,EACb,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,GACR,MAAM,CAqGR"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { reserveParticleEmitter } from '@flighthq/sprite';
|
|
2
|
+
import { sampleParticleColorCurve, sampleParticleCurve } from './curve';
|
|
3
|
+
import { ensureParticleEmitterStateCapacity } from './particleEmitterState';
|
|
4
|
+
const PARTICLE_TRANSFORM_STRIDE = 4;
|
|
5
|
+
const TWO_PI = Math.PI * 2;
|
|
6
|
+
/** Emit `count` particles immediately at an arbitrary point (in the emitter's
|
|
7
|
+
* simulation space), independent of the emitter's own spawn rate, bursts, or
|
|
8
|
+
* duration. Returns the number actually spawned (capped by `maxParticles`).
|
|
9
|
+
*
|
|
10
|
+
* This is the building block for sub-emitters: call it from an `onDeath` /
|
|
11
|
+
* `onSpawn` callback to spawn a child effect at the event position (explosions,
|
|
12
|
+
* debris, impact sparks), or once per live particle for trails. The child
|
|
13
|
+
* emitter/state/config are completely independent of the parent.
|
|
14
|
+
*
|
|
15
|
+
* Spawn randomness is drawn from `state.random`, so a seeded child state keeps
|
|
16
|
+
* sub-emitter output deterministic. */
|
|
17
|
+
export function emitParticleBurst(emitter, state, config, count, x, y) {
|
|
18
|
+
const data = emitter.data;
|
|
19
|
+
const liveCount = data.particleCount;
|
|
20
|
+
let toSpawn = Math.floor(count);
|
|
21
|
+
const maxNew = config.maxParticles - liveCount;
|
|
22
|
+
if (toSpawn > maxNew)
|
|
23
|
+
toSpawn = maxNew;
|
|
24
|
+
if (toSpawn <= 0)
|
|
25
|
+
return 0;
|
|
26
|
+
const hasColorVariance = config.colorStartVarianceR !== 0 ||
|
|
27
|
+
config.colorStartVarianceG !== 0 ||
|
|
28
|
+
config.colorStartVarianceB !== 0 ||
|
|
29
|
+
config.colorEndVarianceR !== 0 ||
|
|
30
|
+
config.colorEndVarianceG !== 0 ||
|
|
31
|
+
config.colorEndVarianceB !== 0;
|
|
32
|
+
const newCount = liveCount + toSpawn;
|
|
33
|
+
reserveParticleEmitter(emitter, newCount);
|
|
34
|
+
ensureParticleEmitterStateCapacity(state, newCount, hasColorVariance);
|
|
35
|
+
const { colorStartR, colorStartG, colorStartB, colorEndR, colorEndG, colorEndB } = config;
|
|
36
|
+
const alphaCurve = config.alphaCurve;
|
|
37
|
+
const colorCurve = config.colorCurve;
|
|
38
|
+
const scaleCurve = config.scaleCurve;
|
|
39
|
+
const hasAlphaCurve = alphaCurve != null && alphaCurve.length > 0;
|
|
40
|
+
const hasColorCurve = colorCurve != null && colorCurve.length >= 3;
|
|
41
|
+
const hasScaleCurve = scaleCurve != null && scaleCurve.length > 0;
|
|
42
|
+
const baseAngle = Math.atan2(config.directionY, config.directionX);
|
|
43
|
+
const regionRange = config.regionIdMax - config.regionIdMin;
|
|
44
|
+
const regionIdMin = config.regionIdMin;
|
|
45
|
+
const rotSpeedRange = config.rotationSpeedMax - config.rotationSpeedMin;
|
|
46
|
+
const hasRotSpeed = config.rotationSpeedMin !== 0 || config.rotationSpeedMax !== 0;
|
|
47
|
+
const random = state.random;
|
|
48
|
+
for (let sIdx = 0; sIdx < toSpawn; sIdx++) {
|
|
49
|
+
const idx = liveCount + sIdx;
|
|
50
|
+
const lifetime = config.lifetimeMin + random() * (config.lifetimeMax - config.lifetimeMin);
|
|
51
|
+
const lt = idx * 2;
|
|
52
|
+
state.lifetimes[lt] = 0;
|
|
53
|
+
state.lifetimes[lt + 1] = lifetime;
|
|
54
|
+
const angle = baseAngle + (random() - 0.5) * 2 * config.spread;
|
|
55
|
+
const speed = config.speedMin + random() * (config.speedMax - config.speedMin);
|
|
56
|
+
state.velocities[idx * 2] = Math.cos(angle) * speed;
|
|
57
|
+
state.velocities[idx * 2 + 1] = Math.sin(angle) * speed;
|
|
58
|
+
// Position = burst point + emitter-shape offset.
|
|
59
|
+
let spawnX = x;
|
|
60
|
+
let spawnY = y;
|
|
61
|
+
if (config.emitterShape === 'circle' && config.emitterRadius > 0) {
|
|
62
|
+
const r = Math.sqrt(random()) * config.emitterRadius;
|
|
63
|
+
const a = random() * TWO_PI;
|
|
64
|
+
spawnX += Math.cos(a) * r;
|
|
65
|
+
spawnY += Math.sin(a) * r;
|
|
66
|
+
}
|
|
67
|
+
else if (config.emitterShape === 'rect' && (config.emitterWidth > 0 || config.emitterHeight > 0)) {
|
|
68
|
+
spawnX += (random() - 0.5) * config.emitterWidth;
|
|
69
|
+
spawnY += (random() - 0.5) * config.emitterHeight;
|
|
70
|
+
}
|
|
71
|
+
const spawnScale = config.scaleMin + random() * (config.scaleMax - config.scaleMin);
|
|
72
|
+
state.scales[idx] = spawnScale;
|
|
73
|
+
const tt = idx * PARTICLE_TRANSFORM_STRIDE;
|
|
74
|
+
data.transforms[tt] = spawnX;
|
|
75
|
+
data.transforms[tt + 1] = spawnY;
|
|
76
|
+
data.transforms[tt + 2] = angle;
|
|
77
|
+
data.transforms[tt + 3] = hasScaleCurve ? spawnScale * sampleParticleCurve(scaleCurve, 0) : spawnScale;
|
|
78
|
+
data.alphas[idx] = hasAlphaCurve ? sampleParticleCurve(alphaCurve, 0) : config.alphaStart;
|
|
79
|
+
const ct = idx * 3;
|
|
80
|
+
if (hasColorCurve) {
|
|
81
|
+
sampleParticleColorCurve(data.colors, ct, colorCurve, 0);
|
|
82
|
+
}
|
|
83
|
+
else if (hasColorVariance) {
|
|
84
|
+
const r0 = clamp01(colorStartR + (random() - 0.5) * 2 * config.colorStartVarianceR);
|
|
85
|
+
const g0 = clamp01(colorStartG + (random() - 0.5) * 2 * config.colorStartVarianceG);
|
|
86
|
+
const b0 = clamp01(colorStartB + (random() - 0.5) * 2 * config.colorStartVarianceB);
|
|
87
|
+
const r1 = clamp01(colorEndR + (random() - 0.5) * 2 * config.colorEndVarianceR);
|
|
88
|
+
const g1 = clamp01(colorEndG + (random() - 0.5) * 2 * config.colorEndVarianceG);
|
|
89
|
+
const b1 = clamp01(colorEndB + (random() - 0.5) * 2 * config.colorEndVarianceB);
|
|
90
|
+
state.colorBirth[ct] = r0;
|
|
91
|
+
state.colorBirth[ct + 1] = g0;
|
|
92
|
+
state.colorBirth[ct + 2] = b0;
|
|
93
|
+
state.colorDeath[ct] = r1;
|
|
94
|
+
state.colorDeath[ct + 1] = g1;
|
|
95
|
+
state.colorDeath[ct + 2] = b1;
|
|
96
|
+
data.colors[ct] = r0;
|
|
97
|
+
data.colors[ct + 1] = g0;
|
|
98
|
+
data.colors[ct + 2] = b0;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
data.colors[ct] = colorStartR;
|
|
102
|
+
data.colors[ct + 1] = colorStartG;
|
|
103
|
+
data.colors[ct + 2] = colorStartB;
|
|
104
|
+
}
|
|
105
|
+
data.ids[idx] = regionIdMin + (config.frameCount > 1 ? 0 : regionRange > 0 ? (random() * regionRange) | 0 : 0);
|
|
106
|
+
state.rotationSpeeds[idx] = hasRotSpeed ? config.rotationSpeedMin + random() * rotSpeedRange : 0;
|
|
107
|
+
}
|
|
108
|
+
data.particleCount = newCount;
|
|
109
|
+
return toSpawn;
|
|
110
|
+
}
|
|
111
|
+
function clamp01(v) {
|
|
112
|
+
return v < 0 ? 0 : v > 1 ? 1 : v;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=emitParticleBurst.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emitParticleBurst.js","sourceRoot":"","sources":["../src/emitParticleBurst.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export * from './applyParticleCollisions';
|
|
2
|
+
export * from './applyParticleForces';
|
|
3
|
+
export * from './curve';
|
|
4
|
+
export * from './emitParticleBurst';
|
|
5
|
+
export * from './particleEmitterConfig';
|
|
6
|
+
export * from './particleEmitterSignals';
|
|
7
|
+
export * from './particleEmitterState';
|
|
8
|
+
export * from './particleObjectsState';
|
|
9
|
+
export * from './prewarmParticleEmitter';
|
|
10
|
+
export * from './stepParticleEmitter';
|
|
11
|
+
export * from './updateParticleEmitter';
|
|
12
|
+
export * from './updateParticleObjects';
|
|
13
|
+
export * from './validateParticleEmitterConfig';
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,SAAS,CAAC;AACxB,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,iCAAiC,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export * from './applyParticleCollisions';
|
|
2
|
+
export * from './applyParticleForces';
|
|
3
|
+
export * from './curve';
|
|
4
|
+
export * from './emitParticleBurst';
|
|
5
|
+
export * from './particleEmitterConfig';
|
|
6
|
+
export * from './particleEmitterSignals';
|
|
7
|
+
export * from './particleEmitterState';
|
|
8
|
+
export * from './particleObjectsState';
|
|
9
|
+
export * from './prewarmParticleEmitter';
|
|
10
|
+
export * from './stepParticleEmitter';
|
|
11
|
+
export * from './updateParticleEmitter';
|
|
12
|
+
export * from './updateParticleObjects';
|
|
13
|
+
export * from './validateParticleEmitterConfig';
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,SAAS,CAAC;AACxB,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,iCAAiC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ParticleBlendMode, ParticleEmitterConfig, ParticleEmitterShape } from '@flighthq/types';
|
|
2
|
+
export type { ParticleBlendMode, ParticleEmitterConfig, ParticleEmitterShape };
|
|
3
|
+
export declare function createParticleEmitterConfig(config?: Partial<ParticleEmitterConfig>): ParticleEmitterConfig;
|
|
4
|
+
//# sourceMappingURL=particleEmitterConfig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"particleEmitterConfig.d.ts","sourceRoot":"","sources":["../src/particleEmitterConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEtG,YAAY,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,CAAC;AAE/E,wBAAgB,2BAA2B,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,GAAG,qBAAqB,CAmD1G"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export function createParticleEmitterConfig(config) {
|
|
2
|
+
return {
|
|
3
|
+
alphaCurve: config?.alphaCurve ?? null,
|
|
4
|
+
alphaEnd: config?.alphaEnd ?? 0,
|
|
5
|
+
alphaStart: config?.alphaStart ?? 1,
|
|
6
|
+
blendMode: config?.blendMode ?? null,
|
|
7
|
+
burstCount: config?.burstCount ?? 0,
|
|
8
|
+
burstInterval: config?.burstInterval ?? 0,
|
|
9
|
+
colorCurve: config?.colorCurve ?? null,
|
|
10
|
+
colorEndB: config?.colorEndB ?? 1,
|
|
11
|
+
colorEndG: config?.colorEndG ?? 1,
|
|
12
|
+
colorEndR: config?.colorEndR ?? 1,
|
|
13
|
+
colorEndVarianceB: config?.colorEndVarianceB ?? 0,
|
|
14
|
+
colorEndVarianceG: config?.colorEndVarianceG ?? 0,
|
|
15
|
+
colorEndVarianceR: config?.colorEndVarianceR ?? 0,
|
|
16
|
+
colorStartB: config?.colorStartB ?? 1,
|
|
17
|
+
colorStartG: config?.colorStartG ?? 1,
|
|
18
|
+
colorStartR: config?.colorStartR ?? 1,
|
|
19
|
+
colorStartVarianceB: config?.colorStartVarianceB ?? 0,
|
|
20
|
+
colorStartVarianceG: config?.colorStartVarianceG ?? 0,
|
|
21
|
+
colorStartVarianceR: config?.colorStartVarianceR ?? 0,
|
|
22
|
+
directionX: config?.directionX ?? 0,
|
|
23
|
+
directionY: config?.directionY ?? -1,
|
|
24
|
+
duration: config?.duration ?? 0,
|
|
25
|
+
emitterHeight: config?.emitterHeight ?? 0,
|
|
26
|
+
emitterRadius: config?.emitterRadius ?? 0,
|
|
27
|
+
emitterShape: config?.emitterShape ?? 'point',
|
|
28
|
+
emitterWidth: config?.emitterWidth ?? 0,
|
|
29
|
+
frameCount: config?.frameCount ?? 1,
|
|
30
|
+
frameRate: config?.frameRate ?? 12,
|
|
31
|
+
gravityX: config?.gravityX ?? 0,
|
|
32
|
+
gravityY: config?.gravityY ?? 0,
|
|
33
|
+
lifetimeMax: config?.lifetimeMax ?? 1,
|
|
34
|
+
lifetimeMin: config?.lifetimeMin ?? 0.5,
|
|
35
|
+
loop: config?.loop ?? true,
|
|
36
|
+
maxParticles: config?.maxParticles ?? 1000,
|
|
37
|
+
regionIdMax: config?.regionIdMax ?? 1,
|
|
38
|
+
regionIdMin: config?.regionIdMin ?? 0,
|
|
39
|
+
rotationSpeedMax: config?.rotationSpeedMax ?? 0,
|
|
40
|
+
rotationSpeedMin: config?.rotationSpeedMin ?? 0,
|
|
41
|
+
scaleCurve: config?.scaleCurve ?? null,
|
|
42
|
+
scaleEnd: config?.scaleEnd ?? 1,
|
|
43
|
+
scaleMax: config?.scaleMax ?? 1,
|
|
44
|
+
scaleMin: config?.scaleMin ?? 1,
|
|
45
|
+
spawnRate: config?.spawnRate ?? 10,
|
|
46
|
+
speedMax: config?.speedMax ?? 100,
|
|
47
|
+
speedMin: config?.speedMin ?? 50,
|
|
48
|
+
spread: config?.spread ?? Math.PI,
|
|
49
|
+
velocityInheritance: config?.velocityInheritance ?? 0,
|
|
50
|
+
worldSpace: config?.worldSpace ?? false,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=particleEmitterConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"particleEmitterConfig.js","sourceRoot":"","sources":["../src/particleEmitterConfig.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ParticleEmitterSignals } from '@flighthq/types';
|
|
2
|
+
export type { ParticleEmitterSignals };
|
|
3
|
+
/** Create a fresh {@link ParticleEmitterSignals} group. Called by
|
|
4
|
+
* {@link enableParticleEmitterSignals} on first use; exported for unit testing. */
|
|
5
|
+
export declare function createParticleEmitterSignals(): ParticleEmitterSignals;
|
|
6
|
+
/** Opt-in signals for a typed-array particle emitter.
|
|
7
|
+
*
|
|
8
|
+
* Returns the {@link ParticleEmitterSignals} group attached to `state`, creating it on
|
|
9
|
+
* first call. The cost of signals is zero until this function is called — keeping it
|
|
10
|
+
* opt-in honors the `enable*` convention and avoids allocation for emitters that do not
|
|
11
|
+
* need loose multi-listener notification.
|
|
12
|
+
*
|
|
13
|
+
* Connect to the returned signals; they are fired by the simulation functions
|
|
14
|
+
* (`updateParticleEmitter`, `stepParticleEmitter`) when the state carries signals.
|
|
15
|
+
* Use `getParticleEmitterSignals` to read without creating. */
|
|
16
|
+
export declare function enableParticleEmitterSignals(state: object): ParticleEmitterSignals;
|
|
17
|
+
/** Return the {@link ParticleEmitterSignals} attached to `state`, or `null` if signals
|
|
18
|
+
* have not been enabled for this emitter. */
|
|
19
|
+
export declare function getParticleEmitterSignals(state: object): ParticleEmitterSignals | null;
|
|
20
|
+
//# sourceMappingURL=particleEmitterSignals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"particleEmitterSignals.d.ts","sourceRoot":"","sources":["../src/particleEmitterSignals.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAE9D,YAAY,EAAE,sBAAsB,EAAE,CAAC;AAEvC;oFACoF;AACpF,wBAAgB,4BAA4B,IAAI,sBAAsB,CAMrE;AAED;;;;;;;;;gEASgE;AAChE,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,sBAAsB,CAGlF;AAED;8CAC8C;AAC9C,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,sBAAsB,GAAG,IAAI,CAEtF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { createSignal } from '@flighthq/signals';
|
|
2
|
+
/** Create a fresh {@link ParticleEmitterSignals} group. Called by
|
|
3
|
+
* {@link enableParticleEmitterSignals} on first use; exported for unit testing. */
|
|
4
|
+
export function createParticleEmitterSignals() {
|
|
5
|
+
return {
|
|
6
|
+
onEmitterComplete: createSignal(),
|
|
7
|
+
onParticleDeath: createSignal(),
|
|
8
|
+
onParticleSpawn: createSignal(),
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/** Opt-in signals for a typed-array particle emitter.
|
|
12
|
+
*
|
|
13
|
+
* Returns the {@link ParticleEmitterSignals} group attached to `state`, creating it on
|
|
14
|
+
* first call. The cost of signals is zero until this function is called — keeping it
|
|
15
|
+
* opt-in honors the `enable*` convention and avoids allocation for emitters that do not
|
|
16
|
+
* need loose multi-listener notification.
|
|
17
|
+
*
|
|
18
|
+
* Connect to the returned signals; they are fired by the simulation functions
|
|
19
|
+
* (`updateParticleEmitter`, `stepParticleEmitter`) when the state carries signals.
|
|
20
|
+
* Use `getParticleEmitterSignals` to read without creating. */
|
|
21
|
+
export function enableParticleEmitterSignals(state) {
|
|
22
|
+
const s = state;
|
|
23
|
+
return (s[signalsSlot] ??= createParticleEmitterSignals());
|
|
24
|
+
}
|
|
25
|
+
/** Return the {@link ParticleEmitterSignals} attached to `state`, or `null` if signals
|
|
26
|
+
* have not been enabled for this emitter. */
|
|
27
|
+
export function getParticleEmitterSignals(state) {
|
|
28
|
+
return state[signalsSlot] ?? null;
|
|
29
|
+
}
|
|
30
|
+
// Per-emitter state slot for signal storage. Keyed by a module-level symbol so
|
|
31
|
+
// there is no collision with other packages that might attach state to the same object.
|
|
32
|
+
const signalsSlot = Symbol('particleEmitterSignals');
|
|
33
|
+
//# sourceMappingURL=particleEmitterSignals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"particleEmitterSignals.js","sourceRoot":"","sources":["../src/particleEmitterSignals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAKjD;oFACoF;AACpF,MAAM,UAAU,4BAA4B;IAC1C,OAAO;QACL,iBAAiB,EAAE,YAAY,EAAE;QACjC,eAAe,EAAE,YAAY,EAAE;QAC/B,eAAe,EAAE,YAAY,EAAE;KAChC,CAAC;AACJ,CAAC;AAED;;;;;;;;;gEASgE;AAChE,MAAM,UAAU,4BAA4B,CAAC,KAAa;IACxD,MAAM,CAAC,GAAG,KAA2D,CAAC;IACtE,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,4BAA4B,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED;8CAC8C;AAC9C,MAAM,UAAU,yBAAyB,CAAC,KAAa;IACrD,OAAQ,KAA4D,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC;AAC5F,CAAC;AAED,+EAA+E;AAC/E,wFAAwF;AACxF,MAAM,WAAW,GAAG,MAAM,CAAC,wBAAwB,CAAC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ParticleEmitterState, RandomSource } from '@flighthq/types';
|
|
2
|
+
export declare function createParticleEmitterState(random?: RandomSource): ParticleEmitterState;
|
|
3
|
+
/** Grow the per-particle state arrays to hold at least `capacity` particles.
|
|
4
|
+
* No-op when already large enough. `colorBirth`/`colorDeath` are only grown when
|
|
5
|
+
* the emitter uses color variance (they stay empty otherwise). */
|
|
6
|
+
export declare function ensureParticleEmitterStateCapacity(state: ParticleEmitterState, capacity: number, hasColorVariance: boolean): void;
|
|
7
|
+
//# sourceMappingURL=particleEmitterState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"particleEmitterState.d.ts","sourceRoot":"","sources":["../src/particleEmitterState.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE1E,wBAAgB,0BAA0B,CAAC,MAAM,GAAE,YAA0B,GAAG,oBAAoB,CAenG;AAED;;mEAEmE;AACnE,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,oBAAoB,EAC3B,QAAQ,EAAE,MAAM,EAChB,gBAAgB,EAAE,OAAO,GACxB,IAAI,CAgBN"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { reserveFloat32Array } from '@flighthq/geometry';
|
|
2
|
+
export function createParticleEmitterState(random = Math.random) {
|
|
3
|
+
return {
|
|
4
|
+
burstTimer: 0,
|
|
5
|
+
colorBirth: new Float32Array(),
|
|
6
|
+
colorDeath: new Float32Array(),
|
|
7
|
+
emitterAge: 0,
|
|
8
|
+
lifetimes: new Float32Array(),
|
|
9
|
+
prevX: NaN,
|
|
10
|
+
prevY: NaN,
|
|
11
|
+
random,
|
|
12
|
+
rotationSpeeds: new Float32Array(),
|
|
13
|
+
scales: new Float32Array(),
|
|
14
|
+
spawnAccumulator: 0,
|
|
15
|
+
velocities: new Float32Array(),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/** Grow the per-particle state arrays to hold at least `capacity` particles.
|
|
19
|
+
* No-op when already large enough. `colorBirth`/`colorDeath` are only grown when
|
|
20
|
+
* the emitter uses color variance (they stay empty otherwise). */
|
|
21
|
+
export function ensureParticleEmitterStateCapacity(state, capacity, hasColorVariance) {
|
|
22
|
+
if (state.lifetimes.length >= capacity * 2) {
|
|
23
|
+
if (hasColorVariance && state.colorBirth.length < capacity * 3) {
|
|
24
|
+
state.colorBirth = reserveFloat32Array(state.colorBirth, capacity * 3);
|
|
25
|
+
state.colorDeath = reserveFloat32Array(state.colorDeath, capacity * 3);
|
|
26
|
+
}
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
state.lifetimes = reserveFloat32Array(state.lifetimes, capacity * 2);
|
|
30
|
+
state.velocities = reserveFloat32Array(state.velocities, capacity * 2);
|
|
31
|
+
state.scales = reserveFloat32Array(state.scales, capacity);
|
|
32
|
+
state.rotationSpeeds = reserveFloat32Array(state.rotationSpeeds, capacity);
|
|
33
|
+
if (hasColorVariance) {
|
|
34
|
+
state.colorBirth = reserveFloat32Array(state.colorBirth, capacity * 3);
|
|
35
|
+
state.colorDeath = reserveFloat32Array(state.colorDeath, capacity * 3);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=particleEmitterState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"particleEmitterState.js","sourceRoot":"","sources":["../src/particleEmitterState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAGzD,MAAM,UAAU,0BAA0B,CAAC,SAAuB,IAAI,CAAC,MAAM;IAC3E,OAAO;QACL,UAAU,EAAE,CAAC;QACb,UAAU,EAAE,IAAI,YAAY,EAAE;QAC9B,UAAU,EAAE,IAAI,YAAY,EAAE;QAC9B,UAAU,EAAE,CAAC;QACb,SAAS,EAAE,IAAI,YAAY,EAAE;QAC7B,KAAK,EAAE,GAAG;QACV,KAAK,EAAE,GAAG;QACV,MAAM;QACN,cAAc,EAAE,IAAI,YAAY,EAAE;QAClC,MAAM,EAAE,IAAI,YAAY,EAAE;QAC1B,gBAAgB,EAAE,CAAC;QACnB,UAAU,EAAE,IAAI,YAAY,EAAE;KAC/B,CAAC;AACJ,CAAC;AAED;;mEAEmE;AACnE,MAAM,UAAU,kCAAkC,CAChD,KAA2B,EAC3B,QAAgB,EAChB,gBAAyB;IAEzB,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QAC3C,IAAI,gBAAgB,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,GAAG,QAAQ,GAAG,CAAC,EAAE,CAAC;YAC/D,KAAK,CAAC,UAAU,GAAG,mBAAmB,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC;YACvE,KAAK,CAAC,UAAU,GAAG,mBAAmB,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC;QACzE,CAAC;QACD,OAAO;IACT,CAAC;IACD,KAAK,CAAC,SAAS,GAAG,mBAAmB,CAAC,KAAK,CAAC,SAAS,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC;IACrE,KAAK,CAAC,UAAU,GAAG,mBAAmB,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC;IACvE,KAAK,CAAC,MAAM,GAAG,mBAAmB,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC3D,KAAK,CAAC,cAAc,GAAG,mBAAmB,CAAC,KAAK,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;IAC3E,IAAI,gBAAgB,EAAE,CAAC;QACrB,KAAK,CAAC,UAAU,GAAG,mBAAmB,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC;QACvE,KAAK,CAAC,UAAU,GAAG,mBAAmB,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC;IACzE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ParticleObjectsState, RandomSource } from '@flighthq/types';
|
|
2
|
+
export declare function createParticleObjectsState(capacity: number, random?: RandomSource): ParticleObjectsState;
|
|
3
|
+
export declare function ensureParticleObjectsStateCapacity(state: ParticleObjectsState, capacity: number): void;
|
|
4
|
+
//# sourceMappingURL=particleObjectsState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"particleObjectsState.d.ts","sourceRoot":"","sources":["../src/particleObjectsState.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE1E,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAE,YAA0B,GAAG,oBAAoB,CAarH;AAED,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAMtG"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { reserveFloat32Array } from '@flighthq/geometry';
|
|
2
|
+
export function createParticleObjectsState(capacity, random = Math.random) {
|
|
3
|
+
return {
|
|
4
|
+
burstTimer: 0,
|
|
5
|
+
emitterAge: 0,
|
|
6
|
+
lifetimes: new Float32Array(capacity * 2),
|
|
7
|
+
prevX: NaN,
|
|
8
|
+
prevY: NaN,
|
|
9
|
+
random,
|
|
10
|
+
rotationSpeeds: new Float32Array(capacity),
|
|
11
|
+
scales: new Float32Array(capacity),
|
|
12
|
+
spawnAccumulator: 0,
|
|
13
|
+
velocities: new Float32Array(capacity * 2),
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export function ensureParticleObjectsStateCapacity(state, capacity) {
|
|
17
|
+
if (state.lifetimes.length >= capacity * 2)
|
|
18
|
+
return;
|
|
19
|
+
state.lifetimes = reserveFloat32Array(state.lifetimes, capacity * 2);
|
|
20
|
+
state.velocities = reserveFloat32Array(state.velocities, capacity * 2);
|
|
21
|
+
state.scales = reserveFloat32Array(state.scales, capacity);
|
|
22
|
+
state.rotationSpeeds = reserveFloat32Array(state.rotationSpeeds, capacity);
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=particleObjectsState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"particleObjectsState.js","sourceRoot":"","sources":["../src/particleObjectsState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAGzD,MAAM,UAAU,0BAA0B,CAAC,QAAgB,EAAE,SAAuB,IAAI,CAAC,MAAM;IAC7F,OAAO;QACL,UAAU,EAAE,CAAC;QACb,UAAU,EAAE,CAAC;QACb,SAAS,EAAE,IAAI,YAAY,CAAC,QAAQ,GAAG,CAAC,CAAC;QACzC,KAAK,EAAE,GAAG;QACV,KAAK,EAAE,GAAG;QACV,MAAM;QACN,cAAc,EAAE,IAAI,YAAY,CAAC,QAAQ,CAAC;QAC1C,MAAM,EAAE,IAAI,YAAY,CAAC,QAAQ,CAAC;QAClC,gBAAgB,EAAE,CAAC;QACnB,UAAU,EAAE,IAAI,YAAY,CAAC,QAAQ,GAAG,CAAC,CAAC;KAC3C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kCAAkC,CAAC,KAA2B,EAAE,QAAgB;IAC9F,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,IAAI,QAAQ,GAAG,CAAC;QAAE,OAAO;IACnD,KAAK,CAAC,SAAS,GAAG,mBAAmB,CAAC,KAAK,CAAC,SAAS,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC;IACrE,KAAK,CAAC,UAAU,GAAG,mBAAmB,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC;IACvE,KAAK,CAAC,MAAM,GAAG,mBAAmB,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC3D,KAAK,CAAC,cAAc,GAAG,mBAAmB,CAAC,KAAK,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;AAC7E,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ParticleEmitter } from '@flighthq/types';
|
|
2
|
+
import type { ParticleEmitterConfig, ParticleEmitterState } from '@flighthq/types';
|
|
3
|
+
import type { ParticleEmitterCallbacks, WorldTransform2D } from './updateParticleEmitter';
|
|
4
|
+
export declare function prewarmParticleEmitter(emitter: ParticleEmitter, state: ParticleEmitterState, config: Readonly<ParticleEmitterConfig>, duration: number, stepDeltaTime?: number, callbacks?: ParticleEmitterCallbacks, worldTransform?: Readonly<WorldTransform2D>): void;
|
|
5
|
+
//# sourceMappingURL=prewarmParticleEmitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prewarmParticleEmitter.d.ts","sourceRoot":"","sources":["../src/prewarmParticleEmitter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEnF,OAAO,KAAK,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAG1F,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,oBAAoB,EAC3B,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC,EACvC,QAAQ,EAAE,MAAM,EAChB,aAAa,SAAS,EACtB,SAAS,CAAC,EAAE,wBAAwB,EACpC,cAAc,CAAC,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAC1C,IAAI,CAUN"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { updateParticleEmitter } from './updateParticleEmitter';
|
|
2
|
+
export function prewarmParticleEmitter(emitter, state, config, duration, stepDeltaTime = 1 / 60, callbacks, worldTransform) {
|
|
3
|
+
// A non-positive step would never advance `elapsed`, spinning forever; fall back
|
|
4
|
+
// to a single step covering the whole duration instead of hanging.
|
|
5
|
+
const step = stepDeltaTime > 0 ? stepDeltaTime : duration;
|
|
6
|
+
let elapsed = 0;
|
|
7
|
+
while (elapsed < duration) {
|
|
8
|
+
const deltaTime = Math.min(step, duration - elapsed);
|
|
9
|
+
updateParticleEmitter(emitter, state, config, deltaTime, callbacks, worldTransform);
|
|
10
|
+
elapsed += deltaTime;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=prewarmParticleEmitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prewarmParticleEmitter.js","sourceRoot":"","sources":["../src/prewarmParticleEmitter.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,UAAU,sBAAsB,CACpC,OAAwB,EACxB,KAA2B,EAC3B,MAAuC,EACvC,QAAgB,EAChB,aAAa,GAAG,CAAC,GAAG,EAAE,EACtB,SAAoC,EACpC,cAA2C;IAE3C,iFAAiF;IACjF,mEAAmE;IACnE,MAAM,IAAI,GAAG,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC1D,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,OAAO,OAAO,GAAG,QAAQ,EAAE,CAAC;QAC1B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,CAAC;QACrD,qBAAqB,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;QACpF,OAAO,IAAI,SAAS,CAAC;IACvB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ParticleCollider, ParticleEmitter, ParticleEmitterCallbacks, ParticleEmitterConfig, ParticleEmitterState, ParticleForce, ParticleObject, ParticleObjectsState, ParticleObjectsUpdateOptions, WorldTransform2D } from '@flighthq/types';
|
|
2
|
+
/**
|
|
3
|
+
* Convenience wrapper for the SoA typed-array emitter that folds the canonical three-step update
|
|
4
|
+
* sequence — `applyParticleForces` → `updateParticleEmitter` → `applyParticleCollisions` — into a
|
|
5
|
+
* single call.
|
|
6
|
+
*
|
|
7
|
+
* The three primitives remain exported for advanced use (custom interleaving, per-force-group
|
|
8
|
+
* timing, etc.). Use this function for the common case where all forces and colliders apply each
|
|
9
|
+
* frame in the documented order.
|
|
10
|
+
*
|
|
11
|
+
* @param emitter - The SoA particle emitter node.
|
|
12
|
+
* @param state - Mutable per-emitter simulation state.
|
|
13
|
+
* @param config - Immutable emitter configuration.
|
|
14
|
+
* @param deltaTime - Elapsed time in seconds since the last step.
|
|
15
|
+
* @param forces - Optional force fields to apply before integration (e.g. wind, attractor).
|
|
16
|
+
* @param colliders - Optional colliders to resolve after integration (e.g. plane, circle).
|
|
17
|
+
* @param callbacks - Optional spawn/death callbacks.
|
|
18
|
+
* @param worldTransform - World-space transform for world-space emitters.
|
|
19
|
+
*/
|
|
20
|
+
export declare function stepParticleEmitter(emitter: ParticleEmitter, state: ParticleEmitterState, config: Readonly<ParticleEmitterConfig>, deltaTime: number, forces?: ReadonlyArray<ParticleForce>, colliders?: ReadonlyArray<ParticleCollider>, callbacks?: ParticleEmitterCallbacks, worldTransform?: Readonly<WorldTransform2D>): void;
|
|
21
|
+
/**
|
|
22
|
+
* Convenience wrapper for the object-pool path that folds the canonical three-step update sequence
|
|
23
|
+
* — `applyParticleObjectForces` → `updateParticleObjects` → `applyParticleObjectCollisions` — into
|
|
24
|
+
* a single call.
|
|
25
|
+
*
|
|
26
|
+
* The three primitives remain exported for advanced use. Use this function for the common case
|
|
27
|
+
* where all forces and colliders apply each frame in the documented order.
|
|
28
|
+
*
|
|
29
|
+
* @param objects - The particle object pool (one display object per slot).
|
|
30
|
+
* @param state - Mutable per-emitter simulation state.
|
|
31
|
+
* @param config - Immutable emitter configuration.
|
|
32
|
+
* @param deltaTime - Elapsed time in seconds since the last step.
|
|
33
|
+
* @param forces - Optional force fields to apply before integration.
|
|
34
|
+
* @param colliders - Optional colliders to resolve after integration.
|
|
35
|
+
* @param updateOptions - Optional emitter position, callbacks, and other per-frame options.
|
|
36
|
+
*/
|
|
37
|
+
export declare function stepParticleObjects(objects: readonly ParticleObject[], state: ParticleObjectsState, config: Readonly<ParticleEmitterConfig>, deltaTime: number, forces?: ReadonlyArray<ParticleForce>, colliders?: ReadonlyArray<ParticleCollider>, updateOptions?: ParticleObjectsUpdateOptions): void;
|
|
38
|
+
//# sourceMappingURL=stepParticleEmitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stepParticleEmitter.d.ts","sourceRoot":"","sources":["../src/stepParticleEmitter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,4BAA4B,EAC5B,gBAAgB,EACjB,MAAM,iBAAiB,CAAC;AAOzB;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,oBAAoB,EAC3B,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC,EACvC,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,aAAa,CAAC,aAAa,CAAC,EACrC,SAAS,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,EAC3C,SAAS,CAAC,EAAE,wBAAwB,EACpC,cAAc,CAAC,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAC1C,IAAI,CAQN;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,SAAS,cAAc,EAAE,EAClC,KAAK,EAAE,oBAAoB,EAC3B,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC,EACvC,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,aAAa,CAAC,aAAa,CAAC,EACrC,SAAS,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,EAC3C,aAAa,CAAC,EAAE,4BAA4B,GAC3C,IAAI,CAQN"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { applyParticleCollisions, applyParticleObjectCollisions } from './applyParticleCollisions';
|
|
2
|
+
import { applyParticleForces, applyParticleObjectForces } from './applyParticleForces';
|
|
3
|
+
import { updateParticleEmitter } from './updateParticleEmitter';
|
|
4
|
+
import { updateParticleObjects } from './updateParticleObjects';
|
|
5
|
+
/**
|
|
6
|
+
* Convenience wrapper for the SoA typed-array emitter that folds the canonical three-step update
|
|
7
|
+
* sequence — `applyParticleForces` → `updateParticleEmitter` → `applyParticleCollisions` — into a
|
|
8
|
+
* single call.
|
|
9
|
+
*
|
|
10
|
+
* The three primitives remain exported for advanced use (custom interleaving, per-force-group
|
|
11
|
+
* timing, etc.). Use this function for the common case where all forces and colliders apply each
|
|
12
|
+
* frame in the documented order.
|
|
13
|
+
*
|
|
14
|
+
* @param emitter - The SoA particle emitter node.
|
|
15
|
+
* @param state - Mutable per-emitter simulation state.
|
|
16
|
+
* @param config - Immutable emitter configuration.
|
|
17
|
+
* @param deltaTime - Elapsed time in seconds since the last step.
|
|
18
|
+
* @param forces - Optional force fields to apply before integration (e.g. wind, attractor).
|
|
19
|
+
* @param colliders - Optional colliders to resolve after integration (e.g. plane, circle).
|
|
20
|
+
* @param callbacks - Optional spawn/death callbacks.
|
|
21
|
+
* @param worldTransform - World-space transform for world-space emitters.
|
|
22
|
+
*/
|
|
23
|
+
export function stepParticleEmitter(emitter, state, config, deltaTime, forces, colliders, callbacks, worldTransform) {
|
|
24
|
+
if (forces != null && forces.length > 0) {
|
|
25
|
+
applyParticleForces(emitter, state, forces, deltaTime);
|
|
26
|
+
}
|
|
27
|
+
updateParticleEmitter(emitter, state, config, deltaTime, callbacks, worldTransform);
|
|
28
|
+
if (colliders != null && colliders.length > 0) {
|
|
29
|
+
applyParticleCollisions(emitter, state, colliders);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Convenience wrapper for the object-pool path that folds the canonical three-step update sequence
|
|
34
|
+
* — `applyParticleObjectForces` → `updateParticleObjects` → `applyParticleObjectCollisions` — into
|
|
35
|
+
* a single call.
|
|
36
|
+
*
|
|
37
|
+
* The three primitives remain exported for advanced use. Use this function for the common case
|
|
38
|
+
* where all forces and colliders apply each frame in the documented order.
|
|
39
|
+
*
|
|
40
|
+
* @param objects - The particle object pool (one display object per slot).
|
|
41
|
+
* @param state - Mutable per-emitter simulation state.
|
|
42
|
+
* @param config - Immutable emitter configuration.
|
|
43
|
+
* @param deltaTime - Elapsed time in seconds since the last step.
|
|
44
|
+
* @param forces - Optional force fields to apply before integration.
|
|
45
|
+
* @param colliders - Optional colliders to resolve after integration.
|
|
46
|
+
* @param updateOptions - Optional emitter position, callbacks, and other per-frame options.
|
|
47
|
+
*/
|
|
48
|
+
export function stepParticleObjects(objects, state, config, deltaTime, forces, colliders, updateOptions) {
|
|
49
|
+
if (forces != null && forces.length > 0) {
|
|
50
|
+
applyParticleObjectForces(objects, state, forces, deltaTime);
|
|
51
|
+
}
|
|
52
|
+
updateParticleObjects(objects, state, config, deltaTime, updateOptions);
|
|
53
|
+
if (colliders != null && colliders.length > 0) {
|
|
54
|
+
applyParticleObjectCollisions(objects, state, colliders);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=stepParticleEmitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stepParticleEmitter.js","sourceRoot":"","sources":["../src/stepParticleEmitter.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,uBAAuB,EAAE,6BAA6B,EAAE,MAAM,2BAA2B,CAAC;AACnG,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACvF,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAAwB,EACxB,KAA2B,EAC3B,MAAuC,EACvC,SAAiB,EACjB,MAAqC,EACrC,SAA2C,EAC3C,SAAoC,EACpC,cAA2C;IAE3C,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxC,mBAAmB,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IACzD,CAAC;IACD,qBAAqB,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;IACpF,IAAI,SAAS,IAAI,IAAI,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,uBAAuB,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IACrD,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAAkC,EAClC,KAA2B,EAC3B,MAAuC,EACvC,SAAiB,EACjB,MAAqC,EACrC,SAA2C,EAC3C,aAA4C;IAE5C,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxC,yBAAyB,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IAC/D,CAAC;IACD,qBAAqB,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;IACxE,IAAI,SAAS,IAAI,IAAI,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,6BAA6B,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ParticleEmitter, ParticleEmitterCallbacks, ParticleEmitterConfig, ParticleEmitterState, WorldTransform2D } from '@flighthq/types';
|
|
2
|
+
export type { ParticleEmitterCallbacks, WorldTransform2D };
|
|
3
|
+
/** True once a finite, non-looping emitter has finished emitting AND all of its
|
|
4
|
+
* particles have died — i.e. a one-shot effect that is safe to recycle/remove.
|
|
5
|
+
* Always false for infinite or looping emitters (they never finish). */
|
|
6
|
+
export declare function isParticleEmitterComplete(emitter: ParticleEmitter, state: Readonly<ParticleEmitterState>, config: Readonly<ParticleEmitterConfig>): boolean;
|
|
7
|
+
export declare function updateParticleEmitter(emitter: ParticleEmitter, state: ParticleEmitterState, config: Readonly<ParticleEmitterConfig>, deltaTime: number, callbacks?: ParticleEmitterCallbacks, worldTransform?: Readonly<WorldTransform2D>): void;
|
|
8
|
+
//# sourceMappingURL=updateParticleEmitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"updateParticleEmitter.d.ts","sourceRoot":"","sources":["../src/updateParticleEmitter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EACjB,MAAM,iBAAiB,CAAC;AAMzB,YAAY,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,CAAC;AAK3D;;yEAEyE;AACzE,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,QAAQ,CAAC,oBAAoB,CAAC,EACrC,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GACtC,OAAO,CAGT;AAQD,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,oBAAoB,EAC3B,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC,EACvC,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,wBAAwB,EACpC,cAAc,CAAC,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAC1C,IAAI,CAgUN"}
|