import * as THREE from 'three'; import type { ScalarCurve, ColorCurve } from './curves.js'; import type { FrameContext } from '../types.js'; /** Spawn volume for particles: `point`, `sphere` (optionally shell-only), `box`, `cone` (angle in radians), or `disc`. */ export type EmitterShape = { kind: 'point'; } | { kind: 'sphere'; radius: number; shell?: boolean; } | { kind: 'box'; size: readonly [number, number, number]; } | { kind: 'cone'; angle: number; radius?: number; } | { kind: 'disc'; radius: number; }; /** Options for {@link createEmitter} and {@link createGpuEmitter}: capacity, emission rate/bursts, lifetime, shape, motion, and appearance curves. */ export interface EmitterOptions { /** Max simultaneously-live particles. Buffers are sized once at this count. */ capacity: number; /** Continuous emission in particles/second. Default: capacity / mean lifetime. */ rate?: number; /** One-shot emissions at sim-time offsets (seconds since emitter creation). */ bursts?: ReadonlyArray<{ time: number; count: number; }>; lifetime?: readonly [number, number]; shape?: EmitterShape; /** Initial speed range along the shape's emission direction. */ speed?: readonly [number, number]; gravity?: readonly [number, number, number]; damping?: number; /** World-unit base size; the size curve multiplies this. */ size?: number; sizeCurve?: ScalarCurve; color?: ColorCurve; alphaCurve?: ScalarCurve; /** Angular velocity range (rad/s) for sprite spin. */ rotation?: readonly [number, number]; texture?: THREE.Texture | null; blending?: 'additive' | 'normal'; seed?: number; } /** A live particle system. Call `tick(ctx)` each frame; `dispose()` frees the GPU buffers. */ export interface Emitter { object: THREE.Object3D; tick(ctx: FrameContext): void; /** Spawn `count` particles immediately (capacity permitting). */ burst(count: number): void; setRate(rate: number): void; dispose(): void; } /** One sampled spawn: position (`px..pz`) and emission direction (`dx..dz`). Reused as scratch — copy to keep. */ export interface SpawnSample { px: number; py: number; pz: number; dx: number; dy: number; dz: number; } /** Sample a spawn position + emission direction from an emitter shape. */ export declare function sampleShape(shape: EmitterShape, r: () => number, out: SpawnSample): void; /** * CPU-simulated billboard particle emitter: a fixed-capacity `Points` cloud * with per-particle lifetime, seeded deterministic spawns, gravity/damping * integration, and size/color/alpha curves evaluated in the shader. * * @param options - Capacity (buffers size once), rate/bursts, lifetime range, * spawn shape, motion, and appearance curves. * @returns An {@link Emitter}; add `object` to the scene and `tick` it. * @remarks Simulation is O(capacity) per frame on the CPU with zero * allocation; rendering is one draw call. Same seed → same particle stream. * @see {@link createGpuEmitter} for a GPGPU variant at higher capacities. * @example * const smoke = createEmitter({ capacity: 500, shape: { kind: 'cone', angle: 0.4 } }) * scene.add(smoke.object) * loop.onFrame(ctx => smoke.tick(ctx)) */ export declare function createEmitter({ capacity, rate, bursts, lifetime, shape, speed, gravity, damping, size, sizeCurve, color, alphaCurve, rotation, texture, blending, seed, }: EmitterOptions): Emitter; //# sourceMappingURL=emitter.d.ts.map