import { Vec3 } from '@quake2ts/shared'; import { IndexBuffer, VertexArray, VertexBuffer } from './resources.js'; import { ShaderProgram } from './shaderProgram.js'; import { RandomGenerator } from '@quake2ts/shared'; export type ParticleBlendMode = 'alpha' | 'additive'; export interface ParticleSpawnOptions { readonly position: Vec3; readonly velocity?: Vec3; readonly color?: readonly [number, number, number, number]; readonly size?: number; readonly lifetime: number; readonly gravity?: number; readonly damping?: number; readonly bounce?: number; readonly blendMode?: ParticleBlendMode; /** * When true, fades alpha from 1 to 0 across the lifetime instead of remaining constant. */ readonly fade?: boolean; /** * Texture index to use for the particle. If undefined, uses the default (0). */ readonly textureIndex?: number; } export interface ParticleSimulationOptions { readonly floorZ?: number; } interface ParticleMeshBatch { readonly blendMode: ParticleBlendMode; readonly start: number; readonly count: number; } export interface ParticleMesh { readonly vertices: Float32Array; readonly indices: Uint16Array; readonly batches: readonly ParticleMeshBatch[]; } export declare class ParticleSystem { readonly maxParticles: number; readonly rng: RandomGenerator; private readonly alive; private readonly positionX; private readonly positionY; private readonly positionZ; private readonly velocityX; private readonly velocityY; private readonly velocityZ; private readonly colorR; private readonly colorG; private readonly colorB; private readonly colorA; private readonly size; private readonly lifetime; private readonly remaining; private readonly gravity; private readonly damping; private readonly bounce; private readonly fade; private readonly blendMode; private readonly textureIndex; constructor(maxParticles: number, rng: RandomGenerator); spawn(options: ParticleSpawnOptions): number | null; update(dt: number, options?: ParticleSimulationOptions): void; killAll(): void; aliveCount(): number; getState(index: number): { readonly alive: boolean; readonly position: Vec3; readonly velocity: Vec3; readonly remaining: number; readonly color: readonly [number, number, number, number]; readonly size: number; readonly blendMode: ParticleBlendMode; readonly textureIndex: number; }; buildMesh(viewRight: Vec3, viewUp: Vec3): ParticleMesh; private findFreeSlot; } export declare const PARTICLE_VERTEX_SHADER = "#version 300 es\nprecision highp float;\n\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec2 a_uv;\nlayout(location = 2) in vec4 a_color;\n\nuniform mat4 u_viewProjection;\n\nout vec2 v_uv;\nout vec4 v_color;\n\nvoid main() {\n v_uv = a_uv;\n v_color = a_color;\n gl_Position = u_viewProjection * vec4(a_position, 1.0);\n}"; export declare const PARTICLE_FRAGMENT_SHADER = "#version 300 es\nprecision highp float;\n\nin vec2 v_uv;\nin vec4 v_color;\n\nout vec4 o_color;\n\nvoid main() {\n float dist = distance(v_uv, vec2(0.5));\n float alpha = v_color.a * (1.0 - smoothstep(0.35, 0.5, dist));\n o_color = vec4(v_color.rgb, alpha);\n}"; export interface ParticleRenderOptions { readonly viewProjection: Float32List; readonly viewRight: Vec3; readonly viewUp: Vec3; } export declare class ParticleRenderer { readonly gl: WebGL2RenderingContext; readonly program: ShaderProgram; readonly system: ParticleSystem; readonly vertexBuffer: VertexBuffer; readonly indexBuffer: IndexBuffer; readonly vertexArray: VertexArray; private vertexCapacity; private indexCapacity; constructor(gl: WebGL2RenderingContext, system: ParticleSystem); get shaderSize(): number; render(options: ParticleRenderOptions): void; dispose(): void; } export interface ParticleEffectContext { readonly system: ParticleSystem; readonly origin: Vec3; readonly normal?: Vec3; readonly direction?: Vec3; } export declare function spawnBulletImpact(context: ParticleEffectContext): void; export declare function spawnExplosion(context: ParticleEffectContext): void; export declare function spawnBlood(context: ParticleEffectContext): void; export declare function spawnTeleportFlash(context: ParticleEffectContext): void; export declare function spawnMuzzleFlash(context: ParticleEffectContext): void; export declare function spawnTrail(context: ParticleEffectContext): void; export declare function spawnSplash(context: ParticleEffectContext): void; export declare function spawnSteam(context: ParticleEffectContext): void; export interface RailTrailContext { readonly system: ParticleSystem; readonly start: Vec3; readonly end: Vec3; } export declare function spawnRailTrail(context: RailTrailContext): void; export interface SparksContext extends ParticleEffectContext { readonly count?: number; readonly color?: readonly [number, number, number, number]; } export declare function spawnSparks(context: SparksContext): void; export interface BlasterImpactContext extends ParticleEffectContext { readonly color?: readonly [number, number, number, number]; } export declare function spawnBlasterImpact(context: BlasterImpactContext): void; export declare function spawnBfgExplosion(context: ParticleEffectContext): void; export {}; //# sourceMappingURL=particleSystem.d.ts.map