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.
@@ -1,4 +1,4 @@
1
- class W {
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, r = e * Math.PI / 180, n = i * Math.PI / 180, o = Math.cos(s), a = Math.sin(s), l = Math.cos(r), d = Math.sin(r), u = Math.cos(n), f = Math.sin(n);
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
- a * d * f + o * u,
20
- o * d * f - a * u,
21
- -d,
22
- a * l,
23
- o * l
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 o = this._rotMatrix, a = s[0], l = s[1], d = s[2];
41
- s[0] = o[0] * a + o[1] * l + o[2] * d, s[1] = o[3] * a + o[4] * l + o[5] * d, s[2] = o[6] * a + o[7] * l + o[8] * d;
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.emissionTranslationX || this.config.emissionTranslationY || this.config.emissionTranslationZ) && (s[0] += this.config.emissionTranslationX || 0, s[1] += this.config.emissionTranslationY || 0, s[2] += this.config.emissionTranslationZ || 0);
44
- const r = e * 8;
45
- t[r] = s[0], t[r + 1] = s[1], t[r + 2] = s[2];
46
- const n = e * 4;
47
- this.calculateVelocity(s[0], s[1], s[2], i, n), this.setParticleColor(t, r), this.setParticleLifetime(t, r);
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), r = Math.random() - 0.5, n = Math.random() - 0.5;
73
- let o, a, l;
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
- o = r, a = n, l = 0.5;
76
+ a = n, c = o, l = 0.5;
77
77
  break;
78
78
  case 1:
79
- o = r, a = n, l = -0.5;
79
+ a = n, c = o, l = -0.5;
80
80
  break;
81
81
  case 2:
82
- o = 0.5, a = r, l = n;
82
+ a = 0.5, c = n, l = o;
83
83
  break;
84
84
  case 3:
85
- o = -0.5, a = r, l = n;
85
+ a = -0.5, c = n, l = o;
86
86
  break;
87
87
  case 4:
88
- o = r, a = 0.5, l = n;
88
+ a = n, c = 0.5, l = o;
89
89
  break;
90
90
  case 5:
91
- o = r, a = -0.5, l = n;
91
+ a = n, c = -0.5, l = o;
92
92
  break;
93
93
  }
94
- const d = Math.random(), u = e + d * (i - e);
95
- t[0] = o * u, t[1] = a * u, t[2] = l * u;
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), r = Math.sin(i) * Math.sin(e), n = Math.cos(i);
101
- let o;
102
- this.config.innerRadius === 0 ? o = this.config.outerRadius * Math.cbrt(Math.random()) : o = this.config.innerRadius + (this.config.outerRadius - this.config.innerRadius) * Math.random(), t[0] = s * o, t[1] = r * o, t[2] = n * o;
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 r = e + (i - e) * Math.random();
108
+ let n = e + (i - e) * Math.random();
109
109
  switch (s) {
110
110
  case 0:
111
- t[0] = (Math.random() * 2 - 1) * r, t[1] = r;
111
+ t[0] = (Math.random() * 2 - 1) * n, t[1] = n;
112
112
  break;
113
113
  case 1:
114
- t[0] = r, t[1] = (Math.random() * 2 - 1) * r;
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) * r, t[1] = -r;
117
+ t[0] = (Math.random() * 2 - 1) * n, t[1] = -n;
118
118
  break;
119
119
  case 3:
120
- t[0] = -r, t[1] = (Math.random() * 2 - 1) * r;
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 r;
130
- e > 0 ? r = e + (i - e) * Math.random() : r = i * Math.sqrt(Math.random()), t[0] = Math.cos(s) * r, t[1] = Math.sin(s) * r, t[2] = 0;
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, r = Math.random() * Math.PI * 2, n = Math.random(), o = n * s, a = i * (1 - n);
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 d = e * (1 - n);
141
- l = d + (a - d) * Math.random();
140
+ const u = e * (1 - o);
141
+ l = u + (c - u) * Math.random();
142
142
  } else
143
- l = a * Math.sqrt(Math.random());
144
- t[0] = Math.cos(r) * l, t[1] = o, t[2] = Math.sin(r) * l;
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, r = Math.random() * Math.PI * 2, n = i * Math.sqrt(Math.random());
148
- t[0] = (e + n * Math.cos(r)) * Math.cos(s), t[1] = n * Math.sin(r), t[2] = (e + n * Math.cos(r)) * Math.sin(s);
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, r = Math.acos(Math.random()), n = Math.sin(r) * Math.cos(s), o = Math.cos(r), a = Math.sin(r) * Math.sin(s);
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] = n * l, t[1] = o * l, t[2] = a * l;
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, r = e + (i - e) * Math.random();
165
- t[0] = Math.cos(s) * r, t[1] = 0, t[2] = Math.sin(s) * r;
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, r = Math.PI * e * e * i, n = 4 / 3 * Math.PI * e * e * e, o = r / (r + n);
169
- if (Math.random() < o) {
170
- const a = Math.random() * Math.PI * 2, l = e * Math.sqrt(Math.random());
171
- t[0] = Math.cos(a) * l, t[1] = (Math.random() - 0.5) * i, t[2] = Math.sin(a) * l;
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 a = Math.random() * Math.PI * 2, l = Math.acos(2 * Math.random() - 1), d = e * Math.cbrt(Math.random());
174
- t[0] = d * Math.sin(l) * Math.cos(a), t[1] = d * Math.cos(l), t[2] = d * Math.sin(l) * Math.sin(a), t[1] += t[1] >= 0 ? s : -s;
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, r = this.config.arcOuterRadius || 2, n = e * Math.PI / 180, o = i * Math.PI / 180, a = n + Math.random() * (o - n);
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 + (r - s) * Math.random() : l = r * Math.sqrt(Math.random()), t[0] = Math.cos(a) * l, t[1] = Math.sin(a) * l, t[2] = 0;
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, r = this.config.spiralHeight || 4, n = Math.random(), o = n * e * Math.PI * 2, a = i + (s - i) * n;
184
- t[0] = Math.cos(o) * a, t[1] = (n - 0.5) * r, t[2] = Math.sin(o) * a;
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, r = Math.random() * Math.PI * 2, n = Math.random(), o = n * s, l = (e + (i - e) * n) * Math.sqrt(Math.random());
188
- t[0] = Math.cos(r) * l, t[1] = o, t[2] = Math.sin(r) * l;
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), r = (Math.random() - 0.5) * e, n = (Math.random() - 0.5) * e;
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] = r, t[1] = n, t[2] = i;
194
+ t[0] = n, t[1] = o, t[2] = i;
195
195
  break;
196
196
  case 1:
197
- t[0] = r, t[1] = n, t[2] = -i;
197
+ t[0] = n, t[1] = o, t[2] = -i;
198
198
  break;
199
199
  case 2:
200
- t[0] = i, t[1] = r, t[2] = n;
200
+ t[0] = i, t[1] = n, t[2] = o;
201
201
  break;
202
202
  case 3:
203
- t[0] = -i, t[1] = r, t[2] = n;
203
+ t[0] = -i, t[1] = n, t[2] = o;
204
204
  break;
205
205
  case 4:
206
- t[0] = r, t[1] = i, t[2] = n;
206
+ t[0] = n, t[1] = i, t[2] = o;
207
207
  break;
208
208
  case 5:
