hz-particles 1.0.13 → 1.0.15
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-lib/hz-particles-r3f.cjs +3 -3
- package/dist-lib/hz-particles-r3f.mjs +386 -318
- package/dist-lib/hz-particles.cjs +24 -10
- package/dist-lib/hz-particles.d.ts +43 -7
- package/dist-lib/hz-particles.mjs +1107 -715
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class W {
|
|
2
2
|
constructor(t = {}) {
|
|
3
3
|
this.config = t, this._posOut = [0, 0, 0], this._rotMatrix = null, this._invRotMatrix = null, this._cachedRotX = void 0, this._cachedRotY = void 0, this._cachedRotZ = void 0;
|
|
4
4
|
}
|
|
@@ -6,20 +6,20 @@ class Z {
|
|
|
6
6
|
* Rebuild the cached rotation matrix if config values changed.
|
|
7
7
|
*/
|
|
8
8
|
_updateRotationMatrix() {
|
|
9
|
-
const t = this.config.
|
|
9
|
+
const t = this.config.emissionRotationX || 0, e = this.config.emissionRotationY || 0, i = this.config.emissionRotationZ || 0;
|
|
10
10
|
if (t === this._cachedRotX && e === this._cachedRotY && i === this._cachedRotZ)
|
|
11
11
|
return;
|
|
12
12
|
this._cachedRotX = t, this._cachedRotY = e, this._cachedRotZ = i;
|
|
13
|
-
const
|
|
13
|
+
const s = t * Math.PI / 180, r = e * Math.PI / 180, n = i * Math.PI / 180, o = Math.cos(s), a = Math.sin(s), l = Math.cos(r), d = Math.sin(r), u = Math.cos(n), f = Math.sin(n);
|
|
14
14
|
this._rotMatrix = [
|
|
15
|
-
l *
|
|
16
|
-
|
|
17
|
-
o *
|
|
15
|
+
l * u,
|
|
16
|
+
a * d * u - o * f,
|
|
17
|
+
o * d * u + a * f,
|
|
18
18
|
l * f,
|
|
19
|
-
|
|
20
|
-
o *
|
|
21
|
-
-
|
|
22
|
-
|
|
19
|
+
a * d * f + o * u,
|
|
20
|
+
o * d * f - a * u,
|
|
21
|
+
-d,
|
|
22
|
+
a * l,
|
|
23
23
|
o * l
|
|
24
24
|
], this._invRotMatrix = [
|
|
25
25
|
this._rotMatrix[0],
|
|
@@ -34,79 +34,79 @@ class Z {
|
|
|
34
34
|
];
|
|
35
35
|
}
|
|
36
36
|
emitParticle(t, e, i) {
|
|
37
|
-
const
|
|
38
|
-
if (this.config.emissionShape === "cube" ? this._emitFromCube(
|
|
37
|
+
const s = this._posOut;
|
|
38
|
+
if (this.config.emissionShape === "cube" ? this._emitFromCube(s) : this.config.emissionShape === "sphere" ? this._emitFromSphere(s) : this.config.emissionShape === "square" ? this._emitFromSquare(s) : this.config.emissionShape === "circle" ? this._emitFromCircle(s) : this.config.emissionShape === "cylinder" ? this._emitFromCylinder(s) : this.config.emissionShape === "plain" ? this._emitFromPlain(s) : this.config.emissionShape === "cone" ? this._emitFromCone(s) : this.config.emissionShape === "torus" ? this._emitFromTorus(s) : this.config.emissionShape === "line" ? this._emitFromLine(s) : this.config.emissionShape === "hemisphere" ? this._emitFromHemisphere(s) : this.config.emissionShape === "disc" ? this._emitFromDisc(s) : this.config.emissionShape === "annulus" ? this._emitFromAnnulus(s) : this.config.emissionShape === "capsule" ? this._emitFromCapsule(s) : this.config.emissionShape === "arc" ? this._emitFromArc(s) : this.config.emissionShape === "spiral" ? this._emitFromSpiral(s) : this.config.emissionShape === "frustum" ? this._emitFromFrustum(s) : this.config.emissionShape === "cubeSurface" ? this._emitFromCubeSurface(s) : this.config.emissionShape === "sphereSurface" ? this._emitFromSphereSurface(s) : this.config.emissionShape === "boxFrame" ? this._emitFromBoxFrame(s) : this.config.emissionShape === "polygon" ? this._emitFromPolygon(s) : this.config.emissionShape === "rectangle" ? this._emitFromRectangle(s) : (s[0] = 0, s[1] = 0, s[2] = 0), this.config.emissionRotationX || this.config.emissionRotationY || this.config.emissionRotationZ) {
|
|
39
39
|
this._updateRotationMatrix();
|
|
40
|
-
const o = this._rotMatrix,
|
|
41
|
-
|
|
40
|
+
const o = this._rotMatrix, a = s[0], l = s[1], d = s[2];
|
|
41
|
+
s[0] = o[0] * a + o[1] * l + o[2] * d, s[1] = o[3] * a + o[4] * l + o[5] * d, s[2] = o[6] * a + o[7] * l + o[8] * d;
|
|
42
42
|
}
|
|
43
|
-
(this.config.
|
|
43
|
+
(this.config.emissionTranslationX || this.config.emissionTranslationY || this.config.emissionTranslationZ) && (s[0] += this.config.emissionTranslationX || 0, s[1] += this.config.emissionTranslationY || 0, s[2] += this.config.emissionTranslationZ || 0);
|
|
44
44
|
const r = e * 8;
|
|
45
|
-
t[r] =
|
|
45
|
+
t[r] = s[0], t[r + 1] = s[1], t[r + 2] = s[2];
|
|
46
46
|
const n = e * 4;
|
|
47
|
-
this.calculateVelocity(
|
|
47
|
+
this.calculateVelocity(s[0], s[1], s[2], i, n), this.setParticleColor(t, r), this.setParticleLifetime(t, r);
|
|
48
48
|
}
|
|
49
49
|
// Apply rotation using cached matrix
|
|
50
50
|
applyRotation(t, e, i) {
|
|
51
51
|
this._updateRotationMatrix();
|
|
52
|
-
const
|
|
52
|
+
const s = this._rotMatrix;
|
|
53
53
|
return [
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
s[0] * t + s[1] * e + s[2] * i,
|
|
55
|
+
s[3] * t + s[4] * e + s[5] * i,
|
|
56
|
+
s[6] * t + s[7] * e + s[8] * i
|
|
57
57
|
];
|
|
58
58
|
}
|
|
59
59
|
// Apply inverse rotation using cached matrix
|
|
60
60
|
inverseRotation(t, e, i) {
|
|
61
61
|
this._updateRotationMatrix();
|
|
62
|
-
const
|
|
62
|
+
const s = this._invRotMatrix;
|
|
63
63
|
return [
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
s[0] * t + s[1] * e + s[2] * i,
|
|
65
|
+
s[3] * t + s[4] * e + s[5] * i,
|
|
66
|
+
s[6] * t + s[7] * e + s[8] * i
|
|
67
67
|
];
|
|
68
68
|
}
|
|
69
69
|
_emitFromCube(t) {
|
|
70
70
|
let e = this.config.innerLength || 0, i = this.config.outerLength || this.config.cubeLength;
|
|
71
71
|
if (e > 0) {
|
|
72
|
-
const
|
|
73
|
-
let o,
|
|
74
|
-
switch (
|
|
72
|
+
const s = Math.floor(Math.random() * 6), r = Math.random() - 0.5, n = Math.random() - 0.5;
|
|
73
|
+
let o, a, l;
|
|
74
|
+
switch (s) {
|
|
75
75
|
case 0:
|
|
76
|
-
o = r,
|
|
76
|
+
o = r, a = n, l = 0.5;
|
|
77
77
|
break;
|
|
78
78
|
case 1:
|
|
79
|
-
o = r,
|
|
79
|
+
o = r, a = n, l = -0.5;
|
|
80
80
|
break;
|
|
81
81
|
case 2:
|
|
82
|
-
o = 0.5,
|
|
82
|
+
o = 0.5, a = r, l = n;
|
|
83
83
|
break;
|
|
84
84
|
case 3:
|
|
85
|
-
o = -0.5,
|
|
85
|
+
o = -0.5, a = r, l = n;
|
|
86
86
|
break;
|
|
87
87
|
case 4:
|
|
88
|
-
o = r,
|
|
88
|
+
o = r, a = 0.5, l = n;
|
|
89
89
|
break;
|
|
90
90
|
case 5:
|
|
91
|
-
o = r,
|
|
91
|
+
o = r, a = -0.5, l = n;
|
|
92
92
|
break;
|
|
93
93
|
}
|
|
94
|
-
const
|
|
95
|
-
t[0] = o *
|
|
94
|
+
const d = Math.random(), u = e + d * (i - e);
|
|
95
|
+
t[0] = o * u, t[1] = a * u, t[2] = l * u;
|
|
96
96
|
} else
|
|
97
97
|
t[0] = (Math.random() - 0.5) * i, t[1] = (Math.random() - 0.5) * i, t[2] = (Math.random() - 0.5) * i;
|
|
98
98
|
}
|
|
99
99
|
_emitFromSphere(t) {
|
|
100
|
-
const e = Math.random() * 2 * Math.PI, i = Math.acos(2 * Math.random() - 1),
|
|
100
|
+
const e = Math.random() * 2 * Math.PI, i = Math.acos(2 * Math.random() - 1), s = Math.sin(i) * Math.cos(e), r = Math.sin(i) * Math.sin(e), n = Math.cos(i);
|
|
101
101
|
let o;
|
|
102
|
-
this.config.innerRadius === 0 ? o = this.config.outerRadius * Math.cbrt(Math.random()) : o = this.config.innerRadius + (this.config.outerRadius - this.config.innerRadius) * Math.random(), t[0] =
|
|
102
|
+
this.config.innerRadius === 0 ? o = this.config.outerRadius * Math.cbrt(Math.random()) : o = this.config.innerRadius + (this.config.outerRadius - this.config.innerRadius) * Math.random(), t[0] = s * o, t[1] = r * o, t[2] = n * o;
|
|
103
103
|
}
|
|
104
104
|
_emitFromSquare(t) {
|
|
105
105
|
const e = this.config.squareInnerSize || 0, i = this.config.squareSize || 2;
|
|
106
106
|
if (e > 0) {
|
|
107
|
-
const
|
|
107
|
+
const s = Math.floor(Math.random() * 4);
|
|
108
108
|
let r = e + (i - e) * Math.random();
|
|
109
|
-
switch (
|
|
109
|
+
switch (s) {
|
|
110
110
|
case 0:
|
|
111
111
|
t[0] = (Math.random() * 2 - 1) * r, t[1] = r;
|
|
112
112
|
break;
|
|
@@ -125,71 +125,71 @@ class Z {
|
|
|
125
125
|
t[2] = 0;
|
|
126
126
|
}
|
|
127
127
|
_emitFromCircle(t) {
|
|
128
|
-
const e = this.config.circleInnerRadius || 0, i = this.config.circleOuterRadius || 2,
|
|
128
|
+
const e = this.config.circleInnerRadius || 0, i = this.config.circleOuterRadius || 2, s = Math.random() * Math.PI * 2;
|
|
129
129
|
let r;
|
|
130
|
-
e > 0 ? r = e + (i - e) * Math.random() : r = i * Math.sqrt(Math.random()), t[0] = Math.cos(
|
|
130
|
+
e > 0 ? r = e + (i - e) * Math.random() : r = i * Math.sqrt(Math.random()), t[0] = Math.cos(s) * r, t[1] = Math.sin(s) * r, t[2] = 0;
|
|
131
131
|
}
|
|
132
132
|
_emitFromPlain(t) {
|
|
133
133
|
const e = this.config.planeWidth || 2, i = this.config.planeDepth || 2;
|
|
134
134
|
t[0] = (Math.random() - 0.5) * e, t[1] = 0, t[2] = (Math.random() - 0.5) * i;
|
|
135
135
|
}
|
|
136
136
|
_emitFromCone(t) {
|
|
137
|
-
const e = this.config.coneInnerRadius || 0, i = this.config.coneOuterRadius || 2,
|
|
137
|
+
const e = this.config.coneInnerRadius || 0, i = this.config.coneOuterRadius || 2, s = this.config.coneHeight || 4, r = Math.random() * Math.PI * 2, n = Math.random(), o = n * s, a = i * (1 - n);
|
|
138
138
|
let l;
|
|
139
139
|
if (e > 0) {
|
|
140
|
-
const
|
|
141
|
-
l =
|
|
140
|
+
const d = e * (1 - n);
|
|
141
|
+
l = d + (a - d) * Math.random();
|
|
142
142
|
} else
|
|
143
|
-
l =
|
|
143
|
+
l = a * Math.sqrt(Math.random());
|
|
144
144
|
t[0] = Math.cos(r) * l, t[1] = o, t[2] = Math.sin(r) * l;
|
|
145
145
|
}
|
|
146
146
|
_emitFromTorus(t) {
|
|
147
|
-
const e = this.config.torusMajorRadius || 2, i = this.config.torusMinorRadius || 0.5,
|
|
148
|
-
t[0] = (e + n * Math.cos(r)) * Math.cos(
|
|
147
|
+
const e = this.config.torusMajorRadius || 2, i = this.config.torusMinorRadius || 0.5, s = Math.random() * Math.PI * 2, r = Math.random() * Math.PI * 2, n = i * Math.sqrt(Math.random());
|
|
148
|
+
t[0] = (e + n * Math.cos(r)) * Math.cos(s), t[1] = n * Math.sin(r), t[2] = (e + n * Math.cos(r)) * Math.sin(s);
|
|
149
149
|
}
|
|
150
150
|
_emitFromLine(t) {
|
|
151
151
|
const e = this.config.lineLength || 4, i = Math.random();
|
|
152
152
|
t[0] = 0, t[1] = (i - 0.5) * e, t[2] = 0;
|
|
153
153
|
}
|
|
154
154
|
_emitFromHemisphere(t) {
|
|
155
|
-
const e = this.config.hemisphereInnerRadius || 0, i = this.config.hemisphereOuterRadius || 2,
|
|
155
|
+
const e = this.config.hemisphereInnerRadius || 0, i = this.config.hemisphereOuterRadius || 2, s = Math.random() * Math.PI * 2, r = Math.acos(Math.random()), n = Math.sin(r) * Math.cos(s), o = Math.cos(r), a = Math.sin(r) * Math.sin(s);
|
|
156
156
|
let l;
|
|
157
|
-
e > 0 ? l = e + (i - e) * Math.random() : l = i * Math.cbrt(Math.random()), t[0] = n * l, t[1] = o * l, t[2] =
|
|
157
|
+
e > 0 ? l = e + (i - e) * Math.random() : l = i * Math.cbrt(Math.random()), t[0] = n * l, t[1] = o * l, t[2] = a * l;
|
|
158
158
|
}
|
|
159
159
|
_emitFromDisc(t) {
|
|
160
|
-
const e = this.config.discRadius || 2, i = Math.random() * Math.PI * 2,
|
|
161
|
-
t[0] = Math.cos(i) *
|
|
160
|
+
const e = this.config.discRadius || 2, i = Math.random() * Math.PI * 2, s = e * Math.sqrt(Math.random());
|
|
161
|
+
t[0] = Math.cos(i) * s, t[1] = 0, t[2] = Math.sin(i) * s;
|
|
162
162
|
}
|
|
163
163
|
_emitFromAnnulus(t) {
|
|
164
|
-
const e = this.config.annulusInnerRadius || 1, i = this.config.annulusOuterRadius || 2,
|
|
165
|
-
t[0] = Math.cos(
|
|
164
|
+
const e = this.config.annulusInnerRadius || 1, i = this.config.annulusOuterRadius || 2, s = Math.random() * Math.PI * 2, r = e + (i - e) * Math.random();
|
|
165
|
+
t[0] = Math.cos(s) * r, t[1] = 0, t[2] = Math.sin(s) * r;
|
|
166
166
|
}
|
|
167
167
|
_emitFromCapsule(t) {
|
|
168
|
-
const e = this.config.capsuleRadius || 0.5, i = this.config.capsuleHeight || 4,
|
|
168
|
+
const e = this.config.capsuleRadius || 0.5, i = this.config.capsuleHeight || 4, s = i * 0.5, r = Math.PI * e * e * i, n = 4 / 3 * Math.PI * e * e * e, o = r / (r + n);
|
|
169
169
|
if (Math.random() < o) {
|
|
170
|
-
const
|
|
171
|
-
t[0] = Math.cos(
|
|
170
|
+
const a = Math.random() * Math.PI * 2, l = e * Math.sqrt(Math.random());
|
|
171
|
+
t[0] = Math.cos(a) * l, t[1] = (Math.random() - 0.5) * i, t[2] = Math.sin(a) * l;
|
|
172
172
|
} else {
|
|
173
|
-
const
|
|
174
|
-
t[0] =
|
|
173
|
+
const a = Math.random() * Math.PI * 2, l = Math.acos(2 * Math.random() - 1), d = e * Math.cbrt(Math.random());
|
|
174
|
+
t[0] = d * Math.sin(l) * Math.cos(a), t[1] = d * Math.cos(l), t[2] = d * Math.sin(l) * Math.sin(a), t[1] += t[1] >= 0 ? s : -s;
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
177
|
_emitFromArc(t) {
|
|
178
|
-
const e = this.config.arcStartAngle || 0, i = this.config.arcEndAngle || 180,
|
|
178
|
+
const e = this.config.arcStartAngle || 0, i = this.config.arcEndAngle || 180, s = this.config.arcInnerRadius || 0, r = this.config.arcOuterRadius || 2, n = e * Math.PI / 180, o = i * Math.PI / 180, a = n + Math.random() * (o - n);
|
|
179
179
|
let l;
|
|
180
|
-
|
|
180
|
+
s > 0 ? l = s + (r - s) * Math.random() : l = r * Math.sqrt(Math.random()), t[0] = Math.cos(a) * l, t[1] = Math.sin(a) * l, t[2] = 0;
|
|
181
181
|
}
|
|
182
182
|
_emitFromSpiral(t) {
|
|
183
|
-
const e = this.config.spiralTurns || 3, i = this.config.spiralRadiusStart || 0.5,
|
|
184
|
-
t[0] = Math.cos(o) *
|
|
183
|
+
const e = this.config.spiralTurns || 3, i = this.config.spiralRadiusStart || 0.5, s = this.config.spiralRadiusEnd || 2, r = this.config.spiralHeight || 4, n = Math.random(), o = n * e * Math.PI * 2, a = i + (s - i) * n;
|
|
184
|
+
t[0] = Math.cos(o) * a, t[1] = (n - 0.5) * r, t[2] = Math.sin(o) * a;
|
|
185
185
|
}
|
|
186
186
|
_emitFromFrustum(t) {
|
|
187
|
-
const e = this.config.frustumRadiusNear || 0.5, i = this.config.frustumRadiusFar || 2,
|
|
187
|
+
const e = this.config.frustumRadiusNear || 0.5, i = this.config.frustumRadiusFar || 2, s = this.config.frustumHeight || 4, r = Math.random() * Math.PI * 2, n = Math.random(), o = n * s, l = (e + (i - e) * n) * Math.sqrt(Math.random());
|
|
188
188
|
t[0] = Math.cos(r) * l, t[1] = o, t[2] = Math.sin(r) * l;
|
|
189
189
|
}
|
|
190
190
|
_emitFromCubeSurface(t) {
|
|
191
|
-
const e = this.config.cubeSurfaceSize || 2, i = e * 0.5,
|
|
192
|
-
switch (
|
|
191
|
+
const e = this.config.cubeSurfaceSize || 2, i = e * 0.5, s = Math.floor(Math.random() * 6), r = (Math.random() - 0.5) * e, n = (Math.random() - 0.5) * e;
|
|
192
|
+
switch (s) {
|
|
193
193
|
case 0:
|
|
194
194
|
t[0] = r, t[1] = n, t[2] = i;
|
|
195
195
|
break;
|
|
@@ -211,67 +211,71 @@ class Z {
|
|
|
211
211
|
}
|
|
212
212
|
}
|
|
213
213
|
_emitFromSphereSurface(t) {
|
|
214
|
-
const e = this.config.sphereSurfaceRadius || 2, i = Math.random() * Math.PI * 2,
|
|
215
|
-
t[0] = e * Math.sin(
|
|
214
|
+
const e = this.config.sphereSurfaceRadius || 2, i = Math.random() * Math.PI * 2, s = Math.acos(2 * Math.random() - 1);
|
|
215
|
+
t[0] = e * Math.sin(s) * Math.cos(i), t[1] = e * Math.sin(s) * Math.sin(i), t[2] = e * Math.cos(s);
|
|
216
216
|
}
|
|
217
217
|
_emitFromBoxFrame(t) {
|
|
218
|
-
const e = this.config.boxFrameSize || 2, i = e * 0.5,
|
|
219
|
-
if (
|
|
220
|
-
const [
|
|
221
|
-
t[0] = n, t[1] =
|
|
222
|
-
} else if (
|
|
223
|
-
const [
|
|
224
|
-
t[0] =
|
|
218
|
+
const e = this.config.boxFrameSize || 2, i = e * 0.5, s = Math.floor(Math.random() * 12), n = (Math.random() - 0.5) * e, o = [[-1, -1], [-1, 1], [1, -1], [1, 1]];
|
|
219
|
+
if (s < 4) {
|
|
220
|
+
const [a, l] = o[s];
|
|
221
|
+
t[0] = n, t[1] = a * i, t[2] = l * i;
|
|
222
|
+
} else if (s < 8) {
|
|
223
|
+
const [a, l] = o[s - 4];
|
|
224
|
+
t[0] = a * i, t[1] = n, t[2] = l * i;
|
|
225
225
|
} else {
|
|
226
|
-
const [
|
|
227
|
-
t[0] =
|
|
226
|
+
const [a, l] = o[s - 8];
|
|
227
|
+
t[0] = a * i, t[1] = l * i, t[2] = n;
|
|
228
228
|
}
|
|
229
229
|
}
|
|
230
230
|
_emitFromPolygon(t) {
|
|
231
|
-
const e = Math.max(3, Math.floor(this.config.polygonSides || 6)), i = this.config.polygonRadius || 2,
|
|
232
|
-
let o = Math.random(),
|
|
233
|
-
o +
|
|
234
|
-
const l = o * Math.cos(r) +
|
|
235
|
-
t[0] = l * i, t[1] =
|
|
231
|
+
const e = Math.max(3, Math.floor(this.config.polygonSides || 6)), i = this.config.polygonRadius || 2, s = Math.floor(Math.random() * e), r = s / e * Math.PI * 2, n = (s + 1) / e * Math.PI * 2;
|
|
232
|
+
let o = Math.random(), a = Math.random();
|
|
233
|
+
o + a > 1 && (o = 1 - o, a = 1 - a);
|
|
234
|
+
const l = o * Math.cos(r) + a * Math.cos(n), d = o * Math.sin(r) + a * Math.sin(n);
|
|
235
|
+
t[0] = l * i, t[1] = d * i, t[2] = 0;
|
|
236
|
+
}
|
|
237
|
+
_emitFromRectangle(t) {
|
|
238
|
+
const e = this.config.rectangleWidth || 2, i = this.config.rectangleHeight || 2;
|
|
239
|
+
t[0] = (Math.random() - 0.5) * e, t[1] = (Math.random() - 0.5) * i, t[2] = 0;
|
|
236
240
|
}
|
|
237
241
|
_emitFromCylinder(t) {
|
|
238
|
-
const e = this.config.cylinderInnerRadius || 0, i = this.config.cylinderOuterRadius || 2,
|
|
242
|
+
const e = this.config.cylinderInnerRadius || 0, i = this.config.cylinderOuterRadius || 2, s = this.config.cylinderHeight || 4, r = Math.random() * Math.PI * 2;
|
|
239
243
|
let n;
|
|
240
|
-
e > 0 ? n = e + (i - e) * Math.random() : n = i * Math.sqrt(Math.random()), t[0] = Math.cos(r) * n, t[1] = (Math.random() - 0.5) *
|
|
244
|
+
e > 0 ? n = e + (i - e) * Math.random() : n = i * Math.sqrt(Math.random()), t[0] = Math.cos(r) * n, t[1] = (Math.random() - 0.5) * s, t[2] = Math.sin(r) * n;
|
|
241
245
|
}
|
|
242
|
-
calculateVelocity(t, e, i,
|
|
243
|
-
const n = this.config.
|
|
246
|
+
calculateVelocity(t, e, i, s, r) {
|
|
247
|
+
const n = this.config.emissionTranslationX || 0, o = this.config.emissionTranslationY || 0, a = this.config.emissionTranslationZ || 0, l = t - n, d = e - o, u = i - a, f = Math.sqrt(l * l + d * d + u * u);
|
|
244
248
|
let h, p, m;
|
|
245
249
|
if (f > 1e-4) {
|
|
246
250
|
let S = !1;
|
|
247
251
|
if (this.config.emissionShape === "circle" && this.config.circleVelocityDirection === "tangential") {
|
|
248
|
-
const y = this.inverseRotation(l,
|
|
249
|
-
if (
|
|
250
|
-
const g = -y[1] /
|
|
251
|
-
h =
|
|
252
|
+
const y = this.inverseRotation(l, d, u), _ = Math.sqrt(y[0] * y[0] + y[1] * y[1]);
|
|
253
|
+
if (_ > 1e-4) {
|
|
254
|
+
const g = -y[1] / _, x = y[0] / _, P = this.applyRotation(g, x, 0);
|
|
255
|
+
h = P[0], p = P[1], m = P[2], S = !0;
|
|
252
256
|
}
|
|
253
257
|
} else if (this.config.emissionShape === "cylinder" && this.config.cylinderVelocityDirection === "tangential") {
|
|
254
|
-
const y = this.inverseRotation(l,
|
|
255
|
-
if (
|
|
256
|
-
const g = -y[2] /
|
|
257
|
-
h =
|
|
258
|
+
const y = this.inverseRotation(l, d, u), _ = Math.sqrt(y[0] * y[0] + y[2] * y[2]);
|
|
259
|
+
if (_ > 1e-4) {
|
|
260
|
+
const g = -y[2] / _, x = y[0] / _, P = this.applyRotation(g, 0, x);
|
|
261
|
+
h = P[0], p = P[1], m = P[2], S = !0;
|
|
258
262
|
} else {
|
|
259
263
|
const g = Math.random() * Math.PI * 2, x = this.applyRotation(Math.cos(g), 0, Math.sin(g));
|
|
260
264
|
h = x[0], p = x[1], m = x[2], S = !0;
|
|
261
265
|
}
|
|
262
266
|
}
|
|
263
|
-
S || (h = l / f, p =
|
|
267
|
+
S || (h = l / f, p = d / f, m = u / f);
|
|
264
268
|
} else {
|
|
265
269
|
const S = Math.random() * Math.PI * 2, y = Math.acos(2 * Math.random() - 1);
|
|
266
270
|
h = Math.sin(y) * Math.cos(S), p = Math.sin(y) * Math.sin(S), m = Math.cos(y);
|
|
267
271
|
}
|
|
268
272
|
let b;
|
|
269
|
-
this.config.randomSpeed ? b = (this.config.minSpeed || 0) + Math.random() * ((this.config.maxSpeed || 1) - (this.config.minSpeed || 0)) : b = this.config.particleSpeed,
|
|
273
|
+
this.config.randomSpeed ? b = (this.config.minSpeed || 0) + Math.random() * ((this.config.maxSpeed || 1) - (this.config.minSpeed || 0)) : b = this.config.particleSpeed, s[r] = this.config.overrideXVelocity ? this.config.xVelocity : h * b, s[r + 1] = this.config.overrideYVelocity ? this.config.yVelocity : p * b, s[r + 2] = this.config.overrideZVelocity ? this.config.zVelocity : m * b, s[r + 3] = 0;
|
|
270
274
|
}
|
|
271
275
|
setParticleColor(t, e) {
|
|
272
276
|
if (this.config.randomColorEnabled && this.config.randomColors.length > 0) {
|
|
273
|
-
const i = this.config.randomColors,
|
|
274
|
-
t[e + 3] =
|
|
277
|
+
const i = this.config.randomColors, s = i[Math.floor(Math.random() * i.length)];
|
|
278
|
+
t[e + 3] = s[0], t[e + 4] = s[1], t[e + 5] = s[2];
|
|
275
279
|
} else this.config.colorTransitionEnabled ? (t[e + 3] = this.config.startColor[0], t[e + 4] = this.config.startColor[1], t[e + 5] = this.config.startColor[2]) : (t[e + 3] = this.config.particleColor[0], t[e + 4] = this.config.particleColor[1], t[e + 5] = this.config.particleColor[2]);
|
|
276
280
|
}
|
|
277
281
|
setParticleLifetime(t, e) {
|
|
@@ -279,7 +283,7 @@ class Z {
|
|
|
279
283
|
t[e + 6] = 0, t[e + 7] = i + (Math.random() * 0.4 - 0.2) * i;
|
|
280
284
|
}
|
|
281
285
|
}
|
|
282
|
-
class
|
|
286
|
+
class J {
|
|
283
287
|
constructor(t, e = 1e4) {
|
|
284
288
|
this.device = t, this.physicsSettings = {
|
|
285
289
|
deltaTime: 0.016,
|
|
@@ -321,17 +325,25 @@ class q {
|
|
|
321
325
|
size: e * 4 * 4,
|
|
322
326
|
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
|
|
323
327
|
label: "RenderReadback_Velocity"
|
|
324
|
-
}), this._renderStagingInUse = !1
|
|
328
|
+
}), this._renderStagingInUse = !1, this._scriptStagingParticleBuffer = t.createBuffer({
|
|
329
|
+
size: e * 8 * 4,
|
|
330
|
+
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
|
|
331
|
+
label: "ScriptReadback_ParticleData"
|
|
332
|
+
}), this._scriptStagingVelocityBuffer = t.createBuffer({
|
|
333
|
+
size: e * 4 * 4,
|
|
334
|
+
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
|
|
335
|
+
label: "ScriptReadback_Velocity"
|
|
336
|
+
}), this._scriptStagingInUse = !1;
|
|
325
337
|
}
|
|
326
338
|
async initComputePipeline(t, e, i) {
|
|
327
339
|
try {
|
|
328
340
|
return await this.createComputePipeline(t, e, i), this.computeReady = !0, !0;
|
|
329
|
-
} catch (
|
|
330
|
-
return console.error("Error initializing compute pipeline:",
|
|
341
|
+
} catch (s) {
|
|
342
|
+
return console.error("Error initializing compute pipeline:", s), !1;
|
|
331
343
|
}
|
|
332
344
|
}
|
|
333
345
|
async createComputePipeline(t, e, i) {
|
|
334
|
-
const { particlePhysicsShader:
|
|
346
|
+
const { particlePhysicsShader: s } = await Promise.resolve().then(() => H);
|
|
335
347
|
this.computeBindGroupLayout = this.device.createBindGroupLayout({
|
|
336
348
|
entries: [
|
|
337
349
|
{
|
|
@@ -361,7 +373,7 @@ class q {
|
|
|
361
373
|
}),
|
|
362
374
|
compute: {
|
|
363
375
|
module: this.device.createShaderModule({
|
|
364
|
-
code:
|
|
376
|
+
code: s
|
|
365
377
|
}),
|
|
366
378
|
entryPoint: "main"
|
|
367
379
|
}
|
|
@@ -387,17 +399,17 @@ class q {
|
|
|
387
399
|
]
|
|
388
400
|
});
|
|
389
401
|
}
|
|
390
|
-
updatePhysics(t, e, i,
|
|
402
|
+
updatePhysics(t, e, i, s, r, n) {
|
|
391
403
|
if (e <= 0 || !this.computeReady)
|
|
392
404
|
return;
|
|
393
|
-
const o = this._physicsData,
|
|
394
|
-
o[0] = t, o[1] = i.particleSpeed, o[2] =
|
|
395
|
-
const l = n || this.device.createCommandEncoder({ label: "ParticlePhysicsEncoder" }),
|
|
396
|
-
|
|
397
|
-
const
|
|
398
|
-
|
|
399
|
-
}
|
|
400
|
-
async readbackAndProcessParticles(t, e, i,
|
|
405
|
+
const o = this._physicsData, a = this.physicsSettings;
|
|
406
|
+
o[0] = t, o[1] = i.particleSpeed, o[2] = a.gravity, o[3] = a.turbulence, o[4] = a.attractorStrength, o[5] = a.damping, o[6] = a.attractorPosition[0], o[7] = a.attractorPosition[1], o[8] = a.attractorPosition[2], this._physicsDataU32View[9] = e, o[10] = a.confinementEnabled ? 1 : 0, o[11] = a.confinementShape === "sphere" ? 1 : 0, o[12] = a.confinementMode === "kill" ? 1 : 0, o[13] = a.confinementSpace === "local" ? 1 : 0, o[14] = a.confinementBoxHalfSize[0], o[15] = a.confinementBoxHalfSize[1], o[16] = a.confinementBoxHalfSize[2], o[17] = a.confinementSphereRadius, o[18] = a.confinementRestitution, o[19] = a.confinementFriction, o[20] = a.confinementCenter[0], o[21] = a.confinementCenter[1], o[22] = a.confinementCenter[2], o[23] = a.softBoundaryEnabled ? 1 : 0, o[24] = a.softBoundaryStrength, o[25] = a.softBoundaryFalloff, o[26] = i.velocityStretchEnabled ? 1 : 0, o[27] = i.velocityStretchFactor ?? 1, o[28] = 0, o[29] = 0, o[30] = 0, o[31] = 0, this.device.queue.writeBuffer(this.physicsUniformBuffer, 0, o);
|
|
407
|
+
const l = n || this.device.createCommandEncoder({ label: "ParticlePhysicsEncoder" }), d = l.beginComputePass({ label: "ParticlePhysicsPass" });
|
|
408
|
+
d.setPipeline(this.computePipeline), d.setBindGroup(0, this.computeBindGroup);
|
|
409
|
+
const u = Math.max(1, Math.ceil(e / 64));
|
|
410
|
+
d.dispatchWorkgroups(u, 1, 1), d.end(), n || this.device.queue.submit([l.finish()]), this.lastUpdateTime = performance.now() / 1e3;
|
|
411
|
+
}
|
|
412
|
+
async readbackAndProcessParticles(t, e, i, s, r) {
|
|
401
413
|
if (t <= 0)
|
|
402
414
|
return { activeCount: 0, shouldUpdate: !1 };
|
|
403
415
|
if (this._stagingInUse)
|
|
@@ -408,19 +420,19 @@ class q {
|
|
|
408
420
|
label: "ParticleReadbackEncoder"
|
|
409
421
|
}), o = t * 8 * 4;
|
|
410
422
|
n.copyBufferToBuffer(
|
|
411
|
-
|
|
423
|
+
s,
|
|
412
424
|
0,
|
|
413
425
|
this._particleDataStagingBuffer,
|
|
414
426
|
0,
|
|
415
427
|
o
|
|
416
428
|
);
|
|
417
|
-
const
|
|
429
|
+
const a = t * 4 * 4;
|
|
418
430
|
return n.copyBufferToBuffer(
|
|
419
431
|
r,
|
|
420
432
|
0,
|
|
421
433
|
this._velocityStagingBuffer,
|
|
422
434
|
0,
|
|
423
|
-
|
|
435
|
+
a
|
|
424
436
|
), this.device.queue.submit([n.finish()]), await Promise.all([
|
|
425
437
|
(async () => {
|
|
426
438
|
await this._particleDataStagingBuffer.mapAsync(GPUMapMode.READ, 0, o);
|
|
@@ -428,8 +440,8 @@ class q {
|
|
|
428
440
|
e.set(l), this._particleDataStagingBuffer.unmap();
|
|
429
441
|
})(),
|
|
430
442
|
(async () => {
|
|
431
|
-
await this._velocityStagingBuffer.mapAsync(GPUMapMode.READ, 0,
|
|
432
|
-
const l = new Float32Array(this._velocityStagingBuffer.getMappedRange(0,
|
|
443
|
+
await this._velocityStagingBuffer.mapAsync(GPUMapMode.READ, 0, a);
|
|
444
|
+
const l = new Float32Array(this._velocityStagingBuffer.getMappedRange(0, a));
|
|
433
445
|
i.set(l), this._velocityStagingBuffer.unmap();
|
|
434
446
|
})()
|
|
435
447
|
]), this._stagingInUse = !1, {
|
|
@@ -465,29 +477,29 @@ class q {
|
|
|
465
477
|
* @param {GPUBuffer} velocityBuffer
|
|
466
478
|
* @returns {Promise<{particleData: Float32Array, particleVelocities: Float32Array, shouldUpdate: boolean}>}
|
|
467
479
|
*/
|
|
468
|
-
async readbackForRendering(t, e, i,
|
|
480
|
+
async readbackForRendering(t, e, i, s, r) {
|
|
469
481
|
if (t <= 0)
|
|
470
482
|
return { shouldUpdate: !1 };
|
|
471
483
|
if (this._renderStagingInUse)
|
|
472
484
|
return { shouldUpdate: !1 };
|
|
473
485
|
try {
|
|
474
486
|
this._renderStagingInUse = !0;
|
|
475
|
-
const n = t * 8 * 4, o = t * 4 * 4,
|
|
487
|
+
const n = t * 8 * 4, o = t * 4 * 4, a = this.device.createCommandEncoder({
|
|
476
488
|
label: "RenderReadbackEncoder"
|
|
477
489
|
});
|
|
478
|
-
return
|
|
479
|
-
|
|
490
|
+
return a.copyBufferToBuffer(
|
|
491
|
+
s,
|
|
480
492
|
0,
|
|
481
493
|
this._renderStagingParticleBuffer,
|
|
482
494
|
0,
|
|
483
495
|
n
|
|
484
|
-
),
|
|
496
|
+
), a.copyBufferToBuffer(
|
|
485
497
|
r,
|
|
486
498
|
0,
|
|
487
499
|
this._renderStagingVelocityBuffer,
|
|
488
500
|
0,
|
|
489
501
|
o
|
|
490
|
-
), this.device.queue.submit([
|
|
502
|
+
), this.device.queue.submit([a.finish()]), await Promise.all([
|
|
491
503
|
(async () => {
|
|
492
504
|
await this._renderStagingParticleBuffer.mapAsync(GPUMapMode.READ, 0, n);
|
|
493
505
|
const l = new Float32Array(this._renderStagingParticleBuffer.getMappedRange(0, n));
|
|
@@ -507,18 +519,67 @@ class q {
|
|
|
507
519
|
return this._renderStagingInUse = !1, console.error("Error in rendering readback:", n), { shouldUpdate: !1 };
|
|
508
520
|
}
|
|
509
521
|
}
|
|
522
|
+
/**
|
|
523
|
+
* Non-blocking readback for CPU-side particle scripting.
|
|
524
|
+
* Uses dedicated staging buffers that never contend with cleanup or rendering readback.
|
|
525
|
+
* Copies GPU data into caller-provided Float32Arrays.
|
|
526
|
+
* @param {number} activeParticles
|
|
527
|
+
* @param {Float32Array} outParticleData
|
|
528
|
+
* @param {Float32Array} outVelocities
|
|
529
|
+
* @param {GPUBuffer} instanceBuffer
|
|
530
|
+
* @param {GPUBuffer} velocityBuffer
|
|
531
|
+
* @returns {Promise<{shouldUpdate: boolean}>}
|
|
532
|
+
*/
|
|
533
|
+
async readbackForScript(t, e, i, s, r) {
|
|
534
|
+
if (t <= 0)
|
|
535
|
+
return { shouldUpdate: !1 };
|
|
536
|
+
if (this._scriptStagingInUse)
|
|
537
|
+
return { shouldUpdate: !1 };
|
|
538
|
+
try {
|
|
539
|
+
this._scriptStagingInUse = !0;
|
|
540
|
+
const n = t * 8 * 4, o = t * 4 * 4, a = this.device.createCommandEncoder({
|
|
541
|
+
label: "ScriptReadbackEncoder"
|
|
542
|
+
});
|
|
543
|
+
return a.copyBufferToBuffer(
|
|
544
|
+
s,
|
|
545
|
+
0,
|
|
546
|
+
this._scriptStagingParticleBuffer,
|
|
547
|
+
0,
|
|
548
|
+
n
|
|
549
|
+
), a.copyBufferToBuffer(
|
|
550
|
+
r,
|
|
551
|
+
0,
|
|
552
|
+
this._scriptStagingVelocityBuffer,
|
|
553
|
+
0,
|
|
554
|
+
o
|
|
555
|
+
), this.device.queue.submit([a.finish()]), await Promise.all([
|
|
556
|
+
(async () => {
|
|
557
|
+
await this._scriptStagingParticleBuffer.mapAsync(GPUMapMode.READ, 0, n);
|
|
558
|
+
const l = new Float32Array(this._scriptStagingParticleBuffer.getMappedRange(0, n));
|
|
559
|
+
e.set(l), this._scriptStagingParticleBuffer.unmap();
|
|
560
|
+
})(),
|
|
561
|
+
(async () => {
|
|
562
|
+
await this._scriptStagingVelocityBuffer.mapAsync(GPUMapMode.READ, 0, o);
|
|
563
|
+
const l = new Float32Array(this._scriptStagingVelocityBuffer.getMappedRange(0, o));
|
|
564
|
+
i.set(l), this._scriptStagingVelocityBuffer.unmap();
|
|
565
|
+
})()
|
|
566
|
+
]), this._scriptStagingInUse = !1, { shouldUpdate: !0 };
|
|
567
|
+
} catch (n) {
|
|
568
|
+
return this._scriptStagingInUse = !1, console.error("Error in script readback:", n), { shouldUpdate: !1 };
|
|
569
|
+
}
|
|
570
|
+
}
|
|
510
571
|
/**
|
|
511
572
|
* Destroy all GPU buffers owned by this physics instance.
|
|
512
573
|
*/
|
|
513
574
|
destroy() {
|
|
514
|
-
this.physicsUniformBuffer.destroy(), this._particleDataStagingBuffer.destroy(), this._velocityStagingBuffer.destroy(), this._renderStagingParticleBuffer.destroy(), this._renderStagingVelocityBuffer.destroy();
|
|
575
|
+
this.physicsUniformBuffer.destroy(), this._particleDataStagingBuffer.destroy(), this._velocityStagingBuffer.destroy(), this._renderStagingParticleBuffer.destroy(), this._renderStagingVelocityBuffer.destroy(), this._scriptStagingParticleBuffer.destroy(), this._scriptStagingVelocityBuffer.destroy();
|
|
515
576
|
}
|
|
516
577
|
setSoftBoundary(t) {
|
|
517
578
|
const e = this.physicsSettings;
|
|
518
579
|
t.enabled !== void 0 && (e.softBoundaryEnabled = t.enabled), t.strength !== void 0 && (e.softBoundaryStrength = t.strength), t.falloff !== void 0 && (e.softBoundaryFalloff = t.falloff);
|
|
519
580
|
}
|
|
520
581
|
}
|
|
521
|
-
class
|
|
582
|
+
class K {
|
|
522
583
|
constructor(t) {
|
|
523
584
|
this.device = t, this.defaultTexture = null, this.createDefaultTexture();
|
|
524
585
|
}
|
|
@@ -557,21 +618,289 @@ class $ {
|
|
|
557
618
|
t && t.label !== "defaultParticleTexture" && t.destroy();
|
|
558
619
|
}
|
|
559
620
|
}
|
|
560
|
-
|
|
621
|
+
const N = Object.freeze({
|
|
622
|
+
sin: Math.sin,
|
|
623
|
+
cos: Math.cos,
|
|
624
|
+
abs: Math.abs,
|
|
625
|
+
floor: Math.floor,
|
|
626
|
+
ceil: Math.ceil,
|
|
627
|
+
round: Math.round,
|
|
628
|
+
min: Math.min,
|
|
629
|
+
max: Math.max,
|
|
630
|
+
sqrt: Math.sqrt,
|
|
631
|
+
pow: Math.pow,
|
|
632
|
+
random: Math.random,
|
|
633
|
+
PI: Math.PI,
|
|
634
|
+
TAU: Math.PI * 2,
|
|
635
|
+
clamp(c, t, e) {
|
|
636
|
+
return c < t ? t : c > e ? e : c;
|
|
637
|
+
},
|
|
638
|
+
lerp(c, t, e) {
|
|
639
|
+
return c + (t - c) * e;
|
|
640
|
+
},
|
|
641
|
+
smoothstep(c, t, e) {
|
|
642
|
+
const i = N.clamp((e - c) / (t - c), 0, 1);
|
|
643
|
+
return i * i * (3 - 2 * i);
|
|
644
|
+
}
|
|
645
|
+
}), T = /* @__PURE__ */ new Set([
|
|
646
|
+
"particleSize",
|
|
647
|
+
"particleSpeed",
|
|
648
|
+
"particleColor",
|
|
649
|
+
"startColor",
|
|
650
|
+
"endColor",
|
|
651
|
+
"opacity",
|
|
652
|
+
"emissionRate",
|
|
653
|
+
"gravityStrength",
|
|
654
|
+
"dampingStrength",
|
|
655
|
+
"attractorStrength",
|
|
656
|
+
"attractorPosition",
|
|
657
|
+
"pulseAmplitude",
|
|
658
|
+
"pulseFrequency",
|
|
659
|
+
"bloomIntensity"
|
|
660
|
+
]);
|
|
661
|
+
class Q {
|
|
662
|
+
constructor(t) {
|
|
663
|
+
this._collection = t, this._pd = null, this._vd = null, this._pi = 0, this._vi = 0;
|
|
664
|
+
}
|
|
665
|
+
_bind(t, e, i) {
|
|
666
|
+
return this._pd = t, this._vd = e, this._pi = i * 8, this._vi = i * 4, this;
|
|
667
|
+
}
|
|
668
|
+
// Position
|
|
669
|
+
get x() {
|
|
670
|
+
return this._pd[this._pi];
|
|
671
|
+
}
|
|
672
|
+
set x(t) {
|
|
673
|
+
this._pd[this._pi] = t, this._collection._dirty = !0;
|
|
674
|
+
}
|
|
675
|
+
get y() {
|
|
676
|
+
return this._pd[this._pi + 1];
|
|
677
|
+
}
|
|
678
|
+
set y(t) {
|
|
679
|
+
this._pd[this._pi + 1] = t, this._collection._dirty = !0;
|
|
680
|
+
}
|
|
681
|
+
get z() {
|
|
682
|
+
return this._pd[this._pi + 2];
|
|
683
|
+
}
|
|
684
|
+
set z(t) {
|
|
685
|
+
this._pd[this._pi + 2] = t, this._collection._dirty = !0;
|
|
686
|
+
}
|
|
687
|
+
// Color
|
|
688
|
+
get r() {
|
|
689
|
+
return this._pd[this._pi + 3];
|
|
690
|
+
}
|
|
691
|
+
set r(t) {
|
|
692
|
+
this._pd[this._pi + 3] = t, this._collection._dirty = !0;
|
|
693
|
+
}
|
|
694
|
+
get g() {
|
|
695
|
+
return this._pd[this._pi + 4];
|
|
696
|
+
}
|
|
697
|
+
set g(t) {
|
|
698
|
+
this._pd[this._pi + 4] = t, this._collection._dirty = !0;
|
|
699
|
+
}
|
|
700
|
+
get b() {
|
|
701
|
+
return this._pd[this._pi + 5];
|
|
702
|
+
}
|
|
703
|
+
set b(t) {
|
|
704
|
+
this._pd[this._pi + 5] = t, this._collection._dirty = !0;
|
|
705
|
+
}
|
|
706
|
+
// Age / Lifetime
|
|
707
|
+
get age() {
|
|
708
|
+
return this._pd[this._pi + 6];
|
|
709
|
+
}
|
|
710
|
+
set age(t) {
|
|
711
|
+
this._pd[this._pi + 6] = t, this._collection._dirty = !0;
|
|
712
|
+
}
|
|
713
|
+
get lifetime() {
|
|
714
|
+
return this._pd[this._pi + 7];
|
|
715
|
+
}
|
|
716
|
+
set lifetime(t) {
|
|
717
|
+
this._pd[this._pi + 7] = t, this._collection._dirty = !0;
|
|
718
|
+
}
|
|
719
|
+
// Velocity
|
|
720
|
+
get vx() {
|
|
721
|
+
return this._vd[this._vi];
|
|
722
|
+
}
|
|
723
|
+
set vx(t) {
|
|
724
|
+
this._vd[this._vi] = t, this._collection._dirty = !0;
|
|
725
|
+
}
|
|
726
|
+
get vy() {
|
|
727
|
+
return this._vd[this._vi + 1];
|
|
728
|
+
}
|
|
729
|
+
set vy(t) {
|
|
730
|
+
this._vd[this._vi + 1] = t, this._collection._dirty = !0;
|
|
731
|
+
}
|
|
732
|
+
get vz() {
|
|
733
|
+
return this._vd[this._vi + 2];
|
|
734
|
+
}
|
|
735
|
+
set vz(t) {
|
|
736
|
+
this._vd[this._vi + 2] = t, this._collection._dirty = !0;
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
class ee {
|
|
740
|
+
constructor() {
|
|
741
|
+
this._proxy = new Q(this), this._pd = null, this._vd = null, this.count = 0, this._dirty = !1;
|
|
742
|
+
}
|
|
743
|
+
_bind(t, e, i) {
|
|
744
|
+
this._pd = t, this._vd = e, this.count = i, this._dirty = !1;
|
|
745
|
+
}
|
|
746
|
+
get(t) {
|
|
747
|
+
return t < 0 || t >= this.count ? null : this._proxy._bind(this._pd, this._vd, t);
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
const te = 1e6;
|
|
751
|
+
function ie(c) {
|
|
752
|
+
let t = 0;
|
|
753
|
+
return c.replace(
|
|
754
|
+
/\b(for|while)\s*\([^)]*\)\s*\{/g,
|
|
755
|
+
(e) => {
|
|
756
|
+
const i = `__lc${t++}`;
|
|
757
|
+
return `${e} if(++${i}>${te})throw new Error("Loop limit exceeded");`;
|
|
758
|
+
}
|
|
759
|
+
).replace(
|
|
760
|
+
/\b(for|while)\s*\([^)]*\)\s*\{/g,
|
|
761
|
+
// already handled above
|
|
762
|
+
(e) => e
|
|
763
|
+
).replace(
|
|
764
|
+
// Prepend counter declarations at the top
|
|
765
|
+
/^/,
|
|
766
|
+
() => {
|
|
767
|
+
let e = "";
|
|
768
|
+
for (let i = 0; i < t; i++)
|
|
769
|
+
e += `let __lc${i}=0;`;
|
|
770
|
+
return e;
|
|
771
|
+
}
|
|
772
|
+
);
|
|
773
|
+
}
|
|
774
|
+
const U = /* @__PURE__ */ new Map();
|
|
775
|
+
for (const c of T)
|
|
776
|
+
U.set(c.toLowerCase(), c);
|
|
777
|
+
function se(c) {
|
|
778
|
+
const t = { value: !1 }, e = /* @__PURE__ */ new Set();
|
|
779
|
+
return new Proxy(c, {
|
|
780
|
+
get(s, r) {
|
|
781
|
+
if (r === "__dirty") return t.value;
|
|
782
|
+
if (r === "__resetDirty") return () => {
|
|
783
|
+
t.value = !1;
|
|
784
|
+
};
|
|
785
|
+
if (typeof r != "string") return;
|
|
786
|
+
if (T.has(r)) return s[r];
|
|
787
|
+
const n = U.get(r.toLowerCase());
|
|
788
|
+
if (n)
|
|
789
|
+
return e.has(r) || (e.add(r), console.warn(`[ParticleScript] config.${r} → did you mean config.${n}?`)), s[n];
|
|
790
|
+
},
|
|
791
|
+
set(s, r, n) {
|
|
792
|
+
if (typeof r != "string") return !0;
|
|
793
|
+
let o = r;
|
|
794
|
+
if (!T.has(o)) {
|
|
795
|
+
const a = U.get(o.toLowerCase());
|
|
796
|
+
if (a)
|
|
797
|
+
e.has(r) || (e.add(r), console.warn(`[ParticleScript] config.${r} → did you mean config.${a}?`)), o = a;
|
|
798
|
+
else
|
|
799
|
+
return !0;
|
|
800
|
+
}
|
|
801
|
+
return s[o] = n, t.value = !0, !0;
|
|
802
|
+
}
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
class z {
|
|
806
|
+
/**
|
|
807
|
+
* @param {string} source - User script source code
|
|
808
|
+
* @param {object} config - ParticleSystem config (will be proxied)
|
|
809
|
+
* @param {number} maxParticles - Max particle count for pre-allocation
|
|
810
|
+
*/
|
|
811
|
+
constructor(t, e, i) {
|
|
812
|
+
this._particles = new ee(), this._configProxy = se(e), this._configSnapshot = null, this._fn = null, this._error = !1, this.compile(t);
|
|
813
|
+
}
|
|
814
|
+
/**
|
|
815
|
+
* Compile script source into a sandboxed function.
|
|
816
|
+
*/
|
|
817
|
+
compile(t) {
|
|
818
|
+
if (this._fn = null, this._error = !1, !(!t || typeof t != "string"))
|
|
819
|
+
try {
|
|
820
|
+
const i = `
|
|
821
|
+
return function(__deltaTime, __time, __currentFrame, __totalFrames, __particles, __config, __math) {
|
|
822
|
+
var window = void 0, document = void 0, globalThis = void 0;
|
|
823
|
+
var Function = void 0, eval = void 0, fetch = void 0;
|
|
824
|
+
var importScripts = void 0, XMLHttpRequest = void 0, WebSocket = void 0;
|
|
825
|
+
var deltaTime = __deltaTime, time = __time;
|
|
826
|
+
var currentFrame = __currentFrame, totalFrames = __totalFrames;
|
|
827
|
+
var particles = __particles, config = __config, math = __math;
|
|
828
|
+
${ie(t)}
|
|
829
|
+
};`, s = new Function(i);
|
|
830
|
+
this._fn = s();
|
|
831
|
+
} catch (e) {
|
|
832
|
+
console.warn("[ParticleScript] Compilation error:", e.message), this._fn = null, this._error = !0;
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
/**
|
|
836
|
+
* Execute the script for one frame.
|
|
837
|
+
* @param {number} deltaTime
|
|
838
|
+
* @param {number} time - seconds since system start
|
|
839
|
+
* @param {number} frame - frame counter
|
|
840
|
+
* @param {number} totalFrames - estimated total frames
|
|
841
|
+
* @param {Float32Array} particleData - read/write
|
|
842
|
+
* @param {Float32Array} velocityData - read/write
|
|
843
|
+
* @param {number} count - active particle count
|
|
844
|
+
* @returns {boolean} true if config was modified
|
|
845
|
+
*/
|
|
846
|
+
execute(t, e, i, s, r, n, o) {
|
|
847
|
+
if (!this._fn || this._error) return { configDirty: !1, particlesDirty: !1 };
|
|
848
|
+
this._particles._bind(r, n, o), this._configProxy.__resetDirty();
|
|
849
|
+
try {
|
|
850
|
+
this._fn(t, e, i, s, this._particles, this._configProxy, N);
|
|
851
|
+
} catch (a) {
|
|
852
|
+
console.warn("[ParticleScript] Runtime error:", a.message);
|
|
853
|
+
}
|
|
854
|
+
return {
|
|
855
|
+
configDirty: this._configProxy.__dirty,
|
|
856
|
+
particlesDirty: this._particles._dirty
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
/**
|
|
860
|
+
* Deep-clone the scriptable config properties for later restoration.
|
|
861
|
+
*/
|
|
862
|
+
snapshotConfig(t) {
|
|
863
|
+
const e = {};
|
|
864
|
+
for (const i of T) {
|
|
865
|
+
const s = t[i];
|
|
866
|
+
s !== void 0 && (e[i] = Array.isArray(s) ? [...s] : s);
|
|
867
|
+
}
|
|
868
|
+
this._configSnapshot = e;
|
|
869
|
+
}
|
|
870
|
+
/**
|
|
871
|
+
* Restore config properties from the snapshot.
|
|
872
|
+
*/
|
|
873
|
+
restoreConfig(t) {
|
|
874
|
+
if (this._configSnapshot) {
|
|
875
|
+
for (const e of T)
|
|
876
|
+
if (e in this._configSnapshot) {
|
|
877
|
+
const i = this._configSnapshot[e];
|
|
878
|
+
t[e] = Array.isArray(i) ? [...i] : i;
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
/**
|
|
883
|
+
* Cleanup.
|
|
884
|
+
*/
|
|
885
|
+
destroy() {
|
|
886
|
+
this._fn = null, this._particles = null, this._configProxy = null, this._configSnapshot = null;
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
async function X(c) {
|
|
561
890
|
const t = new DataView(c);
|
|
562
891
|
if (t.getUint32(0, !0) !== 1179937895)
|
|
563
892
|
throw new Error("Invalid GLB file: incorrect magic number");
|
|
564
893
|
const i = t.getUint32(4, !0);
|
|
565
894
|
if (i !== 2)
|
|
566
895
|
throw new Error(`Unsupported GLB version: ${i} (only version 2 is supported)`);
|
|
567
|
-
const
|
|
896
|
+
const s = t.getUint32(8, !0);
|
|
568
897
|
let r = 12, n = null, o = null;
|
|
569
|
-
for (; r <
|
|
570
|
-
const g = t.getUint32(r, !0), x = t.getUint32(r + 4, !0),
|
|
898
|
+
for (; r < s; ) {
|
|
899
|
+
const g = t.getUint32(r, !0), x = t.getUint32(r + 4, !0), P = c.slice(r + 8, r + 8 + g);
|
|
571
900
|
if (x === 1313821514) {
|
|
572
|
-
const
|
|
573
|
-
n = JSON.parse(
|
|
574
|
-
} else x === 5130562 && (o =
|
|
901
|
+
const w = new TextDecoder("utf-8").decode(P);
|
|
902
|
+
n = JSON.parse(w);
|
|
903
|
+
} else x === 5130562 && (o = P);
|
|
575
904
|
r += 8 + g;
|
|
576
905
|
}
|
|
577
906
|
if (!n)
|
|
@@ -581,50 +910,50 @@ async function O(c) {
|
|
|
581
910
|
const l = n.meshes[0].primitives[0];
|
|
582
911
|
if (!l)
|
|
583
912
|
throw new Error("First mesh has no primitives");
|
|
584
|
-
const
|
|
585
|
-
if (
|
|
913
|
+
const d = l.attributes.POSITION;
|
|
914
|
+
if (d === void 0)
|
|
586
915
|
throw new Error("Mesh primitive missing POSITION attribute");
|
|
587
|
-
const
|
|
916
|
+
const u = E(n, o, d, 3, 5126);
|
|
588
917
|
let f;
|
|
589
918
|
if (l.attributes.NORMAL !== void 0)
|
|
590
|
-
f =
|
|
919
|
+
f = E(n, o, l.attributes.NORMAL, 3, 5126);
|
|
591
920
|
else {
|
|
592
921
|
const g = l.indices;
|
|
593
922
|
if (g === void 0)
|
|
594
923
|
throw new Error("Cannot generate normals without indices");
|
|
595
|
-
const x =
|
|
596
|
-
f =
|
|
924
|
+
const x = F(n, o, g);
|
|
925
|
+
f = ae(u, x);
|
|
597
926
|
}
|
|
598
927
|
const h = l.indices;
|
|
599
928
|
if (h === void 0)
|
|
600
929
|
throw new Error("Mesh primitive missing indices");
|
|
601
|
-
const p =
|
|
930
|
+
const p = F(n, o, h), m = u.length / 3, b = p.length;
|
|
602
931
|
let S = null;
|
|
603
|
-
l.attributes.TEXCOORD_0 !== void 0 && (S =
|
|
932
|
+
l.attributes.TEXCOORD_0 !== void 0 && (S = E(n, o, l.attributes.TEXCOORD_0, 2, 5126));
|
|
604
933
|
let y = !1;
|
|
605
934
|
if (n.materials && n.materials.length > 0) {
|
|
606
935
|
const g = n.materials[0];
|
|
607
936
|
g.pbrMetallicRoughness && g.pbrMetallicRoughness.baseColorTexture !== void 0 && (y = !0);
|
|
608
937
|
}
|
|
609
|
-
let
|
|
938
|
+
let _ = null;
|
|
610
939
|
if (n.skins && n.skins.length > 0)
|
|
611
940
|
try {
|
|
612
|
-
|
|
941
|
+
_ = de(n, o, l), console.log("Animation data extracted:", _);
|
|
613
942
|
} catch (g) {
|
|
614
943
|
console.warn("Failed to extract animation data:", g);
|
|
615
944
|
}
|
|
616
945
|
return {
|
|
617
|
-
positions:
|
|
946
|
+
positions: u,
|
|
618
947
|
normals: f,
|
|
619
948
|
indices: p,
|
|
620
949
|
texCoords: S,
|
|
621
950
|
vertexCount: m,
|
|
622
951
|
indexCount: b,
|
|
623
|
-
animationData:
|
|
952
|
+
animationData: _,
|
|
624
953
|
hasBaseColorTexture: y
|
|
625
954
|
};
|
|
626
955
|
}
|
|
627
|
-
function
|
|
956
|
+
function E(c, t, e, i, s) {
|
|
628
957
|
const r = c.accessors[e], o = {
|
|
629
958
|
SCALAR: 1,
|
|
630
959
|
VEC2: 2,
|
|
@@ -633,130 +962,130 @@ function C(c, t, e, i, a) {
|
|
|
633
962
|
}[r.type];
|
|
634
963
|
if (o !== i)
|
|
635
964
|
throw new Error(`Attribute accessor type mismatch: expected ${i} components, got ${o}`);
|
|
636
|
-
if (r.componentType !==
|
|
637
|
-
throw new Error(`Attribute component type mismatch: expected ${
|
|
638
|
-
const l = (c.bufferViews[r.bufferView].byteOffset || 0) + (r.byteOffset || 0),
|
|
639
|
-
for (let h = 0; h <
|
|
640
|
-
f[h] =
|
|
965
|
+
if (r.componentType !== s)
|
|
966
|
+
throw new Error(`Attribute component type mismatch: expected ${s}, got ${r.componentType}`);
|
|
967
|
+
const l = (c.bufferViews[r.bufferView].byteOffset || 0) + (r.byteOffset || 0), d = r.count, u = new DataView(t, l, d * i * 4), f = new Float32Array(d * i);
|
|
968
|
+
for (let h = 0; h < d * i; h++)
|
|
969
|
+
f[h] = u.getFloat32(h * 4, !0);
|
|
641
970
|
return f;
|
|
642
971
|
}
|
|
643
|
-
function
|
|
972
|
+
function F(c, t, e) {
|
|
644
973
|
const i = c.accessors[e];
|
|
645
974
|
if (i.type !== "SCALAR")
|
|
646
975
|
throw new Error(`Indices accessor must be SCALAR, got ${i.type}`);
|
|
647
976
|
const r = (c.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0), n = i.count;
|
|
648
977
|
if (i.componentType === 5123) {
|
|
649
|
-
const o = new DataView(t, r, n * 2),
|
|
978
|
+
const o = new DataView(t, r, n * 2), a = new Uint16Array(n);
|
|
650
979
|
for (let l = 0; l < n; l++)
|
|
651
|
-
|
|
652
|
-
return
|
|
980
|
+
a[l] = o.getUint16(l * 2, !0);
|
|
981
|
+
return a;
|
|
653
982
|
} else if (i.componentType === 5125) {
|
|
654
|
-
const o = new DataView(t, r, n * 4),
|
|
983
|
+
const o = new DataView(t, r, n * 4), a = new Uint32Array(n);
|
|
655
984
|
for (let l = 0; l < n; l++)
|
|
656
|
-
|
|
657
|
-
return
|
|
985
|
+
a[l] = o.getUint32(l * 4, !0);
|
|
986
|
+
return a;
|
|
658
987
|
} else
|
|
659
988
|
throw new Error(`Unsupported index component type: ${i.componentType}`);
|
|
660
989
|
}
|
|
661
|
-
function
|
|
990
|
+
function ae(c, t) {
|
|
662
991
|
const e = new Float32Array(c.length);
|
|
663
992
|
for (let i = 0; i < t.length; i += 3) {
|
|
664
|
-
const
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
993
|
+
const s = t[i] * 3, r = t[i + 1] * 3, n = t[i + 2] * 3, o = [c[s], c[s + 1], c[s + 2]], a = [c[r], c[r + 1], c[r + 2]], l = [c[n], c[n + 1], c[n + 2]], d = [a[0] - o[0], a[1] - o[1], a[2] - o[2]], u = [l[0] - o[0], l[1] - o[1], l[2] - o[2]], f = [
|
|
994
|
+
d[1] * u[2] - d[2] * u[1],
|
|
995
|
+
d[2] * u[0] - d[0] * u[2],
|
|
996
|
+
d[0] * u[1] - d[1] * u[0]
|
|
668
997
|
], h = Math.sqrt(f[0] * f[0] + f[1] * f[1] + f[2] * f[2]);
|
|
669
|
-
h > 0 && (f[0] /= h, f[1] /= h, f[2] /= h), e[
|
|
998
|
+
h > 0 && (f[0] /= h, f[1] /= h, f[2] /= h), e[s] = e[r] = e[n] = f[0], e[s + 1] = e[r + 1] = e[n + 1] = f[1], e[s + 2] = e[r + 2] = e[n + 2] = f[2];
|
|
670
999
|
}
|
|
671
1000
|
return e;
|
|
672
1001
|
}
|
|
673
|
-
function
|
|
1002
|
+
function re(c, t, e) {
|
|
674
1003
|
const i = c.accessors[e];
|
|
675
1004
|
if (i.type !== "VEC4")
|
|
676
1005
|
throw new Error(`JOINTS_0 must be VEC4, got ${i.type}`);
|
|
677
1006
|
const r = (c.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0), n = i.count;
|
|
678
1007
|
if (i.componentType === 5121) {
|
|
679
|
-
const o = new DataView(t, r, n * 4),
|
|
1008
|
+
const o = new DataView(t, r, n * 4), a = new Uint8Array(n * 4);
|
|
680
1009
|
for (let l = 0; l < n * 4; l++)
|
|
681
|
-
|
|
682
|
-
return
|
|
1010
|
+
a[l] = o.getUint8(l);
|
|
1011
|
+
return a;
|
|
683
1012
|
} else if (i.componentType === 5123) {
|
|
684
|
-
const o = new DataView(t, r, n * 8),
|
|
1013
|
+
const o = new DataView(t, r, n * 8), a = new Uint8Array(n * 4);
|
|
685
1014
|
for (let l = 0; l < n * 4; l++)
|
|
686
|
-
|
|
687
|
-
return
|
|
1015
|
+
a[l] = o.getUint16(l * 2, !0);
|
|
1016
|
+
return a;
|
|
688
1017
|
} else
|
|
689
1018
|
throw new Error(`Unsupported JOINTS_0 component type: ${i.componentType}`);
|
|
690
1019
|
}
|
|
691
|
-
function
|
|
1020
|
+
function ne(c, t, e) {
|
|
692
1021
|
const i = c.accessors[e];
|
|
693
1022
|
if (i.type !== "VEC4")
|
|
694
1023
|
throw new Error(`WEIGHTS_0 must be VEC4, got ${i.type}`);
|
|
695
1024
|
const r = (c.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0), n = i.count;
|
|
696
1025
|
if (i.componentType === 5126) {
|
|
697
|
-
const o = new DataView(t, r, n * 16),
|
|
1026
|
+
const o = new DataView(t, r, n * 16), a = new Float32Array(n * 4);
|
|
698
1027
|
for (let l = 0; l < n * 4; l++)
|
|
699
|
-
|
|
700
|
-
return
|
|
1028
|
+
a[l] = o.getFloat32(l * 4, !0);
|
|
1029
|
+
return a;
|
|
701
1030
|
} else if (i.componentType === 5121) {
|
|
702
|
-
const o = new DataView(t, r, n * 4),
|
|
1031
|
+
const o = new DataView(t, r, n * 4), a = new Float32Array(n * 4);
|
|
703
1032
|
for (let l = 0; l < n * 4; l++)
|
|
704
|
-
|
|
705
|
-
return
|
|
1033
|
+
a[l] = o.getUint8(l) / 255;
|
|
1034
|
+
return a;
|
|
706
1035
|
} else
|
|
707
1036
|
throw new Error(`Unsupported WEIGHTS_0 component type: ${i.componentType}`);
|
|
708
1037
|
}
|
|
709
|
-
function
|
|
1038
|
+
function oe(c, t, e) {
|
|
710
1039
|
const i = c.accessors[e];
|
|
711
1040
|
if (i.type !== "MAT4")
|
|
712
1041
|
throw new Error(`Expected MAT4, got ${i.type}`);
|
|
713
1042
|
if (i.componentType !== 5126)
|
|
714
1043
|
throw new Error(`Expected FLOAT component type for MAT4, got ${i.componentType}`);
|
|
715
|
-
const r = (c.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0), n = i.count, o = new DataView(t, r, n * 64),
|
|
1044
|
+
const r = (c.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0), n = i.count, o = new DataView(t, r, n * 64), a = new Float32Array(n * 16);
|
|
716
1045
|
for (let l = 0; l < n * 16; l++)
|
|
717
|
-
|
|
718
|
-
return
|
|
1046
|
+
a[l] = o.getFloat32(l * 4, !0);
|
|
1047
|
+
return a;
|
|
719
1048
|
}
|
|
720
|
-
function
|
|
1049
|
+
function le(c, t, e) {
|
|
721
1050
|
const i = c.accessors[e];
|
|
722
1051
|
if (i.type !== "SCALAR")
|
|
723
1052
|
throw new Error(`Expected SCALAR, got ${i.type}`);
|
|
724
1053
|
if (i.componentType !== 5126)
|
|
725
1054
|
throw new Error(`Expected FLOAT component type for SCALAR, got ${i.componentType}`);
|
|
726
|
-
const r = (c.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0), n = i.count, o = new DataView(t, r, n * 4),
|
|
1055
|
+
const r = (c.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0), n = i.count, o = new DataView(t, r, n * 4), a = new Float32Array(n);
|
|
727
1056
|
for (let l = 0; l < n; l++)
|
|
728
|
-
|
|
729
|
-
return
|
|
1057
|
+
a[l] = o.getFloat32(l * 4, !0);
|
|
1058
|
+
return a;
|
|
730
1059
|
}
|
|
731
|
-
function
|
|
1060
|
+
function ce(c, t, e) {
|
|
732
1061
|
const i = c.accessors[e], r = { VEC3: 3, VEC4: 4 }[i.type];
|
|
733
1062
|
if (!r)
|
|
734
1063
|
throw new Error(`Expected VEC3 or VEC4, got ${i.type}`);
|
|
735
1064
|
if (i.componentType !== 5126)
|
|
736
1065
|
throw new Error(`Expected FLOAT component type, got ${i.componentType}`);
|
|
737
|
-
const o = (c.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0),
|
|
738
|
-
for (let
|
|
739
|
-
u
|
|
740
|
-
return
|
|
1066
|
+
const o = (c.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0), a = i.count, l = new DataView(t, o, a * r * 4), d = new Float32Array(a * r);
|
|
1067
|
+
for (let u = 0; u < a * r; u++)
|
|
1068
|
+
d[u] = l.getFloat32(u * 4, !0);
|
|
1069
|
+
return d;
|
|
741
1070
|
}
|
|
742
|
-
function
|
|
743
|
-
const i = c.skins[0],
|
|
1071
|
+
function de(c, t, e) {
|
|
1072
|
+
const i = c.skins[0], s = i.joints, r = oe(c, t, i.inverseBindMatrices), n = e.attributes.JOINTS_0 !== void 0 ? re(c, t, e.attributes.JOINTS_0) : null, o = e.attributes.WEIGHTS_0 !== void 0 ? ne(c, t, e.attributes.WEIGHTS_0) : null;
|
|
744
1073
|
if (!n || !o)
|
|
745
1074
|
throw new Error("Mesh missing JOINTS_0 or WEIGHTS_0 attributes");
|
|
746
|
-
const
|
|
747
|
-
translation:
|
|
748
|
-
rotation:
|
|
749
|
-
scale:
|
|
750
|
-
children:
|
|
751
|
-
name:
|
|
1075
|
+
const a = c.nodes.map((d) => ({
|
|
1076
|
+
translation: d.translation || [0, 0, 0],
|
|
1077
|
+
rotation: d.rotation || [0, 0, 0, 1],
|
|
1078
|
+
scale: d.scale || [1, 1, 1],
|
|
1079
|
+
children: d.children || [],
|
|
1080
|
+
name: d.name || ""
|
|
752
1081
|
})), l = [];
|
|
753
1082
|
if (c.animations && c.animations.length > 0)
|
|
754
|
-
for (const
|
|
755
|
-
const
|
|
1083
|
+
for (const d of c.animations) {
|
|
1084
|
+
const u = [];
|
|
756
1085
|
let f = 0;
|
|
757
|
-
for (const h of
|
|
758
|
-
const p =
|
|
759
|
-
S > f && (f = S),
|
|
1086
|
+
for (const h of d.channels) {
|
|
1087
|
+
const p = d.samplers[h.sampler], m = le(c, t, p.input), b = ce(c, t, p.output), S = m[m.length - 1];
|
|
1088
|
+
S > f && (f = S), u.push({
|
|
760
1089
|
targetNode: h.target.node,
|
|
761
1090
|
targetPath: h.target.path,
|
|
762
1091
|
interpolation: p.interpolation || "LINEAR",
|
|
@@ -765,51 +1094,51 @@ function te(c, t, e) {
|
|
|
765
1094
|
});
|
|
766
1095
|
}
|
|
767
1096
|
l.push({
|
|
768
|
-
name:
|
|
1097
|
+
name: d.name || `Animation ${l.length}`,
|
|
769
1098
|
duration: f,
|
|
770
|
-
channels:
|
|
1099
|
+
channels: u
|
|
771
1100
|
});
|
|
772
1101
|
}
|
|
773
1102
|
return {
|
|
774
|
-
joints:
|
|
1103
|
+
joints: s,
|
|
775
1104
|
inverseBindMatrices: r,
|
|
776
1105
|
jointIndices: n,
|
|
777
1106
|
jointWeights: o,
|
|
778
|
-
nodes:
|
|
1107
|
+
nodes: a,
|
|
779
1108
|
animations: l
|
|
780
1109
|
};
|
|
781
1110
|
}
|
|
782
|
-
async function
|
|
1111
|
+
async function ue(c) {
|
|
783
1112
|
const t = new DataView(c);
|
|
784
1113
|
if (t.getUint32(0, !0) !== 1179937895)
|
|
785
1114
|
throw new Error("Invalid GLB file: incorrect magic number");
|
|
786
1115
|
const i = t.getUint32(4, !0);
|
|
787
1116
|
if (i !== 2)
|
|
788
1117
|
throw new Error(`Unsupported GLB version: ${i}`);
|
|
789
|
-
const
|
|
1118
|
+
const s = t.getUint32(8, !0);
|
|
790
1119
|
let r = 12, n = null, o = null;
|
|
791
|
-
for (; r <
|
|
792
|
-
const
|
|
1120
|
+
for (; r < s; ) {
|
|
1121
|
+
const _ = t.getUint32(r, !0), g = t.getUint32(r + 4, !0), x = c.slice(r + 8, r + 8 + _);
|
|
793
1122
|
if (g === 1313821514) {
|
|
794
|
-
const
|
|
795
|
-
n = JSON.parse(
|
|
1123
|
+
const M = new TextDecoder("utf-8").decode(x);
|
|
1124
|
+
n = JSON.parse(M);
|
|
796
1125
|
} else g === 5130562 && (o = x);
|
|
797
|
-
r += 8 +
|
|
1126
|
+
r += 8 + _;
|
|
798
1127
|
}
|
|
799
1128
|
if (!n)
|
|
800
1129
|
throw new Error("GLB file missing JSON chunk");
|
|
801
1130
|
if (!n.materials || n.materials.length === 0)
|
|
802
1131
|
return null;
|
|
803
|
-
const
|
|
804
|
-
if (!
|
|
1132
|
+
const a = n.materials[0];
|
|
1133
|
+
if (!a.pbrMetallicRoughness || a.pbrMetallicRoughness.baseColorTexture === void 0)
|
|
805
1134
|
return null;
|
|
806
|
-
const l =
|
|
1135
|
+
const l = a.pbrMetallicRoughness.baseColorTexture.index;
|
|
807
1136
|
if (!n.textures || !n.textures[l])
|
|
808
1137
|
return null;
|
|
809
|
-
const
|
|
810
|
-
if (
|
|
1138
|
+
const u = n.textures[l].source;
|
|
1139
|
+
if (u === void 0 || !n.images || !n.images[u])
|
|
811
1140
|
return null;
|
|
812
|
-
const f = n.images[
|
|
1141
|
+
const f = n.images[u], h = f.mimeType || "image/png";
|
|
813
1142
|
if (f.bufferView === void 0)
|
|
814
1143
|
return null;
|
|
815
1144
|
if (!o)
|
|
@@ -817,55 +1146,55 @@ async function ie(c) {
|
|
|
817
1146
|
const p = n.bufferViews[f.bufferView], m = p.byteOffset || 0, b = p.byteLength, S = o.slice(m, m + b);
|
|
818
1147
|
return { imageBlob: new Blob([S], { type: h }), mimeType: h };
|
|
819
1148
|
}
|
|
820
|
-
const
|
|
1149
|
+
const D = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
821
1150
|
__proto__: null,
|
|
822
|
-
extractGLBTexture:
|
|
823
|
-
parseGLB:
|
|
1151
|
+
extractGLBTexture: ue,
|
|
1152
|
+
parseGLB: X
|
|
824
1153
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
825
|
-
function
|
|
1154
|
+
function G(c, t, e) {
|
|
826
1155
|
return [
|
|
827
1156
|
c[0] + (t[0] - c[0]) * e,
|
|
828
1157
|
c[1] + (t[1] - c[1]) * e,
|
|
829
1158
|
c[2] + (t[2] - c[2]) * e
|
|
830
1159
|
];
|
|
831
1160
|
}
|
|
832
|
-
function
|
|
833
|
-
let i = c[0] * t[0] + c[1] * t[1] + c[2] * t[2] + c[3] * t[3],
|
|
834
|
-
if (i < 0 && (i = -i,
|
|
1161
|
+
function V(c, t, e) {
|
|
1162
|
+
let i = c[0] * t[0] + c[1] * t[1] + c[2] * t[2] + c[3] * t[3], s = t;
|
|
1163
|
+
if (i < 0 && (i = -i, s = [-t[0], -t[1], -t[2], -t[3]]), i > 0.9995) {
|
|
835
1164
|
const l = [
|
|
836
|
-
c[0] + (
|
|
837
|
-
c[1] + (
|
|
838
|
-
c[2] + (
|
|
839
|
-
c[3] + (
|
|
1165
|
+
c[0] + (s[0] - c[0]) * e,
|
|
1166
|
+
c[1] + (s[1] - c[1]) * e,
|
|
1167
|
+
c[2] + (s[2] - c[2]) * e,
|
|
1168
|
+
c[3] + (s[3] - c[3]) * e
|
|
840
1169
|
];
|
|
841
|
-
return
|
|
1170
|
+
return fe(l);
|
|
842
1171
|
}
|
|
843
|
-
const r = Math.acos(i), n = Math.sin(r), o = Math.sin((1 - e) * r) / n,
|
|
1172
|
+
const r = Math.acos(i), n = Math.sin(r), o = Math.sin((1 - e) * r) / n, a = Math.sin(e * r) / n;
|
|
844
1173
|
return [
|
|
845
|
-
c[0] * o +
|
|
846
|
-
c[1] * o +
|
|
847
|
-
c[2] * o +
|
|
848
|
-
c[3] * o +
|
|
1174
|
+
c[0] * o + s[0] * a,
|
|
1175
|
+
c[1] * o + s[1] * a,
|
|
1176
|
+
c[2] * o + s[2] * a,
|
|
1177
|
+
c[3] * o + s[3] * a
|
|
849
1178
|
];
|
|
850
1179
|
}
|
|
851
|
-
function
|
|
1180
|
+
function fe(c) {
|
|
852
1181
|
const t = Math.sqrt(c[0] * c[0] + c[1] * c[1] + c[2] * c[2] + c[3] * c[3]);
|
|
853
1182
|
return t > 1e-4 ? [c[0] / t, c[1] / t, c[2] / t, c[3] / t] : [0, 0, 0, 1];
|
|
854
1183
|
}
|
|
855
|
-
function
|
|
856
|
-
const t = c[0], e = c[1], i = c[2],
|
|
1184
|
+
function he(c) {
|
|
1185
|
+
const t = c[0], e = c[1], i = c[2], s = c[3], r = t + t, n = e + e, o = i + i, a = t * r, l = t * n, d = t * o, u = e * n, f = e * o, h = i * o, p = s * r, m = s * n, b = s * o;
|
|
857
1186
|
return new Float32Array([
|
|
858
|
-
1 - (
|
|
1187
|
+
1 - (u + h),
|
|
859
1188
|
l + b,
|
|
860
|
-
|
|
1189
|
+
d - m,
|
|
861
1190
|
0,
|
|
862
1191
|
l - b,
|
|
863
|
-
1 - (
|
|
1192
|
+
1 - (a + h),
|
|
864
1193
|
f + p,
|
|
865
1194
|
0,
|
|
866
|
-
|
|
1195
|
+
d + m,
|
|
867
1196
|
f - p,
|
|
868
|
-
1 - (
|
|
1197
|
+
1 - (a + u),
|
|
869
1198
|
0,
|
|
870
1199
|
0,
|
|
871
1200
|
0,
|
|
@@ -873,8 +1202,8 @@ function se(c) {
|
|
|
873
1202
|
1
|
|
874
1203
|
]);
|
|
875
1204
|
}
|
|
876
|
-
function
|
|
877
|
-
const i =
|
|
1205
|
+
function pe(c, t, e) {
|
|
1206
|
+
const i = he(t);
|
|
878
1207
|
return new Float32Array([
|
|
879
1208
|
i[0] * e[0],
|
|
880
1209
|
i[1] * e[0],
|
|
@@ -894,14 +1223,14 @@ function re(c, t, e) {
|
|
|
894
1223
|
1
|
|
895
1224
|
]);
|
|
896
1225
|
}
|
|
897
|
-
function
|
|
1226
|
+
function L(c, t) {
|
|
898
1227
|
const e = new Float32Array(16);
|
|
899
1228
|
for (let i = 0; i < 4; i++)
|
|
900
|
-
for (let
|
|
901
|
-
e[i * 4 +
|
|
1229
|
+
for (let s = 0; s < 4; s++)
|
|
1230
|
+
e[i * 4 + s] = c[0 + s] * t[i * 4 + 0] + c[4 + s] * t[i * 4 + 1] + c[8 + s] * t[i * 4 + 2] + c[12 + s] * t[i * 4 + 3];
|
|
902
1231
|
return e;
|
|
903
1232
|
}
|
|
904
|
-
class
|
|
1233
|
+
class me {
|
|
905
1234
|
constructor(t) {
|
|
906
1235
|
this.joints = t.joints, this.inverseBindMatrices = t.inverseBindMatrices, this.jointWeights = t.jointWeights, this.jointIndices = t.jointIndices, this.nodes = t.nodes, this.animations = t.animations, this.restPositions = null, this.restNormals = null, this.currentAnimIndex = 0, this.currentTime = 0, this.playing = !0, this.speed = 1, this.loop = !0, this.jointLocalTransforms = new Array(this.nodes.length), this.jointGlobalTransforms = new Array(this.nodes.length), this.jointFinalMatrices = new Array(this.joints.length);
|
|
907
1236
|
for (let e = 0; e < this.nodes.length; e++)
|
|
@@ -925,10 +1254,10 @@ class ne {
|
|
|
925
1254
|
async initGPUSkinning(t, e, i) {
|
|
926
1255
|
try {
|
|
927
1256
|
this._gpuDevice = t, this._gpuOutputBuffer = e;
|
|
928
|
-
const
|
|
929
|
-
for (let l = 0; l <
|
|
930
|
-
const
|
|
931
|
-
r[
|
|
1257
|
+
const s = this.restPositions.length / 3, r = new Float32Array(s * 8);
|
|
1258
|
+
for (let l = 0; l < s; l++) {
|
|
1259
|
+
const d = l * 8, u = l * 3, f = l * 2;
|
|
1260
|
+
r[d] = this.restPositions[u], r[d + 1] = this.restPositions[u + 1], r[d + 2] = this.restPositions[u + 2], r[d + 3] = this.restNormals[u], r[d + 4] = this.restNormals[u + 1], r[d + 5] = this.restNormals[u + 2], r[d + 6] = i ? i[f] : 0, r[d + 7] = i ? i[f + 1] : 0;
|
|
932
1261
|
}
|
|
933
1262
|
this._gpuRestDataBuffer = t.createBuffer({
|
|
934
1263
|
size: r.byteLength,
|
|
@@ -951,7 +1280,7 @@ class ne {
|
|
|
951
1280
|
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
|
|
952
1281
|
label: "skinning_jointMatrices"
|
|
953
1282
|
}), this._gpuJointMatricesData = new Float32Array(this.joints.length * 16);
|
|
954
|
-
const { skinningComputeShader: o } = await Promise.resolve().then(() =>
|
|
1283
|
+
const { skinningComputeShader: o } = await Promise.resolve().then(() => H), a = t.createBindGroupLayout({
|
|
955
1284
|
entries: [
|
|
956
1285
|
{ binding: 0, visibility: GPUShaderStage.COMPUTE, buffer: { type: "read-only-storage" } },
|
|
957
1286
|
{ binding: 1, visibility: GPUShaderStage.COMPUTE, buffer: { type: "read-only-storage" } },
|
|
@@ -961,13 +1290,13 @@ class ne {
|
|
|
961
1290
|
]
|
|
962
1291
|
});
|
|
963
1292
|
this._gpuSkinningPipeline = t.createComputePipeline({
|
|
964
|
-
layout: t.createPipelineLayout({ bindGroupLayouts: [
|
|
1293
|
+
layout: t.createPipelineLayout({ bindGroupLayouts: [a] }),
|
|
965
1294
|
compute: {
|
|
966
1295
|
module: t.createShaderModule({ code: o }),
|
|
967
1296
|
entryPoint: "main"
|
|
968
1297
|
}
|
|
969
1298
|
}), this._gpuSkinningBindGroup = t.createBindGroup({
|
|
970
|
-
layout:
|
|
1299
|
+
layout: a,
|
|
971
1300
|
entries: [
|
|
972
1301
|
{ binding: 0, resource: { buffer: this._gpuRestDataBuffer } },
|
|
973
1302
|
{ binding: 1, resource: { buffer: this._gpuJointWeightsBuffer } },
|
|
@@ -975,9 +1304,9 @@ class ne {
|
|
|
975
1304
|
{ binding: 3, resource: { buffer: this._gpuJointMatricesBuffer } },
|
|
976
1305
|
{ binding: 4, resource: { buffer: this._gpuOutputBuffer } }
|
|
977
1306
|
]
|
|
978
|
-
}), this._gpuVertexCount =
|
|
979
|
-
} catch (
|
|
980
|
-
console.warn("GPU skinning init failed, using CPU fallback:",
|
|
1307
|
+
}), this._gpuVertexCount = s, this._gpuSkinningReady = !0, console.log(`GPU skinning initialized: ${s} vertices, ${this.joints.length} joints`);
|
|
1308
|
+
} catch (s) {
|
|
1309
|
+
console.warn("GPU skinning init failed, using CPU fallback:", s), this._gpuSkinningReady = !1;
|
|
981
1310
|
}
|
|
982
1311
|
}
|
|
983
1312
|
/**
|
|
@@ -1034,41 +1363,41 @@ class ne {
|
|
|
1034
1363
|
for (const o of n.children)
|
|
1035
1364
|
i(o);
|
|
1036
1365
|
e.push(r);
|
|
1037
|
-
},
|
|
1366
|
+
}, s = /* @__PURE__ */ new Set();
|
|
1038
1367
|
for (const r of this.nodes)
|
|
1039
1368
|
for (const n of r.children)
|
|
1040
|
-
|
|
1369
|
+
s.add(n);
|
|
1041
1370
|
for (let r = 0; r < this.nodes.length; r++)
|
|
1042
|
-
|
|
1371
|
+
s.has(r) || i(r);
|
|
1043
1372
|
this.topologicalOrder = e.reverse();
|
|
1044
1373
|
}
|
|
1045
1374
|
/**
|
|
1046
1375
|
* Sample a single channel at the given time.
|
|
1047
1376
|
*/
|
|
1048
1377
|
_sampleChannel(t, e) {
|
|
1049
|
-
const { timestamps: i, values:
|
|
1378
|
+
const { timestamps: i, values: s, interpolation: r, targetPath: n } = t;
|
|
1050
1379
|
if (e <= i[0])
|
|
1051
|
-
return this._extractValue(
|
|
1380
|
+
return this._extractValue(s, 0, n);
|
|
1052
1381
|
if (e >= i[i.length - 1])
|
|
1053
|
-
return this._extractValue(
|
|
1054
|
-
let o = 0,
|
|
1055
|
-
for (;
|
|
1056
|
-
const p = Math.floor((o +
|
|
1057
|
-
i[p] <= e ? o = p :
|
|
1382
|
+
return this._extractValue(s, i.length - 1, n);
|
|
1383
|
+
let o = 0, a = i.length - 1;
|
|
1384
|
+
for (; a - o > 1; ) {
|
|
1385
|
+
const p = Math.floor((o + a) / 2);
|
|
1386
|
+
i[p] <= e ? o = p : a = p;
|
|
1058
1387
|
}
|
|
1059
|
-
const l = i[o],
|
|
1060
|
-
return r === "STEP" ? f : n === "rotation" ?
|
|
1388
|
+
const l = i[o], d = i[a], u = (e - l) / (d - l), f = this._extractValue(s, o, n), h = this._extractValue(s, a, n);
|
|
1389
|
+
return r === "STEP" ? f : n === "rotation" ? V(f, h, u) : G(f, h, u);
|
|
1061
1390
|
}
|
|
1062
1391
|
/**
|
|
1063
1392
|
* Extract value from values array at the given index.
|
|
1064
1393
|
*/
|
|
1065
1394
|
_extractValue(t, e, i) {
|
|
1066
1395
|
if (i === "rotation") {
|
|
1067
|
-
const
|
|
1068
|
-
return [t[
|
|
1396
|
+
const s = e * 4;
|
|
1397
|
+
return [t[s], t[s + 1], t[s + 2], t[s + 3]];
|
|
1069
1398
|
} else {
|
|
1070
|
-
const
|
|
1071
|
-
return [t[
|
|
1399
|
+
const s = e * 3;
|
|
1400
|
+
return [t[s], t[s + 1], t[s + 2]];
|
|
1072
1401
|
}
|
|
1073
1402
|
}
|
|
1074
1403
|
/**
|
|
@@ -1077,14 +1406,14 @@ class ne {
|
|
|
1077
1406
|
_computeLocalTransforms(t) {
|
|
1078
1407
|
const e = this.animations[this.currentAnimIndex];
|
|
1079
1408
|
for (let i = 0; i < this.nodes.length; i++) {
|
|
1080
|
-
const
|
|
1081
|
-
let r =
|
|
1082
|
-
for (const
|
|
1083
|
-
if (
|
|
1084
|
-
const l = this._sampleChannel(
|
|
1085
|
-
|
|
1409
|
+
const s = this.nodes[i];
|
|
1410
|
+
let r = s.translation, n = s.rotation, o = s.scale;
|
|
1411
|
+
for (const a of e.channels)
|
|
1412
|
+
if (a.targetNode === i) {
|
|
1413
|
+
const l = this._sampleChannel(a, t);
|
|
1414
|
+
a.targetPath === "translation" ? r = l : a.targetPath === "rotation" ? n = l : a.targetPath === "scale" && (o = l);
|
|
1086
1415
|
}
|
|
1087
|
-
this.jointLocalTransforms[i] =
|
|
1416
|
+
this.jointLocalTransforms[i] = pe(r, n, o);
|
|
1088
1417
|
}
|
|
1089
1418
|
}
|
|
1090
1419
|
/**
|
|
@@ -1094,12 +1423,12 @@ class ne {
|
|
|
1094
1423
|
const t = new Array(this.nodes.length).fill(-1);
|
|
1095
1424
|
for (let e = 0; e < this.nodes.length; e++) {
|
|
1096
1425
|
const i = this.nodes[e];
|
|
1097
|
-
for (const
|
|
1098
|
-
t[
|
|
1426
|
+
for (const s of i.children)
|
|
1427
|
+
t[s] = e;
|
|
1099
1428
|
}
|
|
1100
1429
|
for (const e of this.topologicalOrder) {
|
|
1101
1430
|
const i = t[e];
|
|
1102
|
-
i === -1 ? this.jointGlobalTransforms[e] = this.jointLocalTransforms[e] : this.jointGlobalTransforms[e] =
|
|
1431
|
+
i === -1 ? this.jointGlobalTransforms[e] = this.jointLocalTransforms[e] : this.jointGlobalTransforms[e] = L(
|
|
1103
1432
|
this.jointGlobalTransforms[i],
|
|
1104
1433
|
this.jointLocalTransforms[e]
|
|
1105
1434
|
);
|
|
@@ -1110,8 +1439,8 @@ class ne {
|
|
|
1110
1439
|
*/
|
|
1111
1440
|
_computeFinalMatrices() {
|
|
1112
1441
|
for (let t = 0; t < this.joints.length; t++) {
|
|
1113
|
-
const e = this.joints[t], i = this.jointGlobalTransforms[e],
|
|
1114
|
-
this.jointFinalMatrices[t] =
|
|
1442
|
+
const e = this.joints[t], i = this.jointGlobalTransforms[e], s = t * 16, r = this.inverseBindMatrices.slice(s, s + 16);
|
|
1443
|
+
this.jointFinalMatrices[t] = L(i, r);
|
|
1115
1444
|
}
|
|
1116
1445
|
}
|
|
1117
1446
|
/**
|
|
@@ -1119,28 +1448,28 @@ class ne {
|
|
|
1119
1448
|
* Inlined math, no temporary array allocations.
|
|
1120
1449
|
*/
|
|
1121
1450
|
_applySkinning() {
|
|
1122
|
-
const t = this.restPositions.length / 3, e = this.restPositions, i = this.restNormals,
|
|
1451
|
+
const t = this.restPositions.length / 3, e = this.restPositions, i = this.restNormals, s = this.skinnedPositions, r = this.skinnedNormals, n = this.jointWeights, o = this.jointIndices, a = this.jointFinalMatrices;
|
|
1123
1452
|
for (let l = 0; l < t; l++) {
|
|
1124
|
-
const
|
|
1125
|
-
let y = 0,
|
|
1126
|
-
for (let
|
|
1127
|
-
const
|
|
1128
|
-
if (
|
|
1129
|
-
const v =
|
|
1130
|
-
y += (v[0] * f + v[4] * h + v[8] * p + v[12]) *
|
|
1453
|
+
const d = l * 3, u = l * 4, f = e[d], h = e[d + 1], p = e[d + 2], m = i[d], b = i[d + 1], S = i[d + 2];
|
|
1454
|
+
let y = 0, _ = 0, g = 0, x = 0, P = 0, M = 0;
|
|
1455
|
+
for (let B = 0; B < 4; B++) {
|
|
1456
|
+
const R = n[u + B];
|
|
1457
|
+
if (R === 0) continue;
|
|
1458
|
+
const v = a[o[u + B]];
|
|
1459
|
+
y += (v[0] * f + v[4] * h + v[8] * p + v[12]) * R, _ += (v[1] * f + v[5] * h + v[9] * p + v[13]) * R, g += (v[2] * f + v[6] * h + v[10] * p + v[14]) * R, x += (v[0] * m + v[4] * b + v[8] * S) * R, P += (v[1] * m + v[5] * b + v[9] * S) * R, M += (v[2] * m + v[6] * b + v[10] * S) * R;
|
|
1131
1460
|
}
|
|
1132
|
-
const
|
|
1133
|
-
|
|
1461
|
+
const w = Math.sqrt(x * x + P * P + M * M);
|
|
1462
|
+
w > 1e-4 && (r[d] = x / w, r[d + 1] = P / w, r[d + 2] = M / w), s[d] = y, s[d + 1] = _, s[d + 2] = g;
|
|
1134
1463
|
}
|
|
1135
1464
|
}
|
|
1136
1465
|
}
|
|
1137
|
-
function
|
|
1466
|
+
function O(c) {
|
|
1138
1467
|
const t = atob(c), e = new Uint8Array(t.length);
|
|
1139
1468
|
for (let i = 0; i < t.length; i++)
|
|
1140
1469
|
e[i] = t.charCodeAt(i);
|
|
1141
1470
|
return e.buffer;
|
|
1142
1471
|
}
|
|
1143
|
-
class
|
|
1472
|
+
class A {
|
|
1144
1473
|
constructor(t, e) {
|
|
1145
1474
|
this.device = t, this.config = e, this.MAX_PARTICLES = e.maxParticles || 1e4, this.particleCount = e.particleCount || 100, this.activeParticles = 0, this.emitting = !1, this.currentEmissionTime = 0, this.particleData = new Float32Array(this.MAX_PARTICLES * 8), this.particleVelocities = new Float32Array(this.MAX_PARTICLES * 4), this.instanceBuffer = t.createBuffer({
|
|
1146
1475
|
size: this.MAX_PARTICLES * 8 * 4,
|
|
@@ -1166,7 +1495,7 @@ class _ {
|
|
|
1166
1495
|
// intensity (f32) + padding
|
|
1167
1496
|
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
1168
1497
|
label: "systemBloomIntensityBuffer"
|
|
1169
|
-
}), e.overrideXVelocity === void 0 && (e.overrideXVelocity = !1), e.overrideYVelocity === void 0 && (e.overrideYVelocity = !1), e.overrideZVelocity === void 0 && (e.overrideZVelocity = !1), e.xVelocity === void 0 && (e.xVelocity = 0), e.yVelocity === void 0 && (e.yVelocity = 0), e.zVelocity === void 0 && (e.zVelocity = 0), e.textureEnabled === void 0 && (e.textureEnabled = !1), e.glbModelEnabled === void 0 && (e.glbModelEnabled = !1), e.textureType === void 0 && (e.textureType = "image"), e.glbFileName === void 0 && (e.glbFileName = null), e.animationIndex === void 0 && (e.animationIndex = 0), e.animationSpeed === void 0 && (e.animationSpeed = 1), e.animationLoop === void 0 && (e.animationLoop = !0), e.useGlbTexture === void 0 && (e.useGlbTexture = !1), e.glbHasTexture === void 0 && (e.glbHasTexture = !1), e.particleShape === void 0 && (e.particleShape = "square"), e.particleShapeRotation === void 0 && (e.particleShapeRotation = 0), e.particleShapeRotationX === void 0 && (e.particleShapeRotationX = 0), e.particleShapeRotationY === void 0 && (e.particleShapeRotationY = 0), e.particleShapeRotationZ === void 0 && (e.particleShapeRotationZ = 0), e.particleColor === void 0 && (e.particleColor = [1, 1, 1]), e.startColor === void 0 && (e.startColor = [1, 0, 0]), e.endColor === void 0 && (e.endColor = [0, 0, 1]), e.fadeEnabled === void 0 && (e.fadeEnabled = !0), e.colorTransitionEnabled === void 0 && (e.colorTransitionEnabled = !1), e.randomColorEnabled === void 0 && (e.randomColorEnabled = !1), e.randomColors === void 0 && (e.randomColors = []), e.particleSize === void 0 && (e.particleSize = 0.5), e.particleSpeed === void 0 && (e.particleSpeed = 1), e.opacity === void 0 && (e.opacity = 1), e.aspectRatio === void 0 && (e.aspectRatio = 1), e.rotation === void 0 && (e.rotation = 0), e.rotationMode === void 0 && (e.rotationMode = "fixed"), e.minRotation === void 0 && (e.minRotation = 0), e.maxRotation === void 0 && (e.maxRotation = 90), e.randomSize === void 0 && (e.randomSize = !1), e.minSize === void 0 && (e.minSize = 0.1), e.maxSize === void 0 && (e.maxSize = 0.5), e.randomSpeed === void 0 && (e.randomSpeed = !1), e.minSpeed === void 0 && (e.minSpeed = 0.1), e.maxSpeed === void 0 && (e.maxSpeed = 1), e.fadeSizeEnabled === void 0 && (e.fadeSizeEnabled = !1), e.increaseSizeEnabled === void 0 && (e.increaseSizeEnabled = !1), e.sizeLifetimeSpeed === void 0 && (e.sizeLifetimeSpeed = 1), e.bloomEnabled === void 0 && (e.bloomEnabled = !0), e.bloomIntensity === void 0 && (e.bloomIntensity = 1), e.bloomColor === void 0 && (e.bloomColor = [1, 1, 1]), e.gravityEnabled === void 0 && (e.gravityEnabled = !1), e.gravityStrength === void 0 && (e.gravityStrength = 2), e.dampingEnabled === void 0 && (e.dampingEnabled = !1), e.dampingStrength === void 0 && (e.dampingStrength = 1), e.attractorEnabled === void 0 && (e.attractorEnabled = !1), e.attractorStrength === void 0 && (e.attractorStrength = 1), e.attractorPosition === void 0 && (e.attractorPosition = [0, 0, 0]), e.burstMode === void 0 && (e.burstMode = !1), e.emissionShape === void 0 && (e.emissionShape = "cube"), e.lifetime === void 0 && (e.lifetime = 5), e.emissionRate === void 0 && (e.emissionRate = 10), e.emissionDuration === void 0 && (e.emissionDuration = 10), e.cubeLength === void 0 && (e.cubeLength = 2), e.outerLength === void 0 && (e.outerLength = 2), e.innerLength === void 0 && (e.innerLength = 0), e.outerRadius === void 0 && (e.outerRadius = 2), e.innerRadius === void 0 && (e.innerRadius = 0), e.squareSize === void 0 && (e.squareSize = 2), e.squareInnerSize === void 0 && (e.squareInnerSize = 0), e.circleInnerRadius === void 0 && (e.circleInnerRadius = 0), e.circleOuterRadius === void 0 && (e.circleOuterRadius = 2), e.circleVelocityDirection === void 0 && (e.circleVelocityDirection = "outward"), e.cylinderInnerRadius === void 0 && (e.cylinderInnerRadius = 0), e.cylinderOuterRadius === void 0 && (e.cylinderOuterRadius = 2), e.cylinderHeight === void 0 && (e.cylinderHeight = 4), e.cylinderVelocityDirection === void 0 && (e.cylinderVelocityDirection = "outward"), e.planeWidth === void 0 && (e.planeWidth = 2), e.planeDepth === void 0 && (e.planeDepth = 2), e.coneOuterRadius === void 0 && (e.coneOuterRadius = 2), e.coneInnerRadius === void 0 && (e.coneInnerRadius = 0), e.coneHeight === void 0 && (e.coneHeight = 4), e.torusMajorRadius === void 0 && (e.torusMajorRadius = 2), e.torusMinorRadius === void 0 && (e.torusMinorRadius = 0.5), e.lineLength === void 0 && (e.lineLength = 4), e.hemisphereOuterRadius === void 0 && (e.hemisphereOuterRadius = 2), e.hemisphereInnerRadius === void 0 && (e.hemisphereInnerRadius = 0), e.discRadius === void 0 && (e.discRadius = 2), e.annulusInnerRadius === void 0 && (e.annulusInnerRadius = 1), e.annulusOuterRadius === void 0 && (e.annulusOuterRadius = 2), e.capsuleRadius === void 0 && (e.capsuleRadius = 0.5), e.capsuleHeight === void 0 && (e.capsuleHeight = 4), e.arcStartAngle === void 0 && (e.arcStartAngle = 0), e.arcEndAngle === void 0 && (e.arcEndAngle = 180), e.arcInnerRadius === void 0 && (e.arcInnerRadius = 0), e.arcOuterRadius === void 0 && (e.arcOuterRadius = 2), e.spiralTurns === void 0 && (e.spiralTurns = 3), e.spiralRadiusStart === void 0 && (e.spiralRadiusStart = 0.5), e.spiralRadiusEnd === void 0 && (e.spiralRadiusEnd = 2), e.spiralHeight === void 0 && (e.spiralHeight = 4), e.frustumRadiusNear === void 0 && (e.frustumRadiusNear = 0.5), e.frustumRadiusFar === void 0 && (e.frustumRadiusFar = 2), e.frustumHeight === void 0 && (e.frustumHeight = 4), e.cubeSurfaceSize === void 0 && (e.cubeSurfaceSize = 2), e.sphereSurfaceRadius === void 0 && (e.sphereSurfaceRadius = 2), e.boxFrameSize === void 0 && (e.boxFrameSize = 2), e.polygonSides === void 0 && (e.polygonSides = 6), e.polygonRadius === void 0 && (e.polygonRadius = 2), e.
|
|
1498
|
+
}), e.overrideXVelocity === void 0 && (e.overrideXVelocity = !1), e.overrideYVelocity === void 0 && (e.overrideYVelocity = !1), e.overrideZVelocity === void 0 && (e.overrideZVelocity = !1), e.xVelocity === void 0 && (e.xVelocity = 0), e.yVelocity === void 0 && (e.yVelocity = 0), e.zVelocity === void 0 && (e.zVelocity = 0), e.textureEnabled === void 0 && (e.textureEnabled = !1), e.glbModelEnabled === void 0 && (e.glbModelEnabled = !1), e.textureType === void 0 && (e.textureType = "image"), e.glbFileName === void 0 && (e.glbFileName = null), e.animationIndex === void 0 && (e.animationIndex = 0), e.animationSpeed === void 0 && (e.animationSpeed = 1), e.animationLoop === void 0 && (e.animationLoop = !0), e.useGlbTexture === void 0 && (e.useGlbTexture = !1), e.glbHasTexture === void 0 && (e.glbHasTexture = !1), e.particleShape === void 0 && (e.particleShape = "square"), e.particleShapeRotation === void 0 && (e.particleShapeRotation = 0), e.particleShapeRotationX === void 0 && (e.particleShapeRotationX = 0), e.particleShapeRotationY === void 0 && (e.particleShapeRotationY = 0), e.particleShapeRotationZ === void 0 && (e.particleShapeRotationZ = 0), e.particleColor === void 0 && (e.particleColor = [1, 1, 1]), e.startColor === void 0 && (e.startColor = [1, 0, 0]), e.endColor === void 0 && (e.endColor = [0, 0, 1]), e.fadeEnabled === void 0 && (e.fadeEnabled = !0), e.colorTransitionEnabled === void 0 && (e.colorTransitionEnabled = !1), e.randomColorEnabled === void 0 && (e.randomColorEnabled = !1), e.randomColors === void 0 && (e.randomColors = []), e.particleSize === void 0 && (e.particleSize = 0.5), e.particleSpeed === void 0 && (e.particleSpeed = 1), e.opacity === void 0 && (e.opacity = 1), e.aspectRatio === void 0 && (e.aspectRatio = 1), e.rotation === void 0 && (e.rotation = 0), e.rotationMode === void 0 && (e.rotationMode = "fixed"), e.minRotation === void 0 && (e.minRotation = 0), e.maxRotation === void 0 && (e.maxRotation = 90), e.randomSize === void 0 && (e.randomSize = !1), e.minSize === void 0 && (e.minSize = 0.1), e.maxSize === void 0 && (e.maxSize = 0.5), e.randomSpeed === void 0 && (e.randomSpeed = !1), e.minSpeed === void 0 && (e.minSpeed = 0.1), e.maxSpeed === void 0 && (e.maxSpeed = 1), e.fadeSizeEnabled === void 0 && (e.fadeSizeEnabled = !1), e.increaseSizeEnabled === void 0 && (e.increaseSizeEnabled = !1), e.sizeLifetimeSpeed === void 0 && (e.sizeLifetimeSpeed = 1), e.bloomEnabled === void 0 && (e.bloomEnabled = !0), e.bloomIntensity === void 0 && (e.bloomIntensity = 1), e.bloomColor === void 0 && (e.bloomColor = [1, 1, 1]), e.gravityEnabled === void 0 && (e.gravityEnabled = !1), e.gravityStrength === void 0 && (e.gravityStrength = 2), e.dampingEnabled === void 0 && (e.dampingEnabled = !1), e.dampingStrength === void 0 && (e.dampingStrength = 1), e.attractorEnabled === void 0 && (e.attractorEnabled = !1), e.attractorStrength === void 0 && (e.attractorStrength = 1), e.attractorPosition === void 0 && (e.attractorPosition = [0, 0, 0]), e.burstMode === void 0 && (e.burstMode = !1), e.emissionShape === void 0 && (e.emissionShape = "cube"), e.lifetime === void 0 && (e.lifetime = 5), e.emissionRate === void 0 && (e.emissionRate = 10), e.emissionDuration === void 0 && (e.emissionDuration = 10), e.cubeLength === void 0 && (e.cubeLength = 2), e.outerLength === void 0 && (e.outerLength = 2), e.innerLength === void 0 && (e.innerLength = 0), e.outerRadius === void 0 && (e.outerRadius = 2), e.innerRadius === void 0 && (e.innerRadius = 0), e.squareSize === void 0 && (e.squareSize = 2), e.squareInnerSize === void 0 && (e.squareInnerSize = 0), e.circleInnerRadius === void 0 && (e.circleInnerRadius = 0), e.circleOuterRadius === void 0 && (e.circleOuterRadius = 2), e.circleVelocityDirection === void 0 && (e.circleVelocityDirection = "outward"), e.cylinderInnerRadius === void 0 && (e.cylinderInnerRadius = 0), e.cylinderOuterRadius === void 0 && (e.cylinderOuterRadius = 2), e.cylinderHeight === void 0 && (e.cylinderHeight = 4), e.cylinderVelocityDirection === void 0 && (e.cylinderVelocityDirection = "outward"), e.planeWidth === void 0 && (e.planeWidth = 2), e.planeDepth === void 0 && (e.planeDepth = 2), e.coneOuterRadius === void 0 && (e.coneOuterRadius = 2), e.coneInnerRadius === void 0 && (e.coneInnerRadius = 0), e.coneHeight === void 0 && (e.coneHeight = 4), e.torusMajorRadius === void 0 && (e.torusMajorRadius = 2), e.torusMinorRadius === void 0 && (e.torusMinorRadius = 0.5), e.lineLength === void 0 && (e.lineLength = 4), e.hemisphereOuterRadius === void 0 && (e.hemisphereOuterRadius = 2), e.hemisphereInnerRadius === void 0 && (e.hemisphereInnerRadius = 0), e.discRadius === void 0 && (e.discRadius = 2), e.annulusInnerRadius === void 0 && (e.annulusInnerRadius = 1), e.annulusOuterRadius === void 0 && (e.annulusOuterRadius = 2), e.capsuleRadius === void 0 && (e.capsuleRadius = 0.5), e.capsuleHeight === void 0 && (e.capsuleHeight = 4), e.arcStartAngle === void 0 && (e.arcStartAngle = 0), e.arcEndAngle === void 0 && (e.arcEndAngle = 180), e.arcInnerRadius === void 0 && (e.arcInnerRadius = 0), e.arcOuterRadius === void 0 && (e.arcOuterRadius = 2), e.spiralTurns === void 0 && (e.spiralTurns = 3), e.spiralRadiusStart === void 0 && (e.spiralRadiusStart = 0.5), e.spiralRadiusEnd === void 0 && (e.spiralRadiusEnd = 2), e.spiralHeight === void 0 && (e.spiralHeight = 4), e.frustumRadiusNear === void 0 && (e.frustumRadiusNear = 0.5), e.frustumRadiusFar === void 0 && (e.frustumRadiusFar = 2), e.frustumHeight === void 0 && (e.frustumHeight = 4), e.cubeSurfaceSize === void 0 && (e.cubeSurfaceSize = 2), e.sphereSurfaceRadius === void 0 && (e.sphereSurfaceRadius = 2), e.boxFrameSize === void 0 && (e.boxFrameSize = 2), e.polygonSides === void 0 && (e.polygonSides = 6), e.polygonRadius === void 0 && (e.polygonRadius = 2), e.emissionRotationX === void 0 && (e.emissionRotationX = 0), e.emissionRotationY === void 0 && (e.emissionRotationY = 0), e.emissionRotationZ === void 0 && (e.emissionRotationZ = 0), e.emissionTranslationX === void 0 && (e.emissionTranslationX = 0), e.emissionTranslationY === void 0 && (e.emissionTranslationY = 0), e.emissionTranslationZ === void 0 && (e.emissionTranslationZ = 0), e.pulseEnabled === void 0 && (e.pulseEnabled = !1), e.pulseAmplitude === void 0 && (e.pulseAmplitude = 0.5), e.pulseFrequency === void 0 && (e.pulseFrequency = 1), e.pulsePhaseRandom === void 0 && (e.pulsePhaseRandom = 0), e.pulseOpacity === void 0 && (e.pulseOpacity = !1), e.confinementEnabled === void 0 && (e.confinementEnabled = !1), e.confinementShape === void 0 && (e.confinementShape = "box"), e.confinementMode === void 0 && (e.confinementMode = "bounce"), e.confinementSpace === void 0 && (e.confinementSpace = "world"), e.confinementBoxHalfSize === void 0 && (e.confinementBoxHalfSize = [2, 2, 2]), e.confinementSphereRadius === void 0 && (e.confinementSphereRadius = 3), e.confinementRestitution === void 0 && (e.confinementRestitution = 0.8), e.confinementFriction === void 0 && (e.confinementFriction = 0.1), e.softBoundaryEnabled === void 0 && (e.softBoundaryEnabled = !1), e.softBoundaryStrength === void 0 && (e.softBoundaryStrength = 5), e.softBoundaryFalloff === void 0 && (e.softBoundaryFalloff = 0.5), e.depthWriteEnabled === void 0 && (e.depthWriteEnabled = !1), e.velocityStretchEnabled === void 0 && (e.velocityStretchEnabled = !1), e.velocityStretchFactor === void 0 && (e.velocityStretchFactor = 1), e.emissionTrailEnabled === void 0 && (e.emissionTrailEnabled = !1), e.emissionTrailDuration === void 0 && (e.emissionTrailDuration = 1), e.emissionTrailWidth === void 0 && (e.emissionTrailWidth = 0.3), e.emissionTrailMinDistance === void 0 && (e.emissionTrailMinDistance = 0.05), e.emissionTrailMaxPoints === void 0 && (e.emissionTrailMaxPoints = 256), e.emissionTrailSegments === void 0 && (e.emissionTrailSegments = 8), e.emissionTrailShape === void 0 && (e.emissionTrailShape = "straight"), e.emissionTrailShapeAmplitude === void 0 && (e.emissionTrailShapeAmplitude = 0.1), e.emissionTrailShapeFrequency === void 0 && (e.emissionTrailShapeFrequency = 4), e.emissionTrailShapeSpeed === void 0 && (e.emissionTrailShapeSpeed = 0), e.shapeDisplay === void 0 && (e.shapeDisplay = !0), e.followSystemTranslation === void 0 && (e.followSystemTranslation = !0), e.followSystemId === void 0 && (e.followSystemId = null), this._newEmissions = [], this._emptyEmissions = [], this._pendingFollowEmissions = this._emptyEmissions, this.glbVertexBuffer = null, this.glbIndexBuffer = null, this.glbIndexCount = 0, this.glbIndexFormat = "uint16", this.glbMeshData = null, this.glbRawArrayBuffer = null, this.glbAnimator = null, this.glbAnimated = !1, this._glbInterleavedData = null, this._appearanceData = new Float32Array(44), this._bloomIntensityData = new Float32Array(16), this._simPosition = [0, 0, 0], this._simVelocity = [0, 0, 0], this._simRotMatrix = null, this._simRotX = 0, this._simRotZ = 0, this.emitter = new W(e), this.physics = new J(t, this.MAX_PARTICLES), this.textureManager = new K(t), e.gravityEnabled && this.setGravity(e.gravityStrength || 0), e.dampingEnabled && this.physics.setDamping(e.dampingStrength || 0), e.attractorEnabled && e.attractorPosition && this.setAttractor(e.attractorStrength || 0, e.attractorPosition), e.confinementEnabled && this.setConfinement({
|
|
1170
1499
|
enabled: !0,
|
|
1171
1500
|
shape: e.confinementShape,
|
|
1172
1501
|
mode: e.confinementMode,
|
|
@@ -1179,11 +1508,18 @@ class _ {
|
|
|
1179
1508
|
enabled: !0,
|
|
1180
1509
|
strength: e.softBoundaryStrength,
|
|
1181
1510
|
falloff: e.softBoundaryFalloff
|
|
1182
|
-
}), this.particleTexture = this.textureManager.getDefaultTexture(), this.updateBloomIntensity(), this.updateAppearanceUniform(), this.frameCount = 0, this.shouldReset = !1, this.initComputePipeline(t);
|
|
1511
|
+
}), this.particleTexture = this.textureManager.getDefaultTexture(), this.updateBloomIntensity(), this.updateAppearanceUniform(), this.frameCount = 0, this.shouldReset = !1, this._scriptParticleData = new Float32Array(this.MAX_PARTICLES * 8), this._scriptVelocityData = new Float32Array(this.MAX_PARTICLES * 4), this._scriptReadbackPending = !1, this._scriptReadbackReady = !1, this._scriptFrame = 0, this._scriptTime = 0, this._scriptConfigRestored = !1, this._particleScript = null, e.script && (this._particleScript = new z(e.script, e, this.MAX_PARTICLES)), this.initComputePipeline(t);
|
|
1183
1512
|
}
|
|
1184
1513
|
async initComputePipeline(t) {
|
|
1185
1514
|
this.computeReady = await this.physics.initComputePipeline(this.instanceBuffer, this.velocityBuffer, this.trailBuffer);
|
|
1186
1515
|
}
|
|
1516
|
+
/**
|
|
1517
|
+
* Set or clear the per-frame CPU script for this particle system.
|
|
1518
|
+
* @param {string|null} source - Script source code, or null to disable
|
|
1519
|
+
*/
|
|
1520
|
+
setScript(t) {
|
|
1521
|
+
this._particleScript && (this._particleScript.destroy(), this._particleScript = null), this._scriptReadbackPending = !1, this._scriptReadbackReady = !1, this._scriptFrame = 0, this._scriptTime = 0, this._scriptConfigRestored = !1, t ? (this.config.script = t, this._particleScript = new z(t, this.config, this.MAX_PARTICLES), this._particleScript.snapshotConfig(this.config)) : delete this.config.script;
|
|
1522
|
+
}
|
|
1187
1523
|
async setTexture(t) {
|
|
1188
1524
|
this.textureManager.destroyTexture(this.particleTexture), this.particleTexture = await this.textureManager.loadTexture(t), this.config.textureEnabled = !0, this.updateAppearanceUniform(), this.updateBuffers();
|
|
1189
1525
|
}
|
|
@@ -1193,11 +1529,11 @@ class _ {
|
|
|
1193
1529
|
async setGLBModel(t) {
|
|
1194
1530
|
try {
|
|
1195
1531
|
this.glbRawArrayBuffer = t;
|
|
1196
|
-
const e = await
|
|
1532
|
+
const e = await X(t);
|
|
1197
1533
|
this.glbMeshData = e, this.config.glbHasTexture = e.hasBaseColorTexture || !1;
|
|
1198
1534
|
const i = new Float32Array(e.vertexCount * 8);
|
|
1199
|
-
for (let
|
|
1200
|
-
const r =
|
|
1535
|
+
for (let s = 0; s < e.vertexCount; s++) {
|
|
1536
|
+
const r = s * 8, n = s * 3, o = s * 2;
|
|
1201
1537
|
i[r + 0] = e.positions[n + 0], i[r + 1] = e.positions[n + 1], i[r + 2] = e.positions[n + 2], i[r + 3] = e.normals[n + 0], i[r + 4] = e.normals[n + 1], i[r + 5] = e.normals[n + 2], e.texCoords ? (i[r + 6] = e.texCoords[o + 0], i[r + 7] = e.texCoords[o + 1]) : (i[r + 6] = 0, i[r + 7] = 0);
|
|
1202
1538
|
}
|
|
1203
1539
|
if (this.glbVertexBuffer && this.glbVertexBuffer.destroy(), this.glbIndexBuffer && this.glbIndexBuffer.destroy(), this.glbVertexBuffer = this.device.createBuffer({
|
|
@@ -1209,11 +1545,11 @@ class _ {
|
|
|
1209
1545
|
usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST,
|
|
1210
1546
|
label: "glbIndexBuffer"
|
|
1211
1547
|
}), this.device.queue.writeBuffer(this.glbIndexBuffer, 0, e.indices), this.glbIndexCount = e.indexCount, this.glbIndexFormat = e.indices instanceof Uint32Array ? "uint32" : "uint16", this.config.glbModelEnabled = !0, this.config.textureType = "glb", e.animationData) {
|
|
1212
|
-
this.glbAnimator = new
|
|
1548
|
+
this.glbAnimator = new me(e.animationData), this.glbAnimator.setRestPose(e.positions, e.normals), this.glbAnimated = !0, this.config.glbAnimated = !0, this.glbAnimator.loop = this.config.animationLoop, this._glbInterleavedData = new Float32Array(e.vertexCount * 8);
|
|
1213
1549
|
try {
|
|
1214
1550
|
await this.glbAnimator.initGPUSkinning(this.device, this.glbVertexBuffer, e.texCoords);
|
|
1215
|
-
} catch (
|
|
1216
|
-
console.warn("GPU skinning init failed, using CPU fallback:",
|
|
1551
|
+
} catch (s) {
|
|
1552
|
+
console.warn("GPU skinning init failed, using CPU fallback:", s);
|
|
1217
1553
|
}
|
|
1218
1554
|
console.log(`GLB animated model loaded: ${e.animationData.animations.length} animations`);
|
|
1219
1555
|
} else
|
|
@@ -1237,14 +1573,14 @@ class _ {
|
|
|
1237
1573
|
setSimulationTransform(t) {
|
|
1238
1574
|
if (t.position && (this._simPosition[0] = t.position[0], this._simPosition[1] = t.position[1], this._simPosition[2] = t.position[2]), t.rotation) {
|
|
1239
1575
|
this._simRotX = t.rotation[0], this._simRotZ = t.rotation[1];
|
|
1240
|
-
const e = Math.cos(this._simRotX), i = Math.sin(this._simRotX),
|
|
1576
|
+
const e = Math.cos(this._simRotX), i = Math.sin(this._simRotX), s = Math.cos(this._simRotZ), r = Math.sin(this._simRotZ);
|
|
1241
1577
|
this._simRotMatrix = [
|
|
1242
|
-
|
|
1578
|
+
s,
|
|
1243
1579
|
-r * e,
|
|
1244
1580
|
r * i,
|
|
1245
1581
|
r,
|
|
1246
|
-
|
|
1247
|
-
-
|
|
1582
|
+
s * e,
|
|
1583
|
+
-s * i,
|
|
1248
1584
|
0,
|
|
1249
1585
|
i,
|
|
1250
1586
|
e
|
|
@@ -1261,8 +1597,8 @@ class _ {
|
|
|
1261
1597
|
if (this.glbAnimator._gpuSkinningReady)
|
|
1262
1598
|
return !0;
|
|
1263
1599
|
const t = this.glbAnimator.skinnedPositions, e = this.glbAnimator.skinnedNormals, i = this.glbMeshData.texCoords;
|
|
1264
|
-
for (let
|
|
1265
|
-
const r =
|
|
1600
|
+
for (let s = 0; s < this.glbMeshData.vertexCount; s++) {
|
|
1601
|
+
const r = s * 8, n = s * 3, o = s * 2;
|
|
1266
1602
|
this._glbInterleavedData[r] = t[n], this._glbInterleavedData[r + 1] = t[n + 1], this._glbInterleavedData[r + 2] = t[n + 2], this._glbInterleavedData[r + 3] = e[n], this._glbInterleavedData[r + 4] = e[n + 1], this._glbInterleavedData[r + 5] = e[n + 2], i ? (this._glbInterleavedData[r + 6] = i[o], this._glbInterleavedData[r + 7] = i[o + 1]) : (this._glbInterleavedData[r + 6] = 0, this._glbInterleavedData[r + 7] = 0);
|
|
1267
1603
|
}
|
|
1268
1604
|
return this.device.queue.writeBuffer(this.glbVertexBuffer, 0, this._glbInterleavedData), !0;
|
|
@@ -1270,8 +1606,10 @@ class _ {
|
|
|
1270
1606
|
updateAppearanceUniform() {
|
|
1271
1607
|
let t = 0;
|
|
1272
1608
|
this.config.rotationMode === "random" ? t = 1 : this.config.rotationMode === "velocity" && (t = 2);
|
|
1273
|
-
const i = { square: 0, circle: 1, triangle: 2, diamond: 3, star: 4, hexagon: 5, ring: 6, heart: 7, cross: 8, spark: 9, leaf: 10, capsule: 11, crescent: 12, line: 13, "curved-line": 14 }[this.config.particleShape] ?? 0,
|
|
1274
|
-
|
|
1609
|
+
const i = { square: 0, circle: 1, triangle: 2, diamond: 3, star: 4, hexagon: 5, ring: 6, heart: 7, cross: 8, spark: 9, leaf: 10, capsule: 11, crescent: 12, line: 13, "curved-line": 14 }[this.config.particleShape] ?? 0, s = this._appearanceData;
|
|
1610
|
+
s[0] = this.config.fadeEnabled ? 1 : 0, s[1] = this.config.randomColorEnabled ? 2 : this.config.colorTransitionEnabled ? 1 : 0, s[2] = this.config.particleSize, s[3] = this.config.textureEnabled ? 1 : 0, s[4] = this.config.particleColor[0], s[5] = this.config.particleColor[1], s[6] = this.config.particleColor[2], s[7] = this.config.rotation || 0, s[8] = this.config.startColor[0], s[9] = this.config.startColor[1], s[10] = this.config.startColor[2], s[11] = t, s[12] = this.config.endColor[0], s[13] = this.config.endColor[1], s[14] = this.config.endColor[2], s[15] = this.config.minRotation || 0, s[16] = this.config.maxRotation || 90, s[17] = this.config.aspectRatio || 1, s[18] = this.config.randomSize ? 1 : 0, s[19] = this.config.minSize || 0.1, s[20] = this.config.maxSize || 0.5, s[21] = this.config.fadeSizeEnabled ? 1 : 0, s[22] = this.config.opacity !== void 0 ? this.config.opacity : 1, s[23] = this.config.increaseSizeEnabled ? 1 : 0, s[24] = this.config.sizeLifetimeSpeed ?? 1, s[25] = i, s[26] = this.config.particleShapeRotation || 0, s[27] = this.config.pulseEnabled ? 1 : 0, s[28] = this.config.pulseAmplitude ?? 0.5, s[29] = this.config.pulseFrequency ?? 1, s[30] = this.config.pulsePhaseRandom ?? 0, s[31] = this.config.pulseOpacity ? 1 : 0, s[32] = this.config.particleShapeRotationX || 0, s[33] = this.config.particleShapeRotationY || 0, s[34] = this.config.particleShapeRotationZ || 0, s[35] = 0, (s[32] !== 0 || s[33] !== 0 || s[34] !== 0) && console.log(`[updateAppearanceUniform] ${this.config.name}: d[32-34] = ${s[32]}, ${s[33]}, ${s[34]}`);
|
|
1611
|
+
const r = this.config.followSystemTranslation ?? !0;
|
|
1612
|
+
s[36] = r ? this._simPosition[0] : 0, s[37] = r ? this._simPosition[1] : 0, s[38] = r ? this._simPosition[2] : 0, s[39] = 0, s[40] = this._simRotX, s[41] = this._simRotZ, s[42] = this.config.velocityStretchEnabled ? 1 : 0, s[43] = this.config.velocityStretchFactor ?? 1, this.device.queue.writeBuffer(this.appearanceUniformBuffer, 0, s);
|
|
1275
1613
|
}
|
|
1276
1614
|
updateBloomIntensity() {
|
|
1277
1615
|
const t = this._bloomIntensityData;
|
|
@@ -1280,7 +1618,7 @@ class _ {
|
|
|
1280
1618
|
t[4] = e[0], t[5] = e[1], t[6] = e[2], this.device.queue.writeBuffer(this.bloomIntensityBuffer, 0, t);
|
|
1281
1619
|
}
|
|
1282
1620
|
spawnParticles() {
|
|
1283
|
-
if (this.activeParticles = 0, this.currentEmissionTime = 0, this._newEmissions.length = 0, this._pendingFollowEmissions = this._emptyEmissions, this.device.queue.writeBuffer(this.trailBuffer, 0, this._trailResetData, 0, this.MAX_PARTICLES * 4), this.glbAnimator && (this.glbAnimator.currentTime = 0, this.glbAnimator.playing = !0), this.config.followSystemId) {
|
|
1621
|
+
if (this.activeParticles = 0, this.currentEmissionTime = 0, this._newEmissions.length = 0, this._pendingFollowEmissions = this._emptyEmissions, this._scriptFrame = 0, this._scriptTime = 0, this._scriptReadbackPending = !1, this._scriptReadbackReady = !1, this._scriptConfigRestored = !1, this._particleScript && (this._particleScript._configSnapshot ? (this._particleScript.restoreConfig(this.config), this.config.gravityEnabled && this.setGravity(this.config.gravityStrength), this.config.dampingEnabled && this.physics.setDamping(this.config.dampingStrength), this.config.attractorEnabled && this.setAttractor(this.config.attractorStrength, this.config.attractorPosition), this.updateAppearanceUniform(), this.updateBloomIntensity()) : this._particleScript.snapshotConfig(this.config)), this.device.queue.writeBuffer(this.trailBuffer, 0, this._trailResetData, 0, this.MAX_PARTICLES * 4), this.glbAnimator && (this.glbAnimator.currentTime = 0, this.glbAnimator.playing = !0), this.config.followSystemId) {
|
|
1284
1622
|
this.emitting = !0, this.particleCount = this.MAX_PARTICLES;
|
|
1285
1623
|
return;
|
|
1286
1624
|
}
|
|
@@ -1289,9 +1627,9 @@ class _ {
|
|
|
1289
1627
|
this.particleCount = t;
|
|
1290
1628
|
let e = 0;
|
|
1291
1629
|
const i = 500;
|
|
1292
|
-
for (let
|
|
1293
|
-
if (this.emitParticle(), e++, e >= i ||
|
|
1294
|
-
const r =
|
|
1630
|
+
for (let s = 0; s < t; s++)
|
|
1631
|
+
if (this.emitParticle(), e++, e >= i || s === t - 1) {
|
|
1632
|
+
const r = s - e + 1, n = r * 8, o = r * 4;
|
|
1295
1633
|
this.device.queue.writeBuffer(
|
|
1296
1634
|
this.instanceBuffer,
|
|
1297
1635
|
n * 4,
|
|
@@ -1320,11 +1658,11 @@ class _ {
|
|
|
1320
1658
|
this.emitter.emitParticle(this.particleData, this.activeParticles, this.particleVelocities);
|
|
1321
1659
|
const t = this.activeParticles * 8, e = this.activeParticles * 4;
|
|
1322
1660
|
if (this._simRotMatrix) {
|
|
1323
|
-
let i = this.particleData[t],
|
|
1661
|
+
let i = this.particleData[t], s = this.particleData[t + 1], r = this.particleData[t + 2], n = this.particleVelocities[e], o = this.particleVelocities[e + 1], a = this.particleVelocities[e + 2];
|
|
1324
1662
|
const l = this._simRotMatrix;
|
|
1325
|
-
this.particleData[t] = l[0] * i + l[1] *
|
|
1663
|
+
this.particleData[t] = l[0] * i + l[1] * s + l[2] * r, this.particleData[t + 1] = l[3] * i + l[4] * s + l[5] * r, this.particleData[t + 2] = l[6] * i + l[7] * s + l[8] * r, this.particleVelocities[e] = l[0] * n + l[1] * o + l[2] * a, this.particleVelocities[e + 1] = l[3] * n + l[4] * o + l[5] * a, this.particleVelocities[e + 2] = l[6] * n + l[7] * o + l[8] * a;
|
|
1326
1664
|
}
|
|
1327
|
-
return this._newEmissions.push(
|
|
1665
|
+
return (this.config.followSystemTranslation ?? !0) || (this.particleData[t] += this._simPosition[0], this.particleData[t + 1] += this._simPosition[1], this.particleData[t + 2] += this._simPosition[2]), this._newEmissions.push(
|
|
1328
1666
|
this.particleData[t],
|
|
1329
1667
|
this.particleData[t + 1],
|
|
1330
1668
|
this.particleData[t + 2],
|
|
@@ -1339,29 +1677,59 @@ class _ {
|
|
|
1339
1677
|
*/
|
|
1340
1678
|
emitFollowerParticle(t, e, i) {
|
|
1341
1679
|
if (this.activeParticles >= this.particleCount) return !1;
|
|
1342
|
-
const
|
|
1343
|
-
this.particleData[
|
|
1344
|
-
const
|
|
1345
|
-
return this.emitter.calculateVelocity(r, n, o, this.particleVelocities,
|
|
1680
|
+
const s = this.activeParticles * 8, r = t + (this.config.emissionTranslationX || 0), n = e + (this.config.emissionTranslationY || 0), o = i + (this.config.emissionTranslationZ || 0);
|
|
1681
|
+
this.particleData[s] = r, this.particleData[s + 1] = n, this.particleData[s + 2] = o;
|
|
1682
|
+
const a = this.activeParticles * 4;
|
|
1683
|
+
return this.emitter.calculateVelocity(r, n, o, this.particleVelocities, a), this.emitter.setParticleColor(this.particleData, s), this.emitter.setParticleLifetime(this.particleData, s), this.activeParticles++, !0;
|
|
1346
1684
|
}
|
|
1347
1685
|
updateParticles(t, e) {
|
|
1686
|
+
if (this._particleScript && this._scriptReadbackReady) {
|
|
1687
|
+
this._scriptReadbackReady = !1, this._scriptTime += t, this._scriptFrame++;
|
|
1688
|
+
const o = (this.config.emissionDuration || 0) + (this.config.lifetime || 0);
|
|
1689
|
+
if (o > 0 && this._scriptTime >= o && !this._scriptConfigRestored)
|
|
1690
|
+
this._scriptConfigRestored = !0, this._particleScript._configSnapshot && (this._particleScript.restoreConfig(this.config), this.updateAppearanceUniform(), this.updateBloomIntensity(), this.config.gravityEnabled && this.setGravity(this.config.gravityStrength), this.config.dampingEnabled && this.physics.setDamping(this.config.dampingStrength), this.config.attractorEnabled && this.setAttractor(this.config.attractorStrength, this.config.attractorPosition));
|
|
1691
|
+
else if (!this._scriptConfigRestored) {
|
|
1692
|
+
const a = o > 0 ? Math.ceil(o / 0.016666666666666666) : 0, { configDirty: l, particlesDirty: d } = this._particleScript.execute(
|
|
1693
|
+
t,
|
|
1694
|
+
this._scriptTime,
|
|
1695
|
+
this._scriptFrame,
|
|
1696
|
+
a,
|
|
1697
|
+
this._scriptParticleData,
|
|
1698
|
+
this._scriptVelocityData,
|
|
1699
|
+
this.activeParticles
|
|
1700
|
+
);
|
|
1701
|
+
d && this.activeParticles > 0 && (this.device.queue.writeBuffer(
|
|
1702
|
+
this.instanceBuffer,
|
|
1703
|
+
0,
|
|
1704
|
+
this._scriptParticleData,
|
|
1705
|
+
0,
|
|
1706
|
+
this.activeParticles * 8
|
|
1707
|
+
), this.device.queue.writeBuffer(
|
|
1708
|
+
this.velocityBuffer,
|
|
1709
|
+
0,
|
|
1710
|
+
this._scriptVelocityData,
|
|
1711
|
+
0,
|
|
1712
|
+
this.activeParticles * 4
|
|
1713
|
+
)), l && (this.updateAppearanceUniform(), this.updateBloomIntensity(), this.config.gravityEnabled && this.setGravity(this.config.gravityStrength), this.config.dampingEnabled && this.physics.setDamping(this.config.dampingStrength), this.config.attractorEnabled && this.setAttractor(this.config.attractorStrength, this.config.attractorPosition));
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1348
1716
|
this.physics.physicsAccumulator += t;
|
|
1349
1717
|
const i = performance.now() / 1e3, r = i - this.physics.lastUpdateTime > 1 / this.physics.minUpdatesPerSecond, n = this.activeParticles;
|
|
1350
1718
|
if (this.emitting)
|
|
1351
1719
|
if (this.currentEmissionTime += t, this.currentEmissionTime < this.config.emissionDuration) {
|
|
1352
1720
|
const o = this.activeParticles;
|
|
1353
|
-
let
|
|
1721
|
+
let a = !1;
|
|
1354
1722
|
if (this.config.followSystemId) {
|
|
1355
1723
|
if (this._pendingFollowEmissions.length > 0) {
|
|
1356
1724
|
const l = this._pendingFollowEmissions.length / 6;
|
|
1357
|
-
for (let
|
|
1358
|
-
const
|
|
1725
|
+
for (let d = 0; d < l; d++) {
|
|
1726
|
+
const u = d * 6;
|
|
1359
1727
|
if (this.emitFollowerParticle(
|
|
1360
|
-
this._pendingFollowEmissions[
|
|
1361
|
-
this._pendingFollowEmissions[
|
|
1362
|
-
this._pendingFollowEmissions[
|
|
1728
|
+
this._pendingFollowEmissions[u],
|
|
1729
|
+
this._pendingFollowEmissions[u + 1],
|
|
1730
|
+
this._pendingFollowEmissions[u + 2]
|
|
1363
1731
|
))
|
|
1364
|
-
|
|
1732
|
+
a = !0;
|
|
1365
1733
|
else
|
|
1366
1734
|
break;
|
|
1367
1735
|
}
|
|
@@ -1370,31 +1738,31 @@ class _ {
|
|
|
1370
1738
|
let l = 0;
|
|
1371
1739
|
if (this.config.emissionRate >= 1) {
|
|
1372
1740
|
l = Math.floor(this.config.emissionRate * t);
|
|
1373
|
-
const
|
|
1374
|
-
Math.random() <
|
|
1741
|
+
const d = this.config.emissionRate * t - l;
|
|
1742
|
+
Math.random() < d && (l += 1);
|
|
1375
1743
|
} else {
|
|
1376
|
-
const
|
|
1377
|
-
Math.random() <
|
|
1744
|
+
const d = this.config.emissionRate * t;
|
|
1745
|
+
Math.random() < d && (l = 1);
|
|
1378
1746
|
}
|
|
1379
1747
|
l === 0 && r && this.config.emissionRate > 0 && this.activeParticles < this.particleCount && (l = 1);
|
|
1380
|
-
for (let
|
|
1381
|
-
|
|
1748
|
+
for (let d = 0; d < l && this.emitParticle(); d++)
|
|
1749
|
+
a = !0;
|
|
1382
1750
|
}
|
|
1383
|
-
if (
|
|
1384
|
-
const l = this.activeParticles - o,
|
|
1751
|
+
if (a) {
|
|
1752
|
+
const l = this.activeParticles - o, d = o * 8, u = o * 4;
|
|
1385
1753
|
this.device.queue.writeBuffer(
|
|
1386
1754
|
this.instanceBuffer,
|
|
1387
|
-
|
|
1755
|
+
d * 4,
|
|
1388
1756
|
// Offset in bytes (float32 = 4 bytes)
|
|
1389
1757
|
this.particleData,
|
|
1390
|
-
|
|
1758
|
+
d,
|
|
1391
1759
|
l * 8
|
|
1392
1760
|
), this.device.queue.writeBuffer(
|
|
1393
1761
|
this.velocityBuffer,
|
|
1394
|
-
|
|
1762
|
+
u * 4,
|
|
1395
1763
|
// Offset in bytes (float32 = 4 bytes)
|
|
1396
1764
|
this.particleVelocities,
|
|
1397
|
-
|
|
1765
|
+
u,
|
|
1398
1766
|
l * 4
|
|
1399
1767
|
);
|
|
1400
1768
|
}
|
|
@@ -1416,7 +1784,17 @@ class _ {
|
|
|
1416
1784
|
this.instanceBuffer,
|
|
1417
1785
|
this.velocityBuffer,
|
|
1418
1786
|
e
|
|
1419
|
-
), this.physics.lastUpdateTime = i), this.frameCount++ % 300 === 0 && this.readbackAndProcessParticles()
|
|
1787
|
+
), this.physics.lastUpdateTime = i), this.frameCount++ % 300 === 0 && this.readbackAndProcessParticles(), this._particleScript && this.activeParticles > 0 && !this._scriptReadbackPending && (this._scriptReadbackPending = !0, this.physics.readbackForScript(
|
|
1788
|
+
this.activeParticles,
|
|
1789
|
+
this._scriptParticleData,
|
|
1790
|
+
this._scriptVelocityData,
|
|
1791
|
+
this.instanceBuffer,
|
|
1792
|
+
this.velocityBuffer
|
|
1793
|
+
).then((o) => {
|
|
1794
|
+
this._scriptReadbackPending = !1, o.shouldUpdate && (this._scriptReadbackReady = !0);
|
|
1795
|
+
}).catch(() => {
|
|
1796
|
+
this._scriptReadbackPending = !1;
|
|
1797
|
+
}));
|
|
1420
1798
|
}
|
|
1421
1799
|
async readbackAndProcessParticles() {
|
|
1422
1800
|
if (!(this.activeParticles <= 0))
|
|
@@ -1430,8 +1808,8 @@ class _ {
|
|
|
1430
1808
|
)).shouldUpdate) return;
|
|
1431
1809
|
let e = 0;
|
|
1432
1810
|
for (let i = 0; i < this.activeParticles; i++) {
|
|
1433
|
-
const
|
|
1434
|
-
if (
|
|
1811
|
+
const s = this.particleData[i * 8 + 6], r = this.particleData[i * 8 + 7];
|
|
1812
|
+
if (s >= r) {
|
|
1435
1813
|
if (this.emitting && this.currentEmissionTime < this.config.emissionDuration && e < this.particleCount) {
|
|
1436
1814
|
this.respawnParticle(i, e), e++;
|
|
1437
1815
|
continue;
|
|
@@ -1441,8 +1819,8 @@ class _ {
|
|
|
1441
1819
|
if (e !== i) {
|
|
1442
1820
|
const n = i * 8, o = e * 8;
|
|
1443
1821
|
this.particleData.copyWithin(o, n, n + 8);
|
|
1444
|
-
const
|
|
1445
|
-
this.particleVelocities.copyWithin(l,
|
|
1822
|
+
const a = i * 4, l = e * 4;
|
|
1823
|
+
this.particleVelocities.copyWithin(l, a, a + 4);
|
|
1446
1824
|
}
|
|
1447
1825
|
e++;
|
|
1448
1826
|
}
|
|
@@ -1461,25 +1839,25 @@ class _ {
|
|
|
1461
1839
|
for (let t = 0; t < this.activeParticles; t++) {
|
|
1462
1840
|
const e = t * 8;
|
|
1463
1841
|
if (this.config.randomColorEnabled && this.config.randomColors.length > 0) {
|
|
1464
|
-
const i = this.config.randomColors,
|
|
1465
|
-
this.particleData[e + 3] =
|
|
1842
|
+
const i = this.config.randomColors, s = i[Math.floor(Math.random() * i.length)];
|
|
1843
|
+
this.particleData[e + 3] = s[0], this.particleData[e + 4] = s[1], this.particleData[e + 5] = s[2];
|
|
1466
1844
|
} else this.config.colorTransitionEnabled ? (this.particleData[e + 3] = this.config.startColor[0], this.particleData[e + 4] = this.config.startColor[1], this.particleData[e + 5] = this.config.startColor[2]) : (this.particleData[e + 3] = this.config.particleColor[0], this.particleData[e + 4] = this.config.particleColor[1], this.particleData[e + 5] = this.config.particleColor[2]);
|
|
1467
1845
|
}
|
|
1468
1846
|
this.activeParticles > 0 && this.device.queue.writeBuffer(this.instanceBuffer, 0, this.particleData, 0, this.activeParticles * 8);
|
|
1469
1847
|
}
|
|
1470
1848
|
updateParticleVelocities() {
|
|
1471
1849
|
for (let t = 0; t < this.activeParticles; t++) {
|
|
1472
|
-
const e = t * 8, i = t * 4,
|
|
1473
|
-
o * o +
|
|
1850
|
+
const e = t * 8, i = t * 4, s = this.particleData[e], r = this.particleData[e + 1], n = this.particleData[e + 2], o = this.particleVelocities[i], a = this.particleVelocities[i + 1], l = this.particleVelocities[i + 2], d = Math.sqrt(
|
|
1851
|
+
o * o + a * a + l * l
|
|
1474
1852
|
);
|
|
1475
|
-
if (
|
|
1476
|
-
const
|
|
1477
|
-
this.particleVelocities[i] = o /
|
|
1853
|
+
if (d > 1e-3) {
|
|
1854
|
+
const u = this.config.particleSpeed * 2;
|
|
1855
|
+
this.particleVelocities[i] = o / d * u, this.particleVelocities[i + 1] = a / d * u, this.particleVelocities[i + 2] = l / d * u;
|
|
1478
1856
|
} else {
|
|
1479
|
-
const
|
|
1480
|
-
if (
|
|
1857
|
+
const u = Math.sqrt(s * s + r * r + n * n);
|
|
1858
|
+
if (u > 1e-3) {
|
|
1481
1859
|
const f = this.config.particleSpeed * 2;
|
|
1482
|
-
this.particleVelocities[i] =
|
|
1860
|
+
this.particleVelocities[i] = s / u * f, this.particleVelocities[i + 1] = r / u * f, this.particleVelocities[i + 2] = n / u * f;
|
|
1483
1861
|
} else
|
|
1484
1862
|
this.particleVelocities[i] = 0, this.particleVelocities[i + 1] = this.config.particleSpeed * 2, this.particleVelocities[i + 2] = 0;
|
|
1485
1863
|
}
|
|
@@ -1508,7 +1886,7 @@ class _ {
|
|
|
1508
1886
|
* Call this when the system is no longer needed.
|
|
1509
1887
|
*/
|
|
1510
1888
|
destroy() {
|
|
1511
|
-
this.instanceBuffer.destroy(), this.velocityBuffer.destroy(), this.trailBuffer.destroy(), this.appearanceUniformBuffer.destroy(), this.bloomIntensityBuffer.destroy(), this.physics.destroy(), this.glbVertexBuffer && (this.glbVertexBuffer.destroy(), this.glbVertexBuffer = null), this.glbIndexBuffer && (this.glbIndexBuffer.destroy(), this.glbIndexBuffer = null), this.textureManager.destroyTexture(this.particleTexture), this.glbAnimator = null, this.glbMeshData = null, this.glbRawArrayBuffer = null, this.particleData = null, this.particleVelocities = null;
|
|
1889
|
+
this.instanceBuffer.destroy(), this.velocityBuffer.destroy(), this.trailBuffer.destroy(), this.appearanceUniformBuffer.destroy(), this.bloomIntensityBuffer.destroy(), this.physics.destroy(), this.glbVertexBuffer && (this.glbVertexBuffer.destroy(), this.glbVertexBuffer = null), this.glbIndexBuffer && (this.glbIndexBuffer.destroy(), this.glbIndexBuffer = null), this.textureManager.destroyTexture(this.particleTexture), this._particleScript && (this._particleScript.destroy(), this._particleScript = null), this.glbAnimator = null, this.glbMeshData = null, this.glbRawArrayBuffer = null, this.particleData = null, this.particleVelocities = null, this._scriptParticleData = null, this._scriptVelocityData = null;
|
|
1512
1890
|
}
|
|
1513
1891
|
setGravity(t) {
|
|
1514
1892
|
this.physics.setGravity(t);
|
|
@@ -1517,27 +1895,27 @@ class _ {
|
|
|
1517
1895
|
this.physics.setAttractor(t, e);
|
|
1518
1896
|
}
|
|
1519
1897
|
setConfinement(t) {
|
|
1520
|
-
const e = t.space === "local" ? [this.config.
|
|
1898
|
+
const e = t.space === "local" ? [this.config.emissionTranslationX || 0, this.config.emissionTranslationY || 0, this.config.emissionTranslationZ || 0] : [0, 0, 0];
|
|
1521
1899
|
this.physics.setConfinement({ ...t, center: e });
|
|
1522
1900
|
}
|
|
1523
1901
|
setSoftBoundary(t) {
|
|
1524
1902
|
this.physics.setSoftBoundary(t);
|
|
1525
1903
|
}
|
|
1526
1904
|
}
|
|
1527
|
-
class
|
|
1905
|
+
class Me {
|
|
1528
1906
|
constructor(t) {
|
|
1529
1907
|
this.device = t, this.particleSystems = [], this.activeSystemIndex = 0, this.systemCounter = 1, this.onSystemCreated = null;
|
|
1530
1908
|
}
|
|
1531
1909
|
createParticleSystem(t = {}) {
|
|
1532
|
-
const e = this.systemCounter++, i = t.name || `System ${e + 1}`,
|
|
1910
|
+
const e = this.systemCounter++, i = t.name || `System ${e + 1}`, s = {
|
|
1533
1911
|
...t,
|
|
1534
1912
|
name: i,
|
|
1535
1913
|
id: e
|
|
1536
|
-
}, r = new
|
|
1914
|
+
}, r = new A(this.device, s);
|
|
1537
1915
|
return this.particleSystems.push({
|
|
1538
1916
|
system: r,
|
|
1539
|
-
config:
|
|
1540
|
-
}), this.particleSystems.length === 1 && (this.activeSystemIndex = 0), this.onSystemCreated && typeof this.onSystemCreated == "function" && this.onSystemCreated(e,
|
|
1917
|
+
config: s
|
|
1918
|
+
}), this.particleSystems.length === 1 && (this.activeSystemIndex = 0), this.onSystemCreated && typeof this.onSystemCreated == "function" && this.onSystemCreated(e, s), e;
|
|
1541
1919
|
}
|
|
1542
1920
|
getActiveSystem() {
|
|
1543
1921
|
return this.particleSystems.length === 0 ? null : this.particleSystems[this.activeSystemIndex].system;
|
|
@@ -1564,8 +1942,8 @@ class me {
|
|
|
1564
1942
|
const e = this.particleSystems[t].config;
|
|
1565
1943
|
this.particleSystems[t].system.destroy(), this.particleSystems.splice(t, 1);
|
|
1566
1944
|
const i = e.id;
|
|
1567
|
-
for (const { config:
|
|
1568
|
-
|
|
1945
|
+
for (const { config: s } of this.particleSystems)
|
|
1946
|
+
s.followSystemId === i && (s.followSystemId = null);
|
|
1569
1947
|
return this.particleSystems.length === 0 ? this.activeSystemIndex = 0 : t <= this.activeSystemIndex && (this.activeSystemIndex = Math.max(0, this.activeSystemIndex - 1)), !0;
|
|
1570
1948
|
}
|
|
1571
1949
|
return !1;
|
|
@@ -1577,21 +1955,21 @@ class me {
|
|
|
1577
1955
|
updateAllSystems(t) {
|
|
1578
1956
|
const e = this.device.createCommandEncoder({ label: "BatchedPhysicsEncoder" });
|
|
1579
1957
|
let i = !1;
|
|
1580
|
-
for (const { system:
|
|
1958
|
+
for (const { system: s, config: r } of this.particleSystems) {
|
|
1581
1959
|
if (r.hidden || r.followSystemId) continue;
|
|
1582
|
-
const n =
|
|
1583
|
-
|
|
1960
|
+
const n = s.activeParticles > 0;
|
|
1961
|
+
s.updateParticles(t, e), (n || s.activeParticles > 0) && (i = !0);
|
|
1584
1962
|
}
|
|
1585
|
-
for (const { system:
|
|
1963
|
+
for (const { system: s, config: r } of this.particleSystems) {
|
|
1586
1964
|
if (r.hidden || !r.followSystemId) continue;
|
|
1587
1965
|
const n = this.getSystemById(r.followSystemId);
|
|
1588
|
-
n && (
|
|
1589
|
-
const o =
|
|
1590
|
-
|
|
1966
|
+
n && (s._pendingFollowEmissions = n.system._newEmissions);
|
|
1967
|
+
const o = s.activeParticles > 0;
|
|
1968
|
+
s.updateParticles(t, e), (o || s.activeParticles > 0) && (i = !0);
|
|
1591
1969
|
}
|
|
1592
1970
|
i && this.device.queue.submit([e.finish()]);
|
|
1593
|
-
for (const { system:
|
|
1594
|
-
|
|
1971
|
+
for (const { system: s } of this.particleSystems)
|
|
1972
|
+
s._newEmissions.length = 0, s._pendingFollowEmissions = s._emptyEmissions;
|
|
1595
1973
|
}
|
|
1596
1974
|
getSystemsList() {
|
|
1597
1975
|
return this.particleSystems.map(({ config: t }, e) => ({
|
|
@@ -1618,40 +1996,40 @@ class me {
|
|
|
1618
1996
|
return console.error("Invalid scene data provided"), !1;
|
|
1619
1997
|
try {
|
|
1620
1998
|
this.particleSystems = [], this.systemCounter = 1;
|
|
1621
|
-
for (const
|
|
1999
|
+
for (const s of t.systems) {
|
|
1622
2000
|
const r = this.systemCounter++, n = {
|
|
1623
|
-
...
|
|
2001
|
+
...s,
|
|
1624
2002
|
id: r
|
|
1625
|
-
}, o = new
|
|
2003
|
+
}, o = new A(this.device, n);
|
|
1626
2004
|
this.particleSystems.push({
|
|
1627
2005
|
system: o,
|
|
1628
2006
|
config: n
|
|
1629
2007
|
});
|
|
1630
2008
|
}
|
|
1631
2009
|
const i = {};
|
|
1632
|
-
t.systems.forEach((
|
|
1633
|
-
i[
|
|
2010
|
+
t.systems.forEach((s, r) => {
|
|
2011
|
+
i[s.id] = this.particleSystems[r].config.id;
|
|
1634
2012
|
});
|
|
1635
|
-
for (const { config:
|
|
1636
|
-
|
|
2013
|
+
for (const { config: s } of this.particleSystems)
|
|
2014
|
+
s.followSystemId && i[s.followSystemId] !== void 0 && (s.followSystemId = i[s.followSystemId]);
|
|
1637
2015
|
t.activeSystemIndex !== void 0 && t.activeSystemIndex >= 0 && t.activeSystemIndex < this.particleSystems.length ? this.activeSystemIndex = t.activeSystemIndex : this.activeSystemIndex = 0;
|
|
1638
|
-
for (const { system:
|
|
2016
|
+
for (const { system: s, config: r } of this.particleSystems)
|
|
1639
2017
|
if (r.glbModelEnabled)
|
|
1640
2018
|
try {
|
|
1641
2019
|
let n = null;
|
|
1642
2020
|
if (r.glbModelData)
|
|
1643
|
-
n =
|
|
2021
|
+
n = O(r.glbModelData);
|
|
1644
2022
|
else if (r.glbFileName) {
|
|
1645
2023
|
const o = await fetch(`/${r.glbFileName}`);
|
|
1646
2024
|
o.ok ? n = await o.arrayBuffer() : console.warn(`GLB file not found: ${r.glbFileName}`);
|
|
1647
2025
|
}
|
|
1648
2026
|
if (n) {
|
|
1649
|
-
if (await
|
|
2027
|
+
if (await s.setGLBModel(n), r.animationIndex !== void 0 && s.glbAnimator && s.glbAnimator.setAnimation(r.animationIndex), r.animationSpeed !== void 0 && s.glbAnimator && (s.glbAnimator.speed = r.animationSpeed), r.animationLoop !== void 0 && s.glbAnimator && (s.glbAnimator.loop = r.animationLoop), r.useGlbTexture && (r.textureEnabled = !0), r.useGlbTexture && ((e = s.glbMeshData) != null && e.hasBaseColorTexture))
|
|
1650
2028
|
try {
|
|
1651
|
-
const { extractGLBTexture: o } = await Promise.resolve().then(() =>
|
|
1652
|
-
if (
|
|
1653
|
-
const l = await createImageBitmap(
|
|
1654
|
-
await
|
|
2029
|
+
const { extractGLBTexture: o } = await Promise.resolve().then(() => D), a = await o(n);
|
|
2030
|
+
if (a) {
|
|
2031
|
+
const l = await createImageBitmap(a.imageBlob);
|
|
2032
|
+
await s.setTexture(l), console.log(`GLB embedded texture restored for ${r.name}`);
|
|
1655
2033
|
}
|
|
1656
2034
|
} catch (o) {
|
|
1657
2035
|
console.warn(`Failed to restore GLB texture for ${r.name}:`, o), r.useGlbTexture = !1;
|
|
@@ -1661,20 +2039,20 @@ class me {
|
|
|
1661
2039
|
} catch (n) {
|
|
1662
2040
|
console.warn(`Failed to load GLB for ${r.name}:`, n), r.glbModelEnabled = !1;
|
|
1663
2041
|
}
|
|
1664
|
-
for (const { system:
|
|
2042
|
+
for (const { system: s, config: r } of this.particleSystems)
|
|
1665
2043
|
if (r.textureEnabled && !r.glbModelEnabled && r.textureImageData)
|
|
1666
2044
|
try {
|
|
1667
2045
|
const n = new Image();
|
|
1668
|
-
await new Promise((
|
|
1669
|
-
n.onload =
|
|
2046
|
+
await new Promise((a, l) => {
|
|
2047
|
+
n.onload = a, n.onerror = l, n.src = r.textureImageData;
|
|
1670
2048
|
});
|
|
1671
2049
|
const o = await createImageBitmap(n);
|
|
1672
|
-
await
|
|
2050
|
+
await s.setTexture(o);
|
|
1673
2051
|
} catch (n) {
|
|
1674
2052
|
console.warn(`Failed to restore texture for ${r.name}:`, n), r.textureEnabled = !1;
|
|
1675
2053
|
}
|
|
1676
|
-
for (const { system:
|
|
1677
|
-
|
|
2054
|
+
for (const { system: s, config: r } of this.particleSystems)
|
|
2055
|
+
s.updateAppearanceUniform(), (r.particleShapeRotationX || r.particleShapeRotationY || r.particleShapeRotationZ) && console.log(`[replaceSystems] ${r.name}: glbRotation XYZ = ${r.particleShapeRotationX}, ${r.particleShapeRotationY}, ${r.particleShapeRotationZ} | glbModelEnabled=${r.glbModelEnabled} | glbMeshData=${!!s.glbMeshData}`);
|
|
1678
2056
|
return this.respawnAllSystems(), !0;
|
|
1679
2057
|
} catch (i) {
|
|
1680
2058
|
return console.error("Error replacing systems:", i), !1;
|
|
@@ -1693,91 +2071,91 @@ class me {
|
|
|
1693
2071
|
return console.error("Invalid scene data provided"), !1;
|
|
1694
2072
|
try {
|
|
1695
2073
|
for (const n of t.systems) {
|
|
1696
|
-
const o = this.systemCounter++,
|
|
2074
|
+
const o = this.systemCounter++, a = {
|
|
1697
2075
|
...n,
|
|
1698
2076
|
id: o,
|
|
1699
|
-
// Apply world-space offset to
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
2077
|
+
// Apply world-space offset to emission translation
|
|
2078
|
+
emissionTranslationX: (n.emissionTranslationX || 0) + e[0],
|
|
2079
|
+
emissionTranslationY: (n.emissionTranslationY || 0) + e[1],
|
|
2080
|
+
emissionTranslationZ: (n.emissionTranslationZ || 0) + e[2]
|
|
1703
2081
|
};
|
|
1704
|
-
n.attractorEnabled && n.attractorPosition && (
|
|
2082
|
+
n.attractorEnabled && n.attractorPosition && (a.attractorPosition = [
|
|
1705
2083
|
n.attractorPosition[0] + e[0],
|
|
1706
2084
|
n.attractorPosition[1] + e[1],
|
|
1707
2085
|
n.attractorPosition[2] + e[2]
|
|
1708
2086
|
]);
|
|
1709
|
-
const l = new
|
|
2087
|
+
const l = new A(this.device, a);
|
|
1710
2088
|
this.particleSystems.push({
|
|
1711
2089
|
system: l,
|
|
1712
|
-
config:
|
|
1713
|
-
}), this.onSystemCreated && typeof this.onSystemCreated == "function" && this.onSystemCreated(o,
|
|
2090
|
+
config: a
|
|
2091
|
+
}), this.onSystemCreated && typeof this.onSystemCreated == "function" && this.onSystemCreated(o, a);
|
|
1714
2092
|
}
|
|
1715
|
-
const
|
|
2093
|
+
const s = this.particleSystems.length - t.systems.length, r = {};
|
|
1716
2094
|
t.systems.forEach((n, o) => {
|
|
1717
|
-
r[n.id] = this.particleSystems[
|
|
2095
|
+
r[n.id] = this.particleSystems[s + o].config.id;
|
|
1718
2096
|
});
|
|
1719
|
-
for (let n =
|
|
2097
|
+
for (let n = s; n < this.particleSystems.length; n++) {
|
|
1720
2098
|
const { config: o } = this.particleSystems[n];
|
|
1721
2099
|
o.followSystemId && r[o.followSystemId] !== void 0 && (o.followSystemId = r[o.followSystemId]);
|
|
1722
2100
|
}
|
|
1723
2101
|
for (const { system: n, config: o } of this.particleSystems)
|
|
1724
2102
|
if (o.glbModelEnabled && !n.glbMeshData)
|
|
1725
2103
|
try {
|
|
1726
|
-
let
|
|
2104
|
+
let a = null;
|
|
1727
2105
|
if (o.glbModelData)
|
|
1728
|
-
|
|
2106
|
+
a = O(o.glbModelData);
|
|
1729
2107
|
else if (o.glbFileName) {
|
|
1730
2108
|
const l = await fetch(`/${o.glbFileName}`);
|
|
1731
|
-
l.ok ?
|
|
2109
|
+
l.ok ? a = await l.arrayBuffer() : console.warn(`GLB file not found: ${o.glbFileName}`);
|
|
1732
2110
|
}
|
|
1733
|
-
if (
|
|
1734
|
-
if (await n.setGLBModel(
|
|
2111
|
+
if (a) {
|
|
2112
|
+
if (await n.setGLBModel(a), o.animationIndex !== void 0 && n.glbAnimator && n.glbAnimator.setAnimation(o.animationIndex), o.animationSpeed !== void 0 && n.glbAnimator && (n.glbAnimator.speed = o.animationSpeed), o.animationLoop !== void 0 && n.glbAnimator && (n.glbAnimator.loop = o.animationLoop), o.useGlbTexture && (o.textureEnabled = !0), o.useGlbTexture && ((i = n.glbMeshData) != null && i.hasBaseColorTexture))
|
|
1735
2113
|
try {
|
|
1736
|
-
const { extractGLBTexture: l } = await Promise.resolve().then(() =>
|
|
1737
|
-
if (
|
|
1738
|
-
const
|
|
1739
|
-
await n.setTexture(
|
|
2114
|
+
const { extractGLBTexture: l } = await Promise.resolve().then(() => D), d = await l(a);
|
|
2115
|
+
if (d) {
|
|
2116
|
+
const u = await createImageBitmap(d.imageBlob);
|
|
2117
|
+
await n.setTexture(u), console.log(`GLB embedded texture restored for ${o.name}`);
|
|
1740
2118
|
}
|
|
1741
2119
|
} catch (l) {
|
|
1742
2120
|
console.warn(`Failed to restore GLB texture for ${o.name}:`, l), o.useGlbTexture = !1;
|
|
1743
2121
|
}
|
|
1744
2122
|
} else
|
|
1745
2123
|
o.glbModelEnabled = !1;
|
|
1746
|
-
} catch (
|
|
1747
|
-
console.warn(`Failed to load GLB for ${o.name}:`,
|
|
2124
|
+
} catch (a) {
|
|
2125
|
+
console.warn(`Failed to load GLB for ${o.name}:`, a), o.glbModelEnabled = !1;
|
|
1748
2126
|
}
|
|
1749
2127
|
for (const { system: n, config: o } of this.particleSystems)
|
|
1750
2128
|
if (o.textureEnabled && !o.glbModelEnabled && o.textureImageData && !n._textureRestored)
|
|
1751
2129
|
try {
|
|
1752
|
-
const
|
|
1753
|
-
await new Promise((
|
|
1754
|
-
|
|
2130
|
+
const a = new Image();
|
|
2131
|
+
await new Promise((d, u) => {
|
|
2132
|
+
a.onload = d, a.onerror = u, a.src = o.textureImageData;
|
|
1755
2133
|
});
|
|
1756
|
-
const l = await createImageBitmap(
|
|
2134
|
+
const l = await createImageBitmap(a);
|
|
1757
2135
|
await n.setTexture(l), n._textureRestored = !0;
|
|
1758
|
-
} catch (
|
|
1759
|
-
console.warn(`Failed to restore texture for ${o.name}:`,
|
|
2136
|
+
} catch (a) {
|
|
2137
|
+
console.warn(`Failed to restore texture for ${o.name}:`, a), o.textureEnabled = !1;
|
|
1760
2138
|
}
|
|
1761
2139
|
return !0;
|
|
1762
|
-
} catch (
|
|
1763
|
-
return console.error("Error adding systems:",
|
|
2140
|
+
} catch (s) {
|
|
2141
|
+
return console.error("Error adding systems:", s), !1;
|
|
1764
2142
|
}
|
|
1765
2143
|
}
|
|
1766
2144
|
}
|
|
1767
|
-
async function
|
|
2145
|
+
async function Re(c) {
|
|
1768
2146
|
if (!c)
|
|
1769
2147
|
throw new Error("canvas is required for initWebGPU()");
|
|
1770
2148
|
if (!navigator.gpu)
|
|
1771
2149
|
throw new Error("WebGPU not supported on this browser.");
|
|
1772
|
-
const t = c.getContext("webgpu"), i = await (await navigator.gpu.requestAdapter()).requestDevice(),
|
|
2150
|
+
const t = c.getContext("webgpu"), i = await (await navigator.gpu.requestAdapter()).requestDevice(), s = navigator.gpu.getPreferredCanvasFormat();
|
|
1773
2151
|
return t.configure({
|
|
1774
2152
|
device: i,
|
|
1775
|
-
format:
|
|
2153
|
+
format: s,
|
|
1776
2154
|
alphaMode: "premultiplied"
|
|
1777
|
-
}), { device: i, context: t, format:
|
|
2155
|
+
}), { device: i, context: t, format: s, canvas: c };
|
|
1778
2156
|
}
|
|
1779
|
-
function
|
|
1780
|
-
const
|
|
2157
|
+
function we(c, t, e, i) {
|
|
2158
|
+
const s = c.createTexture({
|
|
1781
2159
|
size: [e, i],
|
|
1782
2160
|
format: t,
|
|
1783
2161
|
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
@@ -1796,16 +2174,16 @@ function ge(c, t, e, i) {
|
|
|
1796
2174
|
mipLevelCount: 1,
|
|
1797
2175
|
sampleCount: 1
|
|
1798
2176
|
});
|
|
1799
|
-
return { sceneTexture:
|
|
2177
|
+
return { sceneTexture: s, bloomTexA: r, bloomTexB: n };
|
|
1800
2178
|
}
|
|
1801
|
-
function
|
|
2179
|
+
function Be(c, t, e) {
|
|
1802
2180
|
return c.createTexture({
|
|
1803
2181
|
size: [t, e],
|
|
1804
2182
|
format: "depth24plus",
|
|
1805
2183
|
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
1806
2184
|
});
|
|
1807
2185
|
}
|
|
1808
|
-
function
|
|
2186
|
+
function C(c, t, e) {
|
|
1809
2187
|
const i = c.createBuffer({
|
|
1810
2188
|
size: t.byteLength,
|
|
1811
2189
|
usage: e,
|
|
@@ -1813,7 +2191,7 @@ function E(c, t, e) {
|
|
|
1813
2191
|
});
|
|
1814
2192
|
return new t.constructor(i.getMappedRange()).set(t), i.unmap(), i;
|
|
1815
2193
|
}
|
|
1816
|
-
const
|
|
2194
|
+
const Y = `
|
|
1817
2195
|
struct Uniforms {
|
|
1818
2196
|
transform: mat4x4<f32>,
|
|
1819
2197
|
cameraPosition: vec3<f32>,
|
|
@@ -2143,7 +2521,7 @@ const j = `
|
|
|
2143
2521
|
return vec4<f32>(input.color, alpha);
|
|
2144
2522
|
}
|
|
2145
2523
|
}
|
|
2146
|
-
`,
|
|
2524
|
+
`, q = `
|
|
2147
2525
|
struct BloomUniforms {
|
|
2148
2526
|
direction: vec2<f32>,
|
|
2149
2527
|
resolution: vec2<f32>,
|
|
@@ -2203,7 +2581,7 @@ const j = `
|
|
|
2203
2581
|
|
|
2204
2582
|
return result / totalWeight * 1.1;
|
|
2205
2583
|
}
|
|
2206
|
-
`,
|
|
2584
|
+
`, Z = `
|
|
2207
2585
|
struct BloomIntensityUniforms {
|
|
2208
2586
|
intensity: f32,
|
|
2209
2587
|
color: vec3<f32>,
|
|
@@ -2249,7 +2627,7 @@ const j = `
|
|
|
2249
2627
|
|
|
2250
2628
|
return vec4<f32>(originalColor.rgb + (mappedBloom * bloomUniforms.intensity), originalColor.a);
|
|
2251
2629
|
}
|
|
2252
|
-
`,
|
|
2630
|
+
`, $ = `
|
|
2253
2631
|
struct BloomIntensityUniforms {
|
|
2254
2632
|
intensity: f32,
|
|
2255
2633
|
color: vec3<f32>,
|
|
@@ -2290,7 +2668,7 @@ const j = `
|
|
|
2290
2668
|
fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> {
|
|
2291
2669
|
return textureSample(originalTexture, texSampler, input.texCoord);
|
|
2292
2670
|
}
|
|
2293
|
-
`,
|
|
2671
|
+
`, ye = `
|
|
2294
2672
|
struct PhysicsUniforms {
|
|
2295
2673
|
deltaTime: f32,
|
|
2296
2674
|
particleSpeed: f32,
|
|
@@ -2500,7 +2878,7 @@ const j = `
|
|
|
2500
2878
|
particleBuffer[baseIndex + 1u] = newPos.y;
|
|
2501
2879
|
particleBuffer[baseIndex + 2u] = newPos.z;
|
|
2502
2880
|
}
|
|
2503
|
-
`,
|
|
2881
|
+
`, ge = `
|
|
2504
2882
|
@group(0) @binding(0) var<storage, read> restData: array<f32>;
|
|
2505
2883
|
@group(0) @binding(1) var<storage, read> jointWeightsData: array<f32>;
|
|
2506
2884
|
@group(0) @binding(2) var<storage, read> jointIndicesData: array<u32>;
|
|
@@ -2556,15 +2934,15 @@ const j = `
|
|
|
2556
2934
|
outputData[outBase + 6u] = uv_u;
|
|
2557
2935
|
outputData[outBase + 7u] = uv_v;
|
|
2558
2936
|
}
|
|
2559
|
-
`,
|
|
2937
|
+
`, H = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2560
2938
|
__proto__: null,
|
|
2561
|
-
blurShader:
|
|
2562
|
-
compositeShader:
|
|
2563
|
-
directRenderShader:
|
|
2564
|
-
particlePhysicsShader:
|
|
2565
|
-
particleShader:
|
|
2566
|
-
skinningComputeShader:
|
|
2567
|
-
}, Symbol.toStringTag, { value: "Module" })),
|
|
2939
|
+
blurShader: q,
|
|
2940
|
+
compositeShader: Z,
|
|
2941
|
+
directRenderShader: $,
|
|
2942
|
+
particlePhysicsShader: ye,
|
|
2943
|
+
particleShader: Y,
|
|
2944
|
+
skinningComputeShader: ge
|
|
2945
|
+
}, Symbol.toStringTag, { value: "Module" })), be = `
|
|
2568
2946
|
struct Uniforms {
|
|
2569
2947
|
transform: mat4x4<f32>,
|
|
2570
2948
|
cameraPosition: vec3<f32>,
|
|
@@ -2626,7 +3004,7 @@ const j = `
|
|
|
2626
3004
|
|
|
2627
3005
|
return finalColor;
|
|
2628
3006
|
}
|
|
2629
|
-
`,
|
|
3007
|
+
`, Se = `
|
|
2630
3008
|
struct Uniforms {
|
|
2631
3009
|
transform: mat4x4<f32>,
|
|
2632
3010
|
cameraPosition: vec3<f32>,
|
|
@@ -2711,9 +3089,14 @@ const j = `
|
|
|
2711
3089
|
|
|
2712
3090
|
// Determine particle color
|
|
2713
3091
|
var finalColor = input.particleColor;
|
|
2714
|
-
if (appearance.colorTransitionEnabled >
|
|
3092
|
+
if (appearance.colorTransitionEnabled > 1.5) {
|
|
3093
|
+
// Random color mode: use per-particle color from instance data
|
|
3094
|
+
finalColor = input.particleColor;
|
|
3095
|
+
} else if (appearance.colorTransitionEnabled > 0.5) {
|
|
3096
|
+
// Color transition mode: interpolate from start to end color over lifetime
|
|
2715
3097
|
finalColor = mix(appearance.startColor, appearance.endColor, lifeRatio);
|
|
2716
3098
|
} else {
|
|
3099
|
+
// Single color mode
|
|
2717
3100
|
finalColor = appearance.singleColor;
|
|
2718
3101
|
}
|
|
2719
3102
|
|
|
@@ -2857,7 +3240,7 @@ const j = `
|
|
|
2857
3240
|
return finalColor;
|
|
2858
3241
|
}
|
|
2859
3242
|
`;
|
|
2860
|
-
function
|
|
3243
|
+
function Te(c) {
|
|
2861
3244
|
const t = c.createBindGroupLayout({
|
|
2862
3245
|
entries: [
|
|
2863
3246
|
{
|
|
@@ -2922,7 +3305,7 @@ function Se(c) {
|
|
|
2922
3305
|
buffer: { type: "uniform" }
|
|
2923
3306
|
}
|
|
2924
3307
|
]
|
|
2925
|
-
}),
|
|
3308
|
+
}), s = c.createBindGroupLayout({
|
|
2926
3309
|
entries: [
|
|
2927
3310
|
{
|
|
2928
3311
|
binding: 0,
|
|
@@ -2940,35 +3323,35 @@ function Se(c) {
|
|
|
2940
3323
|
particleBindGroupLayout: t,
|
|
2941
3324
|
bloomBindGroupLayout: e,
|
|
2942
3325
|
compositeBindGroupLayout: i,
|
|
2943
|
-
object3dBindGroupLayout:
|
|
3326
|
+
object3dBindGroupLayout: s
|
|
2944
3327
|
};
|
|
2945
3328
|
}
|
|
2946
|
-
function
|
|
2947
|
-
const { depthCompare:
|
|
3329
|
+
function Ce(c, t, e, i = {}) {
|
|
3330
|
+
const { depthCompare: s } = i, r = s || "less", {
|
|
2948
3331
|
particleBindGroupLayout: n,
|
|
2949
3332
|
bloomBindGroupLayout: o,
|
|
2950
|
-
compositeBindGroupLayout:
|
|
3333
|
+
compositeBindGroupLayout: a,
|
|
2951
3334
|
object3dBindGroupLayout: l
|
|
2952
|
-
} = e,
|
|
3335
|
+
} = e, d = c.createPipelineLayout({
|
|
2953
3336
|
bindGroupLayouts: [n]
|
|
2954
|
-
}),
|
|
3337
|
+
}), u = c.createPipelineLayout({
|
|
2955
3338
|
bindGroupLayouts: [o]
|
|
2956
3339
|
}), f = c.createPipelineLayout({
|
|
2957
|
-
bindGroupLayouts: [
|
|
3340
|
+
bindGroupLayouts: [a]
|
|
2958
3341
|
}), h = c.createShaderModule({
|
|
2959
|
-
code:
|
|
3342
|
+
code: Y
|
|
2960
3343
|
}), p = c.createShaderModule({
|
|
2961
|
-
code:
|
|
3344
|
+
code: q
|
|
2962
3345
|
}), m = c.createShaderModule({
|
|
2963
|
-
code:
|
|
3346
|
+
code: Z
|
|
2964
3347
|
}), b = c.createShaderModule({
|
|
2965
|
-
code:
|
|
3348
|
+
code: $
|
|
2966
3349
|
}), S = c.createShaderModule({
|
|
2967
|
-
code:
|
|
3350
|
+
code: be
|
|
2968
3351
|
}), y = c.createShaderModule({
|
|
2969
|
-
code:
|
|
2970
|
-
}),
|
|
2971
|
-
layout:
|
|
3352
|
+
code: Se
|
|
3353
|
+
}), _ = c.createRenderPipeline({
|
|
3354
|
+
layout: d,
|
|
2972
3355
|
vertex: {
|
|
2973
3356
|
module: h,
|
|
2974
3357
|
entryPoint: "vs_main",
|
|
@@ -3059,7 +3442,7 @@ function xe(c, t, e, i = {}) {
|
|
|
3059
3442
|
format: "depth24plus"
|
|
3060
3443
|
}
|
|
3061
3444
|
}), g = c.createRenderPipeline({
|
|
3062
|
-
layout:
|
|
3445
|
+
layout: d,
|
|
3063
3446
|
vertex: {
|
|
3064
3447
|
module: h,
|
|
3065
3448
|
entryPoint: "vs_main",
|
|
@@ -3141,7 +3524,7 @@ function xe(c, t, e, i = {}) {
|
|
|
3141
3524
|
format: "depth24plus"
|
|
3142
3525
|
}
|
|
3143
3526
|
}), x = c.createRenderPipeline({
|
|
3144
|
-
layout:
|
|
3527
|
+
layout: u,
|
|
3145
3528
|
vertex: {
|
|
3146
3529
|
module: p,
|
|
3147
3530
|
entryPoint: "vs_main"
|
|
@@ -3156,7 +3539,7 @@ function xe(c, t, e, i = {}) {
|
|
|
3156
3539
|
primitive: {
|
|
3157
3540
|
topology: "triangle-list"
|
|
3158
3541
|
}
|
|
3159
|
-
}),
|
|
3542
|
+
}), P = c.createRenderPipeline({
|
|
3160
3543
|
layout: f,
|
|
3161
3544
|
vertex: {
|
|
3162
3545
|
module: m,
|
|
@@ -3184,7 +3567,7 @@ function xe(c, t, e, i = {}) {
|
|
|
3184
3567
|
primitive: {
|
|
3185
3568
|
topology: "triangle-list"
|
|
3186
3569
|
}
|
|
3187
|
-
}),
|
|
3570
|
+
}), M = c.createRenderPipeline({
|
|
3188
3571
|
layout: f,
|
|
3189
3572
|
vertex: {
|
|
3190
3573
|
module: b,
|
|
@@ -3212,10 +3595,10 @@ function xe(c, t, e, i = {}) {
|
|
|
3212
3595
|
primitive: {
|
|
3213
3596
|
topology: "triangle-list"
|
|
3214
3597
|
}
|
|
3215
|
-
}),
|
|
3598
|
+
}), w = c.createPipelineLayout({
|
|
3216
3599
|
bindGroupLayouts: [l]
|
|
3217
|
-
}),
|
|
3218
|
-
layout:
|
|
3600
|
+
}), B = c.createRenderPipeline({
|
|
3601
|
+
layout: w,
|
|
3219
3602
|
vertex: {
|
|
3220
3603
|
module: S,
|
|
3221
3604
|
entryPoint: "vs_main",
|
|
@@ -3269,8 +3652,8 @@ function xe(c, t, e, i = {}) {
|
|
|
3269
3652
|
depthCompare: r,
|
|
3270
3653
|
format: "depth24plus"
|
|
3271
3654
|
}
|
|
3272
|
-
}),
|
|
3273
|
-
layout:
|
|
3655
|
+
}), R = c.createRenderPipeline({
|
|
3656
|
+
layout: d,
|
|
3274
3657
|
vertex: {
|
|
3275
3658
|
module: y,
|
|
3276
3659
|
entryPoint: "vs_main",
|
|
@@ -3373,26 +3756,26 @@ function xe(c, t, e, i = {}) {
|
|
|
3373
3756
|
}
|
|
3374
3757
|
});
|
|
3375
3758
|
return {
|
|
3376
|
-
particlePipeline:
|
|
3759
|
+
particlePipeline: _,
|
|
3377
3760
|
particleDepthWritePipeline: g,
|
|
3378
3761
|
blurPipeline: x,
|
|
3379
|
-
compositePipeline:
|
|
3380
|
-
directRenderPipeline:
|
|
3381
|
-
object3dPipeline:
|
|
3382
|
-
glbMeshPipeline:
|
|
3762
|
+
compositePipeline: P,
|
|
3763
|
+
directRenderPipeline: M,
|
|
3764
|
+
object3dPipeline: B,
|
|
3765
|
+
glbMeshPipeline: R
|
|
3383
3766
|
};
|
|
3384
3767
|
}
|
|
3385
|
-
function
|
|
3768
|
+
function Ee(c, t, e, i) {
|
|
3386
3769
|
const {
|
|
3387
|
-
uniformBuffer:
|
|
3770
|
+
uniformBuffer: s,
|
|
3388
3771
|
appearanceUniformBuffer: r,
|
|
3389
3772
|
horizontalBlurUniformBuffer: n,
|
|
3390
3773
|
verticalBlurUniformBuffer: o,
|
|
3391
|
-
bloomIntensityBuffer:
|
|
3774
|
+
bloomIntensityBuffer: a
|
|
3392
3775
|
} = e, {
|
|
3393
3776
|
sceneTexture: l,
|
|
3394
|
-
bloomTexA:
|
|
3395
|
-
bloomTexB:
|
|
3777
|
+
bloomTexA: d,
|
|
3778
|
+
bloomTexB: u
|
|
3396
3779
|
} = i, f = c.createBindGroup({
|
|
3397
3780
|
layout: c.createBindGroupLayout({
|
|
3398
3781
|
entries: [
|
|
@@ -3411,7 +3794,7 @@ function ve(c, t, e, i) {
|
|
|
3411
3794
|
entries: [
|
|
3412
3795
|
{
|
|
3413
3796
|
binding: 0,
|
|
3414
|
-
resource: { buffer:
|
|
3797
|
+
resource: { buffer: s }
|
|
3415
3798
|
},
|
|
3416
3799
|
{
|
|
3417
3800
|
binding: 1,
|
|
@@ -3479,7 +3862,7 @@ function ve(c, t, e, i) {
|
|
|
3479
3862
|
},
|
|
3480
3863
|
{
|
|
3481
3864
|
binding: 1,
|
|
3482
|
-
resource:
|
|
3865
|
+
resource: d.createView()
|
|
3483
3866
|
},
|
|
3484
3867
|
{
|
|
3485
3868
|
binding: 2,
|
|
@@ -3522,11 +3905,11 @@ function ve(c, t, e, i) {
|
|
|
3522
3905
|
},
|
|
3523
3906
|
{
|
|
3524
3907
|
binding: 2,
|
|
3525
|
-
resource:
|
|
3908
|
+
resource: u.createView()
|
|
3526
3909
|
},
|
|
3527
3910
|
{
|
|
3528
3911
|
binding: 3,
|
|
3529
|
-
resource: { buffer:
|
|
3912
|
+
resource: { buffer: a }
|
|
3530
3913
|
}
|
|
3531
3914
|
]
|
|
3532
3915
|
}), b = c.createBindGroup({
|
|
@@ -3565,11 +3948,11 @@ function ve(c, t, e, i) {
|
|
|
3565
3948
|
},
|
|
3566
3949
|
{
|
|
3567
3950
|
binding: 2,
|
|
3568
|
-
resource:
|
|
3951
|
+
resource: u.createView()
|
|
3569
3952
|
},
|
|
3570
3953
|
{
|
|
3571
3954
|
binding: 3,
|
|
3572
|
-
resource: { buffer:
|
|
3955
|
+
resource: { buffer: a }
|
|
3573
3956
|
}
|
|
3574
3957
|
]
|
|
3575
3958
|
});
|
|
@@ -3581,7 +3964,7 @@ function ve(c, t, e, i) {
|
|
|
3581
3964
|
directRenderBindGroup: b
|
|
3582
3965
|
};
|
|
3583
3966
|
}
|
|
3584
|
-
function
|
|
3967
|
+
function Ae(c) {
|
|
3585
3968
|
return c.createSampler({
|
|
3586
3969
|
magFilter: "linear",
|
|
3587
3970
|
minFilter: "linear",
|
|
@@ -3591,7 +3974,7 @@ function Pe(c) {
|
|
|
3591
3974
|
maxAnisotropy: 16
|
|
3592
3975
|
});
|
|
3593
3976
|
}
|
|
3594
|
-
function
|
|
3977
|
+
function xe() {
|
|
3595
3978
|
const c = new Float32Array([
|
|
3596
3979
|
// Front face (z = 0.5)
|
|
3597
3980
|
-0.5,
|
|
@@ -3789,18 +4172,18 @@ function de() {
|
|
|
3789
4172
|
]);
|
|
3790
4173
|
return { vertices: c, indices: t };
|
|
3791
4174
|
}
|
|
3792
|
-
function
|
|
4175
|
+
function ve(c = 16, t = 16) {
|
|
3793
4176
|
const e = [], i = [];
|
|
3794
|
-
for (let
|
|
3795
|
-
const r =
|
|
3796
|
-
for (let
|
|
3797
|
-
const l =
|
|
4177
|
+
for (let s = 0; s <= c; s++) {
|
|
4178
|
+
const r = s * Math.PI / c, n = Math.sin(r), o = Math.cos(r);
|
|
4179
|
+
for (let a = 0; a <= t; a++) {
|
|
4180
|
+
const l = a * 2 * Math.PI / t, d = Math.sin(l), f = Math.cos(l) * n, h = o, p = d * n;
|
|
3798
4181
|
e.push(f * 0.5, h * 0.5, p * 0.5), e.push(f, h, p);
|
|
3799
4182
|
}
|
|
3800
4183
|
}
|
|
3801
|
-
for (let
|
|
4184
|
+
for (let s = 0; s < c; s++)
|
|
3802
4185
|
for (let r = 0; r < t; r++) {
|
|
3803
|
-
const n =
|
|
4186
|
+
const n = s * (t + 1) + r, o = n + t + 1;
|
|
3804
4187
|
i.push(n), i.push(o), i.push(n + 1), i.push(o), i.push(o + 1), i.push(n + 1);
|
|
3805
4188
|
}
|
|
3806
4189
|
return {
|
|
@@ -3808,17 +4191,17 @@ function fe(c = 16, t = 16) {
|
|
|
3808
4191
|
indices: new Uint16Array(i)
|
|
3809
4192
|
};
|
|
3810
4193
|
}
|
|
3811
|
-
class
|
|
3812
|
-
constructor(t, e, i,
|
|
3813
|
-
this.id = t, this.type = e, this.position = i, this.scale =
|
|
4194
|
+
class _e {
|
|
4195
|
+
constructor(t, e, i, s, r) {
|
|
4196
|
+
this.id = t, this.type = e, this.position = i, this.scale = s, this.color = r, this.rotation = [0, 0, 0];
|
|
3814
4197
|
}
|
|
3815
4198
|
/**
|
|
3816
4199
|
* Get the model matrix for this object
|
|
3817
4200
|
*/
|
|
3818
4201
|
getModelMatrix() {
|
|
3819
|
-
const { position: t, scale: e, rotation: i } = this,
|
|
3820
|
-
let l =
|
|
3821
|
-
return l = this.multiplyMatrices(l, o), l = this.multiplyMatrices(l, n), l = this.multiplyMatrices(l, r), l = this.multiplyMatrices(l,
|
|
4202
|
+
const { position: t, scale: e, rotation: i } = this, s = this.createTranslationMatrix(t), r = this.createRotationMatrixX(i[0]), n = this.createRotationMatrixY(i[1]), o = this.createRotationMatrixZ(i[2]), a = this.createScaleMatrix(e);
|
|
4203
|
+
let l = s;
|
|
4204
|
+
return l = this.multiplyMatrices(l, o), l = this.multiplyMatrices(l, n), l = this.multiplyMatrices(l, r), l = this.multiplyMatrices(l, a), l;
|
|
3822
4205
|
}
|
|
3823
4206
|
/**
|
|
3824
4207
|
* Get the normal matrix (inverse transpose of model matrix)
|
|
@@ -3932,17 +4315,17 @@ class he {
|
|
|
3932
4315
|
}
|
|
3933
4316
|
multiplyMatrices(t, e) {
|
|
3934
4317
|
const i = new Float32Array(16);
|
|
3935
|
-
for (let
|
|
4318
|
+
for (let s = 0; s < 4; s++)
|
|
3936
4319
|
for (let r = 0; r < 4; r++) {
|
|
3937
4320
|
let n = 0;
|
|
3938
4321
|
for (let o = 0; o < 4; o++)
|
|
3939
|
-
n += t[
|
|
3940
|
-
i[
|
|
4322
|
+
n += t[s * 4 + o] * e[o * 4 + r];
|
|
4323
|
+
i[s * 4 + r] = n;
|
|
3941
4324
|
}
|
|
3942
4325
|
return i;
|
|
3943
4326
|
}
|
|
3944
4327
|
}
|
|
3945
|
-
class
|
|
4328
|
+
class Ie {
|
|
3946
4329
|
constructor(t) {
|
|
3947
4330
|
this.device = t, this.objects = [], this.nextId = 0, this.initializeGeometry(), this.onObjectAdded = null, this.onObjectRemoved = null, this.onObjectUpdated = null;
|
|
3948
4331
|
}
|
|
@@ -3950,20 +4333,20 @@ class Me {
|
|
|
3950
4333
|
* Initialize geometry buffers for cube and sphere
|
|
3951
4334
|
*/
|
|
3952
4335
|
initializeGeometry() {
|
|
3953
|
-
const t =
|
|
3954
|
-
this.cubeVertexBuffer =
|
|
4336
|
+
const t = xe(), e = ve(16, 16);
|
|
4337
|
+
this.cubeVertexBuffer = C(
|
|
3955
4338
|
this.device,
|
|
3956
4339
|
t.vertices,
|
|
3957
4340
|
GPUBufferUsage.VERTEX
|
|
3958
|
-
), this.cubeIndexBuffer =
|
|
4341
|
+
), this.cubeIndexBuffer = C(
|
|
3959
4342
|
this.device,
|
|
3960
4343
|
t.indices,
|
|
3961
4344
|
GPUBufferUsage.INDEX
|
|
3962
|
-
), this.cubeIndexCount = t.indices.length, this.sphereVertexBuffer =
|
|
4345
|
+
), this.cubeIndexCount = t.indices.length, this.sphereVertexBuffer = C(
|
|
3963
4346
|
this.device,
|
|
3964
4347
|
e.vertices,
|
|
3965
4348
|
GPUBufferUsage.VERTEX
|
|
3966
|
-
), this.sphereIndexBuffer =
|
|
4349
|
+
), this.sphereIndexBuffer = C(
|
|
3967
4350
|
this.device,
|
|
3968
4351
|
e.indices,
|
|
3969
4352
|
GPUBufferUsage.INDEX
|
|
@@ -3977,8 +4360,8 @@ class Me {
|
|
|
3977
4360
|
* @param {Array} color - [r, g, b, a] (optional, defaults to white)
|
|
3978
4361
|
* @returns {Object3D} The created object
|
|
3979
4362
|
*/
|
|
3980
|
-
addObject(t, e = [0, 0, 0], i = [1, 1, 1],
|
|
3981
|
-
const r = new
|
|
4363
|
+
addObject(t, e = [0, 0, 0], i = [1, 1, 1], s = [1, 1, 1, 1]) {
|
|
4364
|
+
const r = new _e(this.nextId++, t, e, i, s);
|
|
3982
4365
|
return r.uniformBuffer = this.device.createBuffer({
|
|
3983
4366
|
size: 192,
|
|
3984
4367
|
// modelMatrix (64) + normalMatrix (64) + color (16) + padding (48)
|
|
@@ -3999,7 +4382,7 @@ class Me {
|
|
|
3999
4382
|
* @param {Array} position - [x, y, z]
|
|
4000
4383
|
*/
|
|
4001
4384
|
updateObjectPosition(t, e) {
|
|
4002
|
-
const i = this.objects.find((
|
|
4385
|
+
const i = this.objects.find((s) => s.id === t);
|
|
4003
4386
|
i && (i.position = e, this.onObjectUpdated && this.onObjectUpdated(i));
|
|
4004
4387
|
}
|
|
4005
4388
|
/**
|
|
@@ -4008,7 +4391,7 @@ class Me {
|
|
|
4008
4391
|
* @param {Array} scale - [sx, sy, sz]
|
|
4009
4392
|
*/
|
|
4010
4393
|
updateObjectScale(t, e) {
|
|
4011
|
-
const i = this.objects.find((
|
|
4394
|
+
const i = this.objects.find((s) => s.id === t);
|
|
4012
4395
|
i && (i.scale = e, this.onObjectUpdated && this.onObjectUpdated(i));
|
|
4013
4396
|
}
|
|
4014
4397
|
/**
|
|
@@ -4017,7 +4400,7 @@ class Me {
|
|
|
4017
4400
|
* @param {Array} color - [r, g, b, a]
|
|
4018
4401
|
*/
|
|
4019
4402
|
updateObjectColor(t, e) {
|
|
4020
|
-
const i = this.objects.find((
|
|
4403
|
+
const i = this.objects.find((s) => s.id === t);
|
|
4021
4404
|
i && (i.color = e, this.onObjectUpdated && this.onObjectUpdated(i));
|
|
4022
4405
|
}
|
|
4023
4406
|
/**
|
|
@@ -4038,78 +4421,78 @@ class Me {
|
|
|
4038
4421
|
* @param {Object3D} object
|
|
4039
4422
|
*/
|
|
4040
4423
|
updateObjectUniforms(t) {
|
|
4041
|
-
const e = t.getModelMatrix(), i = t.getNormalMatrix(),
|
|
4042
|
-
this.device.queue.writeBuffer(t.uniformBuffer, 0, e), this.device.queue.writeBuffer(t.uniformBuffer, 64, i), this.device.queue.writeBuffer(t.uniformBuffer, 128,
|
|
4424
|
+
const e = t.getModelMatrix(), i = t.getNormalMatrix(), s = new Float32Array(t.color);
|
|
4425
|
+
this.device.queue.writeBuffer(t.uniformBuffer, 0, e), this.device.queue.writeBuffer(t.uniformBuffer, 64, i), this.device.queue.writeBuffer(t.uniformBuffer, 128, s);
|
|
4043
4426
|
}
|
|
4044
4427
|
/**
|
|
4045
4428
|
* Render all objects
|
|
4046
4429
|
* @param {GPURenderPassEncoder} passEncoder
|
|
4047
4430
|
* @param {GPUBindGroup} cameraBindGroup - Bind group with camera uniforms
|
|
4048
4431
|
*/
|
|
4049
|
-
renderObjects(t, e, i,
|
|
4432
|
+
renderObjects(t, e, i, s) {
|
|
4050
4433
|
for (const r of this.objects) {
|
|
4051
4434
|
this.updateObjectUniforms(r);
|
|
4052
4435
|
const n = this.device.createBindGroup({
|
|
4053
4436
|
layout: i,
|
|
4054
4437
|
entries: [
|
|
4055
|
-
{ binding: 0, resource: { buffer:
|
|
4438
|
+
{ binding: 0, resource: { buffer: s } },
|
|
4056
4439
|
{ binding: 1, resource: { buffer: r.uniformBuffer } }
|
|
4057
4440
|
]
|
|
4058
4441
|
});
|
|
4059
|
-
let o,
|
|
4442
|
+
let o, a, l;
|
|
4060
4443
|
if (r.type === "cube")
|
|
4061
|
-
o = this.cubeVertexBuffer,
|
|
4444
|
+
o = this.cubeVertexBuffer, a = this.cubeIndexBuffer, l = this.cubeIndexCount;
|
|
4062
4445
|
else if (r.type === "sphere")
|
|
4063
|
-
o = this.sphereVertexBuffer,
|
|
4446
|
+
o = this.sphereVertexBuffer, a = this.sphereIndexBuffer, l = this.sphereIndexCount;
|
|
4064
4447
|
else
|
|
4065
4448
|
continue;
|
|
4066
|
-
t.setPipeline(e), t.setBindGroup(0, n), t.setVertexBuffer(0, o), t.setIndexBuffer(
|
|
4449
|
+
t.setPipeline(e), t.setBindGroup(0, n), t.setVertexBuffer(0, o), t.setIndexBuffer(a, "uint16"), t.drawIndexed(l);
|
|
4067
4450
|
}
|
|
4068
4451
|
}
|
|
4069
4452
|
}
|
|
4070
|
-
function
|
|
4453
|
+
function Ue(c) {
|
|
4071
4454
|
const t = parseInt(c.slice(1, 3), 16) / 255, e = parseInt(c.slice(3, 5), 16) / 255, i = parseInt(c.slice(5, 7), 16) / 255;
|
|
4072
4455
|
return [t, e, i];
|
|
4073
4456
|
}
|
|
4074
|
-
function
|
|
4457
|
+
function ze(c) {
|
|
4075
4458
|
if (!c) return "#ffffff";
|
|
4076
4459
|
const t = Math.round(c[0] * 255).toString(16).padStart(2, "0"), e = Math.round(c[1] * 255).toString(16).padStart(2, "0"), i = Math.round(c[2] * 255).toString(16).padStart(2, "0");
|
|
4077
4460
|
return `#${t}${e}${i}`;
|
|
4078
4461
|
}
|
|
4079
|
-
function
|
|
4080
|
-
const i =
|
|
4462
|
+
function Fe(c, t, e) {
|
|
4463
|
+
const i = k([
|
|
4081
4464
|
c[0] - t[0],
|
|
4082
4465
|
c[1] - t[1],
|
|
4083
4466
|
c[2] - t[2]
|
|
4084
|
-
]),
|
|
4467
|
+
]), s = k(j(e, i)), r = j(i, s);
|
|
4085
4468
|
return new Float32Array([
|
|
4086
|
-
|
|
4469
|
+
s[0],
|
|
4087
4470
|
r[0],
|
|
4088
4471
|
i[0],
|
|
4089
4472
|
0,
|
|
4090
|
-
|
|
4473
|
+
s[1],
|
|
4091
4474
|
r[1],
|
|
4092
4475
|
i[1],
|
|
4093
4476
|
0,
|
|
4094
|
-
|
|
4477
|
+
s[2],
|
|
4095
4478
|
r[2],
|
|
4096
4479
|
i[2],
|
|
4097
4480
|
0,
|
|
4098
|
-
-
|
|
4099
|
-
-
|
|
4100
|
-
-
|
|
4481
|
+
-I(s, c),
|
|
4482
|
+
-I(r, c),
|
|
4483
|
+
-I(i, c),
|
|
4101
4484
|
1
|
|
4102
4485
|
]);
|
|
4103
4486
|
}
|
|
4104
|
-
function
|
|
4105
|
-
const
|
|
4487
|
+
function De(c, t = Math.PI / 4) {
|
|
4488
|
+
const s = 1 / Math.tan(t / 2);
|
|
4106
4489
|
return new Float32Array([
|
|
4107
|
-
|
|
4490
|
+
s * c,
|
|
4108
4491
|
0,
|
|
4109
4492
|
0,
|
|
4110
4493
|
0,
|
|
4111
4494
|
0,
|
|
4112
|
-
|
|
4495
|
+
s,
|
|
4113
4496
|
0,
|
|
4114
4497
|
0,
|
|
4115
4498
|
0,
|
|
@@ -4122,39 +4505,39 @@ function Te(c, t = Math.PI / 4) {
|
|
|
4122
4505
|
0
|
|
4123
4506
|
]);
|
|
4124
4507
|
}
|
|
4125
|
-
function
|
|
4508
|
+
function k(c) {
|
|
4126
4509
|
const t = Math.sqrt(c[0] * c[0] + c[1] * c[1] + c[2] * c[2]);
|
|
4127
4510
|
return [c[0] / t, c[1] / t, c[2] / t];
|
|
4128
4511
|
}
|
|
4129
|
-
function
|
|
4512
|
+
function j(c, t) {
|
|
4130
4513
|
return [
|
|
4131
4514
|
c[1] * t[2] - c[2] * t[1],
|
|
4132
4515
|
c[2] * t[0] - c[0] * t[2],
|
|
4133
4516
|
c[0] * t[1] - c[1] * t[0]
|
|
4134
4517
|
];
|
|
4135
4518
|
}
|
|
4136
|
-
function
|
|
4519
|
+
function I(c, t) {
|
|
4137
4520
|
return c[0] * t[0] + c[1] * t[1] + c[2] * t[2];
|
|
4138
4521
|
}
|
|
4139
|
-
function
|
|
4522
|
+
function Ge(c, t) {
|
|
4140
4523
|
const e = new Float32Array(16);
|
|
4141
4524
|
for (let i = 0; i < 4; i++)
|
|
4142
|
-
for (let
|
|
4525
|
+
for (let s = 0; s < 4; s++) {
|
|
4143
4526
|
let r = 0;
|
|
4144
4527
|
for (let n = 0; n < 4; n++)
|
|
4145
|
-
r += c[i + n * 4] * t[n +
|
|
4146
|
-
e[i +
|
|
4528
|
+
r += c[i + n * 4] * t[n + s * 4];
|
|
4529
|
+
e[i + s * 4] = r;
|
|
4147
4530
|
}
|
|
4148
4531
|
return e;
|
|
4149
4532
|
}
|
|
4150
|
-
function
|
|
4533
|
+
function Pe(c) {
|
|
4151
4534
|
const t = new Uint8Array(c);
|
|
4152
4535
|
let e = "";
|
|
4153
4536
|
for (let i = 0; i < t.byteLength; i++)
|
|
4154
4537
|
e += String.fromCharCode(t[i]);
|
|
4155
4538
|
return btoa(e);
|
|
4156
4539
|
}
|
|
4157
|
-
function
|
|
4540
|
+
function Ve(c, t) {
|
|
4158
4541
|
if (!c || !c.particleSystems || c.particleSystems.length === 0) {
|
|
4159
4542
|
alert("No particle systems to save.");
|
|
4160
4543
|
return;
|
|
@@ -4163,134 +4546,142 @@ function Ce(c, t) {
|
|
|
4163
4546
|
const e = {
|
|
4164
4547
|
version: "1.0",
|
|
4165
4548
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4166
|
-
systems: c.particleSystems.map(({ config:
|
|
4549
|
+
systems: c.particleSystems.map(({ config: a, system: l }) => ({
|
|
4167
4550
|
// Include only the serializable properties of each system
|
|
4168
|
-
name:
|
|
4169
|
-
id:
|
|
4170
|
-
particleCount:
|
|
4171
|
-
lifetime:
|
|
4172
|
-
emissionRate:
|
|
4173
|
-
emissionDuration:
|
|
4174
|
-
particleSize:
|
|
4175
|
-
particleSpeed:
|
|
4176
|
-
emissionShape:
|
|
4177
|
-
cubeLength:
|
|
4551
|
+
name: a.name,
|
|
4552
|
+
id: a.id,
|
|
4553
|
+
particleCount: a.particleCount,
|
|
4554
|
+
lifetime: a.lifetime,
|
|
4555
|
+
emissionRate: a.emissionRate,
|
|
4556
|
+
emissionDuration: a.emissionDuration,
|
|
4557
|
+
particleSize: a.particleSize,
|
|
4558
|
+
particleSpeed: a.particleSpeed,
|
|
4559
|
+
emissionShape: a.emissionShape,
|
|
4560
|
+
cubeLength: a.outerLength || a.cubeLength,
|
|
4178
4561
|
// Always use outerLength if available
|
|
4179
|
-
outerLength:
|
|
4562
|
+
outerLength: a.outerLength || a.cubeLength,
|
|
4180
4563
|
// Keep them synchronized
|
|
4181
|
-
innerLength:
|
|
4182
|
-
outerRadius:
|
|
4183
|
-
innerRadius:
|
|
4184
|
-
squareSize:
|
|
4185
|
-
squareInnerSize:
|
|
4186
|
-
circleInnerRadius:
|
|
4187
|
-
circleOuterRadius:
|
|
4188
|
-
fadeEnabled:
|
|
4189
|
-
colorTransitionEnabled:
|
|
4190
|
-
particleColor:
|
|
4191
|
-
startColor:
|
|
4192
|
-
endColor:
|
|
4193
|
-
randomColorEnabled:
|
|
4194
|
-
randomColors:
|
|
4195
|
-
particleShape:
|
|
4196
|
-
particleShapeRotation:
|
|
4197
|
-
particleShapeRotationX:
|
|
4198
|
-
particleShapeRotationY:
|
|
4199
|
-
particleShapeRotationZ:
|
|
4200
|
-
pulseEnabled:
|
|
4201
|
-
pulseAmplitude:
|
|
4202
|
-
pulseFrequency:
|
|
4203
|
-
pulsePhaseRandom:
|
|
4204
|
-
pulseOpacity:
|
|
4205
|
-
bloomEnabled:
|
|
4206
|
-
bloomIntensity:
|
|
4207
|
-
burstMode:
|
|
4208
|
-
gravityEnabled:
|
|
4209
|
-
gravityStrength:
|
|
4210
|
-
dampingEnabled:
|
|
4211
|
-
dampingStrength:
|
|
4212
|
-
attractorEnabled:
|
|
4213
|
-
attractorStrength:
|
|
4214
|
-
attractorPosition:
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
rotation:
|
|
4222
|
-
rotationMode:
|
|
4223
|
-
minRotation:
|
|
4224
|
-
maxRotation:
|
|
4225
|
-
overrideXVelocity:
|
|
4226
|
-
overrideYVelocity:
|
|
4227
|
-
overrideZVelocity:
|
|
4228
|
-
xVelocity:
|
|
4229
|
-
yVelocity:
|
|
4230
|
-
zVelocity:
|
|
4231
|
-
circleVelocityDirection:
|
|
4232
|
-
cylinderVelocityDirection:
|
|
4233
|
-
cylinderInnerRadius:
|
|
4234
|
-
cylinderOuterRadius:
|
|
4235
|
-
cylinderHeight:
|
|
4236
|
-
aspectRatio:
|
|
4237
|
-
randomSize:
|
|
4238
|
-
minSize:
|
|
4239
|
-
maxSize:
|
|
4240
|
-
fadeSizeEnabled:
|
|
4241
|
-
increaseSizeEnabled:
|
|
4242
|
-
sizeLifetimeSpeed:
|
|
4243
|
-
opacity:
|
|
4244
|
-
randomSpeed:
|
|
4245
|
-
minSpeed:
|
|
4246
|
-
maxSpeed:
|
|
4247
|
-
textureEnabled:
|
|
4248
|
-
textureType:
|
|
4249
|
-
glbModelEnabled:
|
|
4250
|
-
glbFileName:
|
|
4251
|
-
glbAnimated:
|
|
4252
|
-
animationIndex:
|
|
4253
|
-
animationSpeed:
|
|
4254
|
-
animationLoop:
|
|
4255
|
-
useGlbTexture:
|
|
4256
|
-
oneOnlyMode:
|
|
4257
|
-
confinementEnabled:
|
|
4258
|
-
confinementShape:
|
|
4259
|
-
confinementMode:
|
|
4260
|
-
confinementSpace:
|
|
4261
|
-
confinementBoxHalfSize:
|
|
4262
|
-
confinementSphereRadius:
|
|
4263
|
-
confinementRestitution:
|
|
4264
|
-
confinementFriction:
|
|
4265
|
-
softBoundaryEnabled:
|
|
4266
|
-
softBoundaryStrength:
|
|
4267
|
-
softBoundaryFalloff:
|
|
4268
|
-
followSystemId:
|
|
4269
|
-
hidden:
|
|
4270
|
-
emissionTrailEnabled:
|
|
4271
|
-
emissionTrailDuration:
|
|
4272
|
-
emissionTrailWidth:
|
|
4273
|
-
emissionTrailMinDistance:
|
|
4274
|
-
emissionTrailMaxPoints:
|
|
4275
|
-
|
|
4276
|
-
|
|
4564
|
+
innerLength: a.innerLength,
|
|
4565
|
+
outerRadius: a.outerRadius,
|
|
4566
|
+
innerRadius: a.innerRadius,
|
|
4567
|
+
squareSize: a.squareSize,
|
|
4568
|
+
squareInnerSize: a.squareInnerSize,
|
|
4569
|
+
circleInnerRadius: a.circleInnerRadius,
|
|
4570
|
+
circleOuterRadius: a.circleOuterRadius,
|
|
4571
|
+
fadeEnabled: a.fadeEnabled,
|
|
4572
|
+
colorTransitionEnabled: a.colorTransitionEnabled,
|
|
4573
|
+
particleColor: a.particleColor,
|
|
4574
|
+
startColor: a.startColor,
|
|
4575
|
+
endColor: a.endColor,
|
|
4576
|
+
randomColorEnabled: a.randomColorEnabled || !1,
|
|
4577
|
+
randomColors: a.randomColors || [],
|
|
4578
|
+
particleShape: a.particleShape || "square",
|
|
4579
|
+
particleShapeRotation: a.particleShapeRotation || 0,
|
|
4580
|
+
particleShapeRotationX: a.particleShapeRotationX || 0,
|
|
4581
|
+
particleShapeRotationY: a.particleShapeRotationY || 0,
|
|
4582
|
+
particleShapeRotationZ: a.particleShapeRotationZ || 0,
|
|
4583
|
+
pulseEnabled: a.pulseEnabled || !1,
|
|
4584
|
+
pulseAmplitude: a.pulseAmplitude ?? 0.5,
|
|
4585
|
+
pulseFrequency: a.pulseFrequency ?? 1,
|
|
4586
|
+
pulsePhaseRandom: a.pulsePhaseRandom ?? 0,
|
|
4587
|
+
pulseOpacity: a.pulseOpacity || !1,
|
|
4588
|
+
bloomEnabled: a.bloomEnabled,
|
|
4589
|
+
bloomIntensity: a.bloomIntensity,
|
|
4590
|
+
burstMode: a.burstMode,
|
|
4591
|
+
gravityEnabled: a.gravityEnabled,
|
|
4592
|
+
gravityStrength: a.gravityStrength,
|
|
4593
|
+
dampingEnabled: a.dampingEnabled,
|
|
4594
|
+
dampingStrength: a.dampingStrength,
|
|
4595
|
+
attractorEnabled: a.attractorEnabled,
|
|
4596
|
+
attractorStrength: a.attractorStrength,
|
|
4597
|
+
attractorPosition: a.attractorPosition,
|
|
4598
|
+
emissionRotationX: a.emissionRotationX,
|
|
4599
|
+
emissionRotationY: a.emissionRotationY,
|
|
4600
|
+
emissionRotationZ: a.emissionRotationZ,
|
|
4601
|
+
emissionTranslationX: a.emissionTranslationX,
|
|
4602
|
+
emissionTranslationY: a.emissionTranslationY,
|
|
4603
|
+
emissionTranslationZ: a.emissionTranslationZ,
|
|
4604
|
+
rotation: a.rotation,
|
|
4605
|
+
rotationMode: a.rotationMode,
|
|
4606
|
+
minRotation: a.minRotation,
|
|
4607
|
+
maxRotation: a.maxRotation,
|
|
4608
|
+
overrideXVelocity: a.overrideXVelocity,
|
|
4609
|
+
overrideYVelocity: a.overrideYVelocity,
|
|
4610
|
+
overrideZVelocity: a.overrideZVelocity,
|
|
4611
|
+
xVelocity: a.xVelocity,
|
|
4612
|
+
yVelocity: a.yVelocity,
|
|
4613
|
+
zVelocity: a.zVelocity,
|
|
4614
|
+
circleVelocityDirection: a.circleVelocityDirection,
|
|
4615
|
+
cylinderVelocityDirection: a.cylinderVelocityDirection,
|
|
4616
|
+
cylinderInnerRadius: a.cylinderInnerRadius,
|
|
4617
|
+
cylinderOuterRadius: a.cylinderOuterRadius,
|
|
4618
|
+
cylinderHeight: a.cylinderHeight,
|
|
4619
|
+
aspectRatio: a.aspectRatio,
|
|
4620
|
+
randomSize: a.randomSize,
|
|
4621
|
+
minSize: a.minSize,
|
|
4622
|
+
maxSize: a.maxSize,
|
|
4623
|
+
fadeSizeEnabled: a.fadeSizeEnabled,
|
|
4624
|
+
increaseSizeEnabled: a.increaseSizeEnabled,
|
|
4625
|
+
sizeLifetimeSpeed: a.sizeLifetimeSpeed,
|
|
4626
|
+
opacity: a.opacity,
|
|
4627
|
+
randomSpeed: a.randomSpeed,
|
|
4628
|
+
minSpeed: a.minSpeed,
|
|
4629
|
+
maxSpeed: a.maxSpeed,
|
|
4630
|
+
textureEnabled: a.textureEnabled,
|
|
4631
|
+
textureType: a.textureType,
|
|
4632
|
+
glbModelEnabled: a.glbModelEnabled,
|
|
4633
|
+
glbFileName: a.glbFileName,
|
|
4634
|
+
glbAnimated: a.glbAnimated,
|
|
4635
|
+
animationIndex: a.animationIndex,
|
|
4636
|
+
animationSpeed: a.animationSpeed,
|
|
4637
|
+
animationLoop: a.animationLoop,
|
|
4638
|
+
useGlbTexture: a.useGlbTexture,
|
|
4639
|
+
oneOnlyMode: a.oneOnlyMode,
|
|
4640
|
+
confinementEnabled: a.confinementEnabled || !1,
|
|
4641
|
+
confinementShape: a.confinementShape || "box",
|
|
4642
|
+
confinementMode: a.confinementMode || "bounce",
|
|
4643
|
+
confinementSpace: a.confinementSpace || "world",
|
|
4644
|
+
confinementBoxHalfSize: a.confinementBoxHalfSize || [2, 2, 2],
|
|
4645
|
+
confinementSphereRadius: a.confinementSphereRadius ?? 3,
|
|
4646
|
+
confinementRestitution: a.confinementRestitution ?? 0.8,
|
|
4647
|
+
confinementFriction: a.confinementFriction ?? 0.1,
|
|
4648
|
+
softBoundaryEnabled: a.softBoundaryEnabled || !1,
|
|
4649
|
+
softBoundaryStrength: a.softBoundaryStrength ?? 5,
|
|
4650
|
+
softBoundaryFalloff: a.softBoundaryFalloff ?? 0.5,
|
|
4651
|
+
followSystemId: a.followSystemId || null,
|
|
4652
|
+
hidden: a.hidden || !1,
|
|
4653
|
+
emissionTrailEnabled: a.emissionTrailEnabled || !1,
|
|
4654
|
+
emissionTrailDuration: a.emissionTrailDuration ?? 1,
|
|
4655
|
+
emissionTrailWidth: a.emissionTrailWidth ?? 0.5,
|
|
4656
|
+
emissionTrailMinDistance: a.emissionTrailMinDistance ?? 0.05,
|
|
4657
|
+
emissionTrailMaxPoints: a.emissionTrailMaxPoints ?? 100,
|
|
4658
|
+
emissionTrailSegments: a.emissionTrailSegments ?? 8,
|
|
4659
|
+
emissionTrailShape: a.emissionTrailShape ?? "straight",
|
|
4660
|
+
emissionTrailShapeAmplitude: a.emissionTrailShapeAmplitude ?? 0.1,
|
|
4661
|
+
emissionTrailShapeFrequency: a.emissionTrailShapeFrequency ?? 4,
|
|
4662
|
+
emissionTrailShapeSpeed: a.emissionTrailShapeSpeed ?? 0,
|
|
4663
|
+
shapeDisplay: a.shapeDisplay ?? !0,
|
|
4664
|
+
followSystemTranslation: a.followSystemTranslation ?? !0,
|
|
4665
|
+
script: a.script || void 0,
|
|
4666
|
+
textureImageData: a.textureEnabled && !a.glbModelEnabled && a.textureImageData ? a.textureImageData : void 0,
|
|
4667
|
+
glbModelData: a.glbModelEnabled && l.glbRawArrayBuffer ? Pe(l.glbRawArrayBuffer) : void 0
|
|
4277
4668
|
})),
|
|
4278
4669
|
activeSystemIndex: c.activeSystemIndex
|
|
4279
4670
|
}, i = JSON.stringify(e, null, 2);
|
|
4280
|
-
let
|
|
4671
|
+
let s;
|
|
4281
4672
|
if (t)
|
|
4282
|
-
|
|
4673
|
+
s = `${t}.json`;
|
|
4283
4674
|
else {
|
|
4284
|
-
const
|
|
4285
|
-
|
|
4675
|
+
const a = /* @__PURE__ */ new Date();
|
|
4676
|
+
s = `particle-scene_${`${a.getFullYear()}-${(a.getMonth() + 1).toString().padStart(2, "0")}-${a.getDate().toString().padStart(2, "0")}_${a.getHours().toString().padStart(2, "0")}${a.getMinutes().toString().padStart(2, "0")}`}.json`;
|
|
4286
4677
|
}
|
|
4287
4678
|
const r = new Blob([i], { type: "application/json" }), n = URL.createObjectURL(r), o = document.createElement("a");
|
|
4288
|
-
o.href = n, o.download =
|
|
4679
|
+
o.href = n, o.download = s, document.body.appendChild(o), o.click(), document.body.removeChild(o), URL.revokeObjectURL(n);
|
|
4289
4680
|
} catch (e) {
|
|
4290
4681
|
console.error("Error saving scene:", e), alert("Error saving scene. See console for details.");
|
|
4291
4682
|
}
|
|
4292
4683
|
}
|
|
4293
|
-
function
|
|
4684
|
+
function Le(c) {
|
|
4294
4685
|
return new Promise((t, e) => {
|
|
4295
4686
|
try {
|
|
4296
4687
|
const i = c.target.files[0];
|
|
@@ -4298,8 +4689,8 @@ function _e(c) {
|
|
|
4298
4689
|
e(new Error("No file selected"));
|
|
4299
4690
|
return;
|
|
4300
4691
|
}
|
|
4301
|
-
const
|
|
4302
|
-
|
|
4692
|
+
const s = new FileReader();
|
|
4693
|
+
s.onload = (r) => {
|
|
4303
4694
|
try {
|
|
4304
4695
|
const n = JSON.parse(r.target.result);
|
|
4305
4696
|
if (!n.version)
|
|
@@ -4307,8 +4698,8 @@ function _e(c) {
|
|
|
4307
4698
|
if (!Array.isArray(n.systems) || n.systems.length === 0)
|
|
4308
4699
|
throw new Error("No valid particle systems found in the file");
|
|
4309
4700
|
const o = [];
|
|
4310
|
-
for (const
|
|
4311
|
-
o.push(
|
|
4701
|
+
for (const a of n.systems)
|
|
4702
|
+
o.push(a);
|
|
4312
4703
|
t({
|
|
4313
4704
|
systems: o,
|
|
4314
4705
|
activeSystemIndex: n.activeSystemIndex || 0
|
|
@@ -4317,15 +4708,15 @@ function _e(c) {
|
|
|
4317
4708
|
console.error("Error loading scene:", n), alert("Error loading scene: " + n.message), e(n);
|
|
4318
4709
|
}
|
|
4319
4710
|
c.target.value = "";
|
|
4320
|
-
},
|
|
4711
|
+
}, s.onerror = () => {
|
|
4321
4712
|
alert("Failed to read the file"), e(new Error("Failed to read the file")), c.target.value = "";
|
|
4322
|
-
},
|
|
4713
|
+
}, s.readAsText(i);
|
|
4323
4714
|
} catch (i) {
|
|
4324
4715
|
console.error("Error in loadScene:", i), e(i);
|
|
4325
4716
|
}
|
|
4326
4717
|
});
|
|
4327
4718
|
}
|
|
4328
|
-
async function
|
|
4719
|
+
async function Oe(c) {
|
|
4329
4720
|
if (!c || typeof c != "string")
|
|
4330
4721
|
throw new Error("[fetchPreset] url must be a non-empty string");
|
|
4331
4722
|
const t = await fetch(c);
|
|
@@ -4341,38 +4732,39 @@ async function Ae(c) {
|
|
|
4341
4732
|
};
|
|
4342
4733
|
}
|
|
4343
4734
|
export {
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
Be as
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4735
|
+
me as GLBAnimator,
|
|
4736
|
+
Ie as Objects3DManager,
|
|
4737
|
+
W as ParticleEmitter,
|
|
4738
|
+
J as ParticlePhysics,
|
|
4739
|
+
z as ParticleScript,
|
|
4740
|
+
A as ParticleSystem,
|
|
4741
|
+
Me as ParticleSystemManager,
|
|
4742
|
+
K as ParticleTextureManager,
|
|
4743
|
+
q as blurShader,
|
|
4744
|
+
Z as compositeShader,
|
|
4745
|
+
Te as createBindGroupLayouts,
|
|
4746
|
+
Ee as createBindGroups,
|
|
4747
|
+
C as createBuffer,
|
|
4748
|
+
xe as createCubeGeometry,
|
|
4749
|
+
Be as createDepthTexture,
|
|
4750
|
+
Fe as createLookAtMatrix,
|
|
4751
|
+
De as createProjectionMatrix,
|
|
4752
|
+
Ce as createRenderPipelines,
|
|
4753
|
+
we as createRenderTextures,
|
|
4754
|
+
Ae as createSampler,
|
|
4755
|
+
ve as createSphereGeometry,
|
|
4756
|
+
$ as directRenderShader,
|
|
4757
|
+
ue as extractGLBTexture,
|
|
4758
|
+
Oe as fetchPreset,
|
|
4759
|
+
Se as glbMeshParticleShader,
|
|
4760
|
+
Ue as hexToRgb,
|
|
4761
|
+
Re as initWebGPU,
|
|
4762
|
+
Le as loadScene,
|
|
4763
|
+
Ge as multiplyMatrices,
|
|
4764
|
+
be as object3dShader,
|
|
4765
|
+
X as parseGLB,
|
|
4766
|
+
ye as particlePhysicsShader,
|
|
4767
|
+
Y as particleShader,
|
|
4768
|
+
ze as rgbToHex,
|
|
4769
|
+
Ve as saveScene
|
|
4378
4770
|
};
|