sparcoon 0.0.8 → 0.2.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 (90) hide show
  1. package/dist/{elements → emitter}/FXEmitter.Internal.d.ts +2 -4
  2. package/dist/{elements → emitter}/FXEmitter.Internal.js +3 -1
  3. package/dist/{elements → emitter}/FXEmitter.d.ts +8 -8
  4. package/dist/{elements → emitter}/FXEmitter.js +21 -18
  5. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorDirectionalGravity.d.ts +2 -2
  6. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorDirectionalGravity.js +2 -2
  7. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorModule.d.ts +1 -1
  8. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorPointGravity.d.ts +2 -2
  9. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorPointGravity.js +2 -2
  10. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorScaleOverLife.d.ts +1 -1
  11. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorScaleOverLife.js +2 -2
  12. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorTorqueDamping.d.ts +1 -1
  13. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorTorqueDamping.js +2 -2
  14. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorTorqueNoise.d.ts +1 -1
  15. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorTorqueNoise.js +3 -3
  16. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorVelocityDamping.d.ts +1 -1
  17. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorVelocityDamping.js +2 -2
  18. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorVelocityNoise.d.ts +1 -1
  19. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorVelocityNoise.js +3 -3
  20. package/dist/{spawnModules → emitter/spawn}/FXSpawnBox.d.ts +2 -2
  21. package/dist/{spawnModules → emitter/spawn}/FXSpawnBox.js +2 -2
  22. package/dist/{spawnModules → emitter/spawn}/FXSpawnModule.d.ts +1 -1
  23. package/dist/{spawnModules → emitter/spawn}/FXSpawnOffset.d.ts +2 -2
  24. package/dist/{spawnModules → emitter/spawn}/FXSpawnOffset.js +2 -2
  25. package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomLifetime.d.ts +1 -1
  26. package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomLifetime.js +2 -2
  27. package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomRotation.d.ts +1 -1
  28. package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomRotation.js +2 -2
  29. package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomScale.d.ts +1 -1
  30. package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomScale.js +2 -2
  31. package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomTorque.d.ts +1 -1
  32. package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomTorque.js +2 -2
  33. package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomVelocity.d.ts +1 -1
  34. package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomVelocity.js +2 -2
  35. package/dist/emitter/spawn/FXSpawnSphere.d.ts +38 -0
  36. package/dist/emitter/spawn/FXSpawnSphere.js +89 -0
  37. package/dist/index.d.ts +24 -20
  38. package/dist/index.js +25 -20
  39. package/dist/instancedParticle/FXInstancedParticle.Internal.d.ts +2 -9
  40. package/dist/instancedParticle/FXInstancedParticle.Internal.js +2 -187
  41. package/dist/instancedParticle/FXInstancedParticle.d.ts +4 -4
  42. package/dist/instancedParticle/FXInstancedParticle.js +5 -6
  43. package/dist/instancedParticle/shared.d.ts +1 -1
  44. package/dist/instancedParticle/shared.js +1 -1
  45. package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.Internal.d.ts +9 -0
  46. package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.Internal.js +108 -0
  47. package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.d.ts +15 -0
  48. package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.js +18 -0
  49. package/dist/materials/FXMaterial.Internal.d.ts +4 -0
  50. package/dist/materials/FXMaterial.Internal.js +106 -0
  51. package/dist/materials/FXMaterial.d.ts +14 -0
  52. package/dist/materials/FXMaterial.js +21 -0
  53. package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.Internal.d.ts +4 -0
  54. package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.Internal.js +80 -0
  55. package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.d.ts +11 -0
  56. package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.js +17 -0
  57. package/dist/materials/color-nodes/FXAnimatedTextureNode.d.ts +10 -0
  58. package/dist/materials/color-nodes/FXAnimatedTextureNode.js +41 -0
  59. package/dist/materials/color-nodes/FXColorNode.d.ts +3 -0
  60. package/dist/materials/color-nodes/FXColorNode.js +8 -0
  61. package/dist/materials/color-nodes/FXColorOverLifeNode.d.ts +7 -0
  62. package/dist/materials/color-nodes/FXColorOverLifeNode.js +38 -0
  63. package/dist/materials/color-nodes/FXStaticTextureNode.d.ts +5 -0
  64. package/dist/materials/color-nodes/FXStaticTextureNode.js +23 -0
  65. package/dist/materials/miscellaneous.d.ts +1 -0
  66. package/dist/materials/miscellaneous.js +25 -0
  67. package/dist/{color → miscellaneous/color}/FXColor.js +2 -2
  68. package/dist/miscellaneous/miscellaneous.d.ts +1 -1
  69. package/package.json +1 -1
  70. package/dist/miscellaneous/texture/FXTextureView.Internal.js +0 -6
  71. package/dist/miscellaneous/texture/FXTextureView.js +0 -234
  72. package/dist/renderingModules/FXRenderingAnimatedTexture.d.ts +0 -5
  73. package/dist/renderingModules/FXRenderingAnimatedTexture.js +0 -14
  74. package/dist/renderingModules/FXRenderingColorOverLife.d.ts +0 -14
  75. package/dist/renderingModules/FXRenderingColorOverLife.js +0 -32
  76. package/dist/renderingModules/FXRenderingColorOverVelocity.d.ts +0 -15
  77. package/dist/renderingModules/FXRenderingColorOverVelocity.js +0 -37
  78. package/dist/renderingModules/FXRenderingModule.d.ts +0 -8
  79. package/dist/renderingModules/FXRenderingModule.js +0 -9
  80. package/dist/renderingModules/FXRenderingTexture.d.ts +0 -14
  81. package/dist/renderingModules/FXRenderingTexture.js +0 -26
  82. package/dist/shaders/FXRenderingAnimatedTexture.glsl.js +0 -3
  83. package/dist/shaders/FXRenderingColorOverLife.glsl.js +0 -3
  84. package/dist/shaders/FXRenderingColorOverVelocity.glsl.js +0 -3
  85. package/dist/shaders/FXRenderingTexture.glsl.js +0 -3
  86. /package/dist/{behaviorModules → emitter/behavior}/FXBehaviorModule.js +0 -0
  87. /package/dist/{spawnModules → emitter/spawn}/FXSpawnModule.js +0 -0
  88. /package/dist/{color → miscellaneous/color}/FXColor.Internal.d.ts +0 -0
  89. /package/dist/{color → miscellaneous/color}/FXColor.Internal.js +0 -0
  90. /package/dist/{color → miscellaneous/color}/FXColor.d.ts +0 -0
