hz-particles 1.0.15 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +84 -60
- package/dist-lib/hz-particles-r3f.cjs +3 -3
- package/dist-lib/hz-particles-r3f.d.ts +22 -17
- package/dist-lib/hz-particles-r3f.mjs +196 -432
- package/dist-lib/hz-particles.cjs +113 -15
- package/dist-lib/hz-particles.d.ts +145 -6
- package/dist-lib/hz-particles.mjs +2009 -1104
- package/package.json +4 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class cs {
|
|
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
|
}
|
|
@@ -10,17 +10,17 @@ class W {
|
|
|
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 s = t * Math.PI / 180,
|
|
13
|
+
const s = t * Math.PI / 180, n = e * Math.PI / 180, o = i * Math.PI / 180, a = Math.cos(s), c = Math.sin(s), l = Math.cos(n), u = Math.sin(n), f = Math.cos(o), h = Math.sin(o);
|
|
14
14
|
this._rotMatrix = [
|
|
15
|
-
l * u,
|
|
16
|
-
a * d * u - o * f,
|
|
17
|
-
o * d * u + a * f,
|
|
18
15
|
l * f,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
a *
|
|
23
|
-
|
|
16
|
+
c * u * f - a * h,
|
|
17
|
+
a * u * f + c * h,
|
|
18
|
+
l * h,
|
|
19
|
+
c * u * h + a * f,
|
|
20
|
+
a * u * h - c * f,
|
|
21
|
+
-u,
|
|
22
|
+
c * l,
|
|
23
|
+
a * l
|
|
24
24
|
], this._invRotMatrix = [
|
|
25
25
|
this._rotMatrix[0],
|
|
26
26
|
this._rotMatrix[3],
|
|
@@ -35,16 +35,16 @@ class W {
|
|
|
35
35
|
}
|
|
36
36
|
emitParticle(t, e, i) {
|
|
37
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) {
|
|
38
|
+
if (this.config.emissionShape === "cube" || this.config.emissionShape === "box" ? 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
|
|
41
|
-
s[0] =
|
|
40
|
+
const a = this._rotMatrix, c = s[0], l = s[1], u = s[2];
|
|
41
|
+
s[0] = a[0] * c + a[1] * l + a[2] * u, s[1] = a[3] * c + a[4] * l + a[5] * u, s[2] = a[6] * c + a[7] * l + a[8] * u;
|
|
42
42
|
}
|
|
43
|
-
(this.config.
|
|
44
|
-
const
|
|
45
|
-
t[
|
|
46
|
-
const
|
|
47
|
-
this.calculateVelocity(s[0], s[1], s[2], i,
|
|
43
|
+
(this.config.emissionPositionX || this.config.emissionPositionY || this.config.emissionPositionZ) && (s[0] += this.config.emissionPositionX || 0, s[1] += this.config.emissionPositionY || 0, s[2] += this.config.emissionPositionZ || 0);
|
|
44
|
+
const n = e * 8;
|
|
45
|
+
t[n] = s[0], t[n + 1] = s[1], t[n + 2] = s[2];
|
|
46
|
+
const o = e * 4;
|
|
47
|
+
this.calculateVelocity(s[0], s[1], s[2], i, o), this.setParticleColor(t, n), this.setParticleLifetime(t, n);
|
|
48
48
|
}
|
|
49
49
|
// Apply rotation using cached matrix
|
|
50
50
|
applyRotation(t, e, i) {
|
|
@@ -69,55 +69,55 @@ class W {
|
|
|
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 s = Math.floor(Math.random() * 6),
|
|
73
|
-
let
|
|
72
|
+
const s = Math.floor(Math.random() * 6), n = Math.random() - 0.5, o = Math.random() - 0.5;
|
|
73
|
+
let a, c, l;
|
|
74
74
|
switch (s) {
|
|
75
75
|
case 0:
|
|
76
|
-
|
|
76
|
+
a = n, c = o, l = 0.5;
|
|
77
77
|
break;
|
|
78
78
|
case 1:
|
|
79
|
-
|
|
79
|
+
a = n, c = o, l = -0.5;
|
|
80
80
|
break;
|
|
81
81
|
case 2:
|
|
82
|
-
|
|
82
|
+
a = 0.5, c = n, l = o;
|
|
83
83
|
break;
|
|
84
84
|
case 3:
|
|
85
|
-
|
|
85
|
+
a = -0.5, c = n, l = o;
|
|
86
86
|
break;
|
|
87
87
|
case 4:
|
|
88
|
-
|
|
88
|
+
a = n, c = 0.5, l = o;
|
|
89
89
|
break;
|
|
90
90
|
case 5:
|
|
91
|
-
|
|
91
|
+
a = n, c = -0.5, l = o;
|
|
92
92
|
break;
|
|
93
93
|
}
|
|
94
|
-
const
|
|
95
|
-
t[0] =
|
|
94
|
+
const u = Math.random(), f = e + u * (i - e);
|
|
95
|
+
t[0] = a * f, t[1] = c * f, t[2] = l * f;
|
|
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), s = Math.sin(i) * Math.cos(e),
|
|
101
|
-
let
|
|
102
|
-
this.config.innerRadius === 0 ?
|
|
100
|
+
const e = Math.random() * 2 * Math.PI, i = Math.acos(2 * Math.random() - 1), s = Math.sin(i) * Math.cos(e), n = Math.sin(i) * Math.sin(e), o = Math.cos(i);
|
|
101
|
+
let a;
|
|
102
|
+
this.config.innerRadius === 0 ? a = this.config.outerRadius * Math.cbrt(Math.random()) : a = this.config.innerRadius + (this.config.outerRadius - this.config.innerRadius) * Math.random(), t[0] = s * a, t[1] = n * a, t[2] = o * a;
|
|
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
107
|
const s = Math.floor(Math.random() * 4);
|
|
108
|
-
let
|
|
108
|
+
let n = e + (i - e) * Math.random();
|
|
109
109
|
switch (s) {
|
|
110
110
|
case 0:
|
|
111
|
-
t[0] = (Math.random() * 2 - 1) *
|
|
111
|
+
t[0] = (Math.random() * 2 - 1) * n, t[1] = n;
|
|
112
112
|
break;
|
|
113
113
|
case 1:
|
|
114
|
-
t[0] =
|
|
114
|
+
t[0] = n, t[1] = (Math.random() * 2 - 1) * n;
|
|
115
115
|
break;
|
|
116
116
|
case 2:
|
|
117
|
-
t[0] = (Math.random() * 2 - 1) *
|
|
117
|
+
t[0] = (Math.random() * 2 - 1) * n, t[1] = -n;
|
|
118
118
|
break;
|
|
119
119
|
case 3:
|
|
120
|
-
t[0] = -
|
|
120
|
+
t[0] = -n, t[1] = (Math.random() * 2 - 1) * n;
|
|
121
121
|
break;
|
|
122
122
|
}
|
|
123
123
|
} else
|
|
@@ -126,87 +126,87 @@ class W {
|
|
|
126
126
|
}
|
|
127
127
|
_emitFromCircle(t) {
|
|
128
128
|
const e = this.config.circleInnerRadius || 0, i = this.config.circleOuterRadius || 2, s = Math.random() * Math.PI * 2;
|
|
129
|
-
let
|
|
130
|
-
e > 0 ?
|
|
129
|
+
let n;
|
|
130
|
+
e > 0 ? n = e + (i - e) * Math.random() : n = i * Math.sqrt(Math.random()), t[0] = Math.cos(s) * n, t[1] = Math.sin(s) * n, 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, s = this.config.coneHeight || 4,
|
|
137
|
+
const e = this.config.coneInnerRadius || 0, i = this.config.coneOuterRadius || 2, s = this.config.coneHeight || 4, n = Math.random() * Math.PI * 2, o = Math.random(), a = o * s, c = i * (1 - o);
|
|
138
138
|
let l;
|
|
139
139
|
if (e > 0) {
|
|
140
|
-
const
|
|
141
|
-
l =
|
|
140
|
+
const u = e * (1 - o);
|
|
141
|
+
l = u + (c - u) * Math.random();
|
|
142
142
|
} else
|
|
143
|
-
l =
|
|
144
|
-
t[0] = Math.cos(
|
|
143
|
+
l = c * Math.sqrt(Math.random());
|
|
144
|
+
t[0] = Math.cos(n) * l, t[1] = a, t[2] = Math.sin(n) * l;
|
|
145
145
|
}
|
|
146
146
|
_emitFromTorus(t) {
|
|
147
|
-
const e = this.config.torusMajorRadius || 2, i = this.config.torusMinorRadius || 0.5, s = Math.random() * Math.PI * 2,
|
|
148
|
-
t[0] = (e +
|
|
147
|
+
const e = this.config.torusMajorRadius || 2, i = this.config.torusMinorRadius || 0.5, s = Math.random() * Math.PI * 2, n = Math.random() * Math.PI * 2, o = i * Math.sqrt(Math.random());
|
|
148
|
+
t[0] = (e + o * Math.cos(n)) * Math.cos(s), t[1] = o * Math.sin(n), t[2] = (e + o * Math.cos(n)) * 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, s = Math.random() * Math.PI * 2,
|
|
155
|
+
const e = this.config.hemisphereInnerRadius || 0, i = this.config.hemisphereOuterRadius || 2, s = Math.random() * Math.PI * 2, n = Math.acos(Math.random()), o = Math.sin(n) * Math.cos(s), a = Math.cos(n), c = Math.sin(n) * Math.sin(s);
|
|
156
156
|
let l;
|
|
157
|
-
e > 0 ? l = e + (i - e) * Math.random() : l = i * Math.cbrt(Math.random()), t[0] =
|
|
157
|
+
e > 0 ? l = e + (i - e) * Math.random() : l = i * Math.cbrt(Math.random()), t[0] = o * l, t[1] = a * l, t[2] = c * l;
|
|
158
158
|
}
|
|
159
159
|
_emitFromDisc(t) {
|
|
160
160
|
const e = this.config.discRadius || 2, i = Math.random() * Math.PI * 2, s = e * Math.sqrt(Math.random());
|
|
161
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, s = Math.random() * Math.PI * 2,
|
|
165
|
-
t[0] = Math.cos(s) *
|
|
164
|
+
const e = this.config.annulusInnerRadius || 1, i = this.config.annulusOuterRadius || 2, s = Math.random() * Math.PI * 2, n = e + (i - e) * Math.random();
|
|
165
|
+
t[0] = Math.cos(s) * n, t[1] = 0, t[2] = Math.sin(s) * n;
|
|
166
166
|
}
|
|
167
167
|
_emitFromCapsule(t) {
|
|
168
|
-
const e = this.config.capsuleRadius || 0.5, i = this.config.capsuleHeight || 4, s = i * 0.5,
|
|
169
|
-
if (Math.random() <
|
|
170
|
-
const
|
|
171
|
-
t[0] = Math.cos(
|
|
168
|
+
const e = this.config.capsuleRadius || 0.5, i = this.config.capsuleHeight || 4, s = i * 0.5, n = Math.PI * e * e * i, o = 4 / 3 * Math.PI * e * e * e, a = n / (n + o);
|
|
169
|
+
if (Math.random() < a) {
|
|
170
|
+
const c = Math.random() * Math.PI * 2, l = e * Math.sqrt(Math.random());
|
|
171
|
+
t[0] = Math.cos(c) * l, t[1] = (Math.random() - 0.5) * i, t[2] = Math.sin(c) * l;
|
|
172
172
|
} else {
|
|
173
|
-
const
|
|
174
|
-
t[0] =
|
|
173
|
+
const c = Math.random() * Math.PI * 2, l = Math.acos(2 * Math.random() - 1), u = e * Math.cbrt(Math.random());
|
|
174
|
+
t[0] = u * Math.sin(l) * Math.cos(c), t[1] = u * Math.cos(l), t[2] = u * Math.sin(l) * Math.sin(c), 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, s = this.config.arcInnerRadius || 0,
|
|
178
|
+
const e = this.config.arcStartAngle || 0, i = this.config.arcEndAngle || 180, s = this.config.arcInnerRadius || 0, n = this.config.arcOuterRadius || 2, o = e * Math.PI / 180, a = i * Math.PI / 180, c = o + Math.random() * (a - o);
|
|
179
179
|
let l;
|
|
180
|
-
s > 0 ? l = s + (
|
|
180
|
+
s > 0 ? l = s + (n - s) * Math.random() : l = n * Math.sqrt(Math.random()), t[0] = Math.cos(c) * l, t[1] = Math.sin(c) * l, t[2] = 0;
|
|
181
181
|
}
|
|
182
182
|
_emitFromSpiral(t) {
|
|
183
|
-
const e = this.config.spiralTurns || 3, i = this.config.spiralRadiusStart || 0.5, s = this.config.spiralRadiusEnd || 2,
|
|
184
|
-
t[0] = Math.cos(
|
|
183
|
+
const e = this.config.spiralTurns || 3, i = this.config.spiralRadiusStart || 0.5, s = this.config.spiralRadiusEnd || 2, n = this.config.spiralHeight || 4, o = Math.random(), a = o * e * Math.PI * 2, c = i + (s - i) * o;
|
|
184
|
+
t[0] = Math.cos(a) * c, t[1] = (o - 0.5) * n, t[2] = Math.sin(a) * c;
|
|
185
185
|
}
|
|
186
186
|
_emitFromFrustum(t) {
|
|
187
|
-
const e = this.config.frustumRadiusNear || 0.5, i = this.config.frustumRadiusFar || 2, s = this.config.frustumHeight || 4,
|
|
188
|
-
t[0] = Math.cos(
|
|
187
|
+
const e = this.config.frustumRadiusNear || 0.5, i = this.config.frustumRadiusFar || 2, s = this.config.frustumHeight || 4, n = Math.random() * Math.PI * 2, o = Math.random(), a = o * s, l = (e + (i - e) * o) * Math.sqrt(Math.random());
|
|
188
|
+
t[0] = Math.cos(n) * l, t[1] = a, t[2] = Math.sin(n) * l;
|
|
189
189
|
}
|
|
190
190
|
_emitFromCubeSurface(t) {
|
|
191
|
-
const e = this.config.cubeSurfaceSize || 2, i = e * 0.5, s = Math.floor(Math.random() * 6),
|
|
191
|
+
const e = this.config.cubeSurfaceSize || 2, i = e * 0.5, s = Math.floor(Math.random() * 6), n = (Math.random() - 0.5) * e, o = (Math.random() - 0.5) * e;
|
|
192
192
|
switch (s) {
|
|
193
193
|
case 0:
|
|
194
|
-
t[0] =
|
|
194
|
+
t[0] = n, t[1] = o, t[2] = i;
|
|
195
195
|
break;
|
|
196
196
|
case 1:
|
|
197
|
-
t[0] =
|
|
197
|
+
t[0] = n, t[1] = o, t[2] = -i;
|
|
198
198
|
break;
|
|
199
199
|
case 2:
|
|
200
|
-
t[0] = i, t[1] =
|
|
200
|
+
t[0] = i, t[1] = n, t[2] = o;
|
|
201
201
|
break;
|
|
202
202
|
case 3:
|
|
203
|
-
t[0] = -i, t[1] =
|
|
203
|
+
t[0] = -i, t[1] = n, t[2] = o;
|
|
204
204
|
break;
|
|
205
205
|
case 4:
|
|
206
|
-
t[0] =
|
|
206
|
+
t[0] = n, t[1] = i, t[2] = o;
|
|
207
207
|
break;
|
|
208
208
|
case 5:
|
|
209
|
-
t[0] =
|
|
209
|
+
t[0] = n, t[1] = -i, t[2] = o;
|
|
210
210
|
break;
|
|
211
211
|
}
|
|
212
212
|
}
|
|
@@ -215,62 +215,62 @@ class W {
|
|
|
215
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, s = Math.floor(Math.random() * 12),
|
|
218
|
+
const e = this.config.boxFrameSize || 2, i = e * 0.5, s = Math.floor(Math.random() * 12), o = (Math.random() - 0.5) * e, a = [[-1, -1], [-1, 1], [1, -1], [1, 1]];
|
|
219
219
|
if (s < 4) {
|
|
220
|
-
const [
|
|
221
|
-
t[0] =
|
|
220
|
+
const [c, l] = a[s];
|
|
221
|
+
t[0] = o, t[1] = c * i, t[2] = l * i;
|
|
222
222
|
} else if (s < 8) {
|
|
223
|
-
const [
|
|
224
|
-
t[0] =
|
|
223
|
+
const [c, l] = a[s - 4];
|
|
224
|
+
t[0] = c * i, t[1] = o, t[2] = l * i;
|
|
225
225
|
} else {
|
|
226
|
-
const [
|
|
227
|
-
t[0] =
|
|
226
|
+
const [c, l] = a[s - 8];
|
|
227
|
+
t[0] = c * i, t[1] = l * i, t[2] = o;
|
|
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, s = Math.floor(Math.random() * e),
|
|
232
|
-
let
|
|
233
|
-
|
|
234
|
-
const l =
|
|
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), n = s / e * Math.PI * 2, o = (s + 1) / e * Math.PI * 2;
|
|
232
|
+
let a = Math.random(), c = Math.random();
|
|
233
|
+
a + c > 1 && (a = 1 - a, c = 1 - c);
|
|
234
|
+
const l = a * Math.cos(n) + c * Math.cos(o), u = a * Math.sin(n) + c * Math.sin(o);
|
|
235
|
+
t[0] = l * i, t[1] = u * i, t[2] = 0;
|
|
236
236
|
}
|
|
237
237
|
_emitFromRectangle(t) {
|
|
238
238
|
const e = this.config.rectangleWidth || 2, i = this.config.rectangleHeight || 2;
|
|
239
239
|
t[0] = (Math.random() - 0.5) * e, t[1] = (Math.random() - 0.5) * i, t[2] = 0;
|
|
240
240
|
}
|
|
241
241
|
_emitFromCylinder(t) {
|
|
242
|
-
const e = this.config.cylinderInnerRadius || 0, i = this.config.cylinderOuterRadius || 2, s = this.config.cylinderHeight || 4,
|
|
243
|
-
let
|
|
244
|
-
e > 0 ?
|
|
242
|
+
const e = this.config.cylinderInnerRadius || 0, i = this.config.cylinderOuterRadius || 2, s = this.config.cylinderHeight || 4, n = Math.random() * Math.PI * 2;
|
|
243
|
+
let o;
|
|
244
|
+
e > 0 ? o = e + (i - e) * Math.random() : o = i * Math.sqrt(Math.random()), t[0] = Math.cos(n) * o, t[1] = (Math.random() - 0.5) * s, t[2] = Math.sin(n) * o;
|
|
245
245
|
}
|
|
246
|
-
calculateVelocity(t, e, i, s,
|
|
247
|
-
const
|
|
248
|
-
let
|
|
249
|
-
if (
|
|
250
|
-
let
|
|
246
|
+
calculateVelocity(t, e, i, s, n) {
|
|
247
|
+
const o = this.config.emissionPositionX || 0, a = this.config.emissionPositionY || 0, c = this.config.emissionPositionZ || 0, l = t - o, u = e - a, f = i - c, h = Math.sqrt(l * l + u * u + f * f);
|
|
248
|
+
let m, S, R;
|
|
249
|
+
if (h > 1e-4) {
|
|
250
|
+
let C = !1;
|
|
251
251
|
if (this.config.emissionShape === "circle" && this.config.circleVelocityDirection === "tangential") {
|
|
252
|
-
const
|
|
253
|
-
if (
|
|
254
|
-
const
|
|
255
|
-
|
|
252
|
+
const B = this.inverseRotation(l, u, f), A = Math.sqrt(B[0] * B[0] + B[1] * B[1]);
|
|
253
|
+
if (A > 1e-4) {
|
|
254
|
+
const P = -B[1] / A, _ = B[0] / A, T = this.applyRotation(P, _, 0);
|
|
255
|
+
m = T[0], S = T[1], R = T[2], C = !0;
|
|
256
256
|
}
|
|
257
257
|
} else if (this.config.emissionShape === "cylinder" && this.config.cylinderVelocityDirection === "tangential") {
|
|
258
|
-
const
|
|
259
|
-
if (
|
|
260
|
-
const
|
|
261
|
-
|
|
258
|
+
const B = this.inverseRotation(l, u, f), A = Math.sqrt(B[0] * B[0] + B[2] * B[2]);
|
|
259
|
+
if (A > 1e-4) {
|
|
260
|
+
const P = -B[2] / A, _ = B[0] / A, T = this.applyRotation(P, 0, _);
|
|
261
|
+
m = T[0], S = T[1], R = T[2], C = !0;
|
|
262
262
|
} else {
|
|
263
|
-
const
|
|
264
|
-
|
|
263
|
+
const P = Math.random() * Math.PI * 2, _ = this.applyRotation(Math.cos(P), 0, Math.sin(P));
|
|
264
|
+
m = _[0], S = _[1], R = _[2], C = !0;
|
|
265
265
|
}
|
|
266
266
|
}
|
|
267
|
-
|
|
267
|
+
C || (m = l / h, S = u / h, R = f / h);
|
|
268
268
|
} else {
|
|
269
|
-
const
|
|
270
|
-
|
|
269
|
+
const C = Math.random() * Math.PI * 2, B = Math.acos(2 * Math.random() - 1);
|
|
270
|
+
m = Math.sin(B) * Math.cos(C), S = Math.sin(B) * Math.sin(C), R = Math.cos(B);
|
|
271
271
|
}
|
|
272
|
-
let
|
|
273
|
-
this.config.randomSpeed ?
|
|
272
|
+
let D;
|
|
273
|
+
this.config.randomSpeed ? D = (this.config.minSpeed || 0) + Math.random() * ((this.config.maxSpeed || 1) - (this.config.minSpeed || 0)) : D = this.config.particleSpeed, s[n] = this.config.overrideXVelocity ? this.config.xVelocity : m * D, s[n + 1] = this.config.overrideYVelocity ? this.config.yVelocity : S * D, s[n + 2] = this.config.overrideZVelocity ? this.config.zVelocity : R * D, s[n + 3] = 0;
|
|
274
274
|
}
|
|
275
275
|
setParticleColor(t, e) {
|
|
276
276
|
if (this.config.randomColorEnabled && this.config.randomColors.length > 0) {
|
|
@@ -283,7 +283,7 @@ class W {
|
|
|
283
283
|
t[e + 6] = 0, t[e + 7] = i + (Math.random() * 0.4 - 0.2) * i;
|
|
284
284
|
}
|
|
285
285
|
}
|
|
286
|
-
class
|
|
286
|
+
class us {
|
|
287
287
|
constructor(t, e = 1e4) {
|
|
288
288
|
this.device = t, this.physicsSettings = {
|
|
289
289
|
deltaTime: 0.016,
|
|
@@ -343,7 +343,7 @@ class J {
|
|
|
343
343
|
}
|
|
344
344
|
}
|
|
345
345
|
async createComputePipeline(t, e, i) {
|
|
346
|
-
const { particlePhysicsShader: s } = await Promise.resolve().then(() =>
|
|
346
|
+
const { particlePhysicsShader: s } = await Promise.resolve().then(() => _i);
|
|
347
347
|
this.computeBindGroupLayout = this.device.createBindGroupLayout({
|
|
348
348
|
entries: [
|
|
349
349
|
{
|
|
@@ -399,49 +399,49 @@ class J {
|
|
|
399
399
|
]
|
|
400
400
|
});
|
|
401
401
|
}
|
|
402
|
-
updatePhysics(t, e, i, s,
|
|
402
|
+
updatePhysics(t, e, i, s, n, o) {
|
|
403
403
|
if (e <= 0 || !this.computeReady)
|
|
404
404
|
return;
|
|
405
|
-
const
|
|
406
|
-
|
|
407
|
-
const l =
|
|
408
|
-
|
|
409
|
-
const
|
|
410
|
-
|
|
411
|
-
}
|
|
412
|
-
async readbackAndProcessParticles(t, e, i, s,
|
|
405
|
+
const a = this._physicsData, c = this.physicsSettings;
|
|
406
|
+
a[0] = t, a[1] = i.particleSpeed, a[2] = c.gravity, a[3] = c.turbulence, a[4] = c.attractorStrength, a[5] = c.damping, a[6] = c.attractorPosition[0], a[7] = c.attractorPosition[1], a[8] = c.attractorPosition[2], this._physicsDataU32View[9] = e, a[10] = c.confinementEnabled ? 1 : 0, a[11] = c.confinementShape === "sphere" ? 1 : 0, a[12] = c.confinementMode === "kill" ? 1 : 0, a[13] = c.confinementSpace === "local" ? 1 : 0, a[14] = c.confinementBoxHalfSize[0], a[15] = c.confinementBoxHalfSize[1], a[16] = c.confinementBoxHalfSize[2], a[17] = c.confinementSphereRadius, a[18] = c.confinementRestitution, a[19] = c.confinementFriction, a[20] = c.confinementCenter[0], a[21] = c.confinementCenter[1], a[22] = c.confinementCenter[2], a[23] = c.softBoundaryEnabled ? 1 : 0, a[24] = c.softBoundaryStrength, a[25] = c.softBoundaryFalloff, a[26] = i.velocityStretchEnabled ? 1 : 0, a[27] = i.velocityStretchFactor ?? 1, a[28] = 0, a[29] = 0, a[30] = 0, a[31] = 0, this.device.queue.writeBuffer(this.physicsUniformBuffer, 0, a);
|
|
407
|
+
const l = o || this.device.createCommandEncoder({ label: "ParticlePhysicsEncoder" }), u = l.beginComputePass({ label: "ParticlePhysicsPass" });
|
|
408
|
+
u.setPipeline(this.computePipeline), u.setBindGroup(0, this.computeBindGroup);
|
|
409
|
+
const f = Math.max(1, Math.ceil(e / 64));
|
|
410
|
+
u.dispatchWorkgroups(f, 1, 1), u.end(), o || this.device.queue.submit([l.finish()]), this.lastUpdateTime = performance.now() / 1e3;
|
|
411
|
+
}
|
|
412
|
+
async readbackAndProcessParticles(t, e, i, s, n) {
|
|
413
413
|
if (t <= 0)
|
|
414
414
|
return { activeCount: 0, shouldUpdate: !1 };
|
|
415
415
|
if (this._stagingInUse)
|
|
416
416
|
return { activeCount: t, shouldUpdate: !1 };
|
|
417
417
|
try {
|
|
418
418
|
this._stagingInUse = !0;
|
|
419
|
-
const
|
|
419
|
+
const o = this.device.createCommandEncoder({
|
|
420
420
|
label: "ParticleReadbackEncoder"
|
|
421
|
-
}),
|
|
422
|
-
|
|
421
|
+
}), a = t * 8 * 4;
|
|
422
|
+
o.copyBufferToBuffer(
|
|
423
423
|
s,
|
|
424
424
|
0,
|
|
425
425
|
this._particleDataStagingBuffer,
|
|
426
426
|
0,
|
|
427
|
-
|
|
427
|
+
a
|
|
428
428
|
);
|
|
429
|
-
const
|
|
430
|
-
return
|
|
431
|
-
|
|
429
|
+
const c = t * 4 * 4;
|
|
430
|
+
return o.copyBufferToBuffer(
|
|
431
|
+
n,
|
|
432
432
|
0,
|
|
433
433
|
this._velocityStagingBuffer,
|
|
434
434
|
0,
|
|
435
|
-
|
|
436
|
-
), this.device.queue.submit([
|
|
435
|
+
c
|
|
436
|
+
), this.device.queue.submit([o.finish()]), await Promise.all([
|
|
437
437
|
(async () => {
|
|
438
|
-
await this._particleDataStagingBuffer.mapAsync(GPUMapMode.READ, 0,
|
|
439
|
-
const l = new Float32Array(this._particleDataStagingBuffer.getMappedRange(0,
|
|
438
|
+
await this._particleDataStagingBuffer.mapAsync(GPUMapMode.READ, 0, a);
|
|
439
|
+
const l = new Float32Array(this._particleDataStagingBuffer.getMappedRange(0, a));
|
|
440
440
|
e.set(l), this._particleDataStagingBuffer.unmap();
|
|
441
441
|
})(),
|
|
442
442
|
(async () => {
|
|
443
|
-
await this._velocityStagingBuffer.mapAsync(GPUMapMode.READ, 0,
|
|
444
|
-
const l = new Float32Array(this._velocityStagingBuffer.getMappedRange(0,
|
|
443
|
+
await this._velocityStagingBuffer.mapAsync(GPUMapMode.READ, 0, c);
|
|
444
|
+
const l = new Float32Array(this._velocityStagingBuffer.getMappedRange(0, c));
|
|
445
445
|
i.set(l), this._velocityStagingBuffer.unmap();
|
|
446
446
|
})()
|
|
447
447
|
]), this._stagingInUse = !1, {
|
|
@@ -449,8 +449,8 @@ class J {
|
|
|
449
449
|
particleVelocities: i,
|
|
450
450
|
shouldUpdate: !0
|
|
451
451
|
};
|
|
452
|
-
} catch (
|
|
453
|
-
return this._stagingInUse = !1, console.error("Error reading back particle data:",
|
|
452
|
+
} catch (o) {
|
|
453
|
+
return this._stagingInUse = !1, o && o.name === "AbortError" || console.error("Error reading back particle data:", o), { activeCount: t, shouldUpdate: !1 };
|
|
454
454
|
}
|
|
455
455
|
}
|
|
456
456
|
setDamping(t) {
|
|
@@ -477,37 +477,37 @@ class J {
|
|
|
477
477
|
* @param {GPUBuffer} velocityBuffer
|
|
478
478
|
* @returns {Promise<{particleData: Float32Array, particleVelocities: Float32Array, shouldUpdate: boolean}>}
|
|
479
479
|
*/
|
|
480
|
-
async readbackForRendering(t, e, i, s,
|
|
480
|
+
async readbackForRendering(t, e, i, s, n) {
|
|
481
481
|
if (t <= 0)
|
|
482
482
|
return { shouldUpdate: !1 };
|
|
483
483
|
if (this._renderStagingInUse)
|
|
484
484
|
return { shouldUpdate: !1 };
|
|
485
485
|
try {
|
|
486
486
|
this._renderStagingInUse = !0;
|
|
487
|
-
const
|
|
487
|
+
const o = t * 8 * 4, a = t * 4 * 4, c = this.device.createCommandEncoder({
|
|
488
488
|
label: "RenderReadbackEncoder"
|
|
489
489
|
});
|
|
490
|
-
return
|
|
490
|
+
return c.copyBufferToBuffer(
|
|
491
491
|
s,
|
|
492
492
|
0,
|
|
493
493
|
this._renderStagingParticleBuffer,
|
|
494
494
|
0,
|
|
495
|
-
|
|
496
|
-
),
|
|
497
|
-
|
|
495
|
+
o
|
|
496
|
+
), c.copyBufferToBuffer(
|
|
497
|
+
n,
|
|
498
498
|
0,
|
|
499
499
|
this._renderStagingVelocityBuffer,
|
|
500
500
|
0,
|
|
501
|
-
|
|
502
|
-
), this.device.queue.submit([
|
|
501
|
+
a
|
|
502
|
+
), this.device.queue.submit([c.finish()]), await Promise.all([
|
|
503
503
|
(async () => {
|
|
504
|
-
await this._renderStagingParticleBuffer.mapAsync(GPUMapMode.READ, 0,
|
|
505
|
-
const l = new Float32Array(this._renderStagingParticleBuffer.getMappedRange(0,
|
|
504
|
+
await this._renderStagingParticleBuffer.mapAsync(GPUMapMode.READ, 0, o);
|
|
505
|
+
const l = new Float32Array(this._renderStagingParticleBuffer.getMappedRange(0, o));
|
|
506
506
|
e.set(l), this._renderStagingParticleBuffer.unmap();
|
|
507
507
|
})(),
|
|
508
508
|
(async () => {
|
|
509
|
-
await this._renderStagingVelocityBuffer.mapAsync(GPUMapMode.READ, 0,
|
|
510
|
-
const l = new Float32Array(this._renderStagingVelocityBuffer.getMappedRange(0,
|
|
509
|
+
await this._renderStagingVelocityBuffer.mapAsync(GPUMapMode.READ, 0, a);
|
|
510
|
+
const l = new Float32Array(this._renderStagingVelocityBuffer.getMappedRange(0, a));
|
|
511
511
|
i.set(l), this._renderStagingVelocityBuffer.unmap();
|
|
512
512
|
})()
|
|
513
513
|
]), this._renderStagingInUse = !1, {
|
|
@@ -515,8 +515,8 @@ class J {
|
|
|
515
515
|
particleVelocities: i,
|
|
516
516
|
shouldUpdate: !0
|
|
517
517
|
};
|
|
518
|
-
} catch (
|
|
519
|
-
return this._renderStagingInUse = !1, console.error("Error in rendering readback:",
|
|
518
|
+
} catch (o) {
|
|
519
|
+
return this._renderStagingInUse = !1, console.error("Error in rendering readback:", o), { shouldUpdate: !1 };
|
|
520
520
|
}
|
|
521
521
|
}
|
|
522
522
|
/**
|
|
@@ -530,42 +530,42 @@ class J {
|
|
|
530
530
|
* @param {GPUBuffer} velocityBuffer
|
|
531
531
|
* @returns {Promise<{shouldUpdate: boolean}>}
|
|
532
532
|
*/
|
|
533
|
-
async readbackForScript(t, e, i, s,
|
|
533
|
+
async readbackForScript(t, e, i, s, n) {
|
|
534
534
|
if (t <= 0)
|
|
535
535
|
return { shouldUpdate: !1 };
|
|
536
536
|
if (this._scriptStagingInUse)
|
|
537
537
|
return { shouldUpdate: !1 };
|
|
538
538
|
try {
|
|
539
539
|
this._scriptStagingInUse = !0;
|
|
540
|
-
const
|
|
540
|
+
const o = t * 8 * 4, a = t * 4 * 4, c = this.device.createCommandEncoder({
|
|
541
541
|
label: "ScriptReadbackEncoder"
|
|
542
542
|
});
|
|
543
|
-
return
|
|
543
|
+
return c.copyBufferToBuffer(
|
|
544
544
|
s,
|
|
545
545
|
0,
|
|
546
546
|
this._scriptStagingParticleBuffer,
|
|
547
547
|
0,
|
|
548
|
-
|
|
549
|
-
),
|
|
550
|
-
|
|
548
|
+
o
|
|
549
|
+
), c.copyBufferToBuffer(
|
|
550
|
+
n,
|
|
551
551
|
0,
|
|
552
552
|
this._scriptStagingVelocityBuffer,
|
|
553
553
|
0,
|
|
554
|
-
|
|
555
|
-
), this.device.queue.submit([
|
|
554
|
+
a
|
|
555
|
+
), this.device.queue.submit([c.finish()]), await Promise.all([
|
|
556
556
|
(async () => {
|
|
557
|
-
await this._scriptStagingParticleBuffer.mapAsync(GPUMapMode.READ, 0,
|
|
558
|
-
const l = new Float32Array(this._scriptStagingParticleBuffer.getMappedRange(0,
|
|
557
|
+
await this._scriptStagingParticleBuffer.mapAsync(GPUMapMode.READ, 0, o);
|
|
558
|
+
const l = new Float32Array(this._scriptStagingParticleBuffer.getMappedRange(0, o));
|
|
559
559
|
e.set(l), this._scriptStagingParticleBuffer.unmap();
|
|
560
560
|
})(),
|
|
561
561
|
(async () => {
|
|
562
|
-
await this._scriptStagingVelocityBuffer.mapAsync(GPUMapMode.READ, 0,
|
|
563
|
-
const l = new Float32Array(this._scriptStagingVelocityBuffer.getMappedRange(0,
|
|
562
|
+
await this._scriptStagingVelocityBuffer.mapAsync(GPUMapMode.READ, 0, a);
|
|
563
|
+
const l = new Float32Array(this._scriptStagingVelocityBuffer.getMappedRange(0, a));
|
|
564
564
|
i.set(l), this._scriptStagingVelocityBuffer.unmap();
|
|
565
565
|
})()
|
|
566
566
|
]), this._scriptStagingInUse = !1, { shouldUpdate: !0 };
|
|
567
|
-
} catch (
|
|
568
|
-
return this._scriptStagingInUse = !1, console.error("Error in script readback:",
|
|
567
|
+
} catch (o) {
|
|
568
|
+
return this._scriptStagingInUse = !1, console.error("Error in script readback:", o), { shouldUpdate: !1 };
|
|
569
569
|
}
|
|
570
570
|
}
|
|
571
571
|
/**
|
|
@@ -579,7 +579,7 @@ class J {
|
|
|
579
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);
|
|
580
580
|
}
|
|
581
581
|
}
|
|
582
|
-
class
|
|
582
|
+
class ds {
|
|
583
583
|
constructor(t) {
|
|
584
584
|
this.device = t, this.defaultTexture = null, this.createDefaultTexture();
|
|
585
585
|
}
|
|
@@ -618,7 +618,7 @@ class K {
|
|
|
618
618
|
t && t.label !== "defaultParticleTexture" && t.destroy();
|
|
619
619
|
}
|
|
620
620
|
}
|
|
621
|
-
const
|
|
621
|
+
const yi = Object.freeze({
|
|
622
622
|
sin: Math.sin,
|
|
623
623
|
cos: Math.cos,
|
|
624
624
|
abs: Math.abs,
|
|
@@ -632,17 +632,17 @@ const N = Object.freeze({
|
|
|
632
632
|
random: Math.random,
|
|
633
633
|
PI: Math.PI,
|
|
634
634
|
TAU: Math.PI * 2,
|
|
635
|
-
clamp(
|
|
636
|
-
return
|
|
635
|
+
clamp(r, t, e) {
|
|
636
|
+
return r < t ? t : r > e ? e : r;
|
|
637
637
|
},
|
|
638
|
-
lerp(
|
|
639
|
-
return
|
|
638
|
+
lerp(r, t, e) {
|
|
639
|
+
return r + (t - r) * e;
|
|
640
640
|
},
|
|
641
|
-
smoothstep(
|
|
642
|
-
const i =
|
|
641
|
+
smoothstep(r, t, e) {
|
|
642
|
+
const i = yi.clamp((e - r) / (t - r), 0, 1);
|
|
643
643
|
return i * i * (3 - 2 * i);
|
|
644
644
|
}
|
|
645
|
-
}),
|
|
645
|
+
}), Ze = /* @__PURE__ */ new Set([
|
|
646
646
|
"particleSize",
|
|
647
647
|
"particleSpeed",
|
|
648
648
|
"particleColor",
|
|
@@ -658,7 +658,7 @@ const N = Object.freeze({
|
|
|
658
658
|
"pulseFrequency",
|
|
659
659
|
"bloomIntensity"
|
|
660
660
|
]);
|
|
661
|
-
class
|
|
661
|
+
class fs {
|
|
662
662
|
constructor(t) {
|
|
663
663
|
this._collection = t, this._pd = null, this._vd = null, this._pi = 0, this._vi = 0;
|
|
664
664
|
}
|
|
@@ -736,9 +736,9 @@ class Q {
|
|
|
736
736
|
this._vd[this._vi + 2] = t, this._collection._dirty = !0;
|
|
737
737
|
}
|
|
738
738
|
}
|
|
739
|
-
class
|
|
739
|
+
class ps {
|
|
740
740
|
constructor() {
|
|
741
|
-
this._proxy = new
|
|
741
|
+
this._proxy = new fs(this), this._pd = null, this._vd = null, this.count = 0, this._dirty = !1;
|
|
742
742
|
}
|
|
743
743
|
_bind(t, e, i) {
|
|
744
744
|
this._pd = t, this._vd = e, this.count = i, this._dirty = !1;
|
|
@@ -747,14 +747,14 @@ class ee {
|
|
|
747
747
|
return t < 0 || t >= this.count ? null : this._proxy._bind(this._pd, this._vd, t);
|
|
748
748
|
}
|
|
749
749
|
}
|
|
750
|
-
const
|
|
751
|
-
function
|
|
750
|
+
const hs = 1e6;
|
|
751
|
+
function ms(r) {
|
|
752
752
|
let t = 0;
|
|
753
|
-
return
|
|
753
|
+
return r.replace(
|
|
754
754
|
/\b(for|while)\s*\([^)]*\)\s*\{/g,
|
|
755
755
|
(e) => {
|
|
756
756
|
const i = `__lc${t++}`;
|
|
757
|
-
return `${e} if(++${i}>${
|
|
757
|
+
return `${e} if(++${i}>${hs})throw new Error("Loop limit exceeded");`;
|
|
758
758
|
}
|
|
759
759
|
).replace(
|
|
760
760
|
/\b(for|while)\s*\([^)]*\)\s*\{/g,
|
|
@@ -771,45 +771,45 @@ function ie(c) {
|
|
|
771
771
|
}
|
|
772
772
|
);
|
|
773
773
|
}
|
|
774
|
-
const
|
|
775
|
-
for (const
|
|
776
|
-
|
|
777
|
-
function
|
|
774
|
+
const vt = /* @__PURE__ */ new Map();
|
|
775
|
+
for (const r of Ze)
|
|
776
|
+
vt.set(r.toLowerCase(), r);
|
|
777
|
+
function ys(r) {
|
|
778
778
|
const t = { value: !1 }, e = /* @__PURE__ */ new Set();
|
|
779
|
-
return new Proxy(
|
|
780
|
-
get(s,
|
|
781
|
-
if (
|
|
782
|
-
if (
|
|
779
|
+
return new Proxy(r, {
|
|
780
|
+
get(s, n) {
|
|
781
|
+
if (n === "__dirty") return t.value;
|
|
782
|
+
if (n === "__resetDirty") return () => {
|
|
783
783
|
t.value = !1;
|
|
784
784
|
};
|
|
785
|
-
if (typeof
|
|
786
|
-
if (
|
|
787
|
-
const
|
|
788
|
-
if (
|
|
789
|
-
return e.has(
|
|
785
|
+
if (typeof n != "string") return;
|
|
786
|
+
if (Ze.has(n)) return s[n];
|
|
787
|
+
const o = vt.get(n.toLowerCase());
|
|
788
|
+
if (o)
|
|
789
|
+
return e.has(n) || (e.add(n), console.warn(`[ParticleScript] config.${n} → did you mean config.${o}?`)), s[o];
|
|
790
790
|
},
|
|
791
|
-
set(s,
|
|
792
|
-
if (typeof
|
|
793
|
-
let
|
|
794
|
-
if (!
|
|
795
|
-
const
|
|
796
|
-
if (
|
|
797
|
-
e.has(
|
|
791
|
+
set(s, n, o) {
|
|
792
|
+
if (typeof n != "string") return !0;
|
|
793
|
+
let a = n;
|
|
794
|
+
if (!Ze.has(a)) {
|
|
795
|
+
const c = vt.get(a.toLowerCase());
|
|
796
|
+
if (c)
|
|
797
|
+
e.has(n) || (e.add(n), console.warn(`[ParticleScript] config.${n} → did you mean config.${c}?`)), a = c;
|
|
798
798
|
else
|
|
799
799
|
return !0;
|
|
800
800
|
}
|
|
801
|
-
return s[
|
|
801
|
+
return s[a] = o, t.value = !0, !0;
|
|
802
802
|
}
|
|
803
803
|
});
|
|
804
804
|
}
|
|
805
|
-
class
|
|
805
|
+
class si {
|
|
806
806
|
/**
|
|
807
807
|
* @param {string} source - User script source code
|
|
808
808
|
* @param {object} config - ParticleSystem config (will be proxied)
|
|
809
809
|
* @param {number} maxParticles - Max particle count for pre-allocation
|
|
810
810
|
*/
|
|
811
811
|
constructor(t, e, i) {
|
|
812
|
-
this._particles = new
|
|
812
|
+
this._particles = new ps(), this._configProxy = ys(e), this._configSnapshot = null, this._fn = null, this._error = !1, this.compile(t);
|
|
813
813
|
}
|
|
814
814
|
/**
|
|
815
815
|
* Compile script source into a sandboxed function.
|
|
@@ -825,7 +825,7 @@ return function(__deltaTime, __time, __currentFrame, __totalFrames, __particles,
|
|
|
825
825
|
var deltaTime = __deltaTime, time = __time;
|
|
826
826
|
var currentFrame = __currentFrame, totalFrames = __totalFrames;
|
|
827
827
|
var particles = __particles, config = __config, math = __math;
|
|
828
|
-
${
|
|
828
|
+
${ms(t)}
|
|
829
829
|
};`, s = new Function(i);
|
|
830
830
|
this._fn = s();
|
|
831
831
|
} catch (e) {
|
|
@@ -843,13 +843,13 @@ return function(__deltaTime, __time, __currentFrame, __totalFrames, __particles,
|
|
|
843
843
|
* @param {number} count - active particle count
|
|
844
844
|
* @returns {boolean} true if config was modified
|
|
845
845
|
*/
|
|
846
|
-
execute(t, e, i, s,
|
|
846
|
+
execute(t, e, i, s, n, o, a) {
|
|
847
847
|
if (!this._fn || this._error) return { configDirty: !1, particlesDirty: !1 };
|
|
848
|
-
this._particles._bind(
|
|
848
|
+
this._particles._bind(n, o, a), this._configProxy.__resetDirty();
|
|
849
849
|
try {
|
|
850
|
-
this._fn(t, e, i, s, this._particles, this._configProxy,
|
|
851
|
-
} catch (
|
|
852
|
-
console.warn("[ParticleScript] Runtime error:",
|
|
850
|
+
this._fn(t, e, i, s, this._particles, this._configProxy, yi);
|
|
851
|
+
} catch (c) {
|
|
852
|
+
console.warn("[ParticleScript] Runtime error:", c.message);
|
|
853
853
|
}
|
|
854
854
|
return {
|
|
855
855
|
configDirty: this._configProxy.__dirty,
|
|
@@ -861,7 +861,7 @@ return function(__deltaTime, __time, __currentFrame, __totalFrames, __particles,
|
|
|
861
861
|
*/
|
|
862
862
|
snapshotConfig(t) {
|
|
863
863
|
const e = {};
|
|
864
|
-
for (const i of
|
|
864
|
+
for (const i of Ze) {
|
|
865
865
|
const s = t[i];
|
|
866
866
|
s !== void 0 && (e[i] = Array.isArray(s) ? [...s] : s);
|
|
867
867
|
}
|
|
@@ -872,7 +872,7 @@ return function(__deltaTime, __time, __currentFrame, __totalFrames, __particles,
|
|
|
872
872
|
*/
|
|
873
873
|
restoreConfig(t) {
|
|
874
874
|
if (this._configSnapshot) {
|
|
875
|
-
for (const e of
|
|
875
|
+
for (const e of Ze)
|
|
876
876
|
if (e in this._configSnapshot) {
|
|
877
877
|
const i = this._configSnapshot[e];
|
|
878
878
|
t[e] = Array.isArray(i) ? [...i] : i;
|
|
@@ -886,315 +886,315 @@ return function(__deltaTime, __time, __currentFrame, __totalFrames, __particles,
|
|
|
886
886
|
this._fn = null, this._particles = null, this._configProxy = null, this._configSnapshot = null;
|
|
887
887
|
}
|
|
888
888
|
}
|
|
889
|
-
async function
|
|
890
|
-
const t = new DataView(
|
|
889
|
+
async function gi(r) {
|
|
890
|
+
const t = new DataView(r);
|
|
891
891
|
if (t.getUint32(0, !0) !== 1179937895)
|
|
892
892
|
throw new Error("Invalid GLB file: incorrect magic number");
|
|
893
893
|
const i = t.getUint32(4, !0);
|
|
894
894
|
if (i !== 2)
|
|
895
895
|
throw new Error(`Unsupported GLB version: ${i} (only version 2 is supported)`);
|
|
896
896
|
const s = t.getUint32(8, !0);
|
|
897
|
-
let
|
|
898
|
-
for (;
|
|
899
|
-
const
|
|
900
|
-
if (
|
|
901
|
-
const
|
|
902
|
-
|
|
903
|
-
} else
|
|
904
|
-
|
|
897
|
+
let n = 12, o = null, a = null;
|
|
898
|
+
for (; n < s; ) {
|
|
899
|
+
const P = t.getUint32(n, !0), _ = t.getUint32(n + 4, !0), T = r.slice(n + 8, n + 8 + P);
|
|
900
|
+
if (_ === 1313821514) {
|
|
901
|
+
const N = new TextDecoder("utf-8").decode(T);
|
|
902
|
+
o = JSON.parse(N);
|
|
903
|
+
} else _ === 5130562 && (a = T);
|
|
904
|
+
n += 8 + P;
|
|
905
905
|
}
|
|
906
|
-
if (!
|
|
906
|
+
if (!o)
|
|
907
907
|
throw new Error("GLB file missing JSON chunk");
|
|
908
|
-
if (!
|
|
908
|
+
if (!o.meshes || o.meshes.length === 0)
|
|
909
909
|
throw new Error("GLB file contains no meshes");
|
|
910
|
-
const l =
|
|
910
|
+
const l = o.meshes[0].primitives[0];
|
|
911
911
|
if (!l)
|
|
912
912
|
throw new Error("First mesh has no primitives");
|
|
913
|
-
const
|
|
914
|
-
if (
|
|
913
|
+
const u = l.attributes.POSITION;
|
|
914
|
+
if (u === void 0)
|
|
915
915
|
throw new Error("Mesh primitive missing POSITION attribute");
|
|
916
|
-
const
|
|
917
|
-
let
|
|
916
|
+
const f = gt(o, a, u, 3, 5126);
|
|
917
|
+
let h;
|
|
918
918
|
if (l.attributes.NORMAL !== void 0)
|
|
919
|
-
|
|
919
|
+
h = gt(o, a, l.attributes.NORMAL, 3, 5126);
|
|
920
920
|
else {
|
|
921
|
-
const
|
|
922
|
-
if (
|
|
921
|
+
const P = l.indices;
|
|
922
|
+
if (P === void 0)
|
|
923
923
|
throw new Error("Cannot generate normals without indices");
|
|
924
|
-
const
|
|
925
|
-
|
|
924
|
+
const _ = ri(o, a, P);
|
|
925
|
+
h = gs(f, _);
|
|
926
926
|
}
|
|
927
|
-
const
|
|
928
|
-
if (
|
|
927
|
+
const m = l.indices;
|
|
928
|
+
if (m === void 0)
|
|
929
929
|
throw new Error("Mesh primitive missing indices");
|
|
930
|
-
const
|
|
931
|
-
let
|
|
932
|
-
l.attributes.TEXCOORD_0 !== void 0 && (
|
|
933
|
-
let
|
|
934
|
-
if (
|
|
935
|
-
const
|
|
936
|
-
|
|
937
|
-
}
|
|
938
|
-
let
|
|
939
|
-
if (
|
|
930
|
+
const S = ri(o, a, m), R = f.length / 3, D = S.length;
|
|
931
|
+
let C = null;
|
|
932
|
+
l.attributes.TEXCOORD_0 !== void 0 && (C = gt(o, a, l.attributes.TEXCOORD_0, 2, 5126));
|
|
933
|
+
let B = !1;
|
|
934
|
+
if (o.materials && o.materials.length > 0) {
|
|
935
|
+
const P = o.materials[0];
|
|
936
|
+
P.pbrMetallicRoughness && P.pbrMetallicRoughness.baseColorTexture !== void 0 && (B = !0);
|
|
937
|
+
}
|
|
938
|
+
let A = null;
|
|
939
|
+
if (o.skins && o.skins.length > 0)
|
|
940
940
|
try {
|
|
941
|
-
|
|
942
|
-
} catch (
|
|
943
|
-
console.warn("Failed to extract animation data:",
|
|
941
|
+
A = _s(o, a, l), console.log("Animation data extracted:", A);
|
|
942
|
+
} catch (P) {
|
|
943
|
+
console.warn("Failed to extract animation data:", P);
|
|
944
944
|
}
|
|
945
945
|
return {
|
|
946
|
-
positions:
|
|
947
|
-
normals:
|
|
948
|
-
indices:
|
|
949
|
-
texCoords:
|
|
950
|
-
vertexCount:
|
|
951
|
-
indexCount:
|
|
952
|
-
animationData:
|
|
953
|
-
hasBaseColorTexture:
|
|
946
|
+
positions: f,
|
|
947
|
+
normals: h,
|
|
948
|
+
indices: S,
|
|
949
|
+
texCoords: C,
|
|
950
|
+
vertexCount: R,
|
|
951
|
+
indexCount: D,
|
|
952
|
+
animationData: A,
|
|
953
|
+
hasBaseColorTexture: B
|
|
954
954
|
};
|
|
955
955
|
}
|
|
956
|
-
function
|
|
957
|
-
const
|
|
956
|
+
function gt(r, t, e, i, s) {
|
|
957
|
+
const n = r.accessors[e], a = {
|
|
958
958
|
SCALAR: 1,
|
|
959
959
|
VEC2: 2,
|
|
960
960
|
VEC3: 3,
|
|
961
961
|
VEC4: 4
|
|
962
|
-
}[
|
|
963
|
-
if (
|
|
964
|
-
throw new Error(`Attribute accessor type mismatch: expected ${i} components, got ${
|
|
965
|
-
if (
|
|
966
|
-
throw new Error(`Attribute component type mismatch: expected ${s}, got ${
|
|
967
|
-
const l = (
|
|
968
|
-
for (let
|
|
969
|
-
|
|
970
|
-
return
|
|
962
|
+
}[n.type];
|
|
963
|
+
if (a !== i)
|
|
964
|
+
throw new Error(`Attribute accessor type mismatch: expected ${i} components, got ${a}`);
|
|
965
|
+
if (n.componentType !== s)
|
|
966
|
+
throw new Error(`Attribute component type mismatch: expected ${s}, got ${n.componentType}`);
|
|
967
|
+
const l = (r.bufferViews[n.bufferView].byteOffset || 0) + (n.byteOffset || 0), u = n.count, f = new DataView(t, l, u * i * 4), h = new Float32Array(u * i);
|
|
968
|
+
for (let m = 0; m < u * i; m++)
|
|
969
|
+
h[m] = f.getFloat32(m * 4, !0);
|
|
970
|
+
return h;
|
|
971
971
|
}
|
|
972
|
-
function
|
|
973
|
-
const i =
|
|
972
|
+
function ri(r, t, e) {
|
|
973
|
+
const i = r.accessors[e];
|
|
974
974
|
if (i.type !== "SCALAR")
|
|
975
975
|
throw new Error(`Indices accessor must be SCALAR, got ${i.type}`);
|
|
976
|
-
const
|
|
976
|
+
const n = (r.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0), o = i.count;
|
|
977
977
|
if (i.componentType === 5123) {
|
|
978
|
-
const
|
|
979
|
-
for (let l = 0; l <
|
|
980
|
-
|
|
981
|
-
return
|
|
978
|
+
const a = new DataView(t, n, o * 2), c = new Uint16Array(o);
|
|
979
|
+
for (let l = 0; l < o; l++)
|
|
980
|
+
c[l] = a.getUint16(l * 2, !0);
|
|
981
|
+
return c;
|
|
982
982
|
} else if (i.componentType === 5125) {
|
|
983
|
-
const
|
|
984
|
-
for (let l = 0; l <
|
|
985
|
-
|
|
986
|
-
return
|
|
983
|
+
const a = new DataView(t, n, o * 4), c = new Uint32Array(o);
|
|
984
|
+
for (let l = 0; l < o; l++)
|
|
985
|
+
c[l] = a.getUint32(l * 4, !0);
|
|
986
|
+
return c;
|
|
987
987
|
} else
|
|
988
988
|
throw new Error(`Unsupported index component type: ${i.componentType}`);
|
|
989
989
|
}
|
|
990
|
-
function
|
|
991
|
-
const e = new Float32Array(
|
|
990
|
+
function gs(r, t) {
|
|
991
|
+
const e = new Float32Array(r.length);
|
|
992
992
|
for (let i = 0; i < t.length; i += 3) {
|
|
993
|
-
const s = t[i] * 3,
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
],
|
|
998
|
-
|
|
993
|
+
const s = t[i] * 3, n = t[i + 1] * 3, o = t[i + 2] * 3, a = [r[s], r[s + 1], r[s + 2]], c = [r[n], r[n + 1], r[n + 2]], l = [r[o], r[o + 1], r[o + 2]], u = [c[0] - a[0], c[1] - a[1], c[2] - a[2]], f = [l[0] - a[0], l[1] - a[1], l[2] - a[2]], h = [
|
|
994
|
+
u[1] * f[2] - u[2] * f[1],
|
|
995
|
+
u[2] * f[0] - u[0] * f[2],
|
|
996
|
+
u[0] * f[1] - u[1] * f[0]
|
|
997
|
+
], m = Math.sqrt(h[0] * h[0] + h[1] * h[1] + h[2] * h[2]);
|
|
998
|
+
m > 0 && (h[0] /= m, h[1] /= m, h[2] /= m), e[s] = e[n] = e[o] = h[0], e[s + 1] = e[n + 1] = e[o + 1] = h[1], e[s + 2] = e[n + 2] = e[o + 2] = h[2];
|
|
999
999
|
}
|
|
1000
1000
|
return e;
|
|
1001
1001
|
}
|
|
1002
|
-
function
|
|
1003
|
-
const i =
|
|
1002
|
+
function bs(r, t, e) {
|
|
1003
|
+
const i = r.accessors[e];
|
|
1004
1004
|
if (i.type !== "VEC4")
|
|
1005
1005
|
throw new Error(`JOINTS_0 must be VEC4, got ${i.type}`);
|
|
1006
|
-
const
|
|
1006
|
+
const n = (r.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0), o = i.count;
|
|
1007
1007
|
if (i.componentType === 5121) {
|
|
1008
|
-
const
|
|
1009
|
-
for (let l = 0; l <
|
|
1010
|
-
|
|
1011
|
-
return
|
|
1008
|
+
const a = new DataView(t, n, o * 4), c = new Uint8Array(o * 4);
|
|
1009
|
+
for (let l = 0; l < o * 4; l++)
|
|
1010
|
+
c[l] = a.getUint8(l);
|
|
1011
|
+
return c;
|
|
1012
1012
|
} else if (i.componentType === 5123) {
|
|
1013
|
-
const
|
|
1014
|
-
for (let l = 0; l <
|
|
1015
|
-
|
|
1016
|
-
return
|
|
1013
|
+
const a = new DataView(t, n, o * 8), c = new Uint8Array(o * 4);
|
|
1014
|
+
for (let l = 0; l < o * 4; l++)
|
|
1015
|
+
c[l] = a.getUint16(l * 2, !0);
|
|
1016
|
+
return c;
|
|
1017
1017
|
} else
|
|
1018
1018
|
throw new Error(`Unsupported JOINTS_0 component type: ${i.componentType}`);
|
|
1019
1019
|
}
|
|
1020
|
-
function
|
|
1021
|
-
const i =
|
|
1020
|
+
function Ss(r, t, e) {
|
|
1021
|
+
const i = r.accessors[e];
|
|
1022
1022
|
if (i.type !== "VEC4")
|
|
1023
1023
|
throw new Error(`WEIGHTS_0 must be VEC4, got ${i.type}`);
|
|
1024
|
-
const
|
|
1024
|
+
const n = (r.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0), o = i.count;
|
|
1025
1025
|
if (i.componentType === 5126) {
|
|
1026
|
-
const
|
|
1027
|
-
for (let l = 0; l <
|
|
1028
|
-
|
|
1029
|
-
return
|
|
1026
|
+
const a = new DataView(t, n, o * 16), c = new Float32Array(o * 4);
|
|
1027
|
+
for (let l = 0; l < o * 4; l++)
|
|
1028
|
+
c[l] = a.getFloat32(l * 4, !0);
|
|
1029
|
+
return c;
|
|
1030
1030
|
} else if (i.componentType === 5121) {
|
|
1031
|
-
const
|
|
1032
|
-
for (let l = 0; l <
|
|
1033
|
-
|
|
1034
|
-
return
|
|
1031
|
+
const a = new DataView(t, n, o * 4), c = new Float32Array(o * 4);
|
|
1032
|
+
for (let l = 0; l < o * 4; l++)
|
|
1033
|
+
c[l] = a.getUint8(l) / 255;
|
|
1034
|
+
return c;
|
|
1035
1035
|
} else
|
|
1036
1036
|
throw new Error(`Unsupported WEIGHTS_0 component type: ${i.componentType}`);
|
|
1037
1037
|
}
|
|
1038
|
-
function
|
|
1039
|
-
const i =
|
|
1038
|
+
function xs(r, t, e) {
|
|
1039
|
+
const i = r.accessors[e];
|
|
1040
1040
|
if (i.type !== "MAT4")
|
|
1041
1041
|
throw new Error(`Expected MAT4, got ${i.type}`);
|
|
1042
1042
|
if (i.componentType !== 5126)
|
|
1043
1043
|
throw new Error(`Expected FLOAT component type for MAT4, got ${i.componentType}`);
|
|
1044
|
-
const
|
|
1045
|
-
for (let l = 0; l <
|
|
1046
|
-
|
|
1047
|
-
return
|
|
1044
|
+
const n = (r.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0), o = i.count, a = new DataView(t, n, o * 64), c = new Float32Array(o * 16);
|
|
1045
|
+
for (let l = 0; l < o * 16; l++)
|
|
1046
|
+
c[l] = a.getFloat32(l * 4, !0);
|
|
1047
|
+
return c;
|
|
1048
1048
|
}
|
|
1049
|
-
function
|
|
1050
|
-
const i =
|
|
1049
|
+
function vs(r, t, e) {
|
|
1050
|
+
const i = r.accessors[e];
|
|
1051
1051
|
if (i.type !== "SCALAR")
|
|
1052
1052
|
throw new Error(`Expected SCALAR, got ${i.type}`);
|
|
1053
1053
|
if (i.componentType !== 5126)
|
|
1054
1054
|
throw new Error(`Expected FLOAT component type for SCALAR, got ${i.componentType}`);
|
|
1055
|
-
const
|
|
1056
|
-
for (let l = 0; l <
|
|
1057
|
-
|
|
1058
|
-
return
|
|
1055
|
+
const n = (r.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0), o = i.count, a = new DataView(t, n, o * 4), c = new Float32Array(o);
|
|
1056
|
+
for (let l = 0; l < o; l++)
|
|
1057
|
+
c[l] = a.getFloat32(l * 4, !0);
|
|
1058
|
+
return c;
|
|
1059
1059
|
}
|
|
1060
|
-
function
|
|
1061
|
-
const i =
|
|
1062
|
-
if (!
|
|
1060
|
+
function Ps(r, t, e) {
|
|
1061
|
+
const i = r.accessors[e], n = { VEC3: 3, VEC4: 4 }[i.type];
|
|
1062
|
+
if (!n)
|
|
1063
1063
|
throw new Error(`Expected VEC3 or VEC4, got ${i.type}`);
|
|
1064
1064
|
if (i.componentType !== 5126)
|
|
1065
1065
|
throw new Error(`Expected FLOAT component type, got ${i.componentType}`);
|
|
1066
|
-
const
|
|
1067
|
-
for (let
|
|
1068
|
-
|
|
1069
|
-
return
|
|
1066
|
+
const a = (r.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0), c = i.count, l = new DataView(t, a, c * n * 4), u = new Float32Array(c * n);
|
|
1067
|
+
for (let f = 0; f < c * n; f++)
|
|
1068
|
+
u[f] = l.getFloat32(f * 4, !0);
|
|
1069
|
+
return u;
|
|
1070
1070
|
}
|
|
1071
|
-
function
|
|
1072
|
-
const i =
|
|
1073
|
-
if (!
|
|
1071
|
+
function _s(r, t, e) {
|
|
1072
|
+
const i = r.skins[0], s = i.joints, n = xs(r, t, i.inverseBindMatrices), o = e.attributes.JOINTS_0 !== void 0 ? bs(r, t, e.attributes.JOINTS_0) : null, a = e.attributes.WEIGHTS_0 !== void 0 ? Ss(r, t, e.attributes.WEIGHTS_0) : null;
|
|
1073
|
+
if (!o || !a)
|
|
1074
1074
|
throw new Error("Mesh missing JOINTS_0 or WEIGHTS_0 attributes");
|
|
1075
|
-
const
|
|
1076
|
-
translation:
|
|
1077
|
-
rotation:
|
|
1078
|
-
scale:
|
|
1079
|
-
children:
|
|
1080
|
-
name:
|
|
1075
|
+
const c = r.nodes.map((u) => ({
|
|
1076
|
+
translation: u.translation || [0, 0, 0],
|
|
1077
|
+
rotation: u.rotation || [0, 0, 0, 1],
|
|
1078
|
+
scale: u.scale || [1, 1, 1],
|
|
1079
|
+
children: u.children || [],
|
|
1080
|
+
name: u.name || ""
|
|
1081
1081
|
})), l = [];
|
|
1082
|
-
if (
|
|
1083
|
-
for (const
|
|
1084
|
-
const
|
|
1085
|
-
let
|
|
1086
|
-
for (const
|
|
1087
|
-
const
|
|
1088
|
-
|
|
1089
|
-
targetNode:
|
|
1090
|
-
targetPath:
|
|
1091
|
-
interpolation:
|
|
1092
|
-
timestamps:
|
|
1093
|
-
values:
|
|
1082
|
+
if (r.animations && r.animations.length > 0)
|
|
1083
|
+
for (const u of r.animations) {
|
|
1084
|
+
const f = [];
|
|
1085
|
+
let h = 0;
|
|
1086
|
+
for (const m of u.channels) {
|
|
1087
|
+
const S = u.samplers[m.sampler], R = vs(r, t, S.input), D = Ps(r, t, S.output), C = R[R.length - 1];
|
|
1088
|
+
C > h && (h = C), f.push({
|
|
1089
|
+
targetNode: m.target.node,
|
|
1090
|
+
targetPath: m.target.path,
|
|
1091
|
+
interpolation: S.interpolation || "LINEAR",
|
|
1092
|
+
timestamps: R,
|
|
1093
|
+
values: D
|
|
1094
1094
|
});
|
|
1095
1095
|
}
|
|
1096
1096
|
l.push({
|
|
1097
|
-
name:
|
|
1098
|
-
duration:
|
|
1099
|
-
channels:
|
|
1097
|
+
name: u.name || `Animation ${l.length}`,
|
|
1098
|
+
duration: h,
|
|
1099
|
+
channels: f
|
|
1100
1100
|
});
|
|
1101
1101
|
}
|
|
1102
1102
|
return {
|
|
1103
1103
|
joints: s,
|
|
1104
|
-
inverseBindMatrices:
|
|
1105
|
-
jointIndices:
|
|
1106
|
-
jointWeights:
|
|
1107
|
-
nodes:
|
|
1104
|
+
inverseBindMatrices: n,
|
|
1105
|
+
jointIndices: o,
|
|
1106
|
+
jointWeights: a,
|
|
1107
|
+
nodes: c,
|
|
1108
1108
|
animations: l
|
|
1109
1109
|
};
|
|
1110
1110
|
}
|
|
1111
|
-
async function
|
|
1112
|
-
const t = new DataView(
|
|
1111
|
+
async function ws(r) {
|
|
1112
|
+
const t = new DataView(r);
|
|
1113
1113
|
if (t.getUint32(0, !0) !== 1179937895)
|
|
1114
1114
|
throw new Error("Invalid GLB file: incorrect magic number");
|
|
1115
1115
|
const i = t.getUint32(4, !0);
|
|
1116
1116
|
if (i !== 2)
|
|
1117
1117
|
throw new Error(`Unsupported GLB version: ${i}`);
|
|
1118
1118
|
const s = t.getUint32(8, !0);
|
|
1119
|
-
let
|
|
1120
|
-
for (;
|
|
1121
|
-
const
|
|
1122
|
-
if (
|
|
1123
|
-
const
|
|
1124
|
-
|
|
1125
|
-
} else
|
|
1126
|
-
|
|
1119
|
+
let n = 12, o = null, a = null;
|
|
1120
|
+
for (; n < s; ) {
|
|
1121
|
+
const A = t.getUint32(n, !0), P = t.getUint32(n + 4, !0), _ = r.slice(n + 8, n + 8 + A);
|
|
1122
|
+
if (P === 1313821514) {
|
|
1123
|
+
const L = new TextDecoder("utf-8").decode(_);
|
|
1124
|
+
o = JSON.parse(L);
|
|
1125
|
+
} else P === 5130562 && (a = _);
|
|
1126
|
+
n += 8 + A;
|
|
1127
1127
|
}
|
|
1128
|
-
if (!
|
|
1128
|
+
if (!o)
|
|
1129
1129
|
throw new Error("GLB file missing JSON chunk");
|
|
1130
|
-
if (!
|
|
1130
|
+
if (!o.materials || o.materials.length === 0)
|
|
1131
1131
|
return null;
|
|
1132
|
-
const
|
|
1133
|
-
if (!
|
|
1132
|
+
const c = o.materials[0];
|
|
1133
|
+
if (!c.pbrMetallicRoughness || c.pbrMetallicRoughness.baseColorTexture === void 0)
|
|
1134
1134
|
return null;
|
|
1135
|
-
const l =
|
|
1136
|
-
if (!
|
|
1135
|
+
const l = c.pbrMetallicRoughness.baseColorTexture.index;
|
|
1136
|
+
if (!o.textures || !o.textures[l])
|
|
1137
1137
|
return null;
|
|
1138
|
-
const
|
|
1139
|
-
if (
|
|
1138
|
+
const f = o.textures[l].source;
|
|
1139
|
+
if (f === void 0 || !o.images || !o.images[f])
|
|
1140
1140
|
return null;
|
|
1141
|
-
const
|
|
1142
|
-
if (
|
|
1141
|
+
const h = o.images[f], m = h.mimeType || "image/png";
|
|
1142
|
+
if (h.bufferView === void 0)
|
|
1143
1143
|
return null;
|
|
1144
|
-
if (!
|
|
1144
|
+
if (!a)
|
|
1145
1145
|
throw new Error("GLB file missing BIN chunk (required for embedded textures)");
|
|
1146
|
-
const
|
|
1147
|
-
return { imageBlob: new Blob([
|
|
1146
|
+
const S = o.bufferViews[h.bufferView], R = S.byteOffset || 0, D = S.byteLength, C = a.slice(R, R + D);
|
|
1147
|
+
return { imageBlob: new Blob([C], { type: m }), mimeType: m };
|
|
1148
1148
|
}
|
|
1149
|
-
const
|
|
1149
|
+
const ni = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1150
1150
|
__proto__: null,
|
|
1151
|
-
extractGLBTexture:
|
|
1152
|
-
parseGLB:
|
|
1151
|
+
extractGLBTexture: ws,
|
|
1152
|
+
parseGLB: gi
|
|
1153
1153
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1154
|
-
function
|
|
1154
|
+
function ai(r, t, e) {
|
|
1155
1155
|
return [
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1156
|
+
r[0] + (t[0] - r[0]) * e,
|
|
1157
|
+
r[1] + (t[1] - r[1]) * e,
|
|
1158
|
+
r[2] + (t[2] - r[2]) * e
|
|
1159
1159
|
];
|
|
1160
1160
|
}
|
|
1161
|
-
function
|
|
1162
|
-
let i =
|
|
1161
|
+
function oi(r, t, e) {
|
|
1162
|
+
let i = r[0] * t[0] + r[1] * t[1] + r[2] * t[2] + r[3] * t[3], s = t;
|
|
1163
1163
|
if (i < 0 && (i = -i, s = [-t[0], -t[1], -t[2], -t[3]]), i > 0.9995) {
|
|
1164
1164
|
const l = [
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1165
|
+
r[0] + (s[0] - r[0]) * e,
|
|
1166
|
+
r[1] + (s[1] - r[1]) * e,
|
|
1167
|
+
r[2] + (s[2] - r[2]) * e,
|
|
1168
|
+
r[3] + (s[3] - r[3]) * e
|
|
1169
1169
|
];
|
|
1170
|
-
return
|
|
1170
|
+
return Bs(l);
|
|
1171
1171
|
}
|
|
1172
|
-
const
|
|
1172
|
+
const n = Math.acos(i), o = Math.sin(n), a = Math.sin((1 - e) * n) / o, c = Math.sin(e * n) / o;
|
|
1173
1173
|
return [
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1174
|
+
r[0] * a + s[0] * c,
|
|
1175
|
+
r[1] * a + s[1] * c,
|
|
1176
|
+
r[2] * a + s[2] * c,
|
|
1177
|
+
r[3] * a + s[3] * c
|
|
1178
1178
|
];
|
|
1179
1179
|
}
|
|
1180
|
-
function
|
|
1181
|
-
const t = Math.sqrt(
|
|
1182
|
-
return t > 1e-4 ? [
|
|
1180
|
+
function Bs(r) {
|
|
1181
|
+
const t = Math.sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2] + r[3] * r[3]);
|
|
1182
|
+
return t > 1e-4 ? [r[0] / t, r[1] / t, r[2] / t, r[3] / t] : [0, 0, 0, 1];
|
|
1183
1183
|
}
|
|
1184
|
-
function
|
|
1185
|
-
const t =
|
|
1184
|
+
function Rs(r) {
|
|
1185
|
+
const t = r[0], e = r[1], i = r[2], s = r[3], n = t + t, o = e + e, a = i + i, c = t * n, l = t * o, u = t * a, f = e * o, h = e * a, m = i * a, S = s * n, R = s * o, D = s * a;
|
|
1186
1186
|
return new Float32Array([
|
|
1187
|
-
1 - (
|
|
1188
|
-
l +
|
|
1189
|
-
|
|
1187
|
+
1 - (f + m),
|
|
1188
|
+
l + D,
|
|
1189
|
+
u - R,
|
|
1190
1190
|
0,
|
|
1191
|
-
l -
|
|
1192
|
-
1 - (
|
|
1193
|
-
|
|
1191
|
+
l - D,
|
|
1192
|
+
1 - (c + m),
|
|
1193
|
+
h + S,
|
|
1194
1194
|
0,
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
1 - (
|
|
1195
|
+
u + R,
|
|
1196
|
+
h - S,
|
|
1197
|
+
1 - (c + f),
|
|
1198
1198
|
0,
|
|
1199
1199
|
0,
|
|
1200
1200
|
0,
|
|
@@ -1202,8 +1202,8 @@ function he(c) {
|
|
|
1202
1202
|
1
|
|
1203
1203
|
]);
|
|
1204
1204
|
}
|
|
1205
|
-
function
|
|
1206
|
-
const i =
|
|
1205
|
+
function Ms(r, t, e) {
|
|
1206
|
+
const i = Rs(t);
|
|
1207
1207
|
return new Float32Array([
|
|
1208
1208
|
i[0] * e[0],
|
|
1209
1209
|
i[1] * e[0],
|
|
@@ -1217,20 +1217,20 @@ function pe(c, t, e) {
|
|
|
1217
1217
|
i[9] * e[2],
|
|
1218
1218
|
i[10] * e[2],
|
|
1219
1219
|
0,
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1220
|
+
r[0],
|
|
1221
|
+
r[1],
|
|
1222
|
+
r[2],
|
|
1223
1223
|
1
|
|
1224
1224
|
]);
|
|
1225
1225
|
}
|
|
1226
|
-
function
|
|
1226
|
+
function li(r, t) {
|
|
1227
1227
|
const e = new Float32Array(16);
|
|
1228
1228
|
for (let i = 0; i < 4; i++)
|
|
1229
1229
|
for (let s = 0; s < 4; s++)
|
|
1230
|
-
e[i * 4 + s] =
|
|
1230
|
+
e[i * 4 + s] = r[0 + s] * t[i * 4 + 0] + r[4 + s] * t[i * 4 + 1] + r[8 + s] * t[i * 4 + 2] + r[12 + s] * t[i * 4 + 3];
|
|
1231
1231
|
return e;
|
|
1232
1232
|
}
|
|
1233
|
-
class
|
|
1233
|
+
class Ts {
|
|
1234
1234
|
constructor(t) {
|
|
1235
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);
|
|
1236
1236
|
for (let e = 0; e < this.nodes.length; e++)
|
|
@@ -1254,33 +1254,33 @@ class me {
|
|
|
1254
1254
|
async initGPUSkinning(t, e, i) {
|
|
1255
1255
|
try {
|
|
1256
1256
|
this._gpuDevice = t, this._gpuOutputBuffer = e;
|
|
1257
|
-
const s = this.restPositions.length / 3,
|
|
1257
|
+
const s = this.restPositions.length / 3, n = new Float32Array(s * 8);
|
|
1258
1258
|
for (let l = 0; l < s; l++) {
|
|
1259
|
-
const
|
|
1260
|
-
|
|
1259
|
+
const u = l * 8, f = l * 3, h = l * 2;
|
|
1260
|
+
n[u] = this.restPositions[f], n[u + 1] = this.restPositions[f + 1], n[u + 2] = this.restPositions[f + 2], n[u + 3] = this.restNormals[f], n[u + 4] = this.restNormals[f + 1], n[u + 5] = this.restNormals[f + 2], n[u + 6] = i ? i[h] : 0, n[u + 7] = i ? i[h + 1] : 0;
|
|
1261
1261
|
}
|
|
1262
1262
|
this._gpuRestDataBuffer = t.createBuffer({
|
|
1263
|
-
size:
|
|
1263
|
+
size: n.byteLength,
|
|
1264
1264
|
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
|
|
1265
1265
|
label: "skinning_restData"
|
|
1266
|
-
}), t.queue.writeBuffer(this._gpuRestDataBuffer, 0,
|
|
1266
|
+
}), t.queue.writeBuffer(this._gpuRestDataBuffer, 0, n), this._gpuJointWeightsBuffer = t.createBuffer({
|
|
1267
1267
|
size: this.jointWeights.byteLength,
|
|
1268
1268
|
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
|
|
1269
1269
|
label: "skinning_jointWeights"
|
|
1270
1270
|
}), t.queue.writeBuffer(this._gpuJointWeightsBuffer, 0, this.jointWeights);
|
|
1271
|
-
const
|
|
1271
|
+
const o = new Uint32Array(this.jointIndices.length);
|
|
1272
1272
|
for (let l = 0; l < this.jointIndices.length; l++)
|
|
1273
|
-
|
|
1273
|
+
o[l] = this.jointIndices[l];
|
|
1274
1274
|
this._gpuJointIndicesBuffer = t.createBuffer({
|
|
1275
|
-
size:
|
|
1275
|
+
size: o.byteLength,
|
|
1276
1276
|
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
|
|
1277
1277
|
label: "skinning_jointIndices"
|
|
1278
|
-
}), t.queue.writeBuffer(this._gpuJointIndicesBuffer, 0,
|
|
1278
|
+
}), t.queue.writeBuffer(this._gpuJointIndicesBuffer, 0, o), this._gpuJointMatricesBuffer = t.createBuffer({
|
|
1279
1279
|
size: this.joints.length * 16 * 4,
|
|
1280
1280
|
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
|
|
1281
1281
|
label: "skinning_jointMatrices"
|
|
1282
1282
|
}), this._gpuJointMatricesData = new Float32Array(this.joints.length * 16);
|
|
1283
|
-
const { skinningComputeShader:
|
|
1283
|
+
const { skinningComputeShader: a } = await Promise.resolve().then(() => _i), c = t.createBindGroupLayout({
|
|
1284
1284
|
entries: [
|
|
1285
1285
|
{ binding: 0, visibility: GPUShaderStage.COMPUTE, buffer: { type: "read-only-storage" } },
|
|
1286
1286
|
{ binding: 1, visibility: GPUShaderStage.COMPUTE, buffer: { type: "read-only-storage" } },
|
|
@@ -1290,13 +1290,13 @@ class me {
|
|
|
1290
1290
|
]
|
|
1291
1291
|
});
|
|
1292
1292
|
this._gpuSkinningPipeline = t.createComputePipeline({
|
|
1293
|
-
layout: t.createPipelineLayout({ bindGroupLayouts: [
|
|
1293
|
+
layout: t.createPipelineLayout({ bindGroupLayouts: [c] }),
|
|
1294
1294
|
compute: {
|
|
1295
|
-
module: t.createShaderModule({ code:
|
|
1295
|
+
module: t.createShaderModule({ code: a }),
|
|
1296
1296
|
entryPoint: "main"
|
|
1297
1297
|
}
|
|
1298
1298
|
}), this._gpuSkinningBindGroup = t.createBindGroup({
|
|
1299
|
-
layout:
|
|
1299
|
+
layout: c,
|
|
1300
1300
|
entries: [
|
|
1301
1301
|
{ binding: 0, resource: { buffer: this._gpuRestDataBuffer } },
|
|
1302
1302
|
{ binding: 1, resource: { buffer: this._gpuJointWeightsBuffer } },
|
|
@@ -1356,37 +1356,37 @@ class me {
|
|
|
1356
1356
|
* Build topological order for node traversal (parent before child).
|
|
1357
1357
|
*/
|
|
1358
1358
|
_buildTopologicalOrder() {
|
|
1359
|
-
const t = /* @__PURE__ */ new Set(), e = [], i = (
|
|
1360
|
-
if (t.has(
|
|
1361
|
-
t.add(
|
|
1362
|
-
const
|
|
1363
|
-
for (const
|
|
1364
|
-
i(
|
|
1365
|
-
e.push(
|
|
1359
|
+
const t = /* @__PURE__ */ new Set(), e = [], i = (n) => {
|
|
1360
|
+
if (t.has(n)) return;
|
|
1361
|
+
t.add(n);
|
|
1362
|
+
const o = this.nodes[n];
|
|
1363
|
+
for (const a of o.children)
|
|
1364
|
+
i(a);
|
|
1365
|
+
e.push(n);
|
|
1366
1366
|
}, s = /* @__PURE__ */ new Set();
|
|
1367
|
-
for (const
|
|
1368
|
-
for (const
|
|
1369
|
-
s.add(
|
|
1370
|
-
for (let
|
|
1371
|
-
s.has(
|
|
1367
|
+
for (const n of this.nodes)
|
|
1368
|
+
for (const o of n.children)
|
|
1369
|
+
s.add(o);
|
|
1370
|
+
for (let n = 0; n < this.nodes.length; n++)
|
|
1371
|
+
s.has(n) || i(n);
|
|
1372
1372
|
this.topologicalOrder = e.reverse();
|
|
1373
1373
|
}
|
|
1374
1374
|
/**
|
|
1375
1375
|
* Sample a single channel at the given time.
|
|
1376
1376
|
*/
|
|
1377
1377
|
_sampleChannel(t, e) {
|
|
1378
|
-
const { timestamps: i, values: s, interpolation:
|
|
1378
|
+
const { timestamps: i, values: s, interpolation: n, targetPath: o } = t;
|
|
1379
1379
|
if (e <= i[0])
|
|
1380
|
-
return this._extractValue(s, 0,
|
|
1380
|
+
return this._extractValue(s, 0, o);
|
|
1381
1381
|
if (e >= i[i.length - 1])
|
|
1382
|
-
return this._extractValue(s, i.length - 1,
|
|
1383
|
-
let
|
|
1384
|
-
for (;
|
|
1385
|
-
const
|
|
1386
|
-
i[
|
|
1382
|
+
return this._extractValue(s, i.length - 1, o);
|
|
1383
|
+
let a = 0, c = i.length - 1;
|
|
1384
|
+
for (; c - a > 1; ) {
|
|
1385
|
+
const S = Math.floor((a + c) / 2);
|
|
1386
|
+
i[S] <= e ? a = S : c = S;
|
|
1387
1387
|
}
|
|
1388
|
-
const l = i[
|
|
1389
|
-
return
|
|
1388
|
+
const l = i[a], u = i[c], f = (e - l) / (u - l), h = this._extractValue(s, a, o), m = this._extractValue(s, c, o);
|
|
1389
|
+
return n === "STEP" ? h : o === "rotation" ? oi(h, m, f) : ai(h, m, f);
|
|
1390
1390
|
}
|
|
1391
1391
|
/**
|
|
1392
1392
|
* Extract value from values array at the given index.
|
|
@@ -1407,13 +1407,13 @@ class me {
|
|
|
1407
1407
|
const e = this.animations[this.currentAnimIndex];
|
|
1408
1408
|
for (let i = 0; i < this.nodes.length; i++) {
|
|
1409
1409
|
const s = this.nodes[i];
|
|
1410
|
-
let
|
|
1411
|
-
for (const
|
|
1412
|
-
if (
|
|
1413
|
-
const l = this._sampleChannel(
|
|
1414
|
-
|
|
1410
|
+
let n = s.translation, o = s.rotation, a = s.scale;
|
|
1411
|
+
for (const c of e.channels)
|
|
1412
|
+
if (c.targetNode === i) {
|
|
1413
|
+
const l = this._sampleChannel(c, t);
|
|
1414
|
+
c.targetPath === "translation" ? n = l : c.targetPath === "rotation" ? o = l : c.targetPath === "scale" && (a = l);
|
|
1415
1415
|
}
|
|
1416
|
-
this.jointLocalTransforms[i] =
|
|
1416
|
+
this.jointLocalTransforms[i] = Ms(n, o, a);
|
|
1417
1417
|
}
|
|
1418
1418
|
}
|
|
1419
1419
|
/**
|
|
@@ -1428,7 +1428,7 @@ class me {
|
|
|
1428
1428
|
}
|
|
1429
1429
|
for (const e of this.topologicalOrder) {
|
|
1430
1430
|
const i = t[e];
|
|
1431
|
-
i === -1 ? this.jointGlobalTransforms[e] = this.jointLocalTransforms[e] : this.jointGlobalTransforms[e] =
|
|
1431
|
+
i === -1 ? this.jointGlobalTransforms[e] = this.jointLocalTransforms[e] : this.jointGlobalTransforms[e] = li(
|
|
1432
1432
|
this.jointGlobalTransforms[i],
|
|
1433
1433
|
this.jointLocalTransforms[e]
|
|
1434
1434
|
);
|
|
@@ -1439,8 +1439,8 @@ class me {
|
|
|
1439
1439
|
*/
|
|
1440
1440
|
_computeFinalMatrices() {
|
|
1441
1441
|
for (let t = 0; t < this.joints.length; t++) {
|
|
1442
|
-
const e = this.joints[t], i = this.jointGlobalTransforms[e], s = t * 16,
|
|
1443
|
-
this.jointFinalMatrices[t] =
|
|
1442
|
+
const e = this.joints[t], i = this.jointGlobalTransforms[e], s = t * 16, n = this.inverseBindMatrices.slice(s, s + 16);
|
|
1443
|
+
this.jointFinalMatrices[t] = li(i, n);
|
|
1444
1444
|
}
|
|
1445
1445
|
}
|
|
1446
1446
|
/**
|
|
@@ -1448,30 +1448,30 @@ class me {
|
|
|
1448
1448
|
* Inlined math, no temporary array allocations.
|
|
1449
1449
|
*/
|
|
1450
1450
|
_applySkinning() {
|
|
1451
|
-
const t = this.restPositions.length / 3, e = this.restPositions, i = this.restNormals, s = this.skinnedPositions,
|
|
1451
|
+
const t = this.restPositions.length / 3, e = this.restPositions, i = this.restNormals, s = this.skinnedPositions, n = this.skinnedNormals, o = this.jointWeights, a = this.jointIndices, c = this.jointFinalMatrices;
|
|
1452
1452
|
for (let l = 0; l < t; l++) {
|
|
1453
|
-
const
|
|
1454
|
-
let
|
|
1455
|
-
for (let
|
|
1456
|
-
const
|
|
1457
|
-
if (
|
|
1458
|
-
const
|
|
1459
|
-
|
|
1453
|
+
const u = l * 3, f = l * 4, h = e[u], m = e[u + 1], S = e[u + 2], R = i[u], D = i[u + 1], C = i[u + 2];
|
|
1454
|
+
let B = 0, A = 0, P = 0, _ = 0, T = 0, L = 0;
|
|
1455
|
+
for (let k = 0; k < 4; k++) {
|
|
1456
|
+
const X = o[f + k];
|
|
1457
|
+
if (X === 0) continue;
|
|
1458
|
+
const z = c[a[f + k]];
|
|
1459
|
+
B += (z[0] * h + z[4] * m + z[8] * S + z[12]) * X, A += (z[1] * h + z[5] * m + z[9] * S + z[13]) * X, P += (z[2] * h + z[6] * m + z[10] * S + z[14]) * X, _ += (z[0] * R + z[4] * D + z[8] * C) * X, T += (z[1] * R + z[5] * D + z[9] * C) * X, L += (z[2] * R + z[6] * D + z[10] * C) * X;
|
|
1460
1460
|
}
|
|
1461
|
-
const
|
|
1462
|
-
|
|
1461
|
+
const N = Math.sqrt(_ * _ + T * T + L * L);
|
|
1462
|
+
N > 1e-4 && (n[u] = _ / N, n[u + 1] = T / N, n[u + 2] = L / N), s[u] = B, s[u + 1] = A, s[u + 2] = P;
|
|
1463
1463
|
}
|
|
1464
1464
|
}
|
|
1465
1465
|
}
|
|
1466
|
-
function
|
|
1467
|
-
const t = atob(
|
|
1466
|
+
function ci(r) {
|
|
1467
|
+
const t = atob(r), e = new Uint8Array(t.length);
|
|
1468
1468
|
for (let i = 0; i < t.length; i++)
|
|
1469
1469
|
e[i] = t.charCodeAt(i);
|
|
1470
1470
|
return e.buffer;
|
|
1471
1471
|
}
|
|
1472
|
-
class
|
|
1472
|
+
class bt {
|
|
1473
1473
|
constructor(t, e) {
|
|
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({
|
|
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.destroyed = !1, this.particleData = new Float32Array(this.MAX_PARTICLES * 8), this.particleVelocities = new Float32Array(this.MAX_PARTICLES * 4), this.instanceBuffer = t.createBuffer({
|
|
1475
1475
|
size: this.MAX_PARTICLES * 8 * 4,
|
|
1476
1476
|
usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST | GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,
|
|
1477
1477
|
label: "particleInstanceBuffer"
|
|
@@ -1486,8 +1486,8 @@ class A {
|
|
|
1486
1486
|
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC,
|
|
1487
1487
|
label: "particleTrailBuffer"
|
|
1488
1488
|
}), this._trailResetData = new Float32Array(this.MAX_PARTICLES * 4), this.appearanceUniformBuffer = t.createBuffer({
|
|
1489
|
-
size:
|
|
1490
|
-
// appearance uniforms + pulse + GLB rotation + system offset + sim rotation
|
|
1489
|
+
size: 208,
|
|
1490
|
+
// appearance uniforms + pulse + GLB rotation + system offset + sim rotation + noise distortion
|
|
1491
1491
|
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
1492
1492
|
label: "appearanceUniformBuffer"
|
|
1493
1493
|
}), this.bloomIntensityBuffer = t.createBuffer({
|
|
@@ -1495,7 +1495,7 @@ class A {
|
|
|
1495
1495
|
// intensity (f32) + padding
|
|
1496
1496
|
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
1497
1497
|
label: "systemBloomIntensityBuffer"
|
|
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
|
|
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.rotation = (e.rotation || 0) + e.particleShapeRotation, delete e.particleShapeRotation), 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.1), 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.05), e.maxSize === void 0 && (e.maxSize = 0.15), 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.emissionDurationInfinite === void 0 && (e.emissionDurationInfinite = !1), e.emissionDuration > 300 && (e.emissionDurationInfinite = !0, e.emissionDuration = 10), e.outerLength === void 0 && (e.outerLength = e.cubeLength ?? 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.emissionPositionX === void 0 && (e.emissionPositionX = e.emissionTranslationX ?? 0), e.emissionPositionY === void 0 && (e.emissionPositionY = e.emissionTranslationY ?? 0), e.emissionPositionZ === void 0 && (e.emissionPositionZ = 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.blendMode === void 0 && (e.blendMode = "normal"), e.noiseDistortEnabled === void 0 && (e.noiseDistortEnabled = !1), e.noiseTilingX === void 0 && (e.noiseTilingX = 3), e.noiseTilingY === void 0 && (e.noiseTilingY = 3), e.noiseSpeed === void 0 && (e.noiseSpeed = -1.5), e.noiseAmplitude === void 0 && (e.noiseAmplitude = 0.08), 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.emissionTrailMode === void 0 && (e.emissionTrailMode = "ribbon"), 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(52), 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._emitSimRotY = 0, this.emitter = new cs(e), this.physics = new us(t, this.MAX_PARTICLES), this.textureManager = new ds(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({
|
|
1499
1499
|
enabled: !0,
|
|
1500
1500
|
shape: e.confinementShape,
|
|
1501
1501
|
mode: e.confinementMode,
|
|
@@ -1508,7 +1508,7 @@ class A {
|
|
|
1508
1508
|
enabled: !0,
|
|
1509
1509
|
strength: e.softBoundaryStrength,
|
|
1510
1510
|
falloff: e.softBoundaryFalloff
|
|
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
|
|
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 si(e.script, e, this.MAX_PARTICLES)), this.initComputePipeline(t);
|
|
1512
1512
|
}
|
|
1513
1513
|
async initComputePipeline(t) {
|
|
1514
1514
|
this.computeReady = await this.physics.initComputePipeline(this.instanceBuffer, this.velocityBuffer, this.trailBuffer);
|
|
@@ -1518,23 +1518,23 @@ class A {
|
|
|
1518
1518
|
* @param {string|null} source - Script source code, or null to disable
|
|
1519
1519
|
*/
|
|
1520
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
|
|
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 si(t, this.config, this.MAX_PARTICLES), this._particleScript.snapshotConfig(this.config)) : delete this.config.script;
|
|
1522
1522
|
}
|
|
1523
1523
|
async setTexture(t) {
|
|
1524
|
-
this.textureManager.destroyTexture(this.particleTexture), this.particleTexture = await this.textureManager.loadTexture(t), this.config.textureEnabled = !0, this.updateAppearanceUniform(), this.updateBuffers();
|
|
1524
|
+
this.destroyed || (this.textureManager.destroyTexture(this.particleTexture), this.particleTexture = await this.textureManager.loadTexture(t), this.config.textureEnabled = !0, this.updateAppearanceUniform(), this.updateBuffers());
|
|
1525
1525
|
}
|
|
1526
1526
|
resetTexture() {
|
|
1527
|
-
this.textureManager.destroyTexture(this.particleTexture), this.particleTexture = this.textureManager.getDefaultTexture(), this.config.textureEnabled = !1, this.updateAppearanceUniform(), this.updateBuffers();
|
|
1527
|
+
this.destroyed || (this.textureManager.destroyTexture(this.particleTexture), this.particleTexture = this.textureManager.getDefaultTexture(), this.config.textureEnabled = !1, this.updateAppearanceUniform(), this.updateBuffers());
|
|
1528
1528
|
}
|
|
1529
1529
|
async setGLBModel(t) {
|
|
1530
1530
|
try {
|
|
1531
1531
|
this.glbRawArrayBuffer = t;
|
|
1532
|
-
const e = await
|
|
1532
|
+
const e = await gi(t);
|
|
1533
1533
|
this.glbMeshData = e, this.config.glbHasTexture = e.hasBaseColorTexture || !1;
|
|
1534
1534
|
const i = new Float32Array(e.vertexCount * 8);
|
|
1535
1535
|
for (let s = 0; s < e.vertexCount; s++) {
|
|
1536
|
-
const
|
|
1537
|
-
i[
|
|
1536
|
+
const n = s * 8, o = s * 3, a = s * 2;
|
|
1537
|
+
i[n + 0] = e.positions[o + 0], i[n + 1] = e.positions[o + 1], i[n + 2] = e.positions[o + 2], i[n + 3] = e.normals[o + 0], i[n + 4] = e.normals[o + 1], i[n + 5] = e.normals[o + 2], e.texCoords ? (i[n + 6] = e.texCoords[a + 0], i[n + 7] = e.texCoords[a + 1]) : (i[n + 6] = 0, i[n + 7] = 0);
|
|
1538
1538
|
}
|
|
1539
1539
|
if (this.glbVertexBuffer && this.glbVertexBuffer.destroy(), this.glbIndexBuffer && this.glbIndexBuffer.destroy(), this.glbVertexBuffer = this.device.createBuffer({
|
|
1540
1540
|
size: i.byteLength,
|
|
@@ -1545,7 +1545,7 @@ class A {
|
|
|
1545
1545
|
usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST,
|
|
1546
1546
|
label: "glbIndexBuffer"
|
|
1547
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) {
|
|
1548
|
-
this.glbAnimator = new
|
|
1548
|
+
this.glbAnimator = new Ts(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);
|
|
1549
1549
|
try {
|
|
1550
1550
|
await this.glbAnimator.initGPUSkinning(this.device, this.glbVertexBuffer, e.texCoords);
|
|
1551
1551
|
} catch (s) {
|
|
@@ -1572,21 +1572,21 @@ class A {
|
|
|
1572
1572
|
*/
|
|
1573
1573
|
setSimulationTransform(t) {
|
|
1574
1574
|
if (t.position && (this._simPosition[0] = t.position[0], this._simPosition[1] = t.position[1], this._simPosition[2] = t.position[2]), t.rotation) {
|
|
1575
|
-
this._simRotX = t.rotation[0], this._simRotZ = t.rotation[1];
|
|
1576
|
-
const e = Math.cos(this._simRotX), i = Math.sin(this._simRotX), s = Math.cos(this._simRotZ),
|
|
1575
|
+
this._simRotX = t.rotation[0] || 0, this._simRotZ = t.rotation[1] || 0, this._simRotY = t.rotation[2] || 0;
|
|
1576
|
+
const e = Math.cos(this._simRotX), i = Math.sin(this._simRotX), s = Math.cos(this._simRotZ), n = Math.sin(this._simRotZ), o = Math.cos(this._simRotY), a = Math.sin(this._simRotY);
|
|
1577
1577
|
this._simRotMatrix = [
|
|
1578
|
-
s,
|
|
1579
|
-
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1578
|
+
o * s,
|
|
1579
|
+
-o * n * e + a * i,
|
|
1580
|
+
o * n * i + a * e,
|
|
1581
|
+
n,
|
|
1582
1582
|
s * e,
|
|
1583
1583
|
-s * i,
|
|
1584
|
-
|
|
1585
|
-
i,
|
|
1586
|
-
e
|
|
1584
|
+
-a * s,
|
|
1585
|
+
a * n * e + o * i,
|
|
1586
|
+
-a * n * i + o * e
|
|
1587
1587
|
];
|
|
1588
1588
|
} else
|
|
1589
|
-
this._simRotMatrix = null, this._simRotX = 0, this._simRotZ = 0;
|
|
1589
|
+
this._simRotMatrix = null, this._simRotX = 0, this._simRotZ = 0, this._simRotY = 0;
|
|
1590
1590
|
t.velocity && (this._simVelocity[0] = t.velocity[0], this._simVelocity[1] = t.velocity[1], this._simVelocity[2] = t.velocity[2]);
|
|
1591
1591
|
}
|
|
1592
1592
|
clearSimulationTransform() {
|
|
@@ -1598,18 +1598,19 @@ class A {
|
|
|
1598
1598
|
return !0;
|
|
1599
1599
|
const t = this.glbAnimator.skinnedPositions, e = this.glbAnimator.skinnedNormals, i = this.glbMeshData.texCoords;
|
|
1600
1600
|
for (let s = 0; s < this.glbMeshData.vertexCount; s++) {
|
|
1601
|
-
const
|
|
1602
|
-
this._glbInterleavedData[
|
|
1601
|
+
const n = s * 8, o = s * 3, a = s * 2;
|
|
1602
|
+
this._glbInterleavedData[n] = t[o], this._glbInterleavedData[n + 1] = t[o + 1], this._glbInterleavedData[n + 2] = t[o + 2], this._glbInterleavedData[n + 3] = e[o], this._glbInterleavedData[n + 4] = e[o + 1], this._glbInterleavedData[n + 5] = e[o + 2], i ? (this._glbInterleavedData[n + 6] = i[a], this._glbInterleavedData[n + 7] = i[a + 1]) : (this._glbInterleavedData[n + 6] = 0, this._glbInterleavedData[n + 7] = 0);
|
|
1603
1603
|
}
|
|
1604
1604
|
return this.device.queue.writeBuffer(this.glbVertexBuffer, 0, this._glbInterleavedData), !0;
|
|
1605
1605
|
}
|
|
1606
1606
|
updateAppearanceUniform() {
|
|
1607
|
+
if (this.destroyed) return;
|
|
1607
1608
|
let t = 0;
|
|
1608
1609
|
this.config.rotationMode === "random" ? t = 1 : this.config.rotationMode === "velocity" && (t = 2);
|
|
1609
1610
|
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] =
|
|
1611
|
-
const
|
|
1612
|
-
s[36] =
|
|
1611
|
+
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] = 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]}`);
|
|
1612
|
+
const n = this.config.followSystemTranslation ?? !0;
|
|
1613
|
+
s[36] = n ? this._simPosition[0] : 0, s[37] = n ? this._simPosition[1] : 0, s[38] = n ? 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, s[44] = this.config.noiseDistortEnabled ? 1 : 0, s[45] = this.config.noiseTilingX ?? 3, s[46] = this.config.noiseTilingY ?? 3, s[47] = this.config.noiseSpeed ?? -1.5, s[48] = this.config.noiseAmplitude ?? 0.08, s[49] = n ? this._simVelocity[0] : 0, s[50] = n ? this._simVelocity[1] : 0, s[51] = n ? this._simVelocity[2] : 0, this.device.queue.writeBuffer(this.appearanceUniformBuffer, 0, s);
|
|
1613
1614
|
}
|
|
1614
1615
|
updateBloomIntensity() {
|
|
1615
1616
|
const t = this._bloomIntensityData;
|
|
@@ -1629,40 +1630,55 @@ class A {
|
|
|
1629
1630
|
const i = 500;
|
|
1630
1631
|
for (let s = 0; s < t; s++)
|
|
1631
1632
|
if (this.emitParticle(), e++, e >= i || s === t - 1) {
|
|
1632
|
-
const
|
|
1633
|
+
const n = s - e + 1, o = n * 8, a = n * 4;
|
|
1633
1634
|
this.device.queue.writeBuffer(
|
|
1634
1635
|
this.instanceBuffer,
|
|
1635
|
-
|
|
1636
|
+
o * 4,
|
|
1636
1637
|
// Offset in bytes
|
|
1637
1638
|
this.particleData,
|
|
1638
|
-
|
|
1639
|
+
o,
|
|
1639
1640
|
e * 8
|
|
1640
1641
|
), this.device.queue.writeBuffer(
|
|
1641
1642
|
this.velocityBuffer,
|
|
1642
|
-
|
|
1643
|
+
a * 4,
|
|
1643
1644
|
// Offset in bytes
|
|
1644
1645
|
this.particleVelocities,
|
|
1645
|
-
|
|
1646
|
+
a,
|
|
1646
1647
|
e * 4
|
|
1647
1648
|
), e = 0;
|
|
1648
1649
|
}
|
|
1649
1650
|
this.emitting = !1;
|
|
1650
1651
|
} else {
|
|
1651
1652
|
this.emitting = !0;
|
|
1652
|
-
const t = this.config.lifetime || 5, e = Math.
|
|
1653
|
+
const t = this.config.lifetime || 5, e = this.config.emissionDurationInfinite ? t : Math.min(this.config.emissionDuration || 10, t);
|
|
1653
1654
|
this.particleCount = Math.min(Math.ceil((this.config.emissionRate || 10) * e), this.MAX_PARTICLES);
|
|
1654
1655
|
}
|
|
1655
1656
|
}
|
|
1657
|
+
// Effective emission window: Infinity when "Infinite Duration" is on (emits forever).
|
|
1658
|
+
// Used by the emission/respawn gates; buffer sizing handles infinity separately.
|
|
1659
|
+
get effectiveEmissionDuration() {
|
|
1660
|
+
return this.config.emissionDurationInfinite ? 1 / 0 : this.config.emissionDuration ?? 10;
|
|
1661
|
+
}
|
|
1662
|
+
// Apply the simulation rotation (and, when not following translation, the world offset) to a
|
|
1663
|
+
// freshly emitted particle at `index`, in local space. MUST be called from BOTH emit routes —
|
|
1664
|
+
// the initial spawn (emitParticle) AND the continuous recycle (respawnParticle). Without it on the
|
|
1665
|
+
// recycle path, a moving emitter's particles lose the sim rotation (e.g. the heading-follow yaw)
|
|
1666
|
+
// after their first lifetime cycle, so the emission orientation silently reverts to the un-rotated
|
|
1667
|
+
// shape mid-flight — the "orientation ne suit pas l'axe" bug.
|
|
1668
|
+
_applySimTransformToParticle(t) {
|
|
1669
|
+
this._emitSimRotY = this._simRotY || 0;
|
|
1670
|
+
const e = t * 8, i = t * 4;
|
|
1671
|
+
if (this._simRotMatrix) {
|
|
1672
|
+
const s = this._simRotMatrix, n = this.particleData[e], o = this.particleData[e + 1], a = this.particleData[e + 2], c = this.particleVelocities[i], l = this.particleVelocities[i + 1], u = this.particleVelocities[i + 2];
|
|
1673
|
+
this.particleData[e] = s[0] * n + s[1] * o + s[2] * a, this.particleData[e + 1] = s[3] * n + s[4] * o + s[5] * a, this.particleData[e + 2] = s[6] * n + s[7] * o + s[8] * a, this.particleVelocities[i] = s[0] * c + s[1] * l + s[2] * u, this.particleVelocities[i + 1] = s[3] * c + s[4] * l + s[5] * u, this.particleVelocities[i + 2] = s[6] * c + s[7] * l + s[8] * u;
|
|
1674
|
+
}
|
|
1675
|
+
(this.config.followSystemTranslation ?? !0) || (this.particleData[e] += this._simPosition[0], this.particleData[e + 1] += this._simPosition[1], this.particleData[e + 2] += this._simPosition[2]);
|
|
1676
|
+
}
|
|
1656
1677
|
emitParticle() {
|
|
1657
1678
|
if (this.activeParticles >= this.particleCount) return !1;
|
|
1658
1679
|
this.emitter.emitParticle(this.particleData, this.activeParticles, this.particleVelocities);
|
|
1659
1680
|
const t = this.activeParticles * 8, e = this.activeParticles * 4;
|
|
1660
|
-
|
|
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];
|
|
1662
|
-
const l = this._simRotMatrix;
|
|
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;
|
|
1664
|
-
}
|
|
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(
|
|
1681
|
+
return this._applySimTransformToParticle(this.activeParticles), this._newEmissions.push(
|
|
1666
1682
|
this.particleData[t],
|
|
1667
1683
|
this.particleData[t + 1],
|
|
1668
1684
|
this.particleData[t + 2],
|
|
@@ -1677,28 +1693,28 @@ class A {
|
|
|
1677
1693
|
*/
|
|
1678
1694
|
emitFollowerParticle(t, e, i) {
|
|
1679
1695
|
if (this.activeParticles >= this.particleCount) return !1;
|
|
1680
|
-
const s = this.activeParticles * 8,
|
|
1681
|
-
this.particleData[s] =
|
|
1682
|
-
const
|
|
1683
|
-
return this.emitter.calculateVelocity(
|
|
1696
|
+
const s = this.activeParticles * 8, n = t + (this.config.emissionPositionX || 0), o = e + (this.config.emissionPositionY || 0), a = i + (this.config.emissionPositionZ || 0);
|
|
1697
|
+
this.particleData[s] = n, this.particleData[s + 1] = o, this.particleData[s + 2] = a;
|
|
1698
|
+
const c = this.activeParticles * 4;
|
|
1699
|
+
return this.emitter.calculateVelocity(n, o, a, this.particleVelocities, c), this.emitter.setParticleColor(this.particleData, s), this.emitter.setParticleLifetime(this.particleData, s), this.activeParticles++, !0;
|
|
1684
1700
|
}
|
|
1685
1701
|
updateParticles(t, e) {
|
|
1686
1702
|
if (this._particleScript && this._scriptReadbackReady) {
|
|
1687
1703
|
this._scriptReadbackReady = !1, this._scriptTime += t, this._scriptFrame++;
|
|
1688
|
-
const
|
|
1689
|
-
if (
|
|
1704
|
+
const a = this.config.emissionDurationInfinite ? 1 / 0 : (this.config.emissionDuration || 0) + (this.config.lifetime || 0);
|
|
1705
|
+
if (a > 0 && this._scriptTime >= a && !this._scriptConfigRestored)
|
|
1690
1706
|
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
1707
|
else if (!this._scriptConfigRestored) {
|
|
1692
|
-
const
|
|
1708
|
+
const c = a > 0 ? Math.ceil(a / 0.016666666666666666) : 0, { configDirty: l, particlesDirty: u } = this._particleScript.execute(
|
|
1693
1709
|
t,
|
|
1694
1710
|
this._scriptTime,
|
|
1695
1711
|
this._scriptFrame,
|
|
1696
|
-
|
|
1712
|
+
c,
|
|
1697
1713
|
this._scriptParticleData,
|
|
1698
1714
|
this._scriptVelocityData,
|
|
1699
1715
|
this.activeParticles
|
|
1700
1716
|
);
|
|
1701
|
-
|
|
1717
|
+
u && this.activeParticles > 0 && (this.device.queue.writeBuffer(
|
|
1702
1718
|
this.instanceBuffer,
|
|
1703
1719
|
0,
|
|
1704
1720
|
this._scriptParticleData,
|
|
@@ -1714,22 +1730,22 @@ class A {
|
|
|
1714
1730
|
}
|
|
1715
1731
|
}
|
|
1716
1732
|
this.physics.physicsAccumulator += t;
|
|
1717
|
-
const i = performance.now() / 1e3,
|
|
1718
|
-
if (this.emitting)
|
|
1719
|
-
if (this.currentEmissionTime += t, this.currentEmissionTime < this.
|
|
1720
|
-
const
|
|
1721
|
-
let
|
|
1733
|
+
const i = performance.now() / 1e3, n = i - this.physics.lastUpdateTime > 1 / this.physics.minUpdatesPerSecond, o = this.activeParticles;
|
|
1734
|
+
if (!this.emitting && !this.config.burstMode && !this.config.followSystemId && this.currentEmissionTime < this.effectiveEmissionDuration && (this.emitting = !0), this.emitting)
|
|
1735
|
+
if (this.currentEmissionTime += t, this.currentEmissionTime < this.effectiveEmissionDuration) {
|
|
1736
|
+
const a = this.activeParticles;
|
|
1737
|
+
let c = !1;
|
|
1722
1738
|
if (this.config.followSystemId) {
|
|
1723
1739
|
if (this._pendingFollowEmissions.length > 0) {
|
|
1724
1740
|
const l = this._pendingFollowEmissions.length / 6;
|
|
1725
|
-
for (let
|
|
1726
|
-
const
|
|
1741
|
+
for (let u = 0; u < l; u++) {
|
|
1742
|
+
const f = u * 6;
|
|
1727
1743
|
if (this.emitFollowerParticle(
|
|
1728
|
-
this._pendingFollowEmissions[
|
|
1729
|
-
this._pendingFollowEmissions[
|
|
1730
|
-
this._pendingFollowEmissions[
|
|
1744
|
+
this._pendingFollowEmissions[f],
|
|
1745
|
+
this._pendingFollowEmissions[f + 1],
|
|
1746
|
+
this._pendingFollowEmissions[f + 2]
|
|
1731
1747
|
))
|
|
1732
|
-
|
|
1748
|
+
c = !0;
|
|
1733
1749
|
else
|
|
1734
1750
|
break;
|
|
1735
1751
|
}
|
|
@@ -1738,31 +1754,31 @@ class A {
|
|
|
1738
1754
|
let l = 0;
|
|
1739
1755
|
if (this.config.emissionRate >= 1) {
|
|
1740
1756
|
l = Math.floor(this.config.emissionRate * t);
|
|
1741
|
-
const
|
|
1742
|
-
Math.random() <
|
|
1757
|
+
const u = this.config.emissionRate * t - l;
|
|
1758
|
+
Math.random() < u && (l += 1);
|
|
1743
1759
|
} else {
|
|
1744
|
-
const
|
|
1745
|
-
Math.random() <
|
|
1760
|
+
const u = this.config.emissionRate * t;
|
|
1761
|
+
Math.random() < u && (l = 1);
|
|
1746
1762
|
}
|
|
1747
|
-
l === 0 &&
|
|
1748
|
-
for (let
|
|
1749
|
-
|
|
1763
|
+
l === 0 && n && this.config.emissionRate > 0 && this.activeParticles < this.particleCount && (l = 1);
|
|
1764
|
+
for (let u = 0; u < l && this.emitParticle(); u++)
|
|
1765
|
+
c = !0;
|
|
1750
1766
|
}
|
|
1751
|
-
if (
|
|
1752
|
-
const l = this.activeParticles -
|
|
1767
|
+
if (c) {
|
|
1768
|
+
const l = this.activeParticles - a, u = a * 8, f = a * 4;
|
|
1753
1769
|
this.device.queue.writeBuffer(
|
|
1754
1770
|
this.instanceBuffer,
|
|
1755
|
-
|
|
1771
|
+
u * 4,
|
|
1756
1772
|
// Offset in bytes (float32 = 4 bytes)
|
|
1757
1773
|
this.particleData,
|
|
1758
|
-
|
|
1774
|
+
u,
|
|
1759
1775
|
l * 8
|
|
1760
1776
|
), this.device.queue.writeBuffer(
|
|
1761
1777
|
this.velocityBuffer,
|
|
1762
|
-
|
|
1778
|
+
f * 4,
|
|
1763
1779
|
// Offset in bytes (float32 = 4 bytes)
|
|
1764
1780
|
this.particleVelocities,
|
|
1765
|
-
|
|
1781
|
+
f,
|
|
1766
1782
|
l * 4
|
|
1767
1783
|
);
|
|
1768
1784
|
}
|
|
@@ -1771,27 +1787,27 @@ class A {
|
|
|
1771
1787
|
for (; this.physics.physicsAccumulator >= this.physics.fixedDeltaTime; )
|
|
1772
1788
|
this.physics.updatePhysics(
|
|
1773
1789
|
this.physics.fixedDeltaTime,
|
|
1774
|
-
|
|
1790
|
+
o,
|
|
1775
1791
|
this.config,
|
|
1776
1792
|
this.instanceBuffer,
|
|
1777
1793
|
this.velocityBuffer,
|
|
1778
1794
|
e
|
|
1779
1795
|
), this.physics.physicsAccumulator -= this.physics.fixedDeltaTime, this.physics.physicsClock += this.physics.fixedDeltaTime;
|
|
1780
|
-
|
|
1796
|
+
n && o > 0 && (this.physics.updatePhysics(
|
|
1781
1797
|
this.physics.fixedDeltaTime,
|
|
1782
|
-
|
|
1798
|
+
o,
|
|
1783
1799
|
this.config,
|
|
1784
1800
|
this.instanceBuffer,
|
|
1785
1801
|
this.velocityBuffer,
|
|
1786
1802
|
e
|
|
1787
|
-
), this.physics.lastUpdateTime = i), this.frameCount
|
|
1803
|
+
), this.physics.lastUpdateTime = i), this.frameCount++, (this.activeParticles >= this.particleCount || this.frameCount % 300 === 0) && this.readbackAndProcessParticles(), this._particleScript && this.activeParticles > 0 && !this._scriptReadbackPending && (this._scriptReadbackPending = !0, this.physics.readbackForScript(
|
|
1788
1804
|
this.activeParticles,
|
|
1789
1805
|
this._scriptParticleData,
|
|
1790
1806
|
this._scriptVelocityData,
|
|
1791
1807
|
this.instanceBuffer,
|
|
1792
1808
|
this.velocityBuffer
|
|
1793
|
-
).then((
|
|
1794
|
-
this._scriptReadbackPending = !1,
|
|
1809
|
+
).then((a) => {
|
|
1810
|
+
this._scriptReadbackPending = !1, a.shouldUpdate && (this._scriptReadbackReady = !0);
|
|
1795
1811
|
}).catch(() => {
|
|
1796
1812
|
this._scriptReadbackPending = !1;
|
|
1797
1813
|
}));
|
|
@@ -1806,58 +1822,60 @@ class A {
|
|
|
1806
1822
|
this.instanceBuffer,
|
|
1807
1823
|
this.velocityBuffer
|
|
1808
1824
|
)).shouldUpdate) return;
|
|
1809
|
-
let e = 0;
|
|
1810
|
-
for (let
|
|
1811
|
-
const
|
|
1812
|
-
if (
|
|
1813
|
-
if (this.emitting && this.currentEmissionTime < this.
|
|
1814
|
-
this.respawnParticle(
|
|
1825
|
+
let e = 0, i = !1;
|
|
1826
|
+
for (let s = 0; s < this.activeParticles; s++) {
|
|
1827
|
+
const n = this.particleData[s * 8 + 6], o = this.particleData[s * 8 + 7];
|
|
1828
|
+
if (n >= o) {
|
|
1829
|
+
if (this.emitting && this.currentEmissionTime < this.effectiveEmissionDuration && e < this.particleCount) {
|
|
1830
|
+
this.respawnParticle(s, e), e++, i = !0;
|
|
1815
1831
|
continue;
|
|
1816
1832
|
}
|
|
1817
1833
|
continue;
|
|
1818
1834
|
}
|
|
1819
|
-
if (e !==
|
|
1820
|
-
const
|
|
1821
|
-
this.particleData.copyWithin(
|
|
1822
|
-
const
|
|
1823
|
-
this.particleVelocities.copyWithin(
|
|
1835
|
+
if (e !== s) {
|
|
1836
|
+
const a = s * 8, c = e * 8;
|
|
1837
|
+
this.particleData.copyWithin(c, a, a + 8);
|
|
1838
|
+
const l = s * 4, u = e * 4;
|
|
1839
|
+
this.particleVelocities.copyWithin(u, l, l + 4), i = !0;
|
|
1824
1840
|
}
|
|
1825
1841
|
e++;
|
|
1826
1842
|
}
|
|
1827
|
-
e !== this.activeParticles && (this.activeParticles = e, this.device.queue.writeBuffer(this.instanceBuffer, 0, this.particleData, 0, this.activeParticles * 8), this.device.queue.writeBuffer(this.velocityBuffer, 0, this.particleVelocities, 0, this.activeParticles * 4));
|
|
1843
|
+
(e !== this.activeParticles || i) && (this.activeParticles = e, this.device.queue.writeBuffer(this.instanceBuffer, 0, this.particleData, 0, this.activeParticles * 8), this.device.queue.writeBuffer(this.velocityBuffer, 0, this.particleVelocities, 0, this.activeParticles * 4));
|
|
1828
1844
|
} catch (t) {
|
|
1829
|
-
console.error("Error reading back particle data:", t);
|
|
1845
|
+
t && t.name === "AbortError" || console.error("Error reading back particle data:", t);
|
|
1830
1846
|
}
|
|
1831
1847
|
}
|
|
1832
1848
|
respawnParticle(t, e) {
|
|
1833
|
-
!this.emitting || this.currentEmissionTime >= this.
|
|
1849
|
+
!this.emitting || this.currentEmissionTime >= this.effectiveEmissionDuration || this.config.followSystemId || (this.emitter.emitParticle(this.particleData, e, this.particleVelocities), this._applySimTransformToParticle(e));
|
|
1834
1850
|
}
|
|
1835
1851
|
updateBuffers() {
|
|
1836
|
-
this.activeParticles > 0 && this.device.queue.writeBuffer(this.instanceBuffer, 0, this.particleData, 0, this.activeParticles * 8);
|
|
1852
|
+
this.destroyed || !this.particleData || this.activeParticles > 0 && this.device.queue.writeBuffer(this.instanceBuffer, 0, this.particleData, 0, this.activeParticles * 8);
|
|
1837
1853
|
}
|
|
1838
1854
|
updateParticleColors() {
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1855
|
+
if (!(this.destroyed || !this.particleData)) {
|
|
1856
|
+
for (let t = 0; t < this.activeParticles; t++) {
|
|
1857
|
+
const e = t * 8;
|
|
1858
|
+
if (this.config.randomColorEnabled && this.config.randomColors.length > 0) {
|
|
1859
|
+
const i = this.config.randomColors, s = i[Math.floor(Math.random() * i.length)];
|
|
1860
|
+
this.particleData[e + 3] = s[0], this.particleData[e + 4] = s[1], this.particleData[e + 5] = s[2];
|
|
1861
|
+
} 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]);
|
|
1862
|
+
}
|
|
1863
|
+
this.activeParticles > 0 && this.device.queue.writeBuffer(this.instanceBuffer, 0, this.particleData, 0, this.activeParticles * 8);
|
|
1845
1864
|
}
|
|
1846
|
-
this.activeParticles > 0 && this.device.queue.writeBuffer(this.instanceBuffer, 0, this.particleData, 0, this.activeParticles * 8);
|
|
1847
1865
|
}
|
|
1848
1866
|
updateParticleVelocities() {
|
|
1849
1867
|
for (let t = 0; t < this.activeParticles; t++) {
|
|
1850
|
-
const e = t * 8, i = t * 4, s = this.particleData[e],
|
|
1851
|
-
|
|
1868
|
+
const e = t * 8, i = t * 4, s = this.particleData[e], n = this.particleData[e + 1], o = this.particleData[e + 2], a = this.particleVelocities[i], c = this.particleVelocities[i + 1], l = this.particleVelocities[i + 2], u = Math.sqrt(
|
|
1869
|
+
a * a + c * c + l * l
|
|
1852
1870
|
);
|
|
1853
|
-
if (
|
|
1854
|
-
const
|
|
1855
|
-
this.particleVelocities[i] =
|
|
1871
|
+
if (u > 1e-3) {
|
|
1872
|
+
const f = this.config.particleSpeed * 2;
|
|
1873
|
+
this.particleVelocities[i] = a / u * f, this.particleVelocities[i + 1] = c / u * f, this.particleVelocities[i + 2] = l / u * f;
|
|
1856
1874
|
} else {
|
|
1857
|
-
const
|
|
1858
|
-
if (
|
|
1859
|
-
const
|
|
1860
|
-
this.particleVelocities[i] = s /
|
|
1875
|
+
const f = Math.sqrt(s * s + n * n + o * o);
|
|
1876
|
+
if (f > 1e-3) {
|
|
1877
|
+
const h = this.config.particleSpeed * 2;
|
|
1878
|
+
this.particleVelocities[i] = s / f * h, this.particleVelocities[i + 1] = n / f * h, this.particleVelocities[i + 2] = o / f * h;
|
|
1861
1879
|
} else
|
|
1862
1880
|
this.particleVelocities[i] = 0, this.particleVelocities[i + 1] = this.config.particleSpeed * 2, this.particleVelocities[i + 2] = 0;
|
|
1863
1881
|
}
|
|
@@ -1886,7 +1904,7 @@ class A {
|
|
|
1886
1904
|
* Call this when the system is no longer needed.
|
|
1887
1905
|
*/
|
|
1888
1906
|
destroy() {
|
|
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;
|
|
1907
|
+
this.destroyed = !0, 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;
|
|
1890
1908
|
}
|
|
1891
1909
|
setGravity(t) {
|
|
1892
1910
|
this.physics.setGravity(t);
|
|
@@ -1895,25 +1913,25 @@ class A {
|
|
|
1895
1913
|
this.physics.setAttractor(t, e);
|
|
1896
1914
|
}
|
|
1897
1915
|
setConfinement(t) {
|
|
1898
|
-
const e = t.space === "local" ? [this.config.
|
|
1899
|
-
this.physics.setConfinement({ ...t, center:
|
|
1916
|
+
const e = t.center || this.config.confinementCenter || [0, 0, 0], i = t.space === "local" ? [this.config.emissionPositionX || 0, this.config.emissionPositionY || 0, this.config.emissionPositionZ || 0] : [0, 0, 0], s = [i[0] + (e[0] || 0), i[1] + (e[1] || 0), i[2] + (e[2] || 0)];
|
|
1917
|
+
this.physics.setConfinement({ ...t, center: s });
|
|
1900
1918
|
}
|
|
1901
1919
|
setSoftBoundary(t) {
|
|
1902
1920
|
this.physics.setSoftBoundary(t);
|
|
1903
1921
|
}
|
|
1904
1922
|
}
|
|
1905
|
-
class
|
|
1923
|
+
class Es {
|
|
1906
1924
|
constructor(t) {
|
|
1907
|
-
this.device = t, this.particleSystems = [], this.activeSystemIndex = 0, this.systemCounter = 1, this.onSystemCreated = null;
|
|
1925
|
+
this.device = t, this.particleSystems = [], this.activeSystemIndex = 0, this.systemCounter = 1, this.onSystemCreated = null, this.loop = void 0, this.ready = !0;
|
|
1908
1926
|
}
|
|
1909
1927
|
createParticleSystem(t = {}) {
|
|
1910
1928
|
const e = this.systemCounter++, i = t.name || `System ${e + 1}`, s = {
|
|
1911
1929
|
...t,
|
|
1912
1930
|
name: i,
|
|
1913
1931
|
id: e
|
|
1914
|
-
},
|
|
1932
|
+
}, n = new bt(this.device, s);
|
|
1915
1933
|
return this.particleSystems.push({
|
|
1916
|
-
system:
|
|
1934
|
+
system: n,
|
|
1917
1935
|
config: s
|
|
1918
1936
|
}), this.particleSystems.length === 1 && (this.activeSystemIndex = 0), this.onSystemCreated && typeof this.onSystemCreated == "function" && this.onSystemCreated(e, s), e;
|
|
1919
1937
|
}
|
|
@@ -1955,18 +1973,18 @@ class Me {
|
|
|
1955
1973
|
updateAllSystems(t) {
|
|
1956
1974
|
const e = this.device.createCommandEncoder({ label: "BatchedPhysicsEncoder" });
|
|
1957
1975
|
let i = !1;
|
|
1958
|
-
for (const { system: s, config:
|
|
1959
|
-
if (
|
|
1960
|
-
const n = s.activeParticles > 0;
|
|
1961
|
-
s.updateParticles(t, e), (n || s.activeParticles > 0) && (i = !0);
|
|
1962
|
-
}
|
|
1963
|
-
for (const { system: s, config: r } of this.particleSystems) {
|
|
1964
|
-
if (r.hidden || !r.followSystemId) continue;
|
|
1965
|
-
const n = this.getSystemById(r.followSystemId);
|
|
1966
|
-
n && (s._pendingFollowEmissions = n.system._newEmissions);
|
|
1976
|
+
for (const { system: s, config: n } of this.particleSystems) {
|
|
1977
|
+
if (n.hidden || n.followSystemId) continue;
|
|
1967
1978
|
const o = s.activeParticles > 0;
|
|
1968
1979
|
s.updateParticles(t, e), (o || s.activeParticles > 0) && (i = !0);
|
|
1969
1980
|
}
|
|
1981
|
+
for (const { system: s, config: n } of this.particleSystems) {
|
|
1982
|
+
if (n.hidden || !n.followSystemId) continue;
|
|
1983
|
+
const o = this.getSystemById(n.followSystemId);
|
|
1984
|
+
o && (s._pendingFollowEmissions = o.system._newEmissions);
|
|
1985
|
+
const a = s.activeParticles > 0;
|
|
1986
|
+
s.updateParticles(t, e), (a || s.activeParticles > 0) && (i = !0);
|
|
1987
|
+
}
|
|
1970
1988
|
i && this.device.queue.submit([e.finish()]);
|
|
1971
1989
|
for (const { system: s } of this.particleSystems)
|
|
1972
1990
|
s._newEmissions.length = 0, s._pendingFollowEmissions = s._emptyEmissions;
|
|
@@ -1994,68 +2012,71 @@ class Me {
|
|
|
1994
2012
|
var e;
|
|
1995
2013
|
if (!t || !t.systems || !Array.isArray(t.systems))
|
|
1996
2014
|
return console.error("Invalid scene data provided"), !1;
|
|
2015
|
+
this.ready = !1;
|
|
1997
2016
|
try {
|
|
1998
2017
|
this.particleSystems = [], this.systemCounter = 1;
|
|
1999
2018
|
for (const s of t.systems) {
|
|
2000
|
-
const
|
|
2019
|
+
const n = this.systemCounter++, o = {
|
|
2001
2020
|
...s,
|
|
2002
|
-
id:
|
|
2003
|
-
},
|
|
2021
|
+
id: n
|
|
2022
|
+
}, a = new bt(this.device, o);
|
|
2004
2023
|
this.particleSystems.push({
|
|
2005
|
-
system:
|
|
2006
|
-
config:
|
|
2024
|
+
system: a,
|
|
2025
|
+
config: o
|
|
2007
2026
|
});
|
|
2008
2027
|
}
|
|
2009
2028
|
const i = {};
|
|
2010
|
-
t.systems.forEach((s,
|
|
2011
|
-
i[s.id] = this.particleSystems[
|
|
2029
|
+
t.systems.forEach((s, n) => {
|
|
2030
|
+
i[s.id] = this.particleSystems[n].config.id;
|
|
2012
2031
|
});
|
|
2013
2032
|
for (const { config: s } of this.particleSystems)
|
|
2014
2033
|
s.followSystemId && i[s.followSystemId] !== void 0 && (s.followSystemId = i[s.followSystemId]);
|
|
2015
|
-
t.activeSystemIndex !== void 0 && t.activeSystemIndex >= 0 && t.activeSystemIndex < this.particleSystems.length ? this.activeSystemIndex = t.activeSystemIndex : this.activeSystemIndex = 0;
|
|
2016
|
-
for (const { system: s, config:
|
|
2017
|
-
if (
|
|
2034
|
+
t.activeSystemIndex !== void 0 && t.activeSystemIndex >= 0 && t.activeSystemIndex < this.particleSystems.length ? this.activeSystemIndex = t.activeSystemIndex : this.activeSystemIndex = 0, this.loop = t.loop;
|
|
2035
|
+
for (const { system: s, config: n } of this.particleSystems)
|
|
2036
|
+
if (n.glbModelEnabled)
|
|
2018
2037
|
try {
|
|
2019
|
-
let
|
|
2020
|
-
if (
|
|
2021
|
-
|
|
2022
|
-
else if (
|
|
2023
|
-
const
|
|
2024
|
-
|
|
2038
|
+
let o = null;
|
|
2039
|
+
if (n.glbModelData)
|
|
2040
|
+
o = ci(n.glbModelData);
|
|
2041
|
+
else if (n.glbFileName) {
|
|
2042
|
+
const a = await fetch(`/${n.glbFileName}`);
|
|
2043
|
+
a.ok ? o = await a.arrayBuffer() : console.warn(`GLB file not found: ${n.glbFileName}`);
|
|
2025
2044
|
}
|
|
2026
|
-
if (
|
|
2027
|
-
if (await s.setGLBModel(
|
|
2045
|
+
if (o) {
|
|
2046
|
+
if (await s.setGLBModel(o), n.animationIndex !== void 0 && s.glbAnimator && s.glbAnimator.setAnimation(n.animationIndex), n.animationSpeed !== void 0 && s.glbAnimator && (s.glbAnimator.speed = n.animationSpeed), n.animationLoop !== void 0 && s.glbAnimator && (s.glbAnimator.loop = n.animationLoop), n.useGlbTexture && (n.textureEnabled = !0), n.useGlbTexture && ((e = s.glbMeshData) != null && e.hasBaseColorTexture))
|
|
2028
2047
|
try {
|
|
2029
|
-
const { extractGLBTexture:
|
|
2030
|
-
if (
|
|
2031
|
-
const l = await createImageBitmap(
|
|
2032
|
-
await s.setTexture(l), console.log(`GLB embedded texture restored for ${
|
|
2048
|
+
const { extractGLBTexture: a } = await Promise.resolve().then(() => ni), c = await a(o);
|
|
2049
|
+
if (c) {
|
|
2050
|
+
const l = await createImageBitmap(c.imageBlob);
|
|
2051
|
+
await s.setTexture(l), console.log(`GLB embedded texture restored for ${n.name}`);
|
|
2033
2052
|
}
|
|
2034
|
-
} catch (
|
|
2035
|
-
console.warn(`Failed to restore GLB texture for ${
|
|
2053
|
+
} catch (a) {
|
|
2054
|
+
console.warn(`Failed to restore GLB texture for ${n.name}:`, a), n.useGlbTexture = !1;
|
|
2036
2055
|
}
|
|
2037
2056
|
} else
|
|
2038
|
-
|
|
2039
|
-
} catch (
|
|
2040
|
-
console.warn(`Failed to load GLB for ${
|
|
2057
|
+
n.glbModelEnabled = !1;
|
|
2058
|
+
} catch (o) {
|
|
2059
|
+
console.warn(`Failed to load GLB for ${n.name}:`, o), n.glbModelEnabled = !1;
|
|
2041
2060
|
}
|
|
2042
|
-
for (const { system: s, config:
|
|
2043
|
-
if (
|
|
2061
|
+
for (const { system: s, config: n } of this.particleSystems)
|
|
2062
|
+
if (n.textureEnabled && !n.glbModelEnabled && n.textureImageData)
|
|
2044
2063
|
try {
|
|
2045
|
-
const
|
|
2046
|
-
await new Promise((
|
|
2047
|
-
|
|
2064
|
+
const o = new Image();
|
|
2065
|
+
await new Promise((c, l) => {
|
|
2066
|
+
o.onload = c, o.onerror = l, o.src = n.textureImageData;
|
|
2048
2067
|
});
|
|
2049
|
-
const
|
|
2050
|
-
await s.setTexture(
|
|
2051
|
-
} catch (
|
|
2052
|
-
console.warn(`Failed to restore texture for ${
|
|
2068
|
+
const a = await createImageBitmap(o);
|
|
2069
|
+
await s.setTexture(a);
|
|
2070
|
+
} catch (o) {
|
|
2071
|
+
console.warn(`Failed to restore texture for ${n.name}:`, o), n.textureEnabled = !1;
|
|
2053
2072
|
}
|
|
2054
|
-
for (const { system: s, config:
|
|
2055
|
-
s.updateAppearanceUniform(), (
|
|
2073
|
+
for (const { system: s, config: n } of this.particleSystems)
|
|
2074
|
+
s.updateAppearanceUniform(), (n.particleShapeRotationX || n.particleShapeRotationY || n.particleShapeRotationZ) && console.log(`[replaceSystems] ${n.name}: glbRotation XYZ = ${n.particleShapeRotationX}, ${n.particleShapeRotationY}, ${n.particleShapeRotationZ} | glbModelEnabled=${n.glbModelEnabled} | glbMeshData=${!!s.glbMeshData}`);
|
|
2056
2075
|
return this.respawnAllSystems(), !0;
|
|
2057
2076
|
} catch (i) {
|
|
2058
2077
|
return console.error("Error replacing systems:", i), !1;
|
|
2078
|
+
} finally {
|
|
2079
|
+
this.ready = !0;
|
|
2059
2080
|
}
|
|
2060
2081
|
}
|
|
2061
2082
|
/**
|
|
@@ -2066,132 +2087,139 @@ class Me {
|
|
|
2066
2087
|
* @returns {boolean} - Whether the addition was successful
|
|
2067
2088
|
*/
|
|
2068
2089
|
async addSystems(t, e = [0, 0, 0]) {
|
|
2069
|
-
var
|
|
2090
|
+
var s;
|
|
2070
2091
|
if (!t || !t.systems || !Array.isArray(t.systems))
|
|
2071
2092
|
return console.error("Invalid scene data provided"), !1;
|
|
2093
|
+
this.ready = !1;
|
|
2094
|
+
const i = [];
|
|
2072
2095
|
try {
|
|
2073
|
-
for (const
|
|
2074
|
-
const
|
|
2075
|
-
|
|
2076
|
-
|
|
2096
|
+
for (const a of t.systems) {
|
|
2097
|
+
const c = this.systemCounter++;
|
|
2098
|
+
i.push(c);
|
|
2099
|
+
const l = {
|
|
2100
|
+
...a,
|
|
2101
|
+
id: c,
|
|
2077
2102
|
// Apply world-space offset to emission translation
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2103
|
+
emissionPositionX: (a.emissionPositionX || 0) + e[0],
|
|
2104
|
+
emissionPositionY: (a.emissionPositionY || 0) + e[1],
|
|
2105
|
+
emissionPositionZ: (a.emissionPositionZ || 0) + e[2]
|
|
2081
2106
|
};
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2107
|
+
a.attractorEnabled && a.attractorPosition && (l.attractorPosition = [
|
|
2108
|
+
a.attractorPosition[0] + e[0],
|
|
2109
|
+
a.attractorPosition[1] + e[1],
|
|
2110
|
+
a.attractorPosition[2] + e[2]
|
|
2086
2111
|
]);
|
|
2087
|
-
const
|
|
2112
|
+
const u = new bt(this.device, l);
|
|
2088
2113
|
this.particleSystems.push({
|
|
2089
|
-
system:
|
|
2090
|
-
config:
|
|
2091
|
-
}), this.onSystemCreated && typeof this.onSystemCreated == "function" && this.onSystemCreated(
|
|
2114
|
+
system: u,
|
|
2115
|
+
config: l
|
|
2116
|
+
}), this.onSystemCreated && typeof this.onSystemCreated == "function" && this.onSystemCreated(c, l);
|
|
2092
2117
|
}
|
|
2093
|
-
const
|
|
2094
|
-
t.systems.forEach((
|
|
2095
|
-
|
|
2118
|
+
const n = this.particleSystems.length - t.systems.length, o = {};
|
|
2119
|
+
t.systems.forEach((a, c) => {
|
|
2120
|
+
o[a.id] = this.particleSystems[n + c].config.id;
|
|
2096
2121
|
});
|
|
2097
|
-
for (let
|
|
2098
|
-
const { config:
|
|
2099
|
-
|
|
2122
|
+
for (let a = n; a < this.particleSystems.length; a++) {
|
|
2123
|
+
const { config: c } = this.particleSystems[a];
|
|
2124
|
+
c.followSystemId && o[c.followSystemId] !== void 0 && (c.followSystemId = o[c.followSystemId]);
|
|
2100
2125
|
}
|
|
2101
|
-
for (const { system:
|
|
2102
|
-
if (
|
|
2126
|
+
for (const { system: a, config: c } of this.particleSystems)
|
|
2127
|
+
if (c.glbModelEnabled && !a.glbMeshData)
|
|
2103
2128
|
try {
|
|
2104
|
-
let
|
|
2105
|
-
if (
|
|
2106
|
-
|
|
2107
|
-
else if (
|
|
2108
|
-
const
|
|
2109
|
-
|
|
2129
|
+
let l = null;
|
|
2130
|
+
if (c.glbModelData)
|
|
2131
|
+
l = ci(c.glbModelData);
|
|
2132
|
+
else if (c.glbFileName) {
|
|
2133
|
+
const u = await fetch(`/${c.glbFileName}`);
|
|
2134
|
+
u.ok ? l = await u.arrayBuffer() : console.warn(`GLB file not found: ${c.glbFileName}`);
|
|
2110
2135
|
}
|
|
2111
|
-
if (
|
|
2112
|
-
if (await
|
|
2136
|
+
if (l) {
|
|
2137
|
+
if (await a.setGLBModel(l), c.animationIndex !== void 0 && a.glbAnimator && a.glbAnimator.setAnimation(c.animationIndex), c.animationSpeed !== void 0 && a.glbAnimator && (a.glbAnimator.speed = c.animationSpeed), c.animationLoop !== void 0 && a.glbAnimator && (a.glbAnimator.loop = c.animationLoop), c.useGlbTexture && (c.textureEnabled = !0), c.useGlbTexture && ((s = a.glbMeshData) != null && s.hasBaseColorTexture))
|
|
2113
2138
|
try {
|
|
2114
|
-
const { extractGLBTexture:
|
|
2115
|
-
if (
|
|
2116
|
-
const
|
|
2117
|
-
await
|
|
2139
|
+
const { extractGLBTexture: u } = await Promise.resolve().then(() => ni), f = await u(l);
|
|
2140
|
+
if (f) {
|
|
2141
|
+
const h = await createImageBitmap(f.imageBlob);
|
|
2142
|
+
await a.setTexture(h), console.log(`GLB embedded texture restored for ${c.name}`);
|
|
2118
2143
|
}
|
|
2119
|
-
} catch (
|
|
2120
|
-
console.warn(`Failed to restore GLB texture for ${
|
|
2144
|
+
} catch (u) {
|
|
2145
|
+
console.warn(`Failed to restore GLB texture for ${c.name}:`, u), c.useGlbTexture = !1;
|
|
2121
2146
|
}
|
|
2122
2147
|
} else
|
|
2123
|
-
|
|
2124
|
-
} catch (
|
|
2125
|
-
console.warn(`Failed to load GLB for ${
|
|
2148
|
+
c.glbModelEnabled = !1;
|
|
2149
|
+
} catch (l) {
|
|
2150
|
+
console.warn(`Failed to load GLB for ${c.name}:`, l), c.glbModelEnabled = !1;
|
|
2126
2151
|
}
|
|
2127
|
-
for (const { system:
|
|
2128
|
-
if (
|
|
2152
|
+
for (const { system: a, config: c } of this.particleSystems)
|
|
2153
|
+
if (c.textureEnabled && !c.glbModelEnabled && c.textureImageData && !a._textureRestored)
|
|
2129
2154
|
try {
|
|
2130
|
-
const
|
|
2131
|
-
await new Promise((
|
|
2132
|
-
|
|
2155
|
+
const l = new Image();
|
|
2156
|
+
await new Promise((f, h) => {
|
|
2157
|
+
l.onload = f, l.onerror = h, l.src = c.textureImageData;
|
|
2133
2158
|
});
|
|
2134
|
-
const
|
|
2135
|
-
await
|
|
2136
|
-
} catch (
|
|
2137
|
-
console.warn(`Failed to restore texture for ${
|
|
2159
|
+
const u = await createImageBitmap(l);
|
|
2160
|
+
await a.setTexture(u), a._textureRestored = !0;
|
|
2161
|
+
} catch (l) {
|
|
2162
|
+
console.warn(`Failed to restore texture for ${c.name}:`, l), c.textureEnabled = !1;
|
|
2138
2163
|
}
|
|
2139
|
-
return
|
|
2140
|
-
} catch (
|
|
2141
|
-
return console.error("Error adding systems:",
|
|
2164
|
+
return i;
|
|
2165
|
+
} catch (n) {
|
|
2166
|
+
return console.error("Error adding systems:", n), !1;
|
|
2167
|
+
} finally {
|
|
2168
|
+
this.ready = !0;
|
|
2142
2169
|
}
|
|
2143
2170
|
}
|
|
2144
2171
|
}
|
|
2145
|
-
async function
|
|
2146
|
-
if (!
|
|
2172
|
+
async function Cs(r) {
|
|
2173
|
+
if (!r)
|
|
2147
2174
|
throw new Error("canvas is required for initWebGPU()");
|
|
2148
2175
|
if (!navigator.gpu)
|
|
2149
2176
|
throw new Error("WebGPU not supported on this browser.");
|
|
2150
|
-
const t =
|
|
2177
|
+
const t = r.getContext("webgpu"), i = await (await navigator.gpu.requestAdapter()).requestDevice(), s = navigator.gpu.getPreferredCanvasFormat();
|
|
2151
2178
|
return t.configure({
|
|
2152
2179
|
device: i,
|
|
2153
2180
|
format: s,
|
|
2154
2181
|
alphaMode: "premultiplied"
|
|
2155
|
-
}), { device: i, context: t, format: s, canvas:
|
|
2182
|
+
}), { device: i, context: t, format: s, canvas: r };
|
|
2156
2183
|
}
|
|
2157
|
-
|
|
2158
|
-
|
|
2184
|
+
const le = "rgba16float";
|
|
2185
|
+
function ui(r, t, e, i) {
|
|
2186
|
+
const s = r.createTexture({
|
|
2159
2187
|
size: [e, i],
|
|
2160
|
-
format:
|
|
2188
|
+
format: le,
|
|
2161
2189
|
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
2162
2190
|
mipLevelCount: 1,
|
|
2163
2191
|
sampleCount: 1
|
|
2164
|
-
}),
|
|
2192
|
+
}), n = r.createTexture({
|
|
2165
2193
|
size: [e, i],
|
|
2166
|
-
format:
|
|
2194
|
+
format: le,
|
|
2167
2195
|
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
2168
2196
|
mipLevelCount: 1,
|
|
2169
2197
|
sampleCount: 1
|
|
2170
|
-
}),
|
|
2198
|
+
}), o = r.createTexture({
|
|
2171
2199
|
size: [e, i],
|
|
2172
|
-
format:
|
|
2200
|
+
format: le,
|
|
2173
2201
|
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
2174
2202
|
mipLevelCount: 1,
|
|
2175
2203
|
sampleCount: 1
|
|
2176
2204
|
});
|
|
2177
|
-
return { sceneTexture: s, bloomTexA:
|
|
2205
|
+
return { sceneTexture: s, bloomTexA: n, bloomTexB: o };
|
|
2178
2206
|
}
|
|
2179
|
-
function
|
|
2180
|
-
return
|
|
2207
|
+
function di(r, t, e) {
|
|
2208
|
+
return r.createTexture({
|
|
2181
2209
|
size: [t, e],
|
|
2182
2210
|
format: "depth24plus",
|
|
2183
2211
|
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
2184
2212
|
});
|
|
2185
2213
|
}
|
|
2186
|
-
function
|
|
2187
|
-
const i =
|
|
2214
|
+
function Ge(r, t, e) {
|
|
2215
|
+
const i = r.createBuffer({
|
|
2188
2216
|
size: t.byteLength,
|
|
2189
2217
|
usage: e,
|
|
2190
2218
|
mappedAtCreation: !0
|
|
2191
2219
|
});
|
|
2192
2220
|
return new t.constructor(i.getMappedRange()).set(t), i.unmap(), i;
|
|
2193
2221
|
}
|
|
2194
|
-
const
|
|
2222
|
+
const bi = `
|
|
2195
2223
|
struct Uniforms {
|
|
2196
2224
|
transform: mat4x4<f32>,
|
|
2197
2225
|
cameraPosition: vec3<f32>,
|
|
@@ -2236,6 +2264,14 @@ const Y = `
|
|
|
2236
2264
|
simRotZ: f32, // simulation rotation Z (radians)
|
|
2237
2265
|
velocityStretchEnabled: f32, // 0=off, 1=on
|
|
2238
2266
|
velocityStretchFactor: f32, // multiplier for stretch (0-10)
|
|
2267
|
+
noiseDistortEnabled: f32, // 0=off, 1=on — UV distortion by scrolling noise (flames)
|
|
2268
|
+
noiseTilingX: f32, // noise tiling along U
|
|
2269
|
+
noiseTilingY: f32, // noise tiling along V
|
|
2270
|
+
noiseSpeed: f32, // vertical scroll speed (negative = noise rises, flame dances upward)
|
|
2271
|
+
noiseAmplitude: f32, // UV distortion amplitude
|
|
2272
|
+
systemVelX: f32, // emitter/system world velocity (for velocity-aligned rotation
|
|
2273
|
+
systemVelY: f32, // of trail particles that move WITH the emitter, e.g. a ball —
|
|
2274
|
+
systemVelZ: f32, // their local velocity is ~0 so they need the system velocity)
|
|
2239
2275
|
}
|
|
2240
2276
|
|
|
2241
2277
|
@binding(0) @group(0) var<uniform> uniforms : Uniforms;
|
|
@@ -2257,6 +2293,22 @@ const Y = `
|
|
|
2257
2293
|
@location(0) color : vec3<f32>,
|
|
2258
2294
|
@location(1) alpha : f32,
|
|
2259
2295
|
@location(2) texCoord : vec2<f32>,
|
|
2296
|
+
@location(3) noiseOffset : vec2<f32>,
|
|
2297
|
+
}
|
|
2298
|
+
|
|
2299
|
+
fn hash21(p: vec2<f32>) -> f32 {
|
|
2300
|
+
return fract(sin(dot(p, vec2<f32>(127.1, 311.7))) * 43758.5453);
|
|
2301
|
+
}
|
|
2302
|
+
|
|
2303
|
+
fn valueNoise(p: vec2<f32>) -> f32 {
|
|
2304
|
+
let i = floor(p);
|
|
2305
|
+
let f = fract(p);
|
|
2306
|
+
let u = f * f * (3.0 - 2.0 * f);
|
|
2307
|
+
let a = hash21(i);
|
|
2308
|
+
let b = hash21(i + vec2<f32>(1.0, 0.0));
|
|
2309
|
+
let c = hash21(i + vec2<f32>(0.0, 1.0));
|
|
2310
|
+
let d = hash21(i + vec2<f32>(1.0, 1.0));
|
|
2311
|
+
return mix(mix(a, b, u.x), mix(c, d, u.x), u.y);
|
|
2260
2312
|
}
|
|
2261
2313
|
|
|
2262
2314
|
@vertex
|
|
@@ -2334,9 +2386,13 @@ const Y = `
|
|
|
2334
2386
|
fract(sin(lifetime * 12345.67) * 43758.5453) *
|
|
2335
2387
|
(appearance.maxRotation - appearance.minRotation);
|
|
2336
2388
|
} else if (appearance.rotationMode == 2.0) {
|
|
2337
|
-
// Calculate rotation based on velocity direction in screen space
|
|
2338
|
-
//
|
|
2339
|
-
|
|
2389
|
+
// Calculate rotation based on velocity direction in screen space. Use the COMBINED velocity
|
|
2390
|
+
// (particle-local + system/emitter): a trail particle riding a moving emitter (e.g. the driven
|
|
2391
|
+
// ball) has ~0 local velocity, so without the system term it would never align to the motion
|
|
2392
|
+
// ("la particule ne suit jamais la direction de la vélocité"). Stays a camera-facing billboard,
|
|
2393
|
+
// just rotated to point along the movement.
|
|
2394
|
+
let combinedVel = input.particleVelocity + vec3<f32>(appearance.systemVelX, appearance.systemVelY, appearance.systemVelZ);
|
|
2395
|
+
let viewVelocity = (uniforms.transform * vec4<f32>(combinedVel, 0.0)).xyz;
|
|
2340
2396
|
|
|
2341
2397
|
// Calculate the angle from the transformed velocity
|
|
2342
2398
|
// We only care about the XY plane in screen space
|
|
@@ -2399,6 +2455,14 @@ const Y = `
|
|
|
2399
2455
|
// Convert the quad position to texture coordinates (0,0 to 1,1)
|
|
2400
2456
|
output.texCoord = vec2<f32>(input.position.x + 0.5, -input.position.y + 0.5);
|
|
2401
2457
|
|
|
2458
|
+
// Per-particle phase (seeded from lifetime) desynchronizes flames sharing
|
|
2459
|
+
// the same system; y carries the vertical noise scroll over time.
|
|
2460
|
+
let noisePhase = fract(sin(lifetime * 76543.21) * 43758.5453) * 6.283185;
|
|
2461
|
+
output.noiseOffset = vec2<f32>(
|
|
2462
|
+
noisePhase,
|
|
2463
|
+
uniforms.elapsedTime * appearance.noiseSpeed + noisePhase
|
|
2464
|
+
);
|
|
2465
|
+
|
|
2402
2466
|
return output;
|
|
2403
2467
|
}
|
|
2404
2468
|
|
|
@@ -2515,13 +2579,27 @@ const Y = `
|
|
|
2515
2579
|
}
|
|
2516
2580
|
|
|
2517
2581
|
if (appearance.textureEnabled > 0.5) {
|
|
2518
|
-
|
|
2582
|
+
var sampleUV = input.texCoord;
|
|
2583
|
+
if (appearance.noiseDistortEnabled > 0.5) {
|
|
2584
|
+
// Flame-style distortion: a scrolling noise field offsets the sample UV
|
|
2585
|
+
// (n = noise(uv×tiling + (phase, t×speed + phase)) − 0.5)
|
|
2586
|
+
let nUV = input.texCoord * vec2<f32>(appearance.noiseTilingX, appearance.noiseTilingY)
|
|
2587
|
+
+ input.noiseOffset;
|
|
2588
|
+
let n1 = valueNoise(nUV) - 0.5;
|
|
2589
|
+
let n2 = valueNoise(nUV + vec2<f32>(13.7, 7.3)) - 0.5;
|
|
2590
|
+
sampleUV = clamp(
|
|
2591
|
+
input.texCoord + vec2<f32>(n1, n2) * appearance.noiseAmplitude,
|
|
2592
|
+
vec2<f32>(0.001, 0.001),
|
|
2593
|
+
vec2<f32>(0.999, 0.999)
|
|
2594
|
+
);
|
|
2595
|
+
}
|
|
2596
|
+
let texColor = textureSample(particleTexture, particleSampler, sampleUV);
|
|
2519
2597
|
return vec4<f32>(input.color * texColor.rgb, alpha * texColor.a);
|
|
2520
2598
|
} else {
|
|
2521
2599
|
return vec4<f32>(input.color, alpha);
|
|
2522
2600
|
}
|
|
2523
2601
|
}
|
|
2524
|
-
`,
|
|
2602
|
+
`, Si = `
|
|
2525
2603
|
struct BloomUniforms {
|
|
2526
2604
|
direction: vec2<f32>,
|
|
2527
2605
|
resolution: vec2<f32>,
|
|
@@ -2581,7 +2659,7 @@ const Y = `
|
|
|
2581
2659
|
|
|
2582
2660
|
return result / totalWeight * 1.1;
|
|
2583
2661
|
}
|
|
2584
|
-
`,
|
|
2662
|
+
`, xi = `
|
|
2585
2663
|
struct BloomIntensityUniforms {
|
|
2586
2664
|
intensity: f32,
|
|
2587
2665
|
color: vec3<f32>,
|
|
@@ -2627,7 +2705,7 @@ const Y = `
|
|
|
2627
2705
|
|
|
2628
2706
|
return vec4<f32>(originalColor.rgb + (mappedBloom * bloomUniforms.intensity), originalColor.a);
|
|
2629
2707
|
}
|
|
2630
|
-
`,
|
|
2708
|
+
`, vi = `
|
|
2631
2709
|
struct BloomIntensityUniforms {
|
|
2632
2710
|
intensity: f32,
|
|
2633
2711
|
color: vec3<f32>,
|
|
@@ -2668,7 +2746,39 @@ const Y = `
|
|
|
2668
2746
|
fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> {
|
|
2669
2747
|
return textureSample(originalTexture, texSampler, input.texCoord);
|
|
2670
2748
|
}
|
|
2671
|
-
`,
|
|
2749
|
+
`, Pi = `
|
|
2750
|
+
@binding(0) @group(0) var texSampler: sampler;
|
|
2751
|
+
@binding(1) @group(0) var originalTexture: texture_2d<f32>;
|
|
2752
|
+
@binding(2) @group(0) var blurredTexture: texture_2d<f32>;
|
|
2753
|
+
struct BloomIntensityUniforms { intensity: f32, color: vec3<f32> }
|
|
2754
|
+
@binding(3) @group(0) var<uniform> bloomUniforms: BloomIntensityUniforms;
|
|
2755
|
+
|
|
2756
|
+
struct VertexOutput {
|
|
2757
|
+
@builtin(position) position: vec4<f32>,
|
|
2758
|
+
@location(0) texCoord: vec2<f32>,
|
|
2759
|
+
}
|
|
2760
|
+
|
|
2761
|
+
@vertex
|
|
2762
|
+
fn vs_main(@builtin(vertex_index) vertexIndex: u32) -> VertexOutput {
|
|
2763
|
+
var output: VertexOutput;
|
|
2764
|
+
let positions = array<vec2<f32>, 3>(vec2<f32>(-1.0, -1.0), vec2<f32>(3.0, -1.0), vec2<f32>(-1.0, 3.0));
|
|
2765
|
+
let texCoords = array<vec2<f32>, 3>(vec2<f32>(0.0, 1.0), vec2<f32>(2.0, 1.0), vec2<f32>(0.0, -1.0));
|
|
2766
|
+
output.position = vec4<f32>(positions[vertexIndex], 0.0, 1.0);
|
|
2767
|
+
output.texCoord = texCoords[vertexIndex];
|
|
2768
|
+
return output;
|
|
2769
|
+
}
|
|
2770
|
+
|
|
2771
|
+
fn aces(x: vec3<f32>) -> vec3<f32> {
|
|
2772
|
+
let a = 2.51; let b = 0.03; let c = 2.43; let d = 0.59; let e = 0.14;
|
|
2773
|
+
return clamp((x * (a * x + b)) / (x * (c * x + d) + e), vec3<f32>(0.0), vec3<f32>(1.0));
|
|
2774
|
+
}
|
|
2775
|
+
|
|
2776
|
+
@fragment
|
|
2777
|
+
fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> {
|
|
2778
|
+
let c = textureSample(originalTexture, texSampler, input.texCoord);
|
|
2779
|
+
return vec4<f32>(aces(c.rgb), c.a);
|
|
2780
|
+
}
|
|
2781
|
+
`, As = `
|
|
2672
2782
|
struct PhysicsUniforms {
|
|
2673
2783
|
deltaTime: f32,
|
|
2674
2784
|
particleSpeed: f32,
|
|
@@ -2878,7 +2988,7 @@ const Y = `
|
|
|
2878
2988
|
particleBuffer[baseIndex + 1u] = newPos.y;
|
|
2879
2989
|
particleBuffer[baseIndex + 2u] = newPos.z;
|
|
2880
2990
|
}
|
|
2881
|
-
`,
|
|
2991
|
+
`, Us = `
|
|
2882
2992
|
@group(0) @binding(0) var<storage, read> restData: array<f32>;
|
|
2883
2993
|
@group(0) @binding(1) var<storage, read> jointWeightsData: array<f32>;
|
|
2884
2994
|
@group(0) @binding(2) var<storage, read> jointIndicesData: array<u32>;
|
|
@@ -2934,15 +3044,16 @@ const Y = `
|
|
|
2934
3044
|
outputData[outBase + 6u] = uv_u;
|
|
2935
3045
|
outputData[outBase + 7u] = uv_v;
|
|
2936
3046
|
}
|
|
2937
|
-
`,
|
|
3047
|
+
`, _i = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2938
3048
|
__proto__: null,
|
|
2939
|
-
blurShader:
|
|
2940
|
-
compositeShader:
|
|
2941
|
-
directRenderShader:
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
3049
|
+
blurShader: Si,
|
|
3050
|
+
compositeShader: xi,
|
|
3051
|
+
directRenderShader: vi,
|
|
3052
|
+
finalCompositeShader: Pi,
|
|
3053
|
+
particlePhysicsShader: As,
|
|
3054
|
+
particleShader: bi,
|
|
3055
|
+
skinningComputeShader: Us
|
|
3056
|
+
}, Symbol.toStringTag, { value: "Module" })), Is = `
|
|
2946
3057
|
struct Uniforms {
|
|
2947
3058
|
transform: mat4x4<f32>,
|
|
2948
3059
|
cameraPosition: vec3<f32>,
|
|
@@ -3004,7 +3115,7 @@ const Y = `
|
|
|
3004
3115
|
|
|
3005
3116
|
return finalColor;
|
|
3006
3117
|
}
|
|
3007
|
-
`,
|
|
3118
|
+
`, Gs = `
|
|
3008
3119
|
struct Uniforms {
|
|
3009
3120
|
transform: mat4x4<f32>,
|
|
3010
3121
|
cameraPosition: vec3<f32>,
|
|
@@ -3240,8 +3351,8 @@ const Y = `
|
|
|
3240
3351
|
return finalColor;
|
|
3241
3352
|
}
|
|
3242
3353
|
`;
|
|
3243
|
-
function
|
|
3244
|
-
const t =
|
|
3354
|
+
function Ds(r) {
|
|
3355
|
+
const t = r.createBindGroupLayout({
|
|
3245
3356
|
entries: [
|
|
3246
3357
|
{
|
|
3247
3358
|
binding: 0,
|
|
@@ -3264,7 +3375,7 @@ function Te(c) {
|
|
|
3264
3375
|
sampler: {}
|
|
3265
3376
|
}
|
|
3266
3377
|
]
|
|
3267
|
-
}), e =
|
|
3378
|
+
}), e = r.createBindGroupLayout({
|
|
3268
3379
|
entries: [
|
|
3269
3380
|
{
|
|
3270
3381
|
binding: 0,
|
|
@@ -3282,7 +3393,7 @@ function Te(c) {
|
|
|
3282
3393
|
buffer: { type: "uniform" }
|
|
3283
3394
|
}
|
|
3284
3395
|
]
|
|
3285
|
-
}), i =
|
|
3396
|
+
}), i = r.createBindGroupLayout({
|
|
3286
3397
|
entries: [
|
|
3287
3398
|
{
|
|
3288
3399
|
binding: 0,
|
|
@@ -3305,7 +3416,7 @@ function Te(c) {
|
|
|
3305
3416
|
buffer: { type: "uniform" }
|
|
3306
3417
|
}
|
|
3307
3418
|
]
|
|
3308
|
-
}), s =
|
|
3419
|
+
}), s = r.createBindGroupLayout({
|
|
3309
3420
|
entries: [
|
|
3310
3421
|
{
|
|
3311
3422
|
binding: 0,
|
|
@@ -3326,34 +3437,34 @@ function Te(c) {
|
|
|
3326
3437
|
object3dBindGroupLayout: s
|
|
3327
3438
|
};
|
|
3328
3439
|
}
|
|
3329
|
-
function
|
|
3330
|
-
const { depthCompare: s } = i,
|
|
3331
|
-
particleBindGroupLayout:
|
|
3332
|
-
bloomBindGroupLayout:
|
|
3333
|
-
compositeBindGroupLayout:
|
|
3440
|
+
function zs(r, t, e, i = {}) {
|
|
3441
|
+
const { depthCompare: s } = i, n = s || "less", {
|
|
3442
|
+
particleBindGroupLayout: o,
|
|
3443
|
+
bloomBindGroupLayout: a,
|
|
3444
|
+
compositeBindGroupLayout: c,
|
|
3334
3445
|
object3dBindGroupLayout: l
|
|
3335
|
-
} = e,
|
|
3336
|
-
bindGroupLayouts: [n]
|
|
3337
|
-
}), u = c.createPipelineLayout({
|
|
3446
|
+
} = e, u = r.createPipelineLayout({
|
|
3338
3447
|
bindGroupLayouts: [o]
|
|
3339
|
-
}), f =
|
|
3448
|
+
}), f = r.createPipelineLayout({
|
|
3340
3449
|
bindGroupLayouts: [a]
|
|
3341
|
-
}), h =
|
|
3342
|
-
|
|
3343
|
-
}),
|
|
3344
|
-
code:
|
|
3345
|
-
}),
|
|
3346
|
-
code:
|
|
3347
|
-
}),
|
|
3348
|
-
code:
|
|
3349
|
-
}),
|
|
3350
|
-
code:
|
|
3351
|
-
}),
|
|
3352
|
-
code:
|
|
3353
|
-
}),
|
|
3354
|
-
|
|
3450
|
+
}), h = r.createPipelineLayout({
|
|
3451
|
+
bindGroupLayouts: [c]
|
|
3452
|
+
}), m = r.createShaderModule({
|
|
3453
|
+
code: bi
|
|
3454
|
+
}), S = r.createShaderModule({
|
|
3455
|
+
code: Si
|
|
3456
|
+
}), R = r.createShaderModule({
|
|
3457
|
+
code: xi
|
|
3458
|
+
}), D = r.createShaderModule({
|
|
3459
|
+
code: vi
|
|
3460
|
+
}), C = r.createShaderModule({
|
|
3461
|
+
code: Is
|
|
3462
|
+
}), B = r.createShaderModule({
|
|
3463
|
+
code: Gs
|
|
3464
|
+
}), A = (at) => r.createRenderPipeline({
|
|
3465
|
+
layout: u,
|
|
3355
3466
|
vertex: {
|
|
3356
|
-
module:
|
|
3467
|
+
module: m,
|
|
3357
3468
|
entryPoint: "vs_main",
|
|
3358
3469
|
buffers: [
|
|
3359
3470
|
{
|
|
@@ -3414,22 +3525,11 @@ function Ce(c, t, e, i = {}) {
|
|
|
3414
3525
|
]
|
|
3415
3526
|
},
|
|
3416
3527
|
fragment: {
|
|
3417
|
-
module:
|
|
3528
|
+
module: m,
|
|
3418
3529
|
entryPoint: "fs_main",
|
|
3419
3530
|
targets: [{
|
|
3420
|
-
format:
|
|
3421
|
-
blend:
|
|
3422
|
-
color: {
|
|
3423
|
-
srcFactor: "src-alpha",
|
|
3424
|
-
dstFactor: "one-minus-src-alpha",
|
|
3425
|
-
operation: "add"
|
|
3426
|
-
},
|
|
3427
|
-
alpha: {
|
|
3428
|
-
srcFactor: "one",
|
|
3429
|
-
dstFactor: "one-minus-src-alpha",
|
|
3430
|
-
operation: "add"
|
|
3431
|
-
}
|
|
3432
|
-
}
|
|
3531
|
+
format: le,
|
|
3532
|
+
blend: at
|
|
3433
3533
|
}]
|
|
3434
3534
|
},
|
|
3435
3535
|
primitive: {
|
|
@@ -3438,13 +3538,35 @@ function Ce(c, t, e, i = {}) {
|
|
|
3438
3538
|
},
|
|
3439
3539
|
depthStencil: {
|
|
3440
3540
|
depthWriteEnabled: !1,
|
|
3441
|
-
depthCompare:
|
|
3541
|
+
depthCompare: n,
|
|
3442
3542
|
format: "depth24plus"
|
|
3443
3543
|
}
|
|
3444
|
-
}),
|
|
3445
|
-
|
|
3544
|
+
}), P = A({
|
|
3545
|
+
color: {
|
|
3546
|
+
srcFactor: "src-alpha",
|
|
3547
|
+
dstFactor: "one-minus-src-alpha",
|
|
3548
|
+
operation: "add"
|
|
3549
|
+
},
|
|
3550
|
+
alpha: {
|
|
3551
|
+
srcFactor: "one",
|
|
3552
|
+
dstFactor: "one-minus-src-alpha",
|
|
3553
|
+
operation: "add"
|
|
3554
|
+
}
|
|
3555
|
+
}), _ = A({
|
|
3556
|
+
color: {
|
|
3557
|
+
srcFactor: "src-alpha",
|
|
3558
|
+
dstFactor: "one",
|
|
3559
|
+
operation: "add"
|
|
3560
|
+
},
|
|
3561
|
+
alpha: {
|
|
3562
|
+
srcFactor: "one",
|
|
3563
|
+
dstFactor: "one-minus-src-alpha",
|
|
3564
|
+
operation: "add"
|
|
3565
|
+
}
|
|
3566
|
+
}), T = r.createRenderPipeline({
|
|
3567
|
+
layout: u,
|
|
3446
3568
|
vertex: {
|
|
3447
|
-
module:
|
|
3569
|
+
module: m,
|
|
3448
3570
|
entryPoint: "vs_main",
|
|
3449
3571
|
buffers: [
|
|
3450
3572
|
{
|
|
@@ -3505,10 +3627,10 @@ function Ce(c, t, e, i = {}) {
|
|
|
3505
3627
|
]
|
|
3506
3628
|
},
|
|
3507
3629
|
fragment: {
|
|
3508
|
-
module:
|
|
3630
|
+
module: m,
|
|
3509
3631
|
entryPoint: "fs_main",
|
|
3510
3632
|
targets: [{
|
|
3511
|
-
format:
|
|
3633
|
+
format: le,
|
|
3512
3634
|
writeMask: 0
|
|
3513
3635
|
// No color write — depth only
|
|
3514
3636
|
}]
|
|
@@ -3523,33 +3645,33 @@ function Ce(c, t, e, i = {}) {
|
|
|
3523
3645
|
// Always write depth (don't self-occlude)
|
|
3524
3646
|
format: "depth24plus"
|
|
3525
3647
|
}
|
|
3526
|
-
}),
|
|
3527
|
-
layout:
|
|
3648
|
+
}), L = r.createRenderPipeline({
|
|
3649
|
+
layout: f,
|
|
3528
3650
|
vertex: {
|
|
3529
|
-
module:
|
|
3651
|
+
module: S,
|
|
3530
3652
|
entryPoint: "vs_main"
|
|
3531
3653
|
},
|
|
3532
3654
|
fragment: {
|
|
3533
|
-
module:
|
|
3655
|
+
module: S,
|
|
3534
3656
|
entryPoint: "fs_main",
|
|
3535
3657
|
targets: [{
|
|
3536
|
-
format:
|
|
3658
|
+
format: le
|
|
3537
3659
|
}]
|
|
3538
3660
|
},
|
|
3539
3661
|
primitive: {
|
|
3540
3662
|
topology: "triangle-list"
|
|
3541
3663
|
}
|
|
3542
|
-
}),
|
|
3543
|
-
layout:
|
|
3664
|
+
}), N = r.createRenderPipeline({
|
|
3665
|
+
layout: h,
|
|
3544
3666
|
vertex: {
|
|
3545
|
-
module:
|
|
3667
|
+
module: R,
|
|
3546
3668
|
entryPoint: "vs_main"
|
|
3547
3669
|
},
|
|
3548
3670
|
fragment: {
|
|
3549
|
-
module:
|
|
3671
|
+
module: R,
|
|
3550
3672
|
entryPoint: "fs_main",
|
|
3551
3673
|
targets: [{
|
|
3552
|
-
format:
|
|
3674
|
+
format: le,
|
|
3553
3675
|
blend: {
|
|
3554
3676
|
color: {
|
|
3555
3677
|
srcFactor: "one",
|
|
@@ -3567,17 +3689,17 @@ function Ce(c, t, e, i = {}) {
|
|
|
3567
3689
|
primitive: {
|
|
3568
3690
|
topology: "triangle-list"
|
|
3569
3691
|
}
|
|
3570
|
-
}),
|
|
3571
|
-
layout:
|
|
3692
|
+
}), k = r.createRenderPipeline({
|
|
3693
|
+
layout: h,
|
|
3572
3694
|
vertex: {
|
|
3573
|
-
module:
|
|
3695
|
+
module: D,
|
|
3574
3696
|
entryPoint: "vs_main"
|
|
3575
3697
|
},
|
|
3576
3698
|
fragment: {
|
|
3577
|
-
module:
|
|
3699
|
+
module: D,
|
|
3578
3700
|
entryPoint: "fs_main",
|
|
3579
3701
|
targets: [{
|
|
3580
|
-
format:
|
|
3702
|
+
format: le,
|
|
3581
3703
|
blend: {
|
|
3582
3704
|
color: {
|
|
3583
3705
|
srcFactor: "one",
|
|
@@ -3595,12 +3717,27 @@ function Ce(c, t, e, i = {}) {
|
|
|
3595
3717
|
primitive: {
|
|
3596
3718
|
topology: "triangle-list"
|
|
3597
3719
|
}
|
|
3598
|
-
}),
|
|
3720
|
+
}), X = r.createShaderModule({ code: Pi }), z = r.createRenderPipeline({
|
|
3721
|
+
layout: h,
|
|
3722
|
+
vertex: { module: X, entryPoint: "vs_main" },
|
|
3723
|
+
fragment: {
|
|
3724
|
+
module: X,
|
|
3725
|
+
entryPoint: "fs_main",
|
|
3726
|
+
targets: [{
|
|
3727
|
+
format: t,
|
|
3728
|
+
blend: {
|
|
3729
|
+
color: { srcFactor: "one", dstFactor: "one-minus-src-alpha", operation: "add" },
|
|
3730
|
+
alpha: { srcFactor: "one", dstFactor: "one-minus-src-alpha", operation: "add" }
|
|
3731
|
+
}
|
|
3732
|
+
}]
|
|
3733
|
+
},
|
|
3734
|
+
primitive: { topology: "triangle-list" }
|
|
3735
|
+
}), me = r.createPipelineLayout({
|
|
3599
3736
|
bindGroupLayouts: [l]
|
|
3600
|
-
}),
|
|
3601
|
-
layout:
|
|
3737
|
+
}), De = r.createRenderPipeline({
|
|
3738
|
+
layout: me,
|
|
3602
3739
|
vertex: {
|
|
3603
|
-
module:
|
|
3740
|
+
module: C,
|
|
3604
3741
|
entryPoint: "vs_main",
|
|
3605
3742
|
buffers: [
|
|
3606
3743
|
{
|
|
@@ -3625,10 +3762,10 @@ function Ce(c, t, e, i = {}) {
|
|
|
3625
3762
|
]
|
|
3626
3763
|
},
|
|
3627
3764
|
fragment: {
|
|
3628
|
-
module:
|
|
3765
|
+
module: C,
|
|
3629
3766
|
entryPoint: "fs_main",
|
|
3630
3767
|
targets: [{
|
|
3631
|
-
format:
|
|
3768
|
+
format: le,
|
|
3632
3769
|
blend: {
|
|
3633
3770
|
color: {
|
|
3634
3771
|
srcFactor: "src-alpha",
|
|
@@ -3649,13 +3786,13 @@ function Ce(c, t, e, i = {}) {
|
|
|
3649
3786
|
},
|
|
3650
3787
|
depthStencil: {
|
|
3651
3788
|
depthWriteEnabled: !0,
|
|
3652
|
-
depthCompare:
|
|
3789
|
+
depthCompare: n,
|
|
3653
3790
|
format: "depth24plus"
|
|
3654
3791
|
}
|
|
3655
|
-
}),
|
|
3656
|
-
layout:
|
|
3792
|
+
}), ze = r.createRenderPipeline({
|
|
3793
|
+
layout: u,
|
|
3657
3794
|
vertex: {
|
|
3658
|
-
module:
|
|
3795
|
+
module: B,
|
|
3659
3796
|
entryPoint: "vs_main",
|
|
3660
3797
|
buffers: [
|
|
3661
3798
|
{
|
|
@@ -3727,10 +3864,10 @@ function Ce(c, t, e, i = {}) {
|
|
|
3727
3864
|
]
|
|
3728
3865
|
},
|
|
3729
3866
|
fragment: {
|
|
3730
|
-
module:
|
|
3867
|
+
module: B,
|
|
3731
3868
|
entryPoint: "fs_main",
|
|
3732
3869
|
targets: [{
|
|
3733
|
-
format:
|
|
3870
|
+
format: le,
|
|
3734
3871
|
blend: {
|
|
3735
3872
|
color: {
|
|
3736
3873
|
srcFactor: "src-alpha",
|
|
@@ -3751,33 +3888,35 @@ function Ce(c, t, e, i = {}) {
|
|
|
3751
3888
|
},
|
|
3752
3889
|
depthStencil: {
|
|
3753
3890
|
depthWriteEnabled: !0,
|
|
3754
|
-
depthCompare:
|
|
3891
|
+
depthCompare: n,
|
|
3755
3892
|
format: "depth24plus"
|
|
3756
3893
|
}
|
|
3757
3894
|
});
|
|
3758
3895
|
return {
|
|
3759
|
-
particlePipeline:
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3896
|
+
particlePipeline: P,
|
|
3897
|
+
particleAdditivePipeline: _,
|
|
3898
|
+
particleDepthWritePipeline: T,
|
|
3899
|
+
blurPipeline: L,
|
|
3900
|
+
compositePipeline: N,
|
|
3901
|
+
directRenderPipeline: k,
|
|
3902
|
+
finalCompositePipeline: z,
|
|
3903
|
+
object3dPipeline: De,
|
|
3904
|
+
glbMeshPipeline: ze
|
|
3766
3905
|
};
|
|
3767
3906
|
}
|
|
3768
|
-
function
|
|
3907
|
+
function St(r, t, e, i) {
|
|
3769
3908
|
const {
|
|
3770
3909
|
uniformBuffer: s,
|
|
3771
|
-
appearanceUniformBuffer:
|
|
3772
|
-
horizontalBlurUniformBuffer:
|
|
3773
|
-
verticalBlurUniformBuffer:
|
|
3774
|
-
bloomIntensityBuffer:
|
|
3910
|
+
appearanceUniformBuffer: n,
|
|
3911
|
+
horizontalBlurUniformBuffer: o,
|
|
3912
|
+
verticalBlurUniformBuffer: a,
|
|
3913
|
+
bloomIntensityBuffer: c
|
|
3775
3914
|
} = e, {
|
|
3776
3915
|
sceneTexture: l,
|
|
3777
|
-
bloomTexA:
|
|
3778
|
-
bloomTexB:
|
|
3779
|
-
} = i,
|
|
3780
|
-
layout:
|
|
3916
|
+
bloomTexA: u,
|
|
3917
|
+
bloomTexB: f
|
|
3918
|
+
} = i, h = r.createBindGroup({
|
|
3919
|
+
layout: r.createBindGroupLayout({
|
|
3781
3920
|
entries: [
|
|
3782
3921
|
{
|
|
3783
3922
|
binding: 0,
|
|
@@ -3798,11 +3937,11 @@ function Ee(c, t, e, i) {
|
|
|
3798
3937
|
},
|
|
3799
3938
|
{
|
|
3800
3939
|
binding: 1,
|
|
3801
|
-
resource: { buffer:
|
|
3940
|
+
resource: { buffer: n }
|
|
3802
3941
|
}
|
|
3803
3942
|
]
|
|
3804
|
-
}),
|
|
3805
|
-
layout:
|
|
3943
|
+
}), m = r.createBindGroup({
|
|
3944
|
+
layout: r.createBindGroupLayout({
|
|
3806
3945
|
entries: [
|
|
3807
3946
|
{
|
|
3808
3947
|
binding: 0,
|
|
@@ -3832,11 +3971,11 @@ function Ee(c, t, e, i) {
|
|
|
3832
3971
|
},
|
|
3833
3972
|
{
|
|
3834
3973
|
binding: 2,
|
|
3835
|
-
resource: { buffer:
|
|
3974
|
+
resource: { buffer: o }
|
|
3836
3975
|
}
|
|
3837
3976
|
]
|
|
3838
|
-
}),
|
|
3839
|
-
layout:
|
|
3977
|
+
}), S = r.createBindGroup({
|
|
3978
|
+
layout: r.createBindGroupLayout({
|
|
3840
3979
|
entries: [
|
|
3841
3980
|
{
|
|
3842
3981
|
binding: 0,
|
|
@@ -3862,15 +4001,15 @@ function Ee(c, t, e, i) {
|
|
|
3862
4001
|
},
|
|
3863
4002
|
{
|
|
3864
4003
|
binding: 1,
|
|
3865
|
-
resource:
|
|
4004
|
+
resource: u.createView()
|
|
3866
4005
|
},
|
|
3867
4006
|
{
|
|
3868
4007
|
binding: 2,
|
|
3869
|
-
resource: { buffer:
|
|
4008
|
+
resource: { buffer: a }
|
|
3870
4009
|
}
|
|
3871
4010
|
]
|
|
3872
|
-
}),
|
|
3873
|
-
layout:
|
|
4011
|
+
}), R = r.createBindGroup({
|
|
4012
|
+
layout: r.createBindGroupLayout({
|
|
3874
4013
|
entries: [
|
|
3875
4014
|
{
|
|
3876
4015
|
binding: 0,
|
|
@@ -3905,15 +4044,15 @@ function Ee(c, t, e, i) {
|
|
|
3905
4044
|
},
|
|
3906
4045
|
{
|
|
3907
4046
|
binding: 2,
|
|
3908
|
-
resource:
|
|
4047
|
+
resource: f.createView()
|
|
3909
4048
|
},
|
|
3910
4049
|
{
|
|
3911
4050
|
binding: 3,
|
|
3912
|
-
resource: { buffer:
|
|
4051
|
+
resource: { buffer: c }
|
|
3913
4052
|
}
|
|
3914
4053
|
]
|
|
3915
|
-
}),
|
|
3916
|
-
layout:
|
|
4054
|
+
}), D = r.createBindGroup({
|
|
4055
|
+
layout: r.createBindGroupLayout({
|
|
3917
4056
|
entries: [
|
|
3918
4057
|
{
|
|
3919
4058
|
binding: 0,
|
|
@@ -3948,24 +4087,24 @@ function Ee(c, t, e, i) {
|
|
|
3948
4087
|
},
|
|
3949
4088
|
{
|
|
3950
4089
|
binding: 2,
|
|
3951
|
-
resource:
|
|
4090
|
+
resource: f.createView()
|
|
3952
4091
|
},
|
|
3953
4092
|
{
|
|
3954
4093
|
binding: 3,
|
|
3955
|
-
resource: { buffer:
|
|
4094
|
+
resource: { buffer: c }
|
|
3956
4095
|
}
|
|
3957
4096
|
]
|
|
3958
4097
|
});
|
|
3959
4098
|
return {
|
|
3960
|
-
particleBindGroup:
|
|
3961
|
-
horizontalBlurBindGroup:
|
|
3962
|
-
verticalBlurBindGroup:
|
|
3963
|
-
compositeBindGroup:
|
|
3964
|
-
directRenderBindGroup:
|
|
4099
|
+
particleBindGroup: h,
|
|
4100
|
+
horizontalBlurBindGroup: m,
|
|
4101
|
+
verticalBlurBindGroup: S,
|
|
4102
|
+
compositeBindGroup: R,
|
|
4103
|
+
directRenderBindGroup: D
|
|
3965
4104
|
};
|
|
3966
4105
|
}
|
|
3967
|
-
function
|
|
3968
|
-
return
|
|
4106
|
+
function Vs(r) {
|
|
4107
|
+
return r.createSampler({
|
|
3969
4108
|
magFilter: "linear",
|
|
3970
4109
|
minFilter: "linear",
|
|
3971
4110
|
mipmapFilter: "linear",
|
|
@@ -3974,8 +4113,8 @@ function Ae(c) {
|
|
|
3974
4113
|
maxAnisotropy: 16
|
|
3975
4114
|
});
|
|
3976
4115
|
}
|
|
3977
|
-
function
|
|
3978
|
-
const
|
|
4116
|
+
function Fs() {
|
|
4117
|
+
const r = new Float32Array([
|
|
3979
4118
|
// Front face (z = 0.5)
|
|
3980
4119
|
-0.5,
|
|
3981
4120
|
-0.5,
|
|
@@ -4170,38 +4309,38 @@ function xe() {
|
|
|
4170
4309
|
23
|
|
4171
4310
|
// left
|
|
4172
4311
|
]);
|
|
4173
|
-
return { vertices:
|
|
4312
|
+
return { vertices: r, indices: t };
|
|
4174
4313
|
}
|
|
4175
|
-
function
|
|
4314
|
+
function Os(r = 16, t = 16) {
|
|
4176
4315
|
const e = [], i = [];
|
|
4177
|
-
for (let s = 0; s <=
|
|
4178
|
-
const
|
|
4179
|
-
for (let
|
|
4180
|
-
const l =
|
|
4181
|
-
e.push(
|
|
4316
|
+
for (let s = 0; s <= r; s++) {
|
|
4317
|
+
const n = s * Math.PI / r, o = Math.sin(n), a = Math.cos(n);
|
|
4318
|
+
for (let c = 0; c <= t; c++) {
|
|
4319
|
+
const l = c * 2 * Math.PI / t, u = Math.sin(l), h = Math.cos(l) * o, m = a, S = u * o;
|
|
4320
|
+
e.push(h * 0.5, m * 0.5, S * 0.5), e.push(h, m, S);
|
|
4182
4321
|
}
|
|
4183
4322
|
}
|
|
4184
|
-
for (let s = 0; s <
|
|
4185
|
-
for (let
|
|
4186
|
-
const
|
|
4187
|
-
i.push(
|
|
4323
|
+
for (let s = 0; s < r; s++)
|
|
4324
|
+
for (let n = 0; n < t; n++) {
|
|
4325
|
+
const o = s * (t + 1) + n, a = o + t + 1;
|
|
4326
|
+
i.push(o), i.push(a), i.push(o + 1), i.push(a), i.push(a + 1), i.push(o + 1);
|
|
4188
4327
|
}
|
|
4189
4328
|
return {
|
|
4190
4329
|
vertices: new Float32Array(e),
|
|
4191
4330
|
indices: new Uint16Array(i)
|
|
4192
4331
|
};
|
|
4193
4332
|
}
|
|
4194
|
-
class
|
|
4195
|
-
constructor(t, e, i, s,
|
|
4196
|
-
this.id = t, this.type = e, this.position = i, this.scale = s, this.color =
|
|
4333
|
+
class Ls {
|
|
4334
|
+
constructor(t, e, i, s, n) {
|
|
4335
|
+
this.id = t, this.type = e, this.position = i, this.scale = s, this.color = n, this.rotation = [0, 0, 0];
|
|
4197
4336
|
}
|
|
4198
4337
|
/**
|
|
4199
4338
|
* Get the model matrix for this object
|
|
4200
4339
|
*/
|
|
4201
4340
|
getModelMatrix() {
|
|
4202
|
-
const { position: t, scale: e, rotation: i } = this, s = this.createTranslationMatrix(t),
|
|
4341
|
+
const { position: t, scale: e, rotation: i } = this, s = this.createTranslationMatrix(t), n = this.createRotationMatrixX(i[0]), o = this.createRotationMatrixY(i[1]), a = this.createRotationMatrixZ(i[2]), c = this.createScaleMatrix(e);
|
|
4203
4342
|
let l = s;
|
|
4204
|
-
return l = this.multiplyMatrices(l,
|
|
4343
|
+
return l = this.multiplyMatrices(l, a), l = this.multiplyMatrices(l, o), l = this.multiplyMatrices(l, n), l = this.multiplyMatrices(l, c), l;
|
|
4205
4344
|
}
|
|
4206
4345
|
/**
|
|
4207
4346
|
* Get the normal matrix (inverse transpose of model matrix)
|
|
@@ -4316,16 +4455,16 @@ class _e {
|
|
|
4316
4455
|
multiplyMatrices(t, e) {
|
|
4317
4456
|
const i = new Float32Array(16);
|
|
4318
4457
|
for (let s = 0; s < 4; s++)
|
|
4319
|
-
for (let
|
|
4320
|
-
let
|
|
4321
|
-
for (let
|
|
4322
|
-
|
|
4323
|
-
i[s * 4 +
|
|
4458
|
+
for (let n = 0; n < 4; n++) {
|
|
4459
|
+
let o = 0;
|
|
4460
|
+
for (let a = 0; a < 4; a++)
|
|
4461
|
+
o += t[s * 4 + a] * e[a * 4 + n];
|
|
4462
|
+
i[s * 4 + n] = o;
|
|
4324
4463
|
}
|
|
4325
4464
|
return i;
|
|
4326
4465
|
}
|
|
4327
4466
|
}
|
|
4328
|
-
class
|
|
4467
|
+
class Zs {
|
|
4329
4468
|
constructor(t) {
|
|
4330
4469
|
this.device = t, this.objects = [], this.nextId = 0, this.initializeGeometry(), this.onObjectAdded = null, this.onObjectRemoved = null, this.onObjectUpdated = null;
|
|
4331
4470
|
}
|
|
@@ -4333,20 +4472,20 @@ class Ie {
|
|
|
4333
4472
|
* Initialize geometry buffers for cube and sphere
|
|
4334
4473
|
*/
|
|
4335
4474
|
initializeGeometry() {
|
|
4336
|
-
const t =
|
|
4337
|
-
this.cubeVertexBuffer =
|
|
4475
|
+
const t = Fs(), e = Os(16, 16);
|
|
4476
|
+
this.cubeVertexBuffer = Ge(
|
|
4338
4477
|
this.device,
|
|
4339
4478
|
t.vertices,
|
|
4340
4479
|
GPUBufferUsage.VERTEX
|
|
4341
|
-
), this.cubeIndexBuffer =
|
|
4480
|
+
), this.cubeIndexBuffer = Ge(
|
|
4342
4481
|
this.device,
|
|
4343
4482
|
t.indices,
|
|
4344
4483
|
GPUBufferUsage.INDEX
|
|
4345
|
-
), this.cubeIndexCount = t.indices.length, this.sphereVertexBuffer =
|
|
4484
|
+
), this.cubeIndexCount = t.indices.length, this.sphereVertexBuffer = Ge(
|
|
4346
4485
|
this.device,
|
|
4347
4486
|
e.vertices,
|
|
4348
4487
|
GPUBufferUsage.VERTEX
|
|
4349
|
-
), this.sphereIndexBuffer =
|
|
4488
|
+
), this.sphereIndexBuffer = Ge(
|
|
4350
4489
|
this.device,
|
|
4351
4490
|
e.indices,
|
|
4352
4491
|
GPUBufferUsage.INDEX
|
|
@@ -4361,12 +4500,12 @@ class Ie {
|
|
|
4361
4500
|
* @returns {Object3D} The created object
|
|
4362
4501
|
*/
|
|
4363
4502
|
addObject(t, e = [0, 0, 0], i = [1, 1, 1], s = [1, 1, 1, 1]) {
|
|
4364
|
-
const
|
|
4365
|
-
return
|
|
4503
|
+
const n = new Ls(this.nextId++, t, e, i, s);
|
|
4504
|
+
return n.uniformBuffer = this.device.createBuffer({
|
|
4366
4505
|
size: 192,
|
|
4367
4506
|
// modelMatrix (64) + normalMatrix (64) + color (16) + padding (48)
|
|
4368
4507
|
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
|
|
4369
|
-
}), this.objects.push(
|
|
4508
|
+
}), this.objects.push(n), this.onObjectAdded && this.onObjectAdded(n), n;
|
|
4370
4509
|
}
|
|
4371
4510
|
/**
|
|
4372
4511
|
* Remove an object by ID
|
|
@@ -4430,64 +4569,64 @@ class Ie {
|
|
|
4430
4569
|
* @param {GPUBindGroup} cameraBindGroup - Bind group with camera uniforms
|
|
4431
4570
|
*/
|
|
4432
4571
|
renderObjects(t, e, i, s) {
|
|
4433
|
-
for (const
|
|
4434
|
-
this.updateObjectUniforms(
|
|
4435
|
-
const
|
|
4572
|
+
for (const n of this.objects) {
|
|
4573
|
+
this.updateObjectUniforms(n);
|
|
4574
|
+
const o = this.device.createBindGroup({
|
|
4436
4575
|
layout: i,
|
|
4437
4576
|
entries: [
|
|
4438
4577
|
{ binding: 0, resource: { buffer: s } },
|
|
4439
|
-
{ binding: 1, resource: { buffer:
|
|
4578
|
+
{ binding: 1, resource: { buffer: n.uniformBuffer } }
|
|
4440
4579
|
]
|
|
4441
4580
|
});
|
|
4442
|
-
let
|
|
4443
|
-
if (
|
|
4444
|
-
|
|
4445
|
-
else if (
|
|
4446
|
-
|
|
4581
|
+
let a, c, l;
|
|
4582
|
+
if (n.type === "cube")
|
|
4583
|
+
a = this.cubeVertexBuffer, c = this.cubeIndexBuffer, l = this.cubeIndexCount;
|
|
4584
|
+
else if (n.type === "sphere")
|
|
4585
|
+
a = this.sphereVertexBuffer, c = this.sphereIndexBuffer, l = this.sphereIndexCount;
|
|
4447
4586
|
else
|
|
4448
4587
|
continue;
|
|
4449
|
-
t.setPipeline(e), t.setBindGroup(0,
|
|
4588
|
+
t.setPipeline(e), t.setBindGroup(0, o), t.setVertexBuffer(0, a), t.setIndexBuffer(c, "uint16"), t.drawIndexed(l);
|
|
4450
4589
|
}
|
|
4451
4590
|
}
|
|
4452
4591
|
}
|
|
4453
|
-
function
|
|
4454
|
-
const t = parseInt(
|
|
4592
|
+
function $s(r) {
|
|
4593
|
+
const t = parseInt(r.slice(1, 3), 16) / 255, e = parseInt(r.slice(3, 5), 16) / 255, i = parseInt(r.slice(5, 7), 16) / 255;
|
|
4455
4594
|
return [t, e, i];
|
|
4456
4595
|
}
|
|
4457
|
-
function
|
|
4458
|
-
if (!
|
|
4459
|
-
const t = Math.round(
|
|
4596
|
+
function Ws(r) {
|
|
4597
|
+
if (!r) return "#ffffff";
|
|
4598
|
+
const t = Math.round(r[0] * 255).toString(16).padStart(2, "0"), e = Math.round(r[1] * 255).toString(16).padStart(2, "0"), i = Math.round(r[2] * 255).toString(16).padStart(2, "0");
|
|
4460
4599
|
return `#${t}${e}${i}`;
|
|
4461
4600
|
}
|
|
4462
|
-
function
|
|
4463
|
-
const i =
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
]), s =
|
|
4601
|
+
function Js(r, t, e) {
|
|
4602
|
+
const i = fi([
|
|
4603
|
+
r[0] - t[0],
|
|
4604
|
+
r[1] - t[1],
|
|
4605
|
+
r[2] - t[2]
|
|
4606
|
+
]), s = fi(pi(e, i)), n = pi(i, s);
|
|
4468
4607
|
return new Float32Array([
|
|
4469
4608
|
s[0],
|
|
4470
|
-
|
|
4609
|
+
n[0],
|
|
4471
4610
|
i[0],
|
|
4472
4611
|
0,
|
|
4473
4612
|
s[1],
|
|
4474
|
-
|
|
4613
|
+
n[1],
|
|
4475
4614
|
i[1],
|
|
4476
4615
|
0,
|
|
4477
4616
|
s[2],
|
|
4478
|
-
|
|
4617
|
+
n[2],
|
|
4479
4618
|
i[2],
|
|
4480
4619
|
0,
|
|
4481
|
-
-
|
|
4482
|
-
-
|
|
4483
|
-
-
|
|
4620
|
+
-xt(s, r),
|
|
4621
|
+
-xt(n, r),
|
|
4622
|
+
-xt(i, r),
|
|
4484
4623
|
1
|
|
4485
4624
|
]);
|
|
4486
4625
|
}
|
|
4487
|
-
function
|
|
4626
|
+
function Ks(r, t = Math.PI / 4) {
|
|
4488
4627
|
const s = 1 / Math.tan(t / 2);
|
|
4489
4628
|
return new Float32Array([
|
|
4490
|
-
s *
|
|
4629
|
+
s * r,
|
|
4491
4630
|
0,
|
|
4492
4631
|
0,
|
|
4493
4632
|
0,
|
|
@@ -4505,266 +4644,1032 @@ function De(c, t = Math.PI / 4) {
|
|
|
4505
4644
|
0
|
|
4506
4645
|
]);
|
|
4507
4646
|
}
|
|
4508
|
-
function
|
|
4509
|
-
const t = Math.sqrt(
|
|
4510
|
-
return [
|
|
4647
|
+
function fi(r) {
|
|
4648
|
+
const t = Math.sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]);
|
|
4649
|
+
return [r[0] / t, r[1] / t, r[2] / t];
|
|
4511
4650
|
}
|
|
4512
|
-
function
|
|
4651
|
+
function pi(r, t) {
|
|
4513
4652
|
return [
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
4653
|
+
r[1] * t[2] - r[2] * t[1],
|
|
4654
|
+
r[2] * t[0] - r[0] * t[2],
|
|
4655
|
+
r[0] * t[1] - r[1] * t[0]
|
|
4517
4656
|
];
|
|
4518
4657
|
}
|
|
4519
|
-
function
|
|
4520
|
-
return
|
|
4658
|
+
function xt(r, t) {
|
|
4659
|
+
return r[0] * t[0] + r[1] * t[1] + r[2] * t[2];
|
|
4521
4660
|
}
|
|
4522
|
-
function
|
|
4661
|
+
function Ns(r, t) {
|
|
4523
4662
|
const e = new Float32Array(16);
|
|
4524
4663
|
for (let i = 0; i < 4; i++)
|
|
4525
4664
|
for (let s = 0; s < 4; s++) {
|
|
4526
|
-
let
|
|
4527
|
-
for (let
|
|
4528
|
-
|
|
4529
|
-
e[i + s * 4] =
|
|
4665
|
+
let n = 0;
|
|
4666
|
+
for (let o = 0; o < 4; o++)
|
|
4667
|
+
n += r[i + o * 4] * t[o + s * 4];
|
|
4668
|
+
e[i + s * 4] = n;
|
|
4530
4669
|
}
|
|
4531
4670
|
return e;
|
|
4532
4671
|
}
|
|
4533
|
-
function
|
|
4534
|
-
|
|
4672
|
+
const Pt = 1481005640, wi = 1, Bi = 1313821514, Ri = 5130562, He = "$hzfxAsset", Mi = (r) => typeof atob == "function" ? Uint8Array.from(atob(r), (t) => t.charCodeAt(0)) : new Uint8Array(Buffer.from(r, "base64")), hi = (r) => {
|
|
4673
|
+
if (typeof btoa == "function") {
|
|
4674
|
+
let t = "";
|
|
4675
|
+
for (let e = 0; e < r.length; e++) t += String.fromCharCode(r[e]);
|
|
4676
|
+
return btoa(t);
|
|
4677
|
+
}
|
|
4678
|
+
return Buffer.from(r).toString("base64");
|
|
4679
|
+
};
|
|
4680
|
+
function Xs(r) {
|
|
4681
|
+
const t = r.indexOf(","), e = r.slice(5, t), i = e.split(";")[0] || "application/octet-stream", s = r.slice(t + 1), o = /;base64/i.test(e) ? Mi(s) : new TextEncoder().encode(decodeURIComponent(s));
|
|
4682
|
+
return { mime: i, bytes: o };
|
|
4683
|
+
}
|
|
4684
|
+
function mi(r) {
|
|
4685
|
+
return (4 - r % 4) % 4;
|
|
4686
|
+
}
|
|
4687
|
+
async function ks(r, t = {}) {
|
|
4688
|
+
const { textureFormat: e = "keep", quality: i = 0.85 } = t, s = [], n = [];
|
|
4689
|
+
let o = 0;
|
|
4690
|
+
const a = (_, T, L) => {
|
|
4691
|
+
const N = o, k = _.length;
|
|
4692
|
+
s.push({ offset: N, length: k, mime: T, kind: L }), n.push(_), o += k;
|
|
4693
|
+
const X = mi(k);
|
|
4694
|
+
return X && (n.push(new Uint8Array(X)), o += X), s.length - 1;
|
|
4695
|
+
}, c = e === "webp" && typeof OffscreenCanvas < "u" && typeof createImageBitmap == "function", l = [];
|
|
4696
|
+
for (const _ of r.systems || []) {
|
|
4697
|
+
const T = { ..._ };
|
|
4698
|
+
if (typeof T.textureImageData == "string" && T.textureImageData.startsWith("data:")) {
|
|
4699
|
+
let { mime: L, bytes: N } = Xs(T.textureImageData);
|
|
4700
|
+
if (c && L !== "image/webp")
|
|
4701
|
+
try {
|
|
4702
|
+
const k = await createImageBitmap(new Blob([N], { type: L })), X = new OffscreenCanvas(k.width, k.height);
|
|
4703
|
+
X.getContext("2d").drawImage(k, 0, 0);
|
|
4704
|
+
const z = await X.convertToBlob({ type: "image/webp", quality: i }), me = new Uint8Array(await z.arrayBuffer());
|
|
4705
|
+
me.length < N.length && (N = me, L = "image/webp");
|
|
4706
|
+
} catch {
|
|
4707
|
+
}
|
|
4708
|
+
T.textureImageData = { [He]: a(N, L, "texture") };
|
|
4709
|
+
}
|
|
4710
|
+
if (typeof T.glbModelData == "string" && T.glbModelData.length > 0) {
|
|
4711
|
+
const L = Mi(T.glbModelData);
|
|
4712
|
+
T.glbModelData = { [He]: a(L, "model/gltf-binary", "glb") };
|
|
4713
|
+
}
|
|
4714
|
+
l.push(T);
|
|
4715
|
+
}
|
|
4716
|
+
const u = { ...r, systems: l, assets: s }, f = new TextEncoder().encode(JSON.stringify(u)), h = mi(f.length), m = new Uint8Array(o);
|
|
4717
|
+
let S = 0;
|
|
4718
|
+
for (const _ of n)
|
|
4719
|
+
m.set(_, S), S += _.length;
|
|
4720
|
+
const R = f.length + h, D = 20 + R + 8 + o, C = new ArrayBuffer(D), B = new DataView(C), A = new Uint8Array(C);
|
|
4721
|
+
let P = 0;
|
|
4722
|
+
B.setUint32(P, Pt, !0), P += 4, B.setUint32(P, wi, !0), P += 4, B.setUint32(P, D, !0), P += 4, B.setUint32(P, R, !0), P += 4, B.setUint32(P, Bi, !0), P += 4, A.set(f, P), P += f.length;
|
|
4723
|
+
for (let _ = 0; _ < h; _++) A[P++] = 32;
|
|
4724
|
+
return B.setUint32(P, o, !0), P += 4, B.setUint32(P, Ri, !0), P += 4, A.set(m, P), P += o, C;
|
|
4725
|
+
}
|
|
4726
|
+
function Ti(r) {
|
|
4727
|
+
return !r || r.byteLength < 12 ? !1 : new DataView(r).getUint32(0, !0) === Pt;
|
|
4728
|
+
}
|
|
4729
|
+
function Ei(r) {
|
|
4730
|
+
const t = new DataView(r);
|
|
4731
|
+
if (t.getUint32(0, !0) !== Pt) throw new Error("[unpackHZFX] bad magic — not an .hzfx file");
|
|
4732
|
+
const e = t.getUint32(4, !0);
|
|
4733
|
+
if (e !== wi) throw new Error(`[unpackHZFX] unsupported version ${e}`);
|
|
4734
|
+
let i = 12, s = null, n = -1;
|
|
4735
|
+
const o = new Uint8Array(r);
|
|
4736
|
+
for (; i + 8 <= r.byteLength; ) {
|
|
4737
|
+
const h = t.getUint32(i, !0);
|
|
4738
|
+
i += 4;
|
|
4739
|
+
const m = t.getUint32(i, !0);
|
|
4740
|
+
i += 4, m === Bi ? s = JSON.parse(new TextDecoder().decode(o.subarray(i, i + h))) : m === Ri && (n = i), i += h;
|
|
4741
|
+
}
|
|
4742
|
+
if (!s) throw new Error("[unpackHZFX] missing JSON chunk");
|
|
4743
|
+
const a = s.assets || [], c = (h) => {
|
|
4744
|
+
const m = a[h];
|
|
4745
|
+
return !m || n < 0 ? null : { ...m, bytes: o.subarray(n + m.offset, n + m.offset + m.length) };
|
|
4746
|
+
}, l = (h) => h && typeof h == "object" && typeof h[He] == "number", u = (s.systems || []).map((h) => {
|
|
4747
|
+
const m = { ...h };
|
|
4748
|
+
if (l(m.textureImageData)) {
|
|
4749
|
+
const S = c(m.textureImageData[He]);
|
|
4750
|
+
m.textureImageData = S ? `data:${S.mime};base64,${hi(S.bytes)}` : void 0;
|
|
4751
|
+
}
|
|
4752
|
+
if (l(m.glbModelData)) {
|
|
4753
|
+
const S = c(m.glbModelData[He]);
|
|
4754
|
+
m.glbModelData = S ? hi(S.bytes) : void 0;
|
|
4755
|
+
}
|
|
4756
|
+
return m;
|
|
4757
|
+
}), f = { ...s, systems: u };
|
|
4758
|
+
return delete f.assets, f;
|
|
4759
|
+
}
|
|
4760
|
+
function js(r) {
|
|
4761
|
+
const t = new Uint8Array(r);
|
|
4535
4762
|
let e = "";
|
|
4536
4763
|
for (let i = 0; i < t.byteLength; i++)
|
|
4537
4764
|
e += String.fromCharCode(t[i]);
|
|
4538
4765
|
return btoa(e);
|
|
4539
4766
|
}
|
|
4540
|
-
function
|
|
4541
|
-
|
|
4767
|
+
function Ys(r) {
|
|
4768
|
+
return {
|
|
4769
|
+
name: r.name,
|
|
4770
|
+
id: r.id,
|
|
4771
|
+
particleCount: r.particleCount,
|
|
4772
|
+
lifetime: r.lifetime,
|
|
4773
|
+
emissionRate: r.emissionRate,
|
|
4774
|
+
emissionDuration: r.emissionDuration,
|
|
4775
|
+
emissionDurationInfinite: r.emissionDurationInfinite || !1,
|
|
4776
|
+
particleSize: r.particleSize,
|
|
4777
|
+
particleSpeed: r.particleSpeed,
|
|
4778
|
+
emissionShape: r.emissionShape,
|
|
4779
|
+
outerLength: r.outerLength ?? r.cubeLength,
|
|
4780
|
+
// cubeLength = legacy alias; migrate to outerLength
|
|
4781
|
+
innerLength: r.innerLength,
|
|
4782
|
+
outerRadius: r.outerRadius,
|
|
4783
|
+
innerRadius: r.innerRadius,
|
|
4784
|
+
squareSize: r.squareSize,
|
|
4785
|
+
squareInnerSize: r.squareInnerSize,
|
|
4786
|
+
circleInnerRadius: r.circleInnerRadius,
|
|
4787
|
+
circleOuterRadius: r.circleOuterRadius,
|
|
4788
|
+
fadeEnabled: r.fadeEnabled,
|
|
4789
|
+
colorTransitionEnabled: r.colorTransitionEnabled,
|
|
4790
|
+
particleColor: r.particleColor,
|
|
4791
|
+
startColor: r.startColor,
|
|
4792
|
+
endColor: r.endColor,
|
|
4793
|
+
randomColorEnabled: r.randomColorEnabled || !1,
|
|
4794
|
+
randomColors: r.randomColors || [],
|
|
4795
|
+
particleShape: r.particleShape || "square",
|
|
4796
|
+
particleShapeRotationX: r.particleShapeRotationX || 0,
|
|
4797
|
+
particleShapeRotationY: r.particleShapeRotationY || 0,
|
|
4798
|
+
particleShapeRotationZ: r.particleShapeRotationZ || 0,
|
|
4799
|
+
pulseEnabled: r.pulseEnabled || !1,
|
|
4800
|
+
pulseAmplitude: r.pulseAmplitude ?? 0.5,
|
|
4801
|
+
pulseFrequency: r.pulseFrequency ?? 1,
|
|
4802
|
+
pulsePhaseRandom: r.pulsePhaseRandom ?? 0,
|
|
4803
|
+
pulseOpacity: r.pulseOpacity || !1,
|
|
4804
|
+
bloomEnabled: r.bloomEnabled,
|
|
4805
|
+
bloomIntensity: r.bloomIntensity,
|
|
4806
|
+
bloomColor: r.bloomColor,
|
|
4807
|
+
depthWriteEnabled: r.depthWriteEnabled || !1,
|
|
4808
|
+
burstMode: r.burstMode,
|
|
4809
|
+
gravityEnabled: r.gravityEnabled,
|
|
4810
|
+
gravityStrength: r.gravityStrength,
|
|
4811
|
+
dampingEnabled: r.dampingEnabled,
|
|
4812
|
+
dampingStrength: r.dampingStrength,
|
|
4813
|
+
attractorEnabled: r.attractorEnabled,
|
|
4814
|
+
attractorStrength: r.attractorStrength,
|
|
4815
|
+
attractorPosition: r.attractorPosition,
|
|
4816
|
+
emissionRotationX: r.emissionRotationX,
|
|
4817
|
+
emissionRotationY: r.emissionRotationY,
|
|
4818
|
+
emissionRotationZ: r.emissionRotationZ,
|
|
4819
|
+
orientToDirection: r.orientToDirection ?? !1,
|
|
4820
|
+
emissionPositionX: r.emissionPositionX,
|
|
4821
|
+
emissionPositionY: r.emissionPositionY,
|
|
4822
|
+
emissionPositionZ: r.emissionPositionZ,
|
|
4823
|
+
rotation: r.rotation,
|
|
4824
|
+
rotationMode: r.rotationMode,
|
|
4825
|
+
minRotation: r.minRotation,
|
|
4826
|
+
maxRotation: r.maxRotation,
|
|
4827
|
+
overrideXVelocity: r.overrideXVelocity,
|
|
4828
|
+
overrideYVelocity: r.overrideYVelocity,
|
|
4829
|
+
overrideZVelocity: r.overrideZVelocity,
|
|
4830
|
+
xVelocity: r.xVelocity,
|
|
4831
|
+
yVelocity: r.yVelocity,
|
|
4832
|
+
zVelocity: r.zVelocity,
|
|
4833
|
+
circleVelocityDirection: r.circleVelocityDirection,
|
|
4834
|
+
cylinderVelocityDirection: r.cylinderVelocityDirection,
|
|
4835
|
+
cylinderInnerRadius: r.cylinderInnerRadius,
|
|
4836
|
+
cylinderOuterRadius: r.cylinderOuterRadius,
|
|
4837
|
+
cylinderHeight: r.cylinderHeight,
|
|
4838
|
+
planeWidth: r.planeWidth,
|
|
4839
|
+
planeDepth: r.planeDepth,
|
|
4840
|
+
rectangleWidth: r.rectangleWidth,
|
|
4841
|
+
rectangleHeight: r.rectangleHeight,
|
|
4842
|
+
coneOuterRadius: r.coneOuterRadius,
|
|
4843
|
+
coneInnerRadius: r.coneInnerRadius,
|
|
4844
|
+
coneHeight: r.coneHeight,
|
|
4845
|
+
torusMajorRadius: r.torusMajorRadius,
|
|
4846
|
+
torusMinorRadius: r.torusMinorRadius,
|
|
4847
|
+
lineLength: r.lineLength,
|
|
4848
|
+
hemisphereOuterRadius: r.hemisphereOuterRadius,
|
|
4849
|
+
hemisphereInnerRadius: r.hemisphereInnerRadius,
|
|
4850
|
+
discRadius: r.discRadius,
|
|
4851
|
+
annulusInnerRadius: r.annulusInnerRadius,
|
|
4852
|
+
annulusOuterRadius: r.annulusOuterRadius,
|
|
4853
|
+
capsuleRadius: r.capsuleRadius,
|
|
4854
|
+
capsuleHeight: r.capsuleHeight,
|
|
4855
|
+
arcStartAngle: r.arcStartAngle,
|
|
4856
|
+
arcEndAngle: r.arcEndAngle,
|
|
4857
|
+
arcInnerRadius: r.arcInnerRadius,
|
|
4858
|
+
arcOuterRadius: r.arcOuterRadius,
|
|
4859
|
+
spiralTurns: r.spiralTurns,
|
|
4860
|
+
spiralRadiusStart: r.spiralRadiusStart,
|
|
4861
|
+
spiralRadiusEnd: r.spiralRadiusEnd,
|
|
4862
|
+
spiralHeight: r.spiralHeight,
|
|
4863
|
+
frustumRadiusNear: r.frustumRadiusNear,
|
|
4864
|
+
frustumRadiusFar: r.frustumRadiusFar,
|
|
4865
|
+
frustumHeight: r.frustumHeight,
|
|
4866
|
+
cubeSurfaceSize: r.cubeSurfaceSize,
|
|
4867
|
+
sphereSurfaceRadius: r.sphereSurfaceRadius,
|
|
4868
|
+
boxFrameSize: r.boxFrameSize,
|
|
4869
|
+
polygonSides: r.polygonSides,
|
|
4870
|
+
polygonRadius: r.polygonRadius,
|
|
4871
|
+
aspectRatio: r.aspectRatio,
|
|
4872
|
+
randomSize: r.randomSize,
|
|
4873
|
+
minSize: r.minSize,
|
|
4874
|
+
maxSize: r.maxSize,
|
|
4875
|
+
fadeSizeEnabled: r.fadeSizeEnabled,
|
|
4876
|
+
increaseSizeEnabled: r.increaseSizeEnabled,
|
|
4877
|
+
sizeLifetimeSpeed: r.sizeLifetimeSpeed,
|
|
4878
|
+
opacity: r.opacity,
|
|
4879
|
+
randomSpeed: r.randomSpeed,
|
|
4880
|
+
minSpeed: r.minSpeed,
|
|
4881
|
+
maxSpeed: r.maxSpeed,
|
|
4882
|
+
oneOnlyMode: r.oneOnlyMode,
|
|
4883
|
+
confinementEnabled: r.confinementEnabled || !1,
|
|
4884
|
+
confinementShape: r.confinementShape || "box",
|
|
4885
|
+
confinementMode: r.confinementMode || "bounce",
|
|
4886
|
+
confinementSpace: r.confinementSpace || "world",
|
|
4887
|
+
confinementBoxHalfSize: r.confinementBoxHalfSize || [2, 2, 2],
|
|
4888
|
+
confinementSphereRadius: r.confinementSphereRadius ?? 3,
|
|
4889
|
+
confinementRestitution: r.confinementRestitution ?? 0.8,
|
|
4890
|
+
confinementFriction: r.confinementFriction ?? 0.1,
|
|
4891
|
+
confinementCenter: r.confinementCenter,
|
|
4892
|
+
softBoundaryEnabled: r.softBoundaryEnabled || !1,
|
|
4893
|
+
softBoundaryStrength: r.softBoundaryStrength ?? 5,
|
|
4894
|
+
softBoundaryFalloff: r.softBoundaryFalloff ?? 0.5,
|
|
4895
|
+
followSystemId: r.followSystemId || null,
|
|
4896
|
+
followSystemTranslation: r.followSystemTranslation ?? !0,
|
|
4897
|
+
hidden: r.hidden || !1,
|
|
4898
|
+
emissionTrailEnabled: r.emissionTrailEnabled || !1,
|
|
4899
|
+
emissionTrailDuration: r.emissionTrailDuration ?? 1,
|
|
4900
|
+
emissionTrailWidth: r.emissionTrailWidth ?? 0.5,
|
|
4901
|
+
emissionTrailMinDistance: r.emissionTrailMinDistance ?? 0.05,
|
|
4902
|
+
emissionTrailMaxPoints: r.emissionTrailMaxPoints ?? 100,
|
|
4903
|
+
emissionTrailSegments: r.emissionTrailSegments ?? 8,
|
|
4904
|
+
emissionTrailMode: r.emissionTrailMode ?? "ribbon",
|
|
4905
|
+
emissionTrailShape: r.emissionTrailShape ?? "straight",
|
|
4906
|
+
emissionTrailShapeAmplitude: r.emissionTrailShapeAmplitude ?? 0.1,
|
|
4907
|
+
emissionTrailShapeFrequency: r.emissionTrailShapeFrequency ?? 4,
|
|
4908
|
+
emissionTrailShapeSpeed: r.emissionTrailShapeSpeed ?? 0,
|
|
4909
|
+
shapeDisplay: r.shapeDisplay ?? !0,
|
|
4910
|
+
blendMode: r.blendMode ?? "normal",
|
|
4911
|
+
noiseDistortEnabled: r.noiseDistortEnabled || !1,
|
|
4912
|
+
noiseTilingX: r.noiseTilingX ?? 3,
|
|
4913
|
+
noiseTilingY: r.noiseTilingY ?? 3,
|
|
4914
|
+
noiseSpeed: r.noiseSpeed ?? -1.5,
|
|
4915
|
+
noiseAmplitude: r.noiseAmplitude ?? 0.08,
|
|
4916
|
+
velocityStretchEnabled: r.velocityStretchEnabled || !1,
|
|
4917
|
+
velocityStretchFactor: r.velocityStretchFactor ?? 1,
|
|
4918
|
+
// Texture / GLB metadata (the binary payloads — textureImageData / glbModelData — are
|
|
4919
|
+
// added by the caller since their encoding differs per export target)
|
|
4920
|
+
textureEnabled: r.textureEnabled || !1,
|
|
4921
|
+
textureType: r.textureType,
|
|
4922
|
+
textureFileName: r.textureFileName,
|
|
4923
|
+
imageDescription: r.imageDescription,
|
|
4924
|
+
glbModelEnabled: r.glbModelEnabled || !1,
|
|
4925
|
+
glbFileName: r.glbFileName,
|
|
4926
|
+
glbHasTexture: r.glbHasTexture || !1,
|
|
4927
|
+
useGlbTexture: r.useGlbTexture || !1,
|
|
4928
|
+
glbAnimated: r.glbAnimated || !1,
|
|
4929
|
+
animationIndex: r.animationIndex,
|
|
4930
|
+
animationSpeed: r.animationSpeed,
|
|
4931
|
+
animationLoop: r.animationLoop,
|
|
4932
|
+
glbDescription: r.glbDescription,
|
|
4933
|
+
script: r.script || void 0,
|
|
4934
|
+
displayUnit: r.displayUnit || "m"
|
|
4935
|
+
};
|
|
4936
|
+
}
|
|
4937
|
+
async function Qs(r, t, e = "hzfx") {
|
|
4938
|
+
if (!r || !r.particleSystems || r.particleSystems.length === 0) {
|
|
4542
4939
|
alert("No particle systems to save.");
|
|
4543
4940
|
return;
|
|
4544
4941
|
}
|
|
4545
4942
|
try {
|
|
4546
|
-
const
|
|
4943
|
+
const i = {
|
|
4547
4944
|
version: "1.0",
|
|
4548
4945
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4549
|
-
systems:
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
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,
|
|
4561
|
-
// Always use outerLength if available
|
|
4562
|
-
outerLength: a.outerLength || a.cubeLength,
|
|
4563
|
-
// Keep them synchronized
|
|
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
|
|
4946
|
+
systems: r.particleSystems.map(({ config: u, system: f }) => ({
|
|
4947
|
+
...Ys(u),
|
|
4948
|
+
// single source of truth for config fields
|
|
4949
|
+
// Binary assets embedded so replaceSystems() can restore them
|
|
4950
|
+
textureImageData: u.textureEnabled && !u.glbModelEnabled && u.textureImageData ? u.textureImageData : void 0,
|
|
4951
|
+
glbModelData: u.glbModelEnabled && f.glbRawArrayBuffer ? js(f.glbRawArrayBuffer) : void 0
|
|
4668
4952
|
})),
|
|
4669
|
-
activeSystemIndex:
|
|
4670
|
-
|
|
4671
|
-
|
|
4953
|
+
activeSystemIndex: r.activeSystemIndex,
|
|
4954
|
+
loop: r.loop || !1
|
|
4955
|
+
// group-level auto-restart
|
|
4956
|
+
}, s = e === "json" ? "json" : "hzfx";
|
|
4957
|
+
let n;
|
|
4958
|
+
if (s === "hzfx") {
|
|
4959
|
+
const u = await ks(i, { textureFormat: "webp" });
|
|
4960
|
+
n = new Blob([u], { type: "application/octet-stream" });
|
|
4961
|
+
} else
|
|
4962
|
+
n = new Blob([JSON.stringify(i, null, 2)], { type: "application/json" });
|
|
4963
|
+
let o;
|
|
4672
4964
|
if (t)
|
|
4673
|
-
|
|
4965
|
+
o = t;
|
|
4674
4966
|
else {
|
|
4675
|
-
const
|
|
4676
|
-
|
|
4967
|
+
const u = /* @__PURE__ */ new Date();
|
|
4968
|
+
o = `particle-scene_${`${u.getFullYear()}-${(u.getMonth() + 1).toString().padStart(2, "0")}-${u.getDate().toString().padStart(2, "0")}_${u.getHours().toString().padStart(2, "0")}${u.getMinutes().toString().padStart(2, "0")}`}`;
|
|
4677
4969
|
}
|
|
4678
|
-
const
|
|
4679
|
-
|
|
4680
|
-
} catch (
|
|
4681
|
-
console.error("Error saving scene:",
|
|
4970
|
+
const a = `${o}.${s}`, c = URL.createObjectURL(n), l = document.createElement("a");
|
|
4971
|
+
l.href = c, l.download = a, document.body.appendChild(l), l.click(), document.body.removeChild(l), URL.revokeObjectURL(c);
|
|
4972
|
+
} catch (i) {
|
|
4973
|
+
console.error("Error saving scene:", i), alert("Error saving scene. See console for details.");
|
|
4682
4974
|
}
|
|
4683
4975
|
}
|
|
4684
|
-
function
|
|
4976
|
+
function er(r) {
|
|
4685
4977
|
return new Promise((t, e) => {
|
|
4686
4978
|
try {
|
|
4687
|
-
const i =
|
|
4979
|
+
const i = r.target.files[0];
|
|
4688
4980
|
if (!i) {
|
|
4689
4981
|
e(new Error("No file selected"));
|
|
4690
4982
|
return;
|
|
4691
4983
|
}
|
|
4692
4984
|
const s = new FileReader();
|
|
4693
|
-
s.onload = (
|
|
4985
|
+
s.onload = (n) => {
|
|
4694
4986
|
try {
|
|
4695
|
-
const
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
if (!Array.isArray(n.systems) || n.systems.length === 0)
|
|
4987
|
+
const o = n.target.result;
|
|
4988
|
+
let a;
|
|
4989
|
+
if (Ti(o) ? a = Ei(o) : a = JSON.parse(new TextDecoder().decode(o)), !Array.isArray(a.systems) || a.systems.length === 0)
|
|
4699
4990
|
throw new Error("No valid particle systems found in the file");
|
|
4700
|
-
const o = [];
|
|
4701
|
-
for (const a of n.systems)
|
|
4702
|
-
o.push(a);
|
|
4703
4991
|
t({
|
|
4704
|
-
systems:
|
|
4705
|
-
activeSystemIndex:
|
|
4992
|
+
systems: a.systems.slice(),
|
|
4993
|
+
activeSystemIndex: a.activeSystemIndex || 0
|
|
4706
4994
|
});
|
|
4707
|
-
} catch (
|
|
4708
|
-
console.error("Error loading scene:",
|
|
4995
|
+
} catch (o) {
|
|
4996
|
+
console.error("Error loading scene:", o), alert("Error loading scene: " + o.message), e(o);
|
|
4709
4997
|
}
|
|
4710
|
-
|
|
4998
|
+
r.target.value = "";
|
|
4711
4999
|
}, s.onerror = () => {
|
|
4712
|
-
alert("Failed to read the file"), e(new Error("Failed to read the file")),
|
|
4713
|
-
}, s.
|
|
5000
|
+
alert("Failed to read the file"), e(new Error("Failed to read the file")), r.target.value = "";
|
|
5001
|
+
}, s.readAsArrayBuffer(i);
|
|
4714
5002
|
} catch (i) {
|
|
4715
5003
|
console.error("Error in loadScene:", i), e(i);
|
|
4716
5004
|
}
|
|
4717
5005
|
});
|
|
4718
5006
|
}
|
|
4719
|
-
async function
|
|
4720
|
-
if (!
|
|
5007
|
+
async function tr(r) {
|
|
5008
|
+
if (!r || typeof r != "string")
|
|
4721
5009
|
throw new Error("[fetchPreset] url must be a non-empty string");
|
|
4722
|
-
const t = await fetch(
|
|
5010
|
+
const t = await fetch(r);
|
|
4723
5011
|
if (!t.ok)
|
|
4724
5012
|
throw new Error(`[fetchPreset] HTTP ${t.status}: ${t.statusText}`);
|
|
4725
|
-
const e = await t.
|
|
4726
|
-
|
|
5013
|
+
const e = await t.arrayBuffer();
|
|
5014
|
+
let i;
|
|
5015
|
+
if (Ti(e) ? i = Ei(e) : i = JSON.parse(new TextDecoder().decode(e)), !Array.isArray(i.systems) || i.systems.length === 0)
|
|
4727
5016
|
throw new Error('[fetchPreset] Invalid preset: "systems" must be a non-empty array');
|
|
4728
5017
|
return {
|
|
4729
|
-
version:
|
|
4730
|
-
systems:
|
|
4731
|
-
activeSystemIndex:
|
|
5018
|
+
version: i.version,
|
|
5019
|
+
systems: i.systems,
|
|
5020
|
+
activeSystemIndex: i.activeSystemIndex ?? 0
|
|
5021
|
+
};
|
|
5022
|
+
}
|
|
5023
|
+
const qs = (r) => `
|
|
5024
|
+
@vertex fn vs(@builtin(vertex_index) i: u32) -> @builtin(position) vec4f {
|
|
5025
|
+
var p = array<vec2f, 3>(vec2f(-1.0, -3.0), vec2f(-1.0, 1.0), vec2f(3.0, 1.0));
|
|
5026
|
+
return vec4f(p[i], 0.0, 1.0);
|
|
5027
|
+
}
|
|
5028
|
+
@group(0) @binding(0) var src: ${r ? "texture_depth_multisampled_2d" : "texture_depth_2d"};
|
|
5029
|
+
@fragment fn fs(@builtin(position) pos: vec4f) -> @builtin(frag_depth) f32 {
|
|
5030
|
+
return textureLoad(src, vec2i(pos.xy), 0);
|
|
5031
|
+
}
|
|
5032
|
+
`;
|
|
5033
|
+
async function ir(r, t = {}) {
|
|
5034
|
+
const { getSceneDepth: e = null, autoRespawn: i = !0, respectEffectLoop: s = !0 } = t;
|
|
5035
|
+
let n, o, a;
|
|
5036
|
+
const c = !!(r && r.device && r.context);
|
|
5037
|
+
c ? ({ device: n, context: o, canvas: a } = r, a || (a = o.canvas)) : (a = r, { device: n, context: o } = await Cs(a));
|
|
5038
|
+
const l = navigator.gpu.getPreferredCanvasFormat(), u = t.manager || new Es(n), f = { layouts: {}, pipelines: {} };
|
|
5039
|
+
function h(d) {
|
|
5040
|
+
const p = d ? "ms" : "ss";
|
|
5041
|
+
if (!f.pipelines[p]) {
|
|
5042
|
+
const b = n.createShaderModule({ code: qs(d) }), y = n.createBindGroupLayout({
|
|
5043
|
+
entries: [{ binding: 0, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: "depth", multisampled: d } }]
|
|
5044
|
+
});
|
|
5045
|
+
f.layouts[p] = y, f.pipelines[p] = n.createRenderPipeline({
|
|
5046
|
+
layout: n.createPipelineLayout({ bindGroupLayouts: [y] }),
|
|
5047
|
+
vertex: { module: b, entryPoint: "vs" },
|
|
5048
|
+
fragment: { module: b, entryPoint: "fs", targets: [] },
|
|
5049
|
+
primitive: { topology: "triangle-list" },
|
|
5050
|
+
depthStencil: { format: "depth24plus", depthWriteEnabled: !0, depthCompare: "always" }
|
|
5051
|
+
});
|
|
5052
|
+
}
|
|
5053
|
+
return { pipeline: f.pipelines[p], layout: f.layouts[p] };
|
|
5054
|
+
}
|
|
5055
|
+
const m = {
|
|
5056
|
+
bloomSourceTextures: {},
|
|
5057
|
+
bloomCompositeTextures: {},
|
|
5058
|
+
combinedTexture: null,
|
|
5059
|
+
getBloomSourceTexture(d, p, b) {
|
|
5060
|
+
return this.bloomSourceTextures[d] || (this.bloomSourceTextures[d] = n.createTexture({
|
|
5061
|
+
size: [p, b],
|
|
5062
|
+
format: "rgba16float",
|
|
5063
|
+
// HDR chain (see webgpu.js HDR_FORMAT) — avoids additive clip
|
|
5064
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
|
|
5065
|
+
})), this.bloomSourceTextures[d];
|
|
5066
|
+
},
|
|
5067
|
+
getBloomCompositeTexture(d, p, b) {
|
|
5068
|
+
return this.bloomCompositeTextures[d] || (this.bloomCompositeTextures[d] = n.createTexture({
|
|
5069
|
+
size: [p, b],
|
|
5070
|
+
format: "rgba16float",
|
|
5071
|
+
// HDR chain
|
|
5072
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
|
|
5073
|
+
})), this.bloomCompositeTextures[d];
|
|
5074
|
+
},
|
|
5075
|
+
getCombinedTexture(d, p) {
|
|
5076
|
+
return this.combinedTexture || (this.combinedTexture = n.createTexture({
|
|
5077
|
+
size: [d, p],
|
|
5078
|
+
format: "rgba16float",
|
|
5079
|
+
// HDR chain — tonemapped to canvas in the final pass
|
|
5080
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
|
|
5081
|
+
})), this.combinedTexture;
|
|
5082
|
+
},
|
|
5083
|
+
resizeTextures() {
|
|
5084
|
+
Object.values(this.bloomSourceTextures).forEach((d) => d == null ? void 0 : d.destroy()), Object.values(this.bloomCompositeTextures).forEach((d) => d == null ? void 0 : d.destroy()), this.combinedTexture && this.combinedTexture.destroy(), this.bloomSourceTextures = {}, this.bloomCompositeTextures = {}, this.combinedTexture = null;
|
|
5085
|
+
}
|
|
5086
|
+
}, S = {
|
|
5087
|
+
systemBindGroups: {},
|
|
5088
|
+
systemBloomHorizontalBindGroups: {},
|
|
5089
|
+
secondHorizontalBindGroups: {},
|
|
5090
|
+
finalBindGroup: null,
|
|
5091
|
+
textureStates: {},
|
|
5092
|
+
textureRefs: {},
|
|
5093
|
+
clear() {
|
|
5094
|
+
this.systemBindGroups = {}, this.systemBloomHorizontalBindGroups = {}, this.secondHorizontalBindGroups = {}, this.finalBindGroup = null, this.textureStates = {}, this.textureRefs = {};
|
|
5095
|
+
}
|
|
5096
|
+
}, R = n.createBuffer({ size: 96, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST }), D = n.createBuffer({ size: 208, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST }), C = n.createBuffer({ size: 32, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST }), B = n.createBuffer({ size: 32, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST }), A = n.createBuffer({ size: 64, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST }), P = Ge(n, new Uint16Array([0, 1, 2, 0, 2, 3]), GPUBufferUsage.INDEX), _ = {}, T = () => Ge(n, new Float32Array([-0.5, -0.5, 0, 0.5, -0.5, 0, 0.5, 0.5, 0, -0.5, 0.5, 0]), GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST);
|
|
5097
|
+
u.onSystemCreated = (d) => {
|
|
5098
|
+
_[d] || (_[d] = T());
|
|
5099
|
+
};
|
|
5100
|
+
const L = 4e4, N = new Float32Array(L * 8), k = new Float32Array(L * 4), X = new Float32Array(L * 4), z = n.createBuffer({ size: L * 8 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST }), me = n.createBuffer({ size: L * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST }), De = n.createBuffer({ size: L * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST }), ze = /* @__PURE__ */ new Map(), at = 8, Q = [];
|
|
5101
|
+
function _t(d) {
|
|
5102
|
+
for (const p of Q) if (p.ids.has(d)) return p;
|
|
5103
|
+
return null;
|
|
5104
|
+
}
|
|
5105
|
+
function Ci(d, p) {
|
|
5106
|
+
if (!d.pos) return;
|
|
5107
|
+
d.hist.push({ t: p, x: d.pos[0], y: d.pos[1], z: d.pos[2] });
|
|
5108
|
+
const b = p - at;
|
|
5109
|
+
for (; d.hist.length > 2 && d.hist[0].t < b; ) d.hist.shift();
|
|
5110
|
+
}
|
|
5111
|
+
function wt(d, p) {
|
|
5112
|
+
const b = d.hist;
|
|
5113
|
+
if (b.length === 0) return d.pos;
|
|
5114
|
+
if (p >= b[b.length - 1].t) {
|
|
5115
|
+
const y = b[b.length - 1];
|
|
5116
|
+
return [y.x, y.y, y.z];
|
|
5117
|
+
}
|
|
5118
|
+
if (p <= b[0].t) return [b[0].x, b[0].y, b[0].z];
|
|
5119
|
+
for (let y = b.length - 1; y > 0; y--)
|
|
5120
|
+
if (b[y - 1].t <= p) {
|
|
5121
|
+
const x = b[y - 1], Y = b[y], Z = (p - x.t) / Math.max(1e-6, Y.t - x.t);
|
|
5122
|
+
return [x.x + (Y.x - x.x) * Z, x.y + (Y.y - x.y) * Z, x.z + (Y.z - x.z) * Z];
|
|
5123
|
+
}
|
|
5124
|
+
return [b[0].x, b[0].y, b[0].z];
|
|
5125
|
+
}
|
|
5126
|
+
const Ai = 0.41421356;
|
|
5127
|
+
function Ui() {
|
|
5128
|
+
ze.clear();
|
|
5129
|
+
let d = 0, p = 0;
|
|
5130
|
+
U.position[0], U.position[1], U.position[2];
|
|
5131
|
+
for (const { system: b, config: y } of u.particleSystems) {
|
|
5132
|
+
if (!y.emissionTrailEnabled || y.hidden || y.glbModelEnabled) continue;
|
|
5133
|
+
b.readbackAndProcessParticles();
|
|
5134
|
+
const x = b.particleData, Y = b.particleVelocities, Z = b.activeParticles;
|
|
5135
|
+
if (!x || !Y || Z <= 0) continue;
|
|
5136
|
+
const $ = y.emissionTrailMode === "particles", W = d, g = y.emissionTrailDuration ?? 1, w = y.opacity ?? 1, G = y.particleSize ?? 0.5, q = y.bloomIntensity || 1, M = Math.max(1, Math.min(64, y.emissionTrailSegments ?? 8)), J = y.emissionTrailShape || "straight", ee = y.followSystemTranslation ?? !0, fe = b._simPosition, O = ee && fe ? fe[0] : 0, Qe = ee && fe ? fe[1] : 0, Vt = ee && fe ? fe[2] : 0, Ae = b._simVelocity, Ft = Ae ? Ae[0] : 0, Ki = Ae ? Ae[1] : 0, Ot = Ae ? Ae[2] : 0, Fe = _t(y.id), Lt = !!(ee && Fe && Fe.hist && Fe.hist.length > 1);
|
|
5137
|
+
for (let et = 0; et < Z; et++) {
|
|
5138
|
+
const ge = et * 8, tt = x[ge], ft = x[ge + 1], it = x[ge + 2], Qi = tt + O, es = ft + Qe, ts = it + Vt;
|
|
5139
|
+
let Oe = x[ge + 3], Le = x[ge + 4], Ne = x[ge + 5];
|
|
5140
|
+
const Xe = x[ge + 6], Ue = x[ge + 7];
|
|
5141
|
+
if (Xe >= Ue || Ue <= 0) continue;
|
|
5142
|
+
const be = Xe / Ue;
|
|
5143
|
+
if (y.colorTransitionEnabled) {
|
|
5144
|
+
const v = y.startColor ?? [1, 0, 0], I = y.endColor ?? [0, 0, 1];
|
|
5145
|
+
Oe = v[0] + (I[0] - v[0]) * be, Le = v[1] + (I[1] - v[1]) * be, Ne = v[2] + (I[2] - v[2]) * be;
|
|
5146
|
+
}
|
|
5147
|
+
Oe = Math.min(1, Oe * q), Le = Math.min(1, Le * q), Ne = Math.min(1, Ne * q);
|
|
5148
|
+
let ke = G;
|
|
5149
|
+
if (y.randomSize) {
|
|
5150
|
+
const v = Math.sin(Ue * 54321.67) * 43758.5453 % 1, I = v < 0 ? v + 1 : v;
|
|
5151
|
+
ke = (y.minSize ?? 0.1) + ((y.maxSize ?? 0.5) - (y.minSize ?? 0.1)) * I;
|
|
5152
|
+
}
|
|
5153
|
+
if (y.fadeSizeEnabled) {
|
|
5154
|
+
const v = Math.max(0.01, Math.min(10, y.sizeLifetimeSpeed ?? 1));
|
|
5155
|
+
ke *= 1 - Math.pow(be, 1 / v);
|
|
5156
|
+
}
|
|
5157
|
+
if (y.increaseSizeEnabled) {
|
|
5158
|
+
const v = Math.max(0.01, Math.min(10, y.sizeLifetimeSpeed ?? 1));
|
|
5159
|
+
ke *= 1 + Math.pow(be, 1 / v);
|
|
5160
|
+
}
|
|
5161
|
+
if (ke <= 0 || be > 0.9) continue;
|
|
5162
|
+
const Nt = Math.min((0.9 - be) * (1 / 0.2), 1), Xt = 0.75 * ke * Ai * Nt;
|
|
5163
|
+
let je = w;
|
|
5164
|
+
if (y.fadeEnabled && (je *= Math.max(0, 1 - be)), je *= Nt, je < 0.01) continue;
|
|
5165
|
+
const pt = et * 4, kt = Y[pt], jt = Y[pt + 1], Yt = Y[pt + 2], st = kt + Ft, rt = jt + Ki, nt = Yt + Ot, qt = Math.sqrt(st * st + rt * rt + nt * nt);
|
|
5166
|
+
if (qt < 1e-3) continue;
|
|
5167
|
+
const ht = 1 / qt, _e = st * ht, we = rt * ht, Se = nt * ht, Ht = U.right[0], Zt = U.right[1], $t = U.right[2];
|
|
5168
|
+
let mt = Ht * _e + Zt * we + $t * Se, ne = Ht - mt * _e, ae = Zt - mt * we, oe = $t - mt * Se, Ye = Math.sqrt(ne * ne + ae * ae + oe * oe);
|
|
5169
|
+
if (Ye < 0.2) {
|
|
5170
|
+
const v = U.up[0], I = U.up[1], H = U.up[2], V = v * _e + I * we + H * Se;
|
|
5171
|
+
ne = v - V * _e, ae = I - V * we, oe = H - V * Se, Ye = Math.sqrt(ne * ne + ae * ae + oe * oe) || 1;
|
|
5172
|
+
}
|
|
5173
|
+
ne /= Ye, ae /= Ye, oe /= Ye;
|
|
5174
|
+
const qe = Math.min(g, Xe);
|
|
5175
|
+
if (qe < 1e-3) continue;
|
|
5176
|
+
const Wt = y.gravityEnabled && y.gravityStrength || 0, Be = new Array(M + 1), Re = new Array(M + 1), Me = new Array(M + 1);
|
|
5177
|
+
if (y.orientToDirection && y.burstMode && Lt) {
|
|
5178
|
+
const v = b._emitSimRotY || 0, I = new Array(M + 1), H = new Array(M + 1), V = new Array(M + 1);
|
|
5179
|
+
for (let E = 0; E <= M; E++) {
|
|
5180
|
+
const F = wt(Fe, ye - E / M * qe);
|
|
5181
|
+
I[E] = F[0], H[E] = F[1], V[E] = F[2];
|
|
5182
|
+
}
|
|
5183
|
+
for (let E = 0; E <= M; E++) {
|
|
5184
|
+
const F = E > 0 ? E - 1 : 0, j = E < M ? E + 1 : M;
|
|
5185
|
+
let Te = I[F] - I[j], Ee = V[F] - V[j];
|
|
5186
|
+
const xe = (Math.hypot(Te, Ee) > 1e-5 ? Math.atan2(Te, Ee) : Math.atan2(Ft, Ot)) - v, se = Math.cos(xe), re = Math.sin(xe), he = E / M * qe, yt = -0.5 * Wt * he * he;
|
|
5187
|
+
Be[E] = se * tt + re * it + I[E], Re[E] = ft + yt + H[E], Me[E] = -re * tt + se * it + V[E];
|
|
5188
|
+
}
|
|
5189
|
+
} else for (let v = 0; v <= M; v++) {
|
|
5190
|
+
const I = v / M * qe, H = -0.5 * Wt * I * I;
|
|
5191
|
+
if (Lt) {
|
|
5192
|
+
const V = wt(Fe, ye - I);
|
|
5193
|
+
Be[v] = tt - kt * I + V[0], Re[v] = ft - jt * I + H + V[1], Me[v] = it - Yt * I + V[2];
|
|
5194
|
+
} else
|
|
5195
|
+
Be[v] = Qi - st * I, Re[v] = es - rt * I + H, Me[v] = ts - nt * I;
|
|
5196
|
+
}
|
|
5197
|
+
if (J !== "straight") {
|
|
5198
|
+
const v = y.emissionTrailShapeAmplitude ?? 0.1, I = y.emissionTrailShapeFrequency ?? 4, H = y.emissionTrailShapeSpeed ?? 0;
|
|
5199
|
+
let V = -Se, E = 0, F = _e, j = Math.sqrt(V * V + F * F);
|
|
5200
|
+
j < 1e-6 && (V = 0, E = Se, F = -we, j = Math.sqrt(V * V + E * E + F * F) || 1), V /= j, E /= j, F /= j;
|
|
5201
|
+
const Te = we * F - Se * E, Ee = Se * V - _e * F, pe = _e * E - we * V;
|
|
5202
|
+
for (let K = 1; K <= M; K++) {
|
|
5203
|
+
const xe = K / M * qe, se = 2 * Math.PI * I * (ye - xe) + H * ye;
|
|
5204
|
+
let re = 0, he = 0;
|
|
5205
|
+
J === "zigzag" ? re = v * Math.sign(Math.sin(se)) : J === "sine" ? re = v * Math.sin(se) : J === "spiral" && (re = v * Math.sin(se), he = v * Math.cos(se)), Be[K] += V * re + Te * he, Re[K] += E * re + Ee * he, Me[K] += F * re + pe * he;
|
|
5206
|
+
}
|
|
5207
|
+
}
|
|
5208
|
+
if ($)
|
|
5209
|
+
for (let v = 1; v <= M && d < L; v++) {
|
|
5210
|
+
const I = v / M, H = Be[v] - O, V = Re[v] - Qe, E = Me[v] - Vt, F = d * 8, j = d * 4;
|
|
5211
|
+
N[F] = H, N[F + 1] = V, N[F + 2] = E, N[F + 3] = Oe, N[F + 4] = Le, N[F + 5] = Ne, N[F + 6] = Xe + (Ue - Xe) * I, N[F + 7] = Ue, k[j] = 0, k[j + 1] = 0, k[j + 2] = 0, k[j + 3] = 0, X[j] = H, X[j + 1] = V, X[j + 2] = E, X[j + 3] = 0, d++;
|
|
5212
|
+
}
|
|
5213
|
+
else
|
|
5214
|
+
for (let v = 0; v < M && !(p + 42 > ue.length); v++) {
|
|
5215
|
+
const I = v / M, H = (v + 1) / M, V = Be[v], E = Re[v], F = Me[v], j = Be[v + 1], Te = Re[v + 1], Ee = Me[v + 1], pe = Xt * (1 - I), K = Xt * (1 - H), xe = je * (1 - I) * (1 - I), se = je * (1 - H) * (1 - H), re = V + ne * pe, he = E + ae * pe, yt = F + oe * pe, Jt = V - ne * pe, Kt = E - ae * pe, Qt = F - oe * pe, ei = j + ne * K, ti = Te + ae * K, ii = Ee + oe * K, is = j - ne * K, ss = Te - ae * K, rs = Ee - oe * K, Ie = (ns, as, os, ls) => {
|
|
5216
|
+
ue[p++] = ns, ue[p++] = as, ue[p++] = os, ue[p++] = Oe, ue[p++] = Le, ue[p++] = Ne, ue[p++] = ls;
|
|
5217
|
+
};
|
|
5218
|
+
Ie(re, he, yt, xe), Ie(Jt, Kt, Qt, xe), Ie(ei, ti, ii, se), Ie(Jt, Kt, Qt, xe), Ie(is, ss, rs, se), Ie(ei, ti, ii, se);
|
|
5219
|
+
}
|
|
5220
|
+
}
|
|
5221
|
+
$ && d > W && ze.set(y.id, { first: W, count: d - W });
|
|
5222
|
+
}
|
|
5223
|
+
d > 0 && (n.queue.writeBuffer(z, 0, N, 0, d * 8), n.queue.writeBuffer(me, 0, k, 0, d * 4), n.queue.writeBuffer(De, 0, X, 0, d * 4)), Ve = p / 7, Ve > 0 && n.queue.writeBuffer(At, 0, ue, 0, p);
|
|
5224
|
+
}
|
|
5225
|
+
const Bt = () => {
|
|
5226
|
+
n.queue.writeBuffer(C, 0, new Float32Array([1, 0, a.width, a.height, 0, 0, 0, 0])), n.queue.writeBuffer(B, 0, new Float32Array([0, 1, a.width, a.height, 0, 0, 0, 0]));
|
|
5227
|
+
};
|
|
5228
|
+
Bt();
|
|
5229
|
+
const Rt = new Float32Array(16).fill(0);
|
|
5230
|
+
Rt[0] = 1, n.queue.writeBuffer(A, 0, Rt);
|
|
5231
|
+
const te = Vs(n), ce = Ds(n), {
|
|
5232
|
+
particlePipeline: Ii,
|
|
5233
|
+
particleAdditivePipeline: Gi,
|
|
5234
|
+
particleDepthWritePipeline: Di,
|
|
5235
|
+
blurPipeline: $e,
|
|
5236
|
+
compositePipeline: zi,
|
|
5237
|
+
directRenderPipeline: Mt,
|
|
5238
|
+
finalCompositePipeline: Vi,
|
|
5239
|
+
glbMeshPipeline: Fi
|
|
5240
|
+
} = zs(n, l, ce), Tt = n.createShaderModule({ code: `
|
|
5241
|
+
struct U { mvp: mat4x4<f32> };
|
|
5242
|
+
@group(0) @binding(0) var<uniform> u: U;
|
|
5243
|
+
struct VIn { @location(0) pos: vec3<f32>, @location(1) col: vec4<f32> };
|
|
5244
|
+
struct VOut { @builtin(position) pos: vec4<f32>, @location(0) col: vec4<f32> };
|
|
5245
|
+
@vertex fn vs(v: VIn) -> VOut { var o: VOut; o.pos = u.mvp * vec4<f32>(v.pos, 1.0); o.col = v.col; return o; }
|
|
5246
|
+
@fragment fn fs(i: VOut) -> @location(0) vec4<f32> { return i.col; }
|
|
5247
|
+
` }), Et = n.createBindGroupLayout({
|
|
5248
|
+
entries: [{ binding: 0, visibility: GPUShaderStage.VERTEX, buffer: { type: "uniform" } }]
|
|
5249
|
+
}), Oi = n.createRenderPipeline({
|
|
5250
|
+
layout: n.createPipelineLayout({ bindGroupLayouts: [Et] }),
|
|
5251
|
+
vertex: {
|
|
5252
|
+
module: Tt,
|
|
5253
|
+
entryPoint: "vs",
|
|
5254
|
+
buffers: [{ arrayStride: 28, attributes: [
|
|
5255
|
+
{ shaderLocation: 0, offset: 0, format: "float32x3" },
|
|
5256
|
+
{ shaderLocation: 1, offset: 12, format: "float32x4" }
|
|
5257
|
+
] }]
|
|
5258
|
+
},
|
|
5259
|
+
fragment: {
|
|
5260
|
+
module: Tt,
|
|
5261
|
+
entryPoint: "fs",
|
|
5262
|
+
targets: [{ format: "rgba16float", blend: {
|
|
5263
|
+
// renders into the HDR sceneTexture
|
|
5264
|
+
color: { srcFactor: "src-alpha", dstFactor: "one-minus-src-alpha" },
|
|
5265
|
+
alpha: { srcFactor: "src-alpha", dstFactor: "one-minus-src-alpha" }
|
|
5266
|
+
} }]
|
|
5267
|
+
},
|
|
5268
|
+
primitive: { topology: "triangle-list" },
|
|
5269
|
+
// depth24plus to match the non-bloom pass; test against the resolved scene depth
|
|
5270
|
+
// (occlusion) but don't write (transparent ribbon).
|
|
5271
|
+
depthStencil: { format: "depth24plus", depthWriteEnabled: !1, depthCompare: "less-equal" }
|
|
5272
|
+
}), Ct = 512 * 64 * 6, ue = new Float32Array(Ct * 7), At = n.createBuffer({
|
|
5273
|
+
size: Ct * 7 * 4,
|
|
5274
|
+
usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
|
|
5275
|
+
label: "ribbonBuffer"
|
|
5276
|
+
}), Li = n.createBindGroup({
|
|
5277
|
+
layout: Et,
|
|
5278
|
+
entries: [{ binding: 0, resource: { buffer: R } }]
|
|
5279
|
+
});
|
|
5280
|
+
let Ve = 0, { sceneTexture: ie, bloomTexA: ve, bloomTexB: de } = ui(n, l, a.width, a.height), Pe = di(n, a.width, a.height);
|
|
5281
|
+
const ot = { uniformBuffer: R, appearanceUniformBuffer: D, horizontalBlurUniformBuffer: C, verticalBlurUniformBuffer: B, bloomIntensityBuffer: A };
|
|
5282
|
+
let We = St(n, te, ot, { sceneTexture: ie, bloomTexA: ve, bloomTexB: de });
|
|
5283
|
+
const U = {
|
|
5284
|
+
mvp: new Float32Array(16),
|
|
5285
|
+
position: new Float32Array([0, 0, 10]),
|
|
5286
|
+
right: new Float32Array([1, 0, 0]),
|
|
5287
|
+
// camera basis (world space) — for stable ribbon width
|
|
5288
|
+
up: new Float32Array([0, 1, 0]),
|
|
5289
|
+
hasCamera: !1
|
|
5290
|
+
};
|
|
5291
|
+
let ye = 0, Ni = 0;
|
|
5292
|
+
const Ce = { key: null, ms: !1, bindGroup: null };
|
|
5293
|
+
let Ut = !1, lt = !0, Je = !1, Ke = null, ct = a.width, ut = a.height;
|
|
5294
|
+
function It() {
|
|
5295
|
+
const d = [ie, ve, de, Pe], p = ui(n, l, a.width, a.height);
|
|
5296
|
+
ie = p.sceneTexture, ve = p.bloomTexA, de = p.bloomTexB, Pe = di(n, a.width, a.height), Bt(), S.clear(), m.resizeTextures(), We = St(n, te, ot, { sceneTexture: ie, bloomTexA: ve, bloomTexB: de });
|
|
5297
|
+
let b = !1;
|
|
5298
|
+
const y = () => {
|
|
5299
|
+
if (!b) {
|
|
5300
|
+
b = !0, requestAnimationFrame(y);
|
|
5301
|
+
return;
|
|
5302
|
+
}
|
|
5303
|
+
d.forEach((x) => x.destroy());
|
|
5304
|
+
};
|
|
5305
|
+
requestAnimationFrame(y);
|
|
5306
|
+
}
|
|
5307
|
+
function Xi(d, p, b) {
|
|
5308
|
+
U.mvp.set(Ns(d, p)), p && p.length >= 10 && (U.right[0] = p[0], U.right[1] = p[4], U.right[2] = p[8], U.up[0] = p[1], U.up[1] = p[5], U.up[2] = p[9]), b && (U.position[0] = b.x ?? b[0], U.position[1] = b.y ?? b[1], U.position[2] = b.z ?? b[2]), U.hasCamera = !0;
|
|
5309
|
+
}
|
|
5310
|
+
function ki(d, p) {
|
|
5311
|
+
U.mvp.set(d), p && (U.position[0] = p.x ?? p[0], U.position[1] = p.y ?? p[1], U.position[2] = p.z ?? p[2]), U.hasCamera = !0;
|
|
5312
|
+
}
|
|
5313
|
+
async function dt(d) {
|
|
5314
|
+
if (Je) {
|
|
5315
|
+
Ke = d;
|
|
5316
|
+
return;
|
|
5317
|
+
}
|
|
5318
|
+
Je = !0;
|
|
5319
|
+
try {
|
|
5320
|
+
for (const p in _) delete _[p];
|
|
5321
|
+
S.clear(), m.resizeTextures(), We = St(n, te, ot, { sceneTexture: ie, bloomTexA: ve, bloomTexB: de }), await u.replaceSystems({ systems: [], activeSystemIndex: 0 });
|
|
5322
|
+
for (const p of d)
|
|
5323
|
+
await u.addSystems(p.preset, p.position || [0, 0, 0]);
|
|
5324
|
+
for (const { config: p } of u.particleSystems)
|
|
5325
|
+
_[p.id] || (_[p.id] = T());
|
|
5326
|
+
lt = !0, u.respawnAllSystems();
|
|
5327
|
+
} finally {
|
|
5328
|
+
if (Je = !1, Ke) {
|
|
5329
|
+
const p = Ke;
|
|
5330
|
+
Ke = null, dt(p);
|
|
5331
|
+
}
|
|
5332
|
+
}
|
|
5333
|
+
}
|
|
5334
|
+
async function ji(d, p = [0, 0, 0]) {
|
|
5335
|
+
return dt([{ preset: d, position: p }]);
|
|
5336
|
+
}
|
|
5337
|
+
function Yi(d) {
|
|
5338
|
+
if (Ut || Je || !u.ready || (d > 0.1 && (d = 0.1), d <= 0) || u.particleSystems.length === 0) return;
|
|
5339
|
+
if ((a.width !== ct || a.height !== ut) && (ct = a.width, ut = a.height, It()), ye += d, Q.length) {
|
|
5340
|
+
for (const g of Q) {
|
|
5341
|
+
if (g.getPosition) {
|
|
5342
|
+
const w = g.getPosition();
|
|
5343
|
+
g.pos = w ? Array.isArray(w) ? [w[0], w[1], w[2]] : [w.x, w.y, w.z] : null;
|
|
5344
|
+
}
|
|
5345
|
+
g.vel = g.pos && g.prevPos && g.wasActive && d > 0 ? [(g.pos[0] - g.prevPos[0]) / d, (g.pos[1] - g.prevPos[1]) / d, (g.pos[2] - g.prevPos[2]) / d] : [0, 0, 0], g.justResumed = !!g.pos && !g.wasActive, g.justResumed && (g.hist.length = 0);
|
|
5346
|
+
}
|
|
5347
|
+
for (const { system: g, config: w } of u.particleSystems) {
|
|
5348
|
+
const G = _t(w.id);
|
|
5349
|
+
if (!(!G || G.historyOnly) && (w.hidden = !G.pos, G.pos)) {
|
|
5350
|
+
let q = null;
|
|
5351
|
+
if (G.orientToDirection && G.vel) {
|
|
5352
|
+
const M = G.vel[0], J = G.vel[2];
|
|
5353
|
+
Math.hypot(M, J) > 1e-4 && (q = [0, 0, Math.atan2(M, J)]);
|
|
5354
|
+
}
|
|
5355
|
+
g.setSimulationTransform({ position: G.pos, velocity: G.vel, rotation: q }), g.updateAppearanceUniform(), (G.justResumed || g.activeParticles === 0) && g.spawnParticles();
|
|
5356
|
+
}
|
|
5357
|
+
}
|
|
5358
|
+
for (const g of Q)
|
|
5359
|
+
g.pos ? Ci(g, ye) : g.hist.length = 0, g.prevPos = g.pos ? g.pos.slice() : null, g.wasActive = !!g.pos;
|
|
5360
|
+
if (globalThis.__HZFX_DEBUG && (Ni++ & 63) === 0) {
|
|
5361
|
+
const g = u.particleSystems.reduce((M, J) => M + (J.system.activeParticles | 0), 0), w = Q.find((M) => M.pos), G = w ? Math.hypot(U.position[0] - w.pos[0], U.position[1] - w.pos[1], U.position[2] - w.pos[2]).toFixed(1) : "-", q = Q.map((M) => `{ids:[${[...M.ids]}],pos:${M.pos ? "1" : "0"},hist:${M.hist.length}}`).join(",");
|
|
5362
|
+
console.info(`[HZFX] movingGroups(${Q.length})=[${q}] activeParticles=${g} systems=${u.particleSystems.length} ribbonVerts=${Ve} camDist=${G} t=${ye.toFixed(1)}`);
|
|
5363
|
+
}
|
|
5364
|
+
}
|
|
5365
|
+
if (u.updateAllSystems(d), s ? u.loop ?? i : i) {
|
|
5366
|
+
const g = u.particleSystems.length > 0 && u.particleSystems.every(({ system: w }) => w.activeParticles === 0 && !w.emitting);
|
|
5367
|
+
g && lt && u.respawnAllSystems(), lt = !g;
|
|
5368
|
+
}
|
|
5369
|
+
for (const { system: g, config: w } of u.particleSystems)
|
|
5370
|
+
w.glbModelEnabled && g.glbAnimator && (g.glbAnimator.update(d), g.updateAnimatedGLBBuffer());
|
|
5371
|
+
n.queue.writeBuffer(R, 0, U.mvp), n.queue.writeBuffer(R, 64, new Float32Array([
|
|
5372
|
+
U.position[0],
|
|
5373
|
+
U.position[1],
|
|
5374
|
+
U.position[2],
|
|
5375
|
+
a.height / Math.max(1, a.width),
|
|
5376
|
+
ye
|
|
5377
|
+
])), Ui();
|
|
5378
|
+
const b = u.particleSystems.some(({ config: g }) => g.bloomEnabled), y = n.createCommandEncoder();
|
|
5379
|
+
let x = !1;
|
|
5380
|
+
if (e)
|
|
5381
|
+
try {
|
|
5382
|
+
const g = e();
|
|
5383
|
+
if (g) {
|
|
5384
|
+
let w = null, G = null, q = !1;
|
|
5385
|
+
if (g instanceof GPUTexture ? g.width === a.width && g.height === a.height && (w = g, G = () => g.createView({ aspect: "depth-only" }), q = g.sampleCount > 1) : g.view && (w = g.view, G = () => g.view, q = !!g.multisampled), w) {
|
|
5386
|
+
const { pipeline: M, layout: J } = h(q);
|
|
5387
|
+
(Ce.key !== w || Ce.ms !== q) && (Ce.key = w, Ce.ms = q, Ce.bindGroup = n.createBindGroup({
|
|
5388
|
+
layout: J,
|
|
5389
|
+
entries: [{ binding: 0, resource: G() }]
|
|
5390
|
+
}));
|
|
5391
|
+
const ee = y.beginRenderPass({
|
|
5392
|
+
colorAttachments: [],
|
|
5393
|
+
depthStencilAttachment: { view: Pe.createView(), depthClearValue: 1, depthLoadOp: "clear", depthStoreOp: "store" }
|
|
5394
|
+
});
|
|
5395
|
+
ee.setPipeline(M), ee.setBindGroup(0, Ce.bindGroup), ee.draw(3), ee.end(), x = !0;
|
|
5396
|
+
}
|
|
5397
|
+
}
|
|
5398
|
+
} catch {
|
|
5399
|
+
}
|
|
5400
|
+
const Y = y.beginRenderPass({
|
|
5401
|
+
colorAttachments: [{ view: ie.createView(), loadOp: "clear", storeOp: "store", clearValue: { r: 0, g: 0, b: 0, a: 0 } }],
|
|
5402
|
+
depthStencilAttachment: x ? { view: Pe.createView(), depthLoadOp: "load", depthStoreOp: "store" } : { view: Pe.createView(), depthClearValue: 1, depthLoadOp: "clear", depthStoreOp: "store" }
|
|
5403
|
+
});
|
|
5404
|
+
for (const { system: g, config: w } of u.particleSystems)
|
|
5405
|
+
w.bloomEnabled || w.hidden || g.activeParticles === 0 || Gt(Y, g, w, !0);
|
|
5406
|
+
if (Ve > 0 && (Y.setPipeline(Oi), Y.setBindGroup(0, Li), Y.setVertexBuffer(0, At), Y.draw(Ve)), Y.end(), b)
|
|
5407
|
+
for (const { system: g, config: w } of u.particleSystems) {
|
|
5408
|
+
if (!w.bloomEnabled || w.hidden || g.activeParticles === 0) continue;
|
|
5409
|
+
const G = g.config.id, q = m.getBloomSourceTexture(G, a.width, a.height), M = y.beginRenderPass({
|
|
5410
|
+
colorAttachments: [{ view: q.createView(), loadOp: "clear", storeOp: "store", clearValue: { r: 0, g: 0, b: 0, a: 0 } }],
|
|
5411
|
+
depthStencilAttachment: { view: Pe.createView(), depthClearValue: 1, depthLoadOp: "load", depthStoreOp: "store" }
|
|
5412
|
+
});
|
|
5413
|
+
Gt(M, g, w, !1), M.end();
|
|
5414
|
+
const J = new Float32Array(16).fill(0);
|
|
5415
|
+
J[0] = w.bloomIntensity, n.queue.writeBuffer(A, 0, J);
|
|
5416
|
+
const ee = {
|
|
5417
|
+
colorAttachments: [{ view: ve.createView(), loadOp: "clear", storeOp: "store", clearValue: { r: 0, g: 0, b: 0, a: 0 } }]
|
|
5418
|
+
}, fe = {
|
|
5419
|
+
colorAttachments: [{ view: de.createView(), loadOp: "clear", storeOp: "store", clearValue: { r: 0, g: 0, b: 0, a: 0 } }]
|
|
5420
|
+
};
|
|
5421
|
+
S.systemBloomHorizontalBindGroups[G] || (S.systemBloomHorizontalBindGroups[G] = n.createBindGroup({
|
|
5422
|
+
layout: ce.bloomBindGroupLayout,
|
|
5423
|
+
entries: [
|
|
5424
|
+
{ binding: 0, resource: te },
|
|
5425
|
+
{ binding: 1, resource: q.createView() },
|
|
5426
|
+
{ binding: 2, resource: { buffer: C } }
|
|
5427
|
+
]
|
|
5428
|
+
}));
|
|
5429
|
+
let O = y.beginRenderPass(ee);
|
|
5430
|
+
O.setPipeline($e), O.setBindGroup(0, S.systemBloomHorizontalBindGroups[G]), O.draw(3), O.end(), O = y.beginRenderPass(fe), O.setPipeline($e), O.setBindGroup(0, We.verticalBlurBindGroup), O.draw(3), O.end(), S.secondHorizontalBindGroups[G] || (S.secondHorizontalBindGroups[G] = n.createBindGroup({
|
|
5431
|
+
layout: ce.bloomBindGroupLayout,
|
|
5432
|
+
entries: [
|
|
5433
|
+
{ binding: 0, resource: te },
|
|
5434
|
+
{ binding: 1, resource: de.createView() },
|
|
5435
|
+
{ binding: 2, resource: { buffer: C } }
|
|
5436
|
+
]
|
|
5437
|
+
})), O = y.beginRenderPass(ee), O.setPipeline($e), O.setBindGroup(0, S.secondHorizontalBindGroups[G]), O.draw(3), O.end(), O = y.beginRenderPass(fe), O.setPipeline($e), O.setBindGroup(0, We.verticalBlurBindGroup), O.draw(3), O.end();
|
|
5438
|
+
const Qe = m.getBloomCompositeTexture(G, a.width, a.height);
|
|
5439
|
+
O = y.beginRenderPass({
|
|
5440
|
+
colorAttachments: [{ view: Qe.createView(), loadOp: "clear", storeOp: "store", clearValue: { r: 0, g: 0, b: 0, a: 0 } }]
|
|
5441
|
+
}), O.setPipeline(zi), O.setBindGroup(0, n.createBindGroup({
|
|
5442
|
+
layout: ce.compositeBindGroupLayout,
|
|
5443
|
+
entries: [
|
|
5444
|
+
{ binding: 0, resource: te },
|
|
5445
|
+
{ binding: 1, resource: q.createView() },
|
|
5446
|
+
{ binding: 2, resource: de.createView() },
|
|
5447
|
+
{ binding: 3, resource: { buffer: g.bloomIntensityBuffer } }
|
|
5448
|
+
]
|
|
5449
|
+
})), O.draw(3), O.end();
|
|
5450
|
+
}
|
|
5451
|
+
const Z = m.getCombinedTexture(a.width, a.height), $ = y.beginRenderPass({
|
|
5452
|
+
colorAttachments: [{ view: Z.createView(), loadOp: "clear", storeOp: "store", clearValue: { r: 0, g: 0, b: 0, a: 0 } }]
|
|
5453
|
+
});
|
|
5454
|
+
$.setPipeline(Mt), $.setBindGroup(0, n.createBindGroup({
|
|
5455
|
+
layout: ce.compositeBindGroupLayout,
|
|
5456
|
+
entries: [
|
|
5457
|
+
{ binding: 0, resource: te },
|
|
5458
|
+
{ binding: 1, resource: ie.createView() },
|
|
5459
|
+
{ binding: 2, resource: ie.createView() },
|
|
5460
|
+
{ binding: 3, resource: { buffer: A } }
|
|
5461
|
+
]
|
|
5462
|
+
})), $.draw(3);
|
|
5463
|
+
for (const { config: g, system: w } of u.particleSystems) {
|
|
5464
|
+
if (!g.bloomEnabled || g.hidden || w.activeParticles === 0) continue;
|
|
5465
|
+
const G = w.config.id;
|
|
5466
|
+
$.setPipeline(Mt), $.setBindGroup(0, n.createBindGroup({
|
|
5467
|
+
layout: ce.compositeBindGroupLayout,
|
|
5468
|
+
entries: [
|
|
5469
|
+
{ binding: 0, resource: te },
|
|
5470
|
+
{ binding: 1, resource: m.getBloomCompositeTexture(G, a.width, a.height).createView() },
|
|
5471
|
+
{ binding: 2, resource: ie.createView() },
|
|
5472
|
+
{ binding: 3, resource: { buffer: A } }
|
|
5473
|
+
]
|
|
5474
|
+
})), $.draw(3);
|
|
5475
|
+
}
|
|
5476
|
+
$.end();
|
|
5477
|
+
const W = y.beginRenderPass({
|
|
5478
|
+
colorAttachments: [{
|
|
5479
|
+
view: o.getCurrentTexture().createView(),
|
|
5480
|
+
loadOp: c ? "load" : "clear",
|
|
5481
|
+
storeOp: "store",
|
|
5482
|
+
clearValue: { r: 0, g: 0, b: 0, a: 0 }
|
|
5483
|
+
}]
|
|
5484
|
+
});
|
|
5485
|
+
W.setPipeline(Vi), S.finalBindGroup || (S.finalBindGroup = n.createBindGroup({
|
|
5486
|
+
layout: ce.compositeBindGroupLayout,
|
|
5487
|
+
entries: [
|
|
5488
|
+
{ binding: 0, resource: te },
|
|
5489
|
+
{ binding: 1, resource: Z.createView() },
|
|
5490
|
+
{ binding: 2, resource: ie.createView() },
|
|
5491
|
+
{ binding: 3, resource: { buffer: A } }
|
|
5492
|
+
]
|
|
5493
|
+
})), W.setBindGroup(0, S.finalBindGroup), W.draw(3), W.end(), n.queue.submit([y.finish()]);
|
|
5494
|
+
}
|
|
5495
|
+
function Gt(d, p, b, y) {
|
|
5496
|
+
const x = p.config.id, Y = b.glbModelEnabled && p.glbMeshData;
|
|
5497
|
+
let Z;
|
|
5498
|
+
if (y) {
|
|
5499
|
+
const W = !S.systemBindGroups[x] || S.textureStates[x] !== b.textureEnabled || S.textureRefs[x] !== p.particleTexture;
|
|
5500
|
+
S.textureStates[x] = b.textureEnabled, S.textureRefs[x] = p.particleTexture, W && (S.systemBindGroups[x] = n.createBindGroup({
|
|
5501
|
+
layout: ce.particleBindGroupLayout,
|
|
5502
|
+
entries: [
|
|
5503
|
+
{ binding: 0, resource: { buffer: R } },
|
|
5504
|
+
{ binding: 1, resource: { buffer: p.appearanceUniformBuffer } },
|
|
5505
|
+
{ binding: 2, resource: p.particleTexture.createView() },
|
|
5506
|
+
{ binding: 3, resource: te }
|
|
5507
|
+
]
|
|
5508
|
+
})), Z = S.systemBindGroups[x];
|
|
5509
|
+
} else
|
|
5510
|
+
Z = n.createBindGroup({
|
|
5511
|
+
layout: ce.particleBindGroupLayout,
|
|
5512
|
+
entries: [
|
|
5513
|
+
{ binding: 0, resource: { buffer: R } },
|
|
5514
|
+
{ binding: 1, resource: { buffer: p.appearanceUniformBuffer } },
|
|
5515
|
+
{ binding: 2, resource: p.particleTexture.createView() },
|
|
5516
|
+
{ binding: 3, resource: te }
|
|
5517
|
+
]
|
|
5518
|
+
});
|
|
5519
|
+
const $ = b.shapeDisplay !== !1;
|
|
5520
|
+
if (Y)
|
|
5521
|
+
$ && (d.setPipeline(Fi), d.setBindGroup(0, Z), d.setVertexBuffer(0, p.glbVertexBuffer), d.setVertexBuffer(1, p.instanceBuffer), d.setVertexBuffer(2, p.velocityBuffer), d.setIndexBuffer(p.glbIndexBuffer, p.glbIndexFormat), d.drawIndexed(p.glbIndexCount, p.activeParticles));
|
|
5522
|
+
else {
|
|
5523
|
+
d.setPipeline(b.blendMode === "additive" ? Gi : Ii), d.setIndexBuffer(P, "uint16"), _[x] || (_[x] = T()), d.setVertexBuffer(0, _[x]), d.setBindGroup(0, Z), $ && (d.setVertexBuffer(1, p.instanceBuffer), d.setVertexBuffer(2, p.velocityBuffer), d.setVertexBuffer(3, p.trailBuffer), d.drawIndexed(6, p.activeParticles));
|
|
5524
|
+
const W = ze.get(x);
|
|
5525
|
+
W && (d.setVertexBuffer(1, z), d.setVertexBuffer(2, me), d.setVertexBuffer(3, De), d.drawIndexed(6, W.count, 0, 0, W.first)), $ && b.depthWriteEnabled && (d.setPipeline(Di), d.drawIndexed(6, p.activeParticles));
|
|
5526
|
+
}
|
|
5527
|
+
}
|
|
5528
|
+
function qi() {
|
|
5529
|
+
ct = a.width, ut = a.height, It();
|
|
5530
|
+
}
|
|
5531
|
+
function Hi() {
|
|
5532
|
+
S.clear();
|
|
5533
|
+
}
|
|
5534
|
+
function Zi() {
|
|
5535
|
+
Ut = !0, u.destroy(), [ie, ve, de, Pe].forEach((d) => d == null ? void 0 : d.destroy()), m.resizeTextures(), [
|
|
5536
|
+
R,
|
|
5537
|
+
D,
|
|
5538
|
+
C,
|
|
5539
|
+
B,
|
|
5540
|
+
A,
|
|
5541
|
+
P,
|
|
5542
|
+
z,
|
|
5543
|
+
me,
|
|
5544
|
+
De
|
|
5545
|
+
].forEach((d) => d == null ? void 0 : d.destroy()), Object.values(_).forEach((d) => d == null ? void 0 : d.destroy());
|
|
5546
|
+
}
|
|
5547
|
+
async function Dt(d, p) {
|
|
5548
|
+
const b = await u.addSystems(d, p);
|
|
5549
|
+
for (const { config: y } of u.particleSystems)
|
|
5550
|
+
_[y.id] || (_[y.id] = T());
|
|
5551
|
+
return u.respawnAllSystems(), new Set(Array.isArray(b) ? b : []);
|
|
5552
|
+
}
|
|
5553
|
+
function zt(d) {
|
|
5554
|
+
for (const p of d) {
|
|
5555
|
+
const b = u.particleSystems.findIndex((y) => y.config.id === p);
|
|
5556
|
+
b >= 0 && u.removeSystem(b);
|
|
5557
|
+
}
|
|
5558
|
+
}
|
|
5559
|
+
async function $i(d, p = [0, 0, 0]) {
|
|
5560
|
+
const b = await Dt(d, p);
|
|
5561
|
+
return { remove() {
|
|
5562
|
+
zt(b);
|
|
5563
|
+
} };
|
|
5564
|
+
}
|
|
5565
|
+
async function Wi(d, p = {}) {
|
|
5566
|
+
const b = await Dt(d, [0, 0, 0]);
|
|
5567
|
+
globalThis.__HZFX_DEBUG && console.info(`[HZFX] addMovingEmitter: presetSystems=${(d && d.systems || []).length} newIds=[${[...b]}]`);
|
|
5568
|
+
const y = { ids: b, pos: null, hist: [], getPosition: p.getPosition || null, orientToDirection: !!p.orientToDirection };
|
|
5569
|
+
return Q.push(y), {
|
|
5570
|
+
setPosition(x) {
|
|
5571
|
+
x && (y.pos = Array.isArray(x) ? [x[0], x[1], x[2]] : [x.x, x.y, x.z]);
|
|
5572
|
+
},
|
|
5573
|
+
setOrientToDirection(x) {
|
|
5574
|
+
y.orientToDirection = !!x;
|
|
5575
|
+
},
|
|
5576
|
+
remove() {
|
|
5577
|
+
zt(b);
|
|
5578
|
+
const x = Q.indexOf(y);
|
|
5579
|
+
x >= 0 && Q.splice(x, 1);
|
|
5580
|
+
}
|
|
5581
|
+
};
|
|
5582
|
+
}
|
|
5583
|
+
function Ji(d, p) {
|
|
5584
|
+
const y = { ids: d instanceof Set ? d : new Set(d), pos: null, hist: [], getPosition: p, historyOnly: !0 };
|
|
5585
|
+
return Q.push(y), {
|
|
5586
|
+
remove() {
|
|
5587
|
+
const x = Q.indexOf(y);
|
|
5588
|
+
x >= 0 && Q.splice(x, 1);
|
|
5589
|
+
},
|
|
5590
|
+
// Update which systems this history group covers WITHOUT losing the accumulated path
|
|
5591
|
+
// history. Needed when the scene's systems change (e.g. duplicate/add/remove) while the
|
|
5592
|
+
// group is active — otherwise a newly-added system's id isn't in the set and its trail
|
|
5593
|
+
// can't follow the recorded movement path (it falls back to straight extrapolation).
|
|
5594
|
+
setIds(x) {
|
|
5595
|
+
y.ids = x instanceof Set ? x : new Set(x);
|
|
5596
|
+
}
|
|
5597
|
+
};
|
|
5598
|
+
}
|
|
5599
|
+
return {
|
|
5600
|
+
manager: u,
|
|
5601
|
+
device: n,
|
|
5602
|
+
context: o,
|
|
5603
|
+
setCamera: Xi,
|
|
5604
|
+
setCameraMVP: ki,
|
|
5605
|
+
setEmitters: dt,
|
|
5606
|
+
loadPreset: ji,
|
|
5607
|
+
addEmitter: $i,
|
|
5608
|
+
addMovingEmitter: Wi,
|
|
5609
|
+
render: Yi,
|
|
5610
|
+
resize: qi,
|
|
5611
|
+
clearCaches: Hi,
|
|
5612
|
+
trackHistoryGroup: Ji,
|
|
5613
|
+
destroy: Zi
|
|
5614
|
+
};
|
|
5615
|
+
}
|
|
5616
|
+
function sr(r) {
|
|
5617
|
+
return () => {
|
|
5618
|
+
var t, e, i, s, n, o;
|
|
5619
|
+
try {
|
|
5620
|
+
const a = r.backend;
|
|
5621
|
+
if (!a) return null;
|
|
5622
|
+
if (r.needsFrameBufferTarget && r._frameBufferTarget) {
|
|
5623
|
+
const u = (i = (e = (t = r._textures) == null ? void 0 : t.get) == null ? void 0 : e.call(t, r._frameBufferTarget)) == null ? void 0 : i.depthTexture, f = u ? (s = a.get(u)) == null ? void 0 : s.texture : null;
|
|
5624
|
+
if (f && f.width === r.domElement.width && f.height === r.domElement.height) return f;
|
|
5625
|
+
}
|
|
5626
|
+
const c = r.getCanvasTarget ? a.get(r.getCanvasTarget()) : null, l = ((o = (n = c == null ? void 0 : c.descriptor) == null ? void 0 : n.depthStencilAttachment) == null ? void 0 : o.view) ?? null;
|
|
5627
|
+
return l ? { view: l, multisampled: (r.currentSamples ?? 0) > 1 } : null;
|
|
5628
|
+
} catch {
|
|
5629
|
+
return null;
|
|
5630
|
+
}
|
|
4732
5631
|
};
|
|
4733
5632
|
}
|
|
4734
5633
|
export {
|
|
4735
|
-
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
5634
|
+
Ts as GLBAnimator,
|
|
5635
|
+
Zs as Objects3DManager,
|
|
5636
|
+
cs as ParticleEmitter,
|
|
5637
|
+
us as ParticlePhysics,
|
|
5638
|
+
si as ParticleScript,
|
|
5639
|
+
bt as ParticleSystem,
|
|
5640
|
+
Es as ParticleSystemManager,
|
|
5641
|
+
ds as ParticleTextureManager,
|
|
5642
|
+
Si as blurShader,
|
|
5643
|
+
xi as compositeShader,
|
|
5644
|
+
Ds as createBindGroupLayouts,
|
|
5645
|
+
St as createBindGroups,
|
|
5646
|
+
Ge as createBuffer,
|
|
5647
|
+
Fs as createCubeGeometry,
|
|
5648
|
+
di as createDepthTexture,
|
|
5649
|
+
Js as createLookAtMatrix,
|
|
5650
|
+
Ks as createProjectionMatrix,
|
|
5651
|
+
zs as createRenderPipelines,
|
|
5652
|
+
ui as createRenderTextures,
|
|
5653
|
+
Vs as createSampler,
|
|
5654
|
+
Os as createSphereGeometry,
|
|
5655
|
+
vi as directRenderShader,
|
|
5656
|
+
ws as extractGLBTexture,
|
|
5657
|
+
tr as fetchPreset,
|
|
5658
|
+
Gs as glbMeshParticleShader,
|
|
5659
|
+
$s as hexToRgb,
|
|
5660
|
+
ir as initHzFxOverlay,
|
|
5661
|
+
Cs as initWebGPU,
|
|
5662
|
+
Ti as isHZFX,
|
|
5663
|
+
er as loadScene,
|
|
5664
|
+
sr as makeThreeSceneDepth,
|
|
5665
|
+
Ns as multiplyMatrices,
|
|
5666
|
+
Is as object3dShader,
|
|
5667
|
+
ks as packHZFX,
|
|
5668
|
+
gi as parseGLB,
|
|
5669
|
+
As as particlePhysicsShader,
|
|
5670
|
+
bi as particleShader,
|
|
5671
|
+
Ws as rgbToHex,
|
|
5672
|
+
Qs as saveScene,
|
|
5673
|
+
Ys as serializeSystemConfig,
|
|
5674
|
+
Ei as unpackHZFX
|
|
4770
5675
|
};
|