@needle-tools/gltf-progressive 3.4.0-beta → 3.4.0-beta.1

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,89 +1,89 @@
1
- import { BufferGeometry as E, Mesh as V, Box3 as he, Vector3 as C, Sphere as De, CompressedTexture as Be, Texture as F, Matrix3 as Ge, InterleavedBuffer as Fe, InterleavedBufferAttribute as We, BufferAttribute as Ue, TextureLoader as ze, Matrix4 as _e, Clock as Ne, MeshStandardMaterial as qe } from "three";
2
- import { GLTFLoader as ye } from "three/examples/jsm/loaders/GLTFLoader.js";
3
- import { MeshoptDecoder as Ee } from "three/examples/jsm/libs/meshopt_decoder.module.js";
4
- import { DRACOLoader as Ve } from "three/examples/jsm/loaders/DRACOLoader.js";
5
- import { KTX2Loader as Xe } from "three/examples/jsm/loaders/KTX2Loader.js";
6
- const je = "";
7
- globalThis.GLTF_PROGRESSIVE_VERSION = je;
1
+ import { BufferGeometry as V, Mesh as X, Box3 as ge, Vector3 as A, Sphere as Oe, CompressedTexture as Ge, Texture as F, Matrix3 as Fe, InterleavedBuffer as We, InterleavedBufferAttribute as Ue, BufferAttribute as ze, TextureLoader as Ne, Matrix4 as Le, Clock as qe, MeshStandardMaterial as Ee } from "three";
2
+ import { GLTFLoader as xe } from "three/examples/jsm/loaders/GLTFLoader.js";
3
+ import { MeshoptDecoder as Ve } from "three/examples/jsm/libs/meshopt_decoder.module.js";
4
+ import { DRACOLoader as Xe } from "three/examples/jsm/loaders/DRACOLoader.js";
5
+ import { KTX2Loader as je } from "three/examples/jsm/loaders/KTX2Loader.js";
6
+ const Ke = "";
7
+ globalThis.GLTF_PROGRESSIVE_VERSION = Ke;
8
8
  console.debug("[gltf-progressive] version -");