@@ -0,0 +1,80 @@
1
+ import { MeshBasicMaterial, DoubleSide } from 'three';
2
+ import { PARTICLE_DEFINES } from '../miscellaneous.js';
3
+
4
+ function buildFXUnlitMaterial(varyings, blending, useAlphaHashing, colorNodes) {
5
+ const attributeDeclarations = [];
6
+ const varyingDeclarations = [];
7
+ const vertexAssignments = [];
8
+ for (const name in varyings) {
9
+ const { glslTypeName } = varyings[name];
10
+ attributeDeclarations.push(`attribute ${glslTypeName} a_${name};`);
11
+ varyingDeclarations.push(`varying ${glslTypeName} p_${name};`);
12
+ vertexAssignments.push(`p_${name} = a_${name};`);
13
+ }
14
+ const material = new MeshBasicMaterial({
15
+ transparent: !useAlphaHashing,
16
+ depthWrite: useAlphaHashing,
17
+ depthTest: true,
18
+ alphaHash: useAlphaHashing,
19
+ blending,
20
+ side: DoubleSide,
21
+ forceSinglePass: true,
22
+ alphaTest: 1 / 255,
23
+ });
24
+ material.onBeforeCompile = (shader) => {
25
+ const vertexPreamble = [
26
+ PARTICLE_DEFINES,
27
+ attributeDeclarations.join("\n"),
28
+ "varying vec2 p_uv;",
29
+ varyingDeclarations.join("\n"),
30
+ ].join("\n");
31
+ shader.vertexShader =
32
+ vertexPreamble +
33
+ "\n" +
34
+ shader.vertexShader
35
+ .replace("#include <begin_vertex>", [
36
+ "p_uv = uv;",
37
+ vertexAssignments.join("\n"),
38
+ "vec3 transformed = position;",
39
+ "#ifdef USE_ALPHAHASH",
40
+ " vPosition = vec3(PARTICLE_POSITION_X, PARTICLE_POSITION_Y, PARTICLE_POSITION_Z) + vec3(position.xy, 0.0);",
41
+ "#endif",
42
+ ].join("\n"))
43
+ .replace("#include <project_vertex>", `
44
+ vec2 p_bp = position.xy;
45
+ p_bp.x *= PARTICLE_SCALE_X;
46
+ p_bp.y *= PARTICLE_SCALE_Y;
47
+ float p_cosR = cos(PARTICLE_ROTATION);
48
+ float p_sinR = sin(PARTICLE_ROTATION);
49
+ p_bp = vec2(
50
+ p_bp.x * p_cosR - p_bp.y * p_sinR,
51
+ p_bp.x * p_sinR + p_bp.y * p_cosR
52
+ );
53
+ vec3 p_c = vec3(PARTICLE_POSITION_X, PARTICLE_POSITION_Y, PARTICLE_POSITION_Z);
54
+ vec4 mvPosition = modelViewMatrix * vec4(p_c, 1.0);
55
+ mvPosition.xy += p_bp;
56
+ gl_Position = projectionMatrix * mvPosition;
57
+ `);
58
+ const fragmentPreamble = [
59
+ PARTICLE_DEFINES,
60
+ "varying vec2 p_uv;",
61
+ varyingDeclarations.join("\n"),
62
+ colorNodes.flatMap((n) => n.uniformDeclarations).join("\n"),
63
+ colorNodes.map((n) => n.helperFunctions).join("\n"),
64
+ ].join("\n");
65
+ for (const node of colorNodes) {
66
+ Object.assign(shader.uniforms, node.uniforms);
67
+ }
68
+ let fragmentShader = shader.fragmentShader;
69
+ if (colorNodes.length > 0) {
70
+ const combinedExpression = colorNodes.map((n) => n.colorExpression).join(" * ");
71
+ const discardLine = useAlphaHashing ? "" : "if (diffuseColor.a < 0.0035) discard;";
72
+ fragmentShader = fragmentShader.replace("#include <map_fragment>", `diffuseColor = ${combinedExpression}; ${discardLine}`);
73
+ }
74
+ shader.fragmentShader = fragmentPreamble + "\n" + fragmentShader;
75
+ };
76
+ material.customProgramCacheKey = () => `fx-unlit-${colorNodes.map((n) => n.cacheKey).join("-") || "none"}`;
77
+ return material;
78
+ }
79
+
80
+ export { buildFXUnlitMaterial };
@@ -0,0 +1,11 @@
1
+ import { type Blending } from "three";
2
+ import { FXMaterial, type FXMaterialOptions } from "../FXMaterial";
3
+ export interface FXUnlitMaterialOptions extends FXMaterialOptions {
4
+ blending: Blending;
5
+ useAlphaHashing: boolean;
6
+ }
7
+ export declare class FXUnlitMaterial extends FXMaterial {
8
+ private readonly blending;
9
+ private readonly useAlphaHashing;
10
+ constructor(options?: Partial<FXUnlitMaterialOptions>);
11
+ }
@@ -0,0 +1,17 @@
1
+ import { NormalBlending } from 'three';
2
+ import { FXMaterial } from '../FXMaterial.js';
3
+ import { buildFXUnlitMaterial } from './FXUnlitMaterial.Internal.js';
4
+
5
+ class FXUnlitMaterial extends FXMaterial {
6
+ constructor(options = {}) {
7
+ super(options);
8
+ this._private_blending = options.blending ?? NormalBlending;
9
+ this._private_useAlphaHashing = options.useAlphaHashing ?? false;
10
+ }
11
+ /** @internal */
12
+ buildThreeMaterial(varyings) {
13
+ return buildFXUnlitMaterial(varyings, this._private_blending, this._private_useAlphaHashing, this.colorNodes);
14
+ }
15
+ }
16
+
17
+ export { FXUnlitMaterial };
@@ -0,0 +1,10 @@
1
+ import type { Texture } from "three";
2
+ import { FXColorNode } from "./FXColorNode";
3
+ export interface FXAnimatedTextureNodeOptions {
4
+ texture: Texture;
5
+ cols: number;
6
+ rows: number;
7
+ }
8
+ export declare class FXAnimatedTextureNode extends FXColorNode {
9
+ constructor({ texture, cols, rows }: FXAnimatedTextureNodeOptions);
10
+ }
@@ -0,0 +1,41 @@
1
+ import { FXColorNode } from './FXColorNode.js';
2
+
3
+ class FXAnimatedTextureNode extends FXColorNode {
4
+ constructor({ texture, cols, rows }) {
5
+ super();
6
+ /** @internal */
7
+ this.cacheKey = "animated";
8
+ /** @internal */
9
+ this.uniformDeclarations = [
10
+ "uniform sampler2D u_AnimatedTexture;",
11
+ "uniform float u_AnimatedTextureCols;",
12
+ "uniform float u_AnimatedTextureRows;",
13
+ ];
14
+ /** @internal */
15
+ this.helperFunctions = `
16
+ vec4 _fx_sampleAnimated(sampler2D tex, vec2 uv, float cols, float rows) {
17
+ float totalFrames = cols * rows;
18
+ float frame = floor(PARTICLE_AGE / PARTICLE_LIFETIME * totalFrames);
19
+ frame = clamp(frame, 0.0, totalFrames - 1.0);
20
+ float col = mod(frame, cols);
21
+ float row = floor(frame / cols);
22
+ vec2 frameUV = vec2((col + uv.x) / cols, 1.0 - (row + 1.0 - uv.y) / rows);
23
+ return texture2D(tex, frameUV);
24
+ }
25
+ `;
26
+ /** @internal */
27
+ this.colorExpression = "_fx_sampleAnimated(u_AnimatedTexture, p_uv, u_AnimatedTextureCols, u_AnimatedTextureRows)";
28
+ /** @internal */
29
+ this.affectsDepth = true;
30
+ this.uniforms = {
31
+ // eslint-disable-next-line @typescript-eslint/naming-convention
32
+ u_AnimatedTexture: { value: texture },
33
+ // eslint-disable-next-line @typescript-eslint/naming-convention
34
+ u_AnimatedTextureCols: { value: cols },
35
+ // eslint-disable-next-line @typescript-eslint/naming-convention
36
+ u_AnimatedTextureRows: { value: rows },
37
+ };
38
+ }
39
+ }
40
+
41
+ export { FXAnimatedTextureNode };
@@ -0,0 +1,3 @@
1
+ export declare abstract class FXColorNode {
2
+ destroy?(): void;
3
+ }
@@ -0,0 +1,8 @@
1
+ class FXColorNode {
2
+ constructor() {
3
+ /** @internal */
4
+ this.affectsDepth = false;
5
+ }
6
+ }
7
+
8
+ export { FXColorNode };
@@ -0,0 +1,7 @@
1
+ import type { FXColor } from "../../miscellaneous/color/FXColor";
2
+ import { FXColorNode } from "./FXColorNode";
3
+ export declare class FXColorOverLifeNode extends FXColorNode {
4
+ private readonly gradientTexture;
5
+ constructor(colors: FXColor[]);
6
+ destroy(): void;
7
+ }
@@ -0,0 +1,38 @@
1
+ import { buildGradientTexture } from '../../miscellaneous/miscellaneous.js';
2
+ import { checkSRGBSupport } from '../../miscellaneous/webglCapabilities.js';
3
+ import { FXColorNode } from './FXColorNode.js';
4
+
5
+ class FXColorOverLifeNode extends FXColorNode {
6
+ constructor(colors) {
7
+ if (colors.length === 0) {
8
+ throw new Error("FXColorOverLifeNode: colors array cannot be empty");
9
+ }
10
+ super();
11
+ /** @internal */
12
+ this.affectsDepth = true;
13
+ /** @internal */
14
+ this.cacheKey = "color-over-life";
15
+ /** @internal */
16
+ this.uniformDeclarations = ["uniform sampler2D u_ColorOverLife;"];
17
+ /** @internal */
18
+ this.colorExpression = "_fx_sampleColorOverLife(u_ColorOverLife)";
19
+ this._private_gradientTexture = buildGradientTexture(colors);
20
+ this.uniforms = {
21
+ // eslint-disable-next-line @typescript-eslint/naming-convention
22
+ u_ColorOverLife: { value: this._private_gradientTexture },
23
+ };
24
+ this.helperFunctions = `
25
+ vec4 _fx_sampleColorOverLife(sampler2D tex) {
26
+ float t = clamp(PARTICLE_AGE / PARTICLE_LIFETIME, 0.0, 1.0);
27
+ vec4 c = texture2D(tex, vec2(t, 0.5));
28
+ ${checkSRGBSupport() ? "" : "c = vec4(pow(c.rgb, vec3(2.2)), c.a);"}
29
+ return c;
30
+ }
31
+ `;
32
+ }
33
+ destroy() {
34
+ this._private_gradientTexture.dispose();
35
+ }
36
+ }
37
+
38
+ export { FXColorOverLifeNode };
@@ -0,0 +1,5 @@
1
+ import type { Texture } from "three";
2
+ import { FXColorNode } from "./FXColorNode";
3
+ export declare class FXStaticTextureNode extends FXColorNode {
4
+ constructor(texture: Texture);
5
+ }
@@ -0,0 +1,23 @@
1
+ import { FXColorNode } from './FXColorNode.js';
2
+
3
+ class FXStaticTextureNode extends FXColorNode {
4
+ constructor(texture) {
5
+ super();
6
+ /** @internal */
7
+ this.cacheKey = "static";
8
+ /** @internal */
9
+ this.uniformDeclarations = ["uniform sampler2D u_StaticTexture;"];
10
+ /** @internal */
11
+ this.helperFunctions = "";
12
+ /** @internal */
13
+ this.colorExpression = "texture2D(u_StaticTexture, p_uv)";
14
+ /** @internal */
15
+ this.affectsDepth = true;
16
+ this.uniforms = {
17
+ // eslint-disable-next-line @typescript-eslint/naming-convention
18
+ u_StaticTexture: { value: texture },
19
+ };
20
+ }
21
+ }
22
+
23
+ export { FXStaticTextureNode };
@@ -0,0 +1 @@
1
+ export declare const PARTICLE_DEFINES = "\n #define PARTICLE_POSITION_X p_builtin[0][0]\n #define PARTICLE_POSITION_Y p_builtin[0][1]\n #define PARTICLE_POSITION_Z p_builtin[0][2]\n\n #define PARTICLE_VELOCITY_X p_builtin[0][3]\n #define PARTICLE_VELOCITY_Y p_builtin[1][0]\n #define PARTICLE_VELOCITY_Z p_builtin[1][1]\n\n #define PARTICLE_SCALE_X p_builtin[1][2]\n #define PARTICLE_SCALE_Y p_builtin[1][3]\n #define PARTICLE_SCALE_Z p_builtin[2][0]\n\n #define PARTICLE_ROTATION p_builtin[2][1]\n #define PARTICLE_TORQUE p_builtin[2][2]\n\n #define PARTICLE_LIFETIME p_builtin[2][3]\n #define PARTICLE_AGE p_builtin[3][0]\n\n #define PARTICLE_RANDOM_A p_builtin[3][1]\n #define PARTICLE_RANDOM_B p_builtin[3][2]\n #define PARTICLE_RANDOM_C p_builtin[3][3]\n";
@@ -0,0 +1,25 @@
1
+ const PARTICLE_DEFINES = `
2
+ #define PARTICLE_POSITION_X p_builtin[0][0]
3
+ #define PARTICLE_POSITION_Y p_builtin[0][1]
4
+ #define PARTICLE_POSITION_Z p_builtin[0][2]
5
+
6
+ #define PARTICLE_VELOCITY_X p_builtin[0][3]
7
+ #define PARTICLE_VELOCITY_Y p_builtin[1][0]
8
+ #define PARTICLE_VELOCITY_Z p_builtin[1][1]
9
+
10
+ #define PARTICLE_SCALE_X p_builtin[1][2]
11
+ #define PARTICLE_SCALE_Y p_builtin[1][3]
12
+ #define PARTICLE_SCALE_Z p_builtin[2][0]
13
+
14
+ #define PARTICLE_ROTATION p_builtin[2][1]
15
+ #define PARTICLE_TORQUE p_builtin[2][2]
16
+
17
+ #define PARTICLE_LIFETIME p_builtin[2][3]
18
+ #define PARTICLE_AGE p_builtin[3][0]
19
+
20
+ #define PARTICLE_RANDOM_A p_builtin[3][1]
21
+ #define PARTICLE_RANDOM_B p_builtin[3][2]
22
+ #define PARTICLE_RANDOM_C p_builtin[3][3]
23
+ `;
24
+
25
+ export { PARTICLE_DEFINES };
@@ -1,6 +1,6 @@
1
1
  import { MathUtils, Color, Vector4 } from 'three';
