@codexo/exojs 0.7.12 → 0.8.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/CHANGELOG.md +737 -0
- package/dist/esm/core/Application.d.ts +3 -1
- package/dist/esm/core/Application.js +7 -6
- package/dist/esm/core/Application.js.map +1 -1
- package/dist/esm/core/Scene.d.ts +30 -0
- package/dist/esm/core/Scene.js +56 -0
- package/dist/esm/core/Scene.js.map +1 -1
- package/dist/esm/core/SceneManager.js +2 -2
- package/dist/esm/core/SceneManager.js.map +1 -1
- package/dist/esm/debug/DebugOverlay.js +2 -2
- package/dist/esm/debug/DebugOverlay.js.map +1 -1
- package/dist/esm/debug/PointerStackLayer.js +1 -1
- package/dist/esm/debug/PointerStackLayer.js.map +1 -1
- package/dist/esm/index.js +32 -10
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/input/ArcadeStickGamepadMapping.js +18 -19
- package/dist/esm/input/ArcadeStickGamepadMapping.js.map +1 -1
- package/dist/esm/input/Gamepad.d.ts +164 -62
- package/dist/esm/input/Gamepad.js +290 -134
- package/dist/esm/input/Gamepad.js.map +1 -1
- package/dist/esm/input/GamepadAxis.d.ts +120 -0
- package/dist/esm/input/GamepadAxis.js +106 -0
- package/dist/esm/input/GamepadAxis.js.map +1 -0
- package/dist/esm/input/GamepadButton.d.ts +110 -0
- package/dist/esm/input/GamepadButton.js +99 -0
- package/dist/esm/input/GamepadButton.js.map +1 -0
- package/dist/esm/input/GamepadDefinitions.js +4 -0
- package/dist/esm/input/GamepadDefinitions.js.map +1 -1
- package/dist/esm/input/GamepadMapping.d.ts +28 -24
- package/dist/esm/input/GamepadMapping.js +33 -16
- package/dist/esm/input/GamepadMapping.js.map +1 -1
- package/dist/esm/input/GamepadPromptLayouts.d.ts +10 -8
- package/dist/esm/input/GamepadPromptLayouts.js +21 -20
- package/dist/esm/input/GamepadPromptLayouts.js.map +1 -1
- package/dist/esm/input/GenericDualAnalogGamepadMapping.d.ts +6 -3
- package/dist/esm/input/GenericDualAnalogGamepadMapping.js +55 -46
- package/dist/esm/input/GenericDualAnalogGamepadMapping.js.map +1 -1
- package/dist/esm/input/InputBinding.d.ts +74 -0
- package/dist/esm/input/InputBinding.js +100 -0
- package/dist/esm/input/InputBinding.js.map +1 -0
- package/dist/esm/input/InputManager.d.ts +79 -33
- package/dist/esm/input/InputManager.js +229 -104
- package/dist/esm/input/InputManager.js.map +1 -1
- package/dist/esm/input/InteractionManager.d.ts +1 -1
- package/dist/esm/input/InteractionManager.js +13 -13
- package/dist/esm/input/InteractionManager.js.map +1 -1
- package/dist/esm/input/JoyConLeftGamepadMapping.d.ts +14 -9
- package/dist/esm/input/JoyConLeftGamepadMapping.js +39 -9
- package/dist/esm/input/JoyConLeftGamepadMapping.js.map +1 -1
- package/dist/esm/input/JoyConRightGamepadMapping.d.ts +14 -9
- package/dist/esm/input/JoyConRightGamepadMapping.js +35 -9
- package/dist/esm/input/JoyConRightGamepadMapping.js.map +1 -1
- package/dist/esm/input/Pointer.d.ts +84 -71
- package/dist/esm/input/Pointer.js +71 -71
- package/dist/esm/input/Pointer.js.map +1 -1
- package/dist/esm/input/SteamDeckGamepadMapping.d.ts +18 -0
- package/dist/esm/input/SteamDeckGamepadMapping.js +76 -0
- package/dist/esm/input/SteamDeckGamepadMapping.js.map +1 -0
- package/dist/esm/input/index.d.ts +7 -4
- package/dist/esm/input/types.d.ts +0 -76
- package/dist/esm/input/types.js +1 -80
- package/dist/esm/input/types.js.map +1 -1
- package/dist/esm/particles/ParticleSystem.d.ts +180 -83
- package/dist/esm/particles/ParticleSystem.js +446 -133
- package/dist/esm/particles/ParticleSystem.js.map +1 -1
- package/dist/esm/particles/distributions/BoxArea.d.ts +17 -0
- package/dist/esm/particles/distributions/BoxArea.js +48 -0
- package/dist/esm/particles/distributions/BoxArea.js.map +1 -0
- package/dist/esm/particles/distributions/CircleArea.d.ts +19 -0
- package/dist/esm/particles/distributions/CircleArea.js +33 -0
- package/dist/esm/particles/distributions/CircleArea.js.map +1 -0
- package/dist/esm/particles/distributions/ConeDirection.d.ts +28 -0
- package/dist/esm/particles/distributions/ConeDirection.js +44 -0
- package/dist/esm/particles/distributions/ConeDirection.js.map +1 -0
- package/dist/esm/particles/distributions/Constant.d.ts +17 -0
- package/dist/esm/particles/distributions/Constant.js +35 -0
- package/dist/esm/particles/distributions/Constant.js.map +1 -0
- package/dist/esm/particles/distributions/Curve.d.ts +30 -0
- package/dist/esm/particles/distributions/Curve.js +53 -0
- package/dist/esm/particles/distributions/Curve.js.map +1 -0
- package/dist/esm/particles/distributions/Distribution.d.ts +45 -0
- package/dist/esm/particles/distributions/Gradient.d.ts +40 -0
- package/dist/esm/particles/distributions/Gradient.js +72 -0
- package/dist/esm/particles/distributions/Gradient.js.map +1 -0
- package/dist/esm/particles/distributions/LineSegment.d.ts +15 -0
- package/dist/esm/particles/distributions/LineSegment.js +27 -0
- package/dist/esm/particles/distributions/LineSegment.js.map +1 -0
- package/dist/esm/particles/distributions/Range.d.ts +12 -0
- package/dist/esm/particles/distributions/Range.js +19 -0
- package/dist/esm/particles/distributions/Range.js.map +1 -0
- package/dist/esm/particles/distributions/VectorRange.d.ts +20 -0
- package/dist/esm/particles/distributions/VectorRange.js +31 -0
- package/dist/esm/particles/distributions/VectorRange.js.map +1 -0
- package/dist/esm/particles/distributions/index.d.ts +12 -0
- package/dist/esm/particles/gpu/ParticleGpuState.d.ts +57 -0
- package/dist/esm/particles/gpu/ParticleGpuState.js +508 -0
- package/dist/esm/particles/gpu/ParticleGpuState.js.map +1 -0
- package/dist/esm/particles/index.d.ts +2 -10
- package/dist/esm/particles/modules/AlphaFadeOverLifetime.d.ts +24 -0
- package/dist/esm/particles/modules/AlphaFadeOverLifetime.js +60 -0
- package/dist/esm/particles/modules/AlphaFadeOverLifetime.js.map +1 -0
- package/dist/esm/particles/modules/ApplyForce.d.ts +20 -0
- package/dist/esm/particles/modules/ApplyForce.js +48 -0
- package/dist/esm/particles/modules/ApplyForce.js.map +1 -0
- package/dist/esm/particles/modules/AttractToPoint.d.ts +27 -0
- package/dist/esm/particles/modules/AttractToPoint.js +73 -0
- package/dist/esm/particles/modules/AttractToPoint.js.map +1 -0
- package/dist/esm/particles/modules/BurstSpawn.d.ts +53 -0
- package/dist/esm/particles/modules/BurstSpawn.js +94 -0
- package/dist/esm/particles/modules/BurstSpawn.js.map +1 -0
- package/dist/esm/particles/modules/ColorOverLifetime.d.ts +22 -0
- package/dist/esm/particles/modules/ColorOverLifetime.js +65 -0
- package/dist/esm/particles/modules/ColorOverLifetime.js.map +1 -0
- package/dist/esm/particles/modules/ColorOverSpeed.d.ts +27 -0
- package/dist/esm/particles/modules/ColorOverSpeed.js +86 -0
- package/dist/esm/particles/modules/ColorOverSpeed.js.map +1 -0
- package/dist/esm/particles/modules/DeathModule.d.ts +24 -0
- package/dist/esm/particles/modules/DeathModule.js +25 -0
- package/dist/esm/particles/modules/DeathModule.js.map +1 -0
- package/dist/esm/particles/modules/Drag.d.ts +20 -0
- package/dist/esm/particles/modules/Drag.js +45 -0
- package/dist/esm/particles/modules/Drag.js.map +1 -0
- package/dist/esm/particles/modules/OrbitalForce.d.ts +28 -0
- package/dist/esm/particles/modules/OrbitalForce.js +65 -0
- package/dist/esm/particles/modules/OrbitalForce.js.map +1 -0
- package/dist/esm/particles/modules/RateSpawn.d.ts +41 -0
- package/dist/esm/particles/modules/RateSpawn.js +76 -0
- package/dist/esm/particles/modules/RateSpawn.js.map +1 -0
- package/dist/esm/particles/modules/RepelFromPoint.d.ts +24 -0
- package/dist/esm/particles/modules/RepelFromPoint.js +76 -0
- package/dist/esm/particles/modules/RepelFromPoint.js.map +1 -0
- package/dist/esm/particles/modules/RotateOverLifetime.d.ts +20 -0
- package/dist/esm/particles/modules/RotateOverLifetime.js +43 -0
- package/dist/esm/particles/modules/RotateOverLifetime.js.map +1 -0
- package/dist/esm/particles/modules/ScaleOverLifetime.d.ts +26 -0
- package/dist/esm/particles/modules/ScaleOverLifetime.js +59 -0
- package/dist/esm/particles/modules/ScaleOverLifetime.js.map +1 -0
- package/dist/esm/particles/modules/SpawnModule.d.ts +30 -0
- package/dist/esm/particles/modules/SpawnModule.js +31 -0
- package/dist/esm/particles/modules/SpawnModule.js.map +1 -0
- package/dist/esm/particles/modules/SpawnOnDeath.d.ts +24 -0
- package/dist/esm/particles/modules/SpawnOnDeath.js +47 -0
- package/dist/esm/particles/modules/SpawnOnDeath.js.map +1 -0
- package/dist/esm/particles/modules/Turbulence.d.ts +30 -0
- package/dist/esm/particles/modules/Turbulence.js +122 -0
- package/dist/esm/particles/modules/Turbulence.js.map +1 -0
- package/dist/esm/particles/modules/UpdateModule.d.ts +95 -0
- package/dist/esm/particles/modules/UpdateModule.js +66 -0
- package/dist/esm/particles/modules/UpdateModule.js.map +1 -0
- package/dist/esm/particles/modules/VelocityOverLifetime.d.ts +30 -0
- package/dist/esm/particles/modules/VelocityOverLifetime.js +84 -0
- package/dist/esm/particles/modules/VelocityOverLifetime.js.map +1 -0
- package/dist/esm/particles/modules/WgslContribution.d.ts +81 -0
- package/dist/esm/particles/modules/WgslContribution.js +34 -0
- package/dist/esm/particles/modules/WgslContribution.js.map +1 -0
- package/dist/esm/particles/modules/index.d.ts +22 -0
- package/dist/esm/rendering/webgl2/WebGl2ParticleRenderer.d.ts +9 -14
- package/dist/esm/rendering/webgl2/WebGl2ParticleRenderer.js +90 -61
- package/dist/esm/rendering/webgl2/WebGl2ParticleRenderer.js.map +1 -1
- package/dist/esm/rendering/webgl2/glsl/particle.vert.js +1 -1
- package/dist/esm/rendering/webgpu/WebGpuParticleRenderer.d.ts +9 -0
- package/dist/esm/rendering/webgpu/WebGpuParticleRenderer.js +107 -23
- package/dist/esm/rendering/webgpu/WebGpuParticleRenderer.js.map +1 -1
- package/dist/esm/rendering/webgpu/compute/WebGpuComputePipeline.d.ts +52 -0
- package/dist/esm/rendering/webgpu/compute/WebGpuStorageBuffer.d.ts +29 -0
- package/dist/esm/rendering/webgpu/compute/index.d.ts +3 -0
- package/dist/esm/resources/CacheFirstStrategy.d.ts +7 -4
- package/dist/esm/resources/CacheFirstStrategy.js +11 -8
- package/dist/esm/resources/CacheFirstStrategy.js.map +1 -1
- package/dist/esm/resources/CacheStrategy.d.ts +14 -6
- package/dist/esm/resources/Loader.d.ts +8 -3
- package/dist/esm/resources/Loader.js +19 -37
- package/dist/esm/resources/Loader.js.map +1 -1
- package/dist/esm/resources/NetworkOnlyStrategy.d.ts +3 -0
- package/dist/esm/resources/NetworkOnlyStrategy.js +8 -3
- package/dist/esm/resources/NetworkOnlyStrategy.js.map +1 -1
- package/dist/esm/resources/factories/ImageFactory.d.ts +2 -2
- package/dist/esm/resources/factories/ImageFactory.js.map +1 -1
- package/dist/esm/resources/factories/TextureFactory.d.ts +2 -2
- package/dist/esm/resources/factories/TextureFactory.js.map +1 -1
- package/dist/esm/resources/factories/VttFactory.d.ts +3 -3
- package/dist/esm/resources/factories/VttFactory.js +83 -6
- package/dist/esm/resources/factories/VttFactory.js.map +1 -1
- package/dist/exo.esm.js +4028 -1518
- package/dist/exo.esm.js.map +1 -1
- package/package.json +2 -1
- package/dist/esm/input/GamepadChannels.d.ts +0 -47
- package/dist/esm/input/GamepadChannels.js +0 -53
- package/dist/esm/input/GamepadChannels.js.map +0 -1
- package/dist/esm/input/GamepadControl.d.ts +0 -33
- package/dist/esm/input/GamepadControl.js +0 -42
- package/dist/esm/input/GamepadControl.js.map +0 -1
- package/dist/esm/input/Input.d.ts +0 -52
- package/dist/esm/input/Input.js +0 -90
- package/dist/esm/input/Input.js.map +0 -1
- package/dist/esm/particles/Particle.d.ts +0 -77
- package/dist/esm/particles/Particle.js +0 -143
- package/dist/esm/particles/Particle.js.map +0 -1
- package/dist/esm/particles/ParticleProperties.d.ts +0 -29
- package/dist/esm/particles/affectors/ColorAffector.d.ts +0 -30
- package/dist/esm/particles/affectors/ColorAffector.js +0 -55
- package/dist/esm/particles/affectors/ColorAffector.js.map +0 -1
- package/dist/esm/particles/affectors/ForceAffector.d.ts +0 -24
- package/dist/esm/particles/affectors/ForceAffector.js +0 -39
- package/dist/esm/particles/affectors/ForceAffector.js.map +0 -1
- package/dist/esm/particles/affectors/ParticleAffector.d.ts +0 -19
- package/dist/esm/particles/affectors/ScaleAffector.d.ts +0 -23
- package/dist/esm/particles/affectors/ScaleAffector.js +0 -38
- package/dist/esm/particles/affectors/ScaleAffector.js.map +0 -1
- package/dist/esm/particles/affectors/TorqueAffector.d.ts +0 -23
- package/dist/esm/particles/affectors/TorqueAffector.js +0 -37
- package/dist/esm/particles/affectors/TorqueAffector.js.map +0 -1
- package/dist/esm/particles/emitters/ParticleEmitter.d.ts +0 -19
- package/dist/esm/particles/emitters/ParticleOptions.d.ts +0 -62
- package/dist/esm/particles/emitters/ParticleOptions.js +0 -120
- package/dist/esm/particles/emitters/ParticleOptions.js.map +0 -1
- package/dist/esm/particles/emitters/UniversalEmitter.d.ts +0 -40
- package/dist/esm/particles/emitters/UniversalEmitter.js +0 -68
- package/dist/esm/particles/emitters/UniversalEmitter.js.map +0 -1
|
@@ -1,112 +1,209 @@
|
|
|
1
|
-
import { Particle } from './Particle';
|
|
2
1
|
import { Rectangle } from '@/math/Rectangle';
|
|
3
2
|
import type { Time } from '@/core/Time';
|
|
4
3
|
import { Drawable } from '@/rendering/Drawable';
|
|
5
|
-
import
|
|
6
|
-
import type {
|
|
7
|
-
import
|
|
4
|
+
import { Texture } from '@/rendering/texture/Texture';
|
|
5
|
+
import type { RenderBackend } from '@/rendering/RenderBackend';
|
|
6
|
+
import { Spritesheet } from '@/rendering/sprite/Spritesheet';
|
|
7
|
+
import type { SpawnModule } from './modules/SpawnModule';
|
|
8
|
+
import type { UpdateModule } from './modules/UpdateModule';
|
|
9
|
+
import type { DeathModule } from './modules/DeathModule';
|
|
10
|
+
import { ParticleGpuState } from './gpu/ParticleGpuState';
|
|
8
11
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
* Options for {@link ParticleSystem}'s constructor — orthogonal config
|
|
13
|
+
* that's independent of the texture source. Texture / frames / spritesheet
|
|
14
|
+
* live in positional arguments to enforce mutual exclusivity at the type
|
|
15
|
+
* level (you can't pass both a texture and a spritesheet by accident).
|
|
16
|
+
*/
|
|
17
|
+
export interface ParticleSystemOptions {
|
|
18
|
+
/** Maximum particle count. Fixed at construction. Default 4096. */
|
|
19
|
+
capacity?: number;
|
|
20
|
+
/**
|
|
21
|
+
* Direct GPU device. Lets advanced consumers wire a `GPUDevice` owned
|
|
22
|
+
* outside an `Application` (or a mock device in tests). When omitted,
|
|
23
|
+
* the backend reference is captured automatically on the first
|
|
24
|
+
* {@link ParticleSystem.render} call — `WebGpuBackend` ⇒ GPU mode,
|
|
25
|
+
* anything else (incl. WebGL2) ⇒ CPU mode.
|
|
26
|
+
*/
|
|
27
|
+
device?: GPUDevice;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The central coordinator of the particle pipeline. `ParticleSystem` is a
|
|
31
|
+
* {@link Drawable} that owns:
|
|
32
|
+
*
|
|
33
|
+
* - **SoA particle storage** — one typed array per attribute (position,
|
|
34
|
+
* velocity, scale, rotation, color, lifetime, ...), sized to a fixed
|
|
35
|
+
* capacity at construction. User code reads/writes via
|
|
36
|
+
* `system.posX[slot]`, `system.velX[slot]`, etc.
|
|
37
|
+
* - **Spawn modules** — write new particles into freshly allocated slots.
|
|
38
|
+
* - **Update modules** — mutate the live range each frame (forces, color
|
|
39
|
+
* blends, scale curves, drag, ...). Built-in modules ship both CPU and
|
|
40
|
+
* WGSL implementations; custom modules can opt into GPU acceleration by
|
|
41
|
+
* implementing `wgsl()`.
|
|
42
|
+
* - **Death modules** — fire once per dying particle, before its slot is
|
|
43
|
+
* recycled (sub-emitters, event hooks).
|
|
44
|
+
*
|
|
45
|
+
* **Auto-routing CPU vs GPU:** at first {@link update}, the system checks:
|
|
46
|
+
* if a `WebGpuBackend` was supplied AND every registered update module has
|
|
47
|
+
* `wgsl()`, the GPU path engages — a composite compute pipeline runs
|
|
48
|
+
* integration plus all module bodies in one dispatch and writes directly
|
|
49
|
+
* into the renderer's instance buffer (no CPU readback). Otherwise the CPU
|
|
50
|
+
* path runs the existing per-module `apply()` loops.
|
|
51
|
+
*
|
|
52
|
+
* **Per-frame order in {@link update} (CPU mode):**
|
|
53
|
+
* 1. Run every spawn module.
|
|
54
|
+
* 2. Integrate position from velocity, rotation from rotationSpeed, advance `elapsed`.
|
|
55
|
+
* 3. Run every update module on the live range.
|
|
56
|
+
* 4. Compact: scan `[0, liveCount)` forward, fire death modules on expired
|
|
57
|
+
* slots, copy survivors down. `liveCount` shrinks to the survivor count.
|
|
16
58
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
59
|
+
* **Per-frame order in {@link update} (GPU mode):**
|
|
60
|
+
* 1. Run every spawn module (CPU writes initial values into the spawn slot).
|
|
61
|
+
* 2. Detect expiries on CPU (via `elapsed >= lifetime`); fire death modules;
|
|
62
|
+
* set `lifetime[slot] = -1` sentinel + clear `alive[slot]` so the GPU
|
|
63
|
+
* shader skips them. **No compaction** — slots are recycled on next spawn.
|
|
64
|
+
* 3. Dispatch the composite compute pipeline. Integration + update modules
|
|
65
|
+
* + pack-instances run in one pass; the instance buffer is written
|
|
66
|
+
* directly. CPU SoA stays as-is for spawn writes.
|
|
67
|
+
*
|
|
68
|
+
* **Coordinate space:** particle positions are LOCAL to the system. The
|
|
69
|
+
* system's `getGlobalTransform()` is applied on top during rendering — both
|
|
70
|
+
* the WebGL2 and WebGPU shaders multiply `projection * translation * rotated`.
|
|
71
|
+
* Setting world-space positions on individual particles double-translates.
|
|
72
|
+
* Position the system itself via `system.setPosition(...)` and emit relative
|
|
73
|
+
* to `(0, 0)`.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* // Backend-agnostic — runs CPU on WebGL2, GPU on WebGPU automatically.
|
|
77
|
+
* const system = new ParticleSystem(loader.get(Texture, 'spark'), {
|
|
78
|
+
* capacity: 8192,
|
|
79
|
+
* backend: app.backend,
|
|
80
|
+
* });
|
|
81
|
+
*
|
|
82
|
+
* system.addSpawnModule(new RateSpawn({ rate: new Constant(60), ... }));
|
|
83
|
+
* system.addUpdateModule(new ApplyForce(0, 980)); // gravity, GPU-eligible
|
|
84
|
+
* system.addUpdateModule(new ColorOverLifetime(fireGradient));
|
|
85
|
+
* scene.addChild(system);
|
|
21
86
|
*/
|
|
22
87
|
export declare class ParticleSystem extends Drawable {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
88
|
+
/** Maximum particle count this system will store. Fixed at construction. */
|
|
89
|
+
readonly capacity: number;
|
|
90
|
+
readonly posX: Float32Array;
|
|
91
|
+
readonly posY: Float32Array;
|
|
92
|
+
readonly velX: Float32Array;
|
|
93
|
+
readonly velY: Float32Array;
|
|
94
|
+
readonly scaleX: Float32Array;
|
|
95
|
+
readonly scaleY: Float32Array;
|
|
96
|
+
readonly rotations: Float32Array;
|
|
97
|
+
readonly rotationSpeeds: Float32Array;
|
|
98
|
+
readonly color: Uint32Array;
|
|
99
|
+
readonly elapsed: Float32Array;
|
|
100
|
+
readonly lifetime: Float32Array;
|
|
101
|
+
readonly textureIndex: Uint16Array;
|
|
102
|
+
/**
|
|
103
|
+
* Number of currently live particles. In CPU mode this is exact: slots
|
|
104
|
+
* `[0, liveCount)` are all alive after each `update()`. In GPU mode
|
|
105
|
+
* this is a high-water mark — slots `[0, liveCount)` may contain dead
|
|
106
|
+
* holes (filled in by future spawns); use {@link aliveCount} for the
|
|
107
|
+
* actual alive count.
|
|
108
|
+
*/
|
|
109
|
+
liveCount: number;
|
|
110
|
+
/**
|
|
111
|
+
* Per-slot alive flag (1 = alive, 0 = dead). Maintained in both CPU
|
|
112
|
+
* and GPU mode. Custom modules iterating the live range should check
|
|
113
|
+
* this to skip dead slots in GPU mode.
|
|
114
|
+
*/
|
|
115
|
+
readonly alive: Uint8Array;
|
|
116
|
+
private readonly _spawnModules;
|
|
117
|
+
private readonly _updateModules;
|
|
118
|
+
private readonly _deathModules;
|
|
119
|
+
private _backend;
|
|
120
|
+
private readonly _device;
|
|
121
|
+
private _gpuState;
|
|
122
|
+
private _gpuMode;
|
|
123
|
+
private _compiled;
|
|
124
|
+
private _spawnHint;
|
|
125
|
+
/**
|
|
126
|
+
* In GPU mode, slots whose CPU SoA values need re-uploading to the GPU
|
|
127
|
+
* (newly spawned, or just-expired with lifetime sentinel). Cleared
|
|
128
|
+
* after each compute dispatch. CPU never overwrites integrated GPU
|
|
129
|
+
* state — only dirty slots flow CPU → GPU.
|
|
130
|
+
*/
|
|
131
|
+
private readonly _gpuDirtySlots;
|
|
27
132
|
private _texture;
|
|
28
|
-
private
|
|
29
|
-
private
|
|
30
|
-
private
|
|
133
|
+
private readonly _frames;
|
|
134
|
+
private readonly _textureFrame;
|
|
135
|
+
private readonly _vertices;
|
|
136
|
+
private readonly _texCoords;
|
|
31
137
|
private _updateTexCoords;
|
|
32
138
|
private _updateVertices;
|
|
33
|
-
|
|
139
|
+
/** No texture — particles render as solid-color quads on a 1×1 white default. */
|
|
140
|
+
constructor(options?: ParticleSystemOptions);
|
|
141
|
+
/** Single texture, no atlas — every particle uses the full texture as one frame. */
|
|
142
|
+
constructor(texture: Texture, options?: ParticleSystemOptions);
|
|
143
|
+
/** Multi-frame atlas — each particle's `textureIndex` selects a frame. */
|
|
144
|
+
constructor(texture: Texture, frames: ReadonlyArray<Rectangle>, options?: ParticleSystemOptions);
|
|
145
|
+
/** Spritesheet shorthand — texture + frames pulled from the sheet. */
|
|
146
|
+
constructor(spritesheet: Spritesheet, options?: ParticleSystemOptions);
|
|
34
147
|
get texture(): Texture;
|
|
35
148
|
set texture(texture: Texture);
|
|
36
149
|
get textureFrame(): Rectangle;
|
|
37
150
|
set textureFrame(frame: Rectangle);
|
|
38
151
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* sprite relative to its world position.
|
|
152
|
+
* Atlas frames declared on this system, or empty when the texture is
|
|
153
|
+
* used as a single frame. Each particle's `textureIndex[i]` selects
|
|
154
|
+
* an entry from this list; out-of-range indices are clamped to 0.
|
|
43
155
|
*/
|
|
156
|
+
get frames(): ReadonlyArray<Rectangle>;
|
|
157
|
+
/** `true` when the system declares more than one atlas frame. */
|
|
158
|
+
get hasAtlas(): boolean;
|
|
44
159
|
get vertices(): Float32Array;
|
|
45
|
-
/**
|
|
46
|
-
* Packed UV coordinates for the current {@link textureFrame} as four
|
|
47
|
-
* `Uint32` values, each encoding a `(u, v)` pair in the upper/lower 16
|
|
48
|
-
* bits (normalised to 0–65535). Vertex order respects
|
|
49
|
-
* {@link Texture.flipY}. Recomputed lazily on texture or frame changes.
|
|
50
|
-
*/
|
|
51
160
|
get texCoords(): Uint32Array;
|
|
52
|
-
|
|
53
|
-
get
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
get
|
|
61
|
-
/**
|
|
62
|
-
* Replaces the particle sprite texture and resets the texture frame to
|
|
63
|
-
* cover the full new texture. No-ops if `texture` is the same instance.
|
|
64
|
-
*/
|
|
161
|
+
/** `true` when the system is running on the GPU compute pipeline. */
|
|
162
|
+
get gpuMode(): boolean;
|
|
163
|
+
/** GPU-side state, or `null` in CPU mode. */
|
|
164
|
+
get gpuState(): ParticleGpuState | null;
|
|
165
|
+
/** Actual count of live particles (slots with `alive[i] === 1`). May differ from `liveCount` in GPU mode. */
|
|
166
|
+
get aliveCount(): number;
|
|
167
|
+
get spawnModules(): ReadonlyArray<SpawnModule>;
|
|
168
|
+
get updateModules(): ReadonlyArray<UpdateModule>;
|
|
169
|
+
get deathModules(): ReadonlyArray<DeathModule>;
|
|
65
170
|
setTexture(texture: Texture): this;
|
|
66
|
-
/**
|
|
67
|
-
* Sets the sub-rectangle of the texture used as the particle sprite,
|
|
68
|
-
* invalidating cached vertices and UV coordinates and updating the system's
|
|
69
|
-
* local bounds to match the frame dimensions.
|
|
70
|
-
*/
|
|
71
171
|
setTextureFrame(frame: Rectangle): this;
|
|
72
|
-
/** Resets the texture frame to the full dimensions of the current texture. */
|
|
73
172
|
resetTextureFrame(): this;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
/** Destroys and removes all registered affectors. */
|
|
81
|
-
clearAffectors(): this;
|
|
82
|
-
/**
|
|
83
|
-
* Returns a recycled particle from the {@link graveyard}, or allocates a
|
|
84
|
-
* new one if the pool is empty. Call {@link Particle.applyOptions}
|
|
85
|
-
* immediately after to reset its state before passing it to
|
|
86
|
-
* {@link emitParticle}.
|
|
87
|
-
*/
|
|
88
|
-
requestParticle(): Particle;
|
|
89
|
-
/** Adds a fully-configured `particle` to the live pool. Typically called by emitters. */
|
|
90
|
-
emitParticle(particle: Particle): this;
|
|
91
|
-
/**
|
|
92
|
-
* Advances a single particle by one `delta` step: increments
|
|
93
|
-
* `elapsedLifetime`, integrates velocity into position, and applies
|
|
94
|
-
* `rotationSpeed` to rotation. Called for every live particle by
|
|
95
|
-
* {@link update} before the affector pass.
|
|
96
|
-
*/
|
|
97
|
-
updateParticle(particle: Particle, delta: Time): this;
|
|
173
|
+
addSpawnModule(mod: SpawnModule): this;
|
|
174
|
+
addUpdateModule(mod: UpdateModule): this;
|
|
175
|
+
addDeathModule(mod: DeathModule): this;
|
|
176
|
+
clearSpawnModules(): this;
|
|
177
|
+
clearUpdateModules(): this;
|
|
178
|
+
clearDeathModules(): this;
|
|
98
179
|
/**
|
|
99
|
-
*
|
|
100
|
-
*
|
|
180
|
+
* Allocates a particle slot and returns its index. Returns `-1` when
|
|
181
|
+
* the system is at {@link capacity}.
|
|
182
|
+
*
|
|
183
|
+
* **CPU mode:** slots are dense in `[0, liveCount)`. `spawn()` returns
|
|
184
|
+
* the next sequential slot; `liveCount++`.
|
|
185
|
+
*
|
|
186
|
+
* **GPU mode:** slots may have dead holes. `spawn()` finds the first
|
|
187
|
+
* `alive[i] === 0` slot via a round-robin hint pointer (amortised O(1),
|
|
188
|
+
* worst case O(capacity) on full systems).
|
|
101
189
|
*/
|
|
190
|
+
spawn(): number;
|
|
191
|
+
/** Resets the system to zero live particles without destroying it. */
|
|
102
192
|
clearParticles(): this;
|
|
103
193
|
/**
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
* without re-indexing.
|
|
194
|
+
* Engine-side render hook. Captures the active backend on each call so
|
|
195
|
+
* the next `update()` can compile a GPU pipeline if the backend turned
|
|
196
|
+
* out to be `WebGpuBackend`. Re-captures and rebuilds when the backend
|
|
197
|
+
* reference changes (e.g. after device-loss recovery).
|
|
109
198
|
*/
|
|
199
|
+
render(backend: RenderBackend): this;
|
|
200
|
+
/** Per-frame entry point. Routes to CPU or GPU pipeline based on auto-detection at first call. */
|
|
110
201
|
update(delta: Time): this;
|
|
111
202
|
destroy(): void;
|
|
203
|
+
private _compile;
|
|
204
|
+
private _spawnCpu;
|
|
205
|
+
private _spawnGpu;
|
|
206
|
+
private _updateCpu;
|
|
207
|
+
private _updateGpu;
|
|
208
|
+
private _copySlot;
|
|
112
209
|
}
|