@needle-tools/engine 4.13.1-next.6cb1b73 → 4.13.1-next.9fc3e64

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