9
- let R = "https://www.gstatic.com/draco/versioned/decoders/1.5.7/", X = "https://cdn.needle.tools/static/three/0.179.1/basis2/";
10
- const Ye = R, Ke = X, Oe = new URL(R + "draco_decoder.js");
11
- Oe.searchParams.append("range", "true");
12
- fetch(Oe, {
9
+ let I = "https://www.gstatic.com/draco/versioned/decoders/1.5.7/", j = "https://cdn.needle.tools/static/three/0.179.1/basis2/";
10
+ const Ye = I, He = j, Se = new URL(I + "draco_decoder.js");
11
+ Se.searchParams.append("range", "true");
12
+ fetch(Se, {
13
13
  method: "GET",
14
14
  headers: {
15
15
  Range: "bytes=0-1"
16
16
  }
17
- }).catch((i) => {
18
- console.debug(`Failed to fetch remote Draco decoder from ${R} (offline: ${typeof navigator < "u" ? navigator.onLine : "unknown"})`), R === Ye && Qe("./include/draco/"), X === Ke && Je("./include/ktx2/");
17
+ }).catch((n) => {
18
+ console.debug(`Failed to fetch remote Draco decoder from ${I} (offline: ${typeof navigator < "u" ? navigator.onLine : "unknown"})`), I === Ye && Je("./include/draco/"), j === He && Ze("./include/ktx2/");
19
19
  }).finally(() => {
20
- Pe();
20
+ Te();
21
21
  });
22
- const He = () => ({
23
- dracoDecoderPath: R,
24
- ktx2TranscoderPath: X
22
+ const Qe = () => ({
23
+ dracoDecoderPath: I,
24
+ ktx2TranscoderPath: j
25
25
  });
26
- function Qe(i) {
27
- R = i, A && A[ge] != R ? (console.debug("Updating Draco decoder path to " + i), A[ge] = R, A.setDecoderPath(R), A.preload()) : console.debug("Setting Draco decoder path to " + i);
26
+ function Je(n) {
27
+ I = n, C && C[pe] != I ? (console.debug("Updating Draco decoder path to " + n), C[pe] = I, C.setDecoderPath(I), C.preload()) : console.debug("Setting Draco decoder path to " + n);
28
28
  }
29
- function Je(i) {
30
- X = i, $ && $.transcoderPath != X ? (console.debug("Updating KTX2 transcoder path to " + i), $.setTranscoderPath(X), $.init()) : console.debug("Setting KTX2 transcoder path to " + i);
29
+ function Ze(n) {
30
+ j = n, $ && $.transcoderPath != j ? (console.debug("Updating KTX2 transcoder path to " + n), $.setTranscoderPath(j), $.init()) : console.debug("Setting KTX2 transcoder path to " + n);
31
31
  }
32
- function xe(i) {
33
- return Pe(), i ? $.detectSupport(i) : i !== null && console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"), { dracoLoader: A, ktx2Loader: $, meshoptDecoder: oe };
32
+ function we(n) {
33
+ return Te(), n ? $.detectSupport(n) : n !== null && console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"), { dracoLoader: C, ktx2Loader: $, meshoptDecoder: oe };
34
34
  }
35
- function Se(i) {
36
- i.dracoLoader || i.setDRACOLoader(A), i.ktx2Loader || i.setKTX2Loader($), i.meshoptDecoder || i.setMeshoptDecoder(oe);
35
+ function Pe(n) {
36
+ n.dracoLoader || n.setDRACOLoader(C), n.ktx2Loader || n.setKTX2Loader($), n.meshoptDecoder || n.setMeshoptDecoder(oe);
37
37
  }
38
- const ge = /* @__PURE__ */ Symbol("dracoDecoderPath");
39
- let A, oe, $;
40
- function Pe() {
41
- A || (A = new Ve(), A[ge] = R, A.setDecoderPath(R), A.setDecoderConfig({ type: "js" }), A.preload()), $ || ($ = new Xe(), $.setTranscoderPath(X), $.init()), oe || (oe = Ee);
38
+ const pe = /* @__PURE__ */ Symbol("dracoDecoderPath");
39
+ let C, oe, $;
40
+ function Te() {
41
+ C || (C = new Xe(), C[pe] = I, C.setDecoderPath(I), C.setDecoderConfig({ type: "js" }), C.preload()), $ || ($ = new je(), $.setTranscoderPath(j), $.init()), oe || (oe = Ve);
42
42
  }
43
- const pe = /* @__PURE__ */ new WeakMap();
44
- function Te(i, t) {
45
- let e = pe.get(i);
46
- e ? e = Object.assign(e, t) : e = t, pe.set(i, e);
43
+ const me = /* @__PURE__ */ new WeakMap();
44
+ function Ce(n, t) {
45
+ let e = me.get(n);
46
+ e ? e = Object.assign(e, t) : e = t, me.set(n, e);
47
47
  }
48
- const Ze = ye.prototype.load;
49
- function et(...i) {
50
- const t = pe.get(this);
51
- let e = i[0];
48
+ const et = xe.prototype.load;
49
+ function tt(...n) {
50
+ const t = me.get(this);
51
+ let e = n[0];
52
52
  const s = new URL(e, window.location.href);
53
53
  if (s.hostname.endsWith("needle.tools")) {
54
- const r = t?.progressive !== void 0 ? t.progressive : !0, n = t?.usecase ? t.usecase : "default";
55
- r ? this.requestHeader.Accept = `*/*;progressive=allowed;usecase=${n}` : this.requestHeader.Accept = `*/*;usecase=${n}`, e = s.toString();
54
+ const i = t?.progressive !== void 0 ? t.progressive : !0, o = t?.usecase ? t.usecase : "default";
55
+ i ? this.requestHeader.Accept = `*/*;progressive=allowed;usecase=${o}` : this.requestHeader.Accept = `*/*;usecase=${o}`, e = s.toString();
56
56
  }
57
- return i[0] = e, Ze?.call(this, ...i);
57
+ return n[0] = e, et?.call(this, ...n);
58
58
  }
59
- ye.prototype.load = et;
60
- j("debugprogressive");
61
- function j(i) {
59
+ xe.prototype.load = tt;
60
+ N("debugprogressive");
61
+ function N(n) {
62
62
  if (typeof window > "u") return !1;
63
- const e = new URL(window.location.href).searchParams.get(i);
63
+ const e = new URL(window.location.href).searchParams.get(n);
64
64
  return e == null || e === "0" || e === "false" ? !1 : e === "" ? !0 : e;
65
65
  }
66
- function tt(i, t) {
67
- if (t === void 0 || i === void 0 || t.startsWith("./") || t.startsWith("http") || t.startsWith("data:") || t.startsWith("blob:"))
66
+ function st(n, t) {
67
+ if (t === void 0 || n === void 0 || t.startsWith("./") || t.startsWith("http") || t.startsWith("data:") || t.startsWith("blob:"))
68
68
  return t;
69
- const e = i.lastIndexOf("/");
69
+ const e = n.lastIndexOf("/");
70
70
  if (e >= 0) {
71
- const s = i.substring(0, e + 1);
71
+ const s = n.substring(0, e + 1);
72
72
  for (; s.endsWith("/") && t.startsWith("/"); ) t = t.substring(1);
73
73
  return s + t;
74
74
  }
75
75
  return t;
76
76
  }
77
77
  function Ae() {
78
- return K !== void 0 || (K = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent), j("debugprogressive") && console.log("[glTF Progressive]: isMobileDevice", K)), K;
78
+ return H !== void 0 || (H = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent), N("debugprogressive") && console.log("[glTF Progressive]: isMobileDevice", H)), H;
79
79
  }
80
- let K;
81
- function Le() {
80
+ let H;
81
+ function ve() {
82
82
  if (typeof window > "u") return !1;
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
- return i.hostname === "127.0.0.1" || t;
83
+ const n = new URL(window.location.href), t = n.hostname === "localhost" || /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(n.hostname);
84
+ return n.hostname === "127.0.0.1" || t;
85
85
  }
86
- class st {
86
+ class rt {
87
87
  constructor(t = 100, e = {}) {
88
88
  this.maxConcurrent = t, this.debug = e.debug ?? !1, window.requestAnimationFrame(this.tick);
89
89
  }
@@ -110,87 +110,99 @@ class st {
110
110
  const t = this.maxConcurrent - this._running.size;
111
111
  for (let e = 0; e < t && this._queue.length > 0; e++) {
112
112
  this.debug && console.debug(`[PromiseQueue]: Running ${this._running.size} promises, waiting for ${this._queue.length} more.`);
113
- const { key: s, resolve: o } = this._queue.shift();
114
- o({
115
- use: (r) => this.add(s, r)
113
+ const { key: s, resolve: r } = this._queue.shift();
114
+ r({
115
+ use: (i) => this.add(s, i)
116
116
  });
117
117
  }
118
118
  }
119
119
  }
120
- const rt = typeof window > "u" && typeof document > "u", me = /* @__PURE__ */ Symbol("needle:raycast-mesh");
121
- function Z(i) {
122
- return i?.[me] instanceof E ? i[me] : null;
120
+ function it(n) {
121
+ const t = n.image?.width ?? 0, e = n.image?.height ?? 0, s = n.image?.depth ?? 1, r = Math.floor(Math.log2(Math.max(t, e, s))) + 1, i = ot(n);
122
+ return t * e * s * i * (1 - Math.pow(0.25, r)) / (1 - 0.25);
123
123
  }
124
- function ot(i, t) {
125
- if ((i.type === "Mesh" || i.type === "SkinnedMesh") && !Z(i)) {
126
- const s = it(t);
127
- s.userData = { isRaycastMesh: !0 }, i[me] = s;
124
+ function ot(n) {
125
+ let t = 4;
126
+ const e = n.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);
128
+ let s = 1;
129
+ const r = n.type;
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
+ }
132
+ const nt = typeof window > "u" && typeof document > "u", ye = /* @__PURE__ */ Symbol("needle:raycast-mesh");
133
+ function ee(n) {
134
+ return n?.[ye] instanceof V ? n[ye] : null;
135
+ }
136
+ function at(n, t) {
137
+ if ((n.type === "Mesh" || n.type === "SkinnedMesh") && !ee(n)) {
138
+ const s = ut(t);
139
+ s.userData = { isRaycastMesh: !0 }, n[ye] = s;
128
140
  }
129
141
  }
130
- function nt(i = !0) {
131
- if (i) {
132
- if (H) return;
133
- const t = H = V.prototype.raycast;
134
- V.prototype.raycast = function(e, s) {
135
- const o = this, r = Z(o);
136
- let n;
137
- r && o.isMesh && (n = o.geometry, o.geometry = r), t.call(this, e, s), n && (o.geometry = n);
142
+ function lt(n = !0) {
143
+ if (n) {
144
+ if (Q) return;
145
+ const t = Q = X.prototype.raycast;
146
+ X.prototype.raycast = function(e, s) {
147
+ const r = this, i = ee(r);
148
+ let o;
149
+ i && r.isMesh && (o = r.geometry, r.geometry = i), t.call(this, e, s), o && (r.geometry = o);
138
150
  };
139
151
  } else {
140
- if (!H) return;
141
- V.prototype.raycast = H, H = null;
152
+ if (!Q) return;
153
+ X.prototype.raycast = Q, Q = null;
142
154
  }
143
155
  }
144
- let H = null;
145
- function it(i) {
146
- const t = new E();
147
- for (const e in i.attributes)
148
- t.setAttribute(e, i.getAttribute(e));
149
- return t.setIndex(i.getIndex()), t;
156
+ let Q = null;
157
+ function ut(n) {
158
+ const t = new V();
159
+ for (const e in n.attributes)
160
+ t.setAttribute(e, n.getAttribute(e));
161
+ return t.setIndex(n.getIndex()), t;
150
162
  }
151
- const z = new Array(), h = j("debugprogressive");
152
- let J, q = -1;
153
- if (h) {
154
- let i = function() {
155
- q += 1, q >= t && (q = -1), console.log(`Toggle LOD level [${q}]`);
163
+ const z = new Array(), f = N("debugprogressive");
164
+ let Z, E = -1;
165
+ if (f) {
166
+ let n = function() {
167
+ E += 1, E >= t && (E = -1), console.log(`Toggle LOD level [${E}]`);
156
168
  }, t = 6;
157
169
  window.addEventListener("keyup", (e) => {
158
- e.key === "p" && i(), e.key === "w" && (J = !J, console.log(`Toggle wireframe [${J}]`));
170
+ e.key === "p" && n(), e.key === "w" && (Z = !Z, console.log(`Toggle wireframe [${Z}]`));
159
171
  const s = parseInt(e.key);
160
- !isNaN(s) && s >= 0 && (q = s, console.log(`Set LOD level to [${q}]`));
172
+ !isNaN(s) && s >= 0 && (E = s, console.log(`Set LOD level to [${E}]`));
161
173
  });
162
174
  }
163
- function Ce(i) {
164
- if (h && J !== void 0)
165
- if (Array.isArray(i))
166
- for (const t of i)
167
- Ce(t);
168
- else i && "wireframe" in i && (i.wireframe = J === !0);
175
+ function ke(n) {
176
+ if (f && Z !== void 0)
177
+ if (Array.isArray(n))
178
+ for (const t of n)
179
+ ke(t);
180
+ else n && "wireframe" in n && (n.wireframe = Z === !0);
169
181
  }
170
- const Q = new Array();
171
- let at = 0;
172
- const lt = Ae() ? 2 : 10;
173
- function ut(i) {
174
- if (Q.length < lt) {
175
- const s = Q.length;
176
- h && console.warn(`[Worker] Creating new worker #${s}`);
177
- const o = we.createWorker(i || {});
178
- return Q.push(o), o;
179
- }
180
- const t = at++ % Q.length;
181
- return Q[t];
182
+ const J = new Array();
183
+ let ct = 0;
184
+ const dt = Ae() ? 2 : 10;
185
+ function ft(n) {
186
+ if (J.length < dt) {
187
+ const s = J.length;
188
+ f && console.warn(`[Worker] Creating new worker #${s}`);
189
+ const r = _e.createWorker(n || {});
190
+ return J.push(r), r;
191
+ }
192
+ const t = ct++ % J.length;
193
+ return J[t];
182
194
  }
183
- class we {
195
+ class _e {
184
196
  constructor(t, e) {
185
197
  this.worker = t, this._debug = e.debug ?? !1, t.onmessage = (s) => {
186
- const o = s.data;
187
- switch (this._debug && console.log("[Worker] EVENT", o), o.type) {
198
+ const r = s.data;
199
+ switch (this._debug && console.log("[Worker] EVENT", r), r.type) {
188
200
  case "loaded-gltf":
189
- for (const r of this._running)
190
- if (r.url === o.result.url) {
191
- dt(o.result), r.resolve(o.result);
192
- const n = r.url;
193
- n.startsWith("blob:") && URL.revokeObjectURL(n);
201
+ for (const i of this._running)
202
+ if (i.url === r.result.url) {
203
+ ht(r.result), i.resolve(r.result);
204
+ const o = i.url;
205
+ o.startsWith("blob:") && URL.revokeObjectURL(o);
194
206
  }
195
207
  }
196
208
  }, t.onerror = (s) => {
@@ -207,18 +219,18 @@ class we {
207
219
  ), {
208
220
  type: "module"
209
221
  });
210
- return new we(e, t);
222
+ return new _e(e, t);
211
223
  }
212
224
  _running = [];
213
225
  _webglRenderer = null;
214
226
  async load(t, e) {
215
- const s = He();
216
- let o = e?.renderer;
217
- o || (this._webglRenderer ??= (async () => {
227
+ const s = Qe();
228
+ let r = e?.renderer;
229
+ r || (this._webglRenderer ??= (async () => {
218
230
  const { WebGLRenderer: u } = await import("three");
219
231
  return new u();
220
- })(), o = await this._webglRenderer);
221
- const l = xe(o).ktx2Loader.workerConfig;
232
+ })(), r = await this._webglRenderer);
233
+ const l = we(r).ktx2Loader.workerConfig;
222
234
  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());
223
235
  const a = {
224
236
  type: "load",
@@ -236,51 +248,51 @@ class we {
236
248
  }
237
249
  _debug = !1;
238
250
  }
239
- function dt(i) {
240
- for (const t of i.geometries) {
241
- const e = t.geometry, s = new E();
251
+ function ht(n) {
252
+ for (const t of n.geometries) {
253
+ const e = t.geometry, s = new V();
242
254
  if (s.name = e.name || "", e.index) {
243
- const o = e.index;
244
- s.setIndex(ae(o));
255
+ const r = e.index;
256
+ s.setIndex(le(r));
245
257
  }
246
- for (const o in e.attributes) {
247
- const r = e.attributes[o], n = ae(r);
248
- s.setAttribute(o, n);
258
+ for (const r in e.attributes) {
259
+ const i = e.attributes[r], o = le(i);
260
+ s.setAttribute(r, o);
249
261
  }
250
262
  if (e.morphAttributes)
251
- for (const o in e.morphAttributes) {
252
- const n = e.morphAttributes[o].map((l) => ae(l));
253
- s.morphAttributes[o] = n;
263
+ for (const r in e.morphAttributes) {
264
+ const o = e.morphAttributes[r].map((l) => le(l));
265
+ s.morphAttributes[r] = o;
254
266
  }
255
- if (s.morphTargetsRelative = e.morphTargetsRelative ?? !1, s.boundingBox = new he(), s.boundingBox.min = new C(
267
+ if (s.morphTargetsRelative = e.morphTargetsRelative ?? !1, s.boundingBox = new ge(), s.boundingBox.min = new A(
256
268
  e.boundingBox?.min.x,
257
269
  e.boundingBox?.min.y,
258
270
  e.boundingBox?.min.z
259
- ), s.boundingBox.max = new C(
271
+ ), s.boundingBox.max = new A(
260
272
  e.boundingBox?.max.x,
261
273
  e.boundingBox?.max.y,
262
274
  e.boundingBox?.max.z
263
- ), s.boundingSphere = new De(
264
- new C(
275
+ ), s.boundingSphere = new Oe(
276
+ new A(
265
277
  e.boundingSphere?.center.x,
266
278
  e.boundingSphere?.center.y,
267
279
  e.boundingSphere?.center.z
268
280
  ),
269
281
  e.boundingSphere?.radius
270
282
  ), e.groups)
271
- for (const o of e.groups)
272
- s.addGroup(o.start, o.count, o.materialIndex);
283
+ for (const r of e.groups)
284
+ s.addGroup(r.start, r.count, r.materialIndex);
273
285
  e.userData && (s.userData = e.userData), t.geometry = s;
274
286
  }
275
- for (const t of i.textures) {
287
+ for (const t of n.textures) {
276
288
  const e = t.texture;
277
289
  let s = null;
278
290
  if (e.isCompressedTexture) {
279
- const o = e.mipmaps, r = e.image?.width || e.source?.data?.width || -1, n = e.image?.height || e.source?.data?.height || -1;
280
- s = new Be(
281
- o,
291
+ const r = e.mipmaps, i = e.image?.width || e.source?.data?.width || -1, o = e.image?.height || e.source?.data?.height || -1;
292
+ s = new Ge(
282
293
  r,
283
- n,
294
+ i,
295
+ o,
284
296
  e.format,
285
297
  e.type,
286
298
  e.mapping,
@@ -303,25 +315,27 @@ function dt(i) {
303
315
  e.type,
304
316
  e.anisotropy,
305
317
  e.colorSpace
306
- ), 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 Ge(...e.matrix.elements);
318
+ ), 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 Fe(...e.matrix.elements);
307
319
  if (!s) {
308
320
  console.error("[Worker] Failed to create new texture from received data. Texture is not a CompressedTexture or Texture.");
309
321
  continue;
310
322
  }
311
323
  t.texture = s;
312
324
  }
313
- return i;
325
+ return n;
314
326
  }
315
- function ae(i) {
316
- let t = i;
317
- if ("isInterleavedBufferAttribute" in i && i.isInterleavedBufferAttribute) {
318
- const e = i.data, s = e.array, o = new Fe(s, e.stride);
319
- t = new We(o, i.itemSize, s.byteOffset, i.normalized), t.offset = i.offset;
320
- } else "isBufferAttribute" in i && i.isBufferAttribute && (t = new Ue(i.array, i.itemSize, i.normalized), t.usage = i.usage, t.gpuType = i.gpuType, t.updateRanges = i.updateRanges);
327
+ function le(n) {
328
+ let t = n;
329
+ if ("isInterleavedBufferAttribute" in n && n.isInterleavedBufferAttribute) {
330
+ const e = n.data, s = e.array, r = new We(s, e.stride);
331
+ t = new Ue(r, n.itemSize, s.byteOffset, n.normalized), t.offset = n.offset;
332
+ } else "isBufferAttribute" in n && n.isBufferAttribute && (t = new ze(n.array, n.itemSize, n.normalized), t.usage = n.usage, t.gpuType = n.gpuType, t.updateRanges = n.updateRanges);
321
333
  return t;
322
334
  }
323
- const ct = j("gltf-progressive-worker"), ft = j("gltf-progressive-reduce-mipmaps"), le = /* @__PURE__ */ Symbol("needle-progressive-texture"), W = "NEEDLE_progressive";
324
- class m {
335
+ const gt = N("gltf-progressive-worker");
336
+ N("gltf-progressive-reduce-mipmaps");
337
+ const K = N("gltf-progressive-gc"), ue = /* @__PURE__ */ Symbol("needle-progressive-texture"), W = "NEEDLE_progressive";
338
+ class y {
325
339
  /** The name of the extension */
326
340
  get name() {
327
341
  return W;
@@ -336,8 +350,8 @@ class m {
336
350
  return e ?? -1;
337
351
  }
338
352
  static getMaterialMinMaxLODsCount(t, e) {
339
- const s = this, o = "LODS:minmax", r = t[o];
340
- if (r != null) return r;
353
+ const s = this, r = "LODS:minmax", i = t[r];
354
+ if (i != null) return i;
341
355
  if (e || (e = {
342
356
  min_count: 1 / 0,
343
357
  max_count: 0,
@@ -345,31 +359,31 @@ class m {
345
359
  }), Array.isArray(t)) {
346
360
  for (const l of t)
347
361
  this.getMaterialMinMaxLODsCount(l, e);
348
- return t[o] = e, e;
362
+ return t[r] = e, e;
349
363
  }
350
- if (h === "verbose" && console.log("getMaterialMinMaxLODsCount", t), t.type === "ShaderMaterial" || t.type === "RawShaderMaterial") {
364
+ if (f === "verbose" && console.log("getMaterialMinMaxLODsCount", t), t.type === "ShaderMaterial" || t.type === "RawShaderMaterial") {
351
365
  const l = t;
352
366
  for (const a of Object.keys(l.uniforms)) {
353
367
  const u = l.uniforms[a].value;
354
- u?.isTexture === !0 && n(u, e);
368
+ u?.isTexture === !0 && o(u, e);
355
369
  }
356
370
  } else if (t.isMaterial)
357
371
  for (const l of Object.keys(t)) {
358
372
  const a = t[l];
359
- a?.isTexture === !0 && n(a, e);
373
+ a?.isTexture === !0 && o(a, e);
360
374
  }
361
375
  else
362
- h && console.warn(`[getMaterialMinMaxLODsCount] Unsupported material type: ${t.type}`);
363
- return t[o] = e, e;
364
- function n(l, a) {
376
+ f && console.warn(`[getMaterialMinMaxLODsCount] Unsupported material type: ${t.type}`);
377
+ return t[r] = e, e;
378
+ function o(l, a) {
365
379
  const u = s.getAssignedLODInformation(l);
366
380
  if (u) {
367
- const d = s.lodInfos.get(u.key);
368
- if (d && d.lods) {
369
- a.min_count = Math.min(a.min_count, d.lods.length), a.max_count = Math.max(a.max_count, d.lods.length);
370
- for (let y = 0; y < d.lods.length; y++) {
371
- const w = d.lods[y];
372
- w.width && (a.lods[y] = a.lods[y] || { min_height: 1 / 0, max_height: 0 }, a.lods[y].min_height = Math.min(a.lods[y].min_height, w.height), a.lods[y].max_height = Math.max(a.lods[y].max_height, w.height));
381
+ const c = s.lodInfos.get(u.key);
382
+ if (c && c.lods) {
383
+ a.min_count = Math.min(a.min_count, c.lods.length), a.max_count = Math.max(a.max_count, c.lods.length);
384
+ for (let m = 0; m < c.lods.length; m++) {
385
+ const w = c.lods[m];
386
+ w.width && (a.lods[m] = a.lods[m] || { min_height: 1 / 0, max_height: 0 }, a.lods[m].min_height = Math.min(a.lods[m].min_height, w.height), a.lods[m].max_height = Math.max(a.lods[m].max_height, w.height));
373
387
  }
374
388
  }
375
389
  }
@@ -382,28 +396,28 @@ class m {
382
396
  */
383
397
  static hasLODLevelAvailable(t, e) {
384
398
  if (Array.isArray(t)) {
385
- for (const r of t)
386
- if (this.hasLODLevelAvailable(r, e)) return !0;
399
+ for (const i of t)
400
+ if (this.hasLODLevelAvailable(i, e)) return !0;
387
401
  return !1;
388
402
  }
389
403
  if (t.isMaterial === !0) {
390
- for (const r of Object.keys(t)) {
391
- const n = t[r];
392
- if (n && n.isTexture && this.hasLODLevelAvailable(n, e))
404
+ for (const i of Object.keys(t)) {
405
+ const o = t[i];
406
+ if (o && o.isTexture && this.hasLODLevelAvailable(o, e))
393
407
  return !0;
394
408
  }
395
409
  return !1;
396
410
  } else if (t.isGroup === !0) {
397
- for (const r of t.children)
398
- if (r.isMesh === !0 && this.hasLODLevelAvailable(r, e))
411
+ for (const i of t.children)
412
+ if (i.isMesh === !0 && this.hasLODLevelAvailable(i, e))
399
413
  return !0;
400
414
  }
401
- let s, o;
415
+ let s, r;
402
416
  if (t.isMesh ? s = t.geometry : (t.isBufferGeometry || t.isTexture) && (s = t), s && s?.userData?.LODS) {
403
- const r = s.userData.LODS;
404
- if (o = this.lodInfos.get(r.key), e === void 0) return o != null;
405
- if (o)
406
- return Array.isArray(o.lods) ? e < o.lods.length : e === 0;
417
+ const i = s.userData.LODS;
418
+ if (r = this.lodInfos.get(i.key), e === void 0) return r != null;
419
+ if (r)
420
+ return Array.isArray(r.lods) ? e < r.lods.length : e === 0;
407
421
  }
408
422
  return !1;
409
423
  }
@@ -423,20 +437,20 @@ class m {
423
437
  */
424
438
  static assignMeshLOD(t, e) {
425
439
  if (!t) return Promise.resolve(null);
426
- if (t instanceof V || t.isMesh === !0) {
427
- const s = t.geometry, o = this.getAssignedLODInformation(s);
428
- if (!o)
440
+ if (t instanceof X || t.isMesh === !0) {
441
+ const s = t.geometry, r = this.getAssignedLODInformation(s);
442
+ if (!r)
429
443
  return Promise.resolve(null);
430
- for (const r of z)
431
- r.onBeforeGetLODMesh?.(t, e);
432
- return t["LOD:requested level"] = e, m.getOrLoadLOD(s, e).then((r) => {
433
- if (Array.isArray(r)) {
434
- const n = o.index || 0;
435
- r = r[n];
444
+ for (const i of z)
445
+ i.onBeforeGetLODMesh?.(t, e);
446
+ return t["LOD:requested level"] = e, y.getOrLoadLOD(s, e).then((i) => {
447
+ if (Array.isArray(i)) {
448
+ const o = r.index || 0;
449
+ i = i[o];
436
450
  }
437
- return t["LOD:requested level"] === e && (delete t["LOD:requested level"], r && s != r && (r?.isBufferGeometry ? t.geometry = r : h && console.error("Invalid LOD geometry", r))), r;
438
- }).catch((r) => (console.error("Error loading mesh LOD", t, r), null));
439
- } else h && console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh", t);
451
+ return t["LOD:requested level"] === e && (delete t["LOD:requested level"], i && s != i && (i?.isBufferGeometry ? t.geometry = i : f && console.error("Invalid LOD geometry", i))), i;
452
+ }).catch((i) => (console.error("Error loading mesh LOD", t, i), null));
453
+ } else f && console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh", t);
440
454
  return Promise.resolve(null);
441
455
  }
442
456
  static assignTextureLOD(t, e = 0) {
@@ -444,44 +458,44 @@ class m {
444
458
  if (t.isMesh === !0) {
445
459
  const s = t;
446
460
  if (Array.isArray(s.material)) {
447
- const o = new Array();
448
- for (const r of s.material) {
449
- const n = this.assignTextureLOD(r, e);
450
- o.push(n);
461
+ const r = new Array();
462
+ for (const i of s.material) {
463
+ const o = this.assignTextureLOD(i, e);
464
+ r.push(o);
451
465
  }
452
- return Promise.all(o).then((r) => {
453
- const n = new Array();
454
- for (const l of r)
455
- Array.isArray(l) && n.push(...l);
456
- return n;
466
+ return Promise.all(r).then((i) => {
467
+ const o = new Array();
468
+ for (const l of i)
469
+ Array.isArray(l) && o.push(...l);
470
+ return o;
457
471
  });
458
472
  } else
459
473
  return this.assignTextureLOD(s.material, e);
460
474
  }
461
475
  if (t.isMaterial === !0) {
462
- const s = t, o = [], r = new Array();
476
+ const s = t, r = [], i = new Array();
463
477
  if (s.uniforms && (s.isRawShaderMaterial || s.isShaderMaterial === !0)) {
464
- const n = s;
465
- for (const l of Object.keys(n.uniforms)) {
466
- const a = n.uniforms[l].value;
478
+ const o = s;
479
+ for (const l of Object.keys(o.uniforms)) {
480
+ const a = o.uniforms[l].value;
467
481
  if (a?.isTexture === !0) {
468
- const u = this.assignTextureLODForSlot(a, e, s, l).then((d) => (d && n.uniforms[l].value != d && (n.uniforms[l].value = d, n.uniformsNeedUpdate = !0), d));
469
- o.push(u), r.push(l);
482
+ const u = this.assignTextureLODForSlot(a, e, s, l).then((c) => (c && o.uniforms[l].value != c && (o.uniforms[l].value = c, o.uniformsNeedUpdate = !0), c));
483
+ r.push(u), i.push(l);
470
484
  }
471
485
  }
472
486
  } else
473
- for (const n of Object.keys(s)) {
474
- const l = s[n];
487
+ for (const o of Object.keys(s)) {
488
+ const l = s[o];
475
489
  if (l?.isTexture === !0) {
476
- const a = this.assignTextureLODForSlot(l, e, s, n);
477
- o.push(a), r.push(n);
490
+ const a = this.assignTextureLODForSlot(l, e, s, o);
491
+ r.push(a), i.push(o);
478
492
  }
479
493
  }
480
- return Promise.all(o).then((n) => {
494
+ return Promise.all(r).then((o) => {
481
495
  const l = new Array();
482
- for (let a = 0; a < n.length; a++) {
483
- const u = n[a], d = r[a];
484
- u && u.isTexture === !0 ? l.push({ material: s, slot: d, texture: u, level: e }) : l.push({ material: s, slot: d, texture: null, level: e });
496
+ for (let a = 0; a < o.length; a++) {
497
+ const u = o[a], c = i[a];
498
+ u && u.isTexture === !0 ? l.push({ material: s, slot: c, texture: u, level: e }) : l.push({ material: s, slot: c, texture: null, level: e });
485
499
  }
486
500
  return l;
487
501
  });
@@ -493,40 +507,40 @@ class m {
493
507
  return Promise.resolve(null);
494
508
  }
495
509
  // #region INTERNAL
496
- static assignTextureLODForSlot(t, e, s, o) {
497
- return t?.isTexture !== !0 ? Promise.resolve(null) : o === "glyphMap" ? Promise.resolve(t) : m.getOrLoadLOD(t, e).then((r) => {
498
- if (Array.isArray(r))
510
+ static assignTextureLODForSlot(t, e, s, r) {
511
+ return t?.isTexture !== !0 ? Promise.resolve(null) : r === "glyphMap" ? Promise.resolve(t) : y.getOrLoadLOD(t, e).then((i) => {
512
+ if (Array.isArray(i))
499
513
  return console.warn("Progressive: Got an array of textures for a texture slot, this should not happen..."), null;
500
- if (r?.isTexture === !0) {
501
- if (r != t && s && o) {
502
- const n = s[o];
503
- if (n && !h) {
504
- const l = this.getAssignedLODInformation(n);
514
+ if (i?.isTexture === !0) {
515
+ if (i != t && s && r) {
516
+ const o = s[r];
517
+ if (o && !f) {
518
+ const l = this.getAssignedLODInformation(o);
505
519
  if (l && l?.level < e)
506
- return h === "verbose" && console.warn("Assigned texture level is already higher: ", l.level, e, s, n, r), null;
520
+ return f === "verbose" && console.warn("Assigned texture level is already higher: ", l.level, e, s, o, i), i && i !== o && ((f || K) && console.log(`[gltf-progressive] Disposing rejected lower-quality texture LOD ${e} (assigned is ${l.level})`, i.uuid), i.dispose()), null;
507
521
  }
508
- if (ft && r.mipmaps) {
509
- const l = r.mipmaps.length;
510
- r.mipmaps.length = Math.min(r.mipmaps.length, 3), l !== r.mipmaps.length && h && console.debug(`Reduced mipmap count from ${l} to ${r.mipmaps.length} for ${r.uuid}: ${r.image?.width}x${r.image?.height}.`);
522
+ if (this.trackTextureUsage(i), o && o !== i && this.untrackTextureUsage(o) && (f || K)) {
523
+ const a = this.getAssignedLODInformation(o);
524
+ console.log(`[gltf-progressive] Disposed old texture LOD ${a?.level ?? "?"} ${e} for ${s.name || s.type}.${r}`, o.uuid);
511
525
  }
512
- s[o] = r;
526
+ s[r] = i;
513
527
  }
514
- return r;
515
- } else h == "verbose" && console.warn("No LOD found for", t, e);
528
+ return i;
529
+ } else f == "verbose" && console.warn("No LOD found for", t, e);
516
530
  return null;
517
- }).catch((r) => (console.error("Error loading LOD", t, r), null));
531
+ }).catch((i) => (console.error("Error loading LOD", t, i), null));
518
532
  }
519
533
  parser;
520
534
  url;
521
535
  constructor(t) {
522
536
  const e = t.options.path;
523
- h && console.log("Progressive extension registered for", e), this.parser = t, this.url = e;
537
+ f && console.log("Progressive extension registered for", e), this.parser = t, this.url = e;
524
538
  }
525
539
  _isLoadingMesh;
526
540
  loadMesh = (t) => {
527
541
  if (this._isLoadingMesh) return null;
528
542
  const e = this.parser.json.meshes[t]?.extensions?.[W];
529
- return e ? (this._isLoadingMesh = !0, this.parser.getDependency("mesh", t).then((s) => (this._isLoadingMesh = !1, s && m.registerMesh(this.url, e.guid, s, e.lods?.length, 0, e), s))) : null;
543
+ return e ? (this._isLoadingMesh = !0, this.parser.getDependency("mesh", t).then((s) => (this._isLoadingMesh = !1, s && y.registerMesh(this.url, e.guid, s, e.lods?.length, 0, e), s))) : null;
530
544
  };
531
545
  // private _isLoadingTexture;
532
546
  // loadTexture = (textureIndex: number) => {
@@ -543,30 +557,30 @@ class m {
543
557
  // });
544
558
  // }
545
559
  afterRoot(t) {
546
- return h && console.log("AFTER", this.url, t), this.parser.json.textures?.forEach((e, s) => {
560
+ return f && console.log("AFTER", this.url, t), this.parser.json.textures?.forEach((e, s) => {
547
561
  if (e?.extensions) {
548
- const o = e?.extensions[W];
549
- if (o) {
550
- if (!o.lods) {
551
- h && console.warn("Texture has no LODs", o);
562
+ const r = e?.extensions[W];
563
+ if (r) {
564
+ if (!r.lods) {
565
+ f && console.warn("Texture has no LODs", r);
552
566
  return;
553
567
  }
554
- let r = !1;
555
- for (const n of this.parser.associations.keys())
556
- n.isTexture === !0 && this.parser.associations.get(n)?.textures === s && (r = !0, m.registerTexture(this.url, n, o.lods?.length, s, o));
557
- r || this.parser.getDependency("texture", s).then((n) => {
558
- n && m.registerTexture(this.url, n, o.lods?.length, s, o);
568
+ let i = !1;
569
+ for (const o of this.parser.associations.keys())
570
+ o.isTexture === !0 && this.parser.associations.get(o)?.textures === s && (i = !0, y.registerTexture(this.url, o, r.lods?.length, s, r));
571
+ i || this.parser.getDependency("texture", s).then((o) => {
572
+ o && y.registerTexture(this.url, o, r.lods?.length, s, r);
559
573
  });
560
574
  }
561
575
  }
562
576
  }), this.parser.json.meshes?.forEach((e, s) => {
563
577
  if (e?.extensions) {
564
- const o = e?.extensions[W];
565
- if (o && o.lods) {
566
- for (const r of this.parser.associations.keys())
567
- if (r.isMesh) {
568
- const n = this.parser.associations.get(r);
569
- n?.meshes === s && m.registerMesh(this.url, o.guid, r, o.lods.length, n.primitives, o);
578
+ const r = e?.extensions[W];
579
+ if (r && r.lods) {
580
+ for (const i of this.parser.associations.keys())
581
+ if (i.isMesh) {
582
+ const o = this.parser.associations.get(i);
583
+ o?.meshes === s && y.registerMesh(this.url, r.guid, i, r.lods.length, o.primitives, r);
570
584
  }
571
585
  }
572
586
  }
@@ -575,38 +589,39 @@ class m {
575
589
  /**
576
590
  * Register a texture with LOD information
577
591
  */
578
- static registerTexture = (t, e, s, o, r) => {
592
+ static registerTexture = (t, e, s, r, i) => {
579
593
  if (!e) {
580
- h && console.error("!! gltf-progressive: Called register texture without texture");
594
+ f && console.error("!! gltf-progressive: Called register texture without texture");
581
595
  return;
582
596
  }
583
- if (h) {
597
+ if (f) {
584
598
  const l = e.image?.width || e.source?.data?.width || 0, a = e.image?.height || e.source?.data?.height || 0;
585
- console.log(`> gltf-progressive: register texture[${o}] "${e.name || e.uuid}", Current: ${l}x${a}, Max: ${r.lods[0]?.width}x${r.lods[0]?.height}, uuid: ${e.uuid}`, r, e);
599
+ console.log(`> gltf-progressive: register texture[${r}] "${e.name || e.uuid}", Current: ${l}x${a}, Max: ${i.lods[0]?.width}x${i.lods[0]?.height}, uuid: ${e.uuid}`, i, e);
586
600
  }
587
- e.source && (e.source[le] = r);
588
- const n = r.guid;
589
- m.assignLODInformation(t, e, n, s, o), m.lodInfos.set(n, r), m.lowresCache.set(n, new WeakRef(e));
601
+ e.source && (e.source[ue] = i);
602
+ const o = i.guid;
603
+ y.assignLODInformation(t, e, o, s, r), y.lodInfos.set(o, i), y.lowresCache.set(o, new WeakRef(e));
590
604
  };
591
605
  /**
592
606
  * Register a mesh with LOD information
593
607
  */
594
- static registerMesh = (t, e, s, o, r, n) => {
608
+ static registerMesh = (t, e, s, r, i, o) => {
595
609
  const l = s.geometry;
596
610
  if (!l) {
597
- h && console.warn("gltf-progressive: Register mesh without geometry");
611
+ f && console.warn("gltf-progressive: Register mesh without geometry");
598
612
  return;
599
613
  }
600
- l.userData || (l.userData = {}), h && console.log("> Progressive: register mesh " + s.name, { index: r, uuid: s.uuid }, n, s), m.assignLODInformation(t, l, e, o, r), m.lodInfos.set(e, n);
601
- let u = m.lowresCache.get(e)?.deref();
602
- u ? u.push(s.geometry) : u = [s.geometry], m.lowresCache.set(e, new WeakRef(u)), o > 0 && !Z(s) && ot(s, l);
603
- for (const d of z)
604
- d.onRegisteredNewMesh?.(s, n);
614
+ l.userData || (l.userData = {}), f && console.log("> Progressive: register mesh " + s.name, { index: i, uuid: s.uuid }, o, s), y.assignLODInformation(t, l, e, r, i), y.lodInfos.set(e, o);
615
+ let u = y.lowresCache.get(e)?.deref();
616
+ u ? u.push(s.geometry) : u = [s.geometry], y.lowresCache.set(e, new WeakRef(u)), r > 0 && !ee(s) && at(s, l);
617
+ for (const c of z)
618
+ c.onRegisteredNewMesh?.(s, o);
605
619
  };
606
620
  /**
607
621
  * Dispose cached resources to free memory.
608
622
  * Call this when a model is removed from the scene to allow garbage collection of its LOD resources.
609
623
  * Calls three.js `.dispose()` on cached Textures and BufferGeometries to free GPU memory.
624
+ * Also clears reference counts for disposed textures.
610
625
  * @param guid Optional GUID to dispose resources for a specific model. If omitted, all cached resources are cleared.
611
626
  */
612
627
  static dispose(t) {
@@ -616,42 +631,48 @@ class m {
616
631
  if (e) {
617
632
  const s = e.deref();
618
633
  if (s) {
619
- if (s.isTexture)
620
- s.dispose();
621
- else if (Array.isArray(s))
622
- for (const o of s) o.dispose();
634
+ if (s.isTexture) {
635
+ const r = s;
636
+ this.textureRefCounts.delete(r.uuid), r.dispose();
637
+ } else if (Array.isArray(s))
638
+ for (const r of s) r.dispose();
623
639
  }
624
640
  this.lowresCache.delete(t);
625
641
  }
626
- for (const [s, o] of this.cache)
627
- s.includes(t) && (this._disposeCacheEntry(o), this.cache.delete(s));
642
+ for (const [s, r] of this.cache)
643
+ s.includes(t) && (this._disposeCacheEntry(r), this.cache.delete(s));
628
644
  } else {
629
645
  this.lodInfos.clear();
630
646
  for (const [, e] of this.lowresCache) {
631
647
  const s = e.deref();
632
648
  if (s) {
633
- if (s.isTexture)
634
- s.dispose();
635
- else if (Array.isArray(s))
636
- for (const o of s) o.dispose();
649
+ if (s.isTexture) {
650
+ const r = s;
651
+ this.textureRefCounts.delete(r.uuid), r.dispose();
652
+ } else if (Array.isArray(s))
653
+ for (const r of s) r.dispose();
637
654
  }
638
655
  }
639
656
  this.lowresCache.clear();
640
657
  for (const [, e] of this.cache)
641
658
  this._disposeCacheEntry(e);
642
- this.cache.clear();
659
+ this.cache.clear(), this.textureRefCounts.clear();
643
660
  }
644
661
  }
645
662
  /** Dispose a single cache entry's three.js resource(s) to free GPU memory. */
646
663
  static _disposeCacheEntry(t) {
647
- t instanceof WeakRef ? t.deref()?.dispose() : t.then((e) => {
648
- if (e)
649
- if (Array.isArray(e))
650
- for (const s of e) s.dispose();
651
- else
652
- e.dispose();
653
- }).catch(() => {
654
- });
664
+ if (t instanceof WeakRef) {
665
+ const e = t.deref();
666
+ e && (e.isTexture && this.textureRefCounts.delete(e.uuid), e.dispose());
667
+ } else
668
+ t.then((e) => {
669
+ if (e)
670
+ if (Array.isArray(e))
671
+ for (const s of e) s.dispose();
672
+ else
673
+ e.isTexture && this.textureRefCounts.delete(e.uuid), e.dispose();
674
+ }).catch(() => {
675
+ });
655
676
  }
656
677
  /** A map of key = asset uuid and value = LOD information */
657
678
  static lodInfos = /* @__PURE__ */ new Map();
@@ -659,107 +680,137 @@ class m {
659
680
  static cache = /* @__PURE__ */ new Map();
660
681
  /** this contains the geometry/textures that were originally loaded. Uses WeakRef to allow garbage collection when unused. */
661
682
  static lowresCache = /* @__PURE__ */ new Map();
683
+ /** Reference counting for textures to track usage across multiple materials/objects */
684
+ static textureRefCounts = /* @__PURE__ */ new Map();
662
685
  /**
663
686
  * FinalizationRegistry to automatically clean up `previouslyLoaded` cache entries
664
687
  * when their associated three.js resources are garbage collected by the browser.
665
688
  * The held value is the cache key string used in `previouslyLoaded`.
666
689
  */
667
690
  static _resourceRegistry = new FinalizationRegistry((t) => {
668
- const e = m.cache.get(t);
669
- h && console.debug(`[gltf-progressive] Resource GC'd
670
- ${t}`), e instanceof WeakRef && (e.deref() || (m.cache.delete(t), h && console.log(`[gltf-progressive] Cache entry auto-cleaned (GC'd): ${t}`)));
691
+ const e = y.cache.get(t);
692
+ (f || K) && console.debug(`[gltf-progressive] Memory: Resource GC'd
693
+ ${t}`), e instanceof WeakRef && (e.deref() || (y.cache.delete(t), (f || K) && console.log("[gltf-progressive] Cache entry deleted (GC)")));
671
694
  });
695
+ /**
696
+ * Track texture usage by incrementing reference count
697
+ */
698
+ static trackTextureUsage(t) {
699
+ const e = t.uuid, s = this.textureRefCounts.get(e) || 0;
700
+ this.textureRefCounts.set(e, s + 1), f === "verbose" && console.log(`[gltf-progressive] Track texture ${e}, refCount: ${s} → ${s + 1}`);
701
+ }
702
+ /**
703
+ * Untrack texture usage by decrementing reference count.
704
+ * Automatically disposes the texture when reference count reaches zero.
705
+ * @returns true if the texture was disposed, false otherwise
706
+ */
707
+ static untrackTextureUsage(t) {
708
+ const e = t.uuid, s = this.textureRefCounts.get(e);
709
+ if (!s)
710
+ return (f === "verbose" || K) && i("[gltf-progressive] Memory: Untrack untracked texture (dispose immediately)", 0), t.dispose(), !0;
711
+ const r = s - 1;
712
+ if (r <= 0)
713
+ return this.textureRefCounts.delete(e), (f || K) && i("[gltf-progressive] Memory: Dispose texture", r), t.dispose(), !0;
714
+ return this.textureRefCounts.set(e, r), f === "verbose" && i("[gltf-progressive] Memory: Untrack texture", r), !1;
715
+ function i(o, l) {
716
+ let a = t.image?.width || t.source?.data?.width || 0, u = t.image?.height || t.source?.data?.height || 0;
717
+ const c = a && u ? `${a}x${u}` : "N/A";
718
+ let m = "N/A";
719
+ a && u && (m = `~${(it(t) / (1024 * 1024)).toFixed(2)} MB`), console.log(`${o} — ${t.name} ${c} (${m}), refCount: ${s} → ${l}
720
+ ${e}`);
721
+ }
722
+ }
672
723
  static workers = [];
673
724
  static _workersIndex = 0;
674
725
  static async getOrLoadLOD(t, e) {
675
- const s = h == "verbose", o = this.getAssignedLODInformation(t);
676
- if (!o)
677
- return h && console.warn(`[gltf-progressive] No LOD information found: ${t.name}, uuid: ${t.uuid}, type: ${t.type}`, t), null;
678
- const r = o?.key;
679
- let n;
726
+ const s = f == "verbose", r = this.getAssignedLODInformation(t);
727
+ if (!r)
728
+ return f && console.warn(`[gltf-progressive] No LOD information found: ${t.name}, uuid: ${t.uuid}, type: ${t.type}`, t), null;
729
+ const i = r?.key;
730
+ let o;
680
731
  if (t.isTexture === !0) {
681
732
  const a = t;
682
- a.source && a.source[le] && (n = a.source[le]);
733
+ a.source && a.source[ue] && (o = a.source[ue]);
683
734
  }
684
- if (n || (n = m.lodInfos.get(r)), !n)
685
- h && console.warn(`Can not load LOD ${e}: no LOD info found for "${r}" ${t.name}`, t.type, m.lodInfos);
735
+ if (o || (o = y.lodInfos.get(i)), !o)
736
+ f && console.warn(`Can not load LOD ${e}: no LOD info found for "${i}" ${t.name}`, t.type, y.lodInfos);
686
737
  else {
687
738
  if (e > 0) {
688
- let d = !1;
689
- const y = Array.isArray(n.lods);
690
- if (y && e >= n.lods.length ? d = !0 : y || (d = !0), d) {
691
- const w = this.lowresCache.get(r);
739
+ let c = !1;
740
+ const m = Array.isArray(o.lods);
741
+ if (m && e >= o.lods.length ? c = !0 : m || (c = !0), c) {
742
+ const w = this.lowresCache.get(i);
692
743
  if (w) {
693
744
  const _ = w.deref();
694
745
  if (_) return _;
695
- this.lowresCache.delete(r), h && console.log(`[gltf-progressive] Lowres cache entry was GC'd: ${r}`);
746
+ this.lowresCache.delete(i), f && console.log(`[gltf-progressive] Lowres cache entry was GC'd: ${i}`);
696
747
  }
697
748
  return null;
698
749
  }
699
750
  }
700
- const a = Array.isArray(n.lods) ? n.lods[e]?.path : n.lods;
751
+ const a = Array.isArray(o.lods) ? o.lods[e]?.path : o.lods;
701
752
  if (!a)
702
- return h && !n["missing:uri"] && (n["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + e, n)), null;
703
- const u = tt(o.url, a);
753
+ return f && !o["missing:uri"] && (o["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + e, o)), null;
754
+ const u = st(r.url, a);
704
755
  if (u.endsWith(".glb") || u.endsWith(".gltf")) {
705
- if (!n.guid)
706
- return console.warn("missing pointer for glb/gltf texture", n), null;
707
- const d = u + "_" + n.guid, y = await this.queue.slot(u), w = this.cache.get(d);
756
+ if (!o.guid)
757
+ return console.warn("missing pointer for glb/gltf texture", o), null;
758
+ const c = u + "_" + o.guid, m = await this.queue.slot(u), w = this.cache.get(c);
708
759
  if (w !== void 0)
709
- if (s && console.log(`LOD ${e} was already loading/loaded: ${d}`), w instanceof WeakRef) {
710
- const c = w.deref();
711
- if (c) {
712
- let g = c, b = !1;
713
- if (g instanceof F && t instanceof F ? g.image?.data || g.source?.data ? g = this.copySettings(t, g) : b = !0 : g instanceof E && t instanceof E && (g.attributes.position?.array || (b = !0)), !b)
760
+ if (s && console.log(`LOD ${e} was already loading/loaded: ${c}`), w instanceof WeakRef) {
761
+ const d = w.deref();
762
+ if (d) {
763
+ let g = d, b = !1;
764
+ if (g instanceof F && t instanceof F ? g.image?.data || g.source?.data ? g = this.copySettings(t, g) : b = !0 : g instanceof V && t instanceof V && (g.attributes.position?.array || (b = !0)), !b)
714
765
  return g;
715
766
  }
716
- this.cache.delete(d), h && console.log(`[gltf-progressive] Re-loading GC'd/disposed resource: ${d}`);
767
+ this.cache.delete(c), f && console.log(`[gltf-progressive] Re-loading GC'd/disposed resource: ${c}`);
717
768
  } else {
718
- let c = await w.catch((b) => (console.error(`Error loading LOD ${e} from ${u}
769
+ let d = await w.catch((b) => (console.error(`Error loading LOD ${e} from ${u}
719
770
  `, b), null)), g = !1;
720
- if (c == null || (c instanceof F && t instanceof F ? c.image?.data || c.source?.data ? c = this.copySettings(t, c) : (g = !0, this.cache.delete(d)) : c instanceof E && t instanceof E && (c.attributes.position?.array || (g = !0, this.cache.delete(d)))), !g)
721
- return c;
771
+ if (d == null || (d instanceof F && t instanceof F ? d.image?.data || d.source?.data ? d = this.copySettings(t, d) : (g = !0, this.cache.delete(c)) : d instanceof V && t instanceof V && (d.attributes.position?.array || (g = !0, this.cache.delete(c)))), !g)
772
+ return d;
722
773
  }
723
- if (!y.use)
724
- return h && console.log(`LOD ${e} was aborted: ${u}`), null;
725
- const _ = n, I = new Promise(async (c, g) => {
726
- if (ct) {
727
- const x = await (await ut({})).load(u);
774
+ if (!m.use)
775
+ return f && console.log(`LOD ${e} was aborted: ${u}`), null;
776
+ const _ = o, k = new Promise(async (d, g) => {
777
+ if (gt) {
778
+ const x = await (await ft({})).load(u);
728
779
  if (x.textures.length > 0)
729
- for (const f of x.textures) {
730
- let p = f.texture;
731
- return m.assignLODInformation(o.url, p, r, e, void 0), t instanceof F && (p = this.copySettings(t, p)), p && (p.guid = _.guid), c(p);
780
+ for (const h of x.textures) {
781
+ let p = h.texture;
782
+ return y.assignLODInformation(r.url, p, i, e, void 0), t instanceof F && (p = this.copySettings(t, p)), p && (p.guid = _.guid), d(p);
732
783
  }
733
784
  if (x.geometries.length > 0) {
734
- const f = new Array();
785
+ const h = new Array();
735
786
  for (const p of x.geometries) {
736
787
  const O = p.geometry;
737
- m.assignLODInformation(o.url, O, r, e, p.primitiveIndex), f.push(O);
788
+ y.assignLODInformation(r.url, O, i, e, p.primitiveIndex), h.push(O);
738
789
  }
739
- return c(f);
790
+ return d(h);
740
791
  }
741
- return c(null);
792
+ return d(null);
742
793
  }
743
- const b = new ye();
744
- Se(b), h && (await new Promise((L) => setTimeout(L, 1e3)), s && console.warn("Start loading (delayed) " + u, _.guid));
794
+ const b = new xe();
795
+ Pe(b), f && (await new Promise((L) => setTimeout(L, 1e3)), s && console.warn("Start loading (delayed) " + u, _.guid));
745
796
  let B = u;
746
797
  if (_ && Array.isArray(_.lods)) {
747
798
  const L = _.lods[e];
748
799
  L.hash && (B += "?v=" + L.hash);
749
800
  }
750
801
  const D = await b.loadAsync(B).catch((L) => (console.error(`Error loading LOD ${e} from ${u}
751
- `, L), c(null)));
802
+ `, L), d(null)));
752
803
  if (!D)
753
- return c(null);
754
- const N = D.parser;
804
+ return d(null);
805
+ const q = D.parser;
755
806
  s && console.log("Loading finished " + u, _.guid);
756
807
  let P = 0;
757
808
  if (D.parser.json.textures) {
758
809
  let L = !1;
759
810
  for (const x of D.parser.json.textures) {
760
811
  if (x?.extensions) {
761
- const f = x?.extensions[W];
762
- if (f?.guid && f.guid === _.guid) {
812
+ const h = x?.extensions[W];
813
+ if (h?.guid && h.guid === _.guid) {
763
814
  L = !0;
764
815
  break;
765
816
  }
@@ -767,16 +818,16 @@ ${t}`), e instanceof WeakRef && (e.deref() || (m.cache.delete(t), h && console.l
767
818
  P++;
768
819
  }
769
820
  if (L) {
770
- let x = await N.getDependency("texture", P);
771
- return x && m.assignLODInformation(o.url, x, r, e, void 0), s && console.log('change "' + t.name + '" → "' + x.name + '"', u, P, x, d), t instanceof F && (x = this.copySettings(t, x)), x && (x.guid = _.guid), c(x);
772
- } else h && console.warn("Could not find texture with guid", _.guid, D.parser.json);
821
+ let x = await q.getDependency("texture", P);
822
+ return x && y.assignLODInformation(r.url, x, i, e, void 0), s && console.log('change "' + t.name + '" → "' + x.name + '"', u, P, x, c), t instanceof F && (x = this.copySettings(t, x)), x && (x.guid = _.guid), d(x);
823
+ } else f && console.warn("Could not find texture with guid", _.guid, D.parser.json);
773
824
  }
774
825
  if (P = 0, D.parser.json.meshes) {
775
826
  let L = !1;
776
827
  for (const x of D.parser.json.meshes) {
777
828
  if (x?.extensions) {
778
- const f = x?.extensions[W];
779
- if (f?.guid && f.guid === _.guid) {
829
+ const h = x?.extensions[W];
830
+ if (h?.guid && h.guid === _.guid) {
780
831
  L = !0;
781
832
  break;
782
833
  }
@@ -784,69 +835,69 @@ ${t}`), e instanceof WeakRef && (e.deref() || (m.cache.delete(t), h && console.l
784
835
  P++;
785
836
  }
786
837
  if (L) {
787
- const x = await N.getDependency("mesh", P);
788
- if (s && console.log(`Loaded Mesh "${x.name}"`, u, P, x, d), x.isMesh === !0) {
789
- const f = x.geometry;
790
- return m.assignLODInformation(o.url, f, r, e, 0), c(f);
838
+ const x = await q.getDependency("mesh", P);
839
+ if (s && console.log(`Loaded Mesh "${x.name}"`, u, P, x, c), x.isMesh === !0) {
840
+ const h = x.geometry;
841
+ return y.assignLODInformation(r.url, h, i, e, 0), d(h);
791
842
  } else {
792
- const f = new Array();
843
+ const h = new Array();
793
844
  for (let p = 0; p < x.children.length; p++) {
794
845
  const O = x.children[p];
795
846
  if (O.isMesh === !0) {
796
847
  const S = O.geometry;
797
- m.assignLODInformation(o.url, S, r, e, p), f.push(S);
848
+ y.assignLODInformation(r.url, S, i, e, p), h.push(S);
798
849
  }
799
850
  }
800
- return c(f);
851
+ return d(h);
801
852
  }
802
- } else h && console.warn("Could not find mesh with guid", _.guid, D.parser.json);
853
+ } else f && console.warn("Could not find mesh with guid", _.guid, D.parser.json);
803
854
  }
804
- return c(null);
855
+ return d(null);
805
856
  });
806
- this.cache.set(d, I), y.use(I);
807
- const M = await I;
808
- return M != null ? M instanceof F ? (this.cache.set(d, new WeakRef(M)), m._resourceRegistry.register(M, d)) : Array.isArray(M) ? this.cache.set(d, Promise.resolve(M)) : this.cache.set(d, Promise.resolve(M)) : this.cache.set(d, Promise.resolve(null)), M;
857
+ this.cache.set(c, k), m.use(k);
858
+ const M = await k;
859
+ return M != null ? M instanceof F ? (this.cache.set(c, new WeakRef(M)), y._resourceRegistry.register(M, c)) : Array.isArray(M) ? this.cache.set(c, Promise.resolve(M)) : this.cache.set(c, Promise.resolve(M)) : this.cache.set(c, Promise.resolve(null)), M;
809
860
  } else if (t instanceof F) {
810
861
  s && console.log("Load texture from uri: " + u);
811
- const y = await new ze().loadAsync(u);
812
- return y ? (y.guid = n.guid, y.flipY = !1, y.needsUpdate = !0, y.colorSpace = t.colorSpace, s && console.log(n, y)) : h && console.warn("failed loading", u), y;
862
+ const m = await new Ne().loadAsync(u);
863
+ return m ? (m.guid = o.guid, m.flipY = !1, m.needsUpdate = !0, m.colorSpace = t.colorSpace, s && console.log(o, m)) : f && console.warn("failed loading", u), m;
813
864
  }
814
865
  }
815
866
  return null;
816
867
  }
817
868
  static maxConcurrent = 50;
818
- static queue = new st(m.maxConcurrent, { debug: h != !1 });
819
- static assignLODInformation(t, e, s, o, r) {
869
+ static queue = new rt(y.maxConcurrent, { debug: f != !1 });
870
+ static assignLODInformation(t, e, s, r, i) {
820
871
  if (!e) return;
821
872
  e.userData || (e.userData = {});
822
- const n = new ht(t, s, o, r);
823
- e.userData.LODS = n, "source" in e && typeof e.source == "object" && (e.source.LODS = n);
873
+ const o = new pt(t, s, r, i);
874
+ e.userData.LODS = o, "source" in e && typeof e.source == "object" && (e.source.LODS = o);
824
875
  }
825
876
  static getAssignedLODInformation(t) {
826
877
  return t ? t.userData?.LODS ? t.userData.LODS : "source" in t && t.source?.LODS ? t.source.LODS : null : null;
827
878
  }
828
879
  // private static readonly _copiedTextures: WeakMap<Texture, Texture> = new Map();
829
880
  static copySettings(t, e) {
830
- return e ? (h === "verbose" && console.debug(`Copy texture settings
881
+ return e ? (f === "verbose" && console.debug(`Copy texture settings
831
882
  `, t.uuid, `
832
883
  `, 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;
833
884
  }
834
885
  }
835
- class ht {
886
+ class pt {
836
887
  url;
837
888
  /** the key to lookup the LOD information */
838
889
  key;
839
890
  level;
840
891
  /** For multi objects (e.g. a group of meshes) this is the index of the object */
841
892
  index;
842
- constructor(t, e, s, o) {
843
- this.url = t, this.key = e, this.level = s, o != null && (this.index = o);
893
+ constructor(t, e, s, r) {
894
+ this.url = t, this.key = e, this.level = s, r != null && (this.index = r);
844
895
  }
845
896
  }
846
- class ue {
847
- static addPromise = (t, e, s, o) => {
848
- o.forEach((r) => {
849
- r.add(t, e, s);
897
+ class ce {
898
+ static addPromise = (t, e, s, r) => {
899
+ r.forEach((i) => {
900
+ i.add(t, e, s);
850
901
  });
851
902
  };
852
903
  ready;
@@ -876,9 +927,9 @@ class ue {
876
927
  _awaiting = [];
877
928
  _maxPromisesPerObject = 1;
878
929
  constructor(t, e) {
879
- const o = Math.max(e.frames ?? 2, 2);
880
- this._frame_start = e.waitForFirstCapture ? void 0 : t, this._frames_to_capture = o, this.ready = new Promise((r) => {
881
- this._resolve = r;
930
+ const r = Math.max(e.frames ?? 2, 2);
931
+ this._frame_start = e.waitForFirstCapture ? void 0 : t, this._frames_to_capture = r, this.ready = new Promise((i) => {
932
+ this._resolve = i;
882
933
  }), this.ready.finally(() => {
883
934
  this._resolved = !0, this._awaiting.length = 0;
884
935
  }), this._signal = e.signal, this._signal?.addEventListener("abort", () => {
@@ -892,18 +943,18 @@ class ue {
892
943
  _seen = /* @__PURE__ */ new WeakMap();
893
944
  add(t, e, s) {
894
945
  if (this._resolved) {
895
- h && console.warn("PromiseGroup: Trying to add a promise to a resolved group, ignoring.");
946
+ f && console.warn("PromiseGroup: Trying to add a promise to a resolved group, ignoring.");
896
947
  return;
897
948
  }
898
949
  if (!(this._frame_start !== void 0 && this._currentFrame > this._frame_start + this._frames_to_capture)) {
899
950
  if (this._maxPromisesPerObject >= 1)
900
951
  if (this._seen.has(e)) {
901
- let o = this._seen.get(e);
902
- if (o >= this._maxPromisesPerObject) {
903
- h && console.warn("PromiseGroup: Already awaiting object ignoring new promise for it.");
952
+ let r = this._seen.get(e);
953
+ if (r >= this._maxPromisesPerObject) {
954
+ f && console.warn("PromiseGroup: Already awaiting object ignoring new promise for it.");
904
955
  return;
905
956
  }
906
- this._seen.set(e, o + 1);
957
+ this._seen.set(e, r + 1);
907
958
  } else
908
959
  this._seen.set(e, 1);
909
960
  this._awaiting.push(s), this._addedCount++, s.finally(() => {
@@ -919,7 +970,7 @@ class ue {
919
970
  });
920
971
  }
921
972
  }
922
- const k = j("debugprogressive"), gt = j("noprogressive"), de = /* @__PURE__ */ Symbol("Needle:LODSManager"), ce = /* @__PURE__ */ Symbol("Needle:LODState"), U = /* @__PURE__ */ Symbol("Needle:CurrentLOD"), T = { mesh_lod: -1, texture_lod: -1 };
973
+ const R = N("debugprogressive"), mt = N("noprogressive"), de = /* @__PURE__ */ Symbol("Needle:LODSManager"), fe = /* @__PURE__ */ Symbol("Needle:LODState"), U = /* @__PURE__ */ Symbol("Needle:CurrentLOD"), T = { mesh_lod: -1, texture_lod: -1 };
923
974
  class v {
924
975
  /**
925
976
  * 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.
@@ -927,7 +978,7 @@ class v {
927
978
  static debugDrawLine;
928
979
  /** @internal */
929
980
  static getObjectLODState(t) {
930
- return t[ce];
981
+ return t[fe];
931
982
  }
932
983
  static addPlugin(t) {
933
984
  z.push(t);
@@ -952,7 +1003,7 @@ class v {
952
1003
  }
953
1004
  renderer;
954
1005
  context;
955
- projectionScreenMatrix = new _e();
1006
+ projectionScreenMatrix = new Le();
956
1007
  /** @deprecated use static `LODsManager.addPlugin()` method. This getter will be removed in later versions */
957
1008
  get plugins() {
958
1009
  return z;
@@ -996,13 +1047,13 @@ class v {
996
1047
  * Call to await LODs loading during the next render cycle.
997
1048
  */
998
1049
  awaitLoading(t) {
999
- const e = this._promiseGroupIds++, s = new ue(this.#r, { ...t });
1050
+ const e = this._promiseGroupIds++, s = new ce(this.#r, { ...t });
1000
1051
  this._newPromiseGroups.push(s);
1001
- const o = performance.now();
1052
+ const r = performance.now();
1002
1053
  return s.ready.finally(() => {
1003
- const r = this._newPromiseGroups.indexOf(s);
1004
- r >= 0 && (this._newPromiseGroups.splice(r, 1), Le() && performance.measure("LODsManager:awaitLoading", {
1005
- start: o,
1054
+ const i = this._newPromiseGroups.indexOf(s);
1055
+ i >= 0 && (this._newPromiseGroups.splice(i, 1), ve() && performance.measure("LODsManager:awaitLoading", {
1056
+ start: r,
1006
1057
  detail: { id: e, name: t?.name, awaited: s.awaitedCount, resolved: s.resolvedCount }
1007
1058
  }));
1008
1059
  }), s.ready;
@@ -1027,10 +1078,10 @@ class v {
1027
1078
  this.renderer = t, this.context = { ...e };
1028
1079
  }
1029
1080
  #t;
1030
- #n = new Ne();
1081
+ #o = new qe();
1031
1082
  #r = 0;
1032
- #o = 0;
1033
1083
  #i = 0;
1084
+ #n = 0;
1034
1085
  #s = 0;
1035
1086
  _fpsBuffer = [60, 60, 60, 60, 60];
1036
1087
  /**
@@ -1042,11 +1093,11 @@ class v {
1042
1093
  let t = 0;
1043
1094
  this.#t = this.renderer.render;
1044
1095
  const e = this;
1045
- xe(this.renderer), this.renderer.render = function(s, o) {
1046
- const r = e.renderer.getRenderTarget();
1047
- (r == null || "isXRRenderTarget" in r && r.isXRRenderTarget) && (t = 0, e.#r += 1, e.#o = e.#n.getDelta(), e.#i += e.#o, e._fpsBuffer.shift(), e._fpsBuffer.push(1 / e.#o), e.#s = e._fpsBuffer.reduce((l, a) => l + a) / e._fpsBuffer.length, k && e.#r % 200 === 0 && console.log("FPS", Math.round(e.#s), "Interval:", e.#e));
1048
- const n = t++;
1049
- e.#t.call(this, s, o), e.onAfterRender(s, o, n);
1096
+ we(this.renderer), this.renderer.render = function(s, r) {
1097
+ const i = e.renderer.getRenderTarget();
1098
+ (i == null || "isXRRenderTarget" in i && i.isXRRenderTarget) && (t = 0, e.#r += 1, e.#i = e.#o.getDelta(), e.#n += e.#i, e._fpsBuffer.shift(), e._fpsBuffer.push(1 / e.#i), e.#s = e._fpsBuffer.reduce((l, a) => l + a) / e._fpsBuffer.length, R && e.#r % 200 === 0 && console.log("FPS", Math.round(e.#s), "Interval:", e.#e));
1099
+ const o = t++;
1100
+ e.#t.call(this, s, r), e.onAfterRender(s, r, o);
1050
1101
  };
1051
1102
  }
1052
1103
  disable() {
@@ -1057,14 +1108,14 @@ class v {
1057
1108
  }
1058
1109
  onAfterRender(t, e, s) {
1059
1110
  if (this.pause) return;
1060
- const r = this.renderer.renderLists.get(t, 0).opaque;
1061
- let n = !0;
1062
- if (r.length === 1) {
1063
- const l = r[0].material;
1064
- (l.name === "EffectMaterial" || l.name === "CopyShader") && (n = !1);
1111
+ const i = this.renderer.renderLists.get(t, 0).opaque;
1112
+ let o = !0;
1113
+ if (i.length === 1) {
1114
+ const l = i[0].material;
1115
+ (l.name === "EffectMaterial" || l.name === "CopyShader") && (o = !1);
1065
1116
  }
1066
- if ((e.parent && e.parent.type === "CubeCamera" || s >= 1 && e.type === "OrthographicCamera") && (n = !1), n) {
1067
- if (gt || (this.updateInterval === "auto" ? this.#s < 40 && this.#e < 10 ? (this.#e += 1, k && console.warn("↓ Reducing LOD updates", this.#e, this.#s.toFixed(0))) : this.#s >= 60 && this.#e > 1 && (this.#e -= 1, k && console.warn("↑ Increasing LOD updates", this.#e, this.#s.toFixed(0))) : this.#e = this.updateInterval, this.#e > 0 && this.#r % this.#e != 0))
1117
+ if ((e.parent && e.parent.type === "CubeCamera" || s >= 1 && e.type === "OrthographicCamera") && (o = !1), o) {
1118
+ if (mt || (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))
1068
1119
  return;
1069
1120
  this.internalUpdate(t, e), this._postprocessPromiseGroups();
1070
1121
  }
@@ -1073,12 +1124,12 @@ class v {
1073
1124
  * Update LODs in a scene
1074
1125
  */
1075
1126
  internalUpdate(t, e) {
1076
- const s = this.renderer.renderLists.get(t, 0), o = s.opaque;
1127
+ const s = this.renderer.renderLists.get(t, 0), r = s.opaque;
1077
1128
  this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix, e.matrixWorldInverse);
1078
- const r = this.targetTriangleDensity;
1079
- for (const a of o) {
1129
+ const i = this.targetTriangleDensity;
1130
+ for (const a of r) {
1080
1131
  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")) {
1081
- k && (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)));
1132
+ 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)));
1082
1133
  continue;
1083
1134
  }
1084
1135
  switch (a.material.type) {
@@ -1090,38 +1141,38 @@ class v {
1090
1141
  case "MeshDepthMaterial":
1091
1142
  continue;
1092
1143
  }
1093
- if (k === "color" && a.material && !a.object.progressive_debug_color) {
1144
+ if (R === "color" && a.material && !a.object.progressive_debug_color) {
1094
1145
  a.object.progressive_debug_color = !0;
1095
- const d = Math.random() * 16777215, y = new qe({ color: d });
1096
- a.object.material = y;
1146
+ const c = Math.random() * 16777215, m = new Ee({ color: c });
1147
+ a.object.material = m;
1097
1148
  }
1098
1149
  const u = a.object;
1099
- (u instanceof V || u.isMesh) && this.updateLODs(t, e, u, r);
1150
+ (u instanceof X || u.isMesh) && this.updateLODs(t, e, u, i);
1100
1151
  }
1101
- const n = s.transparent;
1102
- for (const a of n) {
1152
+ const o = s.transparent;
1153
+ for (const a of o) {
1103
1154
  const u = a.object;
1104
- (u instanceof V || u.isMesh) && this.updateLODs(t, e, u, r);
1155
+ (u instanceof X || u.isMesh) && this.updateLODs(t, e, u, i);
1105
1156
  }
1106
1157
  const l = s.transmissive;
1107
1158
  for (const a of l) {
1108
1159
  const u = a.object;
1109
- (u instanceof V || u.isMesh) && this.updateLODs(t, e, u, r);
1160
+ (u instanceof X || u.isMesh) && this.updateLODs(t, e, u, i);
1110
1161
  }
1111
1162
  }
1112
1163
  /** Update the LOD levels for the renderer. */
1113
- updateLODs(t, e, s, o) {
1164
+ updateLODs(t, e, s, r) {
1114
1165
  s.userData || (s.userData = {});
1115
- let r = s[ce];
1116
- if (r || (r = new pt(), s[ce] = r), r.frames++ < 2)
1166
+ let i = s[fe];
1167
+ if (i || (i = new yt(), s[fe] = i), i.frames++ < 2)
1117
1168
  return;
1118
1169
  for (const l of z)
1119
1170
  l.onBeforeUpdateLOD?.(this.renderer, t, e, s);
1120
- const n = this.overrideLodLevel !== void 0 ? this.overrideLodLevel : q;
1121
- n >= 0 ? (T.mesh_lod = n, T.texture_lod = n) : (this.calculateLodLevel(e, s, r, o, 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, n), h && s.material && !s.isGizmo && Ce(s.material);
1171
+ const o = this.overrideLodLevel !== void 0 ? this.overrideLodLevel : E;
1172
+ o >= 0 ? (T.mesh_lod = o, T.texture_lod = o) : (this.calculateLodLevel(e, s, i, 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 && ke(s.material);
1122
1173
  for (const l of z)
1123
1174
  l.onAfterUpdatedLOD?.(this.renderer, t, e, s, T);
1124
- r.lastLodLevel_Mesh = T.mesh_lod, r.lastLodLevel_Texture = T.texture_lod;
1175
+ i.lastLodLevel_Mesh = T.mesh_lod, i.lastLodLevel_Texture = T.texture_lod;
1125
1176
  }
1126
1177
  /** Load progressive textures for the given material
1127
1178
  * @param material the material to load the textures for
@@ -1131,17 +1182,17 @@ class v {
1131
1182
  loadProgressiveTextures(t, e, s) {
1132
1183
  if (!t) return;
1133
1184
  if (Array.isArray(t)) {
1134
- for (const r of t)
1135
- this.loadProgressiveTextures(r, e);
1185
+ for (const i of t)
1186
+ this.loadProgressiveTextures(i, e);
1136
1187
  return;
1137
1188
  }
1138
- let o = !1;
1139
- if ((t[U] === void 0 || e < t[U]) && (o = !0), s !== void 0 && s >= 0 && (o = t[U] != s, e = s), o) {
1189
+ let r = !1;
1190
+ if ((t[U] === void 0 || e < t[U]) && (r = !0), s !== void 0 && s >= 0 && (r = t[U] != s, e = s), r) {
1140
1191
  t[U] = e;
1141
- const r = m.assignTextureLOD(t, e).then((n) => {
1192
+ const i = y.assignTextureLOD(t, e).then((o) => {
1142
1193
  this._lodchangedlisteners.forEach((l) => l({ type: "texture", level: e, object: t }));
1143
1194
  });
1144
- ue.addPromise("texture", t, r, this._newPromiseGroups);
1195
+ ce.addPromise("texture", t, i, this._newPromiseGroups);
1145
1196
  }
1146
1197
  }
1147
1198
  /** Load progressive meshes for the given mesh
@@ -1153,141 +1204,141 @@ class v {
1153
1204
  loadProgressiveMeshes(t, e) {
1154
1205
  if (!t) return Promise.resolve(null);
1155
1206
  let s = t[U] !== e;
1156
- const o = t["DEBUG:LOD"];
1157
- if (o != null && (s = t[U] != o, e = o), s) {
1207
+ const r = t["DEBUG:LOD"];
1208
+ if (r != null && (s = t[U] != r, e = r), s) {
1158
1209
  t[U] = e;
1159
- const r = t.geometry, n = m.assignMeshLOD(t, e).then((l) => (l && t[U] == e && r != t.geometry && this._lodchangedlisteners.forEach((a) => a({ type: "mesh", level: e, object: t })), l));
1160
- return ue.addPromise("mesh", t, n, this._newPromiseGroups), n;
1210
+ const i = t.geometry, o = y.assignMeshLOD(t, e).then((l) => (l && t[U] == e && i != t.geometry && this._lodchangedlisteners.forEach((a) => a({ type: "mesh", level: e, object: t })), l));
1211
+ return ce.addPromise("mesh", t, o, this._newPromiseGroups), o;
1161
1212
  }
1162
1213
  return Promise.resolve(null);
1163
1214
  }
1164
1215
  // private testIfLODLevelsAreAvailable() {
1165
- _sphere = new De();
1166
- _tempBox = new he();
1167
- _tempBox2 = new he();
1168
- tempMatrix = new _e();
1169
- _tempWorldPosition = new C();
1170
- _tempBoxSize = new C();
1171
- _tempBox2Size = new C();
1172
- static corner0 = new C();
1173
- static corner1 = new C();
1174
- static corner2 = new C();
1175
- static corner3 = new C();
1176
- static _tempPtInside = new C();
1216
+ _sphere = new Oe();
1217
+ _tempBox = new ge();
1218
+ _tempBox2 = new ge();
1219
+ tempMatrix = new Le();
1220
+ _tempWorldPosition = new A();
1221
+ _tempBoxSize = new A();
1222
+ _tempBox2Size = new A();
1223
+ static corner0 = new A();
1224
+ static corner1 = new A();
1225
+ static corner2 = new A();
1226
+ static corner3 = new A();
1227
+ static _tempPtInside = new A();
1177
1228
  static isInside(t, e) {
1178
- const s = t.min, o = t.max, r = (s.x + o.x) * 0.5, n = (s.y + o.y) * 0.5;
1179
- return this._tempPtInside.set(r, n, s.z).applyMatrix4(e).z < 0;
1229
+ const s = t.min, r = t.max, i = (s.x + r.x) * 0.5, o = (s.y + r.y) * 0.5;
1230
+ return this._tempPtInside.set(i, o, s.z).applyMatrix4(e).z < 0;
1180
1231
  }
1181
1232
  static skinnedMeshBoundsFrameOffsetCounter = 0;
1182
1233
  static $skinnedMeshBoundsOffset = /* @__PURE__ */ Symbol("gltf-progressive-skinnedMeshBoundsOffset");
1183
1234
  // #region calculateLodLevel
1184
- calculateLodLevel(t, e, s, o, r) {
1235
+ calculateLodLevel(t, e, s, r, i) {
1185
1236
  if (!e) {
1186
- r.mesh_lod = -1, r.texture_lod = -1;
1237
+ i.mesh_lod = -1, i.texture_lod = -1;
1187
1238
  return;
1188
1239
  }
1189
1240
  if (!t) {
1190
- r.mesh_lod = -1, r.texture_lod = -1;
1241
+ i.mesh_lod = -1, i.texture_lod = -1;
1191
1242
  return;
1192
1243
  }
1193
1244
  let l = 10 + 1, a = !1;
1194
- if (k && e["DEBUG:LOD"] != null)
1245
+ if (R && e["DEBUG:LOD"] != null)
1195
1246
  return e["DEBUG:LOD"];
1196
- const u = m.getMeshLODExtension(e.geometry)?.lods, d = m.getPrimitiveIndex(e.geometry), y = u && u.length > 0, w = m.getMaterialMinMaxLODsCount(e.material), _ = w.min_count !== 1 / 0 && w.min_count >= 0 && w.max_count >= 0;
1197
- if (!y && !_) {
1198
- r.mesh_lod = 0, r.texture_lod = 0;
1247
+ const u = y.getMeshLODExtension(e.geometry)?.lods, c = y.getPrimitiveIndex(e.geometry), m = u && u.length > 0, w = y.getMaterialMinMaxLODsCount(e.material), _ = w.min_count !== 1 / 0 && w.min_count >= 0 && w.max_count >= 0;
1248
+ if (!m && !_) {
1249
+ i.mesh_lod = 0, i.texture_lod = 0;
1199
1250
  return;
1200
1251
  }
1201
- y || (a = !0, l = 0);
1202
- const I = this.renderer.domElement.clientHeight || this.renderer.domElement.height;
1252
+ m || (a = !0, l = 0);
1253
+ const k = this.renderer.domElement.clientHeight || this.renderer.domElement.height;
1203
1254
  let M = e.geometry.boundingBox;
1204
1255
  if (e.type === "SkinnedMesh") {
1205
- const c = e;
1206
- if (!c.boundingBox)
1207
- c.computeBoundingBox();
1256
+ const d = e;
1257
+ if (!d.boundingBox)
1258
+ d.computeBoundingBox();
1208
1259
  else if (this.skinnedMeshAutoUpdateBoundsInterval > 0) {
1209
- if (!c[v.$skinnedMeshBoundsOffset]) {
1260
+ if (!d[v.$skinnedMeshBoundsOffset]) {
1210
1261
  const b = v.skinnedMeshBoundsFrameOffsetCounter++;
1211
- c[v.$skinnedMeshBoundsOffset] = b;
1262
+ d[v.$skinnedMeshBoundsOffset] = b;
1212
1263
  }
1213
- const g = c[v.$skinnedMeshBoundsOffset];
1264
+ const g = d[v.$skinnedMeshBoundsOffset];
1214
1265
  if ((s.frames + g) % this.skinnedMeshAutoUpdateBoundsInterval === 0) {
1215
- const b = Z(c), B = c.geometry;
1216
- b && (c.geometry = b), c.computeBoundingBox(), c.geometry = B;
1266
+ const b = ee(d), B = d.geometry;
1267
+ b && (d.geometry = b), d.computeBoundingBox(), d.geometry = B;
1217
1268
  }
1218
1269
  }
1219
- M = c.boundingBox;
1270
+ M = d.boundingBox;
1220
1271
  }
1221
1272
  if (M) {
1222
- const c = t;
1273
+ const d = t;
1223
1274
  if (e.geometry.attributes.color && e.geometry.attributes.color.count < 100 && e.geometry.boundingSphere) {
1224
1275
  this._sphere.copy(e.geometry.boundingSphere), this._sphere.applyMatrix4(e.matrixWorld);
1225
- const f = t.getWorldPosition(this._tempWorldPosition);
1226
- if (this._sphere.containsPoint(f)) {
1227
- r.mesh_lod = 0, r.texture_lod = 0;
1276
+ const h = t.getWorldPosition(this._tempWorldPosition);
1277
+ if (this._sphere.containsPoint(h)) {
1278
+ i.mesh_lod = 0, i.texture_lod = 0;
1228
1279
  return;
1229
1280
  }
1230
1281
  }
1231
- if (this._tempBox.copy(M), this._tempBox.applyMatrix4(e.matrixWorld), c.isPerspectiveCamera && v.isInside(this._tempBox, this.projectionScreenMatrix)) {
1232
- r.mesh_lod = 0, r.texture_lod = 0;
1282
+ if (this._tempBox.copy(M), this._tempBox.applyMatrix4(e.matrixWorld), d.isPerspectiveCamera && v.isInside(this._tempBox, this.projectionScreenMatrix)) {
1283
+ i.mesh_lod = 0, i.texture_lod = 0;
1233
1284
  return;
1234
1285
  }
1235
- if (this._tempBox.applyMatrix4(this.projectionScreenMatrix), this.renderer.xr.enabled && c.isPerspectiveCamera && c.fov > 70) {
1236
- const f = this._tempBox.min, p = this._tempBox.max;
1237
- let O = f.x, S = f.y, G = p.x, Y = p.y;
1238
- const ee = 2, ne = 1.5, te = (f.x + p.x) * 0.5, se = (f.y + p.y) * 0.5;
1239
- O = (O - te) * ee + te, S = (S - se) * ee + se, G = (G - te) * ee + te, Y = (Y - se) * ee + se;
1240
- const Re = O < 0 && G > 0 ? 0 : Math.min(Math.abs(f.x), Math.abs(p.x)), $e = S < 0 && Y > 0 ? 0 : Math.min(Math.abs(f.y), Math.abs(p.y)), ie = Math.max(Re, $e);
1241
- s.lastCentrality = (ne - ie) * (ne - ie) * (ne - ie);
1286
+ if (this._tempBox.applyMatrix4(this.projectionScreenMatrix), this.renderer.xr.enabled && d.isPerspectiveCamera && d.fov > 70) {
1287
+ const h = this._tempBox.min, p = this._tempBox.max;
1288
+ let O = h.x, S = h.y, G = p.x, Y = p.y;
1289
+ const te = 2, ne = 1.5, se = (h.x + p.x) * 0.5, re = (h.y + p.y) * 0.5;
1290
+ O = (O - se) * te + se, S = (S - re) * te + re, G = (G - se) * te + se, Y = (Y - re) * te + re;
1291
+ const $e = O < 0 && G > 0 ? 0 : Math.min(Math.abs(h.x), Math.abs(p.x)), Be = S < 0 && Y > 0 ? 0 : Math.min(Math.abs(h.y), Math.abs(p.y)), ae = Math.max($e, Be);
1292
+ s.lastCentrality = (ne - ae) * (ne - ae) * (ne - ae);
1242
1293
  } else
1243
1294
  s.lastCentrality = 1;
1244
1295
  const g = this._tempBox.getSize(this._tempBoxSize);
1245
- g.multiplyScalar(0.5), screen.availHeight > 0 && I > 0 && g.multiplyScalar(I / screen.availHeight), t.isPerspectiveCamera ? g.x *= t.aspect : t.isOrthographicCamera;
1296
+ g.multiplyScalar(0.5), screen.availHeight > 0 && k > 0 && g.multiplyScalar(k / screen.availHeight), t.isPerspectiveCamera ? g.x *= t.aspect : t.isOrthographicCamera;
1246
1297
  const b = t.matrixWorldInverse, B = this._tempBox2;
1247
1298
  B.copy(M), B.applyMatrix4(e.matrixWorld), B.applyMatrix4(b);
1248
- const D = B.getSize(this._tempBox2Size), N = Math.max(D.x, D.y);
1249
- if (Math.max(g.x, g.y) != 0 && N != 0 && (g.z = D.z / Math.max(D.x, D.y) * Math.max(g.x, g.y)), s.lastScreenCoverage = Math.max(g.x, g.y, g.z), s.lastScreenspaceVolume.copy(g), s.lastScreenCoverage *= s.lastCentrality, k && v.debugDrawLine) {
1250
- const f = this.tempMatrix.copy(this.projectionScreenMatrix);
1251
- f.invert();
1299
+ const D = B.getSize(this._tempBox2Size), q = Math.max(D.x, D.y);
1300
+ if (Math.max(g.x, g.y) != 0 && q != 0 && (g.z = D.z / Math.max(D.x, D.y) * Math.max(g.x, g.y)), s.lastScreenCoverage = Math.max(g.x, g.y, g.z), s.lastScreenspaceVolume.copy(g), s.lastScreenCoverage *= s.lastCentrality, R && v.debugDrawLine) {
1301
+ const h = this.tempMatrix.copy(this.projectionScreenMatrix);
1302
+ h.invert();
1252
1303
  const p = v.corner0, O = v.corner1, S = v.corner2, G = v.corner3;
1253
1304
  p.copy(this._tempBox.min), O.copy(this._tempBox.max), O.x = p.x, S.copy(this._tempBox.max), S.y = p.y, G.copy(this._tempBox.max);
1254
1305
  const Y = (p.z + G.z) * 0.5;
1255
- p.z = O.z = S.z = G.z = Y, p.applyMatrix4(f), O.applyMatrix4(f), S.applyMatrix4(f), G.applyMatrix4(f), v.debugDrawLine(p, O, 255), v.debugDrawLine(p, S, 255), v.debugDrawLine(O, G, 255), v.debugDrawLine(S, G, 255);
1306
+ p.z = O.z = S.z = G.z = Y, p.applyMatrix4(h), O.applyMatrix4(h), S.applyMatrix4(h), G.applyMatrix4(h), v.debugDrawLine(p, O, 255), v.debugDrawLine(p, S, 255), v.debugDrawLine(O, G, 255), v.debugDrawLine(S, G, 255);
1256
1307
  }
1257
1308
  let L = 999;
1258
1309
  if (u && s.lastScreenCoverage > 0)
1259
- for (let f = 0; f < u.length; f++) {
1260
- const p = u[f], S = (p.densities?.[d] || p.density || 1e-5) / s.lastScreenCoverage;
1261
- if (d > 0 && Le() && !p.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.")), S < o) {
1262
- L = f;
1310
+ for (let h = 0; h < u.length; h++) {
1311
+ const p = u[h], S = (p.densities?.[c] || p.density || 1e-5) / s.lastScreenCoverage;
1312
+ if (c > 0 && ve() && !p.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.")), S < r) {
1313
+ L = h;
1263
1314
  break;
1264
1315
  }
1265
1316
  }
1266
1317
  L < l && (l = L, a = !0);
1267
1318
  }
1268
- if (a ? r.mesh_lod = l : r.mesh_lod = s.lastLodLevel_Mesh, k && r.mesh_lod != s.lastLodLevel_Mesh) {
1269
- const g = u?.[r.mesh_lod];
1270
- g && console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} → ${r.mesh_lod} (density: ${g.densities?.[d].toFixed(0)}) | ${e.name}`);
1319
+ if (a ? i.mesh_lod = l : i.mesh_lod = s.lastLodLevel_Mesh, R && i.mesh_lod != s.lastLodLevel_Mesh) {
1320
+ const g = u?.[i.mesh_lod];
1321
+ g && console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} → ${i.mesh_lod} (density: ${g.densities?.[c].toFixed(0)}) | ${e.name}`);
1271
1322
  }
1272
1323
  if (_) {
1273
- const c = "saveData" in globalThis.navigator && globalThis.navigator.saveData === !0;
1324
+ const d = "saveData" in globalThis.navigator && globalThis.navigator.saveData === !0;
1274
1325
  if (s.lastLodLevel_Texture < 0) {
1275
- if (r.texture_lod = w.max_count - 1, k) {
1326
+ if (i.texture_lod = w.max_count - 1, R) {
1276
1327
  const g = w.lods[w.max_count - 1];
1277
- k && console.log(`First Texture LOD ${r.texture_lod} (${g.max_height}px) - ${e.name}`);
1328
+ R && console.log(`First Texture LOD ${i.texture_lod} (${g.max_height}px) - ${e.name}`);
1278
1329
  }
1279
1330
  } else {
1280
1331
  const g = s.lastScreenspaceVolume.x + s.lastScreenspaceVolume.y + s.lastScreenspaceVolume.z;
1281
1332
  let b = s.lastScreenCoverage * 4;
1282
1333
  this.context?.engine === "model-viewer" && (b *= 1.5);
1283
- const D = I / window.devicePixelRatio * b;
1284
- let N = !1;
1334
+ const D = k / window.devicePixelRatio * b;
1335
+ let q = !1;
1285
1336
  for (let P = w.lods.length - 1; P >= 0; P--) {
1286
1337
  const L = w.lods[P];
1287
- if (!(c && L.max_height >= 2048) && !(Ae() && L.max_height > 4096) && (L.max_height > D || !N && P === 0)) {
1288
- if (N = !0, r.texture_lod = P, k && r.texture_lod < s.lastLodLevel_Texture) {
1338
+ if (!(d && L.max_height >= 2048) && !(Ae() && L.max_height > 4096) && (L.max_height > D || !q && P === 0)) {
1339
+ if (q = !0, i.texture_lod = P, R && i.texture_lod < s.lastLodLevel_Texture) {
1289
1340
  const x = L.max_height;
1290
- console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${r.texture_lod} = ${x}px
1341
+ console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${i.texture_lod} = ${x}px
1291
1342
  Screensize: ${D.toFixed(0)}px, Coverage: ${(100 * s.lastScreenCoverage).toFixed(2)}%, Volume ${g.toFixed(1)}
1292
1343
  ${e.name}`);
1293
1344
  }
@@ -1296,86 +1347,86 @@ ${e.name}`);
1296
1347
  }
1297
1348
  }
1298
1349
  } else
1299
- r.texture_lod = 0;
1350
+ i.texture_lod = 0;
1300
1351
  }
1301
1352
  }
1302
- class pt {
1353
+ class yt {
1303
1354
  frames = 0;
1304
1355
  lastLodLevel_Mesh = -1;
1305
1356
  lastLodLevel_Texture = -1;
1306
1357
  lastScreenCoverage = 0;
1307
- lastScreenspaceVolume = new C();
1358
+ lastScreenspaceVolume = new A();
1308
1359
  lastCentrality = 0;
1309
1360
  }
1310
- const ve = /* @__PURE__ */ Symbol("NEEDLE_mesh_lod"), re = /* @__PURE__ */ Symbol("NEEDLE_texture_lod");
1311
- let fe = null;
1312
- function Ie() {
1313
- const i = mt();
1314
- i && (i.mapURLs(function(t) {
1315
- return be(), t;
1316
- }), be(), fe?.disconnect(), fe = new MutationObserver((t) => {
1361
+ const be = /* @__PURE__ */ Symbol("NEEDLE_mesh_lod"), ie = /* @__PURE__ */ Symbol("NEEDLE_texture_lod");
1362
+ let he = null;
1363
+ function Re() {
1364
+ const n = xt();
1365
+ n && (n.mapURLs(function(t) {
1366
+ return Me(), t;
1367
+ }), Me(), he?.disconnect(), he = new MutationObserver((t) => {
1317
1368
  t.forEach((e) => {
1318
1369
  e.addedNodes.forEach((s) => {
1319
- s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" && ke(s);
1370
+ s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" && Ie(s);
1320
1371
  });
1321
1372
  });
1322
- }), fe.observe(document, { childList: !0, subtree: !0 }));
1373
+ }), he.observe(document, { childList: !0, subtree: !0 }));
1323
1374
  }
1324
- function mt() {
1375
+ function xt() {
1325
1376
  if (typeof customElements > "u") return null;
1326
- const i = customElements.get("model-viewer");
1327
- return i || (customElements.whenDefined("model-viewer").then(() => {
1328
- console.debug("[gltf-progressive] model-viewer defined"), Ie();
1377
+ const n = customElements.get("model-viewer");
1378
+ return n || (customElements.whenDefined("model-viewer").then(() => {
1379
+ console.debug("[gltf-progressive] model-viewer defined"), Re();
1329
1380
  }), null);
1330
1381
  }
1331
- function be() {
1382
+ function Me() {
1332
1383
  if (typeof document > "u") return;
1333
1384
  document.querySelectorAll("model-viewer").forEach((t) => {
1334
- ke(t);
1385
+ Ie(t);
1335
1386
  });
1336
1387
  }
1337
- const Me = /* @__PURE__ */ new WeakSet();
1338
- let yt = 0;
1339
- function ke(i) {
1340
- if (!i || Me.has(i))
1388
+ const De = /* @__PURE__ */ new WeakSet();
1389
+ let wt = 0;
1390
+ function Ie(n) {
1391
+ if (!n || De.has(n))
1341
1392
  return null;
1342
- Me.add(i), console.debug("[gltf-progressive] found new model-viewer..." + ++yt + `
1343
- `, i.getAttribute("src"));
1393
+ De.add(n), console.debug("[gltf-progressive] found new model-viewer..." + ++wt + `
1394
+ `, n.getAttribute("src"));
1344
1395
  let t = null, e = null, s = null;
1345
- for (let o = i; o != null; o = Object.getPrototypeOf(o)) {
1346
- const r = Object.getOwnPropertySymbols(o), n = r.find((u) => u.toString() == "Symbol(renderer)"), l = r.find((u) => u.toString() == "Symbol(scene)"), a = r.find((u) => u.toString() == "Symbol(needsRender)");
1347
- !t && n != null && (t = i[n].threeRenderer), !e && l != null && (e = i[l]), !s && a != null && (s = i[a]);
1396
+ for (let r = n; r != null; r = Object.getPrototypeOf(r)) {
1397
+ const i = Object.getOwnPropertySymbols(r), o = i.find((u) => u.toString() == "Symbol(renderer)"), l = i.find((u) => u.toString() == "Symbol(scene)"), a = i.find((u) => u.toString() == "Symbol(needsRender)");
1398
+ !t && o != null && (t = n[o].threeRenderer), !e && l != null && (e = n[l]), !s && a != null && (s = n[a]);
1348
1399
  }
1349
1400
  if (t && e) {
1350
- let o = function() {
1401
+ let r = function() {
1351
1402
  if (s) {
1352
- let n = 0, l = setInterval(() => {
1353
- if (n++ > 5) {
1403
+ let o = 0, l = setInterval(() => {
1404
+ if (o++ > 5) {
1354
1405
  clearInterval(l);
1355
1406
  return;
1356
1407
  }
1357
- s?.call(i);
1408
+ s?.call(n);
1358
1409
  }, 300);
1359
1410
  }
1360
1411
  };
1361
1412
  console.debug("[gltf-progressive] setup model-viewer");
1362
- const r = v.get(t, { engine: "model-viewer" });
1363
- return v.addPlugin(new xt()), r.enable(), r.addEventListener("changed", () => {
1364
- s?.call(i);
1365
- }), i.addEventListener("model-visibility", (n) => {
1366
- n.detail.visible && s?.call(i);
1367
- }), i.addEventListener("load", () => {
1368
- o();
1413
+ const i = v.get(t, { engine: "model-viewer" });
1414
+ return v.addPlugin(new _t()), i.enable(), i.addEventListener("changed", () => {
1415
+ s?.call(n);
1416
+ }), n.addEventListener("model-visibility", (o) => {
1417
+ o.detail.visible && s?.call(n);
1418
+ }), n.addEventListener("load", () => {
1419
+ r();
1369
1420
  }), () => {
1370
- r.disable();
1421
+ i.disable();
1371
1422
  };
1372
1423
  }
1373
1424
  return null;
1374
1425
  }
1375
- class xt {
1426
+ class _t {
1376
1427
  _didWarnAboutMissingUrl = !1;
1377
- onBeforeUpdateLOD(t, e, s, o) {
1378
- this.tryParseMeshLOD(e, o), this.tryParseTextureLOD(e, o);
1428
+ onBeforeUpdateLOD(t, e, s, r) {
1429
+ this.tryParseMeshLOD(e, r), this.tryParseTextureLOD(e, r);
1379
1430
  }
1380
1431
  getUrl(t) {
1381
1432
  if (!t)
@@ -1390,101 +1441,101 @@ class xt {
1390
1441
  return t.element;
1391
1442
  }
1392
1443
  tryParseTextureLOD(t, e) {
1393
- if (e[re] == !0) return;
1394
- e[re] = !0;
1395
- const s = this.tryGetCurrentGLTF(t), o = this.tryGetCurrentModelViewer(t), r = this.getUrl(o);
1396
- if (r && s && e.material) {
1397
- let n = function(a) {
1398
- if (a[re] == !0) return;
1399
- a[re] = !0, a.userData && (a.userData.LOD = -1);
1444
+ if (e[ie] == !0) return;
1445
+ e[ie] = !0;
1446
+ const s = this.tryGetCurrentGLTF(t), r = this.tryGetCurrentModelViewer(t), i = this.getUrl(r);
1447
+ if (i && s && e.material) {
1448
+ let o = function(a) {
1449
+ if (a[ie] == !0) return;
1450
+ a[ie] = !0, a.userData && (a.userData.LOD = -1);
1400
1451
  const u = Object.keys(a);
1401
- for (let d = 0; d < u.length; d++) {
1402
- const y = u[d], w = a[y];
1452
+ for (let c = 0; c < u.length; c++) {
1453
+ const m = u[c], w = a[m];
1403
1454
  if (w?.isTexture === !0) {
1404
1455
  const _ = w.userData?.associations?.textures;
1405
1456
  if (_ == null) continue;
1406
- const I = s.parser.json.textures[_];
1407
- if (!I) {
1457
+ const k = s.parser.json.textures[_];
1458
+ if (!k) {
1408
1459
  console.warn("Texture data not found for texture index " + _);
1409
1460
  continue;
1410
1461
  }
1411
- if (I?.extensions?.[W]) {
1412
- const M = I.extensions[W];
1413
- M && r && m.registerTexture(r, w, M.lods.length, _, M);
1462
+ if (k?.extensions?.[W]) {
1463
+ const M = k.extensions[W];
1464
+ M && i && y.registerTexture(i, w, M.lods.length, _, M);
1414
1465
  }
1415
1466
  }
1416
1467
  }
1417
1468
  };
1418
1469
  const l = e.material;
1419
- if (Array.isArray(l)) for (const a of l) n(a);
1420
- else n(l);
1470
+ if (Array.isArray(l)) for (const a of l) o(a);
1471
+ else o(l);
1421
1472
  }
1422
1473
  }
1423
1474
  tryParseMeshLOD(t, e) {
1424
- if (e[ve] == !0) return;
1425
- e[ve] = !0;
1426
- const s = this.tryGetCurrentModelViewer(t), o = this.getUrl(s);
1427
- if (!o)
1475
+ if (e[be] == !0) return;
1476
+ e[be] = !0;
1477
+ const s = this.tryGetCurrentModelViewer(t), r = this.getUrl(s);
1478
+ if (!r)
1428
1479
  return;
1429
- const r = e.userData?.gltfExtensions?.[W];
1430
- if (r && o) {
1431
- const n = e.uuid;
1432
- m.registerMesh(o, n, e, 0, r.lods.length, r);
1480
+ const i = e.userData?.gltfExtensions?.[W];
1481
+ if (i && r) {
1482
+ const o = e.uuid;
1483
+ y.registerMesh(r, o, e, 0, i.lods.length, i);
1433
1484
  }
1434
1485
  }
1435
1486
  }
1436
- function wt(...i) {
1437
- let t, e, s, o;
1438
- switch (i.length) {
1487
+ function Lt(...n) {
1488
+ let t, e, s, r;
1489
+ switch (n.length) {
1439
1490
  case 2:
1440
- [s, e] = i, o = {};
1491
+ [s, e] = n, r = {};
1441
1492
  break;
1442
1493
  case 3:
1443
- [s, e, o] = i;
1494
+ [s, e, r] = n;
1444
1495
  break;
1445
1496
  case 4:
1446
- [t, e, s, o] = i;
1497
+ [t, e, s, r] = n;
1447
1498
  break;
1448
1499
  default:
1449
1500
  throw new Error("Invalid arguments");
1450
1501
  }
1451
- xe(e), Se(s), Te(s, {
1502
+ we(e), Pe(s), Ce(s, {
1452
1503
  progressive: !0,
1453
- ...o?.hints
1454
- }), s.register((n) => new m(n));
1455
- const r = v.get(e);
1456
- return o?.enableLODsManager !== !1 && r.enable(), r;
1504
+ ...r?.hints
1505
+ }), s.register((o) => new y(o));
1506
+ const i = v.get(e);
1507
+ return r?.enableLODsManager !== !1 && i.enable(), i;
1457
1508
  }
1458
- Ie();
1459
- if (!rt) {
1460
- const i = {
1509
+ Re();
1510
+ if (!nt) {
1511
+ const n = {
1461
1512
  gltfProgressive: {
1462
- useNeedleProgressive: wt,
1513
+ useNeedleProgressive: Lt,
1463
1514
  LODsManager: v,
1464
- configureLoader: Te,
1465
- getRaycastMesh: Z,
1466
- useRaycastMeshes: nt
1515
+ configureLoader: Ce,
1516
+ getRaycastMesh: ee,
1517
+ useRaycastMeshes: lt
1467
1518
  }
1468
1519
  };
1469
1520
  if (!globalThis.Needle)
1470
- globalThis.Needle = i;
1521
+ globalThis.Needle = n;
1471
1522
  else
1472
- for (const t in i)
1473
- globalThis.Needle[t] = i[t];
1523
+ for (const t in n)
1524
+ globalThis.Needle[t] = n[t];
1474
1525
  }
1475
1526
  export {
1476
1527
  W as EXTENSION_NAME,
1477
1528
  v as LODsManager,
1478
- m as NEEDLE_progressive,
1479
- je as VERSION,
1480
- Se as addDracoAndKTX2Loaders,
1481
- Te as configureLoader,
1482
- xe as createLoaders,
1483
- Z as getRaycastMesh,
1484
- Ie as patchModelViewer,
1485
- ot as registerRaycastMesh,
1486
- Qe as setDracoDecoderLocation,
1487
- Je as setKTX2TranscoderLocation,
1488
- wt as useNeedleProgressive,
1489
- nt as useRaycastMeshes
1529
+ y as NEEDLE_progressive,
1530
+ Ke as VERSION,
1531
+ Pe as addDracoAndKTX2Loaders,
1532
+ Ce as configureLoader,
1533
+ we as createLoaders,
1534
+ ee as getRaycastMesh,
1535
+ Re as patchModelViewer,
1536
+ at as registerRaycastMesh,
1537
+ Je as setDracoDecoderLocation,
1538
+ Ze as setKTX2TranscoderLocation,
1539
+ Lt as useNeedleProgressive,
1540
+ lt as useRaycastMeshes
1490
1541
  };