@needle-tools/gltf-progressive 3.6.0-alpha.2 → 3.6.0-canary.027a4c9

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,69 +1,98 @@
1
- import { BufferGeometry as j, Mesh as K, Box3 as le, Vector3 as k, Sphere as Se, CompressedTexture as ze, Texture as G, Matrix3 as Ee, InterleavedBuffer as Ne, InterleavedBufferAttribute as Ve, BufferAttribute as Xe, TextureLoader as je, Color as Ce, Matrix4 as Pe, Clock as Ke } from "three";
2
- import { GLTFLoader as we } from "three/examples/jsm/loaders/GLTFLoader.js";
3
- import { MeshoptDecoder as Ye } from "three/examples/jsm/libs/meshopt_decoder.module.js";
4
- import { DRACOLoader as He } from "three/examples/jsm/loaders/DRACOLoader.js";
5
- import { KTX2Loader as Qe } from "three/examples/jsm/loaders/KTX2Loader.js";
6
- const Je = "";
7
- globalThis.GLTF_PROGRESSIVE_VERSION = Je;
1
+ import * as Xe from "three";
2
+ import { RedFormat as je, RedIntegerFormat as Ke, RGFormat as Ye, RGIntegerFormat as He, RGBFormat as Qe, RGBAFormat as Je, RGBAIntegerFormat as Ze, BufferGeometry as j, Mesh as K, Box3 as ue, Vector3 as P, Sphere as Ae, CompressedTexture as et, Texture as q, Matrix3 as tt, InterleavedBuffer as st, InterleavedBufferAttribute as rt, BufferAttribute as nt, TextureLoader as it, Color as Ie, Matrix4 as $e } from "three";
3
+ import { GLTFLoader as De } from "three/examples/jsm/loaders/GLTFLoader.js";
4
+ import { MeshoptDecoder as ot } from "three/examples/jsm/libs/meshopt_decoder.module.js";
5
+ import { DRACOLoader as at } from "three/examples/jsm/loaders/DRACOLoader.js";
6
+ import { KTX2Loader as lt } from "three/examples/jsm/loaders/KTX2Loader.js";
7
+ const ut = "";
8
+ globalThis.GLTF_PROGRESSIVE_VERSION = ut;
8
9
  console.debug("[gltf-progressive] version -");
