Allocates every channel for capacity particles. This is the only
allocating operation on the type.
ReadonlyagesSeconds each particle has lived, stride 1.
ReadonlycapacityMaximum simultaneously live particles. Fixed at construction — §36's
maxParticles is a budget, and growing a pool mid-frame would allocate on
the hot path (§7b).
ReadonlycolorsColour ramp endpoints, stride 8 (r₀ g₀ b₀ a₀ r₁ g₁ b₁ a₁).
ReadonlylifetimesSeconds each particle may live, stride 1.
ReadonlypositionsPositions, stride 3 (x, y, z), capacity entries. Slots >= aliveCount are stale.
ReadonlysizesSize ramp endpoints, stride 2 (size₀, size₁).
ReadonlyvelocitiesVelocities in units/s, stride 3 (x, y, z).
Live particle count. The live slots are exactly [0, aliveCount).
Drops every particle. Channel arrays keep their contents — the slots are simply no longer live, and ParticlePool.spawn zeroes anything it hands back — so this is O(1).
Seconds the live particle index has lived.
Writes the current colour of the live particle index into out — the
ramp evaluated component-wise at ParticlePool.getNormalizedAge, in
the same start + (end − start) · t form as ParticlePool.getSize.
Straight (non-premultiplied) RGBA, interpolated in whatever space the author wrote the endpoints in; §60a colour management is the renderer's business, not the pool's.
Size at age = lifetime for the live particle index.
Seconds the live particle index may live.
age / lifetime, clamped to [0, 1] — the parameter every over-lifetime
ramp is evaluated at.
A non-positive lifetime reports 1 (fully aged) rather than Infinity or
NaN: a zero-lifetime particle is one the next expiry pass removes, and a
ramp evaluated at its end is the honest thing to draw in the meantime.
Current size of the live particle index: the ramp evaluated at
ParticlePool.getNormalizedAge, as start + (end − start) · t.
That form (rather than (1 − t)·start + t·end) is exact at t = 0 and
t = 1 for every pair of endpoints, which is what the tests pin.
Size at age 0 for the live particle index.
Removes the particle at index by moving the last live particle into its
slot (swap-remove) and decrementing ParticlePool.aliveCount.
Killing the last live particle is the degenerate case: the "move" is a self-copy, skipped. See the module note on what this does and does not cost.
Sets the age (seconds) of the live particle index.
Sets both colour ramp endpoints of the live particle index, as straight RGBA.
Sets the lifetime (seconds) of the live particle index.
Sets the position of the live particle index.
Sets the size ramp endpoints of the live particle index.
Sets the velocity (units/s) of the live particle index.
Claims the next free slot and returns its index, or -1 when the pool is
full — the caller decides whether that is a dropped spawn (the emitter
counts them) or an error.
The returned slot is zeroed in every channel, so a recycled slot never
leaks its previous occupant's state into a caller that forgets to write a
channel. Note that a zeroed lifetime means
ParticlePool.getNormalizedAge reports 1 until a real lifetime is
written.
Fixed-capacity structure-of-arrays particle storage. See the module documentation for the layout, the allocation policy, and the swap-remove determinism statement.