sparcoon 0.5.0 → 0.6.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/README.md +6 -6
- package/dist/emitter/FXEmitter.Internal.d.ts +55 -0
- package/dist/emitter/FXEmitter.d.ts +49 -0
- package/dist/emitter/FXEmitter.js +64 -0
- package/dist/emitter/behavior/FXBehavior.d.ts +12 -2
- package/dist/emitter/behavior/FXBehavior.js +3 -2
- package/dist/emitter/behavior/FXBehaviorDirectionalForce.d.ts +25 -0
- package/dist/emitter/behavior/FXBehaviorDirectionalForce.js +74 -0
- package/dist/emitter/behavior/FXBehaviorPointForce.d.ts +40 -0
- package/dist/emitter/behavior/FXBehaviorPointForce.js +98 -0
- package/dist/emitter/behavior/FXBehaviorScaleOverLife.d.ts +9 -8
- package/dist/emitter/behavior/FXBehaviorScaleOverLife.js +12 -29
- package/dist/emitter/behavior/FXBehaviorTorqueDamping.d.ts +4 -3
- package/dist/emitter/behavior/FXBehaviorTorqueDamping.js +3 -2
- package/dist/emitter/behavior/FXBehaviorTorqueNoise.d.ts +4 -3
- package/dist/emitter/behavior/FXBehaviorTorqueNoise.js +3 -2
- package/dist/emitter/behavior/FXBehaviorTorqueOverLife.d.ts +17 -0
- package/dist/emitter/behavior/FXBehaviorTorqueOverLife.js +34 -0
- package/dist/emitter/behavior/FXBehaviorVelocityDamping.d.ts +3 -2
- package/dist/emitter/behavior/FXBehaviorVelocityDamping.js +3 -2
- package/dist/emitter/behavior/FXBehaviorVelocityNoise.d.ts +6 -5
- package/dist/emitter/behavior/FXBehaviorVelocityNoise.js +6 -5
- package/dist/emitter/behavior/FXBehaviorVelocityOverLife.d.ts +20 -0
- package/dist/emitter/behavior/FXBehaviorVelocityOverLife.js +48 -0
- package/dist/emitter/spawn/FXSpawn.d.ts +4 -2
- package/dist/emitter/spawn/FXSpawn.js +3 -2
- package/dist/emitter/spawn/FXSpawnBox.d.ts +8 -16
- package/dist/emitter/spawn/FXSpawnBox.js +23 -39
- package/dist/emitter/spawn/{FXSpawnRandomLifetime.d.ts → FXSpawnLifetime.d.ts} +3 -5
- package/dist/emitter/spawn/{FXSpawnRandomLifetime.js → FXSpawnLifetime.js} +8 -10
- package/dist/emitter/spawn/FXSpawnOffset.d.ts +9 -0
- package/dist/emitter/spawn/FXSpawnOffset.js +9 -0
- package/dist/emitter/spawn/FXSpawnPoint.d.ts +8 -0
- package/dist/emitter/spawn/FXSpawnPoint.js +8 -0
- package/dist/emitter/spawn/{FXSpawnRandomRotation.d.ts → FXSpawnRotation.d.ts} +3 -5
- package/dist/emitter/spawn/{FXSpawnRandomRotation.js → FXSpawnRotation.js} +8 -10
- package/dist/emitter/spawn/{FXSpawnRandomScale.d.ts → FXSpawnScale.d.ts} +4 -6
- package/dist/emitter/spawn/{FXSpawnRandomScale.js → FXSpawnScale.js} +12 -14
- package/dist/emitter/spawn/FXSpawnSphere.d.ts +11 -6
- package/dist/emitter/spawn/FXSpawnSphere.js +11 -6
- package/dist/emitter/spawn/{FXSpawnRandomTorque.d.ts → FXSpawnTorque.d.ts} +3 -5
- package/dist/emitter/spawn/{FXSpawnRandomTorque.js → FXSpawnTorque.js} +8 -10
- package/dist/emitter/spawn/FXSpawnVelocity.d.ts +32 -0
- package/dist/emitter/spawn/{FXSpawnRandomVelocity.js → FXSpawnVelocity.js} +26 -11
- package/dist/index.d.ts +23 -16
- package/dist/index.js +20 -16
- package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.Internal.d.ts +4 -4
- package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.Internal.js +2 -2
- package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.d.ts +55 -5
- package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.js +9 -2
- package/dist/materials/FXMaterial/FXDepthMaterial.Internal.d.ts +3 -3
- package/dist/materials/FXMaterial/FXDistanceMaterial.Internal.d.ts +3 -3
- package/dist/materials/FXMaterial/FXMaterial.d.ts +51 -5
- package/dist/materials/FXMaterial/FXMaterial.js +5 -0
- package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.Internal.d.ts +3 -3
- package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.d.ts +3 -3
- package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.js +3 -3
- package/dist/miscellaneous/curve/FXCurve1D.Internal.d.ts +20 -0
- package/dist/miscellaneous/curve/FXCurve1D.d.ts +17 -0
- package/dist/miscellaneous/curve/FXCurve1D.js +94 -0
- package/dist/miscellaneous/miscellaneous.d.ts +3 -1
- package/dist/miscellaneous/miscellaneous.js +8 -4
- package/dist/miscellaneous/texture/FXTextureView.Internal.js +6 -0
- package/dist/miscellaneous/texture/FXTextureView.js +234 -0
- package/dist/nodes/color/FXNodeColor.d.ts +7 -0
- package/dist/nodes/color/FXNodeColor.js +11 -0
- package/dist/nodes/color/FXNodeColorOverLife.d.ts +25 -0
- package/dist/nodes/color/FXNodeColorOverLife.js +60 -0
- package/dist/nodes/color/FXNodeSphericalClip.d.ts +18 -0
- package/dist/nodes/color/FXNodeSphericalClip.js +45 -0
- package/dist/nodes/normal/FXNodeFlatNormal.d.ts +7 -0
- package/dist/nodes/normal/FXNodeFlatNormal.js +17 -0
- package/dist/nodes/normal/FXNodeNormal.d.ts +7 -0
- package/dist/nodes/normal/FXNodeNormal.js +7 -0
- package/dist/nodes/normal/FXNodeSphericalNormal.d.ts +7 -0
- package/dist/nodes/normal/{FXSphericalNormalNode.js → FXNodeSphericalNormal.js} +7 -4
- package/dist/nodes/texture/FXNodeAnimatedTexture.d.ts +47 -0
- package/dist/nodes/texture/FXNodeAnimatedTexture.js +137 -0
- package/dist/nodes/texture/FXNodeStaticTexture.d.ts +18 -0
- package/dist/nodes/texture/FXNodeStaticTexture.js +60 -0
- package/dist/nodes/texture/FXNodeTexture.d.ts +7 -0
- package/dist/nodes/texture/FXNodeTexture.js +11 -0
- package/package.json +2 -4
- package/dist/emitter/behavior/FXBehaviorDirectionalGravity.d.ts +0 -21
- package/dist/emitter/behavior/FXBehaviorDirectionalGravity.js +0 -51
- package/dist/emitter/behavior/FXBehaviorPointGravity.d.ts +0 -39
- package/dist/emitter/behavior/FXBehaviorPointGravity.js +0 -116
- package/dist/emitter/spawn/FXSpawnRandomVelocity.d.ts +0 -17
- package/dist/nodes/color/FXColorNode.d.ts +0 -3
- package/dist/nodes/color/FXColorNode.js +0 -8
- package/dist/nodes/color/FXColorOverLifeNode.d.ts +0 -6
- package/dist/nodes/color/FXColorOverLifeNode.js +0 -44
- package/dist/nodes/color/FXSphericalClipNode.d.ts +0 -5
- package/dist/nodes/color/FXSphericalClipNode.js +0 -30
- package/dist/nodes/normal/FXFlatNormalNode.d.ts +0 -4
- package/dist/nodes/normal/FXFlatNormalNode.js +0 -14
- package/dist/nodes/normal/FXNormalNode.d.ts +0 -3
- package/dist/nodes/normal/FXNormalNode.js +0 -4
- package/dist/nodes/normal/FXSphericalNormalNode.d.ts +0 -4
- package/dist/nodes/texture/FXAnimatedTextureNode.d.ts +0 -12
- package/dist/nodes/texture/FXAnimatedTextureNode.js +0 -88
- package/dist/nodes/texture/FXStaticTextureNode.d.ts +0 -6
- package/dist/nodes/texture/FXStaticTextureNode.js +0 -34
- package/dist/nodes/texture/FXTextureNode.d.ts +0 -3
- package/dist/nodes/texture/FXTextureNode.js +0 -8
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { FXColor } from '../../miscellaneous/color/FXColor.js';
|
|
2
|
-
import {
|
|
2
|
+
import { FXNodeSphericalNormal } from '../../nodes/normal/FXNodeSphericalNormal.js';
|
|
3
3
|
import { FXMaterial } from '../FXMaterial/FXMaterial.js';
|
|
4
4
|
import { buildFXDiffuseMaterial } from './FXDiffuseMaterial.Internal.js';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Diffuse particle material with lighting, normals, emission, and optional subsurface scattering
|
|
8
|
+
*/
|
|
6
9
|
class FXDiffuseMaterial extends FXMaterial {
|
|
10
|
+
/**
|
|
11
|
+
* @param options - Material configuration
|
|
12
|
+
*/
|
|
7
13
|
constructor(options = {}) {
|
|
8
14
|
super(options);
|
|
9
|
-
this._private_normalNodes = options.normalNodes ?? [new
|
|
15
|
+
this._private_normalNodes = options.normalNodes ?? [new FXNodeSphericalNormal()];
|
|
10
16
|
this._private_emissionNodes = options.emissionNodes ?? [];
|
|
11
17
|
this._private_scatterUniforms =
|
|
12
18
|
options.enableScatter === true
|
|
@@ -23,6 +29,7 @@ class FXDiffuseMaterial extends FXMaterial {
|
|
|
23
29
|
: undefined;
|
|
24
30
|
this._private_shadowSensitivity = { value: options.shadowSensitivity ?? 1 };
|
|
25
31
|
}
|
|
32
|
+
/** Releases resources held by all albedo, normal, and emission nodes */
|
|
26
33
|
destroy() {
|
|
27
34
|
super.destroy();
|
|
28
35
|
for (const node of this._private_normalNodes) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { MeshDepthMaterial } from "three";
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
4
|
-
export declare function buildDepthMaterial(albedoNodes: readonly (
|
|
2
|
+
import type { FXNodeColor } from "../../nodes/color/FXNodeColor";
|
|
3
|
+
import type { FXNodeTexture } from "../../nodes/texture/FXNodeTexture";
|
|
4
|
+
export declare function buildDepthMaterial(albedoNodes: readonly (FXNodeColor | FXNodeTexture)[], depthAlphaTest: number, useDepthAlphaHash: boolean, useSphericalDepth: boolean): MeshDepthMaterial;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { MeshDistanceMaterial } from "three";
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
4
|
-
export declare function buildDistanceMaterial(albedoNodes: readonly (
|
|
2
|
+
import type { FXNodeColor } from "../../nodes/color/FXNodeColor";
|
|
3
|
+
import type { FXNodeTexture } from "../../nodes/texture/FXNodeTexture";
|
|
4
|
+
export declare function buildDistanceMaterial(albedoNodes: readonly (FXNodeColor | FXNodeTexture)[], distanceAlphaTest: number, useDistanceAlphaHash: boolean, useSphericalDepth: boolean): MeshDistanceMaterial;
|
|
@@ -1,21 +1,67 @@
|
|
|
1
|
-
import type { Blending
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
1
|
+
import type { Blending } from "three";
|
|
2
|
+
import type { FXNodeColor } from "../../nodes/color/FXNodeColor";
|
|
3
|
+
import type { FXNodeTexture } from "../../nodes/texture/FXNodeTexture";
|
|
4
|
+
/**
|
|
5
|
+
* Configuration options shared by all {@link FXMaterial} subclasses
|
|
6
|
+
*/
|
|
4
7
|
export interface FXMaterialOptions {
|
|
5
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Color and texture nodes composited for particle color
|
|
10
|
+
*
|
|
11
|
+
* @defaultValue `[]`
|
|
12
|
+
*/
|
|
13
|
+
albedoNodes: (FXNodeColor | FXNodeTexture)[];
|
|
14
|
+
/**
|
|
15
|
+
* Three.js blending mode
|
|
16
|
+
*
|
|
17
|
+
* @defaultValue `NormalBlending`
|
|
18
|
+
*/
|
|
6
19
|
blending: Blending;
|
|
20
|
+
/**
|
|
21
|
+
* Use alpha hashing instead of standard transparency
|
|
22
|
+
*
|
|
23
|
+
* @defaultValue `false`
|
|
24
|
+
*/
|
|
7
25
|
useAlphaHashing: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Alpha cutoff threshold for color passes
|
|
28
|
+
*
|
|
29
|
+
* @defaultValue `0.0075`
|
|
30
|
+
*/
|
|
8
31
|
alphaTest: number;
|
|
32
|
+
/**
|
|
33
|
+
* Alpha cutoff threshold for depth and shadow passes
|
|
34
|
+
*
|
|
35
|
+
* @defaultValue `0.5`
|
|
36
|
+
*/
|
|
9
37
|
depthAlphaTest: number;
|
|
38
|
+
/**
|
|
39
|
+
* Use alpha hashing in depth and shadow passes
|
|
40
|
+
*
|
|
41
|
+
* @defaultValue `false`
|
|
42
|
+
*/
|
|
10
43
|
useDepthAlphaHash: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Approximate spherical depth for shadow maps
|
|
46
|
+
*
|
|
47
|
+
* @defaultValue `true`
|
|
48
|
+
*/
|
|
11
49
|
useSphericalDepth: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Use premultiplied alpha blending
|
|
52
|
+
*
|
|
53
|
+
* @defaultValue `true`
|
|
54
|
+
*/
|
|
12
55
|
premultipliedAlpha: boolean;
|
|
13
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Abstract base class for particle materials
|
|
59
|
+
*/
|
|
14
60
|
export declare abstract class FXMaterial {
|
|
15
61
|
private readonly depthAlphaTest;
|
|
16
62
|
private readonly useDepthAlphaHash;
|
|
17
63
|
private readonly useSphericalDepth;
|
|
18
64
|
constructor(options?: Partial<FXMaterialOptions>);
|
|
65
|
+
/** Releases resources held by all albedo nodes */
|
|
19
66
|
destroy(): void;
|
|
20
|
-
buildDistanceMaterial(): MeshDistanceMaterial;
|
|
21
67
|
}
|
|
@@ -2,6 +2,9 @@ import { NormalBlending } from 'three';
|
|
|
2
2
|
import { buildDepthMaterial } from './FXDepthMaterial.Internal.js';
|
|
3
3
|
import { buildDistanceMaterial } from './FXDistanceMaterial.Internal.js';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Abstract base class for particle materials
|
|
7
|
+
*/
|
|
5
8
|
class FXMaterial {
|
|
6
9
|
constructor(options = {}) {
|
|
7
10
|
this.albedoNodes = options.albedoNodes ?? [];
|
|
@@ -14,6 +17,7 @@ class FXMaterial {
|
|
|
14
17
|
this._private_useDepthAlphaHash = options.useDepthAlphaHash ?? false;
|
|
15
18
|
this._private_useSphericalDepth = options.useSphericalDepth ?? true;
|
|
16
19
|
}
|
|
20
|
+
/** Releases resources held by all albedo nodes */
|
|
17
21
|
destroy() {
|
|
18
22
|
for (const node of this.albedoNodes) {
|
|
19
23
|
node.destroy?.();
|
|
@@ -23,6 +27,7 @@ class FXMaterial {
|
|
|
23
27
|
buildDepthMaterial() {
|
|
24
28
|
return buildDepthMaterial(this.albedoNodes, this._private_depthAlphaTest, this._private_useDepthAlphaHash, this._private_useSphericalDepth);
|
|
25
29
|
}
|
|
30
|
+
/** @internal */
|
|
26
31
|
buildDistanceMaterial() {
|
|
27
32
|
return buildDistanceMaterial(this.albedoNodes, this._private_depthAlphaTest, this._private_useDepthAlphaHash, this._private_useSphericalDepth);
|
|
28
33
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Blending } from "three";
|
|
2
2
|
import { MeshBasicMaterial } from "three";
|
|
3
3
|
import type { GLTypeInfo } from "../../instancedParticle/shared";
|
|
4
|
-
import type {
|
|
5
|
-
import type {
|
|
6
|
-
export declare function buildFXUnlitMaterial(varyings: Record<string, GLTypeInfo>, blending: Blending, useAlphaHashing: boolean, alphaTest: number, premultipliedAlpha: boolean, albedoNodes: readonly (
|
|
4
|
+
import type { FXNodeColor } from "../../nodes/color/FXNodeColor";
|
|
5
|
+
import type { FXNodeTexture } from "../../nodes/texture/FXNodeTexture";
|
|
6
|
+
export declare function buildFXUnlitMaterial(varyings: Record<string, GLTypeInfo>, blending: Blending, useAlphaHashing: boolean, alphaTest: number, premultipliedAlpha: boolean, albedoNodes: readonly (FXNodeColor | FXNodeTexture)[]): MeshBasicMaterial;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { FXMaterialOptions } from "../FXMaterial/FXMaterial";
|
|
2
1
|
import { FXMaterial } from "../FXMaterial/FXMaterial";
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Unlit particle material - renders particles without lighting or shadows
|
|
4
|
+
*/
|
|
4
5
|
export declare class FXUnlitMaterial extends FXMaterial {
|
|
5
|
-
constructor(options?: Partial<FXUnlitMaterialOptions>);
|
|
6
6
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { FXMaterial } from '../FXMaterial/FXMaterial.js';
|
|
2
2
|
import { buildFXUnlitMaterial } from './FXUnlitMaterial.Internal.js';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Unlit particle material - renders particles without lighting or shadows
|
|
6
|
+
*/
|
|
4
7
|
class FXUnlitMaterial extends FXMaterial {
|
|
5
|
-
constructor(options = {}) {
|
|
6
|
-
super(options);
|
|
7
|
-
}
|
|
8
8
|
/** @internal */
|
|
9
9
|
buildThreeMaterial(varyings) {
|
|
10
10
|
return buildFXUnlitMaterial(varyings, this.blending, this.useAlphaHashing, this.alphaTest, this.premultipliedAlpha, this.albedoNodes);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { FXCurve1D } from "./FXCurve1D";
|
|
2
|
+
/** Input point for {@link FXCurve1D}. */
|
|
3
|
+
export interface FXCurve1DPoint<T> {
|
|
4
|
+
/** Output value at this position. */
|
|
5
|
+
value: T;
|
|
6
|
+
/** Normalized position in [0, 1]. */
|
|
7
|
+
position: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Accepts either:
|
|
11
|
+
* - Explicit anchor points ({@link FXCurve1DPoint}\<T>[])
|
|
12
|
+
* - A uniform shorthand (`T[]`) where anchors are distributed evenly across [0, 1]
|
|
13
|
+
* - Another {@link FXCurve1D}\<T> instance to copy anchors from
|
|
14
|
+
*/
|
|
15
|
+
export type FXCurve1DConfig<T> = FXCurve1DPoint<T>[] | T[] | FXCurve1D<T>;
|
|
16
|
+
/** Resolved anchor stored internally by {@link FXCurve1D}. */
|
|
17
|
+
export interface FXCurve1DAnchor<T> {
|
|
18
|
+
readonly value: T;
|
|
19
|
+
readonly position: number;
|
|
20
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { FXCurve1DAnchor, FXCurve1DConfig, FXCurve1DPoint } from "./FXCurve1D.Internal";
|
|
2
|
+
export type { FXCurve1DAnchor, FXCurve1DConfig, FXCurve1DPoint };
|
|
3
|
+
/**
|
|
4
|
+
* 1D curve defined by anchor points at explicit normalized positions.
|
|
5
|
+
*
|
|
6
|
+
* Anchors must be strictly ascending by `value`, first must be `0`, last must be `1`.
|
|
7
|
+
* Output at each anchor is a value of type `T` - interpolation is left to the caller.
|
|
8
|
+
*/
|
|
9
|
+
export declare class FXCurve1D<T> {
|
|
10
|
+
private readonly anchorsInternal;
|
|
11
|
+
/**
|
|
12
|
+
* @param config - Explicit anchor points, a uniform shorthand array, or another {@link FXCurve1D} to copy
|
|
13
|
+
*/
|
|
14
|
+
constructor(config: FXCurve1DConfig<T>);
|
|
15
|
+
/** Resolved anchor points ordered ascending by `value`. */
|
|
16
|
+
get anchors(): readonly FXCurve1DAnchor<T>[];
|
|
17
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { assertValidNumber } from '../asserts.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 1D curve defined by anchor points at explicit normalized positions.
|
|
5
|
+
*
|
|
6
|
+
* Anchors must be strictly ascending by `value`, first must be `0`, last must be `1`.
|
|
7
|
+
* Output at each anchor is a value of type `T` - interpolation is left to the caller.
|
|
8
|
+
*/
|
|
9
|
+
class FXCurve1D {
|
|
10
|
+
/**
|
|
11
|
+
* @param config - Explicit anchor points, a uniform shorthand array, or another {@link FXCurve1D} to copy
|
|
12
|
+
*/
|
|
13
|
+
constructor(config) {
|
|
14
|
+
if (config instanceof FXCurve1D) {
|
|
15
|
+
this._private_anchorsInternal = config._private_anchorsInternal.map((anchor) => ({ ...anchor }));
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const isPointArray = config.length > 0 &&
|
|
19
|
+
typeof config[0] === "object" &&
|
|
20
|
+
!Array.isArray(config[0]) &&
|
|
21
|
+
"value" in config[0];
|
|
22
|
+
const points = isPointArray
|
|
23
|
+
? config
|
|
24
|
+
: config.map((value, index) => ({
|
|
25
|
+
value,
|
|
26
|
+
position: index / (config.length - 1),
|
|
27
|
+
}));
|
|
28
|
+
if (points.length < 2) {
|
|
29
|
+
throw new Error("FXCurve1D: at least 2 anchor points are required");
|
|
30
|
+
}
|
|
31
|
+
if (points[0].position !== 0) {
|
|
32
|
+
throw new Error(`FXCurve1D: first anchor value must be 0, got ${points[0].position}`);
|
|
33
|
+
}
|
|
34
|
+
if (points[points.length - 1].position !== 1) {
|
|
35
|
+
throw new Error(`FXCurve1D: last anchor value must be 1, got ${points[points.length - 1].position}`);
|
|
36
|
+
}
|
|
37
|
+
this._private_anchorsInternal = [];
|
|
38
|
+
for (let index = 0; index < points.length; index++) {
|
|
39
|
+
const { value, position } = points[index];
|
|
40
|
+
if (position < 0 || position > 1) {
|
|
41
|
+
throw new Error(`FXCurve1D: anchor[${index}].value must be in [0, 1], got ${position}`);
|
|
42
|
+
}
|
|
43
|
+
if (index > 0 && position <= points[index - 1].position) {
|
|
44
|
+
throw new Error(`FXCurve1D: anchor[${index}].value (${position}) must be strictly greater than anchor[${index - 1}].value (${points[index - 1].position})`);
|
|
45
|
+
}
|
|
46
|
+
this._private_anchorsInternal.push({ value, position });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/** Resolved anchor points ordered ascending by `value`. */
|
|
50
|
+
get anchors() {
|
|
51
|
+
return this._private_anchorsInternal;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Samples the curve at normalized position `t`.
|
|
55
|
+
*
|
|
56
|
+
* Returns the two bracketing anchor values and the local interpolation factor `t` in [0, 1].
|
|
57
|
+
* The caller is responsible for interpolating between `a` and `b` using `t`.
|
|
58
|
+
*
|
|
59
|
+
* @param t - Normalized position in [0, 1]
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
62
|
+
sample(t) {
|
|
63
|
+
assertValidNumber(t, "FXCurve1D.sample.t");
|
|
64
|
+
const anchors = this._private_anchorsInternal;
|
|
65
|
+
const anchorCount = anchors.length;
|
|
66
|
+
let segmentIndex;
|
|
67
|
+
if (anchorCount < 10) {
|
|
68
|
+
segmentIndex = 0;
|
|
69
|
+
while (segmentIndex < anchorCount - 2 && anchors[segmentIndex + 1].position <= t) {
|
|
70
|
+
segmentIndex++;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
let low = 0;
|
|
75
|
+
let high = anchorCount - 2;
|
|
76
|
+
while (low < high) {
|
|
77
|
+
const mid = (low + high + 1) >> 1;
|
|
78
|
+
if (anchors[mid].position <= t) {
|
|
79
|
+
low = mid;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
high = mid - 1;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
segmentIndex = low;
|
|
86
|
+
}
|
|
87
|
+
const anchorA = anchors[segmentIndex];
|
|
88
|
+
const anchorB = anchors[segmentIndex + 1];
|
|
89
|
+
const localT = (t - anchorA.position) / (anchorB.position - anchorA.position);
|
|
90
|
+
return { a: anchorA.value, b: anchorB.value, t: localT };
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export { FXCurve1D };
|
|
@@ -3,6 +3,8 @@ import { DataTexture } from "three";
|
|
|
3
3
|
import type { Vector3Like } from "../miscellaneous/math";
|
|
4
4
|
import type { FXTextureConfig } from "../miscellaneous/texture/FXTextureView.Internal";
|
|
5
5
|
import type { FXColor } from "./color/FXColor";
|
|
6
|
+
import type { FXCurve1D } from "./curve/FXCurve1D";
|
|
7
|
+
export declare function getNextInstanceId(): number;
|
|
6
8
|
export interface FXRange {
|
|
7
9
|
min: number;
|
|
8
10
|
max: number;
|
|
@@ -13,7 +15,7 @@ export type FXAspectConfig = number | FXTextureConfig;
|
|
|
13
15
|
export declare function resolveFXRangeConfig(config: FXRangeConfig): FXRange;
|
|
14
16
|
export declare function resolveFXVector3Config(config: FXVector3Config): Vector3Like;
|
|
15
17
|
export declare function resolveAspect(config: number | FXTextureConfig): number;
|
|
16
|
-
export declare function buildGradientTexture(
|
|
18
|
+
export declare function buildGradientTexture(curve: FXCurve1D<FXColor>): DataTexture;
|
|
17
19
|
export declare const BUILTIN_OFFSET_POSITION_X = 0;
|
|
18
20
|
export declare const BUILTIN_OFFSET_POSITION_Y = 1;
|
|
19
21
|
export declare const BUILTIN_OFFSET_POSITION_Z = 2;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { Texture, DataTexture, RGBAFormat, UnsignedByteType, UVMapping, ClampToEdgeWrapping, LinearFilter, SRGBColorSpace } from 'three';
|
|
2
2
|
|
|
3
|
+
let nextInstanceId = 0;
|
|
4
|
+
function getNextInstanceId() {
|
|
5
|
+
return nextInstanceId++;
|
|
6
|
+
}
|
|
3
7
|
function resolveFXRangeConfig(config) {
|
|
4
8
|
if (typeof config === "number") {
|
|
5
9
|
return { min: config, max: config };
|
|
@@ -27,12 +31,12 @@ function resolveAspect(config) {
|
|
|
27
31
|
}
|
|
28
32
|
return config.sourceSize.w / config.sourceSize.h;
|
|
29
33
|
}
|
|
30
|
-
function buildGradientTexture(
|
|
31
|
-
const width =
|
|
34
|
+
function buildGradientTexture(curve) {
|
|
35
|
+
const width = curve.anchors.length;
|
|
32
36
|
const height = 1;
|
|
33
37
|
const data = new Uint8Array(width * height * 4);
|
|
34
38
|
for (let i = 0; i < width; i++) {
|
|
35
|
-
const color =
|
|
39
|
+
const color = curve.anchors[i].value;
|
|
36
40
|
const index = i * 4;
|
|
37
41
|
data[index] = Math.round(color.r * 255);
|
|
38
42
|
data[index + 1] = Math.round(color.g * 255);
|
|
@@ -82,4 +86,4 @@ const PARTICLE_DEFINES = `
|
|
|
82
86
|
#define PARTICLE_RANDOM_C p_builtin[3][3]
|
|
83
87
|
`;
|
|
84
88
|
|
|
85
|
-
export { BUILTIN_OFFSET_AGE, BUILTIN_OFFSET_LIFETIME, BUILTIN_OFFSET_POSITION_X, BUILTIN_OFFSET_POSITION_Y, BUILTIN_OFFSET_POSITION_Z, BUILTIN_OFFSET_RANDOM_A, BUILTIN_OFFSET_RANDOM_B, BUILTIN_OFFSET_RANDOM_C, BUILTIN_OFFSET_ROTATION, BUILTIN_OFFSET_SCALE_X, BUILTIN_OFFSET_SCALE_Y, BUILTIN_OFFSET_TORQUE, BUILTIN_OFFSET_VELOCITY_X, BUILTIN_OFFSET_VELOCITY_Y, BUILTIN_OFFSET_VELOCITY_Z, PARTICLE_DEFINES, buildGradientTexture, resolveAspect, resolveFXRangeConfig, resolveFXVector3Config };
|
|
89
|
+
export { BUILTIN_OFFSET_AGE, BUILTIN_OFFSET_LIFETIME, BUILTIN_OFFSET_POSITION_X, BUILTIN_OFFSET_POSITION_Y, BUILTIN_OFFSET_POSITION_Z, BUILTIN_OFFSET_RANDOM_A, BUILTIN_OFFSET_RANDOM_B, BUILTIN_OFFSET_RANDOM_C, BUILTIN_OFFSET_ROTATION, BUILTIN_OFFSET_SCALE_X, BUILTIN_OFFSET_SCALE_Y, BUILTIN_OFFSET_TORQUE, BUILTIN_OFFSET_VELOCITY_X, BUILTIN_OFFSET_VELOCITY_Y, BUILTIN_OFFSET_VELOCITY_Z, PARTICLE_DEFINES, buildGradientTexture, getNextInstanceId, resolveAspect, resolveFXRangeConfig, resolveFXVector3Config };
|
|
@@ -0,0 +1,234 @@
|
|
|
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 };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { FXColor } from "../../miscellaneous/color/FXColor";
|
|
2
|
+
import type { FXCurve1DConfig } from "../../miscellaneous/curve/FXCurve1D";
|
|
3
|
+
import { FXCurve1D } from "../../miscellaneous/curve/FXCurve1D";
|
|
4
|
+
import { FXNodeColor } from "./FXNodeColor";
|
|
5
|
+
/**
|
|
6
|
+
* Color node that animates particle color along a gradient curve over its lifetime
|
|
7
|
+
*/
|
|
8
|
+
export declare class FXNodeColorOverLife extends FXNodeColor {
|
|
9
|
+
private readonly uniformName;
|
|
10
|
+
private curveInternal;
|
|
11
|
+
/**
|
|
12
|
+
* @param curve - Color gradient defining the animation over the particle lifetime
|
|
13
|
+
*/
|
|
14
|
+
constructor(curve: FXCurve1DConfig<FXColor>);
|
|
15
|
+
/** Current color gradient curve */
|
|
16
|
+
get curve(): FXCurve1D<FXColor>;
|
|
17
|
+
/**
|
|
18
|
+
* Replaces the color gradient curve and rebuilds the backing texture
|
|
19
|
+
*
|
|
20
|
+
* @param value - New color gradient configuration
|
|
21
|
+
*/
|
|
22
|
+
set curve(value: FXCurve1DConfig<FXColor>);
|
|
23
|
+
/** Releases the backing gradient texture */
|
|
24
|
+
destroy(): void;
|
|
25
|
+
}
|