@codexo/exojs-particles 0.15.3 → 0.16.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.
Files changed (211) hide show
  1. package/README.md +21 -43
  2. package/dist/esm/ParticleStorage.d.ts +188 -0
  3. package/dist/esm/ParticleStorage.d.ts.map +1 -0
  4. package/dist/esm/ParticleStorage.js +208 -0
  5. package/dist/esm/ParticleStorage.js.map +1 -0
  6. package/dist/esm/ParticleSystem.d.ts +189 -60
  7. package/dist/esm/ParticleSystem.d.ts.map +1 -0
  8. package/dist/esm/ParticleSystem.js +660 -560
  9. package/dist/esm/ParticleSystem.js.map +1 -1
  10. package/dist/esm/distributions/BoxArea.d.ts +1 -0
  11. package/dist/esm/distributions/BoxArea.d.ts.map +1 -0
  12. package/dist/esm/distributions/BoxArea.js +38 -44
  13. package/dist/esm/distributions/BoxArea.js.map +1 -1
  14. package/dist/esm/distributions/CircleArea.d.ts +1 -0
  15. package/dist/esm/distributions/CircleArea.d.ts.map +1 -0
  16. package/dist/esm/distributions/CircleArea.js +30 -28
  17. package/dist/esm/distributions/CircleArea.js.map +1 -1
  18. package/dist/esm/distributions/ColorGradient.d.ts +3 -2
  19. package/dist/esm/distributions/ColorGradient.d.ts.map +1 -0
  20. package/dist/esm/distributions/ColorGradient.js +70 -75
  21. package/dist/esm/distributions/ColorGradient.js.map +1 -1
  22. package/dist/esm/distributions/ConeDirection.d.ts +2 -1
  23. package/dist/esm/distributions/ConeDirection.d.ts.map +1 -0
  24. package/dist/esm/distributions/ConeDirection.js +41 -39
  25. package/dist/esm/distributions/ConeDirection.js.map +1 -1
  26. package/dist/esm/distributions/Constant.d.ts +1 -0
  27. package/dist/esm/distributions/Constant.d.ts.map +1 -0
  28. package/dist/esm/distributions/Constant.js +32 -32
  29. package/dist/esm/distributions/Constant.js.map +1 -1
  30. package/dist/esm/distributions/Curve.d.ts +2 -1
  31. package/dist/esm/distributions/Curve.d.ts.map +1 -0
  32. package/dist/esm/distributions/Curve.js +46 -55
  33. package/dist/esm/distributions/Curve.js.map +1 -1
  34. package/dist/esm/distributions/Distribution.d.ts +4 -3
  35. package/dist/esm/distributions/Distribution.d.ts.map +1 -0
  36. package/dist/esm/distributions/LineSegment.d.ts +1 -0
  37. package/dist/esm/distributions/LineSegment.d.ts.map +1 -0
  38. package/dist/esm/distributions/LineSegment.js +25 -23
  39. package/dist/esm/distributions/LineSegment.js.map +1 -1
  40. package/dist/esm/distributions/Range.d.ts +1 -0
  41. package/dist/esm/distributions/Range.d.ts.map +1 -0
  42. package/dist/esm/distributions/Range.js +18 -16
  43. package/dist/esm/distributions/Range.js.map +1 -1
  44. package/dist/esm/distributions/VectorRange.d.ts +1 -0
  45. package/dist/esm/distributions/VectorRange.d.ts.map +1 -0
  46. package/dist/esm/distributions/VectorRange.js +29 -27
  47. package/dist/esm/distributions/VectorRange.js.map +1 -1
  48. package/dist/esm/distributions/index.d.ts +1 -0
  49. package/dist/esm/distributions/index.d.ts.map +1 -0
  50. package/dist/esm/gpu/ParticleGpuState.d.ts +143 -18
  51. package/dist/esm/gpu/ParticleGpuState.d.ts.map +1 -0
  52. package/dist/esm/gpu/ParticleGpuState.js +655 -497
  53. package/dist/esm/gpu/ParticleGpuState.js.map +1 -1
  54. package/dist/esm/gpu/shaders/particle-simulate.wgsl.js +6 -0
  55. package/dist/esm/gpu/shaders/particle-simulate.wgsl.js.map +1 -0
  56. package/dist/esm/index.d.ts +1 -0
  57. package/dist/esm/index.d.ts.map +1 -0
  58. package/dist/esm/index.js +39 -32
  59. package/dist/esm/modules/AlphaFadeOverLifetime.d.ts +4 -3
  60. package/dist/esm/modules/AlphaFadeOverLifetime.d.ts.map +1 -0
  61. package/dist/esm/modules/AlphaFadeOverLifetime.js +68 -55
  62. package/dist/esm/modules/AlphaFadeOverLifetime.js.map +1 -1
  63. package/dist/esm/modules/ApplyForce.d.ts +4 -3
  64. package/dist/esm/modules/ApplyForce.d.ts.map +1 -0
  65. package/dist/esm/modules/ApplyForce.js +49 -43
  66. package/dist/esm/modules/ApplyForce.js.map +1 -1
  67. package/dist/esm/modules/AttractToPoint.d.ts +4 -3
  68. package/dist/esm/modules/AttractToPoint.d.ts.map +1 -0
  69. package/dist/esm/modules/AttractToPoint.js +73 -62
  70. package/dist/esm/modules/AttractToPoint.js.map +1 -1
  71. package/dist/esm/modules/BurstSpawn.d.ts +6 -18
  72. package/dist/esm/modules/BurstSpawn.d.ts.map +1 -0
  73. package/dist/esm/modules/BurstSpawn.js +56 -91
  74. package/dist/esm/modules/BurstSpawn.js.map +1 -1
  75. package/dist/esm/modules/ColorOverLifetime.d.ts +4 -3
  76. package/dist/esm/modules/ColorOverLifetime.d.ts.map +1 -0
  77. package/dist/esm/modules/ColorOverLifetime.js +65 -53
  78. package/dist/esm/modules/ColorOverLifetime.js.map +1 -1
  79. package/dist/esm/modules/ColorOverSpeed.d.ts +5 -4
  80. package/dist/esm/modules/ColorOverSpeed.d.ts.map +1 -0
  81. package/dist/esm/modules/ColorOverSpeed.js +90 -75
  82. package/dist/esm/modules/ColorOverSpeed.js.map +1 -1
  83. package/dist/esm/modules/DeathModule.d.ts +26 -10
  84. package/dist/esm/modules/DeathModule.d.ts.map +1 -0
  85. package/dist/esm/modules/DeathModule.js +38 -22
  86. package/dist/esm/modules/DeathModule.js.map +1 -1
  87. package/dist/esm/modules/Drag.d.ts +3 -2
  88. package/dist/esm/modules/Drag.d.ts.map +1 -0
  89. package/dist/esm/modules/Drag.js +43 -37
  90. package/dist/esm/modules/Drag.js.map +1 -1
  91. package/dist/esm/modules/OrbitalForce.d.ts +4 -3
  92. package/dist/esm/modules/OrbitalForce.d.ts.map +1 -0
  93. package/dist/esm/modules/OrbitalForce.js +70 -58
  94. package/dist/esm/modules/OrbitalForce.js.map +1 -1
  95. package/dist/esm/modules/RateSpawn.d.ts +7 -22
  96. package/dist/esm/modules/RateSpawn.d.ts.map +1 -0
  97. package/dist/esm/modules/RateSpawn.js +39 -71
  98. package/dist/esm/modules/RateSpawn.js.map +1 -1
  99. package/dist/esm/modules/RepelFromPoint.d.ts +4 -3
  100. package/dist/esm/modules/RepelFromPoint.d.ts.map +1 -0
  101. package/dist/esm/modules/RepelFromPoint.js +72 -62
  102. package/dist/esm/modules/RepelFromPoint.js.map +1 -1
  103. package/dist/esm/modules/RotateOverLifetime.d.ts +3 -2
  104. package/dist/esm/modules/RotateOverLifetime.d.ts.map +1 -0
  105. package/dist/esm/modules/RotateOverLifetime.js +40 -36
  106. package/dist/esm/modules/RotateOverLifetime.js.map +1 -1
  107. package/dist/esm/modules/ScaleOverLifetime.d.ts +5 -4
  108. package/dist/esm/modules/ScaleOverLifetime.d.ts.map +1 -0
  109. package/dist/esm/modules/ScaleOverLifetime.js +60 -50
  110. package/dist/esm/modules/ScaleOverLifetime.js.map +1 -1
  111. package/dist/esm/modules/SpawnModule.d.ts +15 -12
  112. package/dist/esm/modules/SpawnModule.d.ts.map +1 -0
  113. package/dist/esm/modules/SpawnModule.js +32 -28
  114. package/dist/esm/modules/SpawnModule.js.map +1 -1
  115. package/dist/esm/modules/SpawnOnDeath.d.ts +13 -9
  116. package/dist/esm/modules/SpawnOnDeath.d.ts.map +1 -0
  117. package/dist/esm/modules/SpawnOnDeath.js +41 -43
  118. package/dist/esm/modules/SpawnOnDeath.js.map +1 -1
  119. package/dist/esm/modules/Turbulence.d.ts +4 -3
  120. package/dist/esm/modules/Turbulence.d.ts.map +1 -0
  121. package/dist/esm/modules/Turbulence.js +101 -89
  122. package/dist/esm/modules/Turbulence.js.map +1 -1
  123. package/dist/esm/modules/UpdateModule.d.ts +21 -13
  124. package/dist/esm/modules/UpdateModule.d.ts.map +1 -0
  125. package/dist/esm/modules/UpdateModule.js +65 -63
  126. package/dist/esm/modules/UpdateModule.js.map +1 -1
  127. package/dist/esm/modules/VelocityOverLifetime.d.ts +7 -6
  128. package/dist/esm/modules/VelocityOverLifetime.d.ts.map +1 -0
  129. package/dist/esm/modules/VelocityOverLifetime.js +75 -73
  130. package/dist/esm/modules/VelocityOverLifetime.js.map +1 -1
  131. package/dist/esm/modules/WgslContribution.d.ts +16 -15
  132. package/dist/esm/modules/WgslContribution.d.ts.map +1 -0
  133. package/dist/esm/modules/WgslContribution.js +37 -29
  134. package/dist/esm/modules/WgslContribution.js.map +1 -1
  135. package/dist/esm/modules/index.d.ts +3 -1
  136. package/dist/esm/modules/index.d.ts.map +1 -0
  137. package/dist/esm/modules/spawnFields.d.ts +32 -0
  138. package/dist/esm/modules/spawnFields.d.ts.map +1 -0
  139. package/dist/esm/modules/spawnFields.js +31 -0
  140. package/dist/esm/modules/spawnFields.js.map +1 -0
  141. package/dist/esm/particlesBuildInfo.d.ts +1 -0
  142. package/dist/esm/particlesBuildInfo.d.ts.map +1 -0
  143. package/dist/esm/particlesBuildInfo.js +6 -4
  144. package/dist/esm/particlesBuildInfo.js.map +1 -1
  145. package/dist/esm/particlesExtension.d.ts +13 -5
  146. package/dist/esm/particlesExtension.d.ts.map +1 -0
  147. package/dist/esm/particlesExtension.js +38 -42
  148. package/dist/esm/particlesExtension.js.map +1 -1
  149. package/dist/esm/public.d.ts +11 -0
  150. package/dist/esm/public.d.ts.map +1 -0
  151. package/dist/esm/renderModes/MeshParticles.d.ts +128 -0
  152. package/dist/esm/renderModes/MeshParticles.d.ts.map +1 -0
  153. package/dist/esm/renderModes/MeshParticles.js +263 -0
  154. package/dist/esm/renderModes/MeshParticles.js.map +1 -0
  155. package/dist/esm/renderModes/ParticleBufferLayout.d.ts +59 -0
  156. package/dist/esm/renderModes/ParticleBufferLayout.d.ts.map +1 -0
  157. package/dist/esm/renderModes/ParticleBufferLayout.js +99 -0
  158. package/dist/esm/renderModes/ParticleBufferLayout.js.map +1 -0
  159. package/dist/esm/renderModes/ParticleInstanceWriter.d.ts +58 -0
  160. package/dist/esm/renderModes/ParticleInstanceWriter.d.ts.map +1 -0
  161. package/dist/esm/renderModes/ParticleInstanceWriter.js +173 -0
  162. package/dist/esm/renderModes/ParticleInstanceWriter.js.map +1 -0
  163. package/dist/esm/renderModes/ParticleMaterial.d.ts +18 -0
  164. package/dist/esm/renderModes/ParticleMaterial.d.ts.map +1 -0
  165. package/dist/esm/renderModes/ParticleMaterial.js +24 -0
  166. package/dist/esm/renderModes/ParticleMaterial.js.map +1 -0
  167. package/dist/esm/renderModes/ParticleRenderMode.d.ts +114 -0
  168. package/dist/esm/renderModes/ParticleRenderMode.d.ts.map +1 -0
  169. package/dist/esm/renderModes/ParticleRenderMode.js +99 -0
  170. package/dist/esm/renderModes/ParticleRenderMode.js.map +1 -0
  171. package/dist/esm/renderModes/QuadParticles.d.ts +55 -0
  172. package/dist/esm/renderModes/QuadParticles.d.ts.map +1 -0
  173. package/dist/esm/renderModes/QuadParticles.js +95 -0
  174. package/dist/esm/renderModes/QuadParticles.js.map +1 -0
  175. package/dist/esm/renderModes/RibbonParticles.d.ts +96 -0
  176. package/dist/esm/renderModes/RibbonParticles.d.ts.map +1 -0
  177. package/dist/esm/renderModes/RibbonParticles.js +202 -0
  178. package/dist/esm/renderModes/RibbonParticles.js.map +1 -0
  179. package/dist/esm/renderModes/shaders/mesh-particles.wgsl.js +6 -0
  180. package/dist/esm/renderModes/shaders/mesh-particles.wgsl.js.map +1 -0
  181. package/dist/esm/renderModes/shaders/mesh.vert.js +6 -0
  182. package/dist/esm/renderModes/shaders/mesh.vert.js.map +1 -0
  183. package/dist/esm/renderModes/shaders/quad-particles.wgsl.js +6 -0
  184. package/dist/esm/renderModes/shaders/quad-particles.wgsl.js.map +1 -0
  185. package/dist/esm/renderModes/shaders/ribbon-particles.wgsl.js +6 -0
  186. package/dist/esm/renderModes/shaders/ribbon-particles.wgsl.js.map +1 -0
  187. package/dist/esm/renderModes/shaders/ribbon.frag.js +6 -0
  188. package/dist/esm/renderModes/shaders/ribbon.frag.js.map +1 -0
  189. package/dist/esm/renderModes/shaders/ribbon.vert.js +6 -0
  190. package/dist/esm/renderModes/shaders/ribbon.vert.js.map +1 -0
  191. package/dist/esm/renderers/WebGl2ParticleRenderer.d.ts +48 -20
  192. package/dist/esm/renderers/WebGl2ParticleRenderer.d.ts.map +1 -0
  193. package/dist/esm/renderers/WebGl2ParticleRenderer.js +317 -321
  194. package/dist/esm/renderers/WebGl2ParticleRenderer.js.map +1 -1
  195. package/dist/esm/renderers/WebGpuParticleRenderer.d.ts +99 -18
  196. package/dist/esm/renderers/WebGpuParticleRenderer.d.ts.map +1 -0
  197. package/dist/esm/renderers/WebGpuParticleRenderer.js +542 -551
  198. package/dist/esm/renderers/WebGpuParticleRenderer.js.map +1 -1
  199. package/dist/esm/renderers/shaders/particle.frag.js +6 -0
  200. package/dist/esm/renderers/shaders/particle.frag.js.map +1 -0
  201. package/dist/esm/renderers/shaders/particle.vert.js +6 -0
  202. package/dist/esm/renderers/shaders/particle.vert.js.map +1 -0
  203. package/package.json +8 -15
  204. package/dist/esm/index.js.map +0 -1
  205. package/dist/esm/register.d.ts +0 -1
  206. package/dist/esm/register.js +0 -43
  207. package/dist/esm/register.js.map +0 -1
  208. package/dist/esm/renderers/glsl/particle.frag.js +0 -4
  209. package/dist/esm/renderers/glsl/particle.frag.js.map +0 -1
  210. package/dist/esm/renderers/glsl/particle.vert.js +0 -4
  211. package/dist/esm/renderers/glsl/particle.vert.js.map +0 -1
