@needle-tools/engine
Version:
Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.
258 lines (257 loc) • 10.8 kB
TypeScript
import { BufferGeometry, Matrix4, Mesh, MeshBasicMaterial, Object3D, Quaternion, SpriteMaterial, Vector3 } from "three";
import type { Behavior, Particle } from "three.quarks";
import { ParticleSystem as _ParticleSystem } from "three.quarks";
import { Context } from "../../engine/engine_setup.js";
import { Behaviour, GameObject } from "../Component.js";
import { ColorBySpeedModule, ColorOverLifetimeModule, EmissionModule, InheritVelocityModule, type IParticleSystem, LimitVelocityOverLifetimeModule, MainModule, NoiseModule, ParticleSystemRenderMode, RotationBySpeedModule, RotationOverLifetimeModule, ShapeModule, SizeBySpeedModule, SizeOverLifetimeModule, TextureSheetAnimationModule, TrailModule, VelocityOverLifetimeModule } from "./ParticleSystemModules.js";
export type { Particle as QParticle, Behavior as QParticleBehaviour, TrailParticle as QTrailParticle } from "three.quarks";
/**
* Defines when a sub-emitter spawns particles relative to the parent particle's lifecycle.
* Used to create complex effects like explosions on impact or trails following particles.
*/
export declare enum SubEmitterType {
/** Sub-emitter triggers when the parent particle is born */
Birth = 0,
/** Sub-emitter triggers when the parent particle collides */
Collision = 1,
/** Sub-emitter triggers when the parent particle dies */
Death = 2,
/** Sub-emitter triggers when the parent particle enters a trigger zone */
Trigger = 3,
/** Sub-emitter is triggered manually via code */
Manual = 4
}
/** @internal */
export declare class ParticleSystemRenderer extends Behaviour {
renderMode?: ParticleSystemRenderMode;
particleMaterial?: SpriteMaterial | MeshBasicMaterial;
trailMaterial?: SpriteMaterial | MeshBasicMaterial;
particleMesh?: Mesh | string;
maxParticleSize: number;
minParticleSize: number;
velocityScale?: number;
cameraVelocityScale?: number;
lengthScale?: number;
start(): void;
get transparent(): boolean;
getMaterial(trailEnabled?: boolean): MeshBasicMaterial | SpriteMaterial | undefined;
getMesh(_renderMode?: ParticleSystemRenderMode): Mesh<BufferGeometry<import("three").NormalBufferAttributes>, MeshBasicMaterial | SpriteMaterial, import("three").Object3DEventMap>;
}
/**
* Base class for custom particle behaviors. Extend this to create custom particle logic.
*
* Override `initialize()` to set up per-particle state when particles spawn.
* Override `update()` to modify particles each frame (position, velocity, color, size, etc.).
* Override `frameUpdate()` for logic that runs once per frame (not per particle).
*
* @example Custom wind effect
* ```ts
* class WindBehaviour extends ParticleSystemBaseBehaviour {
* windStrength = 2;
* windDirection = new Vector3(1, 0, 0);
*
* update(particle: Particle, delta: number) {
* particle.velocity.addScaledVector(this.windDirection, this.windStrength * delta);
* }
* }
* ```
*
* @see {@link ParticleSystem.addBehaviour} to register your custom behavior
* @link https://github.com/Alchemist0823/three.quarks
*/
export declare abstract class ParticleSystemBaseBehaviour implements Behavior {
/** Reference to the particle system this behavior belongs to */
system: ParticleSystem;
/** Access to the engine context for timing, input, etc. */
get context(): Context;
constructor(ps?: ParticleSystem);
/** Behavior type identifier used by three.quarks */
type: string;
/** Called once when a particle is spawned. Use to initialize per-particle state. */
initialize(_particle: Particle): void;
/** Called every frame for each active particle. Use to update particle properties. */
update(_particle: Particle, _delta: number): void;
/** Called once per frame before particle updates. Use for shared calculations. */
frameUpdate(_delta: number): void;
toJSON(): void;
clone(): Behavior;
/** Called when the particle system is reset. */
reset(): void;
}
export declare const $particleLife: unique symbol;
/**
* ParticleSystem efficiently handles the motion and rendering of many individual particles.
* Use it for visual effects like fire, smoke, sparks, rain, magic spells, and more.
*
* 
* 
*
* **Modules:**
* Configure particle behavior through modules like {@link EmissionModule}, {@link ShapeModule},
* {@link ColorOverLifetimeModule}, {@link SizeOverLifetimeModule}, {@link VelocityOverLifetimeModule},
* {@link NoiseModule}, and {@link TrailModule}.
*
* **Custom behaviors:**
* Add custom particle behaviors by extending {@link ParticleSystemBaseBehaviour} and
* calling `addBehaviour()`. This gives you full control over particle initialization and updates.
*
* **Performance:**
* Particles are batched together for fast, performant rendering even on low-end devices.
* Needle Engine uses [three.quarks](https://github.com/Alchemist0823/three.quarks) internally.
*
* @example Basic playback control
* ```ts
* const ps = myObject.getComponent(ParticleSystem);
* ps.play();
* ps.emit(10); // Emit 10 particles immediately
* ps.pause();
* ps.stop(true, true); // Stop and clear all particles
* ```
*
* @example Custom particle behavior
* ```ts
* class GravityBehaviour extends ParticleSystemBaseBehaviour {
* update(particle: Particle, delta: number) {
* particle.velocity.y -= 9.8 * delta;
* }
* }
* particleSystem.addBehaviour(new GravityBehaviour());
* ```
*
* - Example: https://engine.needle.tools/samples/particles
* - Example: https://engine.needle.tools/samples/particle-bursts
* - Example: https://engine.needle.tools/samples/particles-on-collision
*
* @summary Handles the motion and rendering of many individual particles
* @category Rendering
* @group Components
* @see {@link ParticleSystemBaseBehaviour} for custom particle behaviors
* @see {@link EmissionModule} for emission configuration
* @see {@link ShapeModule} for emission shape control
* @see {@link TrailModule} for particle trails
* @link https://engine.needle.tools/docs/features/particles.html
*/
export declare class ParticleSystem extends Behaviour implements IParticleSystem {
play(includeChildren?: boolean): void;
pause(includeChildren?: boolean): void;
/** clear=true removes all emitted particles */
stop(includeChildren?: boolean, clear?: boolean): void;
/** remove emitted particles and reset time */
reset(): void;
private _state?;
emit(count: number): void;
get playOnAwake(): boolean;
set playOnAwake(val: boolean);
readonly colorOverLifetime: ColorOverLifetimeModule;
readonly main: MainModule;
readonly emission: EmissionModule;
readonly sizeOverLifetime: SizeOverLifetimeModule;
readonly shape: ShapeModule;
readonly noise: NoiseModule;
readonly trails: TrailModule;
readonly velocityOverLifetime: VelocityOverLifetimeModule;
readonly limitVelocityOverLifetime: LimitVelocityOverLifetimeModule;
inheritVelocity: InheritVelocityModule;
readonly colorBySpeed: ColorBySpeedModule;
readonly textureSheetAnimation: TextureSheetAnimationModule;
readonly rotationOverLifetime: RotationOverLifetimeModule;
readonly rotationBySpeed: RotationBySpeedModule;
readonly sizeBySpeed: SizeBySpeedModule;
get renderer(): ParticleSystemRenderer;
get isPlaying(): boolean;
get currentParticles(): number;
get maxParticles(): number;
get time(): number;
get duration(): number;
get deltaTime(): number;
get scale(): number;
get cameraScale(): number;
private _cameraScale;
get container(): Object3D;
get worldspace(): boolean;
get localspace(): boolean;
private __worldQuaternion;
get worldQuaternion(): Quaternion;
private _worldQuaternionInverted;
get worldQuaternionInverted(): Quaternion;
private _worldScale;
get worldScale(): Vector3;
private _worldPositionFrame;
private _worldPos;
get worldPos(): Vector3;
get matrixWorld(): Matrix4;
get isSubsystem(): boolean;
/** Add a custom quarks behaviour to the particle system.
* You can add a quarks.Behaviour type or derive from {@link ParticleSystemBaseBehaviour}
* @link https://github.com/Alchemist0823/three.quarks
* @example
* ```typescript
* class MyBehaviour extends ParticleSystemBaseBehaviour {
* initialize(particle: Particle) {
* // initialize the particle
* }
* update(particle: Particle, delta: number) {
* // do something with the particle
* }
* }
*
* const system = gameObject.getComponent(ParticleSystem);
* system.addBehaviour(new MyBehaviour());
* ```
*/
addBehaviour(particleSystemBehaviour: Behavior | ParticleSystemBaseBehaviour): boolean;
/** Remove a custom quarks behaviour from the particle system. **/
removeBehaviour(particleSystemBehaviour: Behavior | ParticleSystemBaseBehaviour): boolean;
/** Removes all behaviours from the particle system
* **Note:** this will also remove the default behaviours like SizeBehaviour, ColorBehaviour etc.
*/
removeAllBehaviours(): boolean;
/** Get the underlying three.quarks particle system behaviours. This can be used to fully customize the behaviour of the particles. */
get behaviours(): Behavior[] | null;
/** Get access to the underlying quarks particle system if you need more control
* @link https://github.com/Alchemist0823/three.quarks
*/
get particleSystem(): _ParticleSystem | null;
private _renderer;
private _batchSystem?;
private _particleSystem?;
private _interface;
private _container;
private _time;
private _isPlaying;
private _isUsedAsSubsystem;
private _didPreWarm;
/** called from deserialization */
private set bursts(value);
private _bursts?;
/** called from deserialization */
private set subEmitterSystems(value);
private _subEmitterSystems?;
/** @internal */
onAfterDeserialize(_: any): void;
/** @internal */
awake(): void;
/** @internal */
start(): void;
/** @internal */
onDestroy(): void;
/** @internal */
onEnable(): void;
onDisable(): void;
/** @internal */
onBeforeRender(): void;
private preWarm;
private _lastBatchesCount;
private onSimulate;
private updateLayers;
private onUpdate;
private addSubParticleSystems;
}
/** @internal */
export declare class SubEmitterSystem {
particleSystem?: ParticleSystem;
emitProbability: number;
properties?: number;
type?: SubEmitterType;
_deserialize(_context: Context, gameObject: GameObject): void;
}