@needle-tools/gltf-progressive 3.6.0-alpha.1 → 3.6.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,69 +1,69 @@
1
- import { BufferGeometry as V, Mesh as X, Box3 as ge, Vector3 as P, Sphere as Oe, CompressedTexture as Ue, Texture as W, Matrix3 as ze, InterleavedBuffer as qe, InterleavedBufferAttribute as Ne, BufferAttribute as Ee, TextureLoader as Ve, Color as ke, Matrix4 as ve, Clock as Xe } from "three";
2
- import { GLTFLoader as xe } from "three/examples/jsm/loaders/GLTFLoader.js";
3
- import { MeshoptDecoder as Ke } from "three/examples/jsm/libs/meshopt_decoder.module.js";
4
- import { DRACOLoader as Ye } from "three/examples/jsm/loaders/DRACOLoader.js";
5
- import { KTX2Loader as je } from "three/examples/jsm/loaders/KTX2Loader.js";
6
- const He = "";
7
- globalThis.GLTF_PROGRESSIVE_VERSION = He;
1
+ import { BufferGeometry as j, Mesh as K, Box3 as ue, Vector3 as P, Sphere as Ce, CompressedTexture as ze, Texture as q, Matrix3 as Ee, InterleavedBuffer as Ne, InterleavedBufferAttribute as Ve, BufferAttribute as Xe, TextureLoader as je, Color as ke, Matrix4 as Pe, Clock as Ke } from "three";
2
+ import { GLTFLoader as Le } 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;
8
8
  console.debug("[gltf-progressive] version -");
