@voluma/vlam 0.2.1 → 0.2.3

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,14 +1,14 @@
1
1
  var dt = Object.defineProperty;
2
- var wt = (e, t, n) => t in e ? dt(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
3
- var A = (e, t, n) => wt(e, typeof t != "symbol" ? t + "" : t, n);
4
- import { w as gt } from "../splat-data-BZM5dhhx.js";
2
+ var gt = (e, t, n) => t in e ? dt(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
3
+ var A = (e, t, n) => gt(e, typeof t != "symbol" ? t + "" : t, n);
4
+ import { w as wt } from "../splat-data-BZM5dhhx.js";
5
5
  import { a as mt, r as pt } from "../sh-pack-D5wAe5gg.js";
6
6
  import * as E from "three/webgpu";
7
- import { M as Ct, L as yt } from "../splat-mesh-types-8QDjTbZO.js";
8
- import { t as ct, a as Q } from "../loading-wLo8vRbA.js";
9
- import { w as D } from "../logging-BfPdd7NJ.js";
10
- import { p as vt, a as xt, b as bt, c as k, d as W } from "../ply-header-BwgExCn-.js";
11
- const U = 32, O = 64, j = 1 << 24;
7
+ import { M as Ct, L as yt } from "../splat-mesh-types-CTN_duw2.js";
8
+ import { t as ct, a as W } from "../loading-wLo8vRbA.js";
9
+ import { w as z } from "../logging-BfPdd7NJ.js";
10
+ import { p as xt, a as vt, b as bt, c as k, d as j } from "../ply-header-BwgExCn-.js";
11
+ const F = 32, O = 64, K = 1 << 24;
12
12
  function Lt(e) {
13
13
  return e === 1 ? 3 : e === 2 ? 8 : 15;
14
14
  }
@@ -24,56 +24,56 @@ function Et(e) {
24
24
  const s = t.totalLevel;
25
25
  if (!Number.isSafeInteger(s) || s < 1)
26
26
  throw new Error(`LCC manifest declares an invalid totalLevel: ${String(s)}.`);
27
- const i = s, r = t.indexDataSize, c = 4 + i * 16;
28
- if (r !== c)
27
+ const i = s, l = t.indexDataSize, c = 4 + i * 16;
28
+ if (l !== c)
29
29
  throw new Error(
30
- `LCC manifest indexDataSize is ${String(r)}, but ${i} levels imply ${c}.`
30
+ `LCC manifest indexDataSize is ${String(l)}, but ${i} levels imply ${c}.`
31
31
  );
32
- const u = t.splats;
33
- if (!Array.isArray(u) || u.length !== i)
32
+ const a = t.splats;
33
+ if (!Array.isArray(a) || a.length !== i)
34
34
  throw new Error(`LCC manifest "splats" must list one count per level (${i}).`);
35
- for (const w of u)
36
- if (!Number.isSafeInteger(w) || w < 0)
37
- throw new Error(`LCC manifest "splats" contains an invalid count: ${String(w)}.`);
38
- const l = t.totalSplats;
39
- if (!Number.isSafeInteger(l) || l < 0)
40
- throw new Error(`LCC manifest declares an invalid totalSplats: ${String(l)}.`);
41
- const a = Z(t, "cellLengthX"), f = Z(t, "cellLengthY");
42
- if (a <= 0 || f <= 0)
35
+ for (const g of a)
36
+ if (!Number.isSafeInteger(g) || g < 0)
37
+ throw new Error(`LCC manifest "splats" contains an invalid count: ${String(g)}.`);
38
+ const r = t.totalSplats;
39
+ if (!Number.isSafeInteger(r) || r < 0)
40
+ throw new Error(`LCC manifest declares an invalid totalSplats: ${String(r)}.`);
41
+ const u = J(t, "cellLengthX"), f = J(t, "cellLengthY");
42
+ if (u <= 0 || f <= 0)
43
43
  throw new Error("LCC manifest cell lengths must be positive.");
44
44
  const h = St(t), d = t.shift;
45
- if (Array.isArray(d) && d.some((w) => w !== 0))
45
+ if (Array.isArray(d) && d.some((g) => g !== 0))
46
46
  throw new Error(
47
47
  `LCC manifest "shift" is non-zero (${JSON.stringify(d)}), which is not supported.`
48
48
  );
49
49
  const m = t.scale;
50
- if (Array.isArray(m) && m.some((w) => w !== 1))
50
+ if (Array.isArray(m) && m.some((g) => g !== 1))
51
51
  throw new Error(
52
52
  `LCC manifest "scale" is non-identity (${JSON.stringify(m)}), which is not supported.`
53
53
  );
54
- const p = t.boundingBox, $ = N(p == null ? void 0 : p.min, "boundingBox.min"), b = N(p == null ? void 0 : p.max, "boundingBox.max"), g = t.attributes;
55
- if (!Array.isArray(g)) throw new Error('LCC manifest is missing "attributes".');
54
+ const p = t.boundingBox, $ = P(p == null ? void 0 : p.min, "boundingBox.min"), b = P(p == null ? void 0 : p.max, "boundingBox.max"), w = t.attributes;
55
+ if (!Array.isArray(w)) throw new Error('LCC manifest is missing "attributes".');
56
56
  const C = /* @__PURE__ */ new Map();
57
- for (const w of g)
58
- typeof (w == null ? void 0 : w.name) == "string" && (!Array.isArray(w.min) || w.min.length < 3 || C.set(w.name, {
59
- min: N(w.min, `attributes.${w.name}.min`),
60
- max: N(w.max, `attributes.${w.name}.max`)
57
+ for (const g of w)
58
+ typeof (g == null ? void 0 : g.name) == "string" && (!Array.isArray(g.min) || g.min.length < 3 || C.set(g.name, {
59
+ min: P(g.min, `attributes.${g.name}.min`),
60
+ max: P(g.max, `attributes.${g.name}.max`)
61
61
  }));
62
- const x = (w) => {
63
- const v = C.get(w);
64
- if (!v) throw new Error(`LCC manifest is missing the "${w}" attribute range.`);
65
- return v;
62
+ const v = (g) => {
63
+ const x = C.get(g);
64
+ if (!x) throw new Error(`LCC manifest is missing the "${g}" attribute range.`);
65
+ return x;
66
66
  }, y = C.get("shcoef") ?? Y, L = $t(t.fileType, y);
67
67
  return {
68
- totalSplats: l,
68
+ totalSplats: r,
69
69
  totalLevel: i,
70
- cellLengthX: a,
70
+ cellLengthX: u,
71
71
  cellLengthY: f,
72
72
  indexDataSize: c,
73
- splats: u,
73
+ splats: a,
74
74
  bounds: { min: $, max: b },
75
75
  fileType: L,
76
- scale: x("scale"),
76
+ scale: v("scale"),
77
77
  // A Portable capture has no SH at all; keep a benign range so the type
78
78
  // stays total rather than sprinkling optionality through the loader.
79
79
  shcoef: y,
@@ -87,7 +87,7 @@ function St(e) {
87
87
  if (!Array.isArray(t) || !t.some((o) => o !== 0)) return;
88
88
  const n = e.epsg;
89
89
  return {
90
- origin: N(t, "offset"),
90
+ origin: P(t, "offset"),
91
91
  epsg: Number.isSafeInteger(n) && n > 0 ? n : void 0
92
92
  };
93
93
  }
@@ -109,95 +109,95 @@ function Mt(e, t) {
109
109
  `LCC index.bin is ${e.byteLength} bytes, not a multiple of indexDataSize ${n}.`
110
110
  );
111
111
  const s = new DataView(e), i = [];
112
- for (let r = 0; r < e.byteLength; r += n) {
112
+ for (let l = 0; l < e.byteLength; l += n) {
113
113
  const c = [];
114
- for (let u = 0; u < o; u++) {
115
- const l = r + 4 + u * 16, a = s.getUint32(l, !0), f = s.getBigUint64(l + 4, !0);
114
+ for (let a = 0; a < o; a++) {
115
+ const r = l + 4 + a * 16, u = s.getUint32(r, !0), f = s.getBigUint64(r + 4, !0);
116
116
  if (f > BigInt(Number.MAX_SAFE_INTEGER))
117
117
  throw new Error(
118
118
  `LCC index.bin has a byte offset beyond Number.MAX_SAFE_INTEGER: ${f}.`
119
119
  );
120
- const h = s.getUint32(l + 12, !0);
121
- if (h !== a * U)
120
+ const h = s.getUint32(r + 12, !0);
121
+ if (h !== u * F)
122
122
  throw new Error(
123
- `LCC index.bin level ${u} declares ${a} splats but ${h} bytes (expected ${a * U}).`
123
+ `LCC index.bin level ${a} declares ${u} splats but ${h} bytes (expected ${u * F}).`
124
124
  );
125
- c.push({ count: a, byteOffset: Number(f), byteSize: h });
125
+ c.push({ count: u, byteOffset: Number(f), byteSize: h });
126
126
  }
127
127
  i.push({
128
- cellX: s.getUint16(r, !0),
129
- cellY: s.getUint16(r + 2, !0),
128
+ cellX: s.getUint16(l, !0),
129
+ cellY: s.getUint16(l + 2, !0),
130
130
  levels: c
131
131
  });
132
132
  }
133
133
  return i;
134
134
  }
135
- function Ut(e) {
135
+ function Ft(e) {
136
136
  const t = e >>> 30 & 3, n = [0, 0, 0, 0];
137
137
  let o = 0;
138
138
  for (let i = 0; i < 4; i++) {
139
139
  if (i === t) continue;
140
- const r = e >>> 10 * o & 1023;
141
- n[i] = (r - 511) * Tt, o++;
140
+ const l = e >>> 10 * o & 1023;
141
+ n[i] = (l - 511) * Tt, o++;
142
142
  }
143
143
  const s = n[0] ** 2 + n[1] ** 2 + n[2] ** 2 + n[3] ** 2;
144
144
  return n[t] = Math.sqrt(Math.max(0, 1 - s)), [n[3], n[0], n[1], n[2]];
145
145
  }
146
146
  const Tt = 1 / (511 * Math.SQRT2);
147
147
  async function re(e, t, n, o) {
148
- var x;
148
+ var v;
149
149
  const s = t.stride;
150
- if (s !== U && s !== U + O)
150
+ if (s !== F && s !== F + O)
151
151
  throw new Error(`LCC chunk declares an unsupported ${s}-byte record.`);
152
- if (((x = t.sh) == null ? void 0 : x.source) === "inline" && s === U)
152
+ if (((v = t.sh) == null ? void 0 : v.source) === "inline" && s === F)
153
153
  throw new Error("LCC chunk asks for inline SH but its records have no room for it.");
154
154
  if (e.byteLength % s !== 0)
155
155
  throw new Error(
156
156
  `LCC chunk is ${e.byteLength} bytes, not a multiple of the ${s}-byte record.`
157
157
  );
158
158
  const i = e.byteLength / s;
159
- if (i > j)
159
+ if (i > K)
160
160
  throw new Error(
161
- `LCC chunk holds ${i} splats, above the supported maximum of ${j}.`
161
+ `LCC chunk holds ${i} splats, above the supported maximum of ${K}.`
162
162
  );
163
- const r = new DataView(e), c = new Float32Array(i * 3), u = new Uint8Array(i * 4), l = new Float32Array(i * 6), a = new Uint8Array(e), { min: f, max: h } = t.scale, d = f[0], m = f[1], p = f[2], $ = h[0] - f[0], b = h[1] - f[1], g = h[2] - f[2];
163
+ const l = new DataView(e), c = new Float32Array(i * 3), a = new Uint8Array(i * 4), r = new Float32Array(i * 6), u = new Uint8Array(e), { min: f, max: h } = t.scale, d = f[0], m = f[1], p = f[2], $ = h[0] - f[0], b = h[1] - f[1], w = h[2] - f[2];
164
164
  for (let y = 0; y < i; y++) {
165
165
  o && (y & 65535) === 0 && y > 0 && (await new Promise((S) => setTimeout(S, 0)), o.throwIfAborted());
166
166
  const L = y * s;
167
- c[y * 3 + 0] = r.getFloat32(L, !0), c[y * 3 + 1] = r.getFloat32(L + 4, !0), c[y * 3 + 2] = r.getFloat32(L + 8, !0), u[y * 4 + 0] = a[L + 12], u[y * 4 + 1] = a[L + 13], u[y * 4 + 2] = a[L + 14], u[y * 4 + 3] = a[L + 15];
168
- const [w, v, F, M] = Ut(r.getUint32(L + 22, !0));
169
- gt(
170
- l,
167
+ c[y * 3 + 0] = l.getFloat32(L, !0), c[y * 3 + 1] = l.getFloat32(L + 4, !0), c[y * 3 + 2] = l.getFloat32(L + 8, !0), a[y * 4 + 0] = u[L + 12], a[y * 4 + 1] = u[L + 13], a[y * 4 + 2] = u[L + 14], a[y * 4 + 3] = u[L + 15];
168
+ const [g, x, U, M] = Ft(l.getUint32(L + 22, !0));
169
+ wt(
170
+ r,
171
171
  y,
172
- d + $ * (r.getUint16(L + 16, !0) / 65535),
173
- m + b * (r.getUint16(L + 18, !0) / 65535),
174
- p + g * (r.getUint16(L + 20, !0) / 65535),
175
- w,
176
- v,
177
- F,
172
+ d + $ * (l.getUint16(L + 16, !0) / 65535),
173
+ m + b * (l.getUint16(L + 18, !0) / 65535),
174
+ p + w * (l.getUint16(L + 20, !0) / 65535),
175
+ g,
176
+ x,
177
+ U,
178
178
  M
179
179
  );
180
180
  }
181
181
  o == null || o.throwIfAborted();
182
- const C = t.sh ? Ft(e, n, t.sh, i, s) : void 0;
182
+ const C = t.sh ? Ut(e, n, t.sh, i, s) : void 0;
183
183
  return {
184
184
  count: i,
185
185
  positions: c,
186
- colors: u,
187
- covariances: l,
186
+ colors: a,
187
+ covariances: r,
188
188
  ...C ? { shPacked: C } : {}
189
189
  };
190
190
  }
191
- function Ft(e, t, n, o, s) {
192
- const i = Lt(n.bands), r = new Uint32Array(o * i);
191
+ function Ut(e, t, n, o, s) {
192
+ const i = Lt(n.bands), l = new Uint32Array(o * i);
193
193
  if (n.source === "inline") {
194
- const l = new DataView(e);
195
- for (let a = 0; a < o; a++) {
196
- const f = a * s + U;
194
+ const r = new DataView(e);
195
+ for (let u = 0; u < o; u++) {
196
+ const f = u * s + F;
197
197
  for (let h = 0; h < i; h++)
198
- r[a * i + h] = l.getUint32(f + h * 4, !0);
198
+ l[u * i + h] = r.getUint32(f + h * 4, !0);
199
199
  }
200
- return K(r, n);
200
+ return Z(l, n);
201
201
  }
202
202
  if (!t) throw new Error("LCC chunk expected shcoef.bin bytes but none were fetched.");
203
203
  const c = o * O;
@@ -205,15 +205,15 @@ function Ft(e, t, n, o, s) {
205
205
  throw new Error(
206
206
  `LCC shcoef.bin range is ${t.byteLength} bytes; expected ${c} for ${o} splats.`
207
207
  );
208
- const u = new DataView(t);
209
- for (let l = 0; l < o; l++) {
210
- const a = l * O;
208
+ const a = new DataView(t);
209
+ for (let r = 0; r < o; r++) {
210
+ const u = r * O;
211
211
  for (let f = 0; f < i; f++)
212
- r[l * i + f] = u.getUint32(a + f * 4, !0);
212
+ l[r * i + f] = a.getUint32(u + f * 4, !0);
213
213
  }
214
- return K(r, n);
214
+ return Z(l, n);
215
215
  }
216
- function K(e, t) {
216
+ function Z(e, t) {
217
217
  const n = t.requantizeTo;
218
218
  if (!n || mt(t.range, n))
219
219
  return { bands: t.bands, packed: e, range: t.range };
@@ -221,13 +221,13 @@ function K(e, t) {
221
221
  e[o] = pt(e[o], t.range, n);
222
222
  return { bands: t.bands, packed: e, range: n };
223
223
  }
224
- function Z(e, t) {
224
+ function J(e, t) {
225
225
  const n = e[t];
226
226
  if (typeof n != "number" || !Number.isFinite(n))
227
227
  throw new Error(`LCC manifest field "${t}" is not a finite number.`);
228
228
  return n;
229
229
  }
230
- function N(e, t) {
230
+ function P(e, t) {
231
231
  if (!Array.isArray(e) || e.length < 3)
232
232
  throw new Error(`LCC manifest "${t}" must have three numbers.`);
233
233
  return e.slice(0, 3).map((o) => {
@@ -236,54 +236,54 @@ function N(e, t) {
236
236
  return o;
237
237
  });
238
238
  }
239
- function q() {
239
+ function H() {
240
240
  return new E.Matrix4().set(-1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1);
241
241
  }
242
242
  function le(e) {
243
- e.matrix.copy(q()), e.matrix.decompose(e.position, e.quaternion, e.scale), e.matrixWorldNeedsUpdate = !0;
243
+ e.matrix.copy(H()), e.matrix.decompose(e.position, e.quaternion, e.scale), e.matrixWorldNeedsUpdate = !0;
244
244
  }
245
245
  const Bt = 128e3;
246
246
  async function ce(e, t, n) {
247
- const o = Et(e), s = (w) => {
248
- const v = t.resolve(w);
249
- if (v === null) throw new Error(`LCC dataset is missing "${w}".`);
250
- return v;
251
- }, i = s("data.bin"), r = t.resolve("environment.bin"), c = Mt(
252
- await It(s("index.bin"), n, "manifest"),
247
+ const o = Et(e), s = (g) => {
248
+ const x = t.resolve(g);
249
+ if (x === null) throw new Error(`LCC dataset is missing "${g}".`);
250
+ return x;
251
+ }, i = s("data.bin"), l = t.resolve("environment.bin"), c = Mt(
252
+ await _t(s("index.bin"), n, "manifest"),
253
253
  o
254
254
  );
255
- Nt(c, o);
256
- const u = o.fileType === "Quality" ? Ct : 0, l = n.shBands ?? u, a = Math.min(l, u), f = a === 0 ? void 0 : a, h = f === void 0 ? null : s("shcoef.bin"), d = [], m = [], p = (w, v) => (d.push(w), m.push(v), d.length - 1), $ = [], b = /* @__PURE__ */ new Set();
257
- let g = 0;
255
+ Pt(c, o);
256
+ const a = o.fileType === "Quality" ? Ct : 0, r = n.shBands ?? a, u = Math.min(r, a), f = u === 0 ? void 0 : u, h = f === void 0 ? null : s("shcoef.bin"), d = [], m = [], p = (g, x) => (d.push(g), m.push(x), d.length - 1), $ = [], b = /* @__PURE__ */ new Set();
257
+ let w = 0;
258
258
  const C = o.totalLevel;
259
- for (let w = 0; w < c.length; w++) {
260
- const v = c[w];
261
- let F = 0;
259
+ for (let g = 0; g < c.length; g++) {
260
+ const x = c[g];
261
+ let U = 0;
262
262
  for (let S = 0; S < C; S++) {
263
- const T = v.levels[S].count;
263
+ const T = x.levels[S].count;
264
264
  if (T > 0) {
265
- F = T;
265
+ U = T;
266
266
  break;
267
267
  }
268
268
  }
269
- const M = Math.max(1, Math.ceil(F / Bt));
269
+ const M = Math.max(1, Math.ceil(U / Bt));
270
270
  for (let S = 0; S < M; S++) {
271
271
  const T = new Array(C).fill(
272
272
  void 0
273
273
  );
274
- let B = -1, H = 0;
275
- for (let P = 0; P < C; P++) {
276
- const _ = v.levels[P];
277
- if (_.count === 0) continue;
278
- const R = Math.floor(S * _.count / M), I = Math.floor((S + 1) * _.count / M);
279
- if (I === R) continue;
280
- const ft = `${i}#c${v.cellX}_${v.cellY}-l${P}${M > 1 ? `.${S}` : ""}`, G = p(ft, {
274
+ let B = -1, G = 0;
275
+ for (let I = 0; I < C; I++) {
276
+ const R = x.levels[I];
277
+ if (R.count === 0) continue;
278
+ const N = Math.floor(S * R.count / M), _ = Math.floor((S + 1) * R.count / M);
279
+ if (_ === N) continue;
280
+ const ft = `${i}#c${x.cellX}_${x.cellY}-l${I}${M > 1 ? `.${S}` : ""}`, Q = p(ft, {
281
281
  format: "lcc-bin",
282
282
  lcc: {
283
283
  kind: "splats",
284
- start: _.byteOffset + R * U,
285
- length: (I - R) * U,
286
- stride: U,
284
+ start: R.byteOffset + N * F,
285
+ length: (_ - N) * F,
286
+ stride: F,
287
287
  scale: o.scale,
288
288
  ...f === void 0 ? {} : {
289
289
  sh: {
@@ -298,22 +298,22 @@ async function ce(e, t, n) {
298
298
  }
299
299
  }
300
300
  });
301
- T[P] = { file: G, offset: 0, count: I - R }, B = G, H = I - R;
301
+ T[I] = { file: Q, offset: 0, count: _ - N }, B = Q, G = _ - N;
302
302
  }
303
- B >= 0 && (b.add(B), g += H), $.push({ bounds: Rt(v, o), lods: T, budgetGroup: w });
303
+ B >= 0 && (b.add(B), w += G), $.push({ bounds: Nt(x, o), lods: T, budgetGroup: g });
304
304
  }
305
305
  }
306
- const x = await _t(t, o);
307
- if (x > 0 && r !== null) {
308
- const w = at(o), v = p(`${r}#env`, {
306
+ const v = await Rt(t, o);
307
+ if (v > 0 && l !== null) {
308
+ const g = at(o), x = p(`${l}#env`, {
309
309
  format: "lcc-bin",
310
310
  lcc: {
311
311
  kind: "environment",
312
312
  start: 0,
313
- length: x * w,
313
+ length: v * g,
314
314
  // From `fileType`, never from whether SH is enabled: a Quality
315
315
  // environment record is 96 bytes even when its SH is being skipped.
316
- stride: w,
316
+ stride: g,
317
317
  scale: o.envScale,
318
318
  ...f === void 0 ? {} : {
319
319
  sh: {
@@ -328,9 +328,9 @@ async function ce(e, t, n) {
328
328
  }
329
329
  }
330
330
  });
331
- b.add(v), g += x, $.push({
331
+ b.add(x), w += v, $.push({
332
332
  bounds: V(o),
333
- lods: [{ file: v, offset: 0, count: x }]
333
+ lods: [{ file: x, offset: 0, count: v }]
334
334
  });
335
335
  }
336
336
  const y = {
@@ -341,7 +341,7 @@ async function ce(e, t, n) {
341
341
  counts: o.splats.slice(0, C),
342
342
  lodLevels: C,
343
343
  bounds: V(o)
344
- }, L = await Pt(t);
344
+ }, L = await It(t);
345
345
  return {
346
346
  // Classic LCC cells are broad XY tiles. Keep their priority independent of
347
347
  // frustum crossings so an orbit does not demote a sharp tile as it leaves
@@ -373,19 +373,19 @@ async function ce(e, t, n) {
373
373
  bounds: V(o),
374
374
  pinnedFiles: b,
375
375
  // Worst case is every cell resident at its finest level, plus the sky.
376
- maxResidentSplats: (o.splats[0] ?? n.budget) + x,
376
+ maxResidentSplats: (o.splats[0] ?? n.budget) + v,
377
377
  // Full coarse coverage is each cell's coarsest level plus the sky - the
378
378
  // budget floor below which even the substitute levels cannot all fit.
379
- minimumCoverageSplats: Math.max(1, g),
379
+ minimumCoverageSplats: Math.max(1, w),
380
380
  // Same Z-up frame as .lcc2; bounds stay source-local and matrixWorld
381
381
  // handles the conversion.
382
- formatTransform: q(),
382
+ formatTransform: H(),
383
383
  // Optional classic-LCC collision mesh file. One descriptor for the whole
384
384
  // `.lci`; `loadCollisionMeshes` expands it into per-cell triangle tiles.
385
385
  ...L !== null ? { collision: { meshes: [{ url: L }] } } : {}
386
386
  };
387
387
  }
388
- async function Pt(e) {
388
+ async function It(e) {
389
389
  for (const t of ["collision.lci", "Collision.lci"]) {
390
390
  const n = await e.size(t);
391
391
  if (n !== null && Number.isSafeInteger(n) && n > 0)
@@ -394,9 +394,9 @@ async function Pt(e) {
394
394
  return null;
395
395
  }
396
396
  function at(e) {
397
- return e.fileType === "Quality" ? U + O : U;
397
+ return e.fileType === "Quality" ? F + O : F;
398
398
  }
399
- function Rt(e, t) {
399
+ function Nt(e, t) {
400
400
  const { min: n, max: o } = t.bounds, s = n[0] + e.cellX * t.cellLengthX, i = n[1] + e.cellY * t.cellLengthY;
401
401
  return new E.Box3(
402
402
  new E.Vector3(Math.min(s, o[0]), Math.min(i, o[1]), n[2]),
@@ -414,18 +414,18 @@ function V(e) {
414
414
  new E.Vector3(n[0], n[1], n[2])
415
415
  );
416
416
  }
417
- function Nt(e, t) {
417
+ function Pt(e, t) {
418
418
  for (let n = 0; n < t.totalLevel; n++) {
419
419
  let o = 0;
420
420
  for (const c of e) o += c.levels[n].count;
421
- const s = t.splats[n], i = s - o, r = Math.max(4, Math.ceil(s * 1e-3));
422
- if (i < 0 || i > r)
421
+ const s = t.splats[n], i = s - o, l = Math.max(4, Math.ceil(s * 1e-3));
422
+ if (i < 0 || i > l)
423
423
  throw new Error(
424
424
  `LCC index.bin level ${n} totals ${o} splats, but the manifest declares ${String(t.splats[n])}.`
425
425
  );
426
426
  }
427
427
  }
428
- async function _t(e, t) {
428
+ async function Rt(e, t) {
429
429
  const n = await e.size("environment.bin");
430
430
  if (n === null || !Number.isSafeInteger(n) || n <= 0) return 0;
431
431
  const o = at(t);
@@ -435,54 +435,54 @@ async function _t(e, t) {
435
435
  );
436
436
  return n / o;
437
437
  }
438
- async function It(e, t, n) {
438
+ async function _t(e, t, n) {
439
439
  let o;
440
440
  try {
441
441
  o = await fetch(e, ct(t.request, t.signal));
442
442
  } catch (s) {
443
- throw Q(s, { phase: n, url: e });
443
+ throw W(s, { phase: n, url: e });
444
444
  }
445
445
  if (!o.ok)
446
- throw Q(new Error(`Failed to load ${e}: HTTP ${o.status}`), {
446
+ throw W(new Error(`Failed to load ${e}: HTTP ${o.status}`), {
447
447
  phase: n,
448
448
  url: e,
449
449
  status: o.status
450
450
  });
451
451
  return o.arrayBuffer();
452
452
  }
453
- const zt = 3, Dt = 0.1, J = 0.1, Ot = 500;
453
+ const Dt = 3, zt = 0.1, tt = 0.1, Ot = 500;
454
454
  function ae(e, t, n, o = 0) {
455
455
  var $, b;
456
- const s = e, i = s.root.splatFiles.map((g) => {
457
- const C = t.resolve(g);
458
- if (C === null) throw new Error(`LCC2 dataset is missing the tile "${g}".`);
456
+ const s = e, i = s.root.splatFiles.map((w) => {
457
+ const C = t.resolve(w);
458
+ if (C === null) throw new Error(`LCC2 dataset is missing the tile "${w}".`);
459
459
  return C;
460
- }), r = [], c = [];
461
- let u = 0;
462
- const l = (g, C) => {
460
+ }), l = [], c = [];
461
+ let a = 0;
462
+ const r = (w, C) => {
463
463
  var M;
464
- const x = (M = g.data) == null ? void 0 : M["3dgs"];
465
- if (!x) throw new Error("LCC2 node is missing 3dgs data.");
466
- const y = r.length;
467
- r.push(null);
468
- const L = u, w = [], v = g.child ? Object.values(g.child) : [];
469
- if (v.length === 0)
470
- c[u] = y, u++;
464
+ const v = (M = w.data) == null ? void 0 : M["3dgs"];
465
+ if (!v) throw new Error("LCC2 node is missing 3dgs data.");
466
+ const y = l.length;
467
+ l.push(null);
468
+ const L = a, g = [], x = w.child ? Object.values(w.child) : [];
469
+ if (x.length === 0)
470
+ c[a] = y, a++;
471
471
  else
472
- for (const S of v) w.push(l(S, C + 1));
473
- const F = v.length === 0 ? L + 1 : u;
474
- return r[y] = {
475
- file: x.name,
476
- offset: x.start,
477
- count: x.count,
478
- bounds: X(g.boundingBox),
472
+ for (const S of x) g.push(r(S, C + 1));
473
+ const U = x.length === 0 ? L + 1 : a;
474
+ return l[y] = {
475
+ file: v.name,
476
+ offset: v.start,
477
+ count: v.count,
478
+ bounds: q(w.boundingBox),
479
479
  level: s.totalLevels - C,
480
- children: w,
480
+ children: g,
481
481
  leafStart: L,
482
- leafEnd: F
482
+ leafEnd: U
483
483
  }, y;
484
- }, a = Object.values(s.root.child ?? {}).map((g) => l(g, 1)), f = new Yt(r, a, c, s.totalLevels - 1, n), h = new Set(a.map((g) => r[g].file)), d = (b = ($ = s.root.data) == null ? void 0 : $.env) == null ? void 0 : b.name, m = d !== void 0 && i[d] !== void 0 ? { file: d } : void 0;
485
- d !== void 0 && m === void 0 && D(`LCC2 root references env tile #${d}, which the manifest does not list.`), m && h.add(m.file);
484
+ }, u = Object.values(s.root.child ?? {}).map((w) => r(w, 1)), f = new Yt(l, u, c, s.totalLevels - 1, n), h = new Set(u.map((w) => l[w].file)), d = (b = ($ = s.root.data) == null ? void 0 : $.env) == null ? void 0 : b.name, m = d !== void 0 && i[d] !== void 0 ? { file: d } : void 0;
485
+ d !== void 0 && m === void 0 && z(`LCC2 root references env tile #${d}, which the manifest does not list.`), m && h.add(m.file);
486
486
  const p = o >= 1 ? o : void 0;
487
487
  return {
488
488
  source: f,
@@ -495,46 +495,46 @@ function ae(e, t, n, o = 0) {
495
495
  format: "sog",
496
496
  ...p ? { sog: { packShBands: p } } : {}
497
497
  })),
498
- bounds: X(s.root.boundingBox),
498
+ bounds: q(s.root.boundingBox),
499
499
  pinnedFiles: h,
500
500
  maxResidentSplats: s.lodSplats[0] ?? n.budget,
501
501
  minimumCoverageSplats: Math.max(
502
502
  1,
503
- a.reduce((g, C) => g + r[C].count, 0)
503
+ u.reduce((w, C) => w + l[C].count, 0)
504
504
  ),
505
505
  ...kt(s, t),
506
506
  ...m ? { environment: m } : {},
507
507
  ...p ? { shBands: p } : {},
508
508
  // Match the established XGRIDS LCC and Spark viewer coordinate frame.
509
509
  // Bounds remain source-local and matrixWorld handles the conversion.
510
- formatTransform: q()
510
+ formatTransform: H()
511
511
  };
512
512
  }
513
513
  function kt(e, t) {
514
514
  const n = e.root.meshFiles;
515
515
  if (!n || n.length === 0) return {};
516
516
  const o = /* @__PURE__ */ new Map(), s = (c) => {
517
- var l;
518
- const u = (l = c.data) == null ? void 0 : l.mesh;
519
- u && !o.has(u.name) && o.set(u.name, X(c.boundingBox));
520
- for (const a of Object.values(c.child ?? {})) s(a);
517
+ var r;
518
+ const a = (r = c.data) == null ? void 0 : r.mesh;
519
+ a && !o.has(a.name) && o.set(a.name, q(c.boundingBox));
520
+ for (const u of Object.values(c.child ?? {})) s(u);
521
521
  };
522
522
  s(e.root);
523
- const i = o.size > 0 ? [...o].map(([c, u]) => ({ file: c, bounds: u })) : n.map((c, u) => ({ file: u })), r = [];
524
- for (const { file: c, bounds: u } of i) {
525
- const l = n[c];
526
- if (l === void 0) {
527
- D(`LCC2 node references mesh file ${c}, which the manifest does not list.`);
523
+ const i = o.size > 0 ? [...o].map(([c, a]) => ({ file: c, bounds: a })) : n.map((c, a) => ({ file: a })), l = [];
524
+ for (const { file: c, bounds: a } of i) {
525
+ const r = n[c];
526
+ if (r === void 0) {
527
+ z(`LCC2 node references mesh file ${c}, which the manifest does not list.`);
528
528
  continue;
529
529
  }
530
- const a = t.resolve(l);
531
- if (a === null) {
532
- D(`LCC2 dataset is missing the collision mesh "${l}"; skipping it.`);
530
+ const u = t.resolve(r);
531
+ if (u === null) {
532
+ z(`LCC2 dataset is missing the collision mesh "${r}"; skipping it.`);
533
533
  continue;
534
534
  }
535
- r.push({ url: a, ...u ? { bounds: u } : {} });
535
+ l.push({ url: u, ...a ? { bounds: a } : {} });
536
536
  }
537
- return r.length > 0 ? { collision: { meshes: r } } : {};
537
+ return l.length > 0 ? { collision: { meshes: l } } : {};
538
538
  }
539
539
  class Yt {
540
540
  constructor(t, n, o, s, i) {
@@ -556,69 +556,97 @@ class Yt {
556
556
  A(this, "scratchBox", new E.Box3());
557
557
  A(this, "scratchSize", new E.Vector3());
558
558
  this.nodes = t, this.rootChildren = n, this.cellNodes = o, this.coarsest = s, this.budget = i.budget, this.lodBaseDistance = i.lodBaseDistance, this.lodMultiplier = i.lodMultiplier;
559
- const r = o.length;
560
- this.cellFinestLevel = new Int32Array(r), this.cellLevel = new Int32Array(r).fill(s), this.changedAt = new Float64Array(r);
561
- for (let c = 0; c < r; c++)
559
+ const l = o.length;
560
+ this.cellFinestLevel = new Int32Array(l), this.cellLevel = new Int32Array(l).fill(s), this.changedAt = new Float64Array(l);
561
+ for (let c = 0; c < l; c++)
562
562
  this.cellFinestLevel[c] = t[o[c]].level;
563
- this.cellRootChild = new Uint32Array(r), n.forEach((c, u) => {
564
- const l = t[c];
565
- for (let a = l.leafStart; a < l.leafEnd; a++) this.cellRootChild[a] = u;
563
+ this.cellRootChild = new Uint32Array(l), n.forEach((c, a) => {
564
+ const r = t[c];
565
+ for (let u = r.leafStart; u < r.leafEnd; u++) this.cellRootChild[u] = a;
566
566
  });
567
567
  }
568
568
  computeDesiredRuns(t, n, o) {
569
- const s = this.updateCellLevels(t, n, o), i = Int32Array.from(this.cellLevel), r = this.rootChildren.map((h) => this.subtreeCutTotal(h, i));
570
- let c = r.reduce((h, d) => h + d, 0);
571
- const u = (h, d) => {
569
+ const s = this.updateCellLevels(t, n, o), i = Int32Array.from(this.cellLevel), l = this.rootChildren.map((h) => this.subtreeCutTotal(h, i));
570
+ let c = l.reduce((h, d) => h + d, 0);
571
+ const a = (h, d) => {
572
572
  i[h] = i[h] + d;
573
573
  const m = this.cellRootChild[h], p = this.subtreeCutTotal(this.rootChildren[m], i);
574
- c += p - r[m], r[m] = p;
575
- }, l = [...this.cellNodes.keys()].sort(
574
+ c += p - l[m], l[m] = p;
575
+ }, r = [...this.cellNodes.keys()].sort(
576
576
  (h, d) => s[d] - s[h]
577
577
  );
578
- for (let h = 0; h < l.length && c > this.budget; ) {
579
- const d = l[h];
580
- i[d] < this.coarsest ? u(d, 1) : h++;
578
+ for (let h = 0; h < r.length && c > this.budget; ) {
579
+ const d = r[h];
580
+ i[d] < this.coarsest ? a(d, 1) : h++;
581
581
  }
582
- const a = this.budget * 0.85;
583
- for (let h = l.length - 1; h >= 0 && c < a; ) {
584
- const d = l[h];
582
+ const u = this.budget * 0.85;
583
+ for (let h = r.length - 1; h >= 0 && c < u; ) {
584
+ const d = r[h];
585
585
  if (i[d] > this.cellFinestLevel[d]) {
586
- if (u(d, -1), c > this.budget) {
587
- u(d, 1);
586
+ if (a(d, -1), c > this.budget) {
587
+ a(d, 1);
588
588
  break;
589
589
  }
590
590
  } else
591
591
  h--;
592
592
  }
593
593
  const f = [];
594
- return this.collectCut(i, (h) => f.push(tt(this.nodes[h]))), f;
594
+ return this.collectCut(i, (h) => f.push(X(this.nodes[h]))), f;
595
595
  }
596
596
  coarsestRunsFor(t, n) {
597
597
  const o = [];
598
598
  for (const s of this.rootChildren) {
599
599
  const i = this.nodes[s];
600
- i.leafStart < n && i.leafEnd > t && o.push(tt(i));
600
+ i.leafStart < n && i.leafEnd > t && o.push(X(i));
601
601
  }
602
602
  return o;
603
603
  }
604
+ /**
605
+ * Coarsest root-child runs covering in-view finest cells. An empty frustum
606
+ * falls back to the nearest cell's root child so a skyward start still paints
607
+ * something rather than releasing an empty hold.
608
+ */
609
+ coverageRunsFor(t, n) {
610
+ const o = this.cellNodes.length;
611
+ if (o === 0) return [];
612
+ const s = new Uint8Array(this.rootChildren.length);
613
+ let i = !1, l = 0, c = Number.POSITIVE_INFINITY;
614
+ for (let r = 0; r < o; r++) {
615
+ const f = this.nodes[this.cellNodes[r]].bounds.distanceToPoint(t);
616
+ f < c && (c = f, l = r), this.cellIntersectsFrustum(n, r) && (s[this.cellRootChild[r]] = 1, i = !0);
617
+ }
618
+ i || (s[this.cellRootChild[l]] = 1);
619
+ const a = [];
620
+ for (let r = 0; r < this.rootChildren.length; r++)
621
+ s[r] === 1 && a.push(X(this.nodes[this.rootChildren[r]]));
622
+ return a;
623
+ }
624
+ /** Finest-cell AABB expanded by {@link FRUSTUM_MARGIN}, written into scratch. */
625
+ expandCellBox(t) {
626
+ const n = this.nodes[this.cellNodes[t]];
627
+ return this.scratchBox.copy(n.bounds), n.bounds.getSize(this.scratchSize), this.scratchBox.expandByScalar(this.scratchSize.length() * zt), this.scratchBox;
628
+ }
629
+ cellIntersectsFrustum(t, n) {
630
+ return t.intersectsBox(this.expandCellBox(n));
631
+ }
604
632
  /** Distance (frustum-penalized) to each finest cell's node bounds. */
605
633
  cellDistanceOf(t, n, o) {
606
- const s = this.nodes[this.cellNodes[o]], i = s.bounds.distanceToPoint(t);
607
- return this.scratchBox.copy(s.bounds), s.bounds.getSize(this.scratchSize), this.scratchBox.expandByScalar(this.scratchSize.length() * Dt), n.intersectsBox(this.scratchBox) ? i : i * zt;
634
+ const i = this.nodes[this.cellNodes[o]].bounds.distanceToPoint(t);
635
+ return this.cellIntersectsFrustum(n, o) ? i : i * Dt;
608
636
  }
609
637
  /** Advances each cell's dwelled level toward the distance target. */
610
638
  updateCellLevels(t, n, o) {
611
- const { lodBaseDistance: s, lodMultiplier: i } = this, r = new Float64Array(this.cellNodes.length);
639
+ const { lodBaseDistance: s, lodMultiplier: i } = this, l = new Float64Array(this.cellNodes.length);
612
640
  for (let c = 0; c < this.cellNodes.length; c++) {
613
- const u = this.cellDistanceOf(t, n, c);
614
- r[c] = u;
615
- const l = this.cellFinestLevel[c];
616
- let a = Math.min(this.coarsest, Math.max(l, this.cellLevel[c]));
617
- for (; a < this.coarsest && u > s * i ** a * (1 + J); ) a++;
618
- for (; a > l && u <= s * i ** (a - 1) * (1 - J); ) a--;
619
- a !== this.cellLevel[c] && o - this.changedAt[c] >= Ot && (this.cellLevel[c] = a, this.changedAt[c] = o);
641
+ const a = this.cellDistanceOf(t, n, c);
642
+ l[c] = a;
643
+ const r = this.cellFinestLevel[c];
644
+ let u = Math.min(this.coarsest, Math.max(r, this.cellLevel[c]));
645
+ for (; u < this.coarsest && a > s * i ** u * (1 + tt); ) u++;
646
+ for (; u > r && a <= s * i ** (u - 1) * (1 - tt); ) u--;
647
+ u !== this.cellLevel[c] && o - this.changedAt[c] >= Ot && (this.cellLevel[c] = u, this.changedAt[c] = o);
620
648
  }
621
- return r;
649
+ return l;
622
650
  }
623
651
  /** Splat total of one subtree's cut for the given per-cell levels. */
624
652
  subtreeCutTotal(t, n) {
@@ -641,19 +669,19 @@ class Yt {
641
669
  const s = this.nodes[t];
642
670
  if (s.children.length > 0) {
643
671
  let i = this.coarsest;
644
- for (let r = s.leafStart; r < s.leafEnd; r++) {
645
- const c = n[r];
672
+ for (let l = s.leafStart; l < s.leafEnd; l++) {
673
+ const c = n[l];
646
674
  c < i && (i = c);
647
675
  }
648
676
  if (i < s.level) {
649
- for (const r of s.children) this.visitCut(r, n, o);
677
+ for (const l of s.children) this.visitCut(l, n, o);
650
678
  return;
651
679
  }
652
680
  }
653
681
  o(t);
654
682
  }
655
683
  }
656
- function tt(e) {
684
+ function X(e) {
657
685
  return {
658
686
  file: e.file,
659
687
  level: e.level,
@@ -663,7 +691,7 @@ function tt(e) {
663
691
  leafEnd: e.leafEnd
664
692
  };
665
693
  }
666
- function X(e) {
694
+ function q(e) {
667
695
  return new E.Box3(
668
696
  new E.Vector3(e.min[0], e.min[1], e.min[2]),
669
697
  new E.Vector3(e.max[0], e.max[1], e.max[2])
@@ -671,9 +699,9 @@ function X(e) {
671
699
  }
672
700
  const et = ["vertex_indices", "vertex_index"];
673
701
  function Vt(e) {
674
- const t = vt(e), n = t.element("vertex");
702
+ const t = xt(e), n = t.element("vertex");
675
703
  if (!n) throw new Error('Not a mesh PLY: no "vertex" element.');
676
- xt(n, ["x", "y", "z"], ["float", "float32"], "Mesh PLY vertex"), bt(n, e.byteLength);
704
+ vt(n, ["x", "y", "z"], ["float", "float32"], "Mesh PLY vertex"), bt(n, e.byteLength);
677
705
  const o = Xt(e, n), s = t.element("face");
678
706
  if (!s) throw new Error('Not a mesh PLY: no "face" element.');
679
707
  const i = qt(e, s, n.count);
@@ -685,12 +713,12 @@ function Vt(e) {
685
713
  };
686
714
  }
687
715
  function Xt(e, t) {
688
- const n = new DataView(e, t.offset), o = k(t, "x"), s = k(t, "y"), i = k(t, "z"), r = new Float32Array(t.count * 3);
716
+ const n = new DataView(e, t.offset), o = k(t, "x"), s = k(t, "y"), i = k(t, "z"), l = new Float32Array(t.count * 3);
689
717
  for (let c = 0; c < t.count; c++) {
690
- const u = c * t.stride;
691
- r[c * 3] = n.getFloat32(u + o, !0), r[c * 3 + 1] = n.getFloat32(u + s, !0), r[c * 3 + 2] = n.getFloat32(u + i, !0);
718
+ const a = c * t.stride;
719
+ l[c * 3] = n.getFloat32(a + o, !0), l[c * 3 + 1] = n.getFloat32(a + s, !0), l[c * 3 + 2] = n.getFloat32(a + i, !0);
692
720
  }
693
- return r;
721
+ return l;
694
722
  }
695
723
  function qt(e, t, n) {
696
724
  if (t.count === 0) return new Uint32Array(0);
@@ -707,31 +735,31 @@ function qt(e, t, n) {
707
735
  throw new Error(
708
736
  `Mesh PLY "face" element is missing an index list (${et.join(" or ")}).`
709
737
  );
710
- const i = W(s.countType), r = W(s.itemType), c = new DataView(e), u = e.byteLength;
711
- let l = new Uint32Array(t.count * 3), a = 0, f = t.offset;
738
+ const i = j(s.countType), l = j(s.itemType), c = new DataView(e), a = e.byteLength;
739
+ let r = new Uint32Array(t.count * 3), u = 0, f = t.offset;
712
740
  for (let h = 0; h < t.count; h++) {
713
- if (f + i > u) throw new Error(nt(h));
741
+ if (f + i > a) throw new Error(nt(h));
714
742
  const d = ot(c, f, s.countType, i);
715
743
  if (d < 0)
716
744
  throw new Error(`Mesh PLY face ${h} declares a negative vertex count (${d}).`);
717
- if (f += i, f + d * r > u) throw new Error(nt(h));
745
+ if (f += i, f + d * l > a) throw new Error(nt(h));
718
746
  const m = Math.max(0, d - 2);
719
- if (a + m * 3 > l.length) {
720
- const b = new Uint32Array(Math.max(l.length * 2, a + m * 3));
721
- b.set(l.subarray(0, a)), l = b;
747
+ if (u + m * 3 > r.length) {
748
+ const b = new Uint32Array(Math.max(r.length * 2, u + m * 3));
749
+ b.set(r.subarray(0, u)), r = b;
722
750
  }
723
751
  let p = 0, $ = 0;
724
752
  for (let b = 0; b < d; b++) {
725
- const g = ot(c, f + b * r, s.itemType, r);
726
- if (g < 0 || g >= n)
753
+ const w = ot(c, f + b * l, s.itemType, l);
754
+ if (w < 0 || w >= n)
727
755
  throw new Error(
728
- `Mesh PLY face ${h} references vertex ${g}, but the file has ${n}.`
756
+ `Mesh PLY face ${h} references vertex ${w}, but the file has ${n}.`
729
757
  );
730
- b === 0 ? p = g : b >= 2 && (l[a++] = p, l[a++] = $, l[a++] = g), $ = g;
758
+ b === 0 ? p = w : b >= 2 && (r[u++] = p, r[u++] = $, r[u++] = w), $ = w;
731
759
  }
732
- f += d * r;
760
+ f += d * l;
733
761
  }
734
- return a === l.length ? l : l.slice(0, a);
762
+ return u === r.length ? r : r.slice(0, u);
735
763
  }
736
764
  function nt(e) {
737
765
  return `Truncated PLY file: the "face" element ends inside face ${e}.`;
@@ -760,11 +788,11 @@ function ot(e, t, n, o) {
760
788
  throw new Error(`Unsupported PLY index type: "${n}" (${o} bytes).`);
761
789
  }
762
790
  }
763
- const Ht = 1819045731, st = 2, z = 48, it = 40, ut = 3, ht = 3, rt = ut * 4, Gt = ht * 4;
791
+ const Ht = 1819045731, st = 2, D = 48, it = 40, ut = 3, ht = 3, rt = ut * 4, Gt = ht * 4;
764
792
  function Qt(e) {
765
- if (e.byteLength < z)
793
+ if (e.byteLength < D)
766
794
  throw new Error(
767
- `collision.lci is truncated: ${e.byteLength} bytes, need at least ${z}.`
795
+ `collision.lci is truncated: ${e.byteLength} bytes, need at least ${D}.`
768
796
  );
769
797
  const t = new DataView(e), n = t.getUint32(0, !0);
770
798
  if (n !== Ht)
@@ -780,63 +808,63 @@ function Qt(e) {
780
808
  t.getFloat32(12, !0),
781
809
  t.getFloat32(16, !0),
782
810
  t.getFloat32(20, !0)
783
- ), r = new E.Vector3(
811
+ ), l = new E.Vector3(
784
812
  t.getFloat32(24, !0),
785
813
  t.getFloat32(28, !0),
786
814
  t.getFloat32(32, !0)
787
- ), c = t.getFloat32(36, !0), u = t.getFloat32(40, !0), l = t.getUint32(44, !0), a = z + l * it;
788
- if (s !== a)
815
+ ), c = t.getFloat32(36, !0), a = t.getFloat32(40, !0), r = t.getUint32(44, !0), u = D + r * it;
816
+ if (s !== u)
789
817
  throw new Error(
790
- `collision.lci headerLen ${s} does not match ${l} mesh headers (expected ${a}).`
818
+ `collision.lci headerLen ${s} does not match ${r} mesh headers (expected ${u}).`
791
819
  );
792
820
  if (e.byteLength < s)
793
821
  throw new Error(
794
822
  `collision.lci is truncated: header claims ${s} bytes, file has ${e.byteLength}.`
795
823
  );
796
- if (!(c > 0) || !(u > 0))
824
+ if (!(c > 0) || !(a > 0))
797
825
  throw new Error(
798
- `collision.lci cell lengths must be positive (got ${c} × ${u}).`
826
+ `collision.lci cell lengths must be positive (got ${c} × ${a}).`
799
827
  );
800
- const f = new E.Box3(i.clone(), r.clone()), h = [];
828
+ const f = new E.Box3(i.clone(), l.clone()), h = [];
801
829
  let d = s;
802
- for (let m = 0; m < l; m++) {
803
- const p = z + m * it, $ = t.getUint32(p, !0), b = t.getUint32(p + 4, !0), g = Number(t.getBigUint64(p + 8, !0)), C = Number(t.getBigUint64(p + 16, !0)), x = t.getUint32(p + 24, !0), y = t.getUint32(p + 28, !0), L = t.getUint32(p + 32, !0);
804
- if (!Number.isSafeInteger(g) || !Number.isSafeInteger(C))
830
+ for (let m = 0; m < r; m++) {
831
+ const p = D + m * it, $ = t.getUint32(p, !0), b = t.getUint32(p + 4, !0), w = Number(t.getBigUint64(p + 8, !0)), C = Number(t.getBigUint64(p + 16, !0)), v = t.getUint32(p + 24, !0), y = t.getUint32(p + 28, !0), L = t.getUint32(p + 32, !0);
832
+ if (!Number.isSafeInteger(w) || !Number.isSafeInteger(C))
805
833
  throw new Error(`collision.lci mesh ${m} has an unsafe data offset/size.`);
806
- if (g !== d)
834
+ if (w !== d)
807
835
  throw new Error(
808
- `collision.lci mesh ${m} data offset ${g} is not contiguous (expected ${d}).`
836
+ `collision.lci mesh ${m} data offset ${w} is not contiguous (expected ${d}).`
809
837
  );
810
- if (x * rt + y * Gt + L !== C)
838
+ if (v * rt + y * Gt + L !== C)
811
839
  throw new Error(
812
- `collision.lci mesh ${m} size ${C} != ${x}*12 + ${y}*12 + BVH ${L}.`
840
+ `collision.lci mesh ${m} size ${C} != ${v}*12 + ${y}*12 + BVH ${L}.`
813
841
  );
814
- const v = g + C;
815
- if (v > e.byteLength)
842
+ const x = w + C;
843
+ if (x > e.byteLength)
816
844
  throw new Error(
817
- `collision.lci mesh ${m} extends to byte ${v}, past file length ${e.byteLength}.`
845
+ `collision.lci mesh ${m} extends to byte ${x}, past file length ${e.byteLength}.`
818
846
  );
819
- const F = new Float32Array(e, g, x * ut), M = g + x * rt, S = new Uint32Array(e, M, y * ht);
847
+ const U = new Float32Array(e, w, v * ut), M = w + v * rt, S = new Uint32Array(e, M, y * ht);
820
848
  for (let T = 0; T < S.length; T++) {
821
849
  const B = S[T];
822
- if (B >= x)
850
+ if (B >= v)
823
851
  throw new Error(
824
- `collision.lci mesh ${m} face index ${B} is out of range (vertexCount ${x}).`
852
+ `collision.lci mesh ${m} face index ${B} is out of range (vertexCount ${v}).`
825
853
  );
826
854
  }
827
855
  h.push({
828
856
  cellX: $,
829
857
  cellY: b,
830
858
  data: {
831
- vertexCount: x,
859
+ vertexCount: v,
832
860
  triangleCount: y,
833
861
  // Copy so the returned arrays outlive a transferred/detached buffer
834
862
  // and are not views into the BVH-adjacent region.
835
- positions: F.slice(),
863
+ positions: U.slice(),
836
864
  indices: S.slice()
837
865
  },
838
- bounds: Wt($, b, c, u, f)
839
- }), d = v;
866
+ bounds: Wt($, b, c, a, f)
867
+ }), d = x;
840
868
  }
841
869
  if (d !== e.byteLength)
842
870
  throw new Error(
@@ -846,17 +874,17 @@ function Qt(e) {
846
874
  version: o,
847
875
  bounds: f,
848
876
  cellLengthX: c,
849
- cellLengthY: u,
877
+ cellLengthY: a,
850
878
  tiles: h
851
879
  };
852
880
  }
853
881
  function Wt(e, t, n, o, s) {
854
- const i = s.min.x + e * n, r = s.min.y + t * o;
882
+ const i = s.min.x + e * n, l = s.min.y + t * o;
855
883
  return new E.Box3(
856
- new E.Vector3(Math.min(i, s.max.x), Math.min(r, s.max.y), s.min.z),
884
+ new E.Vector3(Math.min(i, s.max.x), Math.min(l, s.max.y), s.min.z),
857
885
  new E.Vector3(
858
886
  Math.min(i + n, s.max.x),
859
- Math.min(r + o, s.max.y),
887
+ Math.min(l + o, s.max.y),
860
888
  s.max.z
861
889
  )
862
890
  );
@@ -869,7 +897,7 @@ async function ue(e, t = {}) {
869
897
  (s = t.signal) == null || s.throwIfAborted();
870
898
  const o = [];
871
899
  for (const i of n)
872
- i.status === "fulfilled" ? o.push(...i.value) : D("Skipping a collision mesh that failed to load:", i.reason);
900
+ i.status === "fulfilled" ? o.push(...i.value) : z("Skipping a collision mesh that failed to load:", i.reason);
873
901
  return o;
874
902
  }
875
903
  async function jt(e, t) {
@@ -878,10 +906,10 @@ async function jt(e, t) {
878
906
  throw new Error(`HTTP ${n.status} for collision mesh ${e.url}`);
879
907
  const o = await n.arrayBuffer();
880
908
  if (Kt(e.url))
881
- return Qt(o).tiles.map((r) => ({
882
- url: `${e.url}#c${r.cellX}_${r.cellY}`,
883
- data: r.data,
884
- bounds: r.bounds
909
+ return Qt(o).tiles.map((l) => ({
910
+ url: `${e.url}#c${l.cellX}_${l.cellY}`,
911
+ data: l.data,
912
+ bounds: l.bounds
885
913
  }));
886
914
  const s = Vt(o);
887
915
  return [
@@ -901,22 +929,22 @@ function Kt(e) {
901
929
  }
902
930
  function he(e, t) {
903
931
  Zt(e);
904
- const { positions: n, indices: o, vertexCount: s, triangleCount: i } = e, r = new Uint8Array(s);
905
- for (let l = 0; l < s; l++)
906
- r[l] = t.containsPoint(
907
- n[l * 3],
908
- n[l * 3 + 1],
909
- n[l * 3 + 2]
932
+ const { positions: n, indices: o, vertexCount: s, triangleCount: i } = e, l = new Uint8Array(s);
933
+ for (let r = 0; r < s; r++)
934
+ l[r] = t.containsPoint(
935
+ n[r * 3],
936
+ n[r * 3 + 1],
937
+ n[r * 3 + 2]
910
938
  ) ? 1 : 0;
911
939
  const c = new Uint8Array(i);
912
- let u = 0;
913
- for (let l = 0; l < i; l++) {
914
- const a = o[l * 3], f = o[l * 3 + 1], h = o[l * 3 + 2];
915
- (r[a] === 1 || r[f] === 1 || r[h] === 1) && (c[l] = 1, u++);
940
+ let a = 0;
941
+ for (let r = 0; r < i; r++) {
942
+ const u = o[r * 3], f = o[r * 3 + 1], h = o[r * 3 + 2];
943
+ (l[u] === 1 || l[f] === 1 || l[h] === 1) && (c[r] = 1, a++);
916
944
  }
917
945
  return {
918
- inside: lt(e, c, 1, u),
919
- outside: lt(e, c, 0, i - u)
946
+ inside: lt(e, c, 1, a),
947
+ outside: lt(e, c, 0, i - a)
920
948
  };
921
949
  }
922
950
  function Zt(e) {
@@ -938,26 +966,26 @@ function Zt(e) {
938
966
  }
939
967
  function lt(e, t, n, o) {
940
968
  const s = new Int32Array(e.vertexCount).fill(-1), i = new Uint32Array(o * 3);
941
- let r = 0, c = 0;
942
- for (let l = 0; l < e.triangleCount; l++)
943
- if (t[l] === n)
944
- for (let a = 0; a < 3; a++) {
945
- const f = e.indices[l * 3 + a];
969
+ let l = 0, c = 0;
970
+ for (let r = 0; r < e.triangleCount; r++)
971
+ if (t[r] === n)
972
+ for (let u = 0; u < 3; u++) {
973
+ const f = e.indices[r * 3 + u];
946
974
  let h = s[f];
947
- h < 0 && (h = r++, s[f] = h), i[c++] = h;
975
+ h < 0 && (h = l++, s[f] = h), i[c++] = h;
948
976
  }
949
- const u = new Float32Array(r * 3);
950
- for (let l = 0; l < e.vertexCount; l++) {
951
- const a = s[l];
952
- a < 0 || (u[a * 3] = e.positions[l * 3], u[a * 3 + 1] = e.positions[l * 3 + 1], u[a * 3 + 2] = e.positions[l * 3 + 2]);
977
+ const a = new Float32Array(l * 3);
978
+ for (let r = 0; r < e.vertexCount; r++) {
979
+ const u = s[r];
980
+ u < 0 || (a[u * 3] = e.positions[r * 3], a[u * 3 + 1] = e.positions[r * 3 + 1], a[u * 3 + 2] = e.positions[r * 3 + 2]);
953
981
  }
954
- return { vertexCount: r, triangleCount: o, positions: u, indices: i };
982
+ return { vertexCount: l, triangleCount: o, positions: a, indices: i };
955
983
  }
956
984
  export {
957
985
  le as applyLcc2ToThreeTransform,
958
986
  ae as buildLcc2Scene,
959
987
  ce as buildLccScene,
960
- q as createLcc2ToThreeMatrix,
988
+ H as createLcc2ToThreeMatrix,
961
989
  ue as loadCollisionMeshTiles,
962
990
  Qt as parseCollisionLci,
963
991
  re as parseLccChunk,