@@ -1,11 +1,11 @@
1
- import type { ParticleSystem } from "#ParticleSystem";
1
+ import type { ParticleBatch } from '#ParticleStorage';
2
2
  import { UpdateModule } from './UpdateModule';
3
3
  import type { WgslContribution } from './WgslContribution';
4
4
  /**
5
5
  * Pulls every live particle toward a fixed point in the system's local
6
6
  * coordinate space. Acceleration magnitude is `strength` (units / s²),
7
7
  * applied along the direction `(point − particle)`. The optional `falloff`
8
- * radius softens the pull near the center particles within `falloff`
8
+ * radius softens the pull near the center - particles within `falloff`
9
9
  * units lerp the strength linearly to zero, preventing the singularity at
10
10
  * `r = 0` from yielding infinite acceleration.
11
11
  *
@@ -21,7 +21,8 @@ export declare class AttractToPoint extends UpdateModule {
21
21
  strength: number;
22
22
  falloff: number;
23
23
  constructor(x: number, y: number, strength: number, falloff?: number);
24
- apply(system: ParticleSystem, dt: number): void;
24
+ apply(particles: ParticleBatch, dt: number): void;
25
25
  wgsl(): WgslContribution;
26
26
  writeUniforms(view: DataView, offset: number): void;
27
27
  }
28
+ //# sourceMappingURL=AttractToPoint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AttractToPoint.d.ts","sourceRoot":"","sources":["../../../src/modules/AttractToPoint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D;;;;;;;;;;;;;GAaG;AACH,qBAAa,cAAe,SAAQ,YAAY;IACvC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;gBAEJ,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,SAAI;IAQtD,KAAK,CAAC,SAAS,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAsBjD,IAAI,IAAI,gBAAgB;IAoBxB,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;CAMpE"}
@@ -1,56 +1,66 @@
1
- import { UpdateModule } from './UpdateModule.js';
1
+ import { UpdateModule } from "./UpdateModule.js";
2
2
 
3
+ //#region src/modules/AttractToPoint.ts
3
4
  /**
4
- * Pulls every live particle toward a fixed point in the system's local
5
- * coordinate space. Acceleration magnitude is `strength` (units / s²),
6
- * applied along the direction `(point − particle)`. The optional `falloff`
7
- * radius softens the pull near the center particles within `falloff`
8
- * units lerp the strength linearly to zero, preventing the singularity at
9
- * `r = 0` from yielding infinite acceleration.
10
- *
11
- * Use cases: orbit anchors, pin emitters to a moving target, simulate a
12
- * "black hole" pickup. For repulsion, use {@link RepelFromPoint}; for
13
- * tangential motion, layer with {@link OrbitalForce}.
14
- *
15
- * GPU-eligible.
16
- */
17
- class AttractToPoint extends UpdateModule {
18
- x;
19
- y;
20
- strength;
21
- falloff;
22
- constructor(x, y, strength, falloff = 0) {
23
- super();
24
- this.x = x;
25
- this.y = y;
26
- this.strength = strength;
27
- this.falloff = falloff;
28
- }
29
- apply(system, dt) {
30
- const { posX, posY, velX, velY, liveCount } = system;
31
- const { x, y, strength, falloff } = this;
32
- for (let i = 0; i < liveCount; i++) {
33
- const dx = x - (posX[i] ?? 0);
34
- const dy = y - (posY[i] ?? 0);
35
- const distSq = dx * dx + dy * dy;
36
- const dist = Math.sqrt(distSq);
37
- if (dist < 1e-5)
38
- continue;
39
- const k = falloff > 0 ? Math.min(1, dist / falloff) : 1;
40
- const a = (strength * k * dt) / dist;
41
- velX[i] = (velX[i] ?? 0) + dx * a;
42
- velY[i] = (velY[i] ?? 0) + dy * a;
43
- }
44
- }
45
- wgsl() {
46
- return {
47
- key: 'AttractToPoint',
48
- uniforms: [
49
- { name: 'point', type: 'vec2<f32>' },
50
- { name: 'strength', type: 'f32' },
51
- { name: 'falloff', type: 'f32' },
52
- ],
53
- body: `
5
+ * Pulls every live particle toward a fixed point in the system's local
6
+ * coordinate space. Acceleration magnitude is `strength` (units / s²),
7
+ * applied along the direction `(point − particle)`. The optional `falloff`
8
+ * radius softens the pull near the center - particles within `falloff`
9
+ * units lerp the strength linearly to zero, preventing the singularity at
10
+ * `r = 0` from yielding infinite acceleration.
11
+ *
12
+ * Use cases: orbit anchors, pin emitters to a moving target, simulate a
13
+ * "black hole" pickup. For repulsion, use {@link RepelFromPoint}; for
14
+ * tangential motion, layer with {@link OrbitalForce}.
15
+ *
16
+ * GPU-eligible.
17
+ */
18
+ var AttractToPoint = class extends UpdateModule {
19
+ x;
20
+ y;
21
+ strength;
22
+ falloff;
23
+ constructor(x, y, strength, falloff = 0) {
24
+ super();
25
+ this.x = x;
26
+ this.y = y;
27
+ this.strength = strength;
28
+ this.falloff = falloff;
29
+ }
30
+ apply(particles, dt) {
31
+ const { x: posX, y: posY } = particles.position;
32
+ const { x: velX, y: velY } = particles.velocity;
33
+ const liveCount = particles.count;
34
+ const { x, y, strength, falloff } = this;
35
+ for (let i = 0; i < liveCount; i++) {
36
+ const dx = x - (posX[i] ?? 0);
37
+ const dy = y - (posY[i] ?? 0);
38
+ const distSq = dx * dx + dy * dy;
39
+ const dist = Math.sqrt(distSq);
40
+ if (dist < 1e-5) continue;
41
+ const a = strength * (falloff > 0 ? Math.min(1, dist / falloff) : 1) * dt / dist;
42
+ velX[i] = (velX[i] ?? 0) + dx * a;
43
+ velY[i] = (velY[i] ?? 0) + dy * a;
44
+ }
45
+ }
46
+ wgsl() {
47
+ return {
48
+ key: "AttractToPoint",
49
+ uniforms: [
50
+ {
51
+ name: "point",
52
+ type: "vec2<f32>"
53
+ },
54
+ {
55
+ name: "strength",
56
+ type: "f32"
57
+ },
58
+ {
59
+ name: "falloff",
60
+ type: "f32"
61
+ }
62
+ ],
63
+ body: `
54
64
  let attractDelta = modules.u_AttractToPoint.point - positions[idx];
55
65
  let attractDist = length(attractDelta);
56
66
  if (attractDist > 0.00001) {
@@ -58,16 +68,17 @@ class AttractToPoint extends UpdateModule {
58
68
  let attractAccel = (modules.u_AttractToPoint.strength * attractK * dt) / attractDist;
59
69
  velocities[idx] = velocities[idx] + attractDelta * attractAccel;
60
70
  }
61
- `,
62
- };
63
- }
64
- writeUniforms(view, offset) {
65
- view.setFloat32(offset + 0, this.x, true);
66
- view.setFloat32(offset + 4, this.y, true);
67
- view.setFloat32(offset + 8, this.strength, true);
68
- view.setFloat32(offset + 12, this.falloff, true);
69
- }
70
- }
71
+ `
72
+ };
73
+ }
74
+ writeUniforms(view, offset) {
75
+ view.setFloat32(offset + 0, this.x, true);
76
+ view.setFloat32(offset + 4, this.y, true);
77
+ view.setFloat32(offset + 8, this.strength, true);
78
+ view.setFloat32(offset + 12, this.falloff, true);
79
+ }
80
+ };
71
81
 
82
+ //#endregion
72
83
  export { AttractToPoint };
73
- //# sourceMappingURL=AttractToPoint.js.map
84
+ //# sourceMappingURL=AttractToPoint.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AttractToPoint.js","sources":["../../../../src/modules/AttractToPoint.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAKA;;;;;;;;;;;;;AAaG;AACG,MAAO,cAAe,SAAQ,YAAY,CAAA;AACvC,IAAA,CAAC;AACD,IAAA,CAAC;AACD,IAAA,QAAQ;AACR,IAAA,OAAO;IAEd,WAAA,CAAmB,CAAS,EAAE,CAAS,EAAE,QAAgB,EAAE,OAAO,GAAG,CAAC,EAAA;AACpE,QAAA,KAAK,EAAE;AACP,QAAA,IAAI,CAAC,CAAC,GAAG,CAAC;AACV,QAAA,IAAI,CAAC,CAAC,GAAG,CAAC;AACV,QAAA,IAAI,CAAC,QAAQ,GAAG,QAAQ;AACxB,QAAA,IAAI,CAAC,OAAO,GAAG,OAAO;IACxB;IAEgB,KAAK,CAAC,MAAsB,EAAE,EAAU,EAAA;AACtD,QAAA,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,MAAM;QACpD,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,IAAI;AAExC,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE;AAClC,YAAA,MAAM,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAC7B,YAAA,MAAM,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC7B,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE;YAChC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;YAE9B,IAAI,IAAI,GAAG,IAAI;gBAAE;YAEjB,MAAM,CAAC,GAAG,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC;YACvD,MAAM,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,GAAG,EAAE,IAAI,IAAI;AAEpC,YAAA,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC;AACjC,YAAA,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC;QACnC;IACF;IAEgB,IAAI,GAAA;QAClB,OAAO;AACL,YAAA,GAAG,EAAE,gBAAgB;AACrB,YAAA,QAAQ,EAAE;AACR,gBAAA,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE;AACpC,gBAAA,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE;AACjC,gBAAA,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE;AACjC,aAAA;AACD,YAAA,IAAI,EAAE;;;;;;;;AAQC,YAAA,CAAA;SACR;IACH;IAEgB,aAAa,CAAC,IAAc,EAAE,MAAc,EAAA;AAC1D,QAAA,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC;AACzC,QAAA,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC;AACzC,QAAA,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC;AAChD,QAAA,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,EAAE,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC;IAClD;AACD;;;;"}
1
+ {"version":3,"file":"AttractToPoint.js","names":[],"sources":["../../../src/modules/AttractToPoint.ts"],"sourcesContent":["import type { ParticleBatch } from '#ParticleStorage';\n\nimport { UpdateModule } from './UpdateModule';\nimport type { WgslContribution } from './WgslContribution';\n\n/**\n * Pulls every live particle toward a fixed point in the system's local\n * coordinate space. Acceleration magnitude is `strength` (units / s²),\n * applied along the direction `(point − particle)`. The optional `falloff`\n * radius softens the pull near the center - particles within `falloff`\n * units lerp the strength linearly to zero, preventing the singularity at\n * `r = 0` from yielding infinite acceleration.\n *\n * Use cases: orbit anchors, pin emitters to a moving target, simulate a\n * \"black hole\" pickup. For repulsion, use {@link RepelFromPoint}; for\n * tangential motion, layer with {@link OrbitalForce}.\n *\n * GPU-eligible.\n */\nexport class AttractToPoint extends UpdateModule {\n public x: number;\n public y: number;\n public strength: number;\n public falloff: number;\n\n public constructor(x: number, y: number, strength: number, falloff = 0) {\n super();\n this.x = x;\n this.y = y;\n this.strength = strength;\n this.falloff = falloff;\n }\n\n public override apply(particles: ParticleBatch, dt: number): void {\n const { x: posX, y: posY } = particles.position;\n const { x: velX, y: velY } = particles.velocity;\n const liveCount = particles.count;\n const { x, y, strength, falloff } = this;\n\n for (let i = 0; i < liveCount; i++) {\n const dx = x - (posX[i] ?? 0);\n const dy = y - (posY[i] ?? 0);\n const distSq = dx * dx + dy * dy;\n const dist = Math.sqrt(distSq);\n\n if (dist < 1e-5) continue;\n\n const k = falloff > 0 ? Math.min(1, dist / falloff) : 1;\n const a = (strength * k * dt) / dist;\n\n velX[i] = (velX[i] ?? 0) + dx * a;\n velY[i] = (velY[i] ?? 0) + dy * a;\n }\n }\n\n public override wgsl(): WgslContribution {\n return {\n key: 'AttractToPoint',\n uniforms: [\n { name: 'point', type: 'vec2<f32>' },\n { name: 'strength', type: 'f32' },\n { name: 'falloff', type: 'f32' },\n ],\n body: `\n let attractDelta = modules.u_AttractToPoint.point - positions[idx];\n let attractDist = length(attractDelta);\n if (attractDist > 0.00001) {\n let attractK = select(1.0, min(1.0, attractDist / max(modules.u_AttractToPoint.falloff, 0.000001)), modules.u_AttractToPoint.falloff > 0.0);\n let attractAccel = (modules.u_AttractToPoint.strength * attractK * dt) / attractDist;\n velocities[idx] = velocities[idx] + attractDelta * attractAccel;\n }\n `,\n };\n }\n\n public override writeUniforms(view: DataView, offset: number): void {\n view.setFloat32(offset + 0, this.x, true);\n view.setFloat32(offset + 4, this.y, true);\n view.setFloat32(offset + 8, this.strength, true);\n view.setFloat32(offset + 12, this.falloff, true);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAmBA,IAAa,iBAAb,cAAoC,aAAa;CAC/C,AAAO;CACP,AAAO;CACP,AAAO;CACP,AAAO;CAEP,AAAO,YAAY,GAAW,GAAW,UAAkB,UAAU,GAAG;EACtE,MAAM;EACN,KAAK,IAAI;EACT,KAAK,IAAI;EACT,KAAK,WAAW;EAChB,KAAK,UAAU;CACjB;CAEA,AAAgB,MAAM,WAA0B,IAAkB;EAChE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,UAAU;EACvC,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,UAAU;EACvC,MAAM,YAAY,UAAU;EAC5B,MAAM,EAAE,GAAG,GAAG,UAAU,YAAY;EAEpC,KAAK,IAAI,IAAI,GAAG,IAAI,WAAW,KAAK;GAClC,MAAM,KAAK,KAAK,KAAK,MAAM;GAC3B,MAAM,KAAK,KAAK,KAAK,MAAM;GAC3B,MAAM,SAAS,KAAK,KAAK,KAAK;GAC9B,MAAM,OAAO,KAAK,KAAK,MAAM;GAE7B,IAAI,OAAO,MAAM;GAGjB,MAAM,IAAK,YADD,UAAU,IAAI,KAAK,IAAI,GAAG,OAAO,OAAO,IAAI,KAC5B,KAAM;GAEhC,KAAK,MAAM,KAAK,MAAM,KAAK,KAAK;GAChC,KAAK,MAAM,KAAK,MAAM,KAAK,KAAK;EAClC;CACF;CAEA,AAAgB,OAAyB;EACvC,OAAO;GACL,KAAK;GACL,UAAU;IACR;KAAE,MAAM;KAAS,MAAM;IAAY;IACnC;KAAE,MAAM;KAAY,MAAM;IAAM;IAChC;KAAE,MAAM;KAAW,MAAM;IAAM;GACjC;GACA,MAAM;;;;;;;;;EASR;CACF;CAEA,AAAgB,cAAc,MAAgB,QAAsB;EAClE,KAAK,WAAW,SAAS,GAAG,KAAK,GAAG,IAAI;EACxC,KAAK,WAAW,SAAS,GAAG,KAAK,GAAG,IAAI;EACxC,KAAK,WAAW,SAAS,GAAG,KAAK,UAAU,IAAI;EAC/C,KAAK,WAAW,SAAS,IAAI,KAAK,SAAS,IAAI;CACjD;AACF"}
@@ -1,7 +1,5 @@
1
- import { Color } from '@codexo/exojs';
2
- import { Vector } from '@codexo/exojs';
3
- import type { Distribution } from "#distributions/Distribution";
4
- import type { ParticleSystem } from "#ParticleSystem";
1
+ import type { ParticleEmitter } from '#ParticleStorage';
2
+ import { type ParticleSpawnFields } from './spawnFields';
5
3
  import { SpawnModule } from './SpawnModule';
6
4
  /**
7
5
  * Burst trigger schedule. The module fires at `time` seconds (since
@@ -11,22 +9,11 @@ export interface BurstSchedule {
11
9
  time: number;
12
10
  count: number;
13
11
  }
14
- /**
15
- * Per-property spawn configuration for {@link BurstSpawn}. Same fields as
16
- * {@link RateSpawnConfig} except no rate — the schedule drives counts.
17
- */
18
- export interface BurstSpawnConfig {
12
+ /** Spawn configuration for {@link BurstSpawn}: the burst schedule plus the shared per-property fields. */
13
+ export interface BurstSpawnConfig extends ParticleSpawnFields {
19
14
  schedule: readonly BurstSchedule[];
20
15
  /** Whether to repeat the schedule from t=0 once exhausted. Default `false`. */
21
16
  loop?: boolean;
22
- lifetime?: Distribution<number>;
23
- position?: Distribution<Vector>;
24
- velocity?: Distribution<Vector>;
25
- scale?: Distribution<Vector>;
26
- rotation?: Distribution<number>;
27
- rotationSpeed?: Distribution<number>;
28
- tint?: Distribution<Color>;
29
- textureIndex?: Distribution<number>;
30
17
  }
31
18
  /**
32
19
  * Discrete-burst spawner. Fires at scheduled times with a fixed count per
@@ -46,8 +33,9 @@ export declare class BurstSpawn extends SpawnModule {
46
33
  private readonly _vec;
47
34
  private readonly _color;
48
35
  constructor(config: BurstSpawnConfig);
49
- apply(system: ParticleSystem, dt: number): void;
36
+ apply(emitter: ParticleEmitter, dt: number): void;
50
37
  /** Restart the schedule from t=0. */
51
38
  reset(): this;
52
39
  private _spawnBurst;
53
40
  }
41
+ //# sourceMappingURL=BurstSpawn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BurstSpawn.d.ts","sourceRoot":"","sources":["../../../src/modules/BurstSpawn.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EAAgB,KAAK,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,0GAA0G;AAC1G,MAAM,WAAW,gBAAiB,SAAQ,mBAAmB;IAC3D,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;IACnC,+EAA+E;IAC/E,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,UAAW,SAAQ,WAAW;IAClC,MAAM,EAAE,gBAAgB,CAAC;IAEhC,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;gBAEnB,MAAM,EAAE,gBAAgB;IAK3B,KAAK,CAAC,OAAO,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAwBjE,qCAAqC;IAC9B,KAAK,IAAI,IAAI;IAOpB,OAAO,CAAC,WAAW;CAWpB"}
@@ -1,95 +1,60 @@
1
- import { Vector, Color } from '@codexo/exojs';
2
- import { SpawnModule } from './SpawnModule.js';
1
+ import { fillParticle } from "./spawnFields.js";
2
+ import { SpawnModule } from "./SpawnModule.js";
3
+ import { Color, Vector } from "@codexo/exojs";
3
4
 
5
+ //#region src/modules/BurstSpawn.ts
4
6
  /**
5
- * Discrete-burst spawner. Fires at scheduled times with a fixed count per
6
- * burst. Useful for explosions, hit-impacts, level-up effects.
7
- *
8
- * @example
9
- * new BurstSpawn({
10
- * schedule: [{ time: 0, count: 50 }, { time: 0.2, count: 25 }],
11
- * velocity: ConeDirection.omni(150, 350),
12
- * lifetime: new Range(0.4, 0.9),
13
- * });
14
- */
15
- class BurstSpawn extends SpawnModule {
16
- config;
17
- _elapsed = 0;
18
- _nextIndex = 0;
19
- _vec = new Vector();
20
- _color = new Color();
21
- constructor(config) {
22
- super();
23
- this.config = config;
24
- }
25
- apply(system, dt) {
26
- const cfg = this.config;
27
- const schedule = cfg.schedule;
28
- if (schedule.length === 0) {
29
- return;
30
- }
31
- this._elapsed += dt;
32
- let next = schedule[this._nextIndex];
33
- while (next !== undefined && this._elapsed >= next.time) {
34
- this._spawnBurst(system, next.count);
35
- this._nextIndex++;
36
- next = schedule[this._nextIndex];
37
- }
38
- if (cfg.loop && this._nextIndex >= schedule.length) {
39
- this._elapsed = 0;
40
- this._nextIndex = 0;
41
- }
42
- }
43
- /** Restart the schedule from t=0. */
44
- reset() {
45
- this._elapsed = 0;
46
- this._nextIndex = 0;
47
- return this;
48
- }
49
- _spawnBurst(system, count) {
50
- const cfg = this.config;
51
- const v = this._vec;
52
- const c = this._color;
53
- for (let i = 0; i < count; i++) {
54
- const slot = system.spawn();
55
- if (slot < 0) {
56
- return;
57
- }
58
- system.lifetime[slot] = cfg.lifetime ? cfg.lifetime.sample() : 1;
59
- if (cfg.position) {
60
- cfg.position.sample(v);
61
- system.posX[slot] = v.x;
62
- system.posY[slot] = v.y;
63
- }
64
- else {
65
- system.posX[slot] = 0;
66
- system.posY[slot] = 0;
67
- }
68
- if (cfg.velocity) {
69
- cfg.velocity.sample(v);
70
- system.velX[slot] = v.x;
71
- system.velY[slot] = v.y;
72
- }
73
- else {
74
- system.velX[slot] = 0;
75
- system.velY[slot] = 0;
76
- }
77
- if (cfg.scale) {
78
- cfg.scale.sample(v);
79
- system.scaleX[slot] = v.x;
80
- system.scaleY[slot] = v.y;
81
- }
82
- else {
83
- system.scaleX[slot] = 1;
84
- system.scaleY[slot] = 1;
85
- }
86
- system.rotations[slot] = cfg.rotation ? cfg.rotation.sample() : 0;
87
- system.rotationSpeeds[slot] = cfg.rotationSpeed ? cfg.rotationSpeed.sample() : 0;
88
- system.color[slot] = cfg.tint ? cfg.tint.sample(c).toRgba() : 0xffffffff;
89
- system.textureIndex[slot] = cfg.textureIndex ? cfg.textureIndex.sample() | 0 : 0;
90
- }
91
- }
92
- }
7
+ * Discrete-burst spawner. Fires at scheduled times with a fixed count per
8
+ * burst. Useful for explosions, hit-impacts, level-up effects.
9
+ *
10
+ * @example
11
+ * new BurstSpawn({
12
+ * schedule: [{ time: 0, count: 50 }, { time: 0.2, count: 25 }],
13
+ * velocity: ConeDirection.omni(150, 350),
14
+ * lifetime: new Range(0.4, 0.9),
15
+ * });
16
+ */
17
+ var BurstSpawn = class extends SpawnModule {
18
+ config;
19
+ _elapsed = 0;
20
+ _nextIndex = 0;
21
+ _vec = new Vector();
22
+ _color = new Color();
23
+ constructor(config) {
24
+ super();
25
+ this.config = config;
26
+ }
27
+ apply(emitter, dt) {
28
+ const cfg = this.config;
29
+ const schedule = cfg.schedule;
30
+ if (schedule.length === 0) return;
31
+ this._elapsed += dt;
32
+ let next = schedule[this._nextIndex];
33
+ while (next !== void 0 && this._elapsed >= next.time) {
34
+ this._spawnBurst(emitter, next.count);
35
+ this._nextIndex++;
36
+ next = schedule[this._nextIndex];
37
+ }
38
+ if (cfg.loop && this._nextIndex >= schedule.length) {
39
+ this._elapsed = 0;
40
+ this._nextIndex = 0;
41
+ }
42
+ }
43
+ /** Restart the schedule from t=0. */
44
+ reset() {
45
+ this._elapsed = 0;
46
+ this._nextIndex = 0;
47
+ return this;
48
+ }
49
+ _spawnBurst(emitter, count) {
50
+ for (let i = 0; i < count; i++) {
51
+ const particle = emitter.emit();
52
+ if (particle === null) return;
53
+ fillParticle(particle, this.config, this._vec, this._color);
54
+ }
55
+ }
56
+ };
93
57
 
58
+ //#endregion
94
59
  export { BurstSpawn };
95
- //# sourceMappingURL=BurstSpawn.js.map
60
+ //# sourceMappingURL=BurstSpawn.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BurstSpawn.js","sources":["../../../../src/modules/BurstSpawn.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BurstSpawn.js","names":[],"sources":["../../../src/modules/BurstSpawn.ts"],"sourcesContent":["import { Color } from '@codexo/exojs';\nimport { Vector } from '@codexo/exojs';\n\nimport type { ParticleEmitter } from '#ParticleStorage';\n\nimport { fillParticle, type ParticleSpawnFields } from './spawnFields';\nimport { SpawnModule } from './SpawnModule';\n\n/**\n * Burst trigger schedule. The module fires at `time` seconds (since\n * registration), spawning `count` particles in one frame.\n */\nexport interface BurstSchedule {\n time: number;\n count: number;\n}\n\n/** Spawn configuration for {@link BurstSpawn}: the burst schedule plus the shared per-property fields. */\nexport interface BurstSpawnConfig extends ParticleSpawnFields {\n schedule: readonly BurstSchedule[];\n /** Whether to repeat the schedule from t=0 once exhausted. Default `false`. */\n loop?: boolean;\n}\n\n/**\n * Discrete-burst spawner. Fires at scheduled times with a fixed count per\n * burst. Useful for explosions, hit-impacts, level-up effects.\n *\n * @example\n * new BurstSpawn({\n * schedule: [{ time: 0, count: 50 }, { time: 0.2, count: 25 }],\n * velocity: ConeDirection.omni(150, 350),\n * lifetime: new Range(0.4, 0.9),\n * });\n */\nexport class BurstSpawn extends SpawnModule {\n public config: BurstSpawnConfig;\n\n private _elapsed = 0;\n private _nextIndex = 0;\n private readonly _vec = new Vector();\n private readonly _color = new Color();\n\n public constructor(config: BurstSpawnConfig) {\n super();\n this.config = config;\n }\n\n public override apply(emitter: ParticleEmitter, dt: number): void {\n const cfg = this.config;\n const schedule = cfg.schedule;\n\n if (schedule.length === 0) {\n return;\n }\n\n this._elapsed += dt;\n\n let next = schedule[this._nextIndex];\n\n while (next !== undefined && this._elapsed >= next.time) {\n this._spawnBurst(emitter, next.count);\n this._nextIndex++;\n next = schedule[this._nextIndex];\n }\n\n if (cfg.loop && this._nextIndex >= schedule.length) {\n this._elapsed = 0;\n this._nextIndex = 0;\n }\n }\n\n /** Restart the schedule from t=0. */\n public reset(): this {\n this._elapsed = 0;\n this._nextIndex = 0;\n\n return this;\n }\n\n private _spawnBurst(emitter: ParticleEmitter, count: number): void {\n for (let i = 0; i < count; i++) {\n const particle = emitter.emit();\n\n if (particle === null) {\n return;\n }\n\n fillParticle(particle, this.config, this._vec, this._color);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAmCA,IAAa,aAAb,cAAgC,YAAY;CAC1C,AAAO;CAEP,AAAQ,WAAW;CACnB,AAAQ,aAAa;CACrB,AAAiB,OAAO,IAAI,OAAO;CACnC,AAAiB,SAAS,IAAI,MAAM;CAEpC,AAAO,YAAY,QAA0B;EAC3C,MAAM;EACN,KAAK,SAAS;CAChB;CAEA,AAAgB,MAAM,SAA0B,IAAkB;EAChE,MAAM,MAAM,KAAK;EACjB,MAAM,WAAW,IAAI;EAErB,IAAI,SAAS,WAAW,GACtB;EAGF,KAAK,YAAY;EAEjB,IAAI,OAAO,SAAS,KAAK;EAEzB,OAAO,SAAS,UAAa,KAAK,YAAY,KAAK,MAAM;GACvD,KAAK,YAAY,SAAS,KAAK,KAAK;GACpC,KAAK;GACL,OAAO,SAAS,KAAK;EACvB;EAEA,IAAI,IAAI,QAAQ,KAAK,cAAc,SAAS,QAAQ;GAClD,KAAK,WAAW;GAChB,KAAK,aAAa;EACpB;CACF;;CAGA,AAAO,QAAc;EACnB,KAAK,WAAW;EAChB,KAAK,aAAa;EAElB,OAAO;CACT;CAEA,AAAQ,YAAY,SAA0B,OAAqB;EACjE,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KAAK;GAC9B,MAAM,WAAW,QAAQ,KAAK;GAE9B,IAAI,aAAa,MACf;GAGF,aAAa,UAAU,KAAK,QAAQ,KAAK,MAAM,KAAK,MAAM;EAC5D;CACF;AACF"}
@@ -1,5 +1,5 @@
1
- import type { ColorGradient } from "#distributions/ColorGradient";
2
- import type { ParticleSystem } from "#ParticleSystem";
1
+ import type { ColorGradient } from '#distributions/ColorGradient';
2
+ import type { ParticleBatch } from '#ParticleStorage';
3
3
  import { UpdateModule } from './UpdateModule';
4
4
  import type { WgslContribution } from './WgslContribution';
5
5
  /**
@@ -14,9 +14,10 @@ import type { WgslContribution } from './WgslContribution';
14
14
  export declare class ColorOverLifetime extends UpdateModule {
15
15
  gradient: ColorGradient;
16
16
  constructor(gradient: ColorGradient);
17
- apply(system: ParticleSystem, _dt: number): void;
17
+ apply(particles: ParticleBatch, _dt: number): void;
18
18
  wgsl(): WgslContribution;
19
19
  uploadTextures(device: GPUDevice, textures: ReadonlyMap<string, GPUTexture>): void;
20
20
  }
21
21
  /** Texture width for the gradient lookup table. Exposed for ParticleGpuState. */
22
22
  export declare const colorLookupSize = 256;
23
+ //# sourceMappingURL=ColorOverLifetime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ColorOverLifetime.d.ts","sourceRoot":"","sources":["../../../src/modules/ColorOverLifetime.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAI3D;;;;;;;;GAQG;AACH,qBAAa,iBAAkB,SAAQ,YAAY;IAC1C,QAAQ,EAAE,aAAa,CAAC;gBAEZ,QAAQ,EAAE,aAAa;IAK1B,KAAK,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAalD,IAAI,IAAI,gBAAgB;IAgBxB,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,IAAI;CA8BnG;AAED,iFAAiF;AACjF,eAAO,MAAM,eAAe,MAAa,CAAC"}
@@ -1,36 +1,41 @@
1
- import { Color } from '@codexo/exojs';
2
- import { UpdateModule } from './UpdateModule.js';
1
+ import { UpdateModule } from "./UpdateModule.js";
2
+ import { Color } from "@codexo/exojs";
3
3
 
4
- /// <reference types="@webgpu/types" />
4
+ //#region src/modules/ColorOverLifetime.ts
5
5
  const lookupSize = 256;
6
6
  /**
7
- * Per-frame, per-particle color sampler. Each live particle's tint is set
8
- * to the gradient evaluated at the particle's current `elapsed / lifetime`
9
- * ratio, packed RGBA. Replaces the per-particle blend of `ColorAffector`
10
- * (legacy) with a multi-keyframe gradient.
11
- *
12
- * GPU-eligible: the gradient is uploaded once as a 256-tap 1D RGBA8 texture
13
- * and sampled with linear filtering on the GPU.
14
- */
15
- class ColorOverLifetime extends UpdateModule {
16
- gradient;
17
- constructor(gradient) {
18
- super();
19
- this.gradient = gradient;
20
- }
21
- apply(system, _dt) {
22
- const { color, elapsed, lifetime, liveCount } = system;
23
- const gradient = this.gradient;
24
- for (let i = 0; i < liveCount; i++) {
25
- const t = (elapsed[i] ?? 0) / (lifetime[i] ?? 1);
26
- color[i] = gradient.evaluateRgba(t);
27
- }
28
- }
29
- wgsl() {
30
- return {
31
- key: 'ColorOverLifetime',
32
- textures: [{ name: 'gradient', format: 'rgba8unorm' }],
33
- body: `
7
+ * Per-frame, per-particle color sampler. Each live particle's tint is set
8
+ * to the gradient evaluated at the particle's current `elapsed / lifetime`
9
+ * ratio, packed RGBA. Replaces the per-particle blend of `ColorAffector`
10
+ * (legacy) with a multi-keyframe gradient.
11
+ *
12
+ * GPU-eligible: the gradient is uploaded once as a 256-tap 1D RGBA8 texture
13
+ * and sampled with linear filtering on the GPU.
14
+ */
15
+ var ColorOverLifetime = class extends UpdateModule {
16
+ gradient;
17
+ constructor(gradient) {
18
+ super();
19
+ this.gradient = gradient;
20
+ }
21
+ apply(particles, _dt) {
22
+ const { elapsed, lifetime } = particles.timing;
23
+ const color = particles.color;
24
+ const liveCount = particles.count;
25
+ const gradient = this.gradient;
26
+ for (let i = 0; i < liveCount; i++) {
27
+ const t = (elapsed[i] ?? 0) / (lifetime[i] ?? 1);
28
+ color[i] = gradient.evaluateRgba(t);
29
+ }
30
+ }
31
+ wgsl() {
32
+ return {
33
+ key: "ColorOverLifetime",
34
+ textures: [{
35
+ name: "gradient",
36
+ format: "rgba8unorm"
37
+ }],
38
+ body: `
34
39
  let colorT = clamp(timing[idx].x / max(timing[idx].y, 0.000001), 0.0, 1.0);
35
40
  let colorSample = textureSampleLevel(u_ColorOverLifetime_gradient, u_ColorOverLifetime_gradient_sampler, colorT, 0.0);
36
41
  let r = u32(colorSample.r * 255.0) & 255u;
@@ -38,28 +43,35 @@ class ColorOverLifetime extends UpdateModule {
38
43
  let b = u32(colorSample.b * 255.0) & 255u;
39
44
  let a = u32(colorSample.a * 255.0) & 255u;
40
45
  color[idx] = (a << 24u) | (b << 16u) | (g << 8u) | r;
41
- `,
42
- };
43
- }
44
- uploadTextures(device, textures) {
45
- const texture = textures.get('gradient');
46
- if (texture === undefined) {
47
- return;
48
- }
49
- const data = new Uint8Array(lookupSize * 4);
50
- const scratch = new Color();
51
- for (let i = 0; i < lookupSize; i++) {
52
- const t = i / (lookupSize - 1);
53
- this.gradient.evaluate(t, scratch);
54
- const o = i * 4;
55
- data[o + 0] = scratch.r & 255;
56
- data[o + 1] = scratch.g & 255;
57
- data[o + 2] = scratch.b & 255;
58
- data[o + 3] = ((scratch.a * 255) | 0) & 255;
59
- }
60
- device.queue.writeTexture({ texture }, data.buffer, { offset: 0, bytesPerRow: lookupSize * 4, rowsPerImage: 1 }, { width: lookupSize, height: 1, depthOrArrayLayers: 1 });
61
- }
62
- }
46
+ `
47
+ };
48
+ }
49
+ uploadTextures(device, textures) {
50
+ const texture = textures.get("gradient");
51
+ if (texture === void 0) return;
52
+ const data = new Uint8Array(lookupSize * 4);
53
+ const scratch = new Color();
54
+ for (let i = 0; i < lookupSize; i++) {
55
+ const t = i / 255;
56
+ this.gradient.evaluate(t, scratch);
57
+ const o = i * 4;
58
+ data[o + 0] = scratch.r & 255;
59
+ data[o + 1] = scratch.g & 255;
60
+ data[o + 2] = scratch.b & 255;
61
+ data[o + 3] = (scratch.a * 255 | 0) & 255;
62
+ }
63
+ device.queue.writeTexture({ texture }, data.buffer, {
64
+ offset: 0,
65
+ bytesPerRow: lookupSize * 4,
66
+ rowsPerImage: 1
67
+ }, {
68
+ width: lookupSize,
69
+ height: 1,
70
+ depthOrArrayLayers: 1
71
+ });
72
+ }
73
+ };
63
74
 
75
+ //#endregion
64
76
  export { ColorOverLifetime };
65
- //# sourceMappingURL=ColorOverLifetime.js.map
77
+ //# sourceMappingURL=ColorOverLifetime.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ColorOverLifetime.js","sources":["../../../../src/modules/ColorOverLifetime.ts"],"sourcesContent":[null],"names":[],"mappings":";;;AAAA;AAUA,MAAM,UAAU,GAAG,GAAG;AAEtB;;;;;;;;AAQG;AACG,MAAO,iBAAkB,SAAQ,YAAY,CAAA;AAC1C,IAAA,QAAQ;AAEf,IAAA,WAAA,CAAmB,QAAuB,EAAA;AACxC,QAAA,KAAK,EAAE;AACP,QAAA,IAAI,CAAC,QAAQ,GAAG,QAAQ;IAC1B;IAEgB,KAAK,CAAC,MAAsB,EAAE,GAAW,EAAA;QACvD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM;AACtD,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ;AAE9B,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE;AAClC,YAAA,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAEhD,KAAK,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;QACrC;IACF;IAEgB,IAAI,GAAA;QAClB,OAAO;AACL,YAAA,GAAG,EAAE,mBAAmB;YACxB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;AACtD,YAAA,IAAI,EAAE;;;;;;;;AAQC,YAAA,CAAA;SACR;IACH;IAEgB,cAAc,CAAC,MAAiB,EAAE,QAAyC,EAAA;QACzF,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC;AAExC,QAAA,IAAI,OAAO,KAAK,SAAS,EAAE;YACzB;QACF;QAEA,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,UAAU,GAAG,CAAC,CAAC;AAC3C,QAAA,MAAM,OAAO,GAAG,IAAI,KAAK,EAAE;AAE3B,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE;YACnC,MAAM,CAAC,GAAG,CAAC,IAAI,UAAU,GAAG,CAAC,CAAC;YAE9B,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC;AAElC,YAAA,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;YAEf,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,GAAG;YAC7B,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,GAAG;YAC7B,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,GAAG;AAC7B,YAAA,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,GAAG;QAC7C;AAEA,QAAA,MAAM,CAAC,KAAK,CAAC,YAAY,CACvB,EAAE,OAAO,EAAE,EACX,IAAI,CAAC,MAAM,EACX,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,UAAU,GAAG,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,EAC3D,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,EAAE,kBAAkB,EAAE,CAAC,EAAE,CACxD;IACH;AACD;;;;"}
1
+ {"version":3,"file":"ColorOverLifetime.js","names":[],"sources":["../../../src/modules/ColorOverLifetime.ts"],"sourcesContent":["/// <reference types=\"@webgpu/types\" />\n\nimport { Color } from '@codexo/exojs';\n\nimport type { ColorGradient } from '#distributions/ColorGradient';\nimport type { ParticleBatch } from '#ParticleStorage';\n\nimport { UpdateModule } from './UpdateModule';\nimport type { WgslContribution } from './WgslContribution';\n\nconst lookupSize = 256;\n\n/**\n * Per-frame, per-particle color sampler. Each live particle's tint is set\n * to the gradient evaluated at the particle's current `elapsed / lifetime`\n * ratio, packed RGBA. Replaces the per-particle blend of `ColorAffector`\n * (legacy) with a multi-keyframe gradient.\n *\n * GPU-eligible: the gradient is uploaded once as a 256-tap 1D RGBA8 texture\n * and sampled with linear filtering on the GPU.\n */\nexport class ColorOverLifetime extends UpdateModule {\n public gradient: ColorGradient;\n\n public constructor(gradient: ColorGradient) {\n super();\n this.gradient = gradient;\n }\n\n public override apply(particles: ParticleBatch, _dt: number): void {\n const { elapsed, lifetime } = particles.timing;\n const color = particles.color;\n const liveCount = particles.count;\n const gradient = this.gradient;\n\n for (let i = 0; i < liveCount; i++) {\n const t = (elapsed[i] ?? 0) / (lifetime[i] ?? 1);\n\n color[i] = gradient.evaluateRgba(t);\n }\n }\n\n public override wgsl(): WgslContribution {\n return {\n key: 'ColorOverLifetime',\n textures: [{ name: 'gradient', format: 'rgba8unorm' }],\n body: `\n let colorT = clamp(timing[idx].x / max(timing[idx].y, 0.000001), 0.0, 1.0);\n let colorSample = textureSampleLevel(u_ColorOverLifetime_gradient, u_ColorOverLifetime_gradient_sampler, colorT, 0.0);\n let r = u32(colorSample.r * 255.0) & 255u;\n let g = u32(colorSample.g * 255.0) & 255u;\n let b = u32(colorSample.b * 255.0) & 255u;\n let a = u32(colorSample.a * 255.0) & 255u;\n color[idx] = (a << 24u) | (b << 16u) | (g << 8u) | r;\n `,\n };\n }\n\n public override uploadTextures(device: GPUDevice, textures: ReadonlyMap<string, GPUTexture>): void {\n const texture = textures.get('gradient');\n\n if (texture === undefined) {\n return;\n }\n\n const data = new Uint8Array(lookupSize * 4);\n const scratch = new Color();\n\n for (let i = 0; i < lookupSize; i++) {\n const t = i / (lookupSize - 1);\n\n this.gradient.evaluate(t, scratch);\n\n const o = i * 4;\n\n data[o + 0] = scratch.r & 255;\n data[o + 1] = scratch.g & 255;\n data[o + 2] = scratch.b & 255;\n data[o + 3] = ((scratch.a * 255) | 0) & 255;\n }\n\n device.queue.writeTexture(\n { texture },\n data.buffer,\n { offset: 0, bytesPerRow: lookupSize * 4, rowsPerImage: 1 },\n { width: lookupSize, height: 1, depthOrArrayLayers: 1 },\n );\n }\n}\n\n/** Texture width for the gradient lookup table. Exposed for ParticleGpuState. */\nexport const colorLookupSize = lookupSize;\n"],"mappings":";;;;AAUA,MAAM,aAAa;;;;;;;;;;AAWnB,IAAa,oBAAb,cAAuC,aAAa;CAClD,AAAO;CAEP,AAAO,YAAY,UAAyB;EAC1C,MAAM;EACN,KAAK,WAAW;CAClB;CAEA,AAAgB,MAAM,WAA0B,KAAmB;EACjE,MAAM,EAAE,SAAS,aAAa,UAAU;EACxC,MAAM,QAAQ,UAAU;EACxB,MAAM,YAAY,UAAU;EAC5B,MAAM,WAAW,KAAK;EAEtB,KAAK,IAAI,IAAI,GAAG,IAAI,WAAW,KAAK;GAClC,MAAM,KAAK,QAAQ,MAAM,MAAM,SAAS,MAAM;GAE9C,MAAM,KAAK,SAAS,aAAa,CAAC;EACpC;CACF;CAEA,AAAgB,OAAyB;EACvC,OAAO;GACL,KAAK;GACL,UAAU,CAAC;IAAE,MAAM;IAAY,QAAQ;GAAa,CAAC;GACrD,MAAM;;;;;;;;;EASR;CACF;CAEA,AAAgB,eAAe,QAAmB,UAAiD;EACjG,MAAM,UAAU,SAAS,IAAI,UAAU;EAEvC,IAAI,YAAY,QACd;EAGF,MAAM,OAAO,IAAI,WAAW,aAAa,CAAC;EAC1C,MAAM,UAAU,IAAI,MAAM;EAE1B,KAAK,IAAI,IAAI,GAAG,IAAI,YAAY,KAAK;GACnC,MAAM,IAAI,IAAK;GAEf,KAAK,SAAS,SAAS,GAAG,OAAO;GAEjC,MAAM,IAAI,IAAI;GAEd,KAAK,IAAI,KAAK,QAAQ,IAAI;GAC1B,KAAK,IAAI,KAAK,QAAQ,IAAI;GAC1B,KAAK,IAAI,KAAK,QAAQ,IAAI;GAC1B,KAAK,IAAI,MAAO,QAAQ,IAAI,MAAO,KAAK;EAC1C;EAEA,OAAO,MAAM,aACX,EAAE,QAAQ,GACV,KAAK,QACL;GAAE,QAAQ;GAAG,aAAa,aAAa;GAAG,cAAc;EAAE,GAC1D;GAAE,OAAO;GAAY,QAAQ;GAAG,oBAAoB;EAAE,CACxD;CACF;AACF"}