r3f-vfx 0.1.0 → 0.1.2
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/dist/index.d.ts +4 -7
- package/dist/index.js +81 -105
- package/package.json +2 -2
- package/dist/curveWorker.d.ts +0 -2
- package/dist/curveWorker.js +0 -105
package/dist/index.d.ts
CHANGED
|
@@ -265,15 +265,12 @@ declare const useVFXStore: typeof useVFXStoreImpl & {
|
|
|
265
265
|
};
|
|
266
266
|
|
|
267
267
|
/**
|
|
268
|
-
* Hook for
|
|
268
|
+
* Hook for curve texture loading/baking
|
|
269
269
|
* Returns a STABLE texture reference that updates in place
|
|
270
270
|
*
|
|
271
|
-
* If curveTexturePath is provided, loads pre-baked texture
|
|
272
|
-
* If curves are defined, bakes them
|
|
273
|
-
* If no curves AND no path, returns default texture (no baking
|
|
274
|
-
*
|
|
275
|
-
* The 4KB default texture is always created for shader compatibility,
|
|
276
|
-
* but baking is skipped when not needed (main performance win).
|
|
271
|
+
* If curveTexturePath is provided, loads pre-baked texture from file
|
|
272
|
+
* If curves are defined, bakes them synchronously on the main thread
|
|
273
|
+
* If no curves AND no path, returns default texture (no baking needed)
|
|
277
274
|
*/
|
|
278
275
|
declare const useCurveTextureAsync: (sizeCurve: CurveData | null, opacityCurve: CurveData | null, velocityCurve: CurveData | null, rotationSpeedCurve: CurveData | null, curveTexturePath?: string | null) => THREE.DataTexture;
|
|
279
276
|
|
package/dist/index.js
CHANGED
|
@@ -58,103 +58,79 @@ var init_react_store = __esm({
|
|
|
58
58
|
});
|
|
59
59
|
|
|
60
60
|
// src/useCurveTextureAsync.ts
|
|
61
|
-
import { useRef, useEffect } from "react";
|
|
61
|
+
import { useRef, useEffect, useMemo } from "react";
|
|
62
62
|
import {
|
|
63
63
|
createDefaultCurveTexture,
|
|
64
|
+
createCombinedCurveTexture,
|
|
64
65
|
loadCurveTextureFromPath
|
|
65
66
|
} from "core-vfx";
|
|
66
|
-
var
|
|
67
|
+
var useCurveTextureAsync;
|
|
67
68
|
var init_useCurveTextureAsync = __esm({
|
|
68
69
|
"src/useCurveTextureAsync.ts"() {
|
|
69
70
|
"use strict";
|
|
70
|
-
import_meta = {};
|
|
71
|
-
curveWorker = null;
|
|
72
|
-
curveWorkerCallbacks = /* @__PURE__ */ new Map();
|
|
73
|
-
curveWorkerIdCounter = 0;
|
|
74
|
-
getCurveWorker = () => {
|
|
75
|
-
if (!curveWorker) {
|
|
76
|
-
curveWorker = new Worker(new URL("./curveWorker.js", import_meta.url), {
|
|
77
|
-
type: "module"
|
|
78
|
-
});
|
|
79
|
-
curveWorker.onmessage = (e) => {
|
|
80
|
-
const { id, rgba } = e.data;
|
|
81
|
-
const callback = curveWorkerCallbacks.get(id);
|
|
82
|
-
if (callback) {
|
|
83
|
-
callback(rgba);
|
|
84
|
-
curveWorkerCallbacks.delete(id);
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
return curveWorker;
|
|
89
|
-
};
|
|
90
|
-
bakeCurvesAsync = (sizeCurve, opacityCurve, velocityCurve, rotationSpeedCurve) => {
|
|
91
|
-
return new Promise((resolve) => {
|
|
92
|
-
const worker = getCurveWorker();
|
|
93
|
-
const id = curveWorkerIdCounter++;
|
|
94
|
-
curveWorkerCallbacks.set(id, resolve);
|
|
95
|
-
worker.postMessage({
|
|
96
|
-
id,
|
|
97
|
-
sizeCurve,
|
|
98
|
-
opacityCurve,
|
|
99
|
-
velocityCurve,
|
|
100
|
-
rotationSpeedCurve
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
};
|
|
104
71
|
useCurveTextureAsync = (sizeCurve, opacityCurve, velocityCurve, rotationSpeedCurve, curveTexturePath = null) => {
|
|
105
72
|
const textureRef = useRef(null);
|
|
106
|
-
const pendingRef = useRef(null);
|
|
107
73
|
if (!textureRef.current) {
|
|
108
74
|
textureRef.current = createDefaultCurveTexture();
|
|
109
75
|
}
|
|
76
|
+
const hasAnyCurve = sizeCurve || opacityCurve || velocityCurve || rotationSpeedCurve;
|
|
77
|
+
useMemo(() => {
|
|
78
|
+
if (!curveTexturePath && hasAnyCurve && textureRef.current) {
|
|
79
|
+
const bakedTexture = createCombinedCurveTexture(
|
|
80
|
+
sizeCurve,
|
|
81
|
+
opacityCurve,
|
|
82
|
+
velocityCurve,
|
|
83
|
+
rotationSpeedCurve
|
|
84
|
+
);
|
|
85
|
+
const srcData = bakedTexture.image.data;
|
|
86
|
+
const dstData = textureRef.current.image.data;
|
|
87
|
+
if (srcData && dstData) {
|
|
88
|
+
dstData.set(srcData);
|
|
89
|
+
textureRef.current.needsUpdate = true;
|
|
90
|
+
}
|
|
91
|
+
bakedTexture.dispose();
|
|
92
|
+
}
|
|
93
|
+
}, [
|
|
94
|
+
sizeCurve,
|
|
95
|
+
opacityCurve,
|
|
96
|
+
velocityCurve,
|
|
97
|
+
rotationSpeedCurve,
|
|
98
|
+
curveTexturePath,
|
|
99
|
+
hasAnyCurve
|
|
100
|
+
]);
|
|
110
101
|
useEffect(() => {
|
|
111
|
-
|
|
112
|
-
pendingRef.current = requestId;
|
|
113
|
-
const hasAnyCurve = sizeCurve || opacityCurve || velocityCurve || rotationSpeedCurve;
|
|
114
|
-
if (curveTexturePath) {
|
|
102
|
+
if (curveTexturePath && textureRef.current) {
|
|
115
103
|
loadCurveTextureFromPath(curveTexturePath, textureRef.current).catch(
|
|
116
104
|
(err) => {
|
|
117
105
|
console.warn(
|
|
118
106
|
`Failed to load curve texture: ${curveTexturePath}, falling back to baking`,
|
|
119
107
|
err
|
|
120
108
|
);
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
109
|
+
if (hasAnyCurve && textureRef.current) {
|
|
110
|
+
const bakedTexture = createCombinedCurveTexture(
|
|
111
|
+
sizeCurve,
|
|
112
|
+
opacityCurve,
|
|
113
|
+
velocityCurve,
|
|
114
|
+
rotationSpeedCurve
|
|
115
|
+
);
|
|
116
|
+
const srcData = bakedTexture.image.data;
|
|
117
|
+
const dstData = textureRef.current.image.data;
|
|
118
|
+
if (srcData && dstData) {
|
|
119
|
+
dstData.set(srcData);
|
|
130
120
|
textureRef.current.needsUpdate = true;
|
|
131
121
|
}
|
|
132
|
-
|
|
122
|
+
bakedTexture.dispose();
|
|
123
|
+
}
|
|
133
124
|
}
|
|
134
125
|
);
|
|
135
|
-
} else if (hasAnyCurve) {
|
|
136
|
-
bakeCurvesAsync(
|
|
137
|
-
sizeCurve,
|
|
138
|
-
opacityCurve,
|
|
139
|
-
velocityCurve,
|
|
140
|
-
rotationSpeedCurve
|
|
141
|
-
).then((rgba) => {
|
|
142
|
-
var _a;
|
|
143
|
-
if (pendingRef.current === requestId && ((_a = textureRef.current) == null ? void 0 : _a.image.data)) {
|
|
144
|
-
textureRef.current.image.data.set(rgba);
|
|
145
|
-
textureRef.current.needsUpdate = true;
|
|
146
|
-
}
|
|
147
|
-
});
|
|
148
126
|
}
|
|
149
|
-
return () => {
|
|
150
|
-
pendingRef.current = null;
|
|
151
|
-
};
|
|
152
127
|
}, [
|
|
128
|
+
curveTexturePath,
|
|
153
129
|
sizeCurve,
|
|
154
130
|
opacityCurve,
|
|
155
131
|
velocityCurve,
|
|
156
132
|
rotationSpeedCurve,
|
|
157
|
-
|
|
133
|
+
hasAnyCurve
|
|
158
134
|
]);
|
|
159
135
|
useEffect(() => {
|
|
160
136
|
return () => {
|
|
@@ -3630,7 +3606,7 @@ ${" ".repeat(indent - 2)}}`;
|
|
|
3630
3606
|
flushChanges();
|
|
3631
3607
|
}
|
|
3632
3608
|
const values2 = valuesRef.current;
|
|
3633
|
-
const
|
|
3609
|
+
const CURVE_RESOLUTION = 256;
|
|
3634
3610
|
const evaluateBezierSegment = (t, p0, p1, h0Out, h1In) => {
|
|
3635
3611
|
const cp0 = p0;
|
|
3636
3612
|
const cp1 = [p0[0] + ((h0Out == null ? void 0 : h0Out[0]) || 0), p0[1] + ((h0Out == null ? void 0 : h0Out[1]) || 0)];
|
|
@@ -3687,23 +3663,23 @@ ${" ".repeat(indent - 2)}}`;
|
|
|
3687
3663
|
return Math.max(-0.5, Math.min(1.5, py));
|
|
3688
3664
|
};
|
|
3689
3665
|
const bakeCurveToArray2 = (curveData) => {
|
|
3690
|
-
const data = new Float32Array(
|
|
3666
|
+
const data = new Float32Array(CURVE_RESOLUTION);
|
|
3691
3667
|
if (!(curveData == null ? void 0 : curveData.points) || !Array.isArray(curveData.points) || curveData.points.length < 2) {
|
|
3692
|
-
for (let i = 0; i <
|
|
3693
|
-
data[i] = 1 - i / (
|
|
3668
|
+
for (let i = 0; i < CURVE_RESOLUTION; i++) {
|
|
3669
|
+
data[i] = 1 - i / (CURVE_RESOLUTION - 1);
|
|
3694
3670
|
}
|
|
3695
3671
|
return data;
|
|
3696
3672
|
}
|
|
3697
3673
|
const firstPoint = curveData.points[0];
|
|
3698
3674
|
const lastPoint = curveData.points[curveData.points.length - 1];
|
|
3699
3675
|
if (!(firstPoint == null ? void 0 : firstPoint.pos) || !(lastPoint == null ? void 0 : lastPoint.pos) || !Array.isArray(firstPoint.pos) || !Array.isArray(lastPoint.pos)) {
|
|
3700
|
-
for (let i = 0; i <
|
|
3701
|
-
data[i] = 1 - i / (
|
|
3676
|
+
for (let i = 0; i < CURVE_RESOLUTION; i++) {
|
|
3677
|
+
data[i] = 1 - i / (CURVE_RESOLUTION - 1);
|
|
3702
3678
|
}
|
|
3703
3679
|
return data;
|
|
3704
3680
|
}
|
|
3705
|
-
for (let i = 0; i <
|
|
3706
|
-
const x = i / (
|
|
3681
|
+
for (let i = 0; i < CURVE_RESOLUTION; i++) {
|
|
3682
|
+
const x = i / (CURVE_RESOLUTION - 1);
|
|
3707
3683
|
data[i] = sampleCurveAtX(x, curveData.points);
|
|
3708
3684
|
}
|
|
3709
3685
|
return data;
|
|
@@ -3712,8 +3688,8 @@ ${" ".repeat(indent - 2)}}`;
|
|
|
3712
3688
|
const opacityData = bakeCurveToArray2(values2.fadeOpacityCurve);
|
|
3713
3689
|
const velocityData = bakeCurveToArray2(values2.velocityCurve);
|
|
3714
3690
|
const rotationSpeedData = bakeCurveToArray2(values2.rotationSpeedCurve);
|
|
3715
|
-
const rgba = new Float32Array(
|
|
3716
|
-
for (let i = 0; i <
|
|
3691
|
+
const rgba = new Float32Array(CURVE_RESOLUTION * 4);
|
|
3692
|
+
for (let i = 0; i < CURVE_RESOLUTION; i++) {
|
|
3717
3693
|
rgba[i * 4] = sizeData[i];
|
|
3718
3694
|
rgba[i * 4 + 1] = opacityData[i];
|
|
3719
3695
|
rgba[i * 4 + 2] = velocityData[i];
|
|
@@ -5426,7 +5402,7 @@ import {
|
|
|
5426
5402
|
useImperativeHandle,
|
|
5427
5403
|
useEffect as useEffect3,
|
|
5428
5404
|
useRef as useRef3,
|
|
5429
|
-
useMemo,
|
|
5405
|
+
useMemo as useMemo2,
|
|
5430
5406
|
useCallback as useCallback2,
|
|
5431
5407
|
useState as useState2
|
|
5432
5408
|
} from "react";
|
|
@@ -5458,7 +5434,7 @@ import {
|
|
|
5458
5434
|
Easing as Easing2,
|
|
5459
5435
|
Lighting,
|
|
5460
5436
|
bakeCurveToArray,
|
|
5461
|
-
createCombinedCurveTexture as
|
|
5437
|
+
createCombinedCurveTexture as createCombinedCurveTexture3
|
|
5462
5438
|
} from "core-vfx";
|
|
5463
5439
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
5464
5440
|
var VFXParticles;
|
|
@@ -5673,10 +5649,10 @@ var init_VFXParticles = __esm({
|
|
|
5673
5649
|
attractors,
|
|
5674
5650
|
collision
|
|
5675
5651
|
]);
|
|
5676
|
-
const sizeRange =
|
|
5677
|
-
const speedRange =
|
|
5678
|
-
const fadeSizeRange =
|
|
5679
|
-
const fadeOpacityRange =
|
|
5652
|
+
const sizeRange = useMemo2(() => toRange(size, [0.1, 0.3]), [size]);
|
|
5653
|
+
const speedRange = useMemo2(() => toRange(speed, [0.1, 0.1]), [speed]);
|
|
5654
|
+
const fadeSizeRange = useMemo2(() => toRange(fadeSize, [1, 0]), [fadeSize]);
|
|
5655
|
+
const fadeOpacityRange = useMemo2(
|
|
5680
5656
|
() => toRange(fadeOpacity, [1, 0]),
|
|
5681
5657
|
[fadeOpacity]
|
|
5682
5658
|
);
|
|
@@ -5696,26 +5672,26 @@ var init_VFXParticles = __esm({
|
|
|
5696
5672
|
}
|
|
5697
5673
|
};
|
|
5698
5674
|
}, [curveTexture]);
|
|
5699
|
-
const lifetimeRange =
|
|
5700
|
-
const rotation3D =
|
|
5701
|
-
const rotationSpeed3D =
|
|
5675
|
+
const lifetimeRange = useMemo2(() => toRange(lifetime, [1, 2]), [lifetime]);
|
|
5676
|
+
const rotation3D = useMemo2(() => toRotation3D(rotation), [rotation]);
|
|
5677
|
+
const rotationSpeed3D = useMemo2(
|
|
5702
5678
|
() => toRotation3D(rotationSpeed),
|
|
5703
5679
|
[rotationSpeed]
|
|
5704
5680
|
);
|
|
5705
|
-
const direction3D =
|
|
5706
|
-
const startPosition3D =
|
|
5681
|
+
const direction3D = useMemo2(() => toRotation3D(direction), [direction]);
|
|
5682
|
+
const startPosition3D = useMemo2(
|
|
5707
5683
|
() => toRotation3D(startPosition),
|
|
5708
5684
|
[startPosition]
|
|
5709
5685
|
);
|
|
5710
|
-
const emitterRadiusRange =
|
|
5686
|
+
const emitterRadiusRange = useMemo2(
|
|
5711
5687
|
() => toRange(emitterRadius, [0, 1]),
|
|
5712
5688
|
[emitterRadius]
|
|
5713
5689
|
);
|
|
5714
|
-
const emitterHeightRange =
|
|
5690
|
+
const emitterHeightRange = useMemo2(
|
|
5715
5691
|
() => toRange(emitterHeight, [0, 1]),
|
|
5716
5692
|
[emitterHeight]
|
|
5717
5693
|
);
|
|
5718
|
-
const activeFeatures =
|
|
5694
|
+
const activeFeatures = useMemo2(
|
|
5719
5695
|
() => ({
|
|
5720
5696
|
// Storage array features
|
|
5721
5697
|
needsPerParticleColor: activeNeedsPerParticleColor,
|
|
@@ -5735,33 +5711,33 @@ var init_VFXParticles = __esm({
|
|
|
5735
5711
|
activeCollision
|
|
5736
5712
|
]
|
|
5737
5713
|
);
|
|
5738
|
-
const frictionIntensityRange =
|
|
5714
|
+
const frictionIntensityRange = useMemo2(() => {
|
|
5739
5715
|
if (typeof friction === "object" && friction !== null && "intensity" in friction) {
|
|
5740
5716
|
return toRange(friction.intensity, [0, 0]);
|
|
5741
5717
|
}
|
|
5742
5718
|
return [0, 0];
|
|
5743
5719
|
}, [friction]);
|
|
5744
|
-
const frictionEasingType =
|
|
5720
|
+
const frictionEasingType = useMemo2(() => {
|
|
5745
5721
|
var _a2;
|
|
5746
5722
|
if (typeof friction === "object" && friction !== null && "easing" in friction) {
|
|
5747
5723
|
return easingToType((_a2 = friction.easing) != null ? _a2 : "linear");
|
|
5748
5724
|
}
|
|
5749
5725
|
return 0;
|
|
5750
5726
|
}, [friction]);
|
|
5751
|
-
const startColors =
|
|
5727
|
+
const startColors = useMemo2(() => {
|
|
5752
5728
|
const colors = colorStart.slice(0, 8).map(hexToRgb);
|
|
5753
5729
|
while (colors.length < 8)
|
|
5754
5730
|
colors.push(colors[colors.length - 1] || [1, 1, 1]);
|
|
5755
5731
|
return colors;
|
|
5756
5732
|
}, [colorStart]);
|
|
5757
5733
|
const effectiveColorEnd = colorEnd != null ? colorEnd : colorStart;
|
|
5758
|
-
const endColors =
|
|
5734
|
+
const endColors = useMemo2(() => {
|
|
5759
5735
|
const colors = effectiveColorEnd.slice(0, 8).map(hexToRgb);
|
|
5760
5736
|
while (colors.length < 8)
|
|
5761
5737
|
colors.push(colors[colors.length - 1] || [1, 1, 1]);
|
|
5762
5738
|
return colors;
|
|
5763
5739
|
}, [effectiveColorEnd]);
|
|
5764
|
-
const uniforms =
|
|
5740
|
+
const uniforms = useMemo2(
|
|
5765
5741
|
() => {
|
|
5766
5742
|
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
5767
5743
|
return {
|
|
@@ -6060,7 +6036,7 @@ var init_VFXParticles = __esm({
|
|
|
6060
6036
|
orientAxis,
|
|
6061
6037
|
stretchBySpeed
|
|
6062
6038
|
]);
|
|
6063
|
-
const storage =
|
|
6039
|
+
const storage = useMemo2(() => {
|
|
6064
6040
|
const arrays = {
|
|
6065
6041
|
positions: instancedArray(activeMaxParticles, "vec3"),
|
|
6066
6042
|
velocities: instancedArray(activeMaxParticles, "vec3"),
|
|
@@ -6085,15 +6061,15 @@ var init_VFXParticles = __esm({
|
|
|
6085
6061
|
activeFeatures.needsRotation,
|
|
6086
6062
|
activeFeatures.needsPerParticleColor
|
|
6087
6063
|
]);
|
|
6088
|
-
const computeInit =
|
|
6064
|
+
const computeInit = useMemo2(
|
|
6089
6065
|
() => createInitCompute(storage, activeMaxParticles),
|
|
6090
6066
|
[storage, activeMaxParticles]
|
|
6091
6067
|
);
|
|
6092
|
-
const computeSpawn =
|
|
6068
|
+
const computeSpawn = useMemo2(
|
|
6093
6069
|
() => createSpawnCompute(storage, uniforms, activeMaxParticles),
|
|
6094
6070
|
[storage, uniforms, activeMaxParticles]
|
|
6095
6071
|
);
|
|
6096
|
-
const computeUpdate =
|
|
6072
|
+
const computeUpdate = useMemo2(
|
|
6097
6073
|
() => createUpdateCompute(
|
|
6098
6074
|
storage,
|
|
6099
6075
|
uniforms,
|
|
@@ -6109,7 +6085,7 @@ var init_VFXParticles = __esm({
|
|
|
6109
6085
|
),
|
|
6110
6086
|
[storage, uniforms, curveTexture, activeMaxParticles, activeFeatures]
|
|
6111
6087
|
);
|
|
6112
|
-
const material =
|
|
6088
|
+
const material = useMemo2(
|
|
6113
6089
|
() => createParticleMaterial(storage, uniforms, curveTexture, {
|
|
6114
6090
|
alphaMap,
|
|
6115
6091
|
flipbook,
|
|
@@ -6146,7 +6122,7 @@ var init_VFXParticles = __esm({
|
|
|
6146
6122
|
activeShadow
|
|
6147
6123
|
]
|
|
6148
6124
|
);
|
|
6149
|
-
const renderObject =
|
|
6125
|
+
const renderObject = useMemo2(() => {
|
|
6150
6126
|
if (activeGeometry) {
|
|
6151
6127
|
const mesh = new THREE2.InstancedMesh(
|
|
6152
6128
|
activeGeometry,
|
|
@@ -6358,7 +6334,7 @@ var init_VFXParticles = __esm({
|
|
|
6358
6334
|
nextIndex.current = 0;
|
|
6359
6335
|
};
|
|
6360
6336
|
}, []);
|
|
6361
|
-
const particleAPI =
|
|
6337
|
+
const particleAPI = useMemo2(
|
|
6362
6338
|
() => ({
|
|
6363
6339
|
spawn,
|
|
6364
6340
|
start,
|
|
@@ -7148,7 +7124,7 @@ export {
|
|
|
7148
7124
|
VFXEmitter,
|
|
7149
7125
|
VFXParticles,
|
|
7150
7126
|
bakeCurveToArray,
|
|
7151
|
-
|
|
7127
|
+
createCombinedCurveTexture3 as createCombinedCurveTexture,
|
|
7152
7128
|
useCurveTextureAsync,
|
|
7153
7129
|
useVFXEmitter,
|
|
7154
7130
|
useVFXStore
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "r3f-vfx",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"prepublishOnly": "bun run copy-readme"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"core-vfx": "0.0.
|
|
27
|
+
"core-vfx": "0.0.5",
|
|
28
28
|
"zustand": "5.0.10"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
package/dist/curveWorker.d.ts
DELETED
package/dist/curveWorker.js
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
// src/curveWorker.js
|
|
2
|
-
var CURVE_RESOLUTION = 256;
|
|
3
|
-
var evaluateBezierSegment = (t, p0, p1, h0Out, h1In) => {
|
|
4
|
-
const cp0 = p0;
|
|
5
|
-
const cp1 = [p0[0] + ((h0Out == null ? void 0 : h0Out[0]) || 0), p0[1] + ((h0Out == null ? void 0 : h0Out[1]) || 0)];
|
|
6
|
-
const cp2 = [p1[0] + ((h1In == null ? void 0 : h1In[0]) || 0), p1[1] + ((h1In == null ? void 0 : h1In[1]) || 0)];
|
|
7
|
-
const cp3 = p1;
|
|
8
|
-
const mt = 1 - t;
|
|
9
|
-
const mt2 = mt * mt;
|
|
10
|
-
const mt3 = mt2 * mt;
|
|
11
|
-
const t2 = t * t;
|
|
12
|
-
const t3 = t2 * t;
|
|
13
|
-
return [
|
|
14
|
-
mt3 * cp0[0] + 3 * mt2 * t * cp1[0] + 3 * mt * t2 * cp2[0] + t3 * cp3[0],
|
|
15
|
-
mt3 * cp0[1] + 3 * mt2 * t * cp1[1] + 3 * mt * t2 * cp2[1] + t3 * cp3[1]
|
|
16
|
-
];
|
|
17
|
-
};
|
|
18
|
-
var sampleCurveAtX = (x, points) => {
|
|
19
|
-
var _a, _b, _c, _d;
|
|
20
|
-
if (!points || points.length < 2) return x;
|
|
21
|
-
if (!((_a = points[0]) == null ? void 0 : _a.pos) || !((_b = points[points.length - 1]) == null ? void 0 : _b.pos)) return x;
|
|
22
|
-
let segmentIdx = 0;
|
|
23
|
-
for (let i = 0; i < points.length - 1; i++) {
|
|
24
|
-
if (((_c = points[i]) == null ? void 0 : _c.pos) && ((_d = points[i + 1]) == null ? void 0 : _d.pos) && x >= points[i].pos[0] && x <= points[i + 1].pos[0]) {
|
|
25
|
-
segmentIdx = i;
|
|
26
|
-
break;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
const p0 = points[segmentIdx];
|
|
30
|
-
const p1 = points[segmentIdx + 1];
|
|
31
|
-
if (!(p0 == null ? void 0 : p0.pos) || !(p1 == null ? void 0 : p1.pos)) return x;
|
|
32
|
-
let tLow = 0;
|
|
33
|
-
let tHigh = 1;
|
|
34
|
-
let t = 0.5;
|
|
35
|
-
for (let iter = 0; iter < 20; iter++) {
|
|
36
|
-
const [px] = evaluateBezierSegment(
|
|
37
|
-
t,
|
|
38
|
-
p0.pos,
|
|
39
|
-
p1.pos,
|
|
40
|
-
p0.handleOut,
|
|
41
|
-
p1.handleIn
|
|
42
|
-
);
|
|
43
|
-
if (Math.abs(px - x) < 1e-4) break;
|
|
44
|
-
if (px < x) {
|
|
45
|
-
tLow = t;
|
|
46
|
-
} else {
|
|
47
|
-
tHigh = t;
|
|
48
|
-
}
|
|
49
|
-
t = (tLow + tHigh) / 2;
|
|
50
|
-
}
|
|
51
|
-
const [, py] = evaluateBezierSegment(
|
|
52
|
-
t,
|
|
53
|
-
p0.pos,
|
|
54
|
-
p1.pos,
|
|
55
|
-
p0.handleOut,
|
|
56
|
-
p1.handleIn
|
|
57
|
-
);
|
|
58
|
-
return Math.max(-0.5, Math.min(1.5, py));
|
|
59
|
-
};
|
|
60
|
-
var bakeCurveToArray = (curveData) => {
|
|
61
|
-
const data = new Float32Array(CURVE_RESOLUTION);
|
|
62
|
-
if (!(curveData == null ? void 0 : curveData.points) || !Array.isArray(curveData.points) || curveData.points.length < 2) {
|
|
63
|
-
for (let i = 0; i < CURVE_RESOLUTION; i++) {
|
|
64
|
-
data[i] = 1 - i / (CURVE_RESOLUTION - 1);
|
|
65
|
-
}
|
|
66
|
-
return data;
|
|
67
|
-
}
|
|
68
|
-
const firstPoint = curveData.points[0];
|
|
69
|
-
const lastPoint = curveData.points[curveData.points.length - 1];
|
|
70
|
-
if (!(firstPoint == null ? void 0 : firstPoint.pos) || !(lastPoint == null ? void 0 : lastPoint.pos) || !Array.isArray(firstPoint.pos) || !Array.isArray(lastPoint.pos)) {
|
|
71
|
-
for (let i = 0; i < CURVE_RESOLUTION; i++) {
|
|
72
|
-
data[i] = 1 - i / (CURVE_RESOLUTION - 1);
|
|
73
|
-
}
|
|
74
|
-
return data;
|
|
75
|
-
}
|
|
76
|
-
for (let i = 0; i < CURVE_RESOLUTION; i++) {
|
|
77
|
-
const x = i / (CURVE_RESOLUTION - 1);
|
|
78
|
-
data[i] = sampleCurveAtX(x, curveData.points);
|
|
79
|
-
}
|
|
80
|
-
return data;
|
|
81
|
-
};
|
|
82
|
-
var bakeCombinedCurves = (sizeCurve, opacityCurve, velocityCurve, rotationSpeedCurve) => {
|
|
83
|
-
const sizeData = bakeCurveToArray(sizeCurve);
|
|
84
|
-
const opacityData = bakeCurveToArray(opacityCurve);
|
|
85
|
-
const velocityData = bakeCurveToArray(velocityCurve);
|
|
86
|
-
const rotationSpeedData = bakeCurveToArray(rotationSpeedCurve);
|
|
87
|
-
const rgba = new Float32Array(CURVE_RESOLUTION * 4);
|
|
88
|
-
for (let i = 0; i < CURVE_RESOLUTION; i++) {
|
|
89
|
-
rgba[i * 4] = sizeData[i];
|
|
90
|
-
rgba[i * 4 + 1] = opacityData[i];
|
|
91
|
-
rgba[i * 4 + 2] = velocityData[i];
|
|
92
|
-
rgba[i * 4 + 3] = rotationSpeedData[i];
|
|
93
|
-
}
|
|
94
|
-
return rgba;
|
|
95
|
-
};
|
|
96
|
-
self.onmessage = (e) => {
|
|
97
|
-
const { id, sizeCurve, opacityCurve, velocityCurve, rotationSpeedCurve } = e.data;
|
|
98
|
-
const rgba = bakeCombinedCurves(
|
|
99
|
-
sizeCurve,
|
|
100
|
-
opacityCurve,
|
|
101
|
-
velocityCurve,
|
|
102
|
-
rotationSpeedCurve
|
|
103
|
-
);
|
|
104
|
-
self.postMessage({ id, rgba }, [rgba.buffer]);
|
|
105
|
-
};
|