9
- let I = "https://www.gstatic.com/draco/versioned/decoders/1.5.7/", K = "https://cdn.needle.tools/static/three/0.179.1/basis2/";
10
- const Qe = I, Je = K, Ce = new URL(I + "draco_decoder.js");
11
- Ce.searchParams.append("range", "true");
12
- fetch(Ce, {
9
+ let $ = "https://www.gstatic.com/draco/versioned/decoders/1.5.7/", Y = "https://cdn.needle.tools/static/three/0.179.1/basis2/";
10
+ const Ze = $, et = Y, Re = new URL($ + "draco_decoder.js");
11
+ Re.searchParams.append("range", "true");
12
+ fetch(Re, {
13
13
  method: "GET",
14
14
  headers: {
15
15
  Range: "bytes=0-1"
16
16
  }
17
17
  }).catch((i) => {
18
- console.debug(`Failed to fetch remote Draco decoder from ${I} (offline: ${typeof navigator < "u" ? navigator.onLine : "unknown"})`), I === Qe && et("./include/draco/"), K === Je && tt("./include/ktx2/");
18
+ console.debug(`Failed to fetch remote Draco decoder from ${$} (offline: ${typeof navigator < "u" ? navigator.onLine : "unknown"})`), $ === Ze && st("./include/draco/"), Y === et && rt("./include/ktx2/");
19
19
  }).finally(() => {
20
- Ae();
20
+ Ie();
21
21
  });
22
- const Ze = () => ({
23
- dracoDecoderPath: I,
24
- ktx2TranscoderPath: K
22
+ const tt = () => ({
23
+ dracoDecoderPath: $,
24
+ ktx2TranscoderPath: Y
25
25
  });
26
- function et(i) {
27
- I = i, k && k[pe] != I ? (console.debug("Updating Draco decoder path to " + i), k[pe] = I, k.setDecoderPath(I), k.preload()) : console.debug("Setting Draco decoder path to " + i);
26
+ function st(i) {
27
+ $ = i, k && k[ye] != $ ? (console.debug("Updating Draco decoder path to " + i), k[ye] = $, k.setDecoderPath($), k.preload()) : console.debug("Setting Draco decoder path to " + i);
28
28
  }
29
- function tt(i) {
30
- K = i, $ && $.transcoderPath != K ? (console.debug("Updating KTX2 transcoder path to " + i), $.setTranscoderPath(K), $.init()) : console.debug("Setting KTX2 transcoder path to " + i);
29
+ function rt(i) {
30
+ 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
31
  }
32
- function we(i) {
33
- return Ae(), i ? $.detectSupport(i) : i !== null && console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"), { dracoLoader: k, ktx2Loader: $, meshoptDecoder: oe };
32
+ function ve(i) {
33
+ return Ie(), i ? B.detectSupport(i) : i !== null && console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"), { dracoLoader: k, ktx2Loader: B, meshoptDecoder: le };
34
34
  }
35
- function Pe(i) {
36
- i.dracoLoader || i.setDRACOLoader(k), i.ktx2Loader || i.setKTX2Loader($), i.meshoptDecoder || i.setMeshoptDecoder(oe);
35
+ function Ae(i) {
36
+ i.dracoLoader || i.setDRACOLoader(k), i.ktx2Loader || i.setKTX2Loader(B), i.meshoptDecoder || i.setMeshoptDecoder(le);
37
37
  }
38
- const pe = /* @__PURE__ */ Symbol("dracoDecoderPath");
39
- let k, oe, $;
40
- function Ae() {
41
- k || (k = new Ye(), k[pe] = I, k.setDecoderPath(I), k.setDecoderConfig({ type: "js" }), k.preload()), $ || ($ = new je(), $.setTranscoderPath(K), $.init()), oe || (oe = Ke);
38
+ const ye = /* @__PURE__ */ Symbol("dracoDecoderPath");
39
+ let k, le, B;
40
+ function Ie() {
41
+ k || (k = new He(), k[ye] = $, k.setDecoderPath($), k.setDecoderConfig({ type: "js" }), k.preload()), B || (B = new Qe(), B.setTranscoderPath(Y), B.init()), le || (le = Ye);
42
42
  }
43
- const me = /* @__PURE__ */ new WeakMap();
44
- function Re(i, t) {
45
- let e = me.get(i);
46
- e ? e = Object.assign(e, t) : e = t, me.set(i, e);
43
+ const xe = /* @__PURE__ */ new WeakMap();
44
+ function $e(i, t) {
45
+ let e = xe.get(i);
46
+ e ? e = Object.assign(e, t) : e = t, xe.set(i, e);
47
47
  }
48
- const st = xe.prototype.load;
49
- function rt(...i) {
50
- const t = me.get(this);
48
+ const nt = Le.prototype.load;
49
+ function it(...i) {
50
+ const t = xe.get(this);
51
51
  let e = i[0];
52
52
  const s = new URL(e, window.location.href);
53
53
  if (s.hostname.endsWith("needle.tools")) {
54
54
  const n = t?.progressive !== void 0 ? t.progressive : !0, o = t?.usecase ? t.usecase : "default";
55
55
  n ? this.requestHeader.Accept = `*/*;progressive=allowed;usecase=${o}` : this.requestHeader.Accept = `*/*;usecase=${o}`, e = s.toString();
56
56
  }
57
- return i[0] = e, st?.call(this, ...i);
57
+ return i[0] = e, nt?.call(this, ...i);
58
58
  }
59
- xe.prototype.load = rt;
59
+ Le.prototype.load = it;
60
60
  N("debugprogressive");
61
61
  function N(i) {
62
62
  if (typeof window > "u") return !1;
63
63
  const e = new URL(window.location.href).searchParams.get(i);
64
64
  return e == null || e === "0" || e === "false" ? !1 : e === "" ? !0 : e;
65
65
  }
66
- function nt(i, t) {
66
+ function ot(i, t) {
67
67
  if (t === void 0 || i === void 0 || t.startsWith("./") || t.startsWith("http") || t.startsWith("data:") || t.startsWith("blob:"))
68
68
  return t;
69
69
  const e = i.lastIndexOf("/");
@@ -74,16 +74,16 @@ function nt(i, t) {
74
74
  }
75
75
  return t;
76
76
  }
77
- function Le() {
78
- return j !== void 0 || (j = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent), N("debugprogressive") && console.log("[glTF Progressive]: isMobileDevice", j)), j;
77
+ function _e() {
78
+ return Z !== void 0 || (Z = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent), N("debugprogressive") && console.log("[glTF Progressive]: isMobileDevice", Z)), Z;
79
79
  }
80
- let j;
81
- function Me() {
80
+ let Z;
81
+ function Be() {
82
82
  if (typeof window > "u") return !1;
83
83
  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
84
  return i.hostname === "127.0.0.1" || t;
85
85
  }
86
- class ot {
86
+ class at {
87
87
  constructor(t, e = {}) {
88
88
  this.maxConcurrent = t, this.debug = e.debug ?? !1, typeof window < "u" && window.requestAnimationFrame(this.tick);
89
89
  }
@@ -117,11 +117,11 @@ class ot {
117
117
  }
118
118
  }
119
119
  }
120
- function it(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 = at(i);
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
122
  return t * e * s * n * (1 - Math.pow(0.25, r)) / (1 - 0.25);
123
123
  }
124
- function at(i) {
124
+ function ut(i) {
125
125
  let t = 4;
126
126
  const e = i.format;
127
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);
@@ -129,71 +129,71 @@ function at(i) {
129
129
  const r = i.type;
130
130
  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
131
  }
132
- const lt = typeof window > "u" && typeof document > "u", ye = /* @__PURE__ */ Symbol("needle:raycast-mesh");
133
- function ee(i) {
134
- return i?.[ye] instanceof V ? i[ye] : null;
132
+ const ct = typeof window > "u" && typeof document > "u", we = /* @__PURE__ */ Symbol("needle:raycast-mesh");
133
+ function ne(i) {
134
+ return i?.[we] instanceof j ? i[we] : null;
135
135
  }
136
- function ut(i, t) {
137
- if ((i.type === "Mesh" || i.type === "SkinnedMesh") && !ee(i)) {
138
- const s = dt(t);
139
- s.userData = { isRaycastMesh: !0 }, i[ye] = s;
136
+ function dt(i, t) {
137
+ if ((i.type === "Mesh" || i.type === "SkinnedMesh") && !ne(i)) {
138
+ const s = ht(t);
139
+ s.userData = { isRaycastMesh: !0 }, i[we] = s;
140
140
  }
141
141
  }
142
- function ct(i = !0) {
142
+ function ft(i = !0) {
143
143
  if (i) {
144
- if (H) return;
145
- const t = H = X.prototype.raycast;
146
- X.prototype.raycast = function(e, s) {
147
- const r = this, n = ee(r);
144
+ if (ee) return;
145
+ const t = ee = K.prototype.raycast;
146
+ K.prototype.raycast = function(e, s) {
147
+ const r = this, n = ne(r);
148
148
  let o;
149
149
  n && r.isMesh && (o = r.geometry, r.geometry = n), t.call(this, e, s), o && (r.geometry = o);
150
150
  };
151
151
  } else {
152
- if (!H) return;
153
- X.prototype.raycast = H, H = null;
152
+ if (!ee) return;
153
+ K.prototype.raycast = ee, ee = null;
154
154
  }
155
155
  }
156
- let H = null;
157
- function dt(i) {
158
- const t = new V();
156
+ let ee = null;
157
+ function ht(i) {
158
+ const t = new j();
159
159
  for (const e in i.attributes)
160
160
  t.setAttribute(e, i.getAttribute(e));
161
161
  return t.setIndex(i.getIndex()), t;
162
162
  }
163
- const q = new Array(), h = N("debugprogressive");
164
- let Z, E = -1;
163
+ const E = new Array(), h = N("debugprogressive");
164
+ let re, X = -1;
165
165
  if (h) {
166
166
  let i = function() {
167
- E += 1, E >= t && (E = -1), console.log(`Toggle LOD level [${E}]`);
167
+ X += 1, X >= t && (X = -1), console.log(`Toggle LOD level [${X}]`);
168
168
  };
169
169
  const t = 6;
170
170
  window.addEventListener("keyup", (e) => {
171
- e.key === "p" && i(), e.key === "w" && (Z = !Z, console.log(`Toggle wireframe [${Z}]`));
171
+ e.key === "p" && i(), e.key === "w" && (re = !re, console.log(`Toggle wireframe [${re}]`));
172
172
  const s = parseInt(e.key);
173
- !isNaN(s) && s >= 0 && (E = s, console.log(`Set LOD level to [${E}]`));
173
+ !isNaN(s) && s >= 0 && (X = s, console.log(`Set LOD level to [${X}]`));
174
174
  });
175
175
  }
176
- function Ie(i) {
177
- if (h && Z !== void 0)
176
+ function Ge(i) {
177
+ if (h && re !== void 0)
178
178
  if (Array.isArray(i))
179
179
  for (const t of i)
180
- Ie(t);
181
- else i && "wireframe" in i && (i.wireframe = Z === !0);
180
+ Ge(t);
181
+ else i && "wireframe" in i && (i.wireframe = re === !0);
182
182
  }
183
- const Q = new Array();
184
- let ft = 0;
185
- const ht = Le() ? 2 : 10;
186
- function gt(i) {
187
- if (Q.length < ht) {
188
- const s = Q.length;
183
+ const te = new Array();
184
+ let gt = 0;
185
+ const pt = _e() ? 2 : 10;
186
+ function mt(i) {
187
+ if (te.length < pt) {
188
+ const s = te.length;
189
189
  h && console.warn(`[Worker] Creating new worker #${s}`);
190
- const r = _e.createWorker(i || {});
191
- return Q.push(r), r;
190
+ const r = De.createWorker(i || {});
191
+ return te.push(r), r;
192
192
  }
193
- const t = ft++ % Q.length;
194
- return Q[t];
193
+ const t = gt++ % te.length;
194
+ return te[t];
195
195
  }
196
- class _e {
196
+ class De {
197
197
  constructor(t, e) {
198
198
  this.worker = t, this._debug = e.debug ?? !1, t.onmessage = (s) => {
199
199
  const r = s.data;
@@ -201,7 +201,7 @@ class _e {
201
201
  case "loaded-gltf":
202
202
  for (const n of this._running)
203
203
  if (n.url === r.result.url) {
204
- pt(r.result), n.resolve(r.result);
204
+ yt(r.result), n.resolve(r.result);
205
205
  const o = n.url;
206
206
  o.startsWith("blob:") && URL.revokeObjectURL(o);
207
207
  }
@@ -220,52 +220,52 @@ class _e {
220
220
  ), {
221
221
  type: "module"
222
222
  });
223
- return new _e(e, t);
223
+ return new De(e, t);
224
224
  }
225
225
  _running = [];
226
226
  _webglRenderer = null;
227
227
  async load(t, e) {
228
- const s = Ze();
228
+ const s = tt();
229
229
  let r = e?.renderer;
230
230
  r || (this._webglRenderer ??= (async () => {
231
- const { WebGLRenderer: l } = await import("three");
232
- return new l();
231
+ const { WebGLRenderer: u } = await import("three");
232
+ return new u();
233
233
  })(), r = await this._webglRenderer);
234
- const u = we(r).ktx2Loader.workerConfig;
234
+ const a = ve(r).ktx2Loader.workerConfig;
235
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 = {
236
+ const l = {
237
237
  type: "load",
238
238
  url: t,
239
239
  dracoDecoderPath: s.dracoDecoderPath,
240
240
  ktx2TranscoderPath: s.ktx2TranscoderPath,
241
- ktx2LoaderConfig: u
241
+ ktx2LoaderConfig: a
242
242
  };
243
- return this._debug && console.debug("[Worker] Sending load request", a), this.worker.postMessage(a), new Promise((l) => {
243
+ return this._debug && console.debug("[Worker] Sending load request", l), this.worker.postMessage(l), new Promise((u) => {
244
244
  this._running.push({
245
245
  url: t.toString(),
246
- resolve: l
246
+ resolve: u
247
247
  });
248
248
  });
249
249
  }
250
250
  _debug = !1;
251
251
  }
252
- function pt(i) {
252
+ function yt(i) {
253
253
  for (const t of i.geometries) {
254
- const e = t.geometry, s = new V();
254
+ const e = t.geometry, s = new j();
255
255
  if (s.name = e.name || "", e.index) {
256
256
  const r = e.index;
257
- s.setIndex(le(r));
257
+ s.setIndex(de(r));
258
258
  }
259
259
  for (const r in e.attributes) {
260
- const n = e.attributes[r], o = le(n);
260
+ const n = e.attributes[r], o = de(n);
261
261
  s.setAttribute(r, o);
262
262
  }
263
263
  if (e.morphAttributes)
264
264
  for (const r in e.morphAttributes) {
265
- const o = e.morphAttributes[r].map((u) => le(u));
265
+ const o = e.morphAttributes[r].map((a) => de(a));
266
266
  s.morphAttributes[r] = o;
267
267
  }
268
- if (s.morphTargetsRelative = e.morphTargetsRelative ?? !1, s.boundingBox = new ge(), s.boundingBox.min = new P(
268
+ if (s.morphTargetsRelative = e.morphTargetsRelative ?? !1, s.boundingBox = new ue(), s.boundingBox.min = new P(
269
269
  e.boundingBox?.min.x,
270
270
  e.boundingBox?.min.y,
271
271
  e.boundingBox?.min.z
@@ -273,7 +273,7 @@ function pt(i) {
273
273
  e.boundingBox?.max.x,
274
274
  e.boundingBox?.max.y,
275
275
  e.boundingBox?.max.z
276
- ), s.boundingSphere = new Oe(
276
+ ), s.boundingSphere = new Ce(
277
277
  new P(
278
278
  e.boundingSphere?.center.x,
279
279
  e.boundingSphere?.center.y,
@@ -290,7 +290,7 @@ function pt(i) {
290
290
  let s = null;
291
291
  if (e.isCompressedTexture) {
292
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 Ue(
293
+ s = new ze(
294
294
  r,
295
295
  n,
296
296
  o,
@@ -305,7 +305,7 @@ function pt(i) {
305
305
  e.colorSpace
306
306
  );
307
307
  } else
308
- s = new W(
308
+ s = new q(
309
309
  e.image,
310
310
  e.mapping,
311
311
  e.wrapS,
@@ -316,7 +316,7 @@ function pt(i) {
316
316
  e.type,
317
317
  e.anisotropy,
318
318
  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 ze(...e.matrix.elements);
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);
320
320
  if (!s) {
321
321
  console.error("[Worker] Failed to create new texture from received data. Texture is not a CompressedTexture or Texture.");
322
322
  continue;
@@ -325,17 +325,17 @@ function pt(i) {
325
325
  }
326
326
  return i;
327
327
  }
328
- function le(i) {
328
+ function de(i) {
329
329
  let t = i;
330
330
  if ("isInterleavedBufferAttribute" in i && i.isInterleavedBufferAttribute) {
331
- const e = i.data, s = e.array, r = new qe(s, e.stride);
332
- t = new Ne(r, i.itemSize, s.byteOffset, i.normalized), t.offset = i.offset;
333
- } else "isBufferAttribute" in i && i.isBufferAttribute && (t = new Ee(i.array, i.itemSize, i.normalized), t.usage = i.usage, t.gpuType = i.gpuType, t.updateRanges = i.updateRanges);
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);
334
334
  return t;
335
335
  }
336
- const mt = N("gltf-progressive-worker");
336
+ const xt = N("gltf-progressive-worker");
337
337
  N("gltf-progressive-reduce-mipmaps");
338
- const J = N("gltf-progressive-gc"), ue = /* @__PURE__ */ Symbol("needle-progressive-texture"), U = "NEEDLE_progressive";
338
+ const se = N("gltf-progressive-gc"), fe = /* @__PURE__ */ Symbol("needle-progressive-texture"), U = "NEEDLE_progressive";
339
339
  class p {
340
340
  /** The name of the extension */
341
341
  get name() {
@@ -381,33 +381,33 @@ class p {
381
381
  max_count: 0,
382
382
  lods: []
383
383
  }), Array.isArray(t)) {
384
- for (const u of t)
385
- this.getMaterialMinMaxLODsCount(u, e);
384
+ for (const a of t)
385
+ this.getMaterialMinMaxLODsCount(a, e);
386
386
  return t[r] = e, e;
387
387
  }
388
388
  if (h === "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);
389
+ const a = t;
390
+ for (const l of Object.keys(a.uniforms)) {
391
+ const u = a.uniforms[l].value;
392
+ u?.isTexture === !0 && o(u, e);
393
393
  }
394
394
  } else if (t.isMaterial)
395
- for (const u of Object.keys(t)) {
396
- const a = t[u];
397
- a?.isTexture === !0 && o(a, e);
395
+ for (const a of Object.keys(t)) {
396
+ const l = t[a];
397
+ l?.isTexture === !0 && o(l, e);
398
398
  }
399
399
  else
400
400
  h && console.warn(`[getMaterialMinMaxLODsCount] Unsupported material type: ${t.type}`);
401
401
  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 f = 0; f < c.lods.length; f++) {
409
- const y = c.lods[f];
410
- y.width && (a.lods[f] = a.lods[f] || { min_height: 1 / 0, max_height: 0 }, a.lods[f].min_height = Math.min(a.lods[f].min_height, y.height), a.lods[f].max_height = Math.max(a.lods[f].max_height, y.height));
402
+ function o(a, l) {
403
+ const u = s.getAssignedLODInformation(a);
404
+ if (u) {
405
+ const d = s.lodInfos.get(u.key);
406
+ if (d && d.lods) {
407
+ l.min_count = Math.min(l.min_count, d.lods.length), l.max_count = Math.max(l.max_count, d.lods.length);
408
+ for (let c = 0; c < d.lods.length; c++) {
409
+ const f = d.lods[c];
410
+ f.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, f.height), l.lods[c].max_height = Math.max(l.lods[c].max_height, f.height));
411
411
  }
412
412
  }
413
413
  }
@@ -459,21 +459,26 @@ class p {
459
459
  * });
460
460
  * ```
461
461
  */
462
- static assignMeshLOD(t, e) {
462
+ static assignMeshLOD(t, e, s) {
463
463
  if (!t) return Promise.resolve(null);
464
- if (t instanceof X || t.isMesh === !0) {
465
- const s = t.geometry, r = this.getAssignedLODInformation(s);
466
- if (!r)
464
+ if (t instanceof K || t.isMesh === !0) {
465
+ const r = t.geometry, n = this.getAssignedLODInformation(r);
466
+ if (!n)
467
467
  return Promise.resolve(null);
468
- for (const n of q)
469
- n.onBeforeGetLODMesh?.(t, e);
470
- return t["LOD:requested level"] = e, p.getOrLoadLOD(s, e).then((n) => {
471
- if (Array.isArray(n)) {
472
- const o = r.index || 0;
473
- n = n[o];
468
+ for (const a of E)
469
+ a.onBeforeGetLODMesh?.(t, e);
470
+ t["LOD:requested level"] = e;
471
+ const o = () => t["LOD:requested level"] === e || this.shouldApplyStaleMeshLOD(t, e);
472
+ return p.getOrLoadLOD(r, e, {
473
+ isCurrent: o
474
+ }).then((a) => {
475
+ if (Array.isArray(a)) {
476
+ const u = n.index || 0;
477
+ a = a[u];
474
478
  }
475
- return t["LOD:requested level"] === e && (delete t["LOD:requested level"], n && s != n && (n?.isBufferGeometry ? t.geometry = n : h && console.error("Invalid LOD geometry", n))), n;
476
- }).catch((n) => (console.error("Error loading mesh LOD", t, n), null));
479
+ const l = t["LOD:requested level"] === e;
480
+ 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;
481
+ }).catch((a) => (console.error("Error loading mesh LOD", t, a), null));
477
482
  } else h && console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh", t);
478
483
  return Promise.resolve(null);
479
484
  }
@@ -484,48 +489,48 @@ class p {
484
489
  const n = t;
485
490
  if (Array.isArray(n.material)) {
486
491
  const o = new Array();
487
- for (const u of n.material) {
488
- const a = this.assignTextureLOD(u, e, s);
489
- o.push(a);
492
+ for (const a of n.material) {
493
+ const l = this.assignTextureLOD(a, e, s);
494
+ o.push(l);
490
495
  }
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;
496
+ return Promise.all(o).then((a) => {
497
+ const l = new Array();
498
+ for (const u of a)
499
+ Array.isArray(u) && l.push(...u);
500
+ return l;
496
501
  });
497
502
  } else
498
503
  return this.assignTextureLOD(n.material, e, s);
499
504
  }
500
505
  if (t.isMaterial === !0) {
501
- const n = t, o = [], u = new Array();
506
+ const n = t, o = [], a = new Array();
502
507
  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 f = this.assignTextureLODForSlot(c, e, n, l, r).then((y) => (y && a.uniforms[l].value != y && (a.uniforms[l].value = y, a.uniformsNeedUpdate = !0), y));
508
- o.push(f), u.push(l);
508
+ const l = n;
509
+ for (const u of Object.keys(l.uniforms)) {
510
+ const d = l.uniforms[u].value;
511
+ if (d?.isTexture === !0) {
512
+ const c = this.assignTextureLODForSlot(d, e, n, u, r).then((f) => (f && l.uniforms[u].value != f && (l.uniforms[u].value = f, l.uniformsNeedUpdate = !0), f));
513
+ o.push(c), a.push(u);
509
514
  }
510
515
  }
511
516
  } 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);
517
+ for (const l of Object.keys(n)) {
518
+ const u = n[l];
519
+ if (u?.isTexture === !0) {
520
+ const d = this.assignTextureLODForSlot(u, e, n, l, r);
521
+ o.push(d), a.push(l);
517
522
  }
518
523
  }
519
- return Promise.all(o).then((a) => {
520
- const l = new Array();
521
- for (let c = 0; c < a.length; c++) {
522
- const f = a[c], y = u[c];
523
- f && f.isTexture === !0 ? l.push({ material: n, slot: y, texture: f, level: e }) : l.push({ material: n, slot: y, texture: null, level: e });
524
+ return Promise.all(o).then((l) => {
525
+ const u = new Array();
526
+ for (let d = 0; d < l.length; d++) {
527
+ const c = l[d], f = a[d];
528
+ c && c.isTexture === !0 ? u.push({ material: n, slot: f, texture: c, level: e }) : u.push({ material: n, slot: f, texture: null, level: e });
524
529
  }
525
- return l;
530
+ return u;
526
531
  });
527
532
  }
528
- if (t instanceof W || t.isTexture === !0) {
533
+ if (t instanceof q || t.isTexture === !0) {
529
534
  const n = t;
530
535
  return this.assignTextureLODForSlot(n, e, null, null, r);
531
536
  }
@@ -551,33 +556,38 @@ class p {
551
556
  if (o && (o.level === e || !n && o.level < e))
552
557
  return Promise.resolve(t);
553
558
  if (s && r) {
554
- const a = this.getPendingTextureSlotRequest(s, r);
555
- if (a && a.level === e && a.force === n)
556
- return a.promise;
559
+ const c = this.getPendingTextureSlotRequest(s, r);
560
+ if (c && c.level === e && c.force === n)
561
+ return c.promise;
557
562
  }
558
- const u = p.getOrLoadLOD(t, e).then((a) => {
559
- if (Array.isArray(a))
563
+ 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), d = p.getOrLoadLOD(t, e, {
564
+ isCurrent: u
565
+ }).then((c) => {
566
+ if (!l() && !this.shouldApplyStaleTextureSlotLOD(s, r, e, n)) return null;
567
+ if (Array.isArray(c))
560
568
  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 h === "verbose" && console.warn("Assigned texture level is already higher: ", c.level, e, s, l, a), null;
569
+ if (c?.isTexture === !0) {
570
+ if (c != t && s && r) {
571
+ const f = this.getMaterialTextureSlot(s, r) ?? t;
572
+ if (f && !n) {
573
+ const g = this.getAssignedLODInformation(f);
574
+ if (g && g?.level < e)
575
+ return h === "verbose" && console.warn("Assigned texture level is already higher: ", g.level, e, s, f, c), null;
568
576
  }
569
- this.assignTrackedTextureSlot(s, r, a);
577
+ this.assignTrackedTextureSlot(s, r, c);
570
578
  }
571
- return a;
579
+ return c;
572
580
  } else h == "verbose" && console.warn("No LOD found for", t, e);
573
581
  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;
582
+ }).catch((c) => (console.error("Error loading LOD", t, c), null));
583
+ return s && r && this.setPendingTextureSlotRequest(s, r, e, n, a, d), d;
576
584
  }
577
585
  // Track material slots, not just texture objects. A shared fallback texture can be
578
586
  // referenced by many slots and should only be disposed after every slot moved away.
579
587
  static trackedTextureSlots = /* @__PURE__ */ new WeakMap();
580
588
  static pendingTextureSlotRequests = /* @__PURE__ */ new WeakMap();
589
+ static latestTextureSlotRequests = /* @__PURE__ */ new WeakMap();
590
+ static textureSlotRequestId = 0;
581
591
  static trackCurrentMaterialTextureSlots(t) {
582
592
  if (t.uniforms && (t.isRawShaderMaterial || t.isShaderMaterial === !0)) {
583
593
  const e = t;
@@ -595,12 +605,32 @@ class p {
595
605
  static getPendingTextureSlotRequest(t, e) {
596
606
  return this.pendingTextureSlotRequests.get(t)?.get(e);
597
607
  }
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);
608
+ static nextTextureSlotRequestId(t, e, s, r) {
609
+ let n = this.latestTextureSlotRequests.get(t);
610
+ n || (n = /* @__PURE__ */ new Map(), this.latestTextureSlotRequests.set(t, n));
611
+ const o = ++this.textureSlotRequestId;
612
+ return n.set(e, { id: o, level: s, force: r }), o;
613
+ }
614
+ static getLatestTextureSlotRequest(t, e) {
615
+ return this.latestTextureSlotRequests.get(t)?.get(e);
616
+ }
617
+ static shouldApplyStaleTextureSlotLOD(t, e, s, r) {
618
+ if (!t || !e) return !1;
619
+ const n = this.getLatestTextureSlotRequest(t, e), o = this.getMaterialTextureSlot(t, e), a = this.getAssignedLODInformation(o)?.level ?? 1 / 0;
620
+ return s >= a ? !1 : r ? n ? s >= n.level : !1 : !0;
621
+ }
622
+ static shouldApplyStaleMeshLOD(t, e) {
623
+ const s = t["LOD:requested level"];
624
+ if (typeof s != "number") return !1;
625
+ const r = this.getAssignedLODInformation(t.geometry)?.level ?? 1 / 0;
626
+ return e < r && e >= s;
627
+ }
628
+ static setPendingTextureSlotRequest(t, e, s, r, n, o) {
629
+ let a = this.pendingTextureSlotRequests.get(t);
630
+ a || (a = /* @__PURE__ */ new Map(), this.pendingTextureSlotRequests.set(t, a));
631
+ const l = { level: s, force: r, id: n, promise: o };
632
+ a.set(e, l), o.finally(() => {
633
+ a.get(e)?.id === n && a.delete(e);
604
634
  });
605
635
  }
606
636
  static getMaterialTextureSlot(t, e) {
@@ -633,7 +663,7 @@ class p {
633
663
  }
634
664
  static releaseTrackedTextureSlot(t, e, s) {
635
665
  const r = this.trackedTextureSlots.get(t);
636
- if (r?.get(e) === s && r.delete(e), this.untrackTextureUsage(s) && (h || J)) {
666
+ if (r?.get(e) === s && r.delete(e), this.untrackTextureUsage(s) && (h || se)) {
637
667
  const o = this.getAssignedLODInformation(s);
638
668
  console.log(`[gltf-progressive] Disposed old texture LOD ${o?.level ?? "?"} for ${t.name || t.type}.${e}`, s.uuid);
639
669
  }
@@ -711,10 +741,10 @@ class p {
711
741
  return;
712
742
  }
713
743
  if (h) {
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);
744
+ const a = e.image?.width || e.source?.data?.width || 0, l = e.image?.height || e.source?.data?.height || 0;
745
+ 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
746
  }
717
- e.source && (e.source[ue] = n);
747
+ e.source && (e.source[fe] = n);
718
748
  const o = n.guid;
719
749
  p.assignLODInformation(t, e, o, s, r), p.lodInfos.set(o, n), p.lowresCache.set(o, new WeakRef(e));
720
750
  };
@@ -732,16 +762,16 @@ class p {
732
762
  * @param ext - The parsed progressive mesh extension data containing all available LOD levels with vertex/index counts and densities.
733
763
  */
734
764
  static registerMesh = (t, e, s, r, n, o) => {
735
- const u = s.geometry;
736
- if (!u) {
765
+ const a = s.geometry;
766
+ if (!a) {
737
767
  h && console.warn("gltf-progressive: Register mesh without geometry");
738
768
  return;
739
769
  }
740
- u.userData || (u.userData = {}), h && console.log("> Progressive: register mesh " + s.name, { index: n, uuid: s.uuid }, o, s), p.assignLODInformation(t, u, e, r, n), p.lodInfos.set(e, o);
741
- let l = p.lowresCache.get(e)?.deref();
742
- l ? l.push(s.geometry) : l = [s.geometry], p.lowresCache.set(e, new WeakRef(l)), r > 0 && !ee(s) && ut(s, u);
743
- for (const c of q)
744
- c.onRegisteredNewMesh?.(s, o);
770
+ 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);
771
+ let u = p.lowresCache.get(e)?.deref();
772
+ u ? u.push(s.geometry) : u = [s.geometry], p.lowresCache.set(e, new WeakRef(u)), r > 0 && !ne(s) && dt(s, a);
773
+ for (const d of E)
774
+ d.onRegisteredNewMesh?.(s, o);
745
775
  };
746
776
  /**
747
777
  * Dispose cached resources to free memory.
@@ -782,7 +812,7 @@ class p {
782
812
  this.lowresCache.clear();
783
813
  for (const [, e] of this.cache)
784
814
  this._disposeCacheEntry(e);
785
- this.cache.clear(), this.textureRefCounts.clear(), this.trackedTextureSlots = /* @__PURE__ */ new WeakMap(), this.pendingTextureSlotRequests = /* @__PURE__ */ new WeakMap();
815
+ 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
816
  }
787
817
  }
788
818
  /** Dispose a single cache entry's three.js resource(s) to free GPU memory. */
@@ -815,8 +845,8 @@ class p {
815
845
  */
816
846
  static _resourceRegistry = new FinalizationRegistry((t) => {
817
847
  const e = p.cache.get(t);
818
- (h || J) && console.debug(`[gltf-progressive] Memory: Resource GC'd
819
- ${t}`), e instanceof WeakRef && (e.deref() || (p.cache.delete(t), (h || J) && console.log("[gltf-progressive] ↪ Cache entry deleted (GC)")));
848
+ (h || se) && console.debug(`[gltf-progressive] Memory: Resource GC'd
849
+ ${t}`), e instanceof WeakRef && (e.deref() || (p.cache.delete(t), (h || se) && console.log("[gltf-progressive] ↪ Cache entry deleted (GC)")));
820
850
  });
821
851
  /**
822
852
  * Track texture usage by incrementing reference count
@@ -833,147 +863,154 @@ ${t}`), e instanceof WeakRef && (e.deref() || (p.cache.delete(t), (h || J) && co
833
863
  static untrackTextureUsage(t) {
834
864
  const e = t.uuid, s = this.textureRefCounts.get(e);
835
865
  if (!s)
836
- return (h === "verbose" || J) && n("[gltf-progressive] Memory: Untrack untracked texture (dispose immediately)", 0), t.dispose(), !0;
866
+ return (h === "verbose" || se) && n("[gltf-progressive] Memory: Untrack untracked texture (dispose immediately)", 0), t.dispose(), !0;
837
867
  const r = s - 1;
838
868
  if (r <= 0)
839
- return this.textureRefCounts.delete(e), (h || J) && n("[gltf-progressive] Memory: Dispose texture", r), t.dispose(), !0;
869
+ return this.textureRefCounts.delete(e), (h || se) && n("[gltf-progressive] Memory: Dispose texture", r), t.dispose(), !0;
840
870
  return this.textureRefCounts.set(e, r), h === "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 f = "N/A";
844
- a && l && (f = `~${(it(t) / (1024 * 1024)).toFixed(2)} MB`), console.log(`${o} — ${t.name} ${c} (${f}), refCount: ${s} → ${u}
871
+ function n(o, a) {
872
+ const l = t.image?.width || t.source?.data?.width || 0, u = t.image?.height || t.source?.data?.height || 0, d = l && u ? `${l}x${u}` : "N/A";
873
+ let c = "N/A";
874
+ l && u && (c = `~${(lt(t) / (1024 * 1024)).toFixed(2)} MB`), console.log(`${o} — ${t.name} ${d} (${c}), refCount: ${s} → ${a}
845
875
  ${e}`);
846
876
  }
847
877
  }
848
878
  static workers = [];
849
879
  static _workersIndex = 0;
850
- static async getOrLoadLOD(t, e) {
851
- const s = h == "verbose", r = this.getAssignedLODInformation(t);
852
- if (!r)
880
+ static async getOrLoadLOD(t, e, s) {
881
+ const r = h == "verbose", n = this.getAssignedLODInformation(t);
882
+ if (!n)
853
883
  return h && 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;
884
+ const o = n?.key;
885
+ let a;
856
886
  if (t.isTexture === !0) {
857
- const a = t;
858
- a.source && a.source[ue] && (o = a.source[ue]);
887
+ const u = t;
888
+ u.source && u.source[fe] && (a = u.source[fe]);
859
889
  }
860
- if (o || (o = p.lodInfos.get(n)), !o)
861
- h && console.warn(`Can not load LOD ${e}: no LOD info found for "${n}" ${t.name}`, t.type, p.lodInfos);
890
+ if (a || (a = p.lodInfos.get(o)), !a)
891
+ h && console.warn(`Can not load LOD ${e}: no LOD info found for "${o}" ${t.name}`, t.type, p.lodInfos);
862
892
  else {
863
893
  if (e > 0) {
864
894
  let c = !1;
865
- const f = Array.isArray(o.lods);
866
- if (f && e >= o.lods.length ? c = !0 : f || (c = !0), c) {
867
- const y = this.lowresCache.get(n);
868
- if (y) {
869
- const T = y.deref();
870
- if (T) return T;
871
- this.lowresCache.delete(n), h && console.log(`[gltf-progressive] Lowres cache entry was GC'd: ${n}`);
895
+ const f = Array.isArray(a.lods);
896
+ if (f && e >= a.lods.length ? c = !0 : f || (c = !0), c) {
897
+ const g = this.lowresCache.get(o);
898
+ if (g) {
899
+ const O = g.deref();
900
+ if (O) return O;
901
+ this.lowresCache.delete(o), h && console.log(`[gltf-progressive] Lowres cache entry was GC'd: ${o}`);
872
902
  }
873
903
  return null;
874
904
  }
875
905
  }
876
- const a = Array.isArray(o.lods) ? o.lods[e]?.path : o.lods;
877
- if (!a)
878
- return h && !o["missing:uri"] && (o["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + e, o)), null;
879
- const l = nt(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, f = await this.tryResolveLODCacheEntry(this.cache.get(c), c, l, t, e, s);
906
+ const u = Array.isArray(a.lods) ? a.lods[e]?.path : a.lods;
907
+ if (!u)
908
+ return h && !a["missing:uri"] && (a["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + e, a)), null;
909
+ const d = ot(n.url, u);
910
+ if (d.endsWith(".glb") || d.endsWith(".gltf")) {
911
+ if (!a.guid)
912
+ return console.warn("missing pointer for glb/gltf texture", a), null;
913
+ const c = d + "_" + a.guid, f = await this.tryResolveLODCacheEntry(this.cache.get(c), c, d, t, e, r);
884
914
  if (f.found) return f.value;
885
- const y = await this.queue.slot(l), T = await this.tryResolveLODCacheEntry(this.cache.get(c), c, l, t, e, s);
886
- if (T.found) return T.value;
887
- if (!y.use)
888
- return h && console.log(`LOD ${e} was aborted: ${l}`), null;
889
- const _ = o, C = new Promise(async (m, B) => {
890
- if (mt) {
891
- const d = await (await gt({})).load(l);
892
- if (d.textures.length > 0)
893
- for (const g of d.textures) {
894
- let w = g.texture;
895
- return p.assignLODInformation(r.url, w, n, e, void 0), t instanceof W && (w = this.copySettings(t, w)), w && (w.guid = _.guid), m(w);
915
+ if (s?.isCurrent?.() === !1)
916
+ return r && console.log(`Skipping stale LOD ${e} request before queue: ${d}`), null;
917
+ const g = await this.queue.slot(d);
918
+ if (s?.isCurrent?.() === !1)
919
+ return r && console.log(`Skipping stale LOD ${e} request after queue: ${d}`), null;
920
+ const O = await this.tryResolveLODCacheEntry(this.cache.get(c), c, d, t, e, r);
921
+ if (O.found) return O.value;
922
+ if (!g.use)
923
+ return h && console.log(`LOD ${e} was aborted: ${d}`), null;
924
+ const y = a, x = new Promise(async (L, V) => {
925
+ if (xt) {
926
+ const m = await (await mt({})).load(d);
927
+ if (m.textures.length > 0)
928
+ for (const D of m.textures) {
929
+ let M = D.texture;
930
+ 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
931
  }
897
- if (d.geometries.length > 0) {
898
- const g = new Array();
899
- for (const w of d.geometries) {
900
- const v = w.geometry;
901
- p.assignLODInformation(r.url, v, n, e, w.primitiveIndex), g.push(v);
932
+ if (m.geometries.length > 0) {
933
+ const D = new Array();
934
+ for (const M of m.geometries) {
935
+ const G = M.geometry;
936
+ p.assignLODInformation(n.url, G, o, e, M.primitiveIndex), D.push(G);
902
937
  }
903
- return m(g);
938
+ return L(D);
904
939
  }
905
- return m(null);
940
+ return L(null);
906
941
  }
907
- const G = new xe();
908
- Pe(G), h && (await new Promise((b) => setTimeout(b, 1e3)), s && console.warn("Start loading (delayed) " + l, _.guid));
909
- let A = l;
910
- if (_ && Array.isArray(_.lods)) {
911
- const b = _.lods[e];
912
- b.hash && (A += "?v=" + b.hash);
942
+ const w = new Le();
943
+ Ae(w), h && (await new Promise((b) => setTimeout(b, 1e3)), r && console.warn("Start loading (delayed) " + d, y.guid));
944
+ let S = d;
945
+ if (y && Array.isArray(y.lods)) {
946
+ const b = y.lods[e];
947
+ b.hash && (S += "?v=" + b.hash);
913
948
  }
914
- const S = await G.loadAsync(A).catch((b) => (console.error(`Error loading LOD ${e} from ${l}
915
- `, b), m(null)));
916
- if (!S)
917
- return m(null);
918
- const F = S.parser;
919
- s && console.log("Loading finished " + l, _.guid);
920
- let M = 0;
921
- if (S.parser.json.textures) {
949
+ const _ = await w.loadAsync(S).catch((b) => (console.error(`Error loading LOD ${e} from ${d}
950
+ `, b), L(null)));
951
+ if (!_)
952
+ return L(null);
953
+ const R = _.parser;
954
+ r && console.log("Loading finished " + d, y.guid);
955
+ let C = 0;
956
+ if (_.parser.json.textures) {
922
957
  let b = !1;
923
- for (const d of S.parser.json.textures) {
924
- if (d?.extensions) {
925
- const g = d?.extensions[U];
926
- if (g?.guid && g.guid === _.guid) {
958
+ for (const m of _.parser.json.textures) {
959
+ if (m?.extensions) {
960
+ const D = m?.extensions[U];
961
+ if (D?.guid && D.guid === y.guid) {
927
962
  b = !0;
928
963
  break;
929
964
  }
930
965
  }
931
- M++;
966
+ C++;
932
967
  }
933
968
  if (b) {
934
- let d = await F.getDependency("texture", M);
935
- return d && p.assignLODInformation(r.url, d, n, e, void 0), s && console.log('change "' + t.name + '" → "' + d.name + '"', l, M, d, c), t instanceof W && (d = this.copySettings(t, d)), d && (d.guid = _.guid), m(d);
936
- } else h && console.warn("Could not find texture with guid", _.guid, S.parser.json);
969
+ let m = await R.getDependency("texture", C);
970
+ return m && p.assignLODInformation(n.url, m, o, e, void 0), r && console.log('change "' + t.name + '" → "' + m.name + '"', d, C, m, c), t instanceof q && (m = this.copySettings(t, m)), m && (m.guid = y.guid), L(m);
971
+ } else h && console.warn("Could not find texture with guid", y.guid, _.parser.json);
937
972
  }
938
- if (M = 0, S.parser.json.meshes) {
973
+ if (C = 0, _.parser.json.meshes) {
939
974
  let b = !1;
940
- for (const d of S.parser.json.meshes) {
941
- if (d?.extensions) {
942
- const g = d?.extensions[U];
943
- if (g?.guid && g.guid === _.guid) {
975
+ for (const m of _.parser.json.meshes) {
976
+ if (m?.extensions) {
977
+ const D = m?.extensions[U];
978
+ if (D?.guid && D.guid === y.guid) {
944
979
  b = !0;
945
980
  break;
946
981
  }
947
982
  }
948
- M++;
983
+ C++;
949
984
  }
950
985
  if (b) {
951
- const d = await F.getDependency("mesh", M);
952
- if (s && console.log(`Loaded Mesh "${d.name}"`, l, M, d, c), d.isMesh === !0) {
953
- const g = d.geometry;
954
- return p.assignLODInformation(r.url, g, n, e, 0), m(g);
986
+ const m = await R.getDependency("mesh", C);
987
+ if (r && console.log(`Loaded Mesh "${m.name}"`, d, C, m, c), m.isMesh === !0) {
988
+ const D = m.geometry;
989
+ return p.assignLODInformation(n.url, D, o, e, 0), L(D);
955
990
  } else {
956
- const g = new Array();
957
- for (let w = 0; w < d.children.length; w++) {
958
- const v = d.children[w];
959
- if (v.isMesh === !0) {
960
- const O = v.geometry;
961
- p.assignLODInformation(r.url, O, n, e, w), g.push(O);
991
+ const D = new Array();
992
+ for (let M = 0; M < m.children.length; M++) {
993
+ const G = m.children[M];
994
+ if (G.isMesh === !0) {
995
+ const ie = G.geometry;
996
+ p.assignLODInformation(n.url, ie, o, e, M), D.push(ie);
962
997
  }
963
998
  }
964
- return m(g);
999
+ return L(D);
965
1000
  }
966
- } else h && console.warn("Could not find mesh with guid", _.guid, S.parser.json);
1001
+ } else h && console.warn("Could not find mesh with guid", y.guid, _.parser.json);
967
1002
  }
968
- return m(null);
1003
+ return L(null);
969
1004
  });
970
- this.cache.set(c, C), y.use(C);
971
- const x = await C;
972
- return x != null ? x instanceof W ? (this.cache.set(c, new WeakRef(x)), p._resourceRegistry.register(x, c)) : Array.isArray(x) ? this.cache.set(c, Promise.resolve(x)) : this.cache.set(c, Promise.resolve(x)) : this.cache.set(c, Promise.resolve(null)), x;
973
- } else if (t instanceof W) {
974
- s && console.log("Load texture from uri: " + l);
975
- const f = await new Ve().loadAsync(l);
976
- return f ? (f.guid = o.guid, f.flipY = !1, f.needsUpdate = !0, f.colorSpace = t.colorSpace, s && console.log(o, f)) : h && console.warn("failed loading", l), f;
1005
+ this.cache.set(c, x), g.use(x);
1006
+ const v = await x;
1007
+ 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;
1008
+ } else if (t instanceof q) {
1009
+ if (s?.isCurrent?.() === !1)
1010
+ return r && console.log(`Skipping stale texture LOD ${e} request: ${d}`), null;
1011
+ r && console.log("Load texture from uri: " + d);
1012
+ const f = await new je().loadAsync(d);
1013
+ return s?.isCurrent?.() === !1 ? (f?.dispose(), null) : (f ? (f.guid = a.guid, f.flipY = !1, f.needsUpdate = !0, f.colorSpace = t.colorSpace, r && console.log(a, f)) : h && console.warn("failed loading", d), f);
977
1014
  }
978
1015
  }
979
1016
  return null;
@@ -982,26 +1019,26 @@ ${e}`);
982
1019
  if (t === void 0)
983
1020
  return { found: !1 };
984
1021
  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, f = !1;
988
- if (c instanceof W && r instanceof W ? c.image?.data || c.source?.data ? c = this.copySettings(r, c) : f = !0 : c instanceof V && r instanceof V && (c.attributes.position?.array || (f = !0)), !f)
989
- return { found: !0, value: c };
1022
+ const u = t.deref();
1023
+ if (u) {
1024
+ let d = u, c = !1;
1025
+ if (d instanceof q && r instanceof q ? d.image?.data || d.source?.data ? d = this.copySettings(r, d) : c = !0 : d instanceof j && r instanceof j && (d.attributes.position?.array || (c = !0)), !c)
1026
+ return { found: !0, value: d };
990
1027
  }
991
1028
  return this.cache.delete(e), h && console.log(`[gltf-progressive] Re-loading GC'd/disposed resource: ${e}`), { found: !1 };
992
1029
  }
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 W && r instanceof W ? u.image?.data || u.source?.data ? u = this.copySettings(r, u) : (a = !0, this.cache.delete(e)) : u instanceof V && r instanceof V && (u.attributes.position?.array || (a = !0, this.cache.delete(e)))), a ? { found: !1 } : { found: !0, value: u };
1030
+ let a = await t.catch((u) => (console.error(`Error loading LOD ${n} from ${s}
1031
+ `, u), null)), l = !1;
1032
+ return a == null || (a instanceof q && r instanceof q ? a.image?.data || a.source?.data ? 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
1033
  }
997
1034
  static _queue;
998
1035
  static get queue() {
999
- return this._queue ??= new ot(Le() ? 20 : 50, { debug: h != !1 });
1036
+ return this._queue ??= new at(_e() ? 20 : 50, { debug: h != !1 });
1000
1037
  }
1001
1038
  static assignLODInformation(t, e, s, r, n) {
1002
1039
  if (!e) return;
1003
1040
  e.userData || (e.userData = {});
1004
- const o = new yt(t, s, r, n);
1041
+ const o = new wt(t, s, r, n);
1005
1042
  e.userData.LODS = o, "source" in e && typeof e.source == "object" && (e.source.LODS = o);
1006
1043
  }
1007
1044
  static getAssignedLODInformation(t) {
@@ -1014,7 +1051,7 @@ ${e}`);
1014
1051
  `, 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
1052
  }
1016
1053
  }
1017
- class yt {
1054
+ class wt {
1018
1055
  url;
1019
1056
  /** the key to lookup the LOD information */
1020
1057
  key;
@@ -1025,7 +1062,7 @@ class yt {
1025
1062
  this.url = t, this.key = e, this.level = s, r != null && (this.index = r);
1026
1063
  }
1027
1064
  }
1028
- class ce {
1065
+ class oe {
1029
1066
  static addPromise = (t, e, s, r) => {
1030
1067
  r.forEach((n) => {
1031
1068
  n.add(t, e, s);
@@ -1101,7 +1138,7 @@ class ce {
1101
1138
  });
1102
1139
  }
1103
1140
  }
1104
- const R = N("debugprogressive"), xt = R === "colors", wt = N("noprogressive"), de = /* @__PURE__ */ Symbol("Needle:LODSManager"), fe = /* @__PURE__ */ Symbol("Needle:LODState"), z = /* @__PURE__ */ Symbol("Needle:CurrentLOD"), D = { mesh_lod: -1, texture_lod: -1 }, Lt = new ke(), be = [
1141
+ const A = N("debugprogressive"), Lt = A === "colors", vt = N("noprogressive"), he = /* @__PURE__ */ Symbol("Needle:LODSManager"), ge = /* @__PURE__ */ Symbol("Needle:LODState"), F = /* @__PURE__ */ Symbol("Needle:CurrentLOD"), T = { mesh_lod: -1, texture_lod: -1 }, _t = new ke(), Me = [
1105
1142
  3526751,
1106
1143
  11065402,
1107
1144
  15978811,
@@ -1134,22 +1171,79 @@ const R = N("debugprogressive"), xt = R === "colors", wt = N("noprogressive"), d
1134
1171
  15817653,
1135
1172
  5083278,
1136
1173
  5592405
1137
- ];
1138
- class L {
1174
+ ], pe = new ue(), z = new ue(), Oe = new ue(), Dt = new P(), Mt = new P(), Ot = new Pe(), W = new P(), H = new P(), Q = new P(), J = new P();
1175
+ function St(i, t) {
1176
+ const e = i.min, s = i.max, r = (e.x + s.x) * 0.5, n = (e.y + s.y) * 0.5;
1177
+ return W.set(r, n, e.z).applyMatrix4(t).z < 0;
1178
+ }
1179
+ function bt(i) {
1180
+ const {
1181
+ geometry: t,
1182
+ matrixWorld: e,
1183
+ camera: s,
1184
+ projectionScreenMatrix: r,
1185
+ desiredDensity: n,
1186
+ canvasHeight: o = 0,
1187
+ currentLevel: a = -1,
1188
+ xrEnabled: l = !1,
1189
+ debugDrawLine: u,
1190
+ warnMissingPrimitiveDensities: d = !1
1191
+ } = i, c = p.getMeshLODExtension(t)?.lods, f = p.getPrimitiveIndex(t), g = i.target ?? {
1192
+ level: a,
1193
+ primitiveIndex: f,
1194
+ screenCoverage: 0,
1195
+ screenspaceVolume: new P(),
1196
+ centrality: 1
1197
+ };
1198
+ if (g.level = a, g.primitiveIndex = f, g.screenCoverage = 0, g.screenspaceVolume.set(0, 0, 0), g.centrality = 1, !c?.length) return g;
1199
+ let O = i.boundingBox ?? t.boundingBox;
1200
+ if (O || (t.computeBoundingBox(), O = t.boundingBox), !O) return g;
1201
+ if (pe.copy(O).applyMatrix4(e), s.isPerspectiveCamera && St(pe, r))
1202
+ return g.level = 0, g.screenCoverage = 1 / 0, g.screenspaceVolume.set(1 / 0, 1 / 0, 1 / 0), g;
1203
+ if (z.copy(pe).applyMatrix4(r), l && s.isPerspectiveCamera && s.fov > 70) {
1204
+ const w = z.min, S = z.max;
1205
+ let _ = w.x, R = w.y, C = S.x, b = S.y;
1206
+ const m = 2, D = 1.5, M = (w.x + S.x) * 0.5, G = (w.y + S.y) * 0.5;
1207
+ _ = (_ - M) * m + M, R = (R - G) * m + G, C = (C - M) * m + M, b = (b - G) * m + G;
1208
+ const ie = _ < 0 && C > 0 ? 0 : Math.min(Math.abs(w.x), Math.abs(S.x)), Fe = R < 0 && b > 0 ? 0 : Math.min(Math.abs(w.y), Math.abs(S.y)), ce = Math.max(ie, Fe);
1209
+ g.centrality = (D - ce) * (D - ce) * (D - ce);
1210
+ }
1211
+ const y = z.getSize(Dt);
1212
+ y.multiplyScalar(0.5), globalThis.screen?.availHeight > 0 && o > 0 && y.multiplyScalar(o / globalThis.screen.availHeight), s.isPerspectiveCamera && (y.x *= s.aspect), Oe.copy(O).applyMatrix4(e).applyMatrix4(s.matrixWorldInverse);
1213
+ const x = Oe.getSize(Mt), v = Math.max(y.x, y.y), L = Math.max(x.x, x.y);
1214
+ v !== 0 && L !== 0 && (y.z = x.z / L * v);
1215
+ const V = Math.max(y.x, y.y, y.z) * g.centrality;
1216
+ if (g.screenCoverage = V, g.screenspaceVolume.copy(y), V <= 0) return g;
1217
+ if (u) {
1218
+ const w = Ot.copy(r);
1219
+ 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);
1220
+ const S = (W.z + J.z) * 0.5;
1221
+ W.z = H.z = Q.z = J.z = S, 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);
1222
+ }
1223
+ for (let w = 0; w < c.length; w++) {
1224
+ const S = c[w], _ = S.densities?.[f] || S.density || 1e-5;
1225
+ if (f > 0 && d && Be() && !S.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.")), _ / V < n) {
1226
+ g.level = w;
1227
+ break;
1228
+ }
1229
+ }
1230
+ return g;
1231
+ }
1232
+ class I {
1139
1233
  /**
1140
1234
  * 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.
1141
1235
  */
1142
1236
  static debugDrawLine;
1143
1237
  /** @internal */
1144
1238
  static getObjectLODState(t) {
1145
- return t[fe];
1239
+ return t[ge];
1146
1240
  }
1147
1241
  static addPlugin(t) {
1148
- q.push(t);
1242
+ E.push(t);
1149
1243
  }
1150
1244
  static removePlugin(t) {
1151
- const e = q.indexOf(t);
1152
- e >= 0 && q.splice(e, 1);
1245
+ const e = E.indexOf(t);
1246
+ e >= 0 && E.splice(e, 1);
1153
1247
  }
1154
1248
  /**
1155
1249
  * Gets the LODsManager for the given renderer. If the LODsManager does not exist yet, it will be created.
@@ -1157,20 +1251,20 @@ class L {
1157
1251
  * @returns The LODsManager instance.
1158
1252
  */
1159
1253
  static get(t, e) {
1160
- if (t[de])
1161
- return console.debug("[gltf-progressive] LODsManager already exists for this renderer"), t[de];
1162
- const s = new L(t, {
1254
+ if (t[he])
1255
+ return console.debug("[gltf-progressive] LODsManager already exists for this renderer"), t[he];
1256
+ const s = new I(t, {
1163
1257
  engine: "unknown",
1164
1258
  ...e
1165
1259
  });
1166
- return t[de] = s, s;
1260
+ return t[he] = s, s;
1167
1261
  }
1168
1262
  renderer;
1169
1263
  context;
1170
- projectionScreenMatrix = new ve();
1264
+ projectionScreenMatrix = new Pe();
1171
1265
  /** @deprecated use static `LODsManager.addPlugin()` method. This getter will be removed in later versions */
1172
1266
  get plugins() {
1173
- return q;
1267
+ return E;
1174
1268
  }
1175
1269
  /**
1176
1270
  * Force override the LOD level for all objects (meshes + textures) rendered in the scene
@@ -1235,17 +1329,21 @@ class L {
1235
1329
  * ```
1236
1330
  */
1237
1331
  awaitLoading(t) {
1238
- const e = this._promiseGroupIds++, s = new ce(this.#r, { ...t });
1332
+ const e = this._promiseGroupIds++, s = new oe(this.#r, { ...t });
1239
1333
  this._newPromiseGroups.push(s);
1240
1334
  const r = performance.now();
1241
1335
  return s.ready.finally(() => {
1242
1336
  const n = this._newPromiseGroups.indexOf(s);
1243
- n >= 0 && (this._newPromiseGroups.splice(n, 1), Me() && performance.measure("LODsManager:awaitLoading", {
1337
+ n >= 0 && (this._newPromiseGroups.splice(n, 1), Be() && performance.measure("LODsManager:awaitLoading", {
1244
1338
  start: r,
1245
1339
  detail: { id: e, name: t?.name, awaited: s.awaitedCount, resolved: s.resolvedCount }
1246
1340
  }));
1247
1341
  }), s.ready;
1248
1342
  }
1343
+ /** Track LOD work started outside this manager so {@link awaitLoading} waits for it too. */
1344
+ trackLoadingPromise(t, e, s) {
1345
+ return oe.addPromise(t, e, s, this._newPromiseGroups), s;
1346
+ }
1249
1347
  _postprocessPromiseGroups() {
1250
1348
  if (this._newPromiseGroups.length !== 0)
1251
1349
  for (let t = this._newPromiseGroups.length - 1; t >= 0; t--)
@@ -1292,10 +1390,10 @@ class L {
1292
1390
  this.renderer = t, this.context = { ...e };
1293
1391
  }
1294
1392
  #t;
1295
- #o = new Xe();
1393
+ #i = new Ke();
1296
1394
  #r = 0;
1297
1395
  #n = 0;
1298
- #i = 0;
1396
+ #o = 0;
1299
1397
  #s = 0;
1300
1398
  _fpsBuffer = [60, 60, 60, 60, 60];
1301
1399
  /**
@@ -1307,9 +1405,9 @@ class L {
1307
1405
  let t = 0;
1308
1406
  this.#t = this.renderer.render;
1309
1407
  const e = this;
1310
- we(this.renderer), this.renderer.render = function(s, r) {
1408
+ ve(this.renderer), this.renderer.render = function(s, r) {
1311
1409
  const n = e.renderer.getRenderTarget();
1312
- (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, R && e.#r % 200 === 0 && console.log("FPS", Math.round(e.#s), "Interval:", e.#e));
1410
+ (n == null || "isXRRenderTarget" in n && n.isXRRenderTarget) && (t = 0, e.#r += 1, e.#n = e.#i.getDelta(), 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));
1313
1411
  const o = t++;
1314
1412
  e.#t.call(this, s, r), e.onAfterRender(s, r, o);
1315
1413
  };
@@ -1340,11 +1438,11 @@ class L {
1340
1438
  const n = this.renderer.renderLists.get(t, 0).opaque;
1341
1439
  let o = !0;
1342
1440
  if (n.length === 1) {
1343
- const u = n[0].material;
1344
- (u.name === "EffectMaterial" || u.name === "CopyShader") && (o = !1);
1441
+ const a = n[0].material;
1442
+ (a.name === "EffectMaterial" || a.name === "CopyShader") && (o = !1);
1345
1443
  }
1346
1444
  if ((e.parent && e.parent.type === "CubeCamera" || s >= 1 && e.type === "OrthographicCamera") && (o = !1), o) {
1347
- if (wt || (this.updateInterval === "auto" ? this.#s < 40 && this.#e < 10 ? (this.#e += 1, R && console.warn("↓ Reducing LOD updates", this.#e, this.#s.toFixed(0))) : this.#s >= 60 && this.#e > 1 && (this.#e -= 1, R && console.warn("↑ Increasing LOD updates", this.#e, this.#s.toFixed(0))) : this.#e = this.updateInterval, this.#e > 0 && this.#r % this.#e != 0))
1445
+ 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))
1348
1446
  return;
1349
1447
  this.internalUpdate(t, e), this._postprocessPromiseGroups();
1350
1448
  }
@@ -1356,12 +1454,12 @@ class L {
1356
1454
  const s = this.renderer.renderLists.get(t, 0), r = s.opaque;
1357
1455
  this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix, e.matrixWorldInverse);
1358
1456
  const n = this.targetTriangleDensity;
1359
- for (const a of r) {
1360
- 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")) {
1361
- R && (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)));
1457
+ for (const l of r) {
1458
+ 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")) {
1459
+ 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)));
1362
1460
  continue;
1363
1461
  }
1364
- switch (a.material.type) {
1462
+ switch (l.material.type) {
1365
1463
  case "LineBasicMaterial":
1366
1464
  case "LineDashedMaterial":
1367
1465
  case "PointsMaterial":
@@ -1370,33 +1468,33 @@ class L {
1370
1468
  case "MeshDepthMaterial":
1371
1469
  continue;
1372
1470
  }
1373
- const l = a.object;
1374
- (l instanceof X || l.isMesh) && this.updateLODs(t, e, l, n);
1471
+ const u = l.object;
1472
+ (u instanceof K || u.isMesh) && this.updateLODs(t, e, u, n);
1375
1473
  }
1376
1474
  const o = s.transparent;
1377
- for (const a of o) {
1378
- const l = a.object;
1379
- (l instanceof X || l.isMesh) && this.updateLODs(t, e, l, n);
1475
+ for (const l of o) {
1476
+ const u = l.object;
1477
+ (u instanceof K || u.isMesh) && this.updateLODs(t, e, u, n);
1380
1478
  }
1381
- const u = s.transmissive;
1382
- for (const a of u) {
1383
- const l = a.object;
1384
- (l instanceof X || l.isMesh) && this.updateLODs(t, e, l, n);
1479
+ const a = s.transmissive;
1480
+ for (const l of a) {
1481
+ const u = l.object;
1482
+ (u instanceof K || u.isMesh) && this.updateLODs(t, e, u, n);
1385
1483
  }
1386
1484
  }
1387
1485
  /** Update the LOD levels for the renderer. */
1388
1486
  updateLODs(t, e, s, r) {
1389
1487
  s.userData || (s.userData = {});
1390
- let n = s[fe];
1391
- if (n || (n = new _t(), s[fe] = n), n.frames++ < 2)
1488
+ let n = s[ge];
1489
+ if (n || (n = new Tt(), s[ge] = n), n.frames++ < 2)
1392
1490
  return;
1393
- for (const u of q)
1394
- u.onBeforeUpdateLOD?.(this.renderer, t, e, s);
1395
- const o = this.overrideLodLevel !== void 0 ? this.overrideLodLevel : E;
1396
- o >= 0 ? (D.mesh_lod = o, D.texture_lod = o) : (this.calculateLodLevel(e, s, n, r, D), D.mesh_lod = Math.round(D.mesh_lod), D.texture_lod = Math.round(D.texture_lod)), D.mesh_lod >= 0 && this.loadProgressiveMeshes(s, D.mesh_lod), s.material && D.texture_lod >= 0 && this.loadProgressiveTextures(s.material, D.texture_lod, o), h && s.material && !s.isGizmo && Ie(s.material), xt && s.material && !s.isGizmo && !s.isBatchedMesh && $e(s.material, D.mesh_lod);
1397
- for (const u of q)
1398
- u.onAfterUpdatedLOD?.(this.renderer, t, e, s, D);
1399
- n.lastLodLevel_Mesh = D.mesh_lod, n.lastLodLevel_Texture = D.texture_lod;
1491
+ for (const a of E)
1492
+ a.onBeforeUpdateLOD?.(this.renderer, t, e, s);
1493
+ const o = this.overrideLodLevel !== void 0 ? this.overrideLodLevel : X;
1494
+ 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), h && s.material && !s.isGizmo && Ge(s.material), Lt && s.material && !s.isGizmo && !s.isBatchedMesh && qe(s.material, T.mesh_lod);
1495
+ for (const a of E)
1496
+ a.onAfterUpdatedLOD?.(this.renderer, t, e, s, T);
1497
+ n.lastLodLevel_Mesh = T.mesh_lod, n.lastLodLevel_Texture = T.texture_lod;
1400
1498
  }
1401
1499
  /** Load progressive textures for the given material
1402
1500
  * @param material the material to load the textures for
@@ -1411,14 +1509,14 @@ class L {
1411
1509
  return;
1412
1510
  }
1413
1511
  let r = !1;
1414
- (t[z] === void 0 || e < t[z]) && (r = !0);
1512
+ (t[F] === void 0 || e < t[F]) && (r = !0);
1415
1513
  const n = s !== void 0 && s >= 0;
1416
- if (n && (r = t[z] != s, e = s), r) {
1417
- t[z] = e;
1418
- const o = n ? { force: !0 } : void 0, u = p.assignTextureLOD(t, e, o).then((a) => {
1419
- this._lodchangedlisteners.forEach((l) => l({ type: "texture", level: e, object: t }));
1514
+ if (n && (r = t[F] != s, e = s), r) {
1515
+ t[F] = e;
1516
+ const o = n ? { force: !0 } : void 0, a = p.assignTextureLOD(t, e, o).then((l) => {
1517
+ this._lodchangedlisteners.forEach((u) => u({ type: "texture", level: e, object: t }));
1420
1518
  });
1421
- ce.addPromise("texture", t, u, this._newPromiseGroups);
1519
+ oe.addPromise("texture", t, a, this._newPromiseGroups);
1422
1520
  }
1423
1521
  }
1424
1522
  /** Load progressive meshes for the given mesh
@@ -1429,32 +1527,18 @@ class L {
1429
1527
  */
1430
1528
  loadProgressiveMeshes(t, e) {
1431
1529
  if (!t) return Promise.resolve(null);
1432
- let s = t[z] !== e;
1530
+ let s = t[F] !== e;
1433
1531
  const r = t["DEBUG:LOD"];
1434
- if (r != null && (s = t[z] != r, e = r), s) {
1435
- t[z] = e;
1436
- const n = t.geometry, o = p.assignMeshLOD(t, e).then((u) => (u && t[z] == e && n != t.geometry && this._lodchangedlisteners.forEach((a) => a({ type: "mesh", level: e, object: t })), u));
1437
- return ce.addPromise("mesh", t, o, this._newPromiseGroups), o;
1532
+ if (r != null && (s = t[F] != r, e = r), s) {
1533
+ t[F] = e;
1534
+ const n = t.geometry, o = p.assignMeshLOD(t, e).then((a) => (a && t[F] == e && n != t.geometry && this._lodchangedlisteners.forEach((l) => l({ type: "mesh", level: e, object: t })), a));
1535
+ return oe.addPromise("mesh", t, o, this._newPromiseGroups), o;
1438
1536
  }
1439
1537
  return Promise.resolve(null);
1440
1538
  }
1441
1539
  // private testIfLODLevelsAreAvailable() {
1442
- _sphere = new Oe();
1443
- _tempBox = new ge();
1444
- _tempBox2 = new ge();
1445
- tempMatrix = new ve();
1540
+ _sphere = new Ce();
1446
1541
  _tempWorldPosition = new P();
1447
- _tempBoxSize = new P();
1448
- _tempBox2Size = new P();
1449
- static corner0 = new P();
1450
- static corner1 = new P();
1451
- static corner2 = new P();
1452
- static corner3 = new P();
1453
- static _tempPtInside = new P();
1454
- static isInside(t, e) {
1455
- const s = t.min, r = t.max, n = (s.x + r.x) * 0.5, o = (s.y + r.y) * 0.5;
1456
- return this._tempPtInside.set(n, o, s.z).applyMatrix4(e).z < 0;
1457
- }
1458
1542
  static skinnedMeshBoundsFrameOffsetCounter = 0;
1459
1543
  static $skinnedMeshBoundsOffset = /* @__PURE__ */ Symbol("gltf-progressive-skinnedMeshBoundsOffset");
1460
1544
  // #region calculateLodLevel
@@ -1467,105 +1551,86 @@ class L {
1467
1551
  n.mesh_lod = -1, n.texture_lod = -1;
1468
1552
  return;
1469
1553
  }
1470
- let u = 10 + 1, a = !1;
1471
- if (R && e["DEBUG:LOD"] != null)
1554
+ let a = 10 + 1, l = !1;
1555
+ if (A && e["DEBUG:LOD"] != null)
1472
1556
  return e["DEBUG:LOD"];
1473
- const l = p.getMeshLODExtension(e.geometry)?.lods, c = p.getPrimitiveIndex(e.geometry), f = l && l.length > 0, y = p.getMaterialMinMaxLODsCount(e.material), T = y.min_count !== 1 / 0 && y.min_count >= 0 && y.max_count >= 0;
1474
- if (!f && !T) {
1557
+ const u = p.getMeshLODExtension(e.geometry)?.lods, d = p.getPrimitiveIndex(e.geometry), c = u && u.length > 0, f = p.getMaterialMinMaxLODsCount(e.material), g = f.min_count !== 1 / 0 && f.min_count >= 0 && f.max_count >= 0;
1558
+ if (!c && !g) {
1475
1559
  n.mesh_lod = 0, n.texture_lod = 0;
1476
1560
  return;
1477
1561
  }
1478
- f || (a = !0, u = 0);
1479
- const _ = this.renderer.domElement.clientHeight || this.renderer.domElement.height;
1480
- let C = e.geometry.boundingBox;
1562
+ c || (l = !0, a = 0);
1563
+ const O = this.renderer.domElement.clientHeight || this.renderer.domElement.height;
1564
+ let y = e.geometry.boundingBox;
1481
1565
  if (e.type === "SkinnedMesh") {
1482
1566
  const x = e;
1483
1567
  if (!x.boundingBox)
1484
1568
  x.computeBoundingBox();
1485
1569
  else if (this.skinnedMeshAutoUpdateBoundsInterval > 0) {
1486
- if (!x[L.$skinnedMeshBoundsOffset]) {
1487
- const B = L.skinnedMeshBoundsFrameOffsetCounter++;
1488
- x[L.$skinnedMeshBoundsOffset] = B;
1570
+ if (!x[I.$skinnedMeshBoundsOffset]) {
1571
+ const L = I.skinnedMeshBoundsFrameOffsetCounter++;
1572
+ x[I.$skinnedMeshBoundsOffset] = L;
1489
1573
  }
1490
- const m = x[L.$skinnedMeshBoundsOffset];
1491
- if ((s.frames + m) % this.skinnedMeshAutoUpdateBoundsInterval === 0) {
1492
- const B = ee(x), G = x.geometry;
1493
- B && (x.geometry = B), x.computeBoundingBox(), x.geometry = G;
1574
+ const v = x[I.$skinnedMeshBoundsOffset];
1575
+ if ((s.frames + v) % this.skinnedMeshAutoUpdateBoundsInterval === 0) {
1576
+ const L = ne(x), V = x.geometry;
1577
+ L && (x.geometry = L), x.computeBoundingBox(), x.geometry = V;
1494
1578
  }
1495
1579
  }
1496
- C = x.boundingBox;
1580
+ y = x.boundingBox;
1497
1581
  }
1498
- if (C) {
1499
- const x = t;
1582
+ if (y) {
1500
1583
  if (e.geometry.attributes.color && e.geometry.attributes.color.count < 100 && e.geometry.boundingSphere) {
1501
1584
  this._sphere.copy(e.geometry.boundingSphere), this._sphere.applyMatrix4(e.matrixWorld);
1502
- const d = t.getWorldPosition(this._tempWorldPosition);
1503
- if (this._sphere.containsPoint(d)) {
1585
+ const L = t.getWorldPosition(this._tempWorldPosition);
1586
+ if (this._sphere.containsPoint(L)) {
1504
1587
  n.mesh_lod = 0, n.texture_lod = 0;
1505
1588
  return;
1506
1589
  }
1507
1590
  }
1508
- if (this._tempBox.copy(C), this._tempBox.applyMatrix4(e.matrixWorld), x.isPerspectiveCamera && L.isInside(this._tempBox, this.projectionScreenMatrix)) {
1591
+ const x = bt({
1592
+ geometry: e.geometry,
1593
+ matrixWorld: e.matrixWorld,
1594
+ camera: t,
1595
+ projectionScreenMatrix: this.projectionScreenMatrix,
1596
+ desiredDensity: r,
1597
+ canvasHeight: O,
1598
+ currentLevel: s.lastLodLevel_Mesh,
1599
+ boundingBox: y,
1600
+ xrEnabled: this.renderer.xr.enabled,
1601
+ debugDrawLine: A ? I.debugDrawLine : void 0,
1602
+ warnMissingPrimitiveDensities: !0
1603
+ });
1604
+ if (s.lastCentrality = x.centrality, s.lastScreenCoverage = x.screenCoverage, s.lastScreenspaceVolume.copy(x.screenspaceVolume), x.screenCoverage === 1 / 0) {
1509
1605
  n.mesh_lod = 0, n.texture_lod = 0;
1510
1606
  return;
1511
1607
  }
1512
- if (this._tempBox.applyMatrix4(this.projectionScreenMatrix), this.renderer.xr.enabled && x.isPerspectiveCamera && x.fov > 70) {
1513
- const d = this._tempBox.min, g = this._tempBox.max;
1514
- let w = d.x, v = d.y, O = g.x, Y = g.y;
1515
- const te = 2, ie = 1.5, se = (d.x + g.x) * 0.5, re = (d.y + g.y) * 0.5;
1516
- w = (w - se) * te + se, v = (v - re) * te + re, O = (O - se) * te + se, Y = (Y - re) * te + re;
1517
- const We = w < 0 && O > 0 ? 0 : Math.min(Math.abs(d.x), Math.abs(g.x)), Fe = v < 0 && Y > 0 ? 0 : Math.min(Math.abs(d.y), Math.abs(g.y)), ae = Math.max(We, Fe);
1518
- s.lastCentrality = (ie - ae) * (ie - ae) * (ie - ae);
1519
- } else
1520
- s.lastCentrality = 1;
1521
- const m = this._tempBox.getSize(this._tempBoxSize);
1522
- m.multiplyScalar(0.5), screen.availHeight > 0 && _ > 0 && m.multiplyScalar(_ / screen.availHeight), t.isPerspectiveCamera ? m.x *= t.aspect : t.isOrthographicCamera;
1523
- const B = t.matrixWorldInverse, G = this._tempBox2;
1524
- G.copy(C), G.applyMatrix4(e.matrixWorld), G.applyMatrix4(B);
1525
- const A = G.getSize(this._tempBox2Size), S = Math.max(A.x, A.y);
1526
- if (Math.max(m.x, m.y) != 0 && S != 0 && (m.z = A.z / Math.max(A.x, A.y) * Math.max(m.x, m.y)), s.lastScreenCoverage = Math.max(m.x, m.y, m.z), s.lastScreenspaceVolume.copy(m), s.lastScreenCoverage *= s.lastCentrality, R && L.debugDrawLine) {
1527
- const d = this.tempMatrix.copy(this.projectionScreenMatrix);
1528
- d.invert();
1529
- const g = L.corner0, w = L.corner1, v = L.corner2, O = L.corner3;
1530
- g.copy(this._tempBox.min), w.copy(this._tempBox.max), w.x = g.x, v.copy(this._tempBox.max), v.y = g.y, O.copy(this._tempBox.max);
1531
- const Y = (g.z + O.z) * 0.5;
1532
- g.z = w.z = v.z = O.z = Y, g.applyMatrix4(d), w.applyMatrix4(d), v.applyMatrix4(d), O.applyMatrix4(d), L.debugDrawLine(g, w, 255), L.debugDrawLine(g, v, 255), L.debugDrawLine(w, O, 255), L.debugDrawLine(v, O, 255);
1533
- }
1534
- let M = 999;
1535
- if (l && s.lastScreenCoverage > 0)
1536
- for (let d = 0; d < l.length; d++) {
1537
- const g = l[d], v = (g.densities?.[c] || g.density || 1e-5) / s.lastScreenCoverage;
1538
- if (c > 0 && Me() && !g.densities && !globalThis["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"] && (window["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.")), v < r) {
1539
- M = d;
1540
- break;
1541
- }
1542
- }
1543
- M < u && (u = M, a = !0);
1608
+ x.level >= 0 && x.level < a && (a = x.level, l = !0);
1544
1609
  }
1545
- if (a ? n.mesh_lod = u : n.mesh_lod = s.lastLodLevel_Mesh, R && n.mesh_lod != s.lastLodLevel_Mesh) {
1546
- const m = l?.[n.mesh_lod];
1547
- m && console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} → ${n.mesh_lod} (density: ${m.densities?.[c].toFixed(0)}) | ${e.name}`);
1610
+ if (l ? n.mesh_lod = a : n.mesh_lod = s.lastLodLevel_Mesh, A && n.mesh_lod != s.lastLodLevel_Mesh) {
1611
+ const v = u?.[n.mesh_lod];
1612
+ v && console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} → ${n.mesh_lod} (density: ${v.densities?.[d].toFixed(0)}) | ${e.name}`);
1548
1613
  }
1549
- if (T) {
1614
+ if (g) {
1550
1615
  const x = "saveData" in globalThis.navigator && globalThis.navigator.saveData === !0;
1551
1616
  if (s.lastLodLevel_Texture < 0) {
1552
- if (n.texture_lod = y.max_count - 1, R) {
1553
- const m = y.lods[y.max_count - 1];
1554
- R && console.log(`First Texture LOD ${n.texture_lod} (${m.max_height}px) - ${e.name}`);
1617
+ if (n.texture_lod = f.max_count - 1, A) {
1618
+ const v = f.lods[f.max_count - 1];
1619
+ A && console.log(`First Texture LOD ${n.texture_lod} (${v.max_height}px) - ${e.name}`);
1555
1620
  }
1556
1621
  } else {
1557
- const m = s.lastScreenspaceVolume.x + s.lastScreenspaceVolume.y + s.lastScreenspaceVolume.z;
1558
- let B = s.lastScreenCoverage * 4;
1559
- this.context?.engine === "model-viewer" && (B *= 1.5);
1560
- const A = _ / window.devicePixelRatio * B;
1622
+ const v = s.lastScreenspaceVolume.x + s.lastScreenspaceVolume.y + s.lastScreenspaceVolume.z;
1623
+ let L = s.lastScreenCoverage * 4;
1624
+ this.context?.engine === "model-viewer" && (L *= 1.5);
1625
+ const w = O / window.devicePixelRatio * L;
1561
1626
  let S = !1;
1562
- for (let F = y.lods.length - 1; F >= 0; F--) {
1563
- const M = y.lods[F];
1564
- if (!(x && M.max_height >= 2048) && !(Le() && M.max_height > 4096) && (M.max_height > A || !S && F === 0)) {
1565
- if (S = !0, n.texture_lod = F, R && n.texture_lod < s.lastLodLevel_Texture) {
1566
- const b = M.max_height;
1567
- console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${n.texture_lod} = ${b}px
1568
- Screensize: ${A.toFixed(0)}px, Coverage: ${(100 * s.lastScreenCoverage).toFixed(2)}%, Volume ${m.toFixed(1)}
1627
+ for (let _ = f.lods.length - 1; _ >= 0; _--) {
1628
+ const R = f.lods[_];
1629
+ if (!(x && R.max_height >= 2048) && !(_e() && R.max_height > 4096) && (R.max_height > w || !S && _ === 0)) {
1630
+ if (S = !0, n.texture_lod = _, A && n.texture_lod < s.lastLodLevel_Texture) {
1631
+ const C = R.max_height;
1632
+ console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${n.texture_lod} = ${C}px
1633
+ Screensize: ${w.toFixed(0)}px, Coverage: ${(100 * s.lastScreenCoverage).toFixed(2)}%, Volume ${v.toFixed(1)}
1569
1634
  ${e.name}`);
1570
1635
  }
1571
1636
  break;
@@ -1576,7 +1641,7 @@ ${e.name}`);
1576
1641
  n.texture_lod = 0;
1577
1642
  }
1578
1643
  }
1579
- class _t {
1644
+ class Tt {
1580
1645
  frames = 0;
1581
1646
  lastLodLevel_Mesh = -1;
1582
1647
  lastLodLevel_Texture = -1;
@@ -1584,66 +1649,66 @@ class _t {
1584
1649
  lastScreenspaceVolume = new P();
1585
1650
  lastCentrality = 0;
1586
1651
  }
1587
- function $e(i, t) {
1652
+ function qe(i, t) {
1588
1653
  if (!(t < 0)) {
1589
1654
  if (Array.isArray(i)) {
1590
1655
  for (const e of i)
1591
- $e(e, t);
1656
+ qe(e, t);
1592
1657
  return;
1593
1658
  }
1594
- "color" in i && i.color instanceof ke && (i.color.copy(vt(t, Lt)), i.needsUpdate = !0);
1659
+ "color" in i && i.color instanceof ke && (i.color.copy(Ct(t, _t)), i.needsUpdate = !0);
1595
1660
  }
1596
1661
  }
1597
- function vt(i, t) {
1598
- const e = Math.max(0, Math.min(be.length - 1, Math.floor(i)));
1599
- return t.setHex(be[e]);
1662
+ function Ct(i, t) {
1663
+ const e = Math.max(0, Math.min(Me.length - 1, Math.floor(i)));
1664
+ return t.setHex(Me[e]);
1600
1665
  }
1601
- const De = /* @__PURE__ */ Symbol("NEEDLE_mesh_lod"), ne = /* @__PURE__ */ Symbol("NEEDLE_texture_lod");
1602
- let he = null;
1603
- function Be() {
1604
- const i = Mt();
1666
+ const Se = /* @__PURE__ */ Symbol("NEEDLE_mesh_lod"), ae = /* @__PURE__ */ Symbol("NEEDLE_texture_lod");
1667
+ let me = null;
1668
+ function We() {
1669
+ const i = kt();
1605
1670
  i && (i.mapURLs(function(t) {
1606
- return Te(), t;
1607
- }), Te(), he?.disconnect(), he = new MutationObserver((t) => {
1671
+ return be(), t;
1672
+ }), be(), me?.disconnect(), me = new MutationObserver((t) => {
1608
1673
  t.forEach((e) => {
1609
1674
  e.addedNodes.forEach((s) => {
1610
- s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" && Ge(s);
1675
+ s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" && Ue(s);
1611
1676
  });
1612
1677
  });
1613
- }), he.observe(document, { childList: !0, subtree: !0 }));
1678
+ }), me.observe(document, { childList: !0, subtree: !0 }));
1614
1679
  }
1615
- function Mt() {
1680
+ function kt() {
1616
1681
  if (typeof customElements > "u") return null;
1617
1682
  const i = customElements.get("model-viewer");
1618
1683
  return i || (customElements.whenDefined("model-viewer").then(() => {
1619
- console.debug("[gltf-progressive] model-viewer defined"), Be();
1684
+ console.debug("[gltf-progressive] model-viewer defined"), We();
1620
1685
  }), null);
1621
1686
  }
1622
- function Te() {
1687
+ function be() {
1623
1688
  if (typeof document > "u") return;
1624
1689
  document.querySelectorAll("model-viewer").forEach((t) => {
1625
- Ge(t);
1690
+ Ue(t);
1626
1691
  });
1627
1692
  }
1628
- const Se = /* @__PURE__ */ new WeakSet();
1629
- let bt = 0;
1630
- function Ge(i) {
1631
- if (!i || Se.has(i))
1693
+ const Te = /* @__PURE__ */ new WeakSet();
1694
+ let Pt = 0;
1695
+ function Ue(i) {
1696
+ if (!i || Te.has(i))
1632
1697
  return null;
1633
- Se.add(i), console.debug("[gltf-progressive] found new model-viewer..." + ++bt + `
1698
+ Te.add(i), console.debug("[gltf-progressive] found new model-viewer..." + ++Pt + `
1634
1699
  `, i.getAttribute("src"));
1635
1700
  let t = null, e = null, s = null;
1636
1701
  for (let r = i; r != null; r = Object.getPrototypeOf(r)) {
1637
- 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)");
1638
- !t && o != null && (t = i[o].threeRenderer), !e && u != null && (e = i[u]), !s && a != null && (s = i[a]);
1702
+ 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)");
1703
+ !t && o != null && (t = i[o].threeRenderer), !e && a != null && (e = i[a]), !s && l != null && (s = i[l]);
1639
1704
  }
1640
1705
  if (t && e) {
1641
1706
  let r = function() {
1642
1707
  if (s) {
1643
1708
  let o = 0;
1644
- const u = setInterval(() => {
1709
+ const a = setInterval(() => {
1645
1710
  if (o++ > 5) {
1646
- clearInterval(u);
1711
+ clearInterval(a);
1647
1712
  return;
1648
1713
  }
1649
1714
  s?.call(i);
@@ -1651,8 +1716,8 @@ function Ge(i) {
1651
1716
  }
1652
1717
  };
1653
1718
  console.debug("[gltf-progressive] setup model-viewer");
1654
- const n = L.get(t, { engine: "model-viewer" });
1655
- return L.addPlugin(new Dt()), n.enable(), n.addEventListener("changed", () => {
1719
+ const n = I.get(t, { engine: "model-viewer" });
1720
+ return I.addPlugin(new Rt()), n.enable(), n.addEventListener("changed", () => {
1656
1721
  s?.call(i);
1657
1722
  }), i.addEventListener("model-visibility", (o) => {
1658
1723
  o.detail.visible && s?.call(i);
@@ -1664,7 +1729,7 @@ function Ge(i) {
1664
1729
  }
1665
1730
  return null;
1666
1731
  }
1667
- class Dt {
1732
+ class Rt {
1668
1733
  _didWarnAboutMissingUrl = !1;
1669
1734
  onBeforeUpdateLOD(t, e, s, r) {
1670
1735
  this.tryParseMeshLOD(e, r), this.tryParseTextureLOD(e, r);
@@ -1682,39 +1747,39 @@ class Dt {
1682
1747
  return t.element;
1683
1748
  }
1684
1749
  tryParseTextureLOD(t, e) {
1685
- if (e[ne] == !0) return;
1686
- e[ne] = !0;
1750
+ if (e[ae] == !0) return;
1751
+ e[ae] = !0;
1687
1752
  const s = this.tryGetCurrentGLTF(t), r = this.tryGetCurrentModelViewer(t), n = this.getUrl(r);
1688
1753
  if (n && s && e.material) {
1689
- let o = function(a) {
1690
- if (a[ne] == !0) return;
1691
- a[ne] = !0, a.userData && (a.userData.LOD = -1);
1692
- const l = Object.keys(a);
1693
- for (let c = 0; c < l.length; c++) {
1694
- const f = l[c], y = a[f];
1695
- if (y?.isTexture === !0) {
1696
- const T = y.userData?.associations?.textures;
1697
- if (T == null) continue;
1698
- const _ = s.parser.json.textures[T];
1699
- if (!_) {
1700
- console.warn("Texture data not found for texture index " + T);
1754
+ let o = function(l) {
1755
+ if (l[ae] == !0) return;
1756
+ l[ae] = !0, l.userData && (l.userData.LOD = -1);
1757
+ const u = Object.keys(l);
1758
+ for (let d = 0; d < u.length; d++) {
1759
+ const c = u[d], f = l[c];
1760
+ if (f?.isTexture === !0) {
1761
+ const g = f.userData?.associations?.textures;
1762
+ if (g == null) continue;
1763
+ const O = s.parser.json.textures[g];
1764
+ if (!O) {
1765
+ console.warn("Texture data not found for texture index " + g);
1701
1766
  continue;
1702
1767
  }
1703
- if (_?.extensions?.[U]) {
1704
- const C = _.extensions[U];
1705
- C && n && p.registerTexture(n, y, C.lods.length, T, C);
1768
+ if (O?.extensions?.[U]) {
1769
+ const y = O.extensions[U];
1770
+ y && n && p.registerTexture(n, f, y.lods.length, g, y);
1706
1771
  }
1707
1772
  }
1708
1773
  }
1709
1774
  };
1710
- const u = e.material;
1711
- if (Array.isArray(u)) for (const a of u) o(a);
1712
- else o(u);
1775
+ const a = e.material;
1776
+ if (Array.isArray(a)) for (const l of a) o(l);
1777
+ else o(a);
1713
1778
  }
1714
1779
  }
1715
1780
  tryParseMeshLOD(t, e) {
1716
- if (e[De] == !0) return;
1717
- e[De] = !0;
1781
+ if (e[Se] == !0) return;
1782
+ e[Se] = !0;
1718
1783
  const s = this.tryGetCurrentModelViewer(t), r = this.getUrl(s);
1719
1784
  if (!r)
1720
1785
  return;
@@ -1725,7 +1790,7 @@ class Dt {
1725
1790
  }
1726
1791
  }
1727
1792
  }
1728
- function Tt(...i) {
1793
+ function At(...i) {
1729
1794
  let t, e, s, r;
1730
1795
  switch (i.length) {
1731
1796
  case 2:
@@ -1740,22 +1805,22 @@ function Tt(...i) {
1740
1805
  default:
1741
1806
  throw new Error("Invalid arguments");
1742
1807
  }
1743
- we(e), Pe(s), Re(s, {
1808
+ ve(e), Ae(s), $e(s, {
1744
1809
  progressive: !0,
1745
1810
  ...r?.hints
1746
1811
  }), s.register((o) => new p(o));
1747
- const n = L.get(e);
1812
+ const n = I.get(e);
1748
1813
  return r?.enableLODsManager !== !1 && n.enable(), n;
1749
1814
  }
1750
- Be();
1751
- if (!lt) {
1815
+ We();
1816
+ if (!ct) {
1752
1817
  const i = {
1753
1818
  gltfProgressive: {
1754
- useNeedleProgressive: Tt,
1755
- LODsManager: L,
1756
- configureLoader: Re,
1757
- getRaycastMesh: ee,
1758
- useRaycastMeshes: ct
1819
+ useNeedleProgressive: At,
1820
+ LODsManager: I,
1821
+ configureLoader: $e,
1822
+ getRaycastMesh: ne,
1823
+ useRaycastMeshes: ft
1759
1824
  }
1760
1825
  };
1761
1826
  if (!globalThis.Needle)
@@ -1766,19 +1831,20 @@ if (!lt) {
1766
1831
  }
1767
1832
  export {
1768
1833
  U as EXTENSION_NAME,
1769
- L as LODsManager,
1834
+ I as LODsManager,
1770
1835
  p as NEEDLE_progressive,
1771
- He as VERSION,
1772
- Pe as addDracoAndKTX2Loaders,
1773
- Re as configureLoader,
1774
- we as createLoaders,
1775
- vt as getLODColor,
1776
- ee as getRaycastMesh,
1777
- be as lodDebugColors,
1778
- Be as patchModelViewer,
1779
- ut as registerRaycastMesh,
1780
- et as setDracoDecoderLocation,
1781
- tt as setKTX2TranscoderLocation,
1782
- Tt as useNeedleProgressive,
1783
- ct as useRaycastMeshes
1836
+ Je as VERSION,
1837
+ Ae as addDracoAndKTX2Loaders,
1838
+ bt as calculateMeshLODLevel,
1839
+ $e as configureLoader,
1840
+ ve as createLoaders,
1841
+ Ct as getLODColor,
1842
+ ne as getRaycastMesh,
1843
+ Me as lodDebugColors,
1844
+ We as patchModelViewer,
1845
+ dt as registerRaycastMesh,
1846
+ st as setDracoDecoderLocation,
1847
+ rt as setKTX2TranscoderLocation,
1848
+ At as useNeedleProgressive,
1849
+ ft as useRaycastMeshes
1784
1850
  };