2
- import { assertValidNumber } from '../miscellaneous/asserts.js';
3
- import { srgbToLinear, linearToSRGB } from '../miscellaneous/math.js';
2
+ import { assertValidNumber } from '../asserts.js';
3
+ import { srgbToLinear, linearToSRGB } from '../math.js';
4
4
  import { COLORS } from './FXColor.Internal.js';
5
5
 
6
6
  /** RGBA color with RGB, HSL, hex, and named color support */
@@ -1,8 +1,8 @@
1
1
  import type { Vector3Tuple } from "three";
2
2
  import { DataTexture } from "three";
3
- import type { FXColor } from "../color/FXColor";
4
3
  import type { Vector3Like } from "../miscellaneous/math";
5
4
  import type { FXTextureConfig } from "../miscellaneous/texture/FXTextureView.Internal";
5
+ import type { FXColor } from "./color/FXColor";
6
6
  export interface FXRange {
7
7
  min: number;
8
8
  max: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sparcoon",
3
- "version": "0.0.8",
3
+ "version": "0.2.0",
4
4
  "description": "",
5
5
  "keywords": [
6
6
  "particles",
@@ -1,6 +0,0 @@
1
- import { Texture } from 'three';
2
-
3
- const TEXTURE_DEFAULT_TEXTURE = new Texture();
4
- const TEXTURE_DEFAULT_SIZE = 2;
5
-
6
- export { TEXTURE_DEFAULT_SIZE, TEXTURE_DEFAULT_TEXTURE };
@@ -1,234 +0,0 @@
1
- import { Ferrsign3 } from 'ferrsign';
2
- import { Matrix3, Vector2, Texture } from 'three';
3
- import { assertValidPositiveNumber, assertValidNonNegativeNumber } from '../asserts.js';
4
- import { TEXTURE_DEFAULT_TEXTURE, TEXTURE_DEFAULT_SIZE } from './FXTextureView.Internal.js';
5
-
6
- /** Wrapper for Three.js texture with atlas and trim support. Does not own the underlying texture; user must dispose it. */
7
- class FXTextureView {
8
- /** @param config Texture or atlas configuration */
9
- constructor(config) {
10
- this._private_textureInternal = TEXTURE_DEFAULT_TEXTURE;
11
- this._private_sourceWidth = TEXTURE_DEFAULT_SIZE;
12
- this._private_sourceHeight = TEXTURE_DEFAULT_SIZE;
13
- this._private_frameX = 0;
14
- this._private_frameY = 0;
15
- this._private_frameWidth = TEXTURE_DEFAULT_SIZE;
16
- this._private_frameHeight = TEXTURE_DEFAULT_SIZE;
17
- this._private_rotatedInternal = false;
18
- this._private_scaleInternal = 1;
19
- this._private_trimLeft = 0;
20
- this._private_trimRight = 0;
21
- this._private_trimTop = 0;
22
- this._private_trimBottom = 0;
23
- this._private_textureDirtyInternal = false;
24
- this._private_uvTransformDirtyInternal = false;
25
- this._private_trimDirtyInternal = false;
26
- this._private_signalDiminsionsChangedInternal = new Ferrsign3();
27
- if (config !== undefined) {
28
- this.set(config);
29
- }
30
- }
31
- /** Original width before trimming in world units */
32
- get width() {
33
- return this._private_sourceWidth / this._private_scaleInternal;
34
- }
35
- /** Original height before trimming in world units */
36
- get height() {
37
- return this._private_sourceHeight / this._private_scaleInternal;
38
- }
39
- /** Visible width after trimming in world units */
40
- get trimmedWidth() {
41
- const frameSize = this._private_rotatedInternal ? this._private_frameHeight : this._private_frameWidth;
42
- return frameSize / this._private_scaleInternal;
43
- }
44
- /** Visible height after trimming in world units */
45
- get trimmedHeight() {
46
- const frameSize = this._private_rotatedInternal ? this._private_frameWidth : this._private_frameHeight;
47
- return frameSize / this._private_scaleInternal;
48
- }
49
- /** Underlying Three.js texture */
50
- get texture() {
51
- return this._private_textureInternal;
52
- }
53
- /** Whether sprite is rotated in atlas */
54
- get rotated() {
55
- return this._private_rotatedInternal;
56
- }
57
- /** Scale factor for resolution independence */
58
- get scale() {
59
- return this._private_scaleInternal;
60
- }
61
- /** Transparent padding around visible content */
62
- get trim() {
63
- const scale = this._private_scaleInternal;
64
- return {
65
- left: this._private_trimLeft / scale,
66
- right: this._private_trimRight / scale,
67
- top: this._private_trimTop / scale,
68
- bottom: this._private_trimBottom / scale,
69
- };
70
- }
71
- get textureDirty() {
72
- return this._private_textureDirtyInternal;
73
- }
74
- /** Whether UV transform inputs changed since last check */
75
- get uvTransformDirty() {
76
- return this._private_uvTransformDirtyInternal;
77
- }
78
- /** Whether trim values changed since last check */
79
- get trimDirty() {
80
- return this._private_trimDirtyInternal;
81
- }
82
- get signalDiminsionsChanged() {
83
- return this._private_signalDiminsionsChangedInternal;
84
- }
85
- setTextureDirtyFalse() {
86
- this._private_textureDirtyInternal = false;
87
- }
88
- /** Marks UV transform as clean. @internal */
89
- setUVTransformDirtyFalse() {
90
- this._private_uvTransformDirtyInternal = false;
91
- }
92
- /** Marks trim as clean. @internal */
93
- setTrimDirtyFalse() {
94
- this._private_trimDirtyInternal = false;
95
- }
96
- /**
97
- * Calculates UV transform matrix for shader sampling.
98
- * @param result Matrix to store result in
99
- * @returns UV transform matrix
100
- */
101
- calculateUVTransform(result = new Matrix3()) {
102
- const atlasWidth = this._private_textureInternal.image?.naturalWidth ?? TEXTURE_DEFAULT_SIZE;
103
- const atlasHeight = this._private_textureInternal.image?.naturalHeight ?? TEXTURE_DEFAULT_SIZE;
104
- if (this._private_rotatedInternal) {
105
- const physicalWidth = this._private_frameHeight;
106
- const physicalHeight = this._private_frameWidth;
107
- const u0 = this._private_frameX / atlasWidth;
108
- const v0 = (atlasHeight - this._private_frameY - physicalHeight) / atlasHeight;
109
- const uSize = physicalWidth / atlasWidth;
110
- const vSize = physicalHeight / atlasHeight;
111
- result.set(0, uSize, u0, -vSize, 0, v0 + vSize, 0, 0, 1);
112
- }
113
- else {
114
- const u0 = this._private_frameX / atlasWidth;
115
- const v0 = (atlasHeight - this._private_frameY - this._private_frameHeight) / atlasHeight;
116
- const uSize = this._private_frameWidth / atlasWidth;
117
- const vSize = this._private_frameHeight / atlasHeight;
118
- result.set(uSize, 0, u0, 0, vSize, v0, 0, 0, 1);
119
- }
120
- return result;
121
- }
122
- /**
123
- * Gets original dimensions before trimming.
124
- * @param result Vector to store result in
125
- * @returns Width and height in world units
126
- */
127
- getResolution(result = new Vector2()) {
128
- return result.set(this.width, this.height);
129
- }
130
- /**
131
- * Replaces texture with new configuration.
132
- * @param config Texture or atlas configuration
133
- */
134
- set(config) {
135
- const lastWidth = this.width;
136
- const lastHeight = this.height;
137
- if (config instanceof Texture) {
138
- this._private_setFromTexture(config);
139
- }
140
- else {
141
- this._private_setFromAtlasConfig(config);
142
- }
143
- if (this.width !== lastWidth || this.height !== lastHeight) {
144
- this._private_signalDiminsionsChangedInternal.emit(this.width, this.height, this);
145
- }
146
- }
147
- _private_setFromTexture(texture) {
148
- const width = texture.image?.naturalWidth ?? TEXTURE_DEFAULT_SIZE;
149
- const height = texture.image?.naturalHeight ?? TEXTURE_DEFAULT_SIZE;
150
- this._private_sourceWidth = width;
151
- this._private_sourceHeight = height;
152
- if (this.texture !== texture) {
153
- this._private_textureInternal = texture;
154
- this._private_textureDirtyInternal = true;
155
- }
156
- if (this._private_frameX !== 0 ||
157
- this._private_frameY !== 0 ||
158
- this._private_frameWidth !== width ||
159
- this._private_frameHeight !== height ||
160
- this._private_scaleInternal !== 1 || this._private_rotatedInternal) {
161
- this._private_frameX = 0;
162
- this._private_frameY = 0;
163
- this._private_frameWidth = width;
164
- this._private_frameHeight = height;
165
- this._private_rotatedInternal = false;
166
- this._private_scaleInternal = 1;
167
- this._private_uvTransformDirtyInternal = true;
168
- }
169
- if (this._private_trimLeft !== 0 ||
170
- this._private_trimRight !== 0 ||
171
- this._private_trimTop !== 0 ||
172
- this._private_trimBottom !== 0) {
173
- this._private_trimLeft = 0;
174
- this._private_trimRight = 0;
175
- this._private_trimTop = 0;
176
- this._private_trimBottom = 0;
177
- this._private_trimDirtyInternal = true;
178
- }
179
- }
180
- _private_setFromAtlasConfig(config) {
181
- assertValidPositiveNumber(config.sourceSize.w, "FXTextureView.setFromAtlasConfig.config.sourceSize.w");
182
- assertValidPositiveNumber(config.sourceSize.h, "FXTextureView.setFromAtlasConfig.config.sourceSize.h");
183
- assertValidNonNegativeNumber(config.frame.x, "FXTextureView.setFromAtlasConfig.config.frame.x");
184
- assertValidNonNegativeNumber(config.frame.y, "FXTextureView.setFromAtlasConfig.config.frame.y");
185
- assertValidPositiveNumber(config.frame.w, "FXTextureView.setFromAtlasConfig.config.frame.w");
186
- assertValidPositiveNumber(config.frame.h, "FXTextureView.setFromAtlasConfig.config.frame.h");
187
- assertValidNonNegativeNumber(config.spriteSourceSize.x, "FXTextureView.setFromAtlasConfig.config.spriteSourceSize.x");
188
- assertValidNonNegativeNumber(config.spriteSourceSize.y, "FXTextureView.setFromAtlasConfig.config.spriteSourceSize.y");
189
- assertValidPositiveNumber(config.spriteSourceSize.w, "FXTextureView.setFromAtlasConfig.config.spriteSourceSize.w");
190
- assertValidPositiveNumber(config.spriteSourceSize.h, "FXTextureView.setFromAtlasConfig.config.spriteSourceSize.h");
191
- if (config.scale !== undefined) {
192
- assertValidPositiveNumber(config.scale, "FXTextureView.setFromAtlasConfig.config.scale");
193
- }
194
- this._private_sourceWidth = config.sourceSize.w;
195
- this._private_sourceHeight = config.sourceSize.h;
196
- if (this.texture !== config.texture) {
197
- this._private_textureInternal = config.texture;
198
- this._private_textureDirtyInternal = true;
199
- }
200
- const scale = config.scale ?? 1;
201
- const rotated = config.rotated ?? false;
202
- if (this._private_frameX !== 0 ||
203
- this._private_frameY !== 0 ||
204
- this._private_frameWidth !== config.frame.w ||
205
- this._private_frameHeight !== config.frame.h ||
206
- this._private_scaleInternal !== scale ||
207
- this._private_rotatedInternal !== rotated) {
208
- this._private_frameX = config.frame.x;
209
- this._private_frameY = config.frame.y;
210
- this._private_frameWidth = config.frame.w;
211
- this._private_frameHeight = config.frame.h;
212
- this._private_scaleInternal = scale;
213
- this._private_rotatedInternal = rotated;
214
- this._private_uvTransformDirtyInternal = true;
215
- }
216
- const spriteSource = config.spriteSourceSize;
217
- const trimLeft = spriteSource.x;
218
- const trimTop = spriteSource.y;
219
- const trimRight = this._private_sourceWidth - spriteSource.x - spriteSource.w;
220
- const trimBottom = this._private_sourceHeight - spriteSource.y - spriteSource.h;
221
- if (this._private_trimLeft !== trimLeft ||
222
- this._private_trimRight !== trimRight ||
223
- this._private_trimTop !== trimTop ||
224
- this._private_trimBottom !== trimBottom) {
225
- this._private_trimLeft = trimLeft;
226
- this._private_trimRight = trimRight;
227
- this._private_trimTop = trimTop;
228
- this._private_trimBottom = trimBottom;
229
- this._private_trimDirtyInternal = true;
230
- }
231
- }
232
- }
233
-
234
- export { FXTextureView };
@@ -1,5 +0,0 @@
1
- import { type Texture } from "three";
2
- import { FXRenderingModule } from "./FXRenderingModule";
3
- export declare class FXRenderingAnimatedTexture extends FXRenderingModule {
4
- constructor(texture: Texture, horizontalCount: number, verticalCount: number);
5
- }
@@ -1,14 +0,0 @@
1
- import { Vector2 } from 'three';
2
- import source from '../shaders/FXRenderingAnimatedTexture.glsl.js';
3
- import { FXRenderingModule } from './FXRenderingModule.js';
4
-
5
- class FXRenderingAnimatedTexture extends FXRenderingModule {
6
- constructor(texture, horizontalCount, verticalCount) {
7
- super();
8
- /** @internal */
9
- this.source = source;
10
- this.requiredUniforms = { texture, count: new Vector2(horizontalCount, verticalCount) };
11
- }
12
- }
13
-
14
- export { FXRenderingAnimatedTexture };
@@ -1,14 +0,0 @@
1
- import type { FXColor } from "../color/FXColor";
2
- import { FXRenderingModule } from "./FXRenderingModule";
3
- /**
4
- * Colors particles based on lifetime progression.
5
- *
6
- * Interpolates through color gradient as particles age from birth to death.
7
- */
8
- export declare class FXRenderingColorOverLife extends FXRenderingModule {
9
- /**
10
- * @param colors - Color gradient stops from birth to death
11
- */
12
- constructor(colors: FXColor[]);
13
- destroy(): void;
14
- }
@@ -1,32 +0,0 @@
1
- import { buildGradientTexture } from '../miscellaneous/miscellaneous.js';
2
- import source from '../shaders/FXRenderingColorOverLife.glsl.js';
3
- import { FXRenderingModule } from './FXRenderingModule.js';
4
-
5
- /**
6
- * Colors particles based on lifetime progression.
7
- *
8
- * Interpolates through color gradient as particles age from birth to death.
9
- */
10
- class FXRenderingColorOverLife extends FXRenderingModule {
11
- /**
12
- * @param colors - Color gradient stops from birth to death
13
- */
14
- constructor(colors) {
15
- super();
16
- /** @internal */
17
- this.requiredProperties = {
18
- builtin: "Matrix4",
19
- };
20
- /** @internal */
21
- this.source = source;
22
- if (colors.length === 0) {
23
- throw new Error("FXRenderingColorOverLife: colors array cannot be empty");
24
- }
25
- this.requiredUniforms = { colorOverLifeTexture: buildGradientTexture(colors) };
26
- }
27
- destroy() {
28
- this.requiredUniforms.colorOverLifeTexture.dispose();
29
- }
30
- }
31
-
32
- export { FXRenderingColorOverLife };
@@ -1,15 +0,0 @@
1
- import type { FXColor } from "../color/FXColor";
2
- import { FXRenderingModule } from "./FXRenderingModule";
3
- /**
4
- * Colors particles based on velocity magnitude.
5
- *
6
- * Maps velocity from 0 to maxVelocity across the color gradient.
7
- */
8
- export declare class FXRenderingColorOverVelocity extends FXRenderingModule {
9
- /**
10
- * @param colors - Color gradient from slow to fast
11
- * @param maxVelocity - Velocity mapped to final color
12
- */
13
- constructor(colors: FXColor[], maxVelocity: number);
14
- destroy(): void;
15
- }