209
- t[0] = r, t[1] = -i, t[2] = n;
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), n = (Math.random() - 0.5) * e, o = [[-1, -1], [-1, 1], [1, -1], [1, 1]];
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 [a, l] = o[s];
221
- t[0] = n, t[1] = a * i, t[2] = l * i;
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 [a, l] = o[s - 4];
224
- t[0] = a * i, t[1] = n, t[2] = l * i;
223
+ const [c, l] = a[s - 4];
224
+ t[0] = c * i, t[1] = o, t[2] = l * i;
225
225
  } else {
226
- const [a, l] = o[s - 8];
227
- t[0] = a * i, t[1] = l * i, t[2] = n;
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), r = s / e * Math.PI * 2, n = (s + 1) / e * Math.PI * 2;
232
- let o = Math.random(), a = Math.random();
233
- o + a > 1 && (o = 1 - o, a = 1 - a);
234
- const l = o * Math.cos(r) + a * Math.cos(n), d = o * Math.sin(r) + a * Math.sin(n);
235
- t[0] = l * i, t[1] = d * i, t[2] = 0;
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, r = Math.random() * Math.PI * 2;
243
- let n;
244
- e > 0 ? n = e + (i - e) * Math.random() : n = i * Math.sqrt(Math.random()), t[0] = Math.cos(r) * n, t[1] = (Math.random() - 0.5) * s, t[2] = Math.sin(r) * n;
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, r) {
247
- const n = this.config.emissionTranslationX || 0, o = this.config.emissionTranslationY || 0, a = this.config.emissionTranslationZ || 0, l = t - n, d = e - o, u = i - a, f = Math.sqrt(l * l + d * d + u * u);
248
- let h, p, m;
249
- if (f > 1e-4) {
250
- let S = !1;
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 y = this.inverseRotation(l, d, u), _ = Math.sqrt(y[0] * y[0] + y[1] * y[1]);
253
- if (_ > 1e-4) {
254
- const g = -y[1] / _, x = y[0] / _, P = this.applyRotation(g, x, 0);
255
- h = P[0], p = P[1], m = P[2], S = !0;
252
+ 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 y = this.inverseRotation(l, d, u), _ = Math.sqrt(y[0] * y[0] + y[2] * y[2]);
259
- if (_ > 1e-4) {
260
- const g = -y[2] / _, x = y[0] / _, P = this.applyRotation(g, 0, x);
261
- h = P[0], p = P[1], m = P[2], S = !0;
258
+ 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 g = Math.random() * Math.PI * 2, x = this.applyRotation(Math.cos(g), 0, Math.sin(g));
264
- h = x[0], p = x[1], m = x[2], S = !0;
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
- S || (h = l / f, p = d / f, m = u / f);
267
+ C || (m = l / h, S = u / h, R = f / h);
268
268
  } else {
269
- const S = Math.random() * Math.PI * 2, y = Math.acos(2 * Math.random() - 1);
270
- h = Math.sin(y) * Math.cos(S), p = Math.sin(y) * Math.sin(S), m = Math.cos(y);
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 b;
273
- this.config.randomSpeed ? b = (this.config.minSpeed || 0) + Math.random() * ((this.config.maxSpeed || 1) - (this.config.minSpeed || 0)) : b = this.config.particleSpeed, s[r] = this.config.overrideXVelocity ? this.config.xVelocity : h * b, s[r + 1] = this.config.overrideYVelocity ? this.config.yVelocity : p * b, s[r + 2] = this.config.overrideZVelocity ? this.config.zVelocity : m * b, s[r + 3] = 0;
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 J {
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(() => H);
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, r, n) {
402
+ updatePhysics(t, e, i, s, n, o) {
403
403
  if (e <= 0 || !this.computeReady)
404
404
  return;
405
- const o = this._physicsData, a = this.physicsSettings;
406
- o[0] = t, o[1] = i.particleSpeed, o[2] = a.gravity, o[3] = a.turbulence, o[4] = a.attractorStrength, o[5] = a.damping, o[6] = a.attractorPosition[0], o[7] = a.attractorPosition[1], o[8] = a.attractorPosition[2], this._physicsDataU32View[9] = e, o[10] = a.confinementEnabled ? 1 : 0, o[11] = a.confinementShape === "sphere" ? 1 : 0, o[12] = a.confinementMode === "kill" ? 1 : 0, o[13] = a.confinementSpace === "local" ? 1 : 0, o[14] = a.confinementBoxHalfSize[0], o[15] = a.confinementBoxHalfSize[1], o[16] = a.confinementBoxHalfSize[2], o[17] = a.confinementSphereRadius, o[18] = a.confinementRestitution, o[19] = a.confinementFriction, o[20] = a.confinementCenter[0], o[21] = a.confinementCenter[1], o[22] = a.confinementCenter[2], o[23] = a.softBoundaryEnabled ? 1 : 0, o[24] = a.softBoundaryStrength, o[25] = a.softBoundaryFalloff, o[26] = i.velocityStretchEnabled ? 1 : 0, o[27] = i.velocityStretchFactor ?? 1, o[28] = 0, o[29] = 0, o[30] = 0, o[31] = 0, this.device.queue.writeBuffer(this.physicsUniformBuffer, 0, o);
407
- const l = n || this.device.createCommandEncoder({ label: "ParticlePhysicsEncoder" }), d = l.beginComputePass({ label: "ParticlePhysicsPass" });
408
- d.setPipeline(this.computePipeline), d.setBindGroup(0, this.computeBindGroup);
409
- const u = Math.max(1, Math.ceil(e / 64));
410
- d.dispatchWorkgroups(u, 1, 1), d.end(), n || this.device.queue.submit([l.finish()]), this.lastUpdateTime = performance.now() / 1e3;
411
- }
412
- async readbackAndProcessParticles(t, e, i, s, r) {
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 n = this.device.createCommandEncoder({
419
+ const o = this.device.createCommandEncoder({
420
420
  label: "ParticleReadbackEncoder"
421
- }), o = t * 8 * 4;
422
- n.copyBufferToBuffer(
421
+ }), a = t * 8 * 4;
422
+ o.copyBufferToBuffer(
423
423
  s,
424
424
  0,
425
425
  this._particleDataStagingBuffer,
426
426
  0,
427
- o
427
+ a
428
428
  );
429
- const a = t * 4 * 4;
430
- return n.copyBufferToBuffer(
431
- r,
429
+ const c = t * 4 * 4;
430
+ return o.copyBufferToBuffer(
431
+ n,
432
432
  0,
433
433
  this._velocityStagingBuffer,
434
434
  0,
435
- a
436
- ), this.device.queue.submit([n.finish()]), await Promise.all([
435
+ c
436
+ ), this.device.queue.submit([o.finish()]), await Promise.all([
437
437
  (async () => {
438
- await this._particleDataStagingBuffer.mapAsync(GPUMapMode.READ, 0, o);
439
- const l = new Float32Array(this._particleDataStagingBuffer.getMappedRange(0, o));
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, a);
444
- const l = new Float32Array(this._velocityStagingBuffer.getMappedRange(0, a));
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 (n) {
453
- return this._stagingInUse = !1, console.error("Error reading back particle data:", n), { activeCount: t, shouldUpdate: !1 };
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, r) {
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 n = t * 8 * 4, o = t * 4 * 4, a = this.device.createCommandEncoder({
487
+ const o = t * 8 * 4, a = t * 4 * 4, c = this.device.createCommandEncoder({
488
488
  label: "RenderReadbackEncoder"
489
489
  });
490
- return a.copyBufferToBuffer(
490
+ return c.copyBufferToBuffer(
491
491
  s,
492
492
  0,
493
493
  this._renderStagingParticleBuffer,
494
494
  0,
495
- n
496
- ), a.copyBufferToBuffer(
497
- r,
495
+ o
496
+ ), c.copyBufferToBuffer(
497
+ n,
498
498
  0,
499
499
  this._renderStagingVelocityBuffer,
500
500
  0,
501
- o
502
- ), this.device.queue.submit([a.finish()]), await Promise.all([
501
+ a
502
+ ), this.device.queue.submit([c.finish()]), await Promise.all([
503
503
  (async () => {
504
- await this._renderStagingParticleBuffer.mapAsync(GPUMapMode.READ, 0, n);
505
- const l = new Float32Array(this._renderStagingParticleBuffer.getMappedRange(0, n));
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, o);
510
- const l = new Float32Array(this._renderStagingVelocityBuffer.getMappedRange(0, o));
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 (n) {
519
- return this._renderStagingInUse = !1, console.error("Error in rendering readback:", n), { shouldUpdate: !1 };
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, r) {
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 n = t * 8 * 4, o = t * 4 * 4, a = this.device.createCommandEncoder({
540
+ const o = t * 8 * 4, a = t * 4 * 4, c = this.device.createCommandEncoder({
541
541
  label: "ScriptReadbackEncoder"
542
542
  });
543
- return a.copyBufferToBuffer(
543
+ return c.copyBufferToBuffer(
544
544
  s,
545
545
  0,
546
546
  this._scriptStagingParticleBuffer,
547
547
  0,
548
- n
549
- ), a.copyBufferToBuffer(
550
- r,
548
+ o
549
+ ), c.copyBufferToBuffer(
550
+ n,
551
551
  0,
552
552
  this._scriptStagingVelocityBuffer,
553
553
  0,
554
- o
555
- ), this.device.queue.submit([a.finish()]), await Promise.all([
554
+ a
555
+ ), this.device.queue.submit([c.finish()]), await Promise.all([
556
556
  (async () => {
557
- await this._scriptStagingParticleBuffer.mapAsync(GPUMapMode.READ, 0, n);
558
- const l = new Float32Array(this._scriptStagingParticleBuffer.getMappedRange(0, n));
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, o);
563
- const l = new Float32Array(this._scriptStagingVelocityBuffer.getMappedRange(0, o));
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 (n) {
568
- return this._scriptStagingInUse = !1, console.error("Error in script readback:", n), { shouldUpdate: !1 };
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 K {
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 N = Object.freeze({
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(c, t, e) {
636
- return c < t ? t : c > e ? e : c;
635
+ clamp(r, t, e) {
636
+ return r < t ? t : r > e ? e : r;
637
637
  },
638
- lerp(c, t, e) {
639
- return c + (t - c) * e;
638
+ lerp(r, t, e) {
639
+ return r + (t - r) * e;
640
640
  },
641
- smoothstep(c, t, e) {
642
- const i = N.clamp((e - c) / (t - c), 0, 1);
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
- }), T = /* @__PURE__ */ new Set([
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 Q {
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 ee {
739
+ class ps {
740
740
  constructor() {
741
- this._proxy = new Q(this), this._pd = null, this._vd = null, this.count = 0, this._dirty = !1;
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 te = 1e6;
751
- function ie(c) {
750
+ const hs = 1e6;
751
+ function ms(r) {
752
752
  let t = 0;
753
- return c.replace(
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}>${te})throw new Error("Loop limit exceeded");`;
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 U = /* @__PURE__ */ new Map();
775
- for (const c of T)
776
- U.set(c.toLowerCase(), c);
777
- function se(c) {
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(c, {
780
- get(s, r) {
781
- if (r === "__dirty") return t.value;
782
- if (r === "__resetDirty") return () => {
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 r != "string") return;
786
- if (T.has(r)) return s[r];
787
- const n = U.get(r.toLowerCase());
788
- if (n)
789
- return e.has(r) || (e.add(r), console.warn(`[ParticleScript] config.${r} → did you mean config.${n}?`)), s[n];
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, r, n) {
792
- if (typeof r != "string") return !0;
793
- let o = r;
794
- if (!T.has(o)) {
795
- const a = U.get(o.toLowerCase());
796
- if (a)
797
- e.has(r) || (e.add(r), console.warn(`[ParticleScript] config.${r} → did you mean config.${a}?`)), o = a;
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[o] = n, t.value = !0, !0;
801
+ return s[a] = o, t.value = !0, !0;
802
802
  }
803
803
  });
804
804
  }
805
- class z {
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 ee(), this._configProxy = se(e), this._configSnapshot = null, this._fn = null, this._error = !1, this.compile(t);
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
- ${ie(t)}
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, r, n, o) {
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(r, n, o), this._configProxy.__resetDirty();
848
+ this._particles._bind(n, o, a), this._configProxy.__resetDirty();
849
849
  try {
850
- this._fn(t, e, i, s, this._particles, this._configProxy, N);
851
- } catch (a) {
852
- console.warn("[ParticleScript] Runtime error:", a.message);
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 T) {
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 T)
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 X(c) {
890
- const t = new DataView(c);
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 r = 12, n = null, o = null;
898
- for (; r < s; ) {
899
- const g = t.getUint32(r, !0), x = t.getUint32(r + 4, !0), P = c.slice(r + 8, r + 8 + g);
900
- if (x === 1313821514) {
901
- const w = new TextDecoder("utf-8").decode(P);
902
- n = JSON.parse(w);
903
- } else x === 5130562 && (o = P);
904
- r += 8 + g;
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 (!n)
906
+ if (!o)
907
907
  throw new Error("GLB file missing JSON chunk");
908
- if (!n.meshes || n.meshes.length === 0)
908
+ if (!o.meshes || o.meshes.length === 0)
909
909
  throw new Error("GLB file contains no meshes");
910
- const l = n.meshes[0].primitives[0];
910
+ const l = o.meshes[0].primitives[0];
911
911
  if (!l)
912
912
  throw new Error("First mesh has no primitives");
913
- const d = l.attributes.POSITION;
914
- if (d === void 0)
913
+ const u = l.attributes.POSITION;
914
+ if (u === void 0)
915
915
  throw new Error("Mesh primitive missing POSITION attribute");
916
- const u = E(n, o, d, 3, 5126);
917
- let f;
916
+ const f = gt(o, a, u, 3, 5126);
917
+ let h;
918
918
  if (l.attributes.NORMAL !== void 0)
919
- f = E(n, o, l.attributes.NORMAL, 3, 5126);
919
+ h = gt(o, a, l.attributes.NORMAL, 3, 5126);
920
920
  else {
921
- const g = l.indices;
922
- if (g === void 0)
921
+ const P = l.indices;
922
+ if (P === void 0)
923
923
  throw new Error("Cannot generate normals without indices");
924
- const x = F(n, o, g);
925
- f = ae(u, x);
924
+ const _ = ri(o, a, P);
925
+ h = gs(f, _);
926
926
  }
927
- const h = l.indices;
928
- if (h === void 0)
927
+ const m = l.indices;
928
+ if (m === void 0)
929
929
  throw new Error("Mesh primitive missing indices");
930
- const p = F(n, o, h), m = u.length / 3, b = p.length;
931
- let S = null;
932
- l.attributes.TEXCOORD_0 !== void 0 && (S = E(n, o, l.attributes.TEXCOORD_0, 2, 5126));
933
- let y = !1;
934
- if (n.materials && n.materials.length > 0) {
935
- const g = n.materials[0];
936
- g.pbrMetallicRoughness && g.pbrMetallicRoughness.baseColorTexture !== void 0 && (y = !0);
937
- }
938
- let _ = null;
939
- if (n.skins && n.skins.length > 0)
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
- _ = de(n, o, l), console.log("Animation data extracted:", _);
942
- } catch (g) {
943
- console.warn("Failed to extract animation data:", g);
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: u,
947
- normals: f,
948
- indices: p,
949
- texCoords: S,
950
- vertexCount: m,
951
- indexCount: b,
952
- animationData: _,
953
- hasBaseColorTexture: y
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 E(c, t, e, i, s) {
957
- const r = c.accessors[e], o = {
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
- }[r.type];
963
- if (o !== i)
964
- throw new Error(`Attribute accessor type mismatch: expected ${i} components, got ${o}`);
965
- if (r.componentType !== s)
966
- throw new Error(`Attribute component type mismatch: expected ${s}, got ${r.componentType}`);
967
- const l = (c.bufferViews[r.bufferView].byteOffset || 0) + (r.byteOffset || 0), d = r.count, u = new DataView(t, l, d * i * 4), f = new Float32Array(d * i);
968
- for (let h = 0; h < d * i; h++)
969
- f[h] = u.getFloat32(h * 4, !0);
970
- return f;
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 F(c, t, e) {
973
- const i = c.accessors[e];
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 r = (c.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0), n = i.count;
976
+ const n = (r.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0), o = i.count;
977
977
  if (i.componentType === 5123) {
978
- const o = new DataView(t, r, n * 2), a = new Uint16Array(n);
979
- for (let l = 0; l < n; l++)
980
- a[l] = o.getUint16(l * 2, !0);
981
- return a;
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 o = new DataView(t, r, n * 4), a = new Uint32Array(n);
984
- for (let l = 0; l < n; l++)
985
- a[l] = o.getUint32(l * 4, !0);
986
- return a;
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 ae(c, t) {
991
- const e = new Float32Array(c.length);
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, r = t[i + 1] * 3, n = t[i + 2] * 3, o = [c[s], c[s + 1], c[s + 2]], a = [c[r], c[r + 1], c[r + 2]], l = [c[n], c[n + 1], c[n + 2]], d = [a[0] - o[0], a[1] - o[1], a[2] - o[2]], u = [l[0] - o[0], l[1] - o[1], l[2] - o[2]], f = [
994
- d[1] * u[2] - d[2] * u[1],
995
- d[2] * u[0] - d[0] * u[2],
996
- d[0] * u[1] - d[1] * u[0]
997
- ], h = Math.sqrt(f[0] * f[0] + f[1] * f[1] + f[2] * f[2]);
998
- h > 0 && (f[0] /= h, f[1] /= h, f[2] /= h), e[s] = e[r] = e[n] = f[0], e[s + 1] = e[r + 1] = e[n + 1] = f[1], e[s + 2] = e[r + 2] = e[n + 2] = f[2];
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 re(c, t, e) {
1003
- const i = c.accessors[e];
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 r = (c.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0), n = i.count;
1006
+ const n = (r.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0), o = i.count;
1007
1007
  if (i.componentType === 5121) {
1008
- const o = new DataView(t, r, n * 4), a = new Uint8Array(n * 4);
1009
- for (let l = 0; l < n * 4; l++)
1010
- a[l] = o.getUint8(l);
1011
- return a;
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 o = new DataView(t, r, n * 8), a = new Uint8Array(n * 4);
1014
- for (let l = 0; l < n * 4; l++)
1015
- a[l] = o.getUint16(l * 2, !0);
1016
- return a;
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 ne(c, t, e) {
1021
- const i = c.accessors[e];
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 r = (c.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0), n = i.count;
1024
+ const n = (r.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0), o = i.count;
1025
1025
  if (i.componentType === 5126) {
1026
- const o = new DataView(t, r, n * 16), a = new Float32Array(n * 4);
1027
- for (let l = 0; l < n * 4; l++)
1028
- a[l] = o.getFloat32(l * 4, !0);
1029
- return a;
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 o = new DataView(t, r, n * 4), a = new Float32Array(n * 4);
1032
- for (let l = 0; l < n * 4; l++)
1033
- a[l] = o.getUint8(l) / 255;
1034
- return a;
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 oe(c, t, e) {
1039
- const i = c.accessors[e];
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 r = (c.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0), n = i.count, o = new DataView(t, r, n * 64), a = new Float32Array(n * 16);
1045
- for (let l = 0; l < n * 16; l++)
1046
- a[l] = o.getFloat32(l * 4, !0);
1047
- return a;
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 le(c, t, e) {
1050
- const i = c.accessors[e];
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 r = (c.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0), n = i.count, o = new DataView(t, r, n * 4), a = new Float32Array(n);
1056
- for (let l = 0; l < n; l++)
1057
- a[l] = o.getFloat32(l * 4, !0);
1058
- return a;
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 ce(c, t, e) {
1061
- const i = c.accessors[e], r = { VEC3: 3, VEC4: 4 }[i.type];
1062
- if (!r)
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 o = (c.bufferViews[i.bufferView].byteOffset || 0) + (i.byteOffset || 0), a = i.count, l = new DataView(t, o, a * r * 4), d = new Float32Array(a * r);
1067
- for (let u = 0; u < a * r; u++)
1068
- d[u] = l.getFloat32(u * 4, !0);
1069
- return d;
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 de(c, t, e) {
1072
- const i = c.skins[0], s = i.joints, r = oe(c, t, i.inverseBindMatrices), n = e.attributes.JOINTS_0 !== void 0 ? re(c, t, e.attributes.JOINTS_0) : null, o = e.attributes.WEIGHTS_0 !== void 0 ? ne(c, t, e.attributes.WEIGHTS_0) : null;
1073
- if (!n || !o)
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 a = c.nodes.map((d) => ({
1076
- translation: d.translation || [0, 0, 0],
1077
- rotation: d.rotation || [0, 0, 0, 1],
1078
- scale: d.scale || [1, 1, 1],
1079
- children: d.children || [],
1080
- name: d.name || ""
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 (c.animations && c.animations.length > 0)
1083
- for (const d of c.animations) {
1084
- const u = [];
1085
- let f = 0;
1086
- for (const h of d.channels) {
1087
- const p = d.samplers[h.sampler], m = le(c, t, p.input), b = ce(c, t, p.output), S = m[m.length - 1];
1088
- S > f && (f = S), u.push({
1089
- targetNode: h.target.node,
1090
- targetPath: h.target.path,
1091
- interpolation: p.interpolation || "LINEAR",
1092
- timestamps: m,
1093
- values: b
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: d.name || `Animation ${l.length}`,
1098
- duration: f,
1099
- channels: u
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: r,
1105
- jointIndices: n,
1106
- jointWeights: o,
1107
- nodes: a,
1104
+ inverseBindMatrices: n,
1105
+ jointIndices: o,
1106
+ jointWeights: a,
1107
+ nodes: c,
1108
1108
  animations: l
1109
1109
  };
1110
1110
  }
1111
- async function ue(c) {
1112
- const t = new DataView(c);
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 r = 12, n = null, o = null;
1120
- for (; r < s; ) {
1121
- const _ = t.getUint32(r, !0), g = t.getUint32(r + 4, !0), x = c.slice(r + 8, r + 8 + _);
1122
- if (g === 1313821514) {
1123
- const M = new TextDecoder("utf-8").decode(x);
1124
- n = JSON.parse(M);
1125
- } else g === 5130562 && (o = x);
1126
- r += 8 + _;
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 (!n)
1128
+ if (!o)
1129
1129
  throw new Error("GLB file missing JSON chunk");
1130
- if (!n.materials || n.materials.length === 0)
1130
+ if (!o.materials || o.materials.length === 0)
1131
1131
  return null;
1132
- const a = n.materials[0];
1133
- if (!a.pbrMetallicRoughness || a.pbrMetallicRoughness.baseColorTexture === void 0)
1132
+ const c = o.materials[0];
1133
+ if (!c.pbrMetallicRoughness || c.pbrMetallicRoughness.baseColorTexture === void 0)
1134
1134
  return null;
1135
- const l = a.pbrMetallicRoughness.baseColorTexture.index;
1136
- if (!n.textures || !n.textures[l])
1135
+ const l = c.pbrMetallicRoughness.baseColorTexture.index;
1136
+ if (!o.textures || !o.textures[l])
1137
1137
  return null;
1138
- const u = n.textures[l].source;
1139
- if (u === void 0 || !n.images || !n.images[u])
1138
+ const f = o.textures[l].source;
1139
+ if (f === void 0 || !o.images || !o.images[f])
1140
1140
  return null;
1141
- const f = n.images[u], h = f.mimeType || "image/png";
1142
- if (f.bufferView === void 0)
1141
+ const h = o.images[f], m = h.mimeType || "image/png";
1142
+ if (h.bufferView === void 0)
1143
1143
  return null;
1144
- if (!o)
1144
+ if (!a)
1145
1145
  throw new Error("GLB file missing BIN chunk (required for embedded textures)");
1146
- const p = n.bufferViews[f.bufferView], m = p.byteOffset || 0, b = p.byteLength, S = o.slice(m, m + b);
1147
- return { imageBlob: new Blob([S], { type: h }), mimeType: h };
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 D = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1149
+ const ni = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1150
1150
  __proto__: null,
1151
- extractGLBTexture: ue,
1152
- parseGLB: X
1151
+ extractGLBTexture: ws,
1152
+ parseGLB: gi
1153
1153
  }, Symbol.toStringTag, { value: "Module" }));
1154
- function G(c, t, e) {
1154
+ function ai(r, t, e) {
1155
1155
  return [
1156
- c[0] + (t[0] - c[0]) * e,
1157
- c[1] + (t[1] - c[1]) * e,
1158
- c[2] + (t[2] - c[2]) * e
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 V(c, t, e) {
1162
- let i = c[0] * t[0] + c[1] * t[1] + c[2] * t[2] + c[3] * t[3], s = t;
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
- c[0] + (s[0] - c[0]) * e,
1166
- c[1] + (s[1] - c[1]) * e,
1167
- c[2] + (s[2] - c[2]) * e,
1168
- c[3] + (s[3] - c[3]) * e
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 fe(l);
1170
+ return Bs(l);
1171
1171
  }
1172
- const r = Math.acos(i), n = Math.sin(r), o = Math.sin((1 - e) * r) / n, a = Math.sin(e * r) / n;
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
- c[0] * o + s[0] * a,
1175
- c[1] * o + s[1] * a,
1176
- c[2] * o + s[2] * a,
1177
- c[3] * o + s[3] * a
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 fe(c) {
1181
- const t = Math.sqrt(c[0] * c[0] + c[1] * c[1] + c[2] * c[2] + c[3] * c[3]);
1182
- return t > 1e-4 ? [c[0] / t, c[1] / t, c[2] / t, c[3] / t] : [0, 0, 0, 1];
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 he(c) {
1185
- const t = c[0], e = c[1], i = c[2], s = c[3], r = t + t, n = e + e, o = i + i, a = t * r, l = t * n, d = t * o, u = e * n, f = e * o, h = i * o, p = s * r, m = s * n, b = s * o;
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 - (u + h),
1188
- l + b,
1189
- d - m,
1187
+ 1 - (f + m),
1188
+ l + D,
1189
+ u - R,
1190
1190
  0,
1191
- l - b,
1192
- 1 - (a + h),
1193
- f + p,
1191
+ l - D,
1192
+ 1 - (c + m),
1193
+ h + S,
1194
1194
  0,
1195
- d + m,
1196
- f - p,
1197
- 1 - (a + u),
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 pe(c, t, e) {
1206
- const i = he(t);
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
- c[0],
1221
- c[1],
1222
- c[2],
1220
+ r[0],
1221
+ r[1],
1222
+ r[2],
1223
1223
  1
1224
1224
  ]);
1225
1225
  }
1226
- function L(c, t) {
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] = c[0 + s] * t[i * 4 + 0] + c[4 + s] * t[i * 4 + 1] + c[8 + s] * t[i * 4 + 2] + c[12 + s] * t[i * 4 + 3];
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 me {
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, r = new Float32Array(s * 8);
1257
+ const s = this.restPositions.length / 3, n = new Float32Array(s * 8);
1258
1258
  for (let l = 0; l < s; l++) {
1259
- const d = l * 8, u = l * 3, f = l * 2;
1260
- r[d] = this.restPositions[u], r[d + 1] = this.restPositions[u + 1], r[d + 2] = this.restPositions[u + 2], r[d + 3] = this.restNormals[u], r[d + 4] = this.restNormals[u + 1], r[d + 5] = this.restNormals[u + 2], r[d + 6] = i ? i[f] : 0, r[d + 7] = i ? i[f + 1] : 0;
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: r.byteLength,
1263
+ size: n.byteLength,
1264
1264
  usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
1265
1265
  label: "skinning_restData"
1266
- }), t.queue.writeBuffer(this._gpuRestDataBuffer, 0, r), this._gpuJointWeightsBuffer = t.createBuffer({
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 n = new Uint32Array(this.jointIndices.length);
1271
+ const o = new Uint32Array(this.jointIndices.length);
1272
1272
  for (let l = 0; l < this.jointIndices.length; l++)
1273
- n[l] = this.jointIndices[l];
1273
+ o[l] = this.jointIndices[l];
1274
1274
  this._gpuJointIndicesBuffer = t.createBuffer({
1275
- size: n.byteLength,
1275
+ size: o.byteLength,
1276
1276
  usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
1277
1277
  label: "skinning_jointIndices"
1278
- }), t.queue.writeBuffer(this._gpuJointIndicesBuffer, 0, n), this._gpuJointMatricesBuffer = t.createBuffer({
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: o } = await Promise.resolve().then(() => H), a = t.createBindGroupLayout({
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: [a] }),
1293
+ layout: t.createPipelineLayout({ bindGroupLayouts: [c] }),
1294
1294
  compute: {
1295
- module: t.createShaderModule({ code: o }),
1295
+ module: t.createShaderModule({ code: a }),
1296
1296
  entryPoint: "main"
1297
1297
  }
1298
1298
  }), this._gpuSkinningBindGroup = t.createBindGroup({
1299
- layout: a,
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 = (r) => {
1360
- if (t.has(r)) return;
1361
- t.add(r);
1362
- const n = this.nodes[r];
1363
- for (const o of n.children)
1364
- i(o);
1365
- e.push(r);
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 r of this.nodes)
1368
- for (const n of r.children)
1369
- s.add(n);
1370
- for (let r = 0; r < this.nodes.length; r++)
1371
- s.has(r) || i(r);
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: r, targetPath: n } = t;
1378
+ const { timestamps: i, values: s, interpolation: n, targetPath: o } = t;
1379
1379
  if (e <= i[0])
1380
- return this._extractValue(s, 0, n);
1380
+ return this._extractValue(s, 0, o);
1381
1381
  if (e >= i[i.length - 1])
1382
- return this._extractValue(s, i.length - 1, n);
1383
- let o = 0, a = i.length - 1;
1384
- for (; a - o > 1; ) {
1385
- const p = Math.floor((o + a) / 2);
1386
- i[p] <= e ? o = p : a = p;
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[o], d = i[a], u = (e - l) / (d - l), f = this._extractValue(s, o, n), h = this._extractValue(s, a, n);
1389
- return r === "STEP" ? f : n === "rotation" ? V(f, h, u) : G(f, h, u);
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 r = s.translation, n = s.rotation, o = s.scale;
1411
- for (const a of e.channels)
1412
- if (a.targetNode === i) {
1413
- const l = this._sampleChannel(a, t);
1414
- a.targetPath === "translation" ? r = l : a.targetPath === "rotation" ? n = l : a.targetPath === "scale" && (o = l);
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] = pe(r, n, o);
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] = L(
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, r = this.inverseBindMatrices.slice(s, s + 16);
1443
- this.jointFinalMatrices[t] = L(i, r);
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, r = this.skinnedNormals, n = this.jointWeights, o = this.jointIndices, a = this.jointFinalMatrices;
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 d = l * 3, u = l * 4, f = e[d], h = e[d + 1], p = e[d + 2], m = i[d], b = i[d + 1], S = i[d + 2];
1454
- let y = 0, _ = 0, g = 0, x = 0, P = 0, M = 0;
1455
- for (let B = 0; B < 4; B++) {
1456
- const R = n[u + B];
1457
- if (R === 0) continue;
1458
- const v = a[o[u + B]];
1459
- y += (v[0] * f + v[4] * h + v[8] * p + v[12]) * R, _ += (v[1] * f + v[5] * h + v[9] * p + v[13]) * R, g += (v[2] * f + v[6] * h + v[10] * p + v[14]) * R, x += (v[0] * m + v[4] * b + v[8] * S) * R, P += (v[1] * m + v[5] * b + v[9] * S) * R, M += (v[2] * m + v[6] * b + v[10] * S) * R;
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 w = Math.sqrt(x * x + P * P + M * M);
1462
- w > 1e-4 && (r[d] = x / w, r[d + 1] = P / w, r[d + 2] = M / w), s[d] = y, s[d + 1] = _, s[d + 2] = g;
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 O(c) {
1467
- const t = atob(c), e = new Uint8Array(t.length);
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 A {
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: 176,
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 === void 0 && (e.particleShapeRotation = 0), e.particleShapeRotationX === void 0 && (e.particleShapeRotationX = 0), e.particleShapeRotationY === void 0 && (e.particleShapeRotationY = 0), e.particleShapeRotationZ === void 0 && (e.particleShapeRotationZ = 0), e.particleColor === void 0 && (e.particleColor = [1, 1, 1]), e.startColor === void 0 && (e.startColor = [1, 0, 0]), e.endColor === void 0 && (e.endColor = [0, 0, 1]), e.fadeEnabled === void 0 && (e.fadeEnabled = !0), e.colorTransitionEnabled === void 0 && (e.colorTransitionEnabled = !1), e.randomColorEnabled === void 0 && (e.randomColorEnabled = !1), e.randomColors === void 0 && (e.randomColors = []), e.particleSize === void 0 && (e.particleSize = 0.5), e.particleSpeed === void 0 && (e.particleSpeed = 1), e.opacity === void 0 && (e.opacity = 1), e.aspectRatio === void 0 && (e.aspectRatio = 1), e.rotation === void 0 && (e.rotation = 0), e.rotationMode === void 0 && (e.rotationMode = "fixed"), e.minRotation === void 0 && (e.minRotation = 0), e.maxRotation === void 0 && (e.maxRotation = 90), e.randomSize === void 0 && (e.randomSize = !1), e.minSize === void 0 && (e.minSize = 0.1), e.maxSize === void 0 && (e.maxSize = 0.5), e.randomSpeed === void 0 && (e.randomSpeed = !1), e.minSpeed === void 0 && (e.minSpeed = 0.1), e.maxSpeed === void 0 && (e.maxSpeed = 1), e.fadeSizeEnabled === void 0 && (e.fadeSizeEnabled = !1), e.increaseSizeEnabled === void 0 && (e.increaseSizeEnabled = !1), e.sizeLifetimeSpeed === void 0 && (e.sizeLifetimeSpeed = 1), e.bloomEnabled === void 0 && (e.bloomEnabled = !0), e.bloomIntensity === void 0 && (e.bloomIntensity = 1), e.bloomColor === void 0 && (e.bloomColor = [1, 1, 1]), e.gravityEnabled === void 0 && (e.gravityEnabled = !1), e.gravityStrength === void 0 && (e.gravityStrength = 2), e.dampingEnabled === void 0 && (e.dampingEnabled = !1), e.dampingStrength === void 0 && (e.dampingStrength = 1), e.attractorEnabled === void 0 && (e.attractorEnabled = !1), e.attractorStrength === void 0 && (e.attractorStrength = 1), e.attractorPosition === void 0 && (e.attractorPosition = [0, 0, 0]), e.burstMode === void 0 && (e.burstMode = !1), e.emissionShape === void 0 && (e.emissionShape = "cube"), e.lifetime === void 0 && (e.lifetime = 5), e.emissionRate === void 0 && (e.emissionRate = 10), e.emissionDuration === void 0 && (e.emissionDuration = 10), e.cubeLength === void 0 && (e.cubeLength = 2), e.outerLength === void 0 && (e.outerLength = 2), e.innerLength === void 0 && (e.innerLength = 0), e.outerRadius === void 0 && (e.outerRadius = 2), e.innerRadius === void 0 && (e.innerRadius = 0), e.squareSize === void 0 && (e.squareSize = 2), e.squareInnerSize === void 0 && (e.squareInnerSize = 0), e.circleInnerRadius === void 0 && (e.circleInnerRadius = 0), e.circleOuterRadius === void 0 && (e.circleOuterRadius = 2), e.circleVelocityDirection === void 0 && (e.circleVelocityDirection = "outward"), e.cylinderInnerRadius === void 0 && (e.cylinderInnerRadius = 0), e.cylinderOuterRadius === void 0 && (e.cylinderOuterRadius = 2), e.cylinderHeight === void 0 && (e.cylinderHeight = 4), e.cylinderVelocityDirection === void 0 && (e.cylinderVelocityDirection = "outward"), e.planeWidth === void 0 && (e.planeWidth = 2), e.planeDepth === void 0 && (e.planeDepth = 2), e.coneOuterRadius === void 0 && (e.coneOuterRadius = 2), e.coneInnerRadius === void 0 && (e.coneInnerRadius = 0), e.coneHeight === void 0 && (e.coneHeight = 4), e.torusMajorRadius === void 0 && (e.torusMajorRadius = 2), e.torusMinorRadius === void 0 && (e.torusMinorRadius = 0.5), e.lineLength === void 0 && (e.lineLength = 4), e.hemisphereOuterRadius === void 0 && (e.hemisphereOuterRadius = 2), e.hemisphereInnerRadius === void 0 && (e.hemisphereInnerRadius = 0), e.discRadius === void 0 && (e.discRadius = 2), e.annulusInnerRadius === void 0 && (e.annulusInnerRadius = 1), e.annulusOuterRadius === void 0 && (e.annulusOuterRadius = 2), e.capsuleRadius === void 0 && (e.capsuleRadius = 0.5), e.capsuleHeight === void 0 && (e.capsuleHeight = 4), e.arcStartAngle === void 0 && (e.arcStartAngle = 0), e.arcEndAngle === void 0 && (e.arcEndAngle = 180), e.arcInnerRadius === void 0 && (e.arcInnerRadius = 0), e.arcOuterRadius === void 0 && (e.arcOuterRadius = 2), e.spiralTurns === void 0 && (e.spiralTurns = 3), e.spiralRadiusStart === void 0 && (e.spiralRadiusStart = 0.5), e.spiralRadiusEnd === void 0 && (e.spiralRadiusEnd = 2), e.spiralHeight === void 0 && (e.spiralHeight = 4), e.frustumRadiusNear === void 0 && (e.frustumRadiusNear = 0.5), e.frustumRadiusFar === void 0 && (e.frustumRadiusFar = 2), e.frustumHeight === void 0 && (e.frustumHeight = 4), e.cubeSurfaceSize === void 0 && (e.cubeSurfaceSize = 2), e.sphereSurfaceRadius === void 0 && (e.sphereSurfaceRadius = 2), e.boxFrameSize === void 0 && (e.boxFrameSize = 2), e.polygonSides === void 0 && (e.polygonSides = 6), e.polygonRadius === void 0 && (e.polygonRadius = 2), e.emissionRotationX === void 0 && (e.emissionRotationX = 0), e.emissionRotationY === void 0 && (e.emissionRotationY = 0), e.emissionRotationZ === void 0 && (e.emissionRotationZ = 0), e.emissionTranslationX === void 0 && (e.emissionTranslationX = 0), e.emissionTranslationY === void 0 && (e.emissionTranslationY = 0), e.emissionTranslationZ === void 0 && (e.emissionTranslationZ = 0), e.pulseEnabled === void 0 && (e.pulseEnabled = !1), e.pulseAmplitude === void 0 && (e.pulseAmplitude = 0.5), e.pulseFrequency === void 0 && (e.pulseFrequency = 1), e.pulsePhaseRandom === void 0 && (e.pulsePhaseRandom = 0), e.pulseOpacity === void 0 && (e.pulseOpacity = !1), e.confinementEnabled === void 0 && (e.confinementEnabled = !1), e.confinementShape === void 0 && (e.confinementShape = "box"), e.confinementMode === void 0 && (e.confinementMode = "bounce"), e.confinementSpace === void 0 && (e.confinementSpace = "world"), e.confinementBoxHalfSize === void 0 && (e.confinementBoxHalfSize = [2, 2, 2]), e.confinementSphereRadius === void 0 && (e.confinementSphereRadius = 3), e.confinementRestitution === void 0 && (e.confinementRestitution = 0.8), e.confinementFriction === void 0 && (e.confinementFriction = 0.1), e.softBoundaryEnabled === void 0 && (e.softBoundaryEnabled = !1), e.softBoundaryStrength === void 0 && (e.softBoundaryStrength = 5), e.softBoundaryFalloff === void 0 && (e.softBoundaryFalloff = 0.5), e.depthWriteEnabled === void 0 && (e.depthWriteEnabled = !1), e.velocityStretchEnabled === void 0 && (e.velocityStretchEnabled = !1), e.velocityStretchFactor === void 0 && (e.velocityStretchFactor = 1), e.emissionTrailEnabled === void 0 && (e.emissionTrailEnabled = !1), e.emissionTrailDuration === void 0 && (e.emissionTrailDuration = 1), e.emissionTrailWidth === void 0 && (e.emissionTrailWidth = 0.3), e.emissionTrailMinDistance === void 0 && (e.emissionTrailMinDistance = 0.05), e.emissionTrailMaxPoints === void 0 && (e.emissionTrailMaxPoints = 256), e.emissionTrailSegments === void 0 && (e.emissionTrailSegments = 8), e.emissionTrailShape === void 0 && (e.emissionTrailShape = "straight"), e.emissionTrailShapeAmplitude === void 0 && (e.emissionTrailShapeAmplitude = 0.1), e.emissionTrailShapeFrequency === void 0 && (e.emissionTrailShapeFrequency = 4), e.emissionTrailShapeSpeed === void 0 && (e.emissionTrailShapeSpeed = 0), e.shapeDisplay === void 0 && (e.shapeDisplay = !0), e.followSystemTranslation === void 0 && (e.followSystemTranslation = !0), e.followSystemId === void 0 && (e.followSystemId = null), this._newEmissions = [], this._emptyEmissions = [], this._pendingFollowEmissions = this._emptyEmissions, this.glbVertexBuffer = null, this.glbIndexBuffer = null, this.glbIndexCount = 0, this.glbIndexFormat = "uint16", this.glbMeshData = null, this.glbRawArrayBuffer = null, this.glbAnimator = null, this.glbAnimated = !1, this._glbInterleavedData = null, this._appearanceData = new Float32Array(44), this._bloomIntensityData = new Float32Array(16), this._simPosition = [0, 0, 0], this._simVelocity = [0, 0, 0], this._simRotMatrix = null, this._simRotX = 0, this._simRotZ = 0, this.emitter = new W(e), this.physics = new J(t, this.MAX_PARTICLES), this.textureManager = new K(t), e.gravityEnabled && this.setGravity(e.gravityStrength || 0), e.dampingEnabled && this.physics.setDamping(e.dampingStrength || 0), e.attractorEnabled && e.attractorPosition && this.setAttractor(e.attractorStrength || 0, e.attractorPosition), e.confinementEnabled && this.setConfinement({
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 z(e.script, e, this.MAX_PARTICLES)), this.initComputePipeline(t);
1511
+ }), this.particleTexture = this.textureManager.getDefaultTexture(), this.updateBloomIntensity(), this.updateAppearanceUniform(), this.frameCount = 0, this.shouldReset = !1, this._scriptParticleData = new Float32Array(this.MAX_PARTICLES * 8), this._scriptVelocityData = new Float32Array(this.MAX_PARTICLES * 4), this._scriptReadbackPending = !1, this._scriptReadbackReady = !1, this._scriptFrame = 0, this._scriptTime = 0, this._scriptConfigRestored = !1, this._particleScript = null, e.script && (this._particleScript = new 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 z(t, this.config, this.MAX_PARTICLES), this._particleScript.snapshotConfig(this.config)) : delete this.config.script;
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 X(t);
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 r = s * 8, n = s * 3, o = s * 2;
1537
- i[r + 0] = e.positions[n + 0], i[r + 1] = e.positions[n + 1], i[r + 2] = e.positions[n + 2], i[r + 3] = e.normals[n + 0], i[r + 4] = e.normals[n + 1], i[r + 5] = e.normals[n + 2], e.texCoords ? (i[r + 6] = e.texCoords[o + 0], i[r + 7] = e.texCoords[o + 1]) : (i[r + 6] = 0, i[r + 7] = 0);
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 me(e.animationData), this.glbAnimator.setRestPose(e.positions, e.normals), this.glbAnimated = !0, this.config.glbAnimated = !0, this.glbAnimator.loop = this.config.animationLoop, this._glbInterleavedData = new Float32Array(e.vertexCount * 8);
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), r = Math.sin(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
- -r * e,
1580
- r * i,
1581
- r,
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
- 0,
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 r = s * 8, n = s * 3, o = s * 2;
1602
- this._glbInterleavedData[r] = t[n], this._glbInterleavedData[r + 1] = t[n + 1], this._glbInterleavedData[r + 2] = t[n + 2], this._glbInterleavedData[r + 3] = e[n], this._glbInterleavedData[r + 4] = e[n + 1], this._glbInterleavedData[r + 5] = e[n + 2], i ? (this._glbInterleavedData[r + 6] = i[o], this._glbInterleavedData[r + 7] = i[o + 1]) : (this._glbInterleavedData[r + 6] = 0, this._glbInterleavedData[r + 7] = 0);
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] = this.config.particleShapeRotation || 0, s[27] = this.config.pulseEnabled ? 1 : 0, s[28] = this.config.pulseAmplitude ?? 0.5, s[29] = this.config.pulseFrequency ?? 1, s[30] = this.config.pulsePhaseRandom ?? 0, s[31] = this.config.pulseOpacity ? 1 : 0, s[32] = this.config.particleShapeRotationX || 0, s[33] = this.config.particleShapeRotationY || 0, s[34] = this.config.particleShapeRotationZ || 0, s[35] = 0, (s[32] !== 0 || s[33] !== 0 || s[34] !== 0) && console.log(`[updateAppearanceUniform] ${this.config.name}: d[32-34] = ${s[32]}, ${s[33]}, ${s[34]}`);
1611
- const r = this.config.followSystemTranslation ?? !0;
1612
- s[36] = r ? this._simPosition[0] : 0, s[37] = r ? this._simPosition[1] : 0, s[38] = r ? this._simPosition[2] : 0, s[39] = 0, s[40] = this._simRotX, s[41] = this._simRotZ, s[42] = this.config.velocityStretchEnabled ? 1 : 0, s[43] = this.config.velocityStretchFactor ?? 1, this.device.queue.writeBuffer(this.appearanceUniformBuffer, 0, s);
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 r = s - e + 1, n = r * 8, o = r * 4;
1633
+ const n = s - e + 1, o = n * 8, a = n * 4;
1633
1634
  this.device.queue.writeBuffer(
1634
1635
  this.instanceBuffer,
1635
- n * 4,
1636
+ o * 4,
1636
1637
  // Offset in bytes
1637
1638
  this.particleData,
1638
- n,
1639
+ o,
1639
1640
  e * 8
1640
1641
  ), this.device.queue.writeBuffer(
1641
1642
  this.velocityBuffer,
1642
- o * 4,
1643
+ a * 4,
1643
1644
  // Offset in bytes
1644
1645
  this.particleVelocities,
1645
- o,
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.max(this.config.emissionDuration || 10, t);
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
- if (this._simRotMatrix) {
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, r = t + (this.config.emissionTranslationX || 0), n = e + (this.config.emissionTranslationY || 0), o = i + (this.config.emissionTranslationZ || 0);
1681
- this.particleData[s] = r, this.particleData[s + 1] = n, this.particleData[s + 2] = o;
1682
- const a = this.activeParticles * 4;
1683
- return this.emitter.calculateVelocity(r, n, o, this.particleVelocities, a), this.emitter.setParticleColor(this.particleData, s), this.emitter.setParticleLifetime(this.particleData, s), this.activeParticles++, !0;
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 o = (this.config.emissionDuration || 0) + (this.config.lifetime || 0);
1689
- if (o > 0 && this._scriptTime >= o && !this._scriptConfigRestored)
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 a = o > 0 ? Math.ceil(o / 0.016666666666666666) : 0, { configDirty: l, particlesDirty: d } = this._particleScript.execute(
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
- a,
1712
+ c,
1697
1713
  this._scriptParticleData,
1698
1714
  this._scriptVelocityData,
1699
1715
  this.activeParticles
1700
1716
  );
1701
- d && this.activeParticles > 0 && (this.device.queue.writeBuffer(
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, r = i - this.physics.lastUpdateTime > 1 / this.physics.minUpdatesPerSecond, n = this.activeParticles;
1718
- if (this.emitting)
1719
- if (this.currentEmissionTime += t, this.currentEmissionTime < this.config.emissionDuration) {
1720
- const o = this.activeParticles;
1721
- let a = !1;
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 d = 0; d < l; d++) {
1726
- const u = d * 6;
1741
+ for (let u = 0; u < l; u++) {
1742
+ const f = u * 6;
1727
1743
  if (this.emitFollowerParticle(
1728
- this._pendingFollowEmissions[u],
1729
- this._pendingFollowEmissions[u + 1],
1730
- this._pendingFollowEmissions[u + 2]
1744
+ this._pendingFollowEmissions[f],
1745
+ this._pendingFollowEmissions[f + 1],
1746
+ this._pendingFollowEmissions[f + 2]
1731
1747
  ))
1732
- a = !0;
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 d = this.config.emissionRate * t - l;
1742
- Math.random() < d && (l += 1);
1757
+ const u = this.config.emissionRate * t - l;
1758
+ Math.random() < u && (l += 1);
1743
1759
  } else {
1744
- const d = this.config.emissionRate * t;
1745
- Math.random() < d && (l = 1);
1760
+ const u = this.config.emissionRate * t;
1761
+ Math.random() < u && (l = 1);
1746
1762
  }
1747
- l === 0 && r && this.config.emissionRate > 0 && this.activeParticles < this.particleCount && (l = 1);
1748
- for (let d = 0; d < l && this.emitParticle(); d++)
1749
- a = !0;
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 (a) {
1752
- const l = this.activeParticles - o, d = o * 8, u = o * 4;
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
- d * 4,
1771
+ u * 4,
1756
1772
  // Offset in bytes (float32 = 4 bytes)
1757
1773
  this.particleData,
1758
- d,
1774
+ u,
1759
1775
  l * 8
1760
1776
  ), this.device.queue.writeBuffer(
1761
1777
  this.velocityBuffer,
1762
- u * 4,
1778
+ f * 4,
1763
1779
  // Offset in bytes (float32 = 4 bytes)
1764
1780
  this.particleVelocities,
1765
- u,
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
- n,
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
- r && n > 0 && (this.physics.updatePhysics(
1796
+ n && o > 0 && (this.physics.updatePhysics(
1781
1797
  this.physics.fixedDeltaTime,
1782
- n,
1798
+ o,
1783
1799
  this.config,
1784
1800
  this.instanceBuffer,
1785
1801
  this.velocityBuffer,
1786
1802
  e
1787
- ), this.physics.lastUpdateTime = i), this.frameCount++ % 300 === 0 && this.readbackAndProcessParticles(), this._particleScript && this.activeParticles > 0 && !this._scriptReadbackPending && (this._scriptReadbackPending = !0, this.physics.readbackForScript(
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((o) => {
1794
- this._scriptReadbackPending = !1, o.shouldUpdate && (this._scriptReadbackReady = !0);
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 i = 0; i < this.activeParticles; i++) {
1811
- const s = this.particleData[i * 8 + 6], r = this.particleData[i * 8 + 7];
1812
- if (s >= r) {
1813
- if (this.emitting && this.currentEmissionTime < this.config.emissionDuration && e < this.particleCount) {
1814
- this.respawnParticle(i, e), e++;
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 !== i) {
1820
- const n = i * 8, o = e * 8;
1821
- this.particleData.copyWithin(o, n, n + 8);
1822
- const a = i * 4, l = e * 4;
1823
- this.particleVelocities.copyWithin(l, a, a + 4);
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.config.emissionDuration || this.config.followSystemId || this.emitter.emitParticle(this.particleData, e, this.particleVelocities);
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
- for (let t = 0; t < this.activeParticles; t++) {
1840
- const e = t * 8;
1841
- if (this.config.randomColorEnabled && this.config.randomColors.length > 0) {
1842
- const i = this.config.randomColors, s = i[Math.floor(Math.random() * i.length)];
1843
- this.particleData[e + 3] = s[0], this.particleData[e + 4] = s[1], this.particleData[e + 5] = s[2];
1844
- } else this.config.colorTransitionEnabled ? (this.particleData[e + 3] = this.config.startColor[0], this.particleData[e + 4] = this.config.startColor[1], this.particleData[e + 5] = this.config.startColor[2]) : (this.particleData[e + 3] = this.config.particleColor[0], this.particleData[e + 4] = this.config.particleColor[1], this.particleData[e + 5] = this.config.particleColor[2]);
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], r = this.particleData[e + 1], n = this.particleData[e + 2], o = this.particleVelocities[i], a = this.particleVelocities[i + 1], l = this.particleVelocities[i + 2], d = Math.sqrt(
1851
- o * o + a * a + l * l
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 (d > 1e-3) {
1854
- const u = this.config.particleSpeed * 2;
1855
- this.particleVelocities[i] = o / d * u, this.particleVelocities[i + 1] = a / d * u, this.particleVelocities[i + 2] = l / d * u;
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 u = Math.sqrt(s * s + r * r + n * n);
1858
- if (u > 1e-3) {
1859
- const f = this.config.particleSpeed * 2;
1860
- this.particleVelocities[i] = s / u * f, this.particleVelocities[i + 1] = r / u * f, this.particleVelocities[i + 2] = n / u * f;
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.emissionTranslationX || 0, this.config.emissionTranslationY || 0, this.config.emissionTranslationZ || 0] : [0, 0, 0];
1899
- this.physics.setConfinement({ ...t, center: e });
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 Me {
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
- }, r = new A(this.device, s);
1932
+ }, n = new bt(this.device, s);
1915
1933
  return this.particleSystems.push({
1916
- system: r,
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: r } of this.particleSystems) {
1959
- if (r.hidden || r.followSystemId) continue;
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 r = this.systemCounter++, n = {
2019
+ const n = this.systemCounter++, o = {
2001
2020
  ...s,
2002
- id: r
2003
- }, o = new A(this.device, n);
2021
+ id: n
2022
+ }, a = new bt(this.device, o);
2004
2023
  this.particleSystems.push({
2005
- system: o,
2006
- config: n
2024
+ system: a,
2025
+ config: o
2007
2026
  });
2008
2027
  }
2009
2028
  const i = {};
2010
- t.systems.forEach((s, r) => {
2011
- i[s.id] = this.particleSystems[r].config.id;
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: r } of this.particleSystems)
2017
- if (r.glbModelEnabled)
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 n = null;
2020
- if (r.glbModelData)
2021
- n = O(r.glbModelData);
2022
- else if (r.glbFileName) {
2023
- const o = await fetch(`/${r.glbFileName}`);
2024
- o.ok ? n = await o.arrayBuffer() : console.warn(`GLB file not found: ${r.glbFileName}`);
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 (n) {
2027
- if (await s.setGLBModel(n), r.animationIndex !== void 0 && s.glbAnimator && s.glbAnimator.setAnimation(r.animationIndex), r.animationSpeed !== void 0 && s.glbAnimator && (s.glbAnimator.speed = r.animationSpeed), r.animationLoop !== void 0 && s.glbAnimator && (s.glbAnimator.loop = r.animationLoop), r.useGlbTexture && (r.textureEnabled = !0), r.useGlbTexture && ((e = s.glbMeshData) != null && e.hasBaseColorTexture))
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: o } = await Promise.resolve().then(() => D), a = await o(n);
2030
- if (a) {
2031
- const l = await createImageBitmap(a.imageBlob);
2032
- await s.setTexture(l), console.log(`GLB embedded texture restored for ${r.name}`);
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 (o) {
2035
- console.warn(`Failed to restore GLB texture for ${r.name}:`, o), r.useGlbTexture = !1;
2053
+ } catch (a) {
2054
+ console.warn(`Failed to restore GLB texture for ${n.name}:`, a), n.useGlbTexture = !1;
2036
2055
  }
2037
2056
  } else
2038
- r.glbModelEnabled = !1;
2039
- } catch (n) {
2040
- console.warn(`Failed to load GLB for ${r.name}:`, n), r.glbModelEnabled = !1;
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: r } of this.particleSystems)
2043
- if (r.textureEnabled && !r.glbModelEnabled && r.textureImageData)
2061
+ for (const { system: s, config: n } of this.particleSystems)
2062
+ if (n.textureEnabled && !n.glbModelEnabled && n.textureImageData)
2044
2063
  try {
2045
- const n = new Image();
2046
- await new Promise((a, l) => {
2047
- n.onload = a, n.onerror = l, n.src = r.textureImageData;
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 o = await createImageBitmap(n);
2050
- await s.setTexture(o);
2051
- } catch (n) {
2052
- console.warn(`Failed to restore texture for ${r.name}:`, n), r.textureEnabled = !1;
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: r } of this.particleSystems)
2055
- s.updateAppearanceUniform(), (r.particleShapeRotationX || r.particleShapeRotationY || r.particleShapeRotationZ) && console.log(`[replaceSystems] ${r.name}: glbRotation XYZ = ${r.particleShapeRotationX}, ${r.particleShapeRotationY}, ${r.particleShapeRotationZ} | glbModelEnabled=${r.glbModelEnabled} | glbMeshData=${!!s.glbMeshData}`);
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 i;
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 n of t.systems) {
2074
- const o = this.systemCounter++, a = {
2075
- ...n,
2076
- id: o,
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
- emissionTranslationX: (n.emissionTranslationX || 0) + e[0],
2079
- emissionTranslationY: (n.emissionTranslationY || 0) + e[1],
2080
- emissionTranslationZ: (n.emissionTranslationZ || 0) + e[2]
2103
+ emissionPositionX: (a.emissionPositionX || 0) + e[0],
2104
+ emissionPositionY: (a.emissionPositionY || 0) + e[1],
2105
+ emissionPositionZ: (a.emissionPositionZ || 0) + e[2]
2081
2106
  };
2082
- n.attractorEnabled && n.attractorPosition && (a.attractorPosition = [
2083
- n.attractorPosition[0] + e[0],
2084
- n.attractorPosition[1] + e[1],
2085
- n.attractorPosition[2] + e[2]
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 l = new A(this.device, a);
2112
+ const u = new bt(this.device, l);
2088
2113
  this.particleSystems.push({
2089
- system: l,
2090
- config: a
2091
- }), this.onSystemCreated && typeof this.onSystemCreated == "function" && this.onSystemCreated(o, a);
2114
+ system: u,
2115
+ config: l
2116
+ }), this.onSystemCreated && typeof this.onSystemCreated == "function" && this.onSystemCreated(c, l);
2092
2117
  }
2093
- const s = this.particleSystems.length - t.systems.length, r = {};
2094
- t.systems.forEach((n, o) => {
2095
- r[n.id] = this.particleSystems[s + o].config.id;
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 n = s; n < this.particleSystems.length; n++) {
2098
- const { config: o } = this.particleSystems[n];
2099
- o.followSystemId && r[o.followSystemId] !== void 0 && (o.followSystemId = r[o.followSystemId]);
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: n, config: o } of this.particleSystems)
2102
- if (o.glbModelEnabled && !n.glbMeshData)
2126
+ for (const { system: a, config: c } of this.particleSystems)
2127
+ if (c.glbModelEnabled && !a.glbMeshData)
2103
2128
  try {
2104
- let a = null;
2105
- if (o.glbModelData)
2106
- a = O(o.glbModelData);
2107
- else if (o.glbFileName) {
2108
- const l = await fetch(`/${o.glbFileName}`);
2109
- l.ok ? a = await l.arrayBuffer() : console.warn(`GLB file not found: ${o.glbFileName}`);
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 (a) {
2112
- if (await n.setGLBModel(a), o.animationIndex !== void 0 && n.glbAnimator && n.glbAnimator.setAnimation(o.animationIndex), o.animationSpeed !== void 0 && n.glbAnimator && (n.glbAnimator.speed = o.animationSpeed), o.animationLoop !== void 0 && n.glbAnimator && (n.glbAnimator.loop = o.animationLoop), o.useGlbTexture && (o.textureEnabled = !0), o.useGlbTexture && ((i = n.glbMeshData) != null && i.hasBaseColorTexture))
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: l } = await Promise.resolve().then(() => D), d = await l(a);
2115
- if (d) {
2116
- const u = await createImageBitmap(d.imageBlob);
2117
- await n.setTexture(u), console.log(`GLB embedded texture restored for ${o.name}`);
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 (l) {
2120
- console.warn(`Failed to restore GLB texture for ${o.name}:`, l), o.useGlbTexture = !1;
2144
+ } catch (u) {
2145
+ console.warn(`Failed to restore GLB texture for ${c.name}:`, u), c.useGlbTexture = !1;
2121
2146
  }
2122
2147
  } else
2123
- o.glbModelEnabled = !1;
2124
- } catch (a) {
2125
- console.warn(`Failed to load GLB for ${o.name}:`, a), o.glbModelEnabled = !1;
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: n, config: o } of this.particleSystems)
2128
- if (o.textureEnabled && !o.glbModelEnabled && o.textureImageData && !n._textureRestored)
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 a = new Image();
2131
- await new Promise((d, u) => {
2132
- a.onload = d, a.onerror = u, a.src = o.textureImageData;
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 l = await createImageBitmap(a);
2135
- await n.setTexture(l), n._textureRestored = !0;
2136
- } catch (a) {
2137
- console.warn(`Failed to restore texture for ${o.name}:`, a), o.textureEnabled = !1;
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 !0;
2140
- } catch (s) {
2141
- return console.error("Error adding systems:", s), !1;
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 Re(c) {
2146
- if (!c)
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 = c.getContext("webgpu"), i = await (await navigator.gpu.requestAdapter()).requestDevice(), s = navigator.gpu.getPreferredCanvasFormat();
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: c };
2182
+ }), { device: i, context: t, format: s, canvas: r };
2156
2183
  }
2157
- function we(c, t, e, i) {
2158
- const s = c.createTexture({
2184
+ const le = "rgba16float";
2185
+ function ui(r, t, e, i) {
2186
+ const s = r.createTexture({
2159
2187
  size: [e, i],
2160
- format: t,
2188
+ format: le,
2161
2189
  usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
2162
2190
  mipLevelCount: 1,
2163
2191
  sampleCount: 1
2164
- }), r = c.createTexture({
2192
+ }), n = r.createTexture({
2165
2193
  size: [e, i],
2166
- format: t,
2194
+ format: le,
2167
2195
  usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
2168
2196
  mipLevelCount: 1,
2169
2197
  sampleCount: 1
2170
- }), n = c.createTexture({
2198
+ }), o = r.createTexture({
2171
2199
  size: [e, i],
2172
- format: t,
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: r, bloomTexB: n };
2205
+ return { sceneTexture: s, bloomTexA: n, bloomTexB: o };
2178
2206
  }
2179
- function Be(c, t, e) {
2180
- return c.createTexture({
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 C(c, t, e) {
2187
- const i = c.createBuffer({
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 Y = `
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
- // Transform velocity from world to view space to get correct orientation
2339
- let viewVelocity = (uniforms.transform * vec4<f32>(input.particleVelocity, 0.0)).xyz;
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
- let texColor = textureSample(particleTexture, particleSampler, input.texCoord);
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
- `, q = `
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
- `, Z = `
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
- `, ye = `
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
- `, ge = `
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
- `, H = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
3047
+ `, _i = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2938
3048
  __proto__: null,
2939
- blurShader: q,
2940
- compositeShader: Z,
2941
- directRenderShader: $,
2942
- particlePhysicsShader: ye,
2943
- particleShader: Y,
2944
- skinningComputeShader: ge
2945
- }, Symbol.toStringTag, { value: "Module" })), be = `
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
- `, Se = `
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 Te(c) {
3244
- const t = c.createBindGroupLayout({
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 = c.createBindGroupLayout({
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 = c.createBindGroupLayout({
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 = c.createBindGroupLayout({
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 Ce(c, t, e, i = {}) {
3330
- const { depthCompare: s } = i, r = s || "less", {
3331
- particleBindGroupLayout: n,
3332
- bloomBindGroupLayout: o,
3333
- compositeBindGroupLayout: a,
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, d = c.createPipelineLayout({
3336
- bindGroupLayouts: [n]
3337
- }), u = c.createPipelineLayout({
3446
+ } = e, u = r.createPipelineLayout({
3338
3447
  bindGroupLayouts: [o]
3339
- }), f = c.createPipelineLayout({
3448
+ }), f = r.createPipelineLayout({
3340
3449
  bindGroupLayouts: [a]
3341
- }), h = c.createShaderModule({
3342
- code: Y
3343
- }), p = c.createShaderModule({
3344
- code: q
3345
- }), m = c.createShaderModule({
3346
- code: Z
3347
- }), b = c.createShaderModule({
3348
- code: $
3349
- }), S = c.createShaderModule({
3350
- code: be
3351
- }), y = c.createShaderModule({
3352
- code: Se
3353
- }), _ = c.createRenderPipeline({
3354
- layout: d,
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: h,
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: h,
3528
+ module: m,
3418
3529
  entryPoint: "fs_main",
3419
3530
  targets: [{
3420
- format: t,
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: r,
3541
+ depthCompare: n,
3442
3542
  format: "depth24plus"
3443
3543
  }
3444
- }), g = c.createRenderPipeline({
3445
- layout: d,
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: h,
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: h,
3630
+ module: m,
3509
3631
  entryPoint: "fs_main",
3510
3632
  targets: [{
3511
- format: t,
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
- }), x = c.createRenderPipeline({
3527
- layout: u,
3648
+ }), L = r.createRenderPipeline({
3649
+ layout: f,
3528
3650
  vertex: {
3529
- module: p,
3651
+ module: S,
3530
3652
  entryPoint: "vs_main"
3531
3653
  },
3532
3654
  fragment: {
3533
- module: p,
3655
+ module: S,
3534
3656
  entryPoint: "fs_main",
3535
3657
  targets: [{
3536
- format: t
3658
+ format: le
3537
3659
  }]
3538
3660
  },
3539
3661
  primitive: {
3540
3662
  topology: "triangle-list"
3541
3663
  }
3542
- }), P = c.createRenderPipeline({
3543
- layout: f,
3664
+ }), N = r.createRenderPipeline({
3665
+ layout: h,
3544
3666
  vertex: {
3545
- module: m,
3667
+ module: R,
3546
3668
  entryPoint: "vs_main"
3547
3669
  },
3548
3670
  fragment: {
3549
- module: m,
3671
+ module: R,
3550
3672
  entryPoint: "fs_main",
3551
3673
  targets: [{
3552
- format: t,
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
- }), M = c.createRenderPipeline({
3571
- layout: f,
3692
+ }), k = r.createRenderPipeline({
3693
+ layout: h,
3572
3694
  vertex: {
3573
- module: b,
3695
+ module: D,
3574
3696
  entryPoint: "vs_main"
3575
3697
  },
3576
3698
  fragment: {
3577
- module: b,
3699
+ module: D,
3578
3700
  entryPoint: "fs_main",
3579
3701
  targets: [{
3580
- format: t,
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
- }), w = c.createPipelineLayout({
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
- }), B = c.createRenderPipeline({
3601
- layout: w,
3737
+ }), De = r.createRenderPipeline({
3738
+ layout: me,
3602
3739
  vertex: {
3603
- module: S,
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: S,
3765
+ module: C,
3629
3766
  entryPoint: "fs_main",
3630
3767
  targets: [{
3631
- format: t,
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: r,
3789
+ depthCompare: n,
3653
3790
  format: "depth24plus"
3654
3791
  }
3655
- }), R = c.createRenderPipeline({
3656
- layout: d,
3792
+ }), ze = r.createRenderPipeline({
3793
+ layout: u,
3657
3794
  vertex: {
3658
- module: y,
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: y,
3867
+ module: B,
3731
3868
  entryPoint: "fs_main",
3732
3869
  targets: [{
3733
- format: t,
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: r,
3891
+ depthCompare: n,
3755
3892
  format: "depth24plus"
3756
3893
  }
3757
3894
  });
3758
3895
  return {
3759
- particlePipeline: _,
3760
- particleDepthWritePipeline: g,
3761
- blurPipeline: x,
3762
- compositePipeline: P,
3763
- directRenderPipeline: M,
3764
- object3dPipeline: B,
3765
- glbMeshPipeline: R
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 Ee(c, t, e, i) {
3907
+ function St(r, t, e, i) {
3769
3908
  const {
3770
3909
  uniformBuffer: s,
3771
- appearanceUniformBuffer: r,
3772
- horizontalBlurUniformBuffer: n,
3773
- verticalBlurUniformBuffer: o,
3774
- bloomIntensityBuffer: a
3910
+ appearanceUniformBuffer: n,
3911
+ horizontalBlurUniformBuffer: o,
3912
+ verticalBlurUniformBuffer: a,
3913
+ bloomIntensityBuffer: c
3775
3914
  } = e, {
3776
3915
  sceneTexture: l,
3777
- bloomTexA: d,
3778
- bloomTexB: u
3779
- } = i, f = c.createBindGroup({
3780
- layout: c.createBindGroupLayout({
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: r }
3940
+ resource: { buffer: n }
3802
3941
  }
3803
3942
  ]
3804
- }), h = c.createBindGroup({
3805
- layout: c.createBindGroupLayout({
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: n }
3974
+ resource: { buffer: o }
3836
3975
  }
3837
3976
  ]
3838
- }), p = c.createBindGroup({
3839
- layout: c.createBindGroupLayout({
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: d.createView()
4004
+ resource: u.createView()
3866
4005
  },
3867
4006
  {
3868
4007
  binding: 2,
3869
- resource: { buffer: o }
4008
+ resource: { buffer: a }
3870
4009
  }
3871
4010
  ]
3872
- }), m = c.createBindGroup({
3873
- layout: c.createBindGroupLayout({
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: u.createView()
4047
+ resource: f.createView()
3909
4048
  },
3910
4049
  {
3911
4050
  binding: 3,
3912
- resource: { buffer: a }
4051
+ resource: { buffer: c }
3913
4052
  }
3914
4053
  ]
3915
- }), b = c.createBindGroup({
3916
- layout: c.createBindGroupLayout({
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: u.createView()
4090
+ resource: f.createView()
3952
4091
  },
3953
4092
  {
3954
4093
  binding: 3,
3955
- resource: { buffer: a }
4094
+ resource: { buffer: c }
3956
4095
  }
3957
4096
  ]
3958
4097
  });
3959
4098
  return {
3960
- particleBindGroup: f,
3961
- horizontalBlurBindGroup: h,
3962
- verticalBlurBindGroup: p,
3963
- compositeBindGroup: m,
3964
- directRenderBindGroup: b
4099
+ particleBindGroup: h,
4100
+ horizontalBlurBindGroup: m,
4101
+ verticalBlurBindGroup: S,
4102
+ compositeBindGroup: R,
4103
+ directRenderBindGroup: D
3965
4104
  };
3966
4105
  }
3967
- function Ae(c) {
3968
- return c.createSampler({
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 xe() {
3978
- const c = new Float32Array([
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: c, indices: t };
4312
+ return { vertices: r, indices: t };
4174
4313
  }
4175
- function ve(c = 16, t = 16) {
4314
+ function Os(r = 16, t = 16) {
4176
4315
  const e = [], i = [];
4177
- for (let s = 0; s <= c; s++) {
4178
- const r = s * Math.PI / c, n = Math.sin(r), o = Math.cos(r);
4179
- for (let a = 0; a <= t; a++) {
4180
- const l = a * 2 * Math.PI / t, d = Math.sin(l), f = Math.cos(l) * n, h = o, p = d * n;
4181
- e.push(f * 0.5, h * 0.5, p * 0.5), e.push(f, h, p);
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 < c; s++)
4185
- for (let r = 0; r < t; r++) {
4186
- const n = s * (t + 1) + r, o = n + t + 1;
4187
- i.push(n), i.push(o), i.push(n + 1), i.push(o), i.push(o + 1), i.push(n + 1);
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 _e {
4195
- constructor(t, e, i, s, r) {
4196
- this.id = t, this.type = e, this.position = i, this.scale = s, this.color = r, this.rotation = [0, 0, 0];
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), r = this.createRotationMatrixX(i[0]), n = this.createRotationMatrixY(i[1]), o = this.createRotationMatrixZ(i[2]), a = this.createScaleMatrix(e);
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, o), l = this.multiplyMatrices(l, n), l = this.multiplyMatrices(l, r), l = this.multiplyMatrices(l, a), 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 r = 0; r < 4; r++) {
4320
- let n = 0;
4321
- for (let o = 0; o < 4; o++)
4322
- n += t[s * 4 + o] * e[o * 4 + r];
4323
- i[s * 4 + r] = n;
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 Ie {
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 = xe(), e = ve(16, 16);
4337
- this.cubeVertexBuffer = C(
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 = C(
4480
+ ), this.cubeIndexBuffer = Ge(
4342
4481
  this.device,
4343
4482
  t.indices,
4344
4483
  GPUBufferUsage.INDEX
4345
- ), this.cubeIndexCount = t.indices.length, this.sphereVertexBuffer = C(
4484
+ ), this.cubeIndexCount = t.indices.length, this.sphereVertexBuffer = Ge(
4346
4485
  this.device,
4347
4486
  e.vertices,
4348
4487
  GPUBufferUsage.VERTEX
4349
- ), this.sphereIndexBuffer = C(
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 r = new _e(this.nextId++, t, e, i, s);
4365
- return r.uniformBuffer = this.device.createBuffer({
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(r), this.onObjectAdded && this.onObjectAdded(r), r;
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 r of this.objects) {
4434
- this.updateObjectUniforms(r);
4435
- const n = this.device.createBindGroup({
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: r.uniformBuffer } }
4578
+ { binding: 1, resource: { buffer: n.uniformBuffer } }
4440
4579
  ]
4441
4580
  });
4442
- let o, a, l;
4443
- if (r.type === "cube")
4444
- o = this.cubeVertexBuffer, a = this.cubeIndexBuffer, l = this.cubeIndexCount;
4445
- else if (r.type === "sphere")
4446
- o = this.sphereVertexBuffer, a = this.sphereIndexBuffer, l = this.sphereIndexCount;
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, n), t.setVertexBuffer(0, o), t.setIndexBuffer(a, "uint16"), t.drawIndexed(l);
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 Ue(c) {
4454
- const t = parseInt(c.slice(1, 3), 16) / 255, e = parseInt(c.slice(3, 5), 16) / 255, i = parseInt(c.slice(5, 7), 16) / 255;
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 ze(c) {
4458
- if (!c) return "#ffffff";
4459
- const t = Math.round(c[0] * 255).toString(16).padStart(2, "0"), e = Math.round(c[1] * 255).toString(16).padStart(2, "0"), i = Math.round(c[2] * 255).toString(16).padStart(2, "0");
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 Fe(c, t, e) {
4463
- const i = k([
4464
- c[0] - t[0],
4465
- c[1] - t[1],
4466
- c[2] - t[2]
4467
- ]), s = k(j(e, i)), r = j(i, 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
- r[0],
4609
+ n[0],
4471
4610
  i[0],
4472
4611
  0,
4473
4612
  s[1],
4474
- r[1],
4613
+ n[1],
4475
4614
  i[1],
4476
4615
  0,
4477
4616
  s[2],
4478
- r[2],
4617
+ n[2],
4479
4618
  i[2],
4480
4619
  0,
4481
- -I(s, c),
4482
- -I(r, c),
4483
- -I(i, c),
4620
+ -xt(s, r),
4621
+ -xt(n, r),
4622
+ -xt(i, r),
4484
4623
  1
4485
4624
  ]);
4486
4625
  }
4487
- function De(c, t = Math.PI / 4) {
4626
+ function Ks(r, t = Math.PI / 4) {
4488
4627
  const s = 1 / Math.tan(t / 2);
4489
4628
  return new Float32Array([
4490
- s * c,
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 k(c) {
4509
- const t = Math.sqrt(c[0] * c[0] + c[1] * c[1] + c[2] * c[2]);
4510
- return [c[0] / t, c[1] / t, c[2] / t];
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 j(c, t) {
4651
+ function pi(r, t) {
4513
4652
  return [
4514
- c[1] * t[2] - c[2] * t[1],
4515
- c[2] * t[0] - c[0] * t[2],
4516
- c[0] * t[1] - c[1] * t[0]
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 I(c, t) {
4520
- return c[0] * t[0] + c[1] * t[1] + c[2] * t[2];
4658
+ function xt(r, t) {
4659
+ return r[0] * t[0] + r[1] * t[1] + r[2] * t[2];
4521
4660
  }
4522
- function Ge(c, t) {
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 r = 0;
4527
- for (let n = 0; n < 4; n++)
4528
- r += c[i + n * 4] * t[n + s * 4];
4529
- e[i + s * 4] = r;
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 Pe(c) {
4534
- const t = new Uint8Array(c);
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 Ve(c, t) {
4541
- if (!c || !c.particleSystems || c.particleSystems.length === 0) {
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 e = {
4943
+ const i = {
4547
4944
  version: "1.0",
4548
4945
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
4549
- systems: c.particleSystems.map(({ config: a, system: l }) => ({
4550
- // Include only the serializable properties of each system
4551
- name: a.name,
4552
- id: a.id,
4553
- particleCount: a.particleCount,
4554
- lifetime: a.lifetime,
4555
- emissionRate: a.emissionRate,
4556
- emissionDuration: a.emissionDuration,
4557
- particleSize: a.particleSize,
4558
- particleSpeed: a.particleSpeed,
4559
- emissionShape: a.emissionShape,
4560
- cubeLength: a.outerLength || a.cubeLength,
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: c.activeSystemIndex
4670
- }, i = JSON.stringify(e, null, 2);
4671
- let s;
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
- s = `${t}.json`;
4965
+ o = t;
4674
4966
  else {
4675
- const a = /* @__PURE__ */ new Date();
4676
- s = `particle-scene_${`${a.getFullYear()}-${(a.getMonth() + 1).toString().padStart(2, "0")}-${a.getDate().toString().padStart(2, "0")}_${a.getHours().toString().padStart(2, "0")}${a.getMinutes().toString().padStart(2, "0")}`}.json`;
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 r = new Blob([i], { type: "application/json" }), n = URL.createObjectURL(r), o = document.createElement("a");
4679
- o.href = n, o.download = s, document.body.appendChild(o), o.click(), document.body.removeChild(o), URL.revokeObjectURL(n);
4680
- } catch (e) {
4681
- console.error("Error saving scene:", e), alert("Error saving scene. See console for details.");
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 Le(c) {
4976
+ function er(r) {
4685
4977
  return new Promise((t, e) => {
4686
4978
  try {
4687
- const i = c.target.files[0];
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 = (r) => {
4985
+ s.onload = (n) => {
4694
4986
  try {
4695
- const n = JSON.parse(r.target.result);
4696
- if (!n.version)
4697
- throw new Error("Invalid scene file: missing version information");
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: o,
4705
- activeSystemIndex: n.activeSystemIndex || 0
4992
+ systems: a.systems.slice(),
4993
+ activeSystemIndex: a.activeSystemIndex || 0
4706
4994
  });
4707
- } catch (n) {
4708
- console.error("Error loading scene:", n), alert("Error loading scene: " + n.message), e(n);
4995
+ } catch (o) {
4996
+ console.error("Error loading scene:", o), alert("Error loading scene: " + o.message), e(o);
4709
4997
  }
4710
- c.target.value = "";
4998
+ r.target.value = "";
4711
4999
  }, s.onerror = () => {
4712
- alert("Failed to read the file"), e(new Error("Failed to read the file")), c.target.value = "";
4713
- }, s.readAsText(i);
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 Oe(c) {
4720
- if (!c || typeof c != "string")
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(c);
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.json();
4726
- if (!Array.isArray(e.systems) || e.systems.length === 0)
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: e.version,
4730
- systems: e.systems,
4731
- activeSystemIndex: e.activeSystemIndex ?? 0
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
- me as GLBAnimator,
4736
- Ie as Objects3DManager,
4737
- W as ParticleEmitter,
4738
- J as ParticlePhysics,
4739
- z as ParticleScript,
4740
- A as ParticleSystem,
4741
- Me as ParticleSystemManager,
4742
- K as ParticleTextureManager,
4743
- q as blurShader,
4744
- Z as compositeShader,
4745
- Te as createBindGroupLayouts,
4746
- Ee as createBindGroups,
4747
- C as createBuffer,
4748
- xe as createCubeGeometry,
4749
- Be as createDepthTexture,
4750
- Fe as createLookAtMatrix,
4751
- De as createProjectionMatrix,
4752
- Ce as createRenderPipelines,
4753
- we as createRenderTextures,
4754
- Ae as createSampler,
4755
- ve as createSphereGeometry,
4756
- $ as directRenderShader,
4757
- ue as extractGLBTexture,
4758
- Oe as fetchPreset,
4759
- Se as glbMeshParticleShader,
4760
- Ue as hexToRgb,
4761
- Re as initWebGPU,
4762
- Le as loadScene,
4763
- Ge as multiplyMatrices,
4764
- be as object3dShader,
4765
- X as parseGLB,
4766
- ye as particlePhysicsShader,
4767
- Y as particleShader,
4768
- ze as rgbToHex,
4769
- Ve as saveScene
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
  };