9
- let I = "https://www.gstatic.com/draco/versioned/decoders/1.5.7/", Y = "https://cdn.needle.tools/static/three/0.179.1/basis2/";
10
- const Ze = I, et = Y, ke = new URL(I + "draco_decoder.js");
11
- ke.searchParams.append("range", "true");
12
- fetch(ke, {
10
+ let $ = "https://www.gstatic.com/draco/versioned/decoders/1.5.7/", Y = "https://cdn.needle.tools/static/three/0.179.1/basis2/";
11
+ const ct = $, ft = Y, Be = new URL($ + "draco_decoder.js");
12
+ Be.searchParams.append("range", "true");
13
+ fetch(Be, {
13
14
  method: "GET",
14
15
  headers: {
15
16
  Range: "bytes=0-1"
16
17
  }
17
18
  }).catch((i) => {
18
- console.debug(`Failed to fetch remote Draco decoder from ${I} (offline: ${typeof navigator < "u" ? navigator.onLine : "unknown"})`), I === Ze && st("./include/draco/"), Y === et && rt("./include/ktx2/");
19
+ console.debug(`Failed to fetch remote Draco decoder from ${$} (offline: ${typeof navigator < "u" ? navigator.onLine : "unknown"})`), $ === ct && ht("./include/draco/"), Y === ft && gt("./include/ktx2/");
19
20
  }).finally(() => {
20
- Re();
21
+ qe();
21
22
  });
22
- const tt = () => ({
23
- dracoDecoderPath: I,
23
+ const dt = () => ({
24
+ dracoDecoderPath: $,
24
25
  ktx2TranscoderPath: Y
25
26
  });
26
- function st(i) {
27
- I = i, P && P[me] != I ? (console.debug("Updating Draco decoder path to " + i), P[me] = I, P.setDecoderPath(I), P.preload()) : console.debug("Setting Draco decoder path to " + i);
27
+ function ht(i) {
28
+ $ = i, C && C[ye] != $ ? (console.debug("Updating Draco decoder path to " + i), C[ye] = $, C.setDecoderPath($), C.preload()) : console.debug("Setting Draco decoder path to " + i);
28
29
  }
29
- function rt(i) {
30
- Y = i, $ && $.transcoderPath != Y ? (console.debug("Updating KTX2 transcoder path to " + i), $.setTranscoderPath(Y), $.init()) : console.debug("Setting KTX2 transcoder path to " + i);
30
+ function gt(i) {
31
+ Y = i, B && B.transcoderPath != Y ? (console.debug("Updating KTX2 transcoder path to " + i), B.setTranscoderPath(Y), B.init()) : console.debug("Setting KTX2 transcoder path to " + i);
31
32
  }
32
- function Le(i) {
33
- return Re(), i ? $.detectSupport(i) : i !== null && console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"), { dracoLoader: P, ktx2Loader: $, meshoptDecoder: ae };
33
+ function _e(i) {
34
+ return qe(), i ? B.detectSupport(i) : i !== null && console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"), { dracoLoader: C, ktx2Loader: B, meshoptDecoder: le };
34
35
  }
35
- function Ae(i) {
36
- i.dracoLoader || i.setDRACOLoader(P), i.ktx2Loader || i.setKTX2Loader($), i.meshoptDecoder || i.setMeshoptDecoder(ae);
36
+ function Ge(i) {
37
+ i.dracoLoader || i.setDRACOLoader(C), i.ktx2Loader || i.setKTX2Loader(B), i.meshoptDecoder || i.setMeshoptDecoder(le);
37
38
  }
38
- const me = /* @__PURE__ */ Symbol("dracoDecoderPath");
39
- let P, ae, $;
40
- function Re() {
41
- P || (P = new He(), P[me] = I, P.setDecoderPath(I), P.setDecoderConfig({ type: "js" }), P.preload()), $ || ($ = new Qe(), $.setTranscoderPath(Y), $.init()), ae || (ae = Ye);
39
+ const ye = /* @__PURE__ */ Symbol("dracoDecoderPath");
40
+ let C, le, B;
41
+ function qe() {
42
+ C || (C = new at(), C[ye] = $, C.setDecoderPath($), C.setDecoderConfig({ type: "js" }), C.preload()), B || (B = new lt(), B.setTranscoderPath(Y), B.init()), le || (le = ot);
42
43
  }
43
- const ye = /* @__PURE__ */ new WeakMap();
44
- function Ie(i, t) {
45
- let e = ye.get(i);
46
- e ? e = Object.assign(e, t) : e = t, ye.set(i, e);
44
+ const xe = /* @__PURE__ */ new WeakMap();
45
+ function We(i, t) {
46
+ let e = xe.get(i);
47
+ e ? e = Object.assign(e, t) : e = t, xe.set(i, e);
47
48
  }
48
- const nt = we.prototype.load;
49
- function ot(...i) {
50
- const t = ye.get(this);
49
+ const pt = De.prototype.load;
50
+ function mt(...i) {
51
+ const t = xe.get(this);
51
52
  let e = i[0];
52
- const s = new URL(e, window.location.href);
53
- if (s.hostname.endsWith("needle.tools")) {
53
+ const s = yt(e);
54
+ if (s?.hostname.endsWith("needle.tools")) {
54
55
  const n = t?.progressive !== void 0 ? t.progressive : !0, o = t?.usecase ? t.usecase : "default";
55
56
  n ? this.requestHeader.Accept = `*/*;progressive=allowed;usecase=${o}` : this.requestHeader.Accept = `*/*;usecase=${o}`, e = s.toString();
56
57
  }
57
- return i[0] = e, nt?.call(this, ...i);
58
+ return i[0] = e, pt?.call(this, ...i);
59
+ }
60
+ De.prototype.load = mt;
61
+ function yt(i) {
62
+ try {
63
+ if (i instanceof URL)
64
+ return i;
65
+ const t = globalThis.location?.href;
66
+ return t ? new URL(i, t) : new URL(i);
67
+ } catch {
68
+ return null;
69
+ }
70
+ }
71
+ function Oe(i) {
72
+ return i != null && i.data != null;
73
+ }
74
+ function we(i) {
75
+ const t = i.source?.data;
76
+ return t != null && typeof t == "object" ? t : null;
77
+ }
78
+ function xt(i) {
79
+ const t = i.image;
80
+ return t != null && typeof t == "object" ? t : null;
81
+ }
82
+ function Le(i) {
83
+ const t = xt(i), e = we(i);
84
+ return {
85
+ width: t?.width || e?.width || 0,
86
+ height: t?.height || e?.height || 0
87
+ };
58
88
  }
59
- we.prototype.load = ot;
60
89
  N("debugprogressive");
61
90
  function N(i) {
62
91
  if (typeof window > "u") return !1;
63
92
  const e = new URL(window.location.href).searchParams.get(i);
64
93
  return e == null || e === "0" || e === "false" ? !1 : e === "" ? !0 : e;
65
94
  }
66
- function it(i, t) {
95
+ function wt(i, t) {
67
96
  if (t === void 0 || i === void 0 || t.startsWith("./") || t.startsWith("http") || t.startsWith("data:") || t.startsWith("blob:"))
68
97
  return t;
69
98
  const e = i.lastIndexOf("/");
@@ -74,16 +103,18 @@ function it(i, t) {
74
103
  }
75
104
  return t;
76
105
  }
77
- function ve() {
78
- return Z !== void 0 || (Z = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent), N("debugprogressive") && console.log("[glTF Progressive]: isMobileDevice", Z)), Z;
106
+ function Me() {
107
+ if (Z !== void 0) return Z;
108
+ const i = globalThis.navigator?.userAgent || "";
109
+ return Z = /iPhone|iPad|iPod|Android|IEMobile/i.test(i), N("debugprogressive") && console.log("[glTF Progressive]: isMobileDevice", Z), Z;
79
110
  }
80
111
  let Z;
81
- function $e() {
112
+ function Fe() {
82
113
  if (typeof window > "u") return !1;
83
114
  const i = new URL(window.location.href), t = i.hostname === "localhost" || /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(i.hostname);
84
115
  return i.hostname === "127.0.0.1" || t;
85
116
  }
86
- class at {
117
+ class Lt {
87
118
  constructor(t, e = {}) {
88
119
  this.maxConcurrent = t, this.debug = e.debug ?? !1, typeof window < "u" && window.requestAnimationFrame(this.tick);
89
120
  }
@@ -117,29 +148,29 @@ class at {
117
148
  }
118
149
  }
119
150
  }
120
- function lt(i) {
121
- const t = i.image?.width ?? 0, e = i.image?.height ?? 0, s = i.image?.depth ?? 1, r = Math.floor(Math.log2(Math.max(t, e, s))) + 1, n = ut(i);
122
- return t * e * s * n * (1 - Math.pow(0.25, r)) / (1 - 0.25);
151
+ function vt(i) {
152
+ const t = i.image, e = t?.width ?? 0, s = t?.height ?? 0, r = t?.depth ?? 1, n = Math.floor(Math.log2(Math.max(e, s, r))) + 1, o = Dt(i);
153
+ return e * s * r * o * (1 - Math.pow(0.25, n)) / (1 - 0.25);
123
154
  }
124
- function ut(i) {
155
+ function Dt(i) {
125
156
  let t = 4;
126
157
  const e = i.format;
127
- e === 1024 || e === 1025 ? t = 1 : e === 1026 || e === 1027 ? t = 2 : e === 1022 || e === 1029 ? t = 3 : (e === 1023 || e === 1033) && (t = 4);
158
+ e === je || e === Ke ? t = 1 : e === Ye || e === He ? t = 2 : e === Qe || e === 1029 ? t = 3 : (e === Je || e === Ze) && (t = 4);
128
159
  let s = 1;
129
160
  const r = i.type;
130
161
  return r === 1009 || r === 1010 ? s = 1 : r === 1011 || r === 1012 ? s = 2 : r === 1013 || r === 1014 || r === 1015 ? s = 4 : r === 1016 && (s = 2), t * s;
131
162
  }
132
- const ct = typeof window > "u" && typeof document > "u", xe = /* @__PURE__ */ Symbol("needle:raycast-mesh");
163
+ const _t = typeof window > "u" && typeof document > "u", ve = /* @__PURE__ */ Symbol("needle:raycast-mesh");
133
164
  function ne(i) {
134
- return i?.[xe] instanceof j ? i[xe] : null;
165
+ return i?.[ve] instanceof j ? i[ve] : null;
135
166
  }
136
- function dt(i, t) {
167
+ function Mt(i, t) {
137
168
  if ((i.type === "Mesh" || i.type === "SkinnedMesh") && !ne(i)) {
138
- const s = ht(t);
139
- s.userData = { isRaycastMesh: !0 }, i[xe] = s;
169
+ const s = Ot(t);
170
+ s.userData = { isRaycastMesh: !0 }, i[ve] = s;
140
171
  }
141
172
  }
142
- function ft(i = !0) {
173
+ function bt(i = !0) {
143
174
  if (i) {
144
175
  if (ee) return;
145
176
  const t = ee = K.prototype.raycast;
@@ -154,15 +185,15 @@ function ft(i = !0) {
154
185
  }
155
186
  }
156
187
  let ee = null;
157
- function ht(i) {
188
+ function Ot(i) {
158
189
  const t = new j();
159
190
  for (const e in i.attributes)
160
191
  t.setAttribute(e, i.getAttribute(e));
161
192
  return t.setIndex(i.getIndex()), t;
162
193
  }
163
- const E = new Array(), f = N("debugprogressive");
194
+ const E = new Array(), h = N("debugprogressive");
164
195
  let re, X = -1;
165
- if (f) {
196
+ if (h) {
166
197
  let i = function() {
167
198
  X += 1, X >= t && (X = -1), console.log(`Toggle LOD level [${X}]`);
168
199
  };
@@ -173,27 +204,27 @@ if (f) {
173
204
  !isNaN(s) && s >= 0 && (X = s, console.log(`Set LOD level to [${X}]`));
174
205
  });
175
206
  }
176
- function Be(i) {
177
- if (f && re !== void 0)
207
+ function Ue(i) {
208
+ if (h && re !== void 0)
178
209
  if (Array.isArray(i))
179
210
  for (const t of i)
180
- Be(t);
211
+ Ue(t);
181
212
  else i && "wireframe" in i && (i.wireframe = re === !0);
182
213
  }
183
214
  const te = new Array();
184
- let gt = 0;
185
- const pt = ve() ? 2 : 10;
186
- function mt(i) {
187
- if (te.length < pt) {
215
+ let Tt = 0;
216
+ const St = Me() ? 2 : 10;
217
+ function Rt(i) {
218
+ if (te.length < St) {
188
219
  const s = te.length;
189
- f && console.warn(`[Worker] Creating new worker #${s}`);
190
- const r = _e.createWorker(i || {});
220
+ h && console.warn(`[Worker] Creating new worker #${s}`);
221
+ const r = be.createWorker(i || {});
191
222
  return te.push(r), r;
192
223
  }
193
- const t = gt++ % te.length;
224
+ const t = Tt++ % te.length;
194
225
  return te[t];
195
226
  }
196
- class _e {
227
+ class be {
197
228
  constructor(t, e) {
198
229
  this.worker = t, this._debug = e.debug ?? !1, t.onmessage = (s) => {
199
230
  const r = s.data;
@@ -201,7 +232,7 @@ class _e {
201
232
  case "loaded-gltf":
202
233
  for (const n of this._running)
203
234
  if (n.url === r.result.url) {
204
- yt(r.result), n.resolve(r.result);
235
+ Ct(r.result), n.resolve(r.result);
205
236
  const o = n.url;
206
237
  o.startsWith("blob:") && URL.revokeObjectURL(o);
207
238
  }
@@ -220,61 +251,68 @@ class _e {
220
251
  ), {
221
252
  type: "module"
222
253
  });
223
- return new _e(e, t);
254
+ return new be(e, t);
224
255
  }
225
256
  _running = [];
226
257
  _webglRenderer = null;
227
258
  async load(t, e) {
228
- const s = tt();
259
+ const s = dt();
229
260
  let r = e?.renderer;
230
261
  r || (this._webglRenderer ??= (async () => {
231
- const { WebGLRenderer: l } = await import("three");
232
- return new l();
262
+ const { WebGLRenderer: u } = await import("three");
263
+ return new u();
233
264
  })(), r = await this._webglRenderer);
234
- const u = Le(r).ktx2Loader.workerConfig;
235
- t instanceof URL ? t = t.toString() : t.startsWith("file:") ? t = URL.createObjectURL(new Blob([t])) : !t.startsWith("blob:") && !t.startsWith("http:") && !t.startsWith("https:") && (t = new URL(t, window.location.href).toString());
236
- const a = {
265
+ const a = _e(r).ktx2Loader.workerConfig;
266
+ if (t instanceof URL)
267
+ t = t.toString();
268
+ else if (t.startsWith("file:"))
269
+ t = URL.createObjectURL(new Blob([t]));
270
+ else if (!t.startsWith("blob:") && !t.startsWith("http:") && !t.startsWith("https:")) {
271
+ const u = globalThis.location?.href;
272
+ u && (t = new URL(t, u).toString());
273
+ }
274
+ const l = {
237
275
  type: "load",
238
276
  url: t,
239
277
  dracoDecoderPath: s.dracoDecoderPath,
240
278
  ktx2TranscoderPath: s.ktx2TranscoderPath,
241
- ktx2LoaderConfig: u
279
+ ktx2LoaderConfig: a
242
280
  };
243
- return this._debug && console.debug("[Worker] Sending load request", a), this.worker.postMessage(a), new Promise((l) => {
281
+ return this._debug && console.debug("[Worker] Sending load request", l), this.worker.postMessage(l), new Promise((u) => {
244
282
  this._running.push({
245
283
  url: t.toString(),
246
- resolve: l
284
+ resolve: u
247
285
  });
248
286
  });
249
287
  }
250
288
  _debug = !1;
251
289
  }
252
- function yt(i) {
290
+ function Ct(i) {
253
291
  for (const t of i.geometries) {
254
292
  const e = t.geometry, s = new j();
255
293
  if (s.name = e.name || "", e.index) {
256
294
  const r = e.index;
257
- s.setIndex(ce(r));
295
+ s.setIndex(fe(r));
258
296
  }
259
297
  for (const r in e.attributes) {
260
- const n = e.attributes[r], o = ce(n);
298
+ const n = e.attributes[r], o = fe(n);
261
299
  s.setAttribute(r, o);
262
300
  }
263
301
  if (e.morphAttributes)
264
302
  for (const r in e.morphAttributes) {
265
- const o = e.morphAttributes[r].map((u) => ce(u));
303
+ const o = e.morphAttributes[r].map((a) => fe(a));
266
304
  s.morphAttributes[r] = o;
267
305
  }
268
- if (s.morphTargetsRelative = e.morphTargetsRelative ?? !1, s.boundingBox = new le(), s.boundingBox.min = new k(
306
+ if (s.morphTargetsRelative = e.morphTargetsRelative ?? !1, s.boundingBox = new ue(), s.boundingBox.min = new P(
269
307
  e.boundingBox?.min.x,
270
308
  e.boundingBox?.min.y,
271
309
  e.boundingBox?.min.z
272
- ), s.boundingBox.max = new k(
310
+ ), s.boundingBox.max = new P(
273
311
  e.boundingBox?.max.x,
274
312
  e.boundingBox?.max.y,
275
313
  e.boundingBox?.max.z
276
- ), s.boundingSphere = new Se(
277
- new k(
314
+ ), s.boundingSphere = new Ae(
315
+ new P(
278
316
  e.boundingSphere?.center.x,
279
317
  e.boundingSphere?.center.y,
280
318
  e.boundingSphere?.center.z
@@ -289,8 +327,8 @@ function yt(i) {
289
327
  const e = t.texture;
290
328
  let s = null;
291
329
  if (e.isCompressedTexture) {
292
- const r = e.mipmaps, n = e.image?.width || e.source?.data?.width || -1, o = e.image?.height || e.source?.data?.height || -1;
293
- s = new ze(
330
+ const r = e.mipmaps, { width: n, height: o } = Le(e);
331
+ s = new et(
294
332
  r,
295
333
  n,
296
334
  o,
@@ -305,7 +343,7 @@ function yt(i) {
305
343
  e.colorSpace
306
344
  );
307
345
  } else
308
- s = new G(
346
+ s = new q(
309
347
  e.image,
310
348
  e.mapping,
311
349
  e.wrapS,
@@ -316,7 +354,7 @@ function yt(i) {
316
354
  e.type,
317
355
  e.anisotropy,
318
356
  e.colorSpace
319
- ), s.mipmaps = e.mipmaps, s.channel = e.channel, s.source.data = e.source.data, s.flipY = e.flipY, s.premultiplyAlpha = e.premultiplyAlpha, s.unpackAlignment = e.unpackAlignment, s.matrix = new Ee(...e.matrix.elements);
357
+ ), s.mipmaps = e.mipmaps, s.channel = e.channel, s.source.data = e.source.data, s.flipY = e.flipY, s.premultiplyAlpha = e.premultiplyAlpha, s.unpackAlignment = e.unpackAlignment, s.matrix = new tt(...e.matrix.elements);
320
358
  if (!s) {
321
359
  console.error("[Worker] Failed to create new texture from received data. Texture is not a CompressedTexture or Texture.");
322
360
  continue;
@@ -325,18 +363,18 @@ function yt(i) {
325
363
  }
326
364
  return i;
327
365
  }
328
- function ce(i) {
366
+ function fe(i) {
329
367
  let t = i;
330
368
  if ("isInterleavedBufferAttribute" in i && i.isInterleavedBufferAttribute) {
331
- const e = i.data, s = e.array, r = new Ne(s, e.stride);
332
- t = new Ve(r, i.itemSize, s.byteOffset, i.normalized), t.offset = i.offset;
333
- } else "isBufferAttribute" in i && i.isBufferAttribute && (t = new Xe(i.array, i.itemSize, i.normalized), t.usage = i.usage, t.gpuType = i.gpuType, t.updateRanges = i.updateRanges);
369
+ const e = i.data, s = e.array, r = new st(s, e.stride);
370
+ t = new rt(r, i.itemSize, s.byteOffset, i.normalized), t.offset = i.offset;
371
+ } else "isBufferAttribute" in i && i.isBufferAttribute && (t = new nt(i.array, i.itemSize, i.normalized), t.usage = i.usage, t.gpuType = i.gpuType, t.updateRanges = i.updateRanges);
334
372
  return t;
335
373
  }
336
- const xt = N("gltf-progressive-worker");
374
+ const Pt = N("gltf-progressive-worker");
337
375
  N("gltf-progressive-reduce-mipmaps");
338
376
  const se = N("gltf-progressive-gc"), de = /* @__PURE__ */ Symbol("needle-progressive-texture"), F = "NEEDLE_progressive";
339
- class h {
377
+ class p {
340
378
  /** The name of the extension */
341
379
  get name() {
342
380
  return F;
@@ -381,33 +419,33 @@ class h {
381
419
  max_count: 0,
382
420
  lods: []
383
421
  }), Array.isArray(t)) {
384
- for (const u of t)
385
- this.getMaterialMinMaxLODsCount(u, e);
422
+ for (const a of t)
423
+ this.getMaterialMinMaxLODsCount(a, e);
386
424
  return t[r] = e, e;
387
425
  }
388
- if (f === "verbose" && console.log("getMaterialMinMaxLODsCount", t), t.type === "ShaderMaterial" || t.type === "RawShaderMaterial") {
389
- const u = t;
390
- for (const a of Object.keys(u.uniforms)) {
391
- const l = u.uniforms[a].value;
392
- l?.isTexture === !0 && o(l, e);
426
+ if (h === "verbose" && console.log("getMaterialMinMaxLODsCount", t), t.type === "ShaderMaterial" || t.type === "RawShaderMaterial") {
427
+ const a = t;
428
+ for (const l of Object.keys(a.uniforms)) {
429
+ const u = a.uniforms[l].value;
430
+ u?.isTexture === !0 && o(u, e);
393
431
  }
394
432
  } else if (t.isMaterial)
395
- for (const u of Object.keys(t)) {
396
- const a = t[u];
397
- a?.isTexture === !0 && o(a, e);
433
+ for (const a of Object.keys(t)) {
434
+ const l = t[a];
435
+ l?.isTexture === !0 && o(l, e);
398
436
  }
399
437
  else
400
- f && console.warn(`[getMaterialMinMaxLODsCount] Unsupported material type: ${t.type}`);
438
+ h && console.warn(`[getMaterialMinMaxLODsCount] Unsupported material type: ${t.type}`);
401
439
  return t[r] = e, e;
402
- function o(u, a) {
403
- const l = s.getAssignedLODInformation(u);
404
- if (l) {
405
- const c = s.lodInfos.get(l.key);
406
- if (c && c.lods) {
407
- a.min_count = Math.min(a.min_count, c.lods.length), a.max_count = Math.max(a.max_count, c.lods.length);
408
- for (let d = 0; d < c.lods.length; d++) {
409
- const g = c.lods[d];
410
- g.width && (a.lods[d] = a.lods[d] || { min_height: 1 / 0, max_height: 0 }, a.lods[d].min_height = Math.min(a.lods[d].min_height, g.height), a.lods[d].max_height = Math.max(a.lods[d].max_height, g.height));
440
+ function o(a, l) {
441
+ const u = s.getAssignedLODInformation(a);
442
+ if (u) {
443
+ const f = s.lodInfos.get(u.key);
444
+ if (f && f.lods) {
445
+ l.min_count = Math.min(l.min_count, f.lods.length), l.max_count = Math.max(l.max_count, f.lods.length);
446
+ for (let c = 0; c < f.lods.length; c++) {
447
+ const d = f.lods[c];
448
+ d.width && (l.lods[c] = l.lods[c] || { min_height: 1 / 0, max_height: 0 }, l.lods[c].min_height = Math.min(l.lods[c].min_height, d.height), l.lods[c].max_height = Math.max(l.lods[c].max_height, d.height));
411
449
  }
412
450
  }
413
451
  }
@@ -465,16 +503,21 @@ class h {
465
503
  const r = t.geometry, n = this.getAssignedLODInformation(r);
466
504
  if (!n)
467
505
  return Promise.resolve(null);
468
- for (const o of E)
469
- o.onBeforeGetLODMesh?.(t, e);
470
- return t["LOD:requested level"] = e, h.getOrLoadLOD(r, e).then((o) => {
471
- if (Array.isArray(o)) {
506
+ for (const a of E)
507
+ a.onBeforeGetLODMesh?.(t, e);
508
+ t["LOD:requested level"] = e;
509
+ const o = () => t["LOD:requested level"] === e || this.shouldApplyStaleMeshLOD(t, e);
510
+ return p.getOrLoadLOD(r, e, {
511
+ isCurrent: o
512
+ }).then((a) => {
513
+ if (Array.isArray(a)) {
472
514
  const u = n.index || 0;
473
- o = o[u];
515
+ a = a[u];
474
516
  }
475
- return t["LOD:requested level"] === e && (delete t["LOD:requested level"], o && r != o && (o?.isBufferGeometry ? typeof s?.apply == "function" ? s.apply(o, e, t) : s?.apply !== !1 && (t.geometry = o) : f && console.error("Invalid LOD geometry", o))), o;
476
- }).catch((o) => (console.error("Error loading mesh LOD", t, o), null));
477
- } else f && console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh", t);
517
+ const l = t["LOD:requested level"] === e;
518
+ return (l || this.shouldApplyStaleMeshLOD(t, e)) && (l && delete t["LOD:requested level"], a && r != a && (a?.isBufferGeometry ? typeof s?.apply == "function" ? s.apply(a, e, t) : s?.apply !== !1 && (t.geometry = a) : h && console.error("Invalid LOD geometry", a))), a;
519
+ }).catch((a) => (console.error("Error loading mesh LOD", t, a), null));
520
+ } else h && console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh", t);
478
521
  return Promise.resolve(null);
479
522
  }
480
523
  static assignTextureLOD(t, e = 0, s) {
@@ -484,48 +527,48 @@ class h {
484
527
  const n = t;
485
528
  if (Array.isArray(n.material)) {
486
529
  const o = new Array();
487
- for (const u of n.material) {
488
- const a = this.assignTextureLOD(u, e, s);
489
- o.push(a);
530
+ for (const a of n.material) {
531
+ const l = this.assignTextureLOD(a, e, s);
532
+ o.push(l);
490
533
  }
491
- return Promise.all(o).then((u) => {
492
- const a = new Array();
493
- for (const l of u)
494
- Array.isArray(l) && a.push(...l);
495
- return a;
534
+ return Promise.all(o).then((a) => {
535
+ const l = new Array();
536
+ for (const u of a)
537
+ Array.isArray(u) && l.push(...u);
538
+ return l;
496
539
  });
497
540
  } else
498
541
  return this.assignTextureLOD(n.material, e, s);
499
542
  }
500
543
  if (t.isMaterial === !0) {
501
- const n = t, o = [], u = new Array();
544
+ const n = t, o = [], a = new Array();
502
545
  if (this.trackCurrentMaterialTextureSlots(n), n.uniforms && (n.isRawShaderMaterial || n.isShaderMaterial === !0)) {
503
- const a = n;
504
- for (const l of Object.keys(a.uniforms)) {
505
- const c = a.uniforms[l].value;
506
- if (c?.isTexture === !0) {
507
- const d = this.assignTextureLODForSlot(c, e, n, l, r).then((g) => (g && a.uniforms[l].value != g && (a.uniforms[l].value = g, a.uniformsNeedUpdate = !0), g));
508
- o.push(d), u.push(l);
546
+ const l = n;
547
+ for (const u of Object.keys(l.uniforms)) {
548
+ const f = l.uniforms[u].value;
549
+ if (f?.isTexture === !0) {
550
+ const c = this.assignTextureLODForSlot(f, e, n, u, r).then((d) => (d && l.uniforms[u].value != d && (l.uniforms[u].value = d, l.uniformsNeedUpdate = !0), d));
551
+ o.push(c), a.push(u);
509
552
  }
510
553
  }
511
554
  } else
512
- for (const a of Object.keys(n)) {
513
- const l = n[a];
514
- if (l?.isTexture === !0) {
515
- const c = this.assignTextureLODForSlot(l, e, n, a, r);
516
- o.push(c), u.push(a);
555
+ for (const l of Object.keys(n)) {
556
+ const u = n[l];
557
+ if (u?.isTexture === !0) {
558
+ const f = this.assignTextureLODForSlot(u, e, n, l, r);
559
+ o.push(f), a.push(l);
517
560
  }
518
561
  }
519
- return Promise.all(o).then((a) => {
520
- const l = new Array();
521
- for (let c = 0; c < a.length; c++) {
522
- const d = a[c], g = u[c];
523
- d && d.isTexture === !0 ? l.push({ material: n, slot: g, texture: d, level: e }) : l.push({ material: n, slot: g, texture: null, level: e });
562
+ return Promise.all(o).then((l) => {
563
+ const u = new Array();
564
+ for (let f = 0; f < l.length; f++) {
565
+ const c = l[f], d = a[f];
566
+ c && c.isTexture === !0 ? u.push({ material: n, slot: d, texture: c, level: e }) : u.push({ material: n, slot: d, texture: null, level: e });
524
567
  }
525
- return l;
568
+ return u;
526
569
  });
527
570
  }
528
- if (t instanceof G || t.isTexture === !0) {
571
+ if (t instanceof q || t.isTexture === !0) {
529
572
  const n = t;
530
573
  return this.assignTextureLODForSlot(n, e, null, null, r);
531
574
  }
@@ -536,10 +579,10 @@ class h {
536
579
  * @default 50 on desktop, 20 on mobile devices
537
580
  */
538
581
  static set maxConcurrentLoadingTasks(t) {
539
- h.queue.maxConcurrent = t;
582
+ p.queue.maxConcurrent = t;
540
583
  }
541
584
  static get maxConcurrentLoadingTasks() {
542
- return h.queue.maxConcurrent;
585
+ return p.queue.maxConcurrent;
543
586
  }
544
587
  // #region INTERNAL
545
588
  static assignTextureLODForSlot(t, e, s, r, n) {
@@ -551,33 +594,38 @@ class h {
551
594
  if (o && (o.level === e || !n && o.level < e))
552
595
  return Promise.resolve(t);
553
596
  if (s && r) {
554
- const a = this.getPendingTextureSlotRequest(s, r);
555
- if (a && a.level === e && a.force === n)
556
- return a.promise;
597
+ const c = this.getPendingTextureSlotRequest(s, r);
598
+ if (c && c.level === e && c.force === n)
599
+ return c.promise;
557
600
  }
558
- const u = h.getOrLoadLOD(t, e).then((a) => {
559
- if (Array.isArray(a))
601
+ const a = s && r ? this.nextTextureSlotRequestId(s, r, e, n) : 0, l = () => !s || !r || this.getLatestTextureSlotRequest(s, r)?.id === a, u = () => l() || this.shouldApplyStaleTextureSlotLOD(s, r, e, n), f = p.getOrLoadLOD(t, e, {
602
+ isCurrent: u
603
+ }).then((c) => {
604
+ if (!l() && !this.shouldApplyStaleTextureSlotLOD(s, r, e, n)) return null;
605
+ if (Array.isArray(c))
560
606
  return console.warn("Progressive: Got an array of textures for a texture slot, this should not happen..."), null;
561
- if (a?.isTexture === !0) {
562
- if (a != t && s && r) {
563
- const l = this.getMaterialTextureSlot(s, r) ?? t;
564
- if (l && !n) {
565
- const c = this.getAssignedLODInformation(l);
566
- if (c && c?.level < e)
567
- return f === "verbose" && console.warn("Assigned texture level is already higher: ", c.level, e, s, l, a), null;
607
+ if (c?.isTexture === !0) {
608
+ if (c != t && s && r) {
609
+ const d = this.getMaterialTextureSlot(s, r) ?? t;
610
+ if (d && !n) {
611
+ const g = this.getAssignedLODInformation(d);
612
+ if (g && g?.level < e)
613
+ return h === "verbose" && console.warn("Assigned texture level is already higher: ", g.level, e, s, d, c), null;
568
614
  }
569
- this.assignTrackedTextureSlot(s, r, a);
615
+ this.assignTrackedTextureSlot(s, r, c);
570
616
  }
571
- return a;
572
- } else f == "verbose" && console.warn("No LOD found for", t, e);
617
+ return c;
618
+ } else h == "verbose" && console.warn("No LOD found for", t, e);
573
619
  return null;
574
- }).catch((a) => (console.error("Error loading LOD", t, a), null));
575
- return s && r && this.setPendingTextureSlotRequest(s, r, e, n, u), u;
620
+ }).catch((c) => (console.error("Error loading LOD", t, c), null));
621
+ return s && r && this.setPendingTextureSlotRequest(s, r, e, n, a, f), f;
576
622
  }
577
623
  // Track material slots, not just texture objects. A shared fallback texture can be
578
624
  // referenced by many slots and should only be disposed after every slot moved away.
579
625
  static trackedTextureSlots = /* @__PURE__ */ new WeakMap();
580
626
  static pendingTextureSlotRequests = /* @__PURE__ */ new WeakMap();
627
+ static latestTextureSlotRequests = /* @__PURE__ */ new WeakMap();
628
+ static textureSlotRequestId = 0;
581
629
  static trackCurrentMaterialTextureSlots(t) {
582
630
  if (t.uniforms && (t.isRawShaderMaterial || t.isShaderMaterial === !0)) {
583
631
  const e = t;
@@ -595,12 +643,32 @@ class h {
595
643
  static getPendingTextureSlotRequest(t, e) {
596
644
  return this.pendingTextureSlotRequests.get(t)?.get(e);
597
645
  }
598
- static setPendingTextureSlotRequest(t, e, s, r, n) {
599
- let o = this.pendingTextureSlotRequests.get(t);
600
- o || (o = /* @__PURE__ */ new Map(), this.pendingTextureSlotRequests.set(t, o));
601
- const u = { level: s, force: r, promise: n };
602
- o.set(e, u), n.finally(() => {
603
- o.get(e) === u && o.delete(e);
646
+ static nextTextureSlotRequestId(t, e, s, r) {
647
+ let n = this.latestTextureSlotRequests.get(t);
648
+ n || (n = /* @__PURE__ */ new Map(), this.latestTextureSlotRequests.set(t, n));
649
+ const o = ++this.textureSlotRequestId;
650
+ return n.set(e, { id: o, level: s, force: r }), o;
651
+ }
652
+ static getLatestTextureSlotRequest(t, e) {
653
+ return this.latestTextureSlotRequests.get(t)?.get(e);
654
+ }
655
+ static shouldApplyStaleTextureSlotLOD(t, e, s, r) {
656
+ if (!t || !e) return !1;
657
+ const n = this.getLatestTextureSlotRequest(t, e), o = this.getMaterialTextureSlot(t, e), a = this.getAssignedLODInformation(o)?.level ?? 1 / 0;
658
+ return s >= a ? !1 : r ? n ? s >= n.level : !1 : !0;
659
+ }
660
+ static shouldApplyStaleMeshLOD(t, e) {
661
+ const s = t["LOD:requested level"];
662
+ if (typeof s != "number") return !1;
663
+ const r = this.getAssignedLODInformation(t.geometry)?.level ?? 1 / 0;
664
+ return e < r && e >= s;
665
+ }
666
+ static setPendingTextureSlotRequest(t, e, s, r, n, o) {
667
+ let a = this.pendingTextureSlotRequests.get(t);
668
+ a || (a = /* @__PURE__ */ new Map(), this.pendingTextureSlotRequests.set(t, a));
669
+ const l = { level: s, force: r, id: n, promise: o };
670
+ a.set(e, l), o.finally(() => {
671
+ a.get(e)?.id === n && a.delete(e);
604
672
  });
605
673
  }
606
674
  static getMaterialTextureSlot(t, e) {
@@ -633,7 +701,7 @@ class h {
633
701
  }
634
702
  static releaseTrackedTextureSlot(t, e, s) {
635
703
  const r = this.trackedTextureSlots.get(t);
636
- if (r?.get(e) === s && r.delete(e), this.untrackTextureUsage(s) && (f || se)) {
704
+ if (r?.get(e) === s && r.delete(e), this.untrackTextureUsage(s) && (h || se)) {
637
705
  const o = this.getAssignedLODInformation(s);
638
706
  console.log(`[gltf-progressive] Disposed old texture LOD ${o?.level ?? "?"} for ${t.name || t.type}.${e}`, s.uuid);
639
707
  }
@@ -642,13 +710,13 @@ class h {
642
710
  url;
643
711
  constructor(t) {
644
712
  const e = t.options.path;
645
- f && console.log("Progressive extension registered for", e), this.parser = t, this.url = e;
713
+ h && console.log("Progressive extension registered for", e), this.parser = t, this.url = e;
646
714
  }
647
715
  _isLoadingMesh;
648
716
  loadMesh = (t) => {
649
717
  if (this._isLoadingMesh) return null;
650
718
  const e = this.parser.json.meshes[t]?.extensions?.[F];
651
- return e ? (this._isLoadingMesh = !0, this.parser.getDependency("mesh", t).then((s) => (this._isLoadingMesh = !1, s && h.registerMesh(this.url, e.guid, s, e.lods?.length, 0, e), s))) : null;
719
+ return e ? (this._isLoadingMesh = !0, this.parser.getDependency("mesh", t).then((s) => (this._isLoadingMesh = !1, s && p.registerMesh(this.url, e.guid, s, e.lods?.length, 0, e), s))) : null;
652
720
  };
653
721
  // private _isLoadingTexture;
654
722
  // loadTexture = (textureIndex: number) => {
@@ -665,19 +733,19 @@ class h {
665
733
  // });
666
734
  // }
667
735
  afterRoot(t) {
668
- return f && console.log("AFTER", this.url, t), this.parser.json.textures?.forEach((e, s) => {
736
+ return h && console.log("AFTER", this.url, t), this.parser.json.textures?.forEach((e, s) => {
669
737
  if (e?.extensions) {
670
738
  const r = e?.extensions[F];
671
739
  if (r) {
672
740
  if (!r.lods) {
673
- f && console.warn("Texture has no LODs", r);
741
+ h && console.warn("Texture has no LODs", r);
674
742
  return;
675
743
  }
676
744
  let n = !1;
677
745
  for (const o of this.parser.associations.keys())
678
- o.isTexture === !0 && this.parser.associations.get(o)?.textures === s && (n = !0, h.registerTexture(this.url, o, r.lods?.length, s, r));
746
+ o.isTexture === !0 && this.parser.associations.get(o)?.textures === s && (n = !0, p.registerTexture(this.url, o, r.lods?.length, s, r));
679
747
  n || this.parser.getDependency("texture", s).then((o) => {
680
- o && h.registerTexture(this.url, o, r.lods?.length, s, r);
748
+ o && p.registerTexture(this.url, o, r.lods?.length, s, r);
681
749
  });
682
750
  }
683
751
  }
@@ -688,7 +756,7 @@ class h {
688
756
  for (const n of this.parser.associations.keys())
689
757
  if (n.isMesh) {
690
758
  const o = this.parser.associations.get(n);
691
- o?.meshes === s && h.registerMesh(this.url, r.guid, n, r.lods.length, o.primitives, r);
759
+ o?.meshes === s && p.registerMesh(this.url, r.guid, n, r.lods.length, o.primitives, r);
692
760
  }
693
761
  }
694
762
  }
@@ -707,16 +775,16 @@ class h {
707
775
  */
708
776
  static registerTexture = (t, e, s, r, n) => {
709
777
  if (!e) {
710
- f && console.error("!! gltf-progressive: Called register texture without texture");
778
+ h && console.error("!! gltf-progressive: Called register texture without texture");
711
779
  return;
712
780
  }
713
- if (f) {
714
- const u = e.image?.width || e.source?.data?.width || 0, a = e.image?.height || e.source?.data?.height || 0;
715
- console.log(`> gltf-progressive: register texture[${r}] "${e.name || e.uuid}", Current: ${u}x${a}, Max: ${n.lods[0]?.width}x${n.lods[0]?.height}, uuid: ${e.uuid}`, n, e);
781
+ if (h) {
782
+ const { width: a, height: l } = Le(e);
783
+ console.log(`> gltf-progressive: register texture[${r}] "${e.name || e.uuid}", Current: ${a}x${l}, Max: ${n.lods[0]?.width}x${n.lods[0]?.height}, uuid: ${e.uuid}`, n, e);
716
784
  }
717
785
  e.source && (e.source[de] = n);
718
786
  const o = n.guid;
719
- h.assignLODInformation(t, e, o, s, r), h.lodInfos.set(o, n), h.lowresCache.set(o, new WeakRef(e));
787
+ p.assignLODInformation(t, e, o, s, r), p.lodInfos.set(o, n), p.lowresCache.set(o, new WeakRef(e));
720
788
  };
721
789
  /**
722
790
  * Register a mesh with progressive LOD information. This associates the mesh geometry with its LOD extension data
@@ -732,16 +800,16 @@ class h {
732
800
  * @param ext - The parsed progressive mesh extension data containing all available LOD levels with vertex/index counts and densities.
733
801
  */
734
802
  static registerMesh = (t, e, s, r, n, o) => {
735
- const u = s.geometry;
736
- if (!u) {
737
- f && console.warn("gltf-progressive: Register mesh without geometry");
803
+ const a = s.geometry;
804
+ if (!a) {
805
+ h && console.warn("gltf-progressive: Register mesh without geometry");
738
806
  return;
739
807
  }
740
- u.userData || (u.userData = {}), f && console.log("> Progressive: register mesh " + s.name, { index: n, uuid: s.uuid }, o, s), h.assignLODInformation(t, u, e, r, n), h.lodInfos.set(e, o);
741
- let l = h.lowresCache.get(e)?.deref();
742
- l ? l.push(s.geometry) : l = [s.geometry], h.lowresCache.set(e, new WeakRef(l)), r > 0 && !ne(s) && dt(s, u);
743
- for (const c of E)
744
- c.onRegisteredNewMesh?.(s, o);
808
+ a.userData || (a.userData = {}), h && console.log("> Progressive: register mesh " + s.name, { index: n, uuid: s.uuid }, o, s), p.assignLODInformation(t, a, e, r, n), p.lodInfos.set(e, o);
809
+ let u = p.lowresCache.get(e)?.deref();
810
+ u ? u.push(s.geometry) : u = [s.geometry], p.lowresCache.set(e, new WeakRef(u)), r > 0 && !ne(s) && Mt(s, a);
811
+ for (const f of E)
812
+ f.onRegisteredNewMesh?.(s, o);
745
813
  };
746
814
  /**
747
815
  * Dispose cached resources to free memory.
@@ -782,7 +850,7 @@ class h {
782
850
  this.lowresCache.clear();
783
851
  for (const [, e] of this.cache)
784
852
  this._disposeCacheEntry(e);
785
- this.cache.clear(), this.textureRefCounts.clear(), this.trackedTextureSlots = /* @__PURE__ */ new WeakMap(), this.pendingTextureSlotRequests = /* @__PURE__ */ new WeakMap();
853
+ this.cache.clear(), this.textureRefCounts.clear(), this.trackedTextureSlots = /* @__PURE__ */ new WeakMap(), this.pendingTextureSlotRequests = /* @__PURE__ */ new WeakMap(), this.latestTextureSlotRequests = /* @__PURE__ */ new WeakMap(), this.textureSlotRequestId = 0;
786
854
  }
787
855
  }
788
856
  /** Dispose a single cache entry's three.js resource(s) to free GPU memory. */
@@ -814,16 +882,16 @@ class h {
814
882
  * The held value is the cache key string used in `previouslyLoaded`.
815
883
  */
816
884
  static _resourceRegistry = new FinalizationRegistry((t) => {
817
- const e = h.cache.get(t);
818
- (f || se) && console.debug(`[gltf-progressive] Memory: Resource GC'd
819
- ${t}`), e instanceof WeakRef && (e.deref() || (h.cache.delete(t), (f || se) && console.log("[gltf-progressive] ↪ Cache entry deleted (GC)")));
885
+ const e = p.cache.get(t);
886
+ (h || se) && console.debug(`[gltf-progressive] Memory: Resource GC'd
887
+ ${t}`), e instanceof WeakRef && (e.deref() || (p.cache.delete(t), (h || se) && console.log("[gltf-progressive] ↪ Cache entry deleted (GC)")));
820
888
  });
821
889
  /**
822
890
  * Track texture usage by incrementing reference count
823
891
  */
824
892
  static trackTextureUsage(t) {
825
893
  const e = t.uuid, s = this.textureRefCounts.get(e) || 0;
826
- this.textureRefCounts.set(e, s + 1), f === "verbose" && console.log(`[gltf-progressive] Track texture ${e}, refCount: ${s} → ${s + 1}`);
894
+ this.textureRefCounts.set(e, s + 1), h === "verbose" && console.log(`[gltf-progressive] Track texture ${e}, refCount: ${s} → ${s + 1}`);
827
895
  }
828
896
  /**
829
897
  * Untrack texture usage by decrementing reference count.
@@ -833,147 +901,155 @@ ${t}`), e instanceof WeakRef && (e.deref() || (h.cache.delete(t), (f || se) && c
833
901
  static untrackTextureUsage(t) {
834
902
  const e = t.uuid, s = this.textureRefCounts.get(e);
835
903
  if (!s)
836
- return (f === "verbose" || se) && n("[gltf-progressive] Memory: Untrack untracked texture (dispose immediately)", 0), t.dispose(), !0;
904
+ return (h === "verbose" || se) && n("[gltf-progressive] Memory: Untrack untracked texture (dispose immediately)", 0), t.dispose(), !0;
837
905
  const r = s - 1;
838
906
  if (r <= 0)
839
- return this.textureRefCounts.delete(e), (f || se) && n("[gltf-progressive] Memory: Dispose texture", r), t.dispose(), !0;
840
- return this.textureRefCounts.set(e, r), f === "verbose" && n("[gltf-progressive] Memory: Untrack texture", r), !1;
841
- function n(o, u) {
842
- const a = t.image?.width || t.source?.data?.width || 0, l = t.image?.height || t.source?.data?.height || 0, c = a && l ? `${a}x${l}` : "N/A";
843
- let d = "N/A";
844
- a && l && (d = `~${(lt(t) / (1024 * 1024)).toFixed(2)} MB`), console.log(`${o} — ${t.name} ${c} (${d}), refCount: ${s} → ${u}
907
+ return this.textureRefCounts.delete(e), (h || se) && n("[gltf-progressive] Memory: Dispose texture", r), t.dispose(), !0;
908
+ return this.textureRefCounts.set(e, r), h === "verbose" && n("[gltf-progressive] Memory: Untrack texture", r), !1;
909
+ function n(o, a) {
910
+ let { width: l, height: u } = Le(t);
911
+ const f = l && u ? `${l}x${u}` : "N/A";
912
+ let c = "N/A";
913
+ l && u && (c = `~${(vt(t) / (1024 * 1024)).toFixed(2)} MB`), console.log(`${o} — ${t.name} ${f} (${c}), refCount: ${s} → ${a}
845
914
  ${e}`);
846
915
  }
847
916
  }
848
917
  static workers = [];
849
918
  static _workersIndex = 0;
850
- static async getOrLoadLOD(t, e) {
851
- const s = f == "verbose", r = this.getAssignedLODInformation(t);
852
- if (!r)
853
- return f && console.warn(`[gltf-progressive] No LOD information found: ${t.name}, uuid: ${t.uuid}, type: ${t.type}`, t), null;
854
- const n = r?.key;
855
- let o;
919
+ static async getOrLoadLOD(t, e, s) {
920
+ const r = h == "verbose", n = this.getAssignedLODInformation(t);
921
+ if (!n)
922
+ return h && console.warn(`[gltf-progressive] No LOD information found: ${t.name}, uuid: ${t.uuid}, type: ${t.type}`, t), null;
923
+ const o = n?.key;
924
+ let a;
856
925
  if (t.isTexture === !0) {
857
- const a = t;
858
- a.source && a.source[de] && (o = a.source[de]);
926
+ const u = t;
927
+ u.source && u.source[de] && (a = u.source[de]);
859
928
  }
860
- if (o || (o = h.lodInfos.get(n)), !o)
861
- f && console.warn(`Can not load LOD ${e}: no LOD info found for "${n}" ${t.name}`, t.type, h.lodInfos);
929
+ if (a || (a = p.lodInfos.get(o)), !a)
930
+ h && console.warn(`Can not load LOD ${e}: no LOD info found for "${o}" ${t.name}`, t.type, p.lodInfos);
862
931
  else {
863
932
  if (e > 0) {
864
933
  let c = !1;
865
- const d = Array.isArray(o.lods);
866
- if (d && e >= o.lods.length ? c = !0 : d || (c = !0), c) {
867
- const g = this.lowresCache.get(n);
934
+ const d = Array.isArray(a.lods);
935
+ if (d && e >= a.lods.length ? c = !0 : d || (c = !0), c) {
936
+ const g = this.lowresCache.get(o);
868
937
  if (g) {
869
- const m = g.deref();
870
- if (m) return m;
871
- this.lowresCache.delete(n), f && console.log(`[gltf-progressive] Lowres cache entry was GC'd: ${n}`);
938
+ const b = g.deref();
939
+ if (b) return b;
940
+ this.lowresCache.delete(o), h && console.log(`[gltf-progressive] Lowres cache entry was GC'd: ${o}`);
872
941
  }
873
942
  return null;
874
943
  }
875
944
  }
876
- const a = Array.isArray(o.lods) ? o.lods[e]?.path : o.lods;
877
- if (!a)
878
- return f && !o["missing:uri"] && (o["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + e, o)), null;
879
- const l = it(r.url, a);
880
- if (l.endsWith(".glb") || l.endsWith(".gltf")) {
881
- if (!o.guid)
882
- return console.warn("missing pointer for glb/gltf texture", o), null;
883
- const c = l + "_" + o.guid, d = await this.tryResolveLODCacheEntry(this.cache.get(c), c, l, t, e, s);
945
+ const u = Array.isArray(a.lods) ? a.lods[e]?.path : a.lods;
946
+ if (!u)
947
+ return h && !a["missing:uri"] && (a["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + e, a)), null;
948
+ const f = wt(n.url, u);
949
+ if (f.endsWith(".glb") || f.endsWith(".gltf")) {
950
+ if (!a.guid)
951
+ return console.warn("missing pointer for glb/gltf texture", a), null;
952
+ const c = f + "_" + a.guid, d = await this.tryResolveLODCacheEntry(this.cache.get(c), c, f, t, e, r);
884
953
  if (d.found) return d.value;
885
- const g = await this.queue.slot(l), m = await this.tryResolveLODCacheEntry(this.cache.get(c), c, l, t, e, s);
886
- if (m.found) return m.value;
954
+ if (s?.isCurrent?.() === !1)
955
+ return r && console.log(`Skipping stale LOD ${e} request before queue: ${f}`), null;
956
+ const g = await this.queue.slot(f);
957
+ if (s?.isCurrent?.() === !1)
958
+ return r && console.log(`Skipping stale LOD ${e} request after queue: ${f}`), null;
959
+ const b = await this.tryResolveLODCacheEntry(this.cache.get(c), c, f, t, e, r);
960
+ if (b.found) return b.value;
887
961
  if (!g.use)
888
- return f && console.log(`LOD ${e} was aborted: ${l}`), null;
889
- const x = o, v = new Promise(async (_, C) => {
890
- if (xt) {
891
- const y = await (await mt({})).load(l);
892
- if (y.textures.length > 0)
893
- for (const M of y.textures) {
894
- let b = M.texture;
895
- return h.assignLODInformation(r.url, b, n, e, void 0), t instanceof G && (b = this.copySettings(t, b)), b && (b.guid = x.guid), _(b);
962
+ return h && console.log(`LOD ${e} was aborted: ${f}`), null;
963
+ const y = a, x = new Promise(async (L, V) => {
964
+ if (Pt) {
965
+ const m = await (await Rt({})).load(f);
966
+ if (m.textures.length > 0)
967
+ for (const _ of m.textures) {
968
+ let M = _.texture;
969
+ return p.assignLODInformation(n.url, M, o, e, void 0), t instanceof q && (M = this.copySettings(t, M)), M && (M.guid = y.guid), L(M);
896
970
  }
897
- if (y.geometries.length > 0) {
898
- const M = new Array();
899
- for (const b of y.geometries) {
900
- const B = b.geometry;
901
- h.assignLODInformation(r.url, B, n, e, b.primitiveIndex), M.push(B);
971
+ if (m.geometries.length > 0) {
972
+ const _ = new Array();
973
+ for (const M of m.geometries) {
974
+ const G = M.geometry;
975
+ p.assignLODInformation(n.url, G, o, e, M.primitiveIndex), _.push(G);
902
976
  }
903
- return _(M);
977
+ return L(_);
904
978
  }
905
- return _(null);
979
+ return L(null);
906
980
  }
907
- const W = new we();
908
- Ae(W), f && (await new Promise((D) => setTimeout(D, 1e3)), s && console.warn("Start loading (delayed) " + l, x.guid));
909
- let L = l;
910
- if (x && Array.isArray(x.lods)) {
911
- const D = x.lods[e];
912
- D.hash && (L += "?v=" + D.hash);
981
+ const w = new De();
982
+ Ge(w), h && (await new Promise((T) => setTimeout(T, 1e3)), r && console.warn("Start loading (delayed) " + f, y.guid));
983
+ let O = f;
984
+ if (y && Array.isArray(y.lods)) {
985
+ const T = y.lods[e];
986
+ T.hash && (O += "?v=" + T.hash);
913
987
  }
914
- const w = await W.loadAsync(L).catch((D) => (console.error(`Error loading LOD ${e} from ${l}
915
- `, D), _(null)));
916
- if (!w)
917
- return _(null);
918
- const S = w.parser;
919
- s && console.log("Loading finished " + l, x.guid);
920
- let O = 0;
921
- if (w.parser.json.textures) {
922
- let D = !1;
923
- for (const y of w.parser.json.textures) {
924
- if (y?.extensions) {
925
- const M = y?.extensions[F];
926
- if (M?.guid && M.guid === x.guid) {
927
- D = !0;
988
+ const D = await w.loadAsync(O).catch((T) => (console.error(`Error loading LOD ${e} from ${f}
989
+ `, T), L(null)));
990
+ if (!D)
991
+ return L(null);
992
+ const k = D.parser;
993
+ r && console.log("Loading finished " + f, y.guid);
994
+ let R = 0;
995
+ if (D.parser.json.textures) {
996
+ let T = !1;
997
+ for (const m of D.parser.json.textures) {
998
+ if (m?.extensions) {
999
+ const _ = m?.extensions[F];
1000
+ if (_?.guid && _.guid === y.guid) {
1001
+ T = !0;
928
1002
  break;
929
1003
  }
930
1004
  }
931
- O++;
1005
+ R++;
932
1006
  }
933
- if (D) {
934
- let y = await S.getDependency("texture", O);
935
- return y && h.assignLODInformation(r.url, y, n, e, void 0), s && console.log('change "' + t.name + '" → "' + y.name + '"', l, O, y, c), t instanceof G && (y = this.copySettings(t, y)), y && (y.guid = x.guid), _(y);
936
- } else f && console.warn("Could not find texture with guid", x.guid, w.parser.json);
1007
+ if (T) {
1008
+ let m = await k.getDependency("texture", R);
1009
+ return m && p.assignLODInformation(n.url, m, o, e, void 0), r && console.log('change "' + t.name + '" → "' + m.name + '"', f, R, m, c), t instanceof q && (m = this.copySettings(t, m)), m && (m.guid = y.guid), L(m);
1010
+ } else h && console.warn("Could not find texture with guid", y.guid, D.parser.json);
937
1011
  }
938
- if (O = 0, w.parser.json.meshes) {
939
- let D = !1;
940
- for (const y of w.parser.json.meshes) {
941
- if (y?.extensions) {
942
- const M = y?.extensions[F];
943
- if (M?.guid && M.guid === x.guid) {
944
- D = !0;
1012
+ if (R = 0, D.parser.json.meshes) {
1013
+ let T = !1;
1014
+ for (const m of D.parser.json.meshes) {
1015
+ if (m?.extensions) {
1016
+ const _ = m?.extensions[F];
1017
+ if (_?.guid && _.guid === y.guid) {
1018
+ T = !0;
945
1019
  break;
946
1020
  }
947
1021
  }
948
- O++;
1022
+ R++;
949
1023
  }
950
- if (D) {
951
- const y = await S.getDependency("mesh", O);
952
- if (s && console.log(`Loaded Mesh "${y.name}"`, l, O, y, c), y.isMesh === !0) {
953
- const M = y.geometry;
954
- return h.assignLODInformation(r.url, M, n, e, 0), _(M);
1024
+ if (T) {
1025
+ const m = await k.getDependency("mesh", R);
1026
+ if (r && console.log(`Loaded Mesh "${m.name}"`, f, R, m, c), m.isMesh === !0) {
1027
+ const _ = m.geometry;
1028
+ return p.assignLODInformation(n.url, _, o, e, 0), L(_);
955
1029
  } else {
956
- const M = new Array();
957
- for (let b = 0; b < y.children.length; b++) {
958
- const B = y.children[b];
959
- if (B.isMesh === !0) {
960
- const V = B.geometry;
961
- h.assignLODInformation(r.url, V, n, e, b), M.push(V);
1030
+ const _ = new Array();
1031
+ for (let M = 0; M < m.children.length; M++) {
1032
+ const G = m.children[M];
1033
+ if (G.isMesh === !0) {
1034
+ const ie = G.geometry;
1035
+ p.assignLODInformation(n.url, ie, o, e, M), _.push(ie);
962
1036
  }
963
1037
  }
964
- return _(M);
1038
+ return L(_);
965
1039
  }
966
- } else f && console.warn("Could not find mesh with guid", x.guid, w.parser.json);
1040
+ } else h && console.warn("Could not find mesh with guid", y.guid, D.parser.json);
967
1041
  }
968
- return _(null);
1042
+ return L(null);
969
1043
  });
970
- this.cache.set(c, v), g.use(v);
971
- const p = await v;
972
- return p != null ? p instanceof G ? (this.cache.set(c, new WeakRef(p)), h._resourceRegistry.register(p, c)) : Array.isArray(p) ? this.cache.set(c, Promise.resolve(p)) : this.cache.set(c, Promise.resolve(p)) : this.cache.set(c, Promise.resolve(null)), p;
973
- } else if (t instanceof G) {
974
- s && console.log("Load texture from uri: " + l);
975
- const d = await new je().loadAsync(l);
976
- return d ? (d.guid = o.guid, d.flipY = !1, d.needsUpdate = !0, d.colorSpace = t.colorSpace, s && console.log(o, d)) : f && console.warn("failed loading", l), d;
1044
+ this.cache.set(c, x), g.use(x);
1045
+ const v = await x;
1046
+ return v != null ? v instanceof q ? (this.cache.set(c, new WeakRef(v)), p._resourceRegistry.register(v, c)) : Array.isArray(v) ? this.cache.set(c, Promise.resolve(v)) : this.cache.set(c, Promise.resolve(v)) : this.cache.set(c, Promise.resolve(null)), v;
1047
+ } else if (t instanceof q) {
1048
+ if (s?.isCurrent?.() === !1)
1049
+ return r && console.log(`Skipping stale texture LOD ${e} request: ${f}`), null;
1050
+ r && console.log("Load texture from uri: " + f);
1051
+ const d = await new it().loadAsync(f);
1052
+ return s?.isCurrent?.() === !1 ? (d?.dispose(), null) : (d ? (d.guid = a.guid, d.flipY = !1, d.needsUpdate = !0, d.colorSpace = t.colorSpace, r && console.log(a, d)) : h && console.warn("failed loading", f), d);
977
1053
  }
978
1054
  }
979
1055
  return null;
@@ -982,26 +1058,26 @@ ${e}`);
982
1058
  if (t === void 0)
983
1059
  return { found: !1 };
984
1060
  if (o && console.log(`LOD ${n} was already loading/loaded: ${e}`), t instanceof WeakRef) {
985
- const l = t.deref();
986
- if (l) {
987
- let c = l, d = !1;
988
- if (c instanceof G && r instanceof G ? c.image?.data || c.source?.data ? c = this.copySettings(r, c) : d = !0 : c instanceof j && r instanceof j && (c.attributes.position?.array || (d = !0)), !d)
989
- return { found: !0, value: c };
1061
+ const u = t.deref();
1062
+ if (u) {
1063
+ let f = u, c = !1;
1064
+ if (f instanceof q && r instanceof q ? Oe(f.image) || we(f) ? f = this.copySettings(r, f) : c = !0 : f instanceof j && r instanceof j && (f.attributes.position?.array || (c = !0)), !c)
1065
+ return { found: !0, value: f };
990
1066
  }
991
- return this.cache.delete(e), f && console.log(`[gltf-progressive] Re-loading GC'd/disposed resource: ${e}`), { found: !1 };
1067
+ return this.cache.delete(e), h && console.log(`[gltf-progressive] Re-loading GC'd/disposed resource: ${e}`), { found: !1 };
992
1068
  }
993
- let u = await t.catch((l) => (console.error(`Error loading LOD ${n} from ${s}
994
- `, l), null)), a = !1;
995
- return u == null || (u instanceof G && r instanceof G ? u.image?.data || u.source?.data ? u = this.copySettings(r, u) : (a = !0, this.cache.delete(e)) : u instanceof j && r instanceof j && (u.attributes.position?.array || (a = !0, this.cache.delete(e)))), a ? { found: !1 } : { found: !0, value: u };
1069
+ let a = await t.catch((u) => (console.error(`Error loading LOD ${n} from ${s}
1070
+ `, u), null)), l = !1;
1071
+ return a == null || (a instanceof q && r instanceof q ? Oe(a.image) || we(a) ? a = this.copySettings(r, a) : (l = !0, this.cache.delete(e)) : a instanceof j && r instanceof j && (a.attributes.position?.array || (l = !0, this.cache.delete(e)))), l ? { found: !1 } : { found: !0, value: a };
996
1072
  }
997
1073
  static _queue;
998
1074
  static get queue() {
999
- return this._queue ??= new at(ve() ? 20 : 50, { debug: f != !1 });
1075
+ return this._queue ??= new Lt(Me() ? 20 : 50, { debug: h != !1 });
1000
1076
  }
1001
1077
  static assignLODInformation(t, e, s, r, n) {
1002
1078
  if (!e) return;
1003
1079
  e.userData || (e.userData = {});
1004
- const o = new wt(t, s, r, n);
1080
+ const o = new kt(t, s, r, n);
1005
1081
  e.userData.LODS = o, "source" in e && typeof e.source == "object" && (e.source.LODS = o);
1006
1082
  }
1007
1083
  static getAssignedLODInformation(t) {
@@ -1009,12 +1085,12 @@ ${e}`);
1009
1085
  }
1010
1086
  // private static readonly _copiedTextures: WeakMap<Texture, Texture> = new Map();
1011
1087
  static copySettings(t, e) {
1012
- return e ? (f === "verbose" && console.debug(`Copy texture settings
1088
+ return e ? (h === "verbose" && console.debug(`Copy texture settings
1013
1089
  `, t.uuid, `
1014
1090
  `, e.uuid), e = e.clone(), e.offset = t.offset, e.repeat = t.repeat, e.colorSpace = t.colorSpace, e.magFilter = t.magFilter, e.minFilter = t.minFilter, e.wrapS = t.wrapS, e.wrapT = t.wrapT, e.flipY = t.flipY, e.anisotropy = t.anisotropy, e.mipmaps || (e.generateMipmaps = t.generateMipmaps), e) : t;
1015
1091
  }
1016
1092
  }
1017
- class wt {
1093
+ class kt {
1018
1094
  url;
1019
1095
  /** the key to lookup the LOD information */
1020
1096
  key;
@@ -1074,7 +1150,7 @@ class oe {
1074
1150
  _seen = /* @__PURE__ */ new WeakMap();
1075
1151
  add(t, e, s) {
1076
1152
  if (this._resolved) {
1077
- f && console.warn("PromiseGroup: Trying to add a promise to a resolved group, ignoring.");
1153
+ h && console.warn("PromiseGroup: Trying to add a promise to a resolved group, ignoring.");
1078
1154
  return;
1079
1155
  }
1080
1156
  if (!(this._frame_start !== void 0 && this._currentFrame > this._frame_start + this._frames_to_capture)) {
@@ -1082,7 +1158,7 @@ class oe {
1082
1158
  if (this._seen.has(e)) {
1083
1159
  const r = this._seen.get(e);
1084
1160
  if (r >= this._maxPromisesPerObject) {
1085
- f && console.warn("PromiseGroup: Already awaiting object ignoring new promise for it.");
1161
+ h && console.warn("PromiseGroup: Already awaiting object ignoring new promise for it.");
1086
1162
  return;
1087
1163
  }
1088
1164
  this._seen.set(e, r + 1);
@@ -1101,7 +1177,7 @@ class oe {
1101
1177
  });
1102
1178
  }
1103
1179
  }
1104
- const A = N("debugprogressive"), Lt = A === "colors", vt = N("noprogressive"), fe = /* @__PURE__ */ Symbol("Needle:LODSManager"), he = /* @__PURE__ */ Symbol("Needle:LODState"), q = /* @__PURE__ */ Symbol("Needle:CurrentLOD"), T = { mesh_lod: -1, texture_lod: -1 }, _t = new Ce(), Me = [
1180
+ const A = N("debugprogressive"), At = A === "colors", It = N("noprogressive"), he = /* @__PURE__ */ Symbol("Needle:LODSManager"), ge = /* @__PURE__ */ Symbol("Needle:LODState"), U = /* @__PURE__ */ Symbol("Needle:CurrentLOD"), Te = Xe, S = { mesh_lod: -1, texture_lod: -1 }, $t = new Ie(), Se = [
1105
1181
  3526751,
1106
1182
  11065402,
1107
1183
  15978811,
@@ -1134,12 +1210,17 @@ const A = N("debugprogressive"), Lt = A === "colors", vt = N("noprogressive"), f
1134
1210
  15817653,
1135
1211
  5083278,
1136
1212
  5592405
1137
- ], ge = new le(), z = new le(), De = new le(), Mt = new k(), Dt = new k(), bt = new Pe(), U = new k(), H = new k(), Q = new k(), J = new k();
1138
- function Ot(i, t) {
1213
+ ];
1214
+ function Bt() {
1215
+ const i = Te.Timer || Te.Clock;
1216
+ return new i();
1217
+ }
1218
+ const pe = new ue(), z = new ue(), Re = new ue(), Gt = new P(), qt = new P(), Wt = new $e(), W = new P(), H = new P(), Q = new P(), J = new P();
1219
+ function Ft(i, t) {
1139
1220
  const e = i.min, s = i.max, r = (e.x + s.x) * 0.5, n = (e.y + s.y) * 0.5;
1140
- return U.set(r, n, e.z).applyMatrix4(t).z < 0;
1221
+ return W.set(r, n, e.z).applyMatrix4(t).z < 0;
1141
1222
  }
1142
- function Tt(i) {
1223
+ function Ut(i) {
1143
1224
  const {
1144
1225
  geometry: t,
1145
1226
  matrixWorld: e,
@@ -1147,59 +1228,59 @@ function Tt(i) {
1147
1228
  projectionScreenMatrix: r,
1148
1229
  desiredDensity: n,
1149
1230
  canvasHeight: o = 0,
1150
- currentLevel: u = -1,
1151
- xrEnabled: a = !1,
1152
- debugDrawLine: l,
1153
- warnMissingPrimitiveDensities: c = !1
1154
- } = i, d = h.getMeshLODExtension(t)?.lods, g = h.getPrimitiveIndex(t), m = i.target ?? {
1155
- level: u,
1156
- primitiveIndex: g,
1231
+ currentLevel: a = -1,
1232
+ xrEnabled: l = !1,
1233
+ debugDrawLine: u,
1234
+ warnMissingPrimitiveDensities: f = !1
1235
+ } = i, c = p.getMeshLODExtension(t)?.lods, d = p.getPrimitiveIndex(t), g = i.target ?? {
1236
+ level: a,
1237
+ primitiveIndex: d,
1157
1238
  screenCoverage: 0,
1158
- screenspaceVolume: new k(),
1239
+ screenspaceVolume: new P(),
1159
1240
  centrality: 1
1160
1241
  };
1161
- if (m.level = u, m.primitiveIndex = g, m.screenCoverage = 0, m.screenspaceVolume.set(0, 0, 0), m.centrality = 1, !d?.length) return m;
1162
- let x = i.boundingBox ?? t.boundingBox;
1163
- if (x || (t.computeBoundingBox(), x = t.boundingBox), !x) return m;
1164
- if (ge.copy(x).applyMatrix4(e), s.isPerspectiveCamera && Ot(ge, r))
1165
- return m.level = 0, m.screenCoverage = 1 / 0, m.screenspaceVolume.set(1 / 0, 1 / 0, 1 / 0), m;
1166
- if (z.copy(ge).applyMatrix4(r), a && s.isPerspectiveCamera && s.fov > 70) {
1167
- const L = z.min, w = z.max;
1168
- let S = L.x, O = L.y, D = w.x, y = w.y;
1169
- const M = 2, b = 1.5, B = (L.x + w.x) * 0.5, V = (L.y + w.y) * 0.5;
1170
- S = (S - B) * M + B, O = (O - V) * M + V, D = (D - B) * M + B, y = (y - V) * M + V;
1171
- const Fe = S < 0 && D > 0 ? 0 : Math.min(Math.abs(L.x), Math.abs(w.x)), qe = O < 0 && y > 0 ? 0 : Math.min(Math.abs(L.y), Math.abs(w.y)), ue = Math.max(Fe, qe);
1172
- m.centrality = (b - ue) * (b - ue) * (b - ue);
1173
- }
1174
- const v = z.getSize(Mt);
1175
- v.multiplyScalar(0.5), globalThis.screen?.availHeight > 0 && o > 0 && v.multiplyScalar(o / globalThis.screen.availHeight), s.isPerspectiveCamera && (v.x *= s.aspect), De.copy(x).applyMatrix4(e).applyMatrix4(s.matrixWorldInverse);
1176
- const p = De.getSize(Dt), _ = Math.max(v.x, v.y), C = Math.max(p.x, p.y);
1177
- _ !== 0 && C !== 0 && (v.z = p.z / C * _);
1178
- const W = Math.max(v.x, v.y, v.z) * m.centrality;
1179
- if (m.screenCoverage = W, m.screenspaceVolume.copy(v), W <= 0) return m;
1180
- if (l) {
1181
- const L = bt.copy(r);
1182
- L.invert(), U.copy(z.min), H.copy(z.max), H.x = U.x, Q.copy(z.max), Q.y = U.y, J.copy(z.max);
1183
- const w = (U.z + J.z) * 0.5;
1184
- U.z = H.z = Q.z = J.z = w, U.applyMatrix4(L), H.applyMatrix4(L), Q.applyMatrix4(L), J.applyMatrix4(L), l(U, H, 255), l(U, Q, 255), l(H, J, 255), l(Q, J, 255);
1185
- }
1186
- for (let L = 0; L < d.length; L++) {
1187
- const w = d[L], S = w.densities?.[g] || w.density || 1e-5;
1188
- if (g > 0 && c && $e() && !w.densities && !globalThis["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"] && (globalThis["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"] = !0, console.warn("[Needle Progressive] Detected usage of mesh without primitive densities. This might cause incorrect LOD level selection: Consider re-optimizing your model by updating your Needle Integration, Needle glTF Pipeline or running optimization again on Needle Cloud.")), S / W < n) {
1189
- m.level = L;
1242
+ if (g.level = a, g.primitiveIndex = d, g.screenCoverage = 0, g.screenspaceVolume.set(0, 0, 0), g.centrality = 1, !c?.length) return g;
1243
+ let b = i.boundingBox ?? t.boundingBox;
1244
+ if (b || (t.computeBoundingBox(), b = t.boundingBox), !b) return g;
1245
+ if (pe.copy(b).applyMatrix4(e), s.isPerspectiveCamera && Ft(pe, r))
1246
+ return g.level = 0, g.screenCoverage = 1 / 0, g.screenspaceVolume.set(1 / 0, 1 / 0, 1 / 0), g;
1247
+ if (z.copy(pe).applyMatrix4(r), l && s.isPerspectiveCamera && s.fov > 70) {
1248
+ const w = z.min, O = z.max;
1249
+ let D = w.x, k = w.y, R = O.x, T = O.y;
1250
+ const m = 2, _ = 1.5, M = (w.x + O.x) * 0.5, G = (w.y + O.y) * 0.5;
1251
+ D = (D - M) * m + M, k = (k - G) * m + G, R = (R - M) * m + M, T = (T - G) * m + G;
1252
+ const ie = D < 0 && R > 0 ? 0 : Math.min(Math.abs(w.x), Math.abs(O.x)), Ve = k < 0 && T > 0 ? 0 : Math.min(Math.abs(w.y), Math.abs(O.y)), ce = Math.max(ie, Ve);
1253
+ g.centrality = (_ - ce) * (_ - ce) * (_ - ce);
1254
+ }
1255
+ const y = z.getSize(Gt);
1256
+ y.multiplyScalar(0.5), globalThis.screen?.availHeight > 0 && o > 0 && y.multiplyScalar(o / globalThis.screen.availHeight), s.isPerspectiveCamera && (y.x *= s.aspect), Re.copy(b).applyMatrix4(e).applyMatrix4(s.matrixWorldInverse);
1257
+ const x = Re.getSize(qt), v = Math.max(y.x, y.y), L = Math.max(x.x, x.y);
1258
+ v !== 0 && L !== 0 && (y.z = x.z / L * v);
1259
+ const V = Math.max(y.x, y.y, y.z) * g.centrality;
1260
+ if (g.screenCoverage = V, g.screenspaceVolume.copy(y), V <= 0) return g;
1261
+ if (u) {
1262
+ const w = Wt.copy(r);
1263
+ w.invert(), W.copy(z.min), H.copy(z.max), H.x = W.x, Q.copy(z.max), Q.y = W.y, J.copy(z.max);
1264
+ const O = (W.z + J.z) * 0.5;
1265
+ W.z = H.z = Q.z = J.z = O, W.applyMatrix4(w), H.applyMatrix4(w), Q.applyMatrix4(w), J.applyMatrix4(w), u(W, H, 255), u(W, Q, 255), u(H, J, 255), u(Q, J, 255);
1266
+ }
1267
+ for (let w = 0; w < c.length; w++) {
1268
+ const O = c[w], D = O.densities?.[d] || O.density || 1e-5;
1269
+ if (d > 0 && f && Fe() && !O.densities && !globalThis["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"] && (globalThis["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"] = !0, console.warn("[Needle Progressive] Detected usage of mesh without primitive densities. This might cause incorrect LOD level selection: Consider re-optimizing your model by updating your Needle Integration, Needle glTF Pipeline or running optimization again on Needle Cloud.")), D / V < n) {
1270
+ g.level = w;
1190
1271
  break;
1191
1272
  }
1192
1273
  }
1193
- return m;
1274
+ return g;
1194
1275
  }
1195
- class R {
1276
+ class I {
1196
1277
  /**
1197
1278
  * Assign a function to draw debug lines for the LODs. This function will be called with the start and end position of the line and the color of the line when the `debugprogressive` query parameter is set.
1198
1279
  */
1199
1280
  static debugDrawLine;
1200
1281
  /** @internal */
1201
1282
  static getObjectLODState(t) {
1202
- return t[he];
1283
+ return t[ge];
1203
1284
  }
1204
1285
  static addPlugin(t) {
1205
1286
  E.push(t);
@@ -1214,17 +1295,17 @@ class R {
1214
1295
  * @returns The LODsManager instance.
1215
1296
  */
1216
1297
  static get(t, e) {
1217
- if (t[fe])
1218
- return console.debug("[gltf-progressive] LODsManager already exists for this renderer"), t[fe];
1219
- const s = new R(t, {
1298
+ if (t[he])
1299
+ return console.debug("[gltf-progressive] LODsManager already exists for this renderer"), t[he];
1300
+ const s = new I(t, {
1220
1301
  engine: "unknown",
1221
1302
  ...e
1222
1303
  });
1223
- return t[fe] = s, s;
1304
+ return t[he] = s, s;
1224
1305
  }
1225
1306
  renderer;
1226
1307
  context;
1227
- projectionScreenMatrix = new Pe();
1308
+ projectionScreenMatrix = new $e();
1228
1309
  /** @deprecated use static `LODsManager.addPlugin()` method. This getter will be removed in later versions */
1229
1310
  get plugins() {
1230
1311
  return E;
@@ -1297,7 +1378,7 @@ class R {
1297
1378
  const r = performance.now();
1298
1379
  return s.ready.finally(() => {
1299
1380
  const n = this._newPromiseGroups.indexOf(s);
1300
- n >= 0 && (this._newPromiseGroups.splice(n, 1), $e() && performance.measure("LODsManager:awaitLoading", {
1381
+ n >= 0 && (this._newPromiseGroups.splice(n, 1), Fe() && performance.measure("LODsManager:awaitLoading", {
1301
1382
  start: r,
1302
1383
  detail: { id: e, name: t?.name, awaited: s.awaitedCount, resolved: s.resolvedCount }
1303
1384
  }));
@@ -1353,11 +1434,11 @@ class R {
1353
1434
  this.renderer = t, this.context = { ...e };
1354
1435
  }
1355
1436
  #t;
1356
- #o = new Ke();
1357
1437
  #r = 0;
1358
1438
  #n = 0;
1359
- #i = 0;
1439
+ #o = 0;
1360
1440
  #s = 0;
1441
+ #i = Bt();
1361
1442
  _fpsBuffer = [60, 60, 60, 60, 60];
1362
1443
  /**
1363
1444
  * Enable the LODsManager. This will replace the render method of the renderer with a method that updates the LODs.
@@ -1368,9 +1449,9 @@ class R {
1368
1449
  let t = 0;
1369
1450
  this.#t = this.renderer.render;
1370
1451
  const e = this;
1371
- Le(this.renderer), this.renderer.render = function(s, r) {
1452
+ _e(this.renderer), this.renderer.render = function(s, r) {
1372
1453
  const n = e.renderer.getRenderTarget();
1373
- (n == null || "isXRRenderTarget" in n && n.isXRRenderTarget) && (t = 0, e.#r += 1, e.#n = e.#o.getDelta(), e.#i += e.#n, e._fpsBuffer.shift(), e._fpsBuffer.push(1 / e.#n), e.#s = e._fpsBuffer.reduce((u, a) => u + a) / e._fpsBuffer.length, A && e.#r % 200 === 0 && console.log("FPS", Math.round(e.#s), "Interval:", e.#e));
1454
+ (n == null || "isXRRenderTarget" in n && n.isXRRenderTarget) && (t = 0, e.#r += 1, e.#i.update?.(), e.#n = Math.max(e.#i.getDelta(), 1 / 1e3), e.#o += e.#n, e._fpsBuffer.shift(), e._fpsBuffer.push(1 / e.#n), e.#s = e._fpsBuffer.reduce((a, l) => a + l) / e._fpsBuffer.length, A && e.#r % 200 === 0 && console.log("FPS", Math.round(e.#s), "Interval:", e.#e));
1374
1455
  const o = t++;
1375
1456
  e.#t.call(this, s, r), e.onAfterRender(s, r, o);
1376
1457
  };
@@ -1398,14 +1479,16 @@ class R {
1398
1479
  }
1399
1480
  onAfterRender(t, e, s) {
1400
1481
  if (this.pause) return;
1401
- const n = this.renderer.renderLists.get(t, 0).opaque;
1482
+ const r = this.getRenderList(t, e, s);
1483
+ if (!r) return;
1484
+ const n = r.opaque;
1402
1485
  let o = !0;
1403
1486
  if (n.length === 1) {
1404
- const u = n[0].material;
1405
- (u.name === "EffectMaterial" || u.name === "CopyShader") && (o = !1);
1487
+ const a = n[0].material;
1488
+ (a.name === "EffectMaterial" || a.name === "CopyShader") && (o = !1);
1406
1489
  }
1407
1490
  if ((e.parent && e.parent.type === "CubeCamera" || s >= 1 && e.type === "OrthographicCamera") && (o = !1), o) {
1408
- if (vt || (this.updateInterval === "auto" ? this.#s < 40 && this.#e < 10 ? (this.#e += 1, A && console.warn("↓ Reducing LOD updates", this.#e, this.#s.toFixed(0))) : this.#s >= 60 && this.#e > 1 && (this.#e -= 1, A && console.warn("↑ Increasing LOD updates", this.#e, this.#s.toFixed(0))) : this.#e = this.updateInterval, this.#e > 0 && this.#r % this.#e != 0))
1491
+ if (It || (this.updateInterval === "auto" ? this.#s < 40 && this.#e < 10 ? (this.#e += 1, A && console.warn("↓ Reducing LOD updates", this.#e, this.#s.toFixed(0))) : this.#s >= 60 && this.#e > 1 && (this.#e -= 1, A && console.warn("↑ Increasing LOD updates", this.#e, this.#s.toFixed(0))) : this.#e = this.updateInterval, this.#e > 0 && this.#r % this.#e != 0))
1409
1492
  return;
1410
1493
  this.internalUpdate(t, e), this._postprocessPromiseGroups();
1411
1494
  }
@@ -1414,15 +1497,17 @@ class R {
1414
1497
  * Update LODs in a scene
1415
1498
  */
1416
1499
  internalUpdate(t, e) {
1417
- const s = this.renderer.renderLists.get(t, 0), r = s.opaque;
1500
+ const s = this.getRenderList(t, e, 0);
1501
+ if (!s) return;
1502
+ const r = s.opaque;
1418
1503
  this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix, e.matrixWorldInverse);
1419
1504
  const n = this.targetTriangleDensity;
1420
- for (const a of r) {
1421
- if (a.material && (a.geometry?.type === "BoxGeometry" || a.geometry?.type === "BufferGeometry") && (a.material.name === "SphericalGaussianBlur" || a.material.name == "BackgroundCubeMaterial" || a.material.name === "CubemapFromEquirect" || a.material.name === "EquirectangularToCubeUV")) {
1422
- A && (a.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"] || (a.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"] = !0, console.warn("Ignoring skybox or BLIT object", a, a.material.name, a.material.type)));
1505
+ for (const l of r) {
1506
+ if (l.material && (l.geometry?.type === "BoxGeometry" || l.geometry?.type === "BufferGeometry") && (l.material.name === "SphericalGaussianBlur" || l.material.name == "BackgroundCubeMaterial" || l.material.name === "CubemapFromEquirect" || l.material.name === "EquirectangularToCubeUV")) {
1507
+ A && (l.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"] || (l.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"] = !0, console.warn("Ignoring skybox or BLIT object", l, l.material.name, l.material.type)));
1423
1508
  continue;
1424
1509
  }
1425
- switch (a.material.type) {
1510
+ switch (l.material.type) {
1426
1511
  case "LineBasicMaterial":
1427
1512
  case "LineDashedMaterial":
1428
1513
  case "PointsMaterial":
@@ -1431,33 +1516,52 @@ class R {
1431
1516
  case "MeshDepthMaterial":
1432
1517
  continue;
1433
1518
  }
1434
- const l = a.object;
1435
- (l instanceof K || l.isMesh) && this.updateLODs(t, e, l, n);
1519
+ const u = l.object;
1520
+ (u instanceof K || u.isMesh) && this.updateLODs(t, e, u, n);
1436
1521
  }
1437
1522
  const o = s.transparent;
1438
- for (const a of o) {
1439
- const l = a.object;
1440
- (l instanceof K || l.isMesh) && this.updateLODs(t, e, l, n);
1523
+ for (const l of o) {
1524
+ const u = l.object;
1525
+ (u instanceof K || u.isMesh) && this.updateLODs(t, e, u, n);
1441
1526
  }
1442
- const u = s.transmissive;
1443
- for (const a of u) {
1444
- const l = a.object;
1445
- (l instanceof K || l.isMesh) && this.updateLODs(t, e, l, n);
1527
+ const a = s.transmissive;
1528
+ for (const l of a) {
1529
+ const u = l.object;
1530
+ (u instanceof K || u.isMesh) && this.updateLODs(t, e, u, n);
1446
1531
  }
1447
1532
  }
1533
+ getRenderList(t, e, s) {
1534
+ const r = this.renderer;
1535
+ let n = null;
1536
+ if (r.isWebGPURenderer === !0) {
1537
+ const o = r._renderLists;
1538
+ if (!o) return null;
1539
+ n = o.get(t, e);
1540
+ } else if (r.isWebGLRenderer === !0) {
1541
+ const o = r.renderLists;
1542
+ if (!o) return null;
1543
+ n = o.get(t, s);
1544
+ }
1545
+ return n ? {
1546
+ opaque: n.opaque || [],
1547
+ transparent: n.transparent || [],
1548
+ transmissive: n.transmissive || n.transparentDoublePass || [],
1549
+ transparentDoublePass: n.transparentDoublePass || []
1550
+ } : null;
1551
+ }
1448
1552
  /** Update the LOD levels for the renderer. */
1449
1553
  updateLODs(t, e, s, r) {
1450
1554
  s.userData || (s.userData = {});
1451
- let n = s[he];
1452
- if (n || (n = new St(), s[he] = n), n.frames++ < 2)
1555
+ let n = s[ge];
1556
+ if (n || (n = new zt(), s[ge] = n), n.frames++ < 2)
1453
1557
  return;
1454
- for (const u of E)
1455
- u.onBeforeUpdateLOD?.(this.renderer, t, e, s);
1558
+ for (const a of E)
1559
+ a.onBeforeUpdateLOD?.(this.renderer, t, e, s);
1456
1560
  const o = this.overrideLodLevel !== void 0 ? this.overrideLodLevel : X;
1457
- o >= 0 ? (T.mesh_lod = o, T.texture_lod = o) : (this.calculateLodLevel(e, s, n, r, T), T.mesh_lod = Math.round(T.mesh_lod), T.texture_lod = Math.round(T.texture_lod)), T.mesh_lod >= 0 && this.loadProgressiveMeshes(s, T.mesh_lod), s.material && T.texture_lod >= 0 && this.loadProgressiveTextures(s.material, T.texture_lod, o), f && s.material && !s.isGizmo && Be(s.material), Lt && s.material && !s.isGizmo && !s.isBatchedMesh && Ge(s.material, T.mesh_lod);
1458
- for (const u of E)
1459
- u.onAfterUpdatedLOD?.(this.renderer, t, e, s, T);
1460
- n.lastLodLevel_Mesh = T.mesh_lod, n.lastLodLevel_Texture = T.texture_lod;
1561
+ o >= 0 ? (S.mesh_lod = o, S.texture_lod = o) : (this.calculateLodLevel(e, s, n, r, S), S.mesh_lod = Math.round(S.mesh_lod), S.texture_lod = Math.round(S.texture_lod)), S.mesh_lod >= 0 && this.loadProgressiveMeshes(s, S.mesh_lod), s.material && S.texture_lod >= 0 && this.loadProgressiveTextures(s.material, S.texture_lod, o), h && s.material && !s.isGizmo && Ue(s.material), At && s.material && !s.isGizmo && !s.isBatchedMesh && ze(s.material, S.mesh_lod);
1562
+ for (const a of E)
1563
+ a.onAfterUpdatedLOD?.(this.renderer, t, e, s, S);
1564
+ n.lastLodLevel_Mesh = S.mesh_lod, n.lastLodLevel_Texture = S.texture_lod;
1461
1565
  }
1462
1566
  /** Load progressive textures for the given material
1463
1567
  * @param material the material to load the textures for
@@ -1472,14 +1576,14 @@ class R {
1472
1576
  return;
1473
1577
  }
1474
1578
  let r = !1;
1475
- (t[q] === void 0 || e < t[q]) && (r = !0);
1579
+ (t[U] === void 0 || e < t[U]) && (r = !0);
1476
1580
  const n = s !== void 0 && s >= 0;
1477
- if (n && (r = t[q] != s, e = s), r) {
1478
- t[q] = e;
1479
- const o = n ? { force: !0 } : void 0, u = h.assignTextureLOD(t, e, o).then((a) => {
1480
- this._lodchangedlisteners.forEach((l) => l({ type: "texture", level: e, object: t }));
1581
+ if (n && (r = t[U] != s, e = s), r) {
1582
+ t[U] = e;
1583
+ const o = n ? { force: !0 } : void 0, a = p.assignTextureLOD(t, e, o).then((l) => {
1584
+ this._lodchangedlisteners.forEach((u) => u({ type: "texture", level: e, object: t }));
1481
1585
  });
1482
- oe.addPromise("texture", t, u, this._newPromiseGroups);
1586
+ oe.addPromise("texture", t, a, this._newPromiseGroups);
1483
1587
  }
1484
1588
  }
1485
1589
  /** Load progressive meshes for the given mesh
@@ -1490,18 +1594,18 @@ class R {
1490
1594
  */
1491
1595
  loadProgressiveMeshes(t, e) {
1492
1596
  if (!t) return Promise.resolve(null);
1493
- let s = t[q] !== e;
1597
+ let s = t[U] !== e;
1494
1598
  const r = t["DEBUG:LOD"];
1495
- if (r != null && (s = t[q] != r, e = r), s) {
1496
- t[q] = e;
1497
- const n = t.geometry, o = h.assignMeshLOD(t, e).then((u) => (u && t[q] == e && n != t.geometry && this._lodchangedlisteners.forEach((a) => a({ type: "mesh", level: e, object: t })), u));
1599
+ if (r != null && (s = t[U] != r, e = r), s) {
1600
+ t[U] = e;
1601
+ const n = t.geometry, o = p.assignMeshLOD(t, e).then((a) => (a && t[U] == e && n != t.geometry && this._lodchangedlisteners.forEach((l) => l({ type: "mesh", level: e, object: t })), a));
1498
1602
  return oe.addPromise("mesh", t, o, this._newPromiseGroups), o;
1499
1603
  }
1500
1604
  return Promise.resolve(null);
1501
1605
  }
1502
1606
  // private testIfLODLevelsAreAvailable() {
1503
- _sphere = new Se();
1504
- _tempWorldPosition = new k();
1607
+ _sphere = new Ae();
1608
+ _tempWorldPosition = new P();
1505
1609
  static skinnedMeshBoundsFrameOffsetCounter = 0;
1506
1610
  static $skinnedMeshBoundsOffset = /* @__PURE__ */ Symbol("gltf-progressive-skinnedMeshBoundsOffset");
1507
1611
  // #region calculateLodLevel
@@ -1514,86 +1618,86 @@ class R {
1514
1618
  n.mesh_lod = -1, n.texture_lod = -1;
1515
1619
  return;
1516
1620
  }
1517
- let u = 10 + 1, a = !1;
1621
+ let a = 10 + 1, l = !1;
1518
1622
  if (A && e["DEBUG:LOD"] != null)
1519
1623
  return e["DEBUG:LOD"];
1520
- const l = h.getMeshLODExtension(e.geometry)?.lods, c = h.getPrimitiveIndex(e.geometry), d = l && l.length > 0, g = h.getMaterialMinMaxLODsCount(e.material), m = g.min_count !== 1 / 0 && g.min_count >= 0 && g.max_count >= 0;
1521
- if (!d && !m) {
1624
+ const u = p.getMeshLODExtension(e.geometry)?.lods, f = p.getPrimitiveIndex(e.geometry), c = u && u.length > 0, d = p.getMaterialMinMaxLODsCount(e.material), g = d.min_count !== 1 / 0 && d.min_count >= 0 && d.max_count >= 0;
1625
+ if (!c && !g) {
1522
1626
  n.mesh_lod = 0, n.texture_lod = 0;
1523
1627
  return;
1524
1628
  }
1525
- d || (a = !0, u = 0);
1526
- const x = this.renderer.domElement.clientHeight || this.renderer.domElement.height;
1527
- let v = e.geometry.boundingBox;
1629
+ c || (l = !0, a = 0);
1630
+ const b = this.renderer.domElement.clientHeight || this.renderer.domElement.height;
1631
+ let y = e.geometry.boundingBox;
1528
1632
  if (e.type === "SkinnedMesh") {
1529
- const p = e;
1530
- if (!p.boundingBox)
1531
- p.computeBoundingBox();
1633
+ const x = e;
1634
+ if (!x.boundingBox)
1635
+ x.computeBoundingBox();
1532
1636
  else if (this.skinnedMeshAutoUpdateBoundsInterval > 0) {
1533
- if (!p[R.$skinnedMeshBoundsOffset]) {
1534
- const C = R.skinnedMeshBoundsFrameOffsetCounter++;
1535
- p[R.$skinnedMeshBoundsOffset] = C;
1637
+ if (!x[I.$skinnedMeshBoundsOffset]) {
1638
+ const L = I.skinnedMeshBoundsFrameOffsetCounter++;
1639
+ x[I.$skinnedMeshBoundsOffset] = L;
1536
1640
  }
1537
- const _ = p[R.$skinnedMeshBoundsOffset];
1538
- if ((s.frames + _) % this.skinnedMeshAutoUpdateBoundsInterval === 0) {
1539
- const C = ne(p), W = p.geometry;
1540
- C && (p.geometry = C), p.computeBoundingBox(), p.geometry = W;
1641
+ const v = x[I.$skinnedMeshBoundsOffset];
1642
+ if ((s.frames + v) % this.skinnedMeshAutoUpdateBoundsInterval === 0) {
1643
+ const L = ne(x), V = x.geometry;
1644
+ L && (x.geometry = L), x.computeBoundingBox(), x.geometry = V;
1541
1645
  }
1542
1646
  }
1543
- v = p.boundingBox;
1647
+ y = x.boundingBox;
1544
1648
  }
1545
- if (v) {
1649
+ if (y) {
1546
1650
  if (e.geometry.attributes.color && e.geometry.attributes.color.count < 100 && e.geometry.boundingSphere) {
1547
1651
  this._sphere.copy(e.geometry.boundingSphere), this._sphere.applyMatrix4(e.matrixWorld);
1548
- const C = t.getWorldPosition(this._tempWorldPosition);
1549
- if (this._sphere.containsPoint(C)) {
1652
+ const L = t.getWorldPosition(this._tempWorldPosition);
1653
+ if (this._sphere.containsPoint(L)) {
1550
1654
  n.mesh_lod = 0, n.texture_lod = 0;
1551
1655
  return;
1552
1656
  }
1553
1657
  }
1554
- const p = Tt({
1658
+ const x = Ut({
1555
1659
  geometry: e.geometry,
1556
1660
  matrixWorld: e.matrixWorld,
1557
1661
  camera: t,
1558
1662
  projectionScreenMatrix: this.projectionScreenMatrix,
1559
1663
  desiredDensity: r,
1560
- canvasHeight: x,
1664
+ canvasHeight: b,
1561
1665
  currentLevel: s.lastLodLevel_Mesh,
1562
- boundingBox: v,
1666
+ boundingBox: y,
1563
1667
  xrEnabled: this.renderer.xr.enabled,
1564
- debugDrawLine: A ? R.debugDrawLine : void 0,
1668
+ debugDrawLine: A ? I.debugDrawLine : void 0,
1565
1669
  warnMissingPrimitiveDensities: !0
1566
1670
  });
1567
- if (s.lastCentrality = p.centrality, s.lastScreenCoverage = p.screenCoverage, s.lastScreenspaceVolume.copy(p.screenspaceVolume), p.screenCoverage === 1 / 0) {
1671
+ if (s.lastCentrality = x.centrality, s.lastScreenCoverage = x.screenCoverage, s.lastScreenspaceVolume.copy(x.screenspaceVolume), x.screenCoverage === 1 / 0) {
1568
1672
  n.mesh_lod = 0, n.texture_lod = 0;
1569
1673
  return;
1570
1674
  }
1571
- p.level >= 0 && p.level < u && (u = p.level, a = !0);
1675
+ x.level >= 0 && x.level < a && (a = x.level, l = !0);
1572
1676
  }
1573
- if (a ? n.mesh_lod = u : n.mesh_lod = s.lastLodLevel_Mesh, A && n.mesh_lod != s.lastLodLevel_Mesh) {
1574
- const _ = l?.[n.mesh_lod];
1575
- _ && console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} → ${n.mesh_lod} (density: ${_.densities?.[c].toFixed(0)}) | ${e.name}`);
1677
+ if (l ? n.mesh_lod = a : n.mesh_lod = s.lastLodLevel_Mesh, A && n.mesh_lod != s.lastLodLevel_Mesh) {
1678
+ const v = u?.[n.mesh_lod];
1679
+ v && console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} → ${n.mesh_lod} (density: ${v.densities?.[f].toFixed(0)}) | ${e.name}`);
1576
1680
  }
1577
- if (m) {
1578
- const p = "saveData" in globalThis.navigator && globalThis.navigator.saveData === !0;
1681
+ if (g) {
1682
+ const x = "saveData" in globalThis.navigator && globalThis.navigator.saveData === !0;
1579
1683
  if (s.lastLodLevel_Texture < 0) {
1580
- if (n.texture_lod = g.max_count - 1, A) {
1581
- const _ = g.lods[g.max_count - 1];
1582
- A && console.log(`First Texture LOD ${n.texture_lod} (${_.max_height}px) - ${e.name}`);
1684
+ if (n.texture_lod = d.max_count - 1, A) {
1685
+ const v = d.lods[d.max_count - 1];
1686
+ A && console.log(`First Texture LOD ${n.texture_lod} (${v.max_height}px) - ${e.name}`);
1583
1687
  }
1584
1688
  } else {
1585
- const _ = s.lastScreenspaceVolume.x + s.lastScreenspaceVolume.y + s.lastScreenspaceVolume.z;
1586
- let C = s.lastScreenCoverage * 4;
1587
- this.context?.engine === "model-viewer" && (C *= 1.5);
1588
- const L = x / window.devicePixelRatio * C;
1589
- let w = !1;
1590
- for (let S = g.lods.length - 1; S >= 0; S--) {
1591
- const O = g.lods[S];
1592
- if (!(p && O.max_height >= 2048) && !(ve() && O.max_height > 4096) && (O.max_height > L || !w && S === 0)) {
1593
- if (w = !0, n.texture_lod = S, A && n.texture_lod < s.lastLodLevel_Texture) {
1594
- const D = O.max_height;
1595
- console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${n.texture_lod} = ${D}px
1596
- Screensize: ${L.toFixed(0)}px, Coverage: ${(100 * s.lastScreenCoverage).toFixed(2)}%, Volume ${_.toFixed(1)}
1689
+ const v = s.lastScreenspaceVolume.x + s.lastScreenspaceVolume.y + s.lastScreenspaceVolume.z;
1690
+ let L = s.lastScreenCoverage * 4;
1691
+ this.context?.engine === "model-viewer" && (L *= 1.5);
1692
+ const w = b / window.devicePixelRatio * L;
1693
+ let O = !1;
1694
+ for (let D = d.lods.length - 1; D >= 0; D--) {
1695
+ const k = d.lods[D];
1696
+ if (!(x && k.max_height >= 2048) && !(Me() && k.max_height > 4096) && (k.max_height > w || !O && D === 0)) {
1697
+ if (O = !0, n.texture_lod = D, A && n.texture_lod < s.lastLodLevel_Texture) {
1698
+ const R = k.max_height;
1699
+ console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${n.texture_lod} = ${R}px
1700
+ Screensize: ${w.toFixed(0)}px, Coverage: ${(100 * s.lastScreenCoverage).toFixed(2)}%, Volume ${v.toFixed(1)}
1597
1701
  ${e.name}`);
1598
1702
  }
1599
1703
  break;
@@ -1604,74 +1708,74 @@ ${e.name}`);
1604
1708
  n.texture_lod = 0;
1605
1709
  }
1606
1710
  }
1607
- class St {
1711
+ class zt {
1608
1712
  frames = 0;
1609
1713
  lastLodLevel_Mesh = -1;
1610
1714
  lastLodLevel_Texture = -1;
1611
1715
  lastScreenCoverage = 0;
1612
- lastScreenspaceVolume = new k();
1716
+ lastScreenspaceVolume = new P();
1613
1717
  lastCentrality = 0;
1614
1718
  }
1615
- function Ge(i, t) {
1719
+ function ze(i, t) {
1616
1720
  if (!(t < 0)) {
1617
1721
  if (Array.isArray(i)) {
1618
1722
  for (const e of i)
1619
- Ge(e, t);
1723
+ ze(e, t);
1620
1724
  return;
1621
1725
  }
1622
- "color" in i && i.color instanceof Ce && (i.color.copy(Ct(t, _t)), i.needsUpdate = !0);
1726
+ "color" in i && i.color instanceof Ie && (i.color.copy(Et(t, $t)), i.needsUpdate = !0);
1623
1727
  }
1624
1728
  }
1625
- function Ct(i, t) {
1626
- const e = Math.max(0, Math.min(Me.length - 1, Math.floor(i)));
1627
- return t.setHex(Me[e]);
1729
+ function Et(i, t) {
1730
+ const e = Math.max(0, Math.min(Se.length - 1, Math.floor(i)));
1731
+ return t.setHex(Se[e]);
1628
1732
  }
1629
- const be = /* @__PURE__ */ Symbol("NEEDLE_mesh_lod"), ie = /* @__PURE__ */ Symbol("NEEDLE_texture_lod");
1630
- let pe = null;
1631
- function We() {
1632
- const i = Pt();
1733
+ const Ce = /* @__PURE__ */ Symbol("NEEDLE_mesh_lod"), ae = /* @__PURE__ */ Symbol("NEEDLE_texture_lod");
1734
+ let me = null;
1735
+ function Ee() {
1736
+ const i = Nt();
1633
1737
  i && (i.mapURLs(function(t) {
1634
- return Oe(), t;
1635
- }), Oe(), pe?.disconnect(), pe = new MutationObserver((t) => {
1738
+ return Pe(), t;
1739
+ }), Pe(), me?.disconnect(), me = new MutationObserver((t) => {
1636
1740
  t.forEach((e) => {
1637
1741
  e.addedNodes.forEach((s) => {
1638
- s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" && Ue(s);
1742
+ s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" && Ne(s);
1639
1743
  });
1640
1744
  });
1641
- }), pe.observe(document, { childList: !0, subtree: !0 }));
1745
+ }), me.observe(document, { childList: !0, subtree: !0 }));
1642
1746
  }
1643
- function Pt() {
1747
+ function Nt() {
1644
1748
  if (typeof customElements > "u") return null;
1645
1749
  const i = customElements.get("model-viewer");
1646
1750
  return i || (customElements.whenDefined("model-viewer").then(() => {
1647
- console.debug("[gltf-progressive] model-viewer defined"), We();
1751
+ console.debug("[gltf-progressive] model-viewer defined"), Ee();
1648
1752
  }), null);
1649
1753
  }
1650
- function Oe() {
1754
+ function Pe() {
1651
1755
  if (typeof document > "u") return;
1652
1756
  document.querySelectorAll("model-viewer").forEach((t) => {
1653
- Ue(t);
1757
+ Ne(t);
1654
1758
  });
1655
1759
  }
1656
- const Te = /* @__PURE__ */ new WeakSet();
1657
- let kt = 0;
1658
- function Ue(i) {
1659
- if (!i || Te.has(i))
1760
+ const ke = /* @__PURE__ */ new WeakSet();
1761
+ let Vt = 0;
1762
+ function Ne(i) {
1763
+ if (!i || ke.has(i))
1660
1764
  return null;
1661
- Te.add(i), console.debug("[gltf-progressive] found new model-viewer..." + ++kt + `
1765
+ ke.add(i), console.debug("[gltf-progressive] found new model-viewer..." + ++Vt + `
1662
1766
  `, i.getAttribute("src"));
1663
1767
  let t = null, e = null, s = null;
1664
1768
  for (let r = i; r != null; r = Object.getPrototypeOf(r)) {
1665
- const n = Object.getOwnPropertySymbols(r), o = n.find((l) => l.toString() == "Symbol(renderer)"), u = n.find((l) => l.toString() == "Symbol(scene)"), a = n.find((l) => l.toString() == "Symbol(needsRender)");
1666
- !t && o != null && (t = i[o].threeRenderer), !e && u != null && (e = i[u]), !s && a != null && (s = i[a]);
1769
+ const n = Object.getOwnPropertySymbols(r), o = n.find((u) => u.toString() == "Symbol(renderer)"), a = n.find((u) => u.toString() == "Symbol(scene)"), l = n.find((u) => u.toString() == "Symbol(needsRender)");
1770
+ !t && o != null && (t = i[o].threeRenderer), !e && a != null && (e = i[a]), !s && l != null && (s = i[l]);
1667
1771
  }
1668
1772
  if (t && e) {
1669
1773
  let r = function() {
1670
1774
  if (s) {
1671
1775
  let o = 0;
1672
- const u = setInterval(() => {
1776
+ const a = setInterval(() => {
1673
1777
  if (o++ > 5) {
1674
- clearInterval(u);
1778
+ clearInterval(a);
1675
1779
  return;
1676
1780
  }
1677
1781
  s?.call(i);
@@ -1679,8 +1783,8 @@ function Ue(i) {
1679
1783
  }
1680
1784
  };
1681
1785
  console.debug("[gltf-progressive] setup model-viewer");
1682
- const n = R.get(t, { engine: "model-viewer" });
1683
- return R.addPlugin(new At()), n.enable(), n.addEventListener("changed", () => {
1786
+ const n = I.get(t, { engine: "model-viewer" });
1787
+ return I.addPlugin(new Xt()), n.enable(), n.addEventListener("changed", () => {
1684
1788
  s?.call(i);
1685
1789
  }), i.addEventListener("model-visibility", (o) => {
1686
1790
  o.detail.visible && s?.call(i);
@@ -1692,7 +1796,7 @@ function Ue(i) {
1692
1796
  }
1693
1797
  return null;
1694
1798
  }
1695
- class At {
1799
+ class Xt {
1696
1800
  _didWarnAboutMissingUrl = !1;
1697
1801
  onBeforeUpdateLOD(t, e, s, r) {
1698
1802
  this.tryParseMeshLOD(e, r), this.tryParseTextureLOD(e, r);
@@ -1710,50 +1814,50 @@ class At {
1710
1814
  return t.element;
1711
1815
  }
1712
1816
  tryParseTextureLOD(t, e) {
1713
- if (e[ie] == !0) return;
1714
- e[ie] = !0;
1817
+ if (e[ae] == !0) return;
1818
+ e[ae] = !0;
1715
1819
  const s = this.tryGetCurrentGLTF(t), r = this.tryGetCurrentModelViewer(t), n = this.getUrl(r);
1716
1820
  if (n && s && e.material) {
1717
- let o = function(a) {
1718
- if (a[ie] == !0) return;
1719
- a[ie] = !0, a.userData && (a.userData.LOD = -1);
1720
- const l = Object.keys(a);
1721
- for (let c = 0; c < l.length; c++) {
1722
- const d = l[c], g = a[d];
1723
- if (g?.isTexture === !0) {
1724
- const m = g.userData?.associations?.textures;
1725
- if (m == null) continue;
1726
- const x = s.parser.json.textures[m];
1727
- if (!x) {
1728
- console.warn("Texture data not found for texture index " + m);
1821
+ let o = function(l) {
1822
+ if (l[ae] == !0) return;
1823
+ l[ae] = !0, l.userData && (l.userData.LOD = -1);
1824
+ const u = Object.keys(l);
1825
+ for (let f = 0; f < u.length; f++) {
1826
+ const c = u[f], d = l[c];
1827
+ if (d?.isTexture === !0) {
1828
+ const g = d.userData?.associations?.textures;
1829
+ if (g == null) continue;
1830
+ const b = s.parser.json.textures[g];
1831
+ if (!b) {
1832
+ console.warn("Texture data not found for texture index " + g);
1729
1833
  continue;
1730
1834
  }
1731
- if (x?.extensions?.[F]) {
1732
- const v = x.extensions[F];
1733
- v && n && h.registerTexture(n, g, v.lods.length, m, v);
1835
+ if (b?.extensions?.[F]) {
1836
+ const y = b.extensions[F];
1837
+ y && n && p.registerTexture(n, d, y.lods.length, g, y);
1734
1838
  }
1735
1839
  }
1736
1840
  }
1737
1841
  };
1738
- const u = e.material;
1739
- if (Array.isArray(u)) for (const a of u) o(a);
1740
- else o(u);
1842
+ const a = e.material;
1843
+ if (Array.isArray(a)) for (const l of a) o(l);
1844
+ else o(a);
1741
1845
  }
1742
1846
  }
1743
1847
  tryParseMeshLOD(t, e) {
1744
- if (e[be] == !0) return;
1745
- e[be] = !0;
1848
+ if (e[Ce] == !0) return;
1849
+ e[Ce] = !0;
1746
1850
  const s = this.tryGetCurrentModelViewer(t), r = this.getUrl(s);
1747
1851
  if (!r)
1748
1852
  return;
1749
1853
  const n = e.userData?.gltfExtensions?.[F];
1750
1854
  if (n && r) {
1751
1855
  const o = e.uuid;
1752
- h.registerMesh(r, o, e, 0, n.lods.length, n);
1856
+ p.registerMesh(r, o, e, 0, n.lods.length, n);
1753
1857
  }
1754
1858
  }
1755
1859
  }
1756
- function Rt(...i) {
1860
+ function jt(...i) {
1757
1861
  let t, e, s, r;
1758
1862
  switch (i.length) {
1759
1863
  case 2:
@@ -1768,22 +1872,22 @@ function Rt(...i) {
1768
1872
  default:
1769
1873
  throw new Error("Invalid arguments");
1770
1874
  }
1771
- Le(e), Ae(s), Ie(s, {
1875
+ _e(e), Ge(s), We(s, {
1772
1876
  progressive: !0,
1773
1877
  ...r?.hints
1774
- }), s.register((o) => new h(o));
1775
- const n = R.get(e);
1878
+ }), s.register((o) => new p(o));
1879
+ const n = I.get(e);
1776
1880
  return r?.enableLODsManager !== !1 && n.enable(), n;
1777
1881
  }
1778
- We();
1779
- if (!ct) {
1882
+ Ee();
1883
+ if (!_t) {
1780
1884
  const i = {
1781
1885
  gltfProgressive: {
1782
- useNeedleProgressive: Rt,
1783
- LODsManager: R,
1784
- configureLoader: Ie,
1886
+ useNeedleProgressive: jt,
1887
+ LODsManager: I,
1888
+ configureLoader: We,
1785
1889
  getRaycastMesh: ne,
1786
- useRaycastMeshes: ft
1890
+ useRaycastMeshes: bt
1787
1891
  }
1788
1892
  };
1789
1893
  if (!globalThis.Needle)
@@ -1794,20 +1898,20 @@ if (!ct) {
1794
1898
  }
1795
1899
  export {
1796
1900
  F as EXTENSION_NAME,
1797
- R as LODsManager,
1798
- h as NEEDLE_progressive,
1799
- Je as VERSION,
1800
- Ae as addDracoAndKTX2Loaders,
1801
- Tt as calculateMeshLODLevel,
1802
- Ie as configureLoader,
1803
- Le as createLoaders,
1804
- Ct as getLODColor,
1901
+ I as LODsManager,
1902
+ p as NEEDLE_progressive,
1903
+ ut as VERSION,
1904
+ Ge as addDracoAndKTX2Loaders,
1905
+ Ut as calculateMeshLODLevel,
1906
+ We as configureLoader,
1907
+ _e as createLoaders,
1908
+ Et as getLODColor,
1805
1909
  ne as getRaycastMesh,
1806
- Me as lodDebugColors,
1807
- We as patchModelViewer,
1808
- dt as registerRaycastMesh,
1809
- st as setDracoDecoderLocation,
1810
- rt as setKTX2TranscoderLocation,
1811
- Rt as useNeedleProgressive,
1812
- ft as useRaycastMeshes
1910
+ Se as lodDebugColors,
1911
+ Ee as patchModelViewer,
1912
+ Mt as registerRaycastMesh,
1913
+ ht as setDracoDecoderLocation,
1914
+ gt as setKTX2TranscoderLocation,
1915
+ jt as useNeedleProgressive,
1916
+ bt as useRaycastMeshes
1813
1917
  };