@needle-tools/engine 4.8.0-next.4eaf70a → 4.8.0-next.58ab763

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.
Files changed (52) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/{generateMeshBVH.worker-BaNp_Xtp.js → generateMeshBVH.worker-2qGLkQjg.js} +1 -1
  3. package/dist/{gltf-progressive-CeuEsYpY.min.js → gltf-progressive-C0OrHmZf.min.js} +4 -4
  4. package/dist/{gltf-progressive-DY5t1MFv.js → gltf-progressive-CqwFE7bV.js} +78 -63
  5. package/dist/{gltf-progressive--2HtE1d8.umd.cjs → gltf-progressive-VK6wRj74.umd.cjs} +3 -3
  6. package/dist/loader.worker-CrU5fNbR.js +27 -0
  7. package/dist/{needle-engine.bundle-1687n4dK.js → needle-engine.bundle-C-obl9GH.js} +1799 -1781
  8. package/dist/{needle-engine.bundle-CooE_ge1.umd.cjs → needle-engine.bundle-D2j8atLK.umd.cjs} +87 -87
  9. package/dist/{needle-engine.bundle-BayRUkg4.min.js → needle-engine.bundle-DYYKGkWL.min.js} +101 -101
  10. package/dist/needle-engine.js +21 -21
  11. package/dist/needle-engine.min.js +1 -1
  12. package/dist/needle-engine.umd.cjs +1 -1
  13. package/dist/{postprocessing-DtxaELce.umd.cjs → postprocessing-BgC7XZwK.umd.cjs} +1 -1
  14. package/dist/{postprocessing-DElbMQgB.js → postprocessing-DddlM3CK.js} +1 -1
  15. package/dist/rapier--oeYP_h7.umd.cjs +1 -0
  16. package/dist/{rapier-CU5cp-KB.js → rapier-B3xpyPtq.js} +88 -88
  17. package/dist/{three-examples-CM6Iip03.js → three-examples-BIuXQPSf.js} +6 -6
  18. package/dist/{three-examples-BhQvv1B9.umd.cjs → three-examples-CNRuT27G.umd.cjs} +2 -2
  19. package/dist/{vendor-ClB-U1Hn.js → vendor-CGONwIc0.js} +73 -73
  20. package/dist/vendor-Cty8Dnri.umd.cjs +1121 -0
  21. package/lib/engine/engine_gizmos.d.ts +3 -2
  22. package/lib/engine/engine_gizmos.js +6 -1
  23. package/lib/engine/engine_gizmos.js.map +1 -1
  24. package/lib/engine/engine_lightdata.js +2 -0
  25. package/lib/engine/engine_lightdata.js.map +1 -1
  26. package/lib/engine/engine_physics.d.ts +1 -1
  27. package/lib/engine/engine_physics_rapier.d.ts +12 -3
  28. package/lib/engine/engine_physics_rapier.js +28 -7
  29. package/lib/engine/engine_physics_rapier.js.map +1 -1
  30. package/lib/engine/engine_serialization_builtin_serializer.js +1 -1
  31. package/lib/engine/engine_serialization_builtin_serializer.js.map +1 -1
  32. package/lib/engine/engine_types.d.ts +12 -5
  33. package/lib/engine/engine_types.js +1 -1
  34. package/lib/engine/engine_types.js.map +1 -1
  35. package/lib/engine/engine_utils_format.js +8 -2
  36. package/lib/engine/engine_utils_format.js.map +1 -1
  37. package/lib/engine/extensions/extensions.js +1 -1
  38. package/lib/engine/extensions/extensions.js.map +1 -1
  39. package/package.json +2 -2
  40. package/plugins/vite/asap.js +1 -1
  41. package/plugins/vite/dependencies.js +28 -19
  42. package/plugins/vite/dependency-watcher.js +6 -1
  43. package/src/engine/engine_gizmos.ts +4 -1
  44. package/src/engine/engine_lightdata.ts +2 -0
  45. package/src/engine/engine_physics_rapier.ts +31 -10
  46. package/src/engine/engine_serialization_builtin_serializer.ts +1 -1
  47. package/src/engine/engine_types.ts +14 -5
  48. package/src/engine/engine_utils_format.ts +9 -2
  49. package/src/engine/extensions/extensions.ts +1 -1
  50. package/dist/loader.worker-8olmVOL4.js +0 -1
  51. package/dist/rapier-CUe6_xwE.umd.cjs +0 -1
  52. package/dist/vendor-bOWOWClg.umd.cjs +0 -1121
@@ -1,10 +1,10 @@
1
- import { BufferGeometry as Q, Mesh as q, Box3 as ge, Vector3 as A, Sphere as ve, CompressedTexture as Fe, Texture as E, Matrix3 as Ue, InterleavedBuffer as We, InterleavedBufferAttribute as ze, BufferAttribute as Ee, TextureLoader as Ne, Matrix4 as _e, Clock as qe, MeshStandardMaterial as Ve } from "./three-DrqIzZTH.js";
2
- import { DRACOLoader as Xe, KTX2Loader as Ke, MeshoptDecoder as je, GLTFLoader as xe } from "./three-examples-CM6Iip03.js";
3
- const Se = "3.1.1";
1
+ import { BufferGeometry as Q, Mesh as q, Box3 as ge, Vector3 as A, Sphere as Oe, CompressedTexture as Fe, Texture as E, Matrix3 as Ue, InterleavedBuffer as We, InterleavedBufferAttribute as ze, BufferAttribute as Ee, TextureLoader as Ne, Matrix4 as _e, Clock as qe, MeshStandardMaterial as Ve } from "./three-DrqIzZTH.js";
2
+ import { DRACOLoader as Xe, KTX2Loader as Ke, MeshoptDecoder as je, GLTFLoader as xe } from "./three-examples-BIuXQPSf.js";
3
+ const Se = "3.2.0";
4
4
  globalThis.GLTF_PROGRESSIVE_VERSION = Se;
5
5
  console.debug(`[gltf-progressive] version ${Se}`);
6
- let k = "https://www.gstatic.com/draco/versioned/decoders/1.5.7/", V = "https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";
7
- const Ye = k, He = V, Pe = new URL(k + "draco_decoder.js");
6
+ let C = "https://www.gstatic.com/draco/versioned/decoders/1.5.7/", V = "https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";
7
+ const Ye = C, He = V, Pe = new URL(C + "draco_decoder.js");
8
8
  Pe.searchParams.append("range", "true");
9
9
  fetch(Pe, {
10
10
  method: "GET",
@@ -12,16 +12,16 @@ fetch(Pe, {
12
12
  Range: "bytes=0-1"
13
13
  }
14
14
  }).catch((o) => {
15
- console.debug(`Failed to fetch remote Draco decoder from ${k} (offline: ${typeof navigator < "u" ? navigator.onLine : "unknown"})`), k === Ye && Je("./include/draco/"), V === He && Ze("./include/ktx2/");
15
+ console.debug(`Failed to fetch remote Draco decoder from ${C} (offline: ${typeof navigator < "u" ? navigator.onLine : "unknown"})`), C === Ye && Je("./include/draco/"), V === He && Ze("./include/ktx2/");
16
16
  }).finally(() => {
17
17
  Ae();
18
18
  });
19
19
  const Qe = () => ({
20
- dracoDecoderPath: k,
20
+ dracoDecoderPath: C,
21
21
  ktx2TranscoderPath: V
22
22
  });
23
23
  function Je(o) {
24
- k = o, T && T[pe] != k ? (console.debug("Updating Draco decoder path to " + o), T[pe] = k, T.setDecoderPath(k), T.preload()) : console.debug("Setting Draco decoder path to " + o);
24
+ C = o, T && T[pe] != C ? (console.debug("Updating Draco decoder path to " + o), T[pe] = C, T.setDecoderPath(C), T.preload()) : console.debug("Setting Draco decoder path to " + o);
25
25
  }
26
26
  function Ze(o) {
27
27
  V = o, R && R.transcoderPath != V ? (console.debug("Updating KTX2 transcoder path to " + o), R.setTranscoderPath(V), R.init()) : console.debug("Setting KTX2 transcoder path to " + o);
@@ -35,7 +35,7 @@ function Te(o) {
35
35
  const pe = Symbol("dracoDecoderPath");
36
36
  let T, re, R;
37
37
  function Ae() {
38
- T || (T = new Xe(), T[pe] = k, T.setDecoderPath(k), T.setDecoderConfig({ type: "js" }), T.preload()), R || (R = new Ke(), R.setTranscoderPath(V), R.init()), re || (re = je);
38
+ T || (T = new Xe(), T[pe] = C, T.setDecoderPath(C), T.setDecoderConfig({ type: "js" }), T.preload()), R || (R = new Ke(), R.setTranscoderPath(V), R.init()), re || (re = je);
39
39
  }
40
40
  const me = /* @__PURE__ */ new WeakMap();
41
41
  function Ie(o, t) {
@@ -74,7 +74,7 @@ function st(o, t) {
74
74
  return t;
75
75
  }
76
76
  let j;
77
- function Ce() {
77
+ function ke() {
78
78
  return j !== void 0 || (j = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent), X("debugprogressive") && console.log("[glTF Progressive]: isMobileDevice", j)), j;
79
79
  }
80
80
  function Me() {
@@ -163,16 +163,16 @@ if (g) {
163
163
  !isNaN(s) && s >= 0 && (N = s, console.log(`Set LOD level to [${N}]`));
164
164
  });
165
165
  }
166
- function ke(o) {
166
+ function Ce(o) {
167
167
  if (g)
168
168
  if (Array.isArray(o))
169
169
  for (const t of o)
170
- ke(t);
170
+ Ce(t);
171
171
  else o && "wireframe" in o && (o.wireframe = ne === !0);
172
172
  }
173
173
  const H = new Array();
174
174
  let lt = 0;
175
- const ut = Ce() ? 2 : 10;
175
+ const ut = ke() ? 2 : 10;
176
176
  function dt(o) {
177
177
  if (H.length < ut) {
178
178
  const s = H.length;
@@ -188,7 +188,7 @@ class Le {
188
188
  static async createWorker(t) {
189
189
  const e = new Worker(new URL(
190
190
  /* @vite-ignore */
191
- "/loader.worker-8olmVOL4.js",
191
+ "/loader.worker-CrU5fNbR.js",
192
192
  import.meta.url
193
193
  ), {
194
194
  type: "module"
@@ -256,7 +256,7 @@ function ct(o) {
256
256
  const i = e.morphAttributes[r].map((l) => le(l));
257
257
  s.morphAttributes[r] = i;
258
258
  }
259
- if (s.morphTargetsRelative = e.morphTargetsRelative ?? !1, s.boundingBox = new ge(), s.boundingBox.min = new A(e.boundingBox?.min.x, e.boundingBox?.min.y, e.boundingBox?.min.z), s.boundingBox.max = new A(e.boundingBox?.max.x, e.boundingBox?.max.y, e.boundingBox?.max.z), s.boundingSphere = new ve(new A(e.boundingSphere?.center.x, e.boundingSphere?.center.y, e.boundingSphere?.center.z), e.boundingSphere?.radius), e.groups)
259
+ if (s.morphTargetsRelative = e.morphTargetsRelative ?? !1, s.boundingBox = new ge(), s.boundingBox.min = new A(e.boundingBox?.min.x, e.boundingBox?.min.y, e.boundingBox?.min.z), s.boundingBox.max = new A(e.boundingBox?.max.x, e.boundingBox?.max.y, e.boundingBox?.max.z), s.boundingSphere = new Oe(new A(e.boundingSphere?.center.x, e.boundingSphere?.center.y, e.boundingSphere?.center.z), e.boundingSphere?.radius), e.groups)
260
260
  for (const r of e.groups)
261
261
  s.addGroup(r.start, r.count, r.materialIndex);
262
262
  e.userData && (s.userData = e.userData), t.geometry = s;
@@ -486,7 +486,8 @@ class y {
486
486
  }
487
487
  parser;
488
488
  url;
489
- constructor(t, e) {
489
+ constructor(t) {
490
+ const e = t.options.path;
490
491
  g && console.log("Progressive extension registered for", e), this.parser = t, this.url = e;
491
492
  }
492
493
  _isLoadingMesh;
@@ -606,8 +607,8 @@ class y {
606
607
  const d = u + "_" + i.guid, p = await this.queue.slot(u), L = this.previouslyLoaded.get(d);
607
608
  if (L !== void 0) {
608
609
  s && console.log(`LOD ${e} was already loading/loaded: ${d}`);
609
- let c = await L.catch((v) => (console.error(`Error loading LOD ${e} from ${u}
610
- `, v), null)), x = !1;
610
+ let c = await L.catch((O) => (console.error(`Error loading LOD ${e} from ${u}
611
+ `, O), null)), x = !1;
611
612
  if (c == null || (c instanceof E && t instanceof E ? c.image?.data || c.source?.data ? c = this.copySettings(t, c) : (x = !0, this.previouslyLoaded.delete(d)) : c instanceof Q && t instanceof Q && (c.attributes.position?.array || (x = !0, this.previouslyLoaded.delete(d)))), !x)
612
613
  return c;
613
614
  }
@@ -631,14 +632,14 @@ class y {
631
632
  }
632
633
  return c(null);
633
634
  }
634
- const v = new xe();
635
- Te(v), g && (await new Promise((w) => setTimeout(w, 1e3)), s && console.warn("Start loading (delayed) " + u, _.guid));
635
+ const O = new xe();
636
+ Te(O), g && (await new Promise((w) => setTimeout(w, 1e3)), s && console.warn("Start loading (delayed) " + u, _.guid));
636
637
  let B = u;
637
638
  if (_ && Array.isArray(_.lods)) {
638
639
  const w = _.lods[e];
639
640
  w.hash && (B += "?v=" + w.hash);
640
641
  }
641
- const D = await v.loadAsync(B).catch((w) => (console.error(`Error loading LOD ${e} from ${u}
642
+ const D = await O.loadAsync(B).catch((w) => (console.error(`Error loading LOD ${e} from ${u}
642
643
  `, w), c(null)));
643
644
  if (!D)
644
645
  return c(null);
@@ -684,8 +685,8 @@ class y {
684
685
  for (let h = 0; h < m.children.length; h++) {
685
686
  const b = m.children[h];
686
687
  if (b.isMesh === !0) {
687
- const O = b.geometry;
688
- y.assignLODInformation(r.url, O, n, e, h), f.push(O);
688
+ const v = b.geometry;
689
+ y.assignLODInformation(r.url, v, n, e, h), f.push(v);
689
690
  }
690
691
  }
691
692
  return c(f);
@@ -807,7 +808,7 @@ class de {
807
808
  });
808
809
  }
809
810
  }
810
- const C = X("debugprogressive"), pt = X("noprogressive"), ce = Symbol("Needle:LODSManager"), fe = Symbol("Needle:LODState"), U = Symbol("Needle:CurrentLOD"), P = { mesh_lod: -1, texture_lod: -1 };
811
+ const k = X("debugprogressive"), pt = X("noprogressive"), ce = Symbol("Needle:LODSManager"), fe = Symbol("Needle:LODState"), U = Symbol("Needle:CurrentLOD"), P = { mesh_lod: -1, texture_lod: -1 };
811
812
  let ie = class M {
812
813
  /**
813
814
  * 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.
@@ -932,7 +933,7 @@ let ie = class M {
932
933
  const e = this;
933
934
  we(this.renderer), this.renderer.render = function(s, r) {
934
935
  const n = e.renderer.getRenderTarget();
935
- (n == null || "isXRRenderTarget" in n && n.isXRRenderTarget) && (t = 0, e.#n += 1, e.#r = e.#i.getDelta(), e.#o += e.#r, e._fpsBuffer.shift(), e._fpsBuffer.push(1 / e.#r), e.#s = e._fpsBuffer.reduce((l, a) => l + a) / e._fpsBuffer.length, C && e.#n % 200 === 0 && console.log("FPS", Math.round(e.#s), "Interval:", e.#e));
936
+ (n == null || "isXRRenderTarget" in n && n.isXRRenderTarget) && (t = 0, e.#n += 1, e.#r = e.#i.getDelta(), e.#o += e.#r, e._fpsBuffer.shift(), e._fpsBuffer.push(1 / e.#r), e.#s = e._fpsBuffer.reduce((l, a) => l + a) / e._fpsBuffer.length, k && e.#n % 200 === 0 && console.log("FPS", Math.round(e.#s), "Interval:", e.#e));
936
937
  const i = t++;
937
938
  e.#t.call(this, s, r), e.onAfterRender(s, r, i);
938
939
  };
@@ -953,7 +954,7 @@ let ie = class M {
953
954
  (l.name === "EffectMaterial" || l.name === "CopyShader") && (i = !1);
954
955
  }
955
956
  if ((e.parent && e.parent.type === "CubeCamera" || s >= 1 && e.type === "OrthographicCamera") && (i = !1), i) {
956
- if (pt || (this.updateInterval === "auto" ? this.#s < 40 && this.#e < 10 ? (this.#e += 1, C && console.warn("↓ Reducing LOD updates", this.#e, this.#s.toFixed(0))) : this.#s >= 60 && this.#e > 1 && (this.#e -= 1, C && console.warn("↑ Increasing LOD updates", this.#e, this.#s.toFixed(0))) : this.#e = this.updateInterval, this.#e > 0 && this.#n % this.#e != 0))
957
+ if (pt || (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.#n % this.#e != 0))
957
958
  return;
958
959
  this.internalUpdate(t, e), this._postprocessPromiseGroups();
959
960
  }
@@ -967,7 +968,7 @@ let ie = class M {
967
968
  const n = this.targetTriangleDensity;
968
969
  for (const a of r) {
969
970
  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")) {
970
- C && (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)));
971
+ 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)));
971
972
  continue;
972
973
  }
973
974
  switch (a.material.type) {
@@ -979,7 +980,7 @@ let ie = class M {
979
980
  case "MeshDepthMaterial":
980
981
  continue;
981
982
  }
982
- if (C === "color" && a.material && !a.object.progressive_debug_color) {
983
+ if (k === "color" && a.material && !a.object.progressive_debug_color) {
983
984
  a.object.progressive_debug_color = !0;
984
985
  const d = Math.random() * 16777215, p = new Ve({ color: d });
985
986
  a.object.material = p;
@@ -1007,7 +1008,7 @@ let ie = class M {
1007
1008
  for (const l of W)
1008
1009
  l.onBeforeUpdateLOD?.(this.renderer, t, e, s);
1009
1010
  const i = M.overrideGlobalLodLevel !== void 0 ? M.overrideGlobalLodLevel : N;
1010
- i >= 0 ? (P.mesh_lod = i, P.texture_lod = i) : (this.calculateLodLevel(e, s, n, r, P), P.mesh_lod = Math.round(P.mesh_lod), P.texture_lod = Math.round(P.texture_lod)), P.mesh_lod >= 0 && this.loadProgressiveMeshes(s, P.mesh_lod), s.material && P.texture_lod >= 0 && this.loadProgressiveTextures(s.material, P.texture_lod, i), g && s.material && !s.isGizmo && ke(s.material);
1011
+ i >= 0 ? (P.mesh_lod = i, P.texture_lod = i) : (this.calculateLodLevel(e, s, n, r, P), P.mesh_lod = Math.round(P.mesh_lod), P.texture_lod = Math.round(P.texture_lod)), P.mesh_lod >= 0 && this.loadProgressiveMeshes(s, P.mesh_lod), s.material && P.texture_lod >= 0 && this.loadProgressiveTextures(s.material, P.texture_lod, i), g && s.material && !s.isGizmo && Ce(s.material);
1011
1012
  for (const l of W)
1012
1013
  l.onAfterUpdatedLOD?.(this.renderer, t, e, s, P);
1013
1014
  n.lastLodLevel_Mesh = P.mesh_lod, n.lastLodLevel_Texture = P.texture_lod;
@@ -1053,7 +1054,7 @@ let ie = class M {
1053
1054
  return Promise.resolve(null);
1054
1055
  }
1055
1056
  // private testIfLODLevelsAreAvailable() {
1056
- _sphere = new ve();
1057
+ _sphere = new Oe();
1057
1058
  _tempBox = new ge();
1058
1059
  _tempBox2 = new ge();
1059
1060
  tempMatrix = new _e();
@@ -1082,7 +1083,7 @@ let ie = class M {
1082
1083
  return;
1083
1084
  }
1084
1085
  let l = 10 + 1, a = !1;
1085
- if (C && e["DEBUG:LOD"] != null)
1086
+ if (k && e["DEBUG:LOD"] != null)
1086
1087
  return e["DEBUG:LOD"];
1087
1088
  const u = y.getMeshLODExtension(e.geometry)?.lods, d = y.getPrimitiveIndex(e.geometry), p = u && u.length > 0, L = y.getMaterialMinMaxLODsCount(e.material), _ = L.min_count !== 1 / 0 && L.min_count >= 0 && L.max_count >= 0;
1088
1089
  if (!p && !_) {
@@ -1098,13 +1099,13 @@ let ie = class M {
1098
1099
  c.computeBoundingBox();
1099
1100
  else if (this.skinnedMeshAutoUpdateBoundsInterval > 0) {
1100
1101
  if (!c[M.$skinnedMeshBoundsOffset]) {
1101
- const v = M.skinnedMeshBoundsFrameOffsetCounter++;
1102
- c[M.$skinnedMeshBoundsOffset] = v;
1102
+ const O = M.skinnedMeshBoundsFrameOffsetCounter++;
1103
+ c[M.$skinnedMeshBoundsOffset] = O;
1103
1104
  }
1104
1105
  const x = c[M.$skinnedMeshBoundsOffset];
1105
1106
  if ((s.frames + x) % this.skinnedMeshAutoUpdateBoundsInterval === 0) {
1106
- const v = J(c), B = c.geometry;
1107
- v && (c.geometry = v), c.computeBoundingBox(), c.geometry = B;
1107
+ const O = J(c), B = c.geometry;
1108
+ O && (c.geometry = O), c.computeBoundingBox(), c.geometry = B;
1108
1109
  }
1109
1110
  }
1110
1111
  G = c.boundingBox;
@@ -1125,58 +1126,58 @@ let ie = class M {
1125
1126
  }
1126
1127
  if (this._tempBox.applyMatrix4(this.projectionScreenMatrix), this.renderer.xr.enabled && c.isPerspectiveCamera && c.fov > 70) {
1127
1128
  const f = this._tempBox.min, h = this._tempBox.max;
1128
- let b = f.x, O = f.y, $ = h.x, K = h.y;
1129
+ let b = f.x, v = f.y, $ = h.x, K = h.y;
1129
1130
  const Z = 2, oe = 1.5, ee = (f.x + h.x) * 0.5, te = (f.y + h.y) * 0.5;
1130
- b = (b - ee) * Z + ee, O = (O - te) * Z + te, $ = ($ - ee) * Z + ee, K = (K - te) * Z + te;
1131
- const $e = b < 0 && $ > 0 ? 0 : Math.min(Math.abs(f.x), Math.abs(h.x)), Ge = O < 0 && K > 0 ? 0 : Math.min(Math.abs(f.y), Math.abs(h.y)), ae = Math.max($e, Ge);
1131
+ b = (b - ee) * Z + ee, v = (v - te) * Z + te, $ = ($ - ee) * Z + ee, K = (K - te) * Z + te;
1132
+ const $e = b < 0 && $ > 0 ? 0 : Math.min(Math.abs(f.x), Math.abs(h.x)), Ge = v < 0 && K > 0 ? 0 : Math.min(Math.abs(f.y), Math.abs(h.y)), ae = Math.max($e, Ge);
1132
1133
  s.lastCentrality = (oe - ae) * (oe - ae) * (oe - ae);
1133
1134
  } else
1134
1135
  s.lastCentrality = 1;
1135
1136
  const x = this._tempBox.getSize(this._tempBoxSize);
1136
1137
  x.multiplyScalar(0.5), screen.availHeight > 0 && I > 0 && x.multiplyScalar(I / screen.availHeight), t.isPerspectiveCamera ? x.x *= t.aspect : t.isOrthographicCamera;
1137
- const v = t.matrixWorldInverse, B = this._tempBox2;
1138
- B.copy(G), B.applyMatrix4(e.matrixWorld), B.applyMatrix4(v);
1138
+ const O = t.matrixWorldInverse, B = this._tempBox2;
1139
+ B.copy(G), B.applyMatrix4(e.matrixWorld), B.applyMatrix4(O);
1139
1140
  const D = B.getSize(this._tempBox2Size), z = Math.max(D.x, D.y);
1140
- if (Math.max(x.x, x.y) != 0 && z != 0 && (x.z = D.z / Math.max(D.x, D.y) * Math.max(x.x, x.y)), s.lastScreenCoverage = Math.max(x.x, x.y, x.z), s.lastScreenspaceVolume.copy(x), s.lastScreenCoverage *= s.lastCentrality, C && M.debugDrawLine) {
1141
+ if (Math.max(x.x, x.y) != 0 && z != 0 && (x.z = D.z / Math.max(D.x, D.y) * Math.max(x.x, x.y)), s.lastScreenCoverage = Math.max(x.x, x.y, x.z), s.lastScreenspaceVolume.copy(x), s.lastScreenCoverage *= s.lastCentrality, k && M.debugDrawLine) {
1141
1142
  const f = this.tempMatrix.copy(this.projectionScreenMatrix);
1142
1143
  f.invert();
1143
- const h = M.corner0, b = M.corner1, O = M.corner2, $ = M.corner3;
1144
- h.copy(this._tempBox.min), b.copy(this._tempBox.max), b.x = h.x, O.copy(this._tempBox.max), O.y = h.y, $.copy(this._tempBox.max);
1144
+ const h = M.corner0, b = M.corner1, v = M.corner2, $ = M.corner3;
1145
+ h.copy(this._tempBox.min), b.copy(this._tempBox.max), b.x = h.x, v.copy(this._tempBox.max), v.y = h.y, $.copy(this._tempBox.max);
1145
1146
  const K = (h.z + $.z) * 0.5;
1146
- h.z = b.z = O.z = $.z = K, h.applyMatrix4(f), b.applyMatrix4(f), O.applyMatrix4(f), $.applyMatrix4(f), M.debugDrawLine(h, b, 255), M.debugDrawLine(h, O, 255), M.debugDrawLine(b, $, 255), M.debugDrawLine(O, $, 255);
1147
+ h.z = b.z = v.z = $.z = K, h.applyMatrix4(f), b.applyMatrix4(f), v.applyMatrix4(f), $.applyMatrix4(f), M.debugDrawLine(h, b, 255), M.debugDrawLine(h, v, 255), M.debugDrawLine(b, $, 255), M.debugDrawLine(v, $, 255);
1147
1148
  }
1148
1149
  let w = 999;
1149
1150
  if (u && s.lastScreenCoverage > 0)
1150
1151
  for (let f = 0; f < u.length; f++) {
1151
- const h = u[f], O = (h.densities?.[d] || h.density || 1e-5) / s.lastScreenCoverage;
1152
- if (d > 0 && Me() && !h.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.")), O < r) {
1152
+ const h = u[f], v = (h.densities?.[d] || h.density || 1e-5) / s.lastScreenCoverage;
1153
+ if (d > 0 && Me() && !h.densities && !globalThis["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"] && (window["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"] = !0, console.warn("[Needle Progressive] Detected usage of mesh without primitive densities. This might cause incorrect LOD level selection: Consider re-optimizing your model by updating your Needle Integration, Needle glTF Pipeline or running optimization again on Needle Cloud.")), v < r) {
1153
1154
  w = f;
1154
1155
  break;
1155
1156
  }
1156
1157
  }
1157
1158
  w < l && (l = w, a = !0);
1158
1159
  }
1159
- if (a ? n.mesh_lod = l : n.mesh_lod = s.lastLodLevel_Mesh, C && n.mesh_lod != s.lastLodLevel_Mesh) {
1160
+ if (a ? n.mesh_lod = l : n.mesh_lod = s.lastLodLevel_Mesh, k && n.mesh_lod != s.lastLodLevel_Mesh) {
1160
1161
  const x = u?.[n.mesh_lod];
1161
1162
  x && console.debug(`Mesh LOD changed: ${s.lastLodLevel_Mesh} → ${n.mesh_lod} (density: ${x.densities?.[d].toFixed(0)}) | ${e.name}`);
1162
1163
  }
1163
1164
  if (_) {
1164
1165
  const c = "saveData" in globalThis.navigator && globalThis.navigator.saveData === !0;
1165
1166
  if (s.lastLodLevel_Texture < 0) {
1166
- if (n.texture_lod = L.max_count - 1, C) {
1167
+ if (n.texture_lod = L.max_count - 1, k) {
1167
1168
  const x = L.lods[L.max_count - 1];
1168
- C && console.log(`First Texture LOD ${n.texture_lod} (${x.max_height}px) - ${e.name}`);
1169
+ k && console.log(`First Texture LOD ${n.texture_lod} (${x.max_height}px) - ${e.name}`);
1169
1170
  }
1170
1171
  } else {
1171
1172
  const x = s.lastScreenspaceVolume.x + s.lastScreenspaceVolume.y + s.lastScreenspaceVolume.z;
1172
- let v = s.lastScreenCoverage * 4;
1173
- this.context?.engine === "model-viewer" && (v *= 1.5);
1174
- const D = I / window.devicePixelRatio * v;
1173
+ let O = s.lastScreenCoverage * 4;
1174
+ this.context?.engine === "model-viewer" && (O *= 1.5);
1175
+ const D = I / window.devicePixelRatio * O;
1175
1176
  let z = !1;
1176
1177
  for (let S = L.lods.length - 1; S >= 0; S--) {
1177
1178
  const w = L.lods[S];
1178
- if (!(c && w.max_height >= 2048) && !(Ce() && w.max_height > 4096) && (w.max_height > D || !z && S === 0)) {
1179
- if (z = !0, n.texture_lod = S, C && n.texture_lod < s.lastLodLevel_Texture) {
1179
+ if (!(c && w.max_height >= 2048) && !(ke() && w.max_height > 4096) && (w.max_height > D || !z && S === 0)) {
1180
+ if (z = !0, n.texture_lod = S, k && n.texture_lod < s.lastLodLevel_Texture) {
1180
1181
  const m = w.max_height;
1181
1182
  console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${n.texture_lod} = ${m}px
1182
1183
  Screensize: ${D.toFixed(0)}px, Coverage: ${(100 * s.lastScreenCoverage).toFixed(2)}%, Volume ${x.toFixed(1)}
@@ -1227,12 +1228,12 @@ function be() {
1227
1228
  Be(t);
1228
1229
  });
1229
1230
  }
1230
- const Oe = /* @__PURE__ */ new WeakSet();
1231
+ const ve = /* @__PURE__ */ new WeakSet();
1231
1232
  let xt = 0;
1232
1233
  function Be(o) {
1233
- if (!o || Oe.has(o))
1234
+ if (!o || ve.has(o))
1234
1235
  return null;
1235
- Oe.add(o), console.debug("[gltf-progressive] found new model-viewer..." + ++xt + `
1236
+ ve.add(o), console.debug("[gltf-progressive] found new model-viewer..." + ++xt + `
1236
1237
  `, o.getAttribute("src"));
1237
1238
  let t = null, e = null, s = null;
1238
1239
  for (let r = o; r != null; r = Object.getPrototypeOf(r)) {
@@ -1333,13 +1334,27 @@ class wt {
1333
1334
  }
1334
1335
  }
1335
1336
  }
1336
- function Lt(o, t, e, s) {
1337
- we(t), Te(e), Ie(e, {
1337
+ function Lt(...o) {
1338
+ let t, e, s, r;
1339
+ switch (o.length) {
1340
+ case 2:
1341
+ [s, e] = o, r = {};
1342
+ break;
1343
+ case 3:
1344
+ [s, e, r] = o;
1345
+ break;
1346
+ case 4:
1347
+ [t, e, s, r] = o;
1348
+ break;
1349
+ default:
1350
+ throw new Error("Invalid arguments");
1351
+ }
1352
+ we(e), Te(s), Ie(s, {
1338
1353
  progressive: !0,
1339
- ...s?.hints
1340
- }), e.register((n) => new y(n, o));
1341
- const r = ie.get(t);
1342
- return s?.enableLODsManager !== !1 && r.enable(), r;
1354
+ ...r?.hints
1355
+ }), s.register((i) => new y(i));
1356
+ const n = ie.get(e);
1357
+ return r?.enableLODsManager !== !1 && n.enable(), n;
1343
1358
  }
1344
1359
  Re();
1345
1360
  if (!rt) {
@@ -1,8 +1,8 @@
1
- "use strict";const d=require("./three-B_hneGZr.umd.cjs"),q=require("./three-examples-BhQvv1B9.umd.cjs");var ae=typeof document<"u"?document.currentScript:null;const be="3.1.1";globalThis.GLTF_PROGRESSIVE_VERSION=be;console.debug(`[gltf-progressive] version ${be}`);let k="https://www.gstatic.com/draco/versioned/decoders/1.5.7/",V="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";const Be=k,$e=V,ve=new URL(k+"draco_decoder.js");ve.searchParams.append("range","true");fetch(ve,{method:"GET",headers:{Range:"bytes=0-1"}}).catch(i=>{console.debug(`Failed to fetch remote Draco decoder from ${k} (offline: ${typeof navigator<"u"?navigator.onLine:"unknown"})`),k===Be&&Oe("./include/draco/"),V===$e&&Se("./include/ktx2/")}).finally(()=>{Te()});const Ge=()=>({dracoDecoderPath:k,ktx2TranscoderPath:V});function Oe(i){k=i,A&&A[ge]!=k?(console.debug("Updating Draco decoder path to "+i),A[ge]=k,A.setDecoderPath(k),A.preload()):console.debug("Setting Draco decoder path to "+i)}function Se(i){V=i,R&&R.transcoderPath!=V?(console.debug("Updating KTX2 transcoder path to "+i),R.setTranscoderPath(V),R.init()):console.debug("Setting KTX2 transcoder path to "+i)}function ne(i){return Te(),i?R.detectSupport(i):i!==null&&console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"),{dracoLoader:A,ktx2Loader:R,meshoptDecoder:se}}function ye(i){i.dracoLoader||i.setDRACOLoader(A),i.ktx2Loader||i.setKTX2Loader(R),i.meshoptDecoder||i.setMeshoptDecoder(se)}const ge=Symbol("dracoDecoderPath");let A,se,R;function Te(){A||(A=new q.DRACOLoader,A[ge]=k,A.setDecoderPath(k),A.setDecoderConfig({type:"js"}),A.preload()),R||(R=new q.KTX2Loader,R.setTranscoderPath(V),R.init()),se||(se=q.MeshoptDecoder)}const pe=new WeakMap;function xe(i,t){let e=pe.get(i);e?e=Object.assign(e,t):e=t,pe.set(i,e)}const Fe=q.GLTFLoader.prototype.load;function Ue(...i){const t=pe.get(this);let e=i[0];const r=new URL(e,window.location.href);if(r.hostname.endsWith("needle.tools")){const s=t?.progressive!==void 0?t.progressive:!0,o=t?.usecase?t.usecase:"default";s?this.requestHeader.Accept=`*/*;progressive=allowed;usecase=${o}`:this.requestHeader.Accept=`*/*;usecase=${o}`,e=r.toString()}return i[0]=e,Fe?.call(this,...i)}q.GLTFLoader.prototype.load=Ue;N("debugprogressive");function N(i){if(typeof window>"u")return!1;const e=new URL(window.location.href).searchParams.get(i);return e==null||e==="0"||e==="false"?!1:e===""?!0:e}function Ee(i,t){if(t===void 0||t.startsWith("./")||t.startsWith("http")||i===void 0)return t;const e=i.lastIndexOf("/");if(e>=0){const r=i.substring(0,e+1);for(;r.endsWith("/")&&t.startsWith("/");)t=t.substring(1);return r+t}return t}let j;function Pe(){return j!==void 0||(j=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),N("debugprogressive")&&console.log("[glTF Progressive]: isMobileDevice",j)),j}function Le(){if(typeof window>"u")return!1;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);return i.hostname==="127.0.0.1"||t}class We{maxConcurrent;_running=new Map;_queue=[];debug=!1;constructor(t=100,e={}){this.maxConcurrent=t,this.debug=e.debug??!1,window.requestAnimationFrame(this.tick)}tick=()=>{this.internalUpdate(),setTimeout(this.tick,10)};slot(t){return this.debug&&console.debug(`[PromiseQueue]: Requesting slot for key ${t}, running: ${this._running.size}, waiting: ${this._queue.length}`),new Promise(e=>{this._queue.push({key:t,resolve:e})})}add(t,e){this._running.has(t)||(this._running.set(t,e),e.finally(()=>{this._running.delete(t),this.debug&&console.debug(`[PromiseQueue]: Promise finished now running: ${this._running.size}, waiting: ${this._queue.length}. (finished ${t})`)}),this.debug&&console.debug(`[PromiseQueue]: Added new promise, now running: ${this._running.size}, waiting: ${this._queue.length}. (added ${t})`))}internalUpdate(){const t=this.maxConcurrent-this._running.size;for(let e=0;e<t&&this._queue.length>0;e++){this.debug&&console.debug(`[PromiseQueue]: Running ${this._running.size} promises, waiting for ${this._queue.length} more.`);const{key:r,resolve:n}=this._queue.shift();n({use:s=>this.add(r,s)})}}}const ze=typeof window>"u"&&typeof document>"u",me=Symbol("needle:raycast-mesh");function X(i){return i?.[me]instanceof d.BufferGeometry?i[me]:null}function Ve(i,t){if((i.type==="Mesh"||i.type==="SkinnedMesh")&&!X(i)){const r=qe(t);r.userData={isRaycastMesh:!0},i[me]=r}}function Ne(i=!0){if(i){if(Y)return;const t=Y=d.Mesh.prototype.raycast;d.Mesh.prototype.raycast=function(e,r){const n=this,s=X(n);let o;s&&n.isMesh&&(o=n.geometry,n.geometry=s),t.call(this,e,r),o&&(n.geometry=o)}}else{if(!Y)return;d.Mesh.prototype.raycast=Y,Y=null}}let Y=null;function qe(i){const t=new d.BufferGeometry;for(const e in i.attributes)t.setAttribute(e,i.getAttribute(e));return t.setIndex(i.getIndex()),t}const E=new Array,p=N("debugprogressive");let re,z=-1;if(p){let t=function(){z+=1,z>=i&&(z=-1),console.log(`Toggle LOD level [${z}]`)},i=6;window.addEventListener("keyup",e=>{e.key==="p"&&t(),e.key==="w"&&(re=!re,console.log(`Toggle wireframe [${re}]`));const r=parseInt(e.key);!isNaN(r)&&r>=0&&(z=r,console.log(`Set LOD level to [${z}]`))})}function Ae(i){if(p)if(Array.isArray(i))for(const t of i)Ae(t);else i&&"wireframe"in i&&(i.wireframe=re===!0)}const H=new Array;let Xe=0;const Ke=Pe()?2:10;function je(i){if(H.length<Ke){const r=H.length;p&&console.warn(`[Worker] Creating new worker #${r}`);const n=we.createWorker(i||{});return H.push(n),n}const t=Xe++%H.length;return H[t]}class we{worker;static async createWorker(t){const e=new Worker(new URL("/loader.worker-8olmVOL4.js",typeof document>"u"?require("url").pathToFileURL(__filename).href:ae&&ae.tagName.toUpperCase()==="SCRIPT"&&ae.src||new URL("gltf-progressive--2HtE1d8.umd.cjs",document.baseURI).href),{type:"module"});return new we(e,t)}_running=[];_webglRenderer=null;async load(t,e){const r=Ge();let n=e?.renderer;n||(this._webglRenderer??=(async()=>{const{WebGLRenderer:u}=await Promise.resolve().then(()=>require("./three-B_hneGZr.umd.cjs")).then(c=>c.THREE);return new u})(),n=await this._webglRenderer);const l=ne(n).ktx2Loader.workerConfig;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());const a={type:"load",url:t,dracoDecoderPath:r.dracoDecoderPath,ktx2TranscoderPath:r.ktx2TranscoderPath,ktx2LoaderConfig:l};return this._debug&&console.debug("[Worker] Sending load request",a),this.worker.postMessage(a),new Promise(u=>{this._running.push({url:t.toString(),resolve:u})})}_debug=!1;constructor(t,e){this.worker=t,this._debug=e.debug??!1,t.onmessage=r=>{const n=r.data;switch(this._debug&&console.log("[Worker] EVENT",n),n.type){case"loaded-gltf":for(const s of this._running)if(s.url===n.result.url){Ye(n.result),s.resolve(n.result);const o=s.url;o.startsWith("blob:")&&URL.revokeObjectURL(o)}}},t.onerror=r=>{console.error("[Worker] Error in gltf-progressive worker:",r)},t.postMessage({type:"init"})}}function Ye(i){for(const t of i.geometries){const e=t.geometry,r=new d.BufferGeometry;if(r.name=e.name||"",e.index){const n=e.index;r.setIndex(le(n))}for(const n in e.attributes){const s=e.attributes[n],o=le(s);r.setAttribute(n,o)}if(e.morphAttributes)for(const n in e.morphAttributes){const o=e.morphAttributes[n].map(l=>le(l));r.morphAttributes[n]=o}if(r.morphTargetsRelative=e.morphTargetsRelative??!1,r.boundingBox=new d.Box3,r.boundingBox.min=new d.Vector3(e.boundingBox?.min.x,e.boundingBox?.min.y,e.boundingBox?.min.z),r.boundingBox.max=new d.Vector3(e.boundingBox?.max.x,e.boundingBox?.max.y,e.boundingBox?.max.z),r.boundingSphere=new d.Sphere(new d.Vector3(e.boundingSphere?.center.x,e.boundingSphere?.center.y,e.boundingSphere?.center.z),e.boundingSphere?.radius),e.groups)for(const n of e.groups)r.addGroup(n.start,n.count,n.materialIndex);e.userData&&(r.userData=e.userData),t.geometry=r}for(const t of i.textures){const e=t.texture;let r=null;if(e.isCompressedTexture){const n=e.mipmaps,s=e.image?.width||e.source?.data?.width||-1,o=e.image?.height||e.source?.data?.height||-1;r=new d.CompressedTexture(n,s,o,e.format,e.type,e.mapping,e.wrapS,e.wrapT,e.magFilter,e.minFilter,e.anisotropy,e.colorSpace)}else r=new d.Texture(e.image,e.mapping,e.wrapS,e.wrapT,e.magFilter,e.minFilter,e.format,e.type,e.anisotropy,e.colorSpace),r.mipmaps=e.mipmaps,r.channel=e.channel,r.source.data=e.source.data,r.flipY=e.flipY,r.premultiplyAlpha=e.premultiplyAlpha,r.unpackAlignment=e.unpackAlignment,r.matrix=new d.Matrix3(...e.matrix.elements);if(!r){console.error("[Worker] Failed to create new texture from received data. Texture is not a CompressedTexture or Texture.");continue}t.texture=r}return i}function le(i){let t=i;if("isInterleavedBufferAttribute"in i&&i.isInterleavedBufferAttribute){const e=i.data,r=e.array,n=new d.InterleavedBuffer(r,e.stride);t=new d.InterleavedBufferAttribute(n,i.itemSize,r.byteOffset,i.normalized),t.offset=i.offset}else"isBufferAttribute"in i&&i.isBufferAttribute&&(t=new d.BufferAttribute(i.array,i.itemSize,i.normalized),t.usage=i.usage,t.gpuType=i.gpuType,t.updateRanges=i.updateRanges);return t}const He=N("gltf-progressive-worker"),Qe=N("gltf-progressive-reduce-mipmaps"),ue=Symbol("needle-progressive-texture"),F="NEEDLE_progressive";class x{get name(){return F}static getMeshLODExtension(t){const e=this.getAssignedLODInformation(t);return e?.key?this.lodInfos.get(e.key):null}static getPrimitiveIndex(t){const e=this.getAssignedLODInformation(t)?.index;return e??-1}static getMaterialMinMaxLODsCount(t,e){const r=this,n="LODS:minmax",s=t[n];if(s!=null)return s;if(e||(e={min_count:1/0,max_count:0,lods:[]}),Array.isArray(t)){for(const l of t)this.getMaterialMinMaxLODsCount(l,e);return t[n]=e,e}if(p==="verbose"&&console.log("getMaterialMinMaxLODsCount",t),t.type==="ShaderMaterial"||t.type==="RawShaderMaterial"){const l=t;for(const a of Object.keys(l.uniforms)){const u=l.uniforms[a].value;u?.isTexture===!0&&o(u,e)}}else if(t.isMaterial)for(const l of Object.keys(t)){const a=t[l];a?.isTexture===!0&&o(a,e)}else p&&console.warn(`[getMaterialMinMaxLODsCount] Unsupported material type: ${t.type}`);return t[n]=e,e;function o(l,a){const u=r.getAssignedLODInformation(l);if(u){const c=r.lodInfos.get(u.key);if(c&&c.lods){a.min_count=Math.min(a.min_count,c.lods.length),a.max_count=Math.max(a.max_count,c.lods.length);for(let m=0;m<c.lods.length;m++){const _=c.lods[m];_.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,_.height),a.lods[m].max_height=Math.max(a.lods[m].max_height,_.height))}}}}}static hasLODLevelAvailable(t,e){if(Array.isArray(t)){for(const s of t)if(this.hasLODLevelAvailable(s,e))return!0;return!1}if(t.isMaterial===!0){for(const s of Object.keys(t)){const o=t[s];if(o&&o.isTexture&&this.hasLODLevelAvailable(o,e))return!0}return!1}else if(t.isGroup===!0){for(const s of t.children)if(s.isMesh===!0&&this.hasLODLevelAvailable(s,e))return!0}let r,n;if(t.isMesh?r=t.geometry:(t.isBufferGeometry||t.isTexture)&&(r=t),r&&r?.userData?.LODS){const s=r.userData.LODS;if(n=this.lodInfos.get(s.key),e===void 0)return n!=null;if(n)return Array.isArray(n.lods)?e<n.lods.length:e===0}return!1}static assignMeshLOD(t,e){if(!t)return Promise.resolve(null);if(t instanceof d.Mesh||t.isMesh===!0){const r=t.geometry,n=this.getAssignedLODInformation(r);if(!n)return Promise.resolve(null);for(const s of E)s.onBeforeGetLODMesh?.(t,e);return t["LOD:requested level"]=e,x.getOrLoadLOD(r,e).then(s=>{if(Array.isArray(s)){const o=n.index||0;s=s[o]}return t["LOD:requested level"]===e&&(delete t["LOD:requested level"],s&&r!=s&&(s?.isBufferGeometry?t.geometry=s:p&&console.error("Invalid LOD geometry",s))),s}).catch(s=>(console.error("Error loading mesh LOD",t,s),null))}else p&&console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh",t);return Promise.resolve(null)}static assignTextureLOD(t,e=0){if(!t)return Promise.resolve(null);if(t.isMesh===!0){const r=t;if(Array.isArray(r.material)){const n=new Array;for(const s of r.material){const o=this.assignTextureLOD(s,e);n.push(o)}return Promise.all(n).then(s=>{const o=new Array;for(const l of s)Array.isArray(l)&&o.push(...l);return o})}else return this.assignTextureLOD(r.material,e)}if(t.isMaterial===!0){const r=t,n=[],s=new Array;if(r.uniforms&&(r.isRawShaderMaterial||r.isShaderMaterial===!0)){const o=r;for(const l of Object.keys(o.uniforms)){const a=o.uniforms[l].value;if(a?.isTexture===!0){const u=this.assignTextureLODForSlot(a,e,r,l).then(c=>(c&&o.uniforms[l].value!=c&&(o.uniforms[l].value=c,o.uniformsNeedUpdate=!0),c));n.push(u),s.push(l)}}}else for(const o of Object.keys(r)){const l=r[o];if(l?.isTexture===!0){const a=this.assignTextureLODForSlot(l,e,r,o);n.push(a),s.push(o)}}return Promise.all(n).then(o=>{const l=new Array;for(let a=0;a<o.length;a++){const u=o[a],c=s[a];u&&u.isTexture===!0?l.push({material:r,slot:c,texture:u,level:e}):l.push({material:r,slot:c,texture:null,level:e})}return l})}if(t instanceof d.Texture||t.isTexture===!0){const r=t;return this.assignTextureLODForSlot(r,e,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(t,e,r,n){return t?.isTexture!==!0?Promise.resolve(null):n==="glyphMap"?Promise.resolve(t):x.getOrLoadLOD(t,e).then(s=>{if(Array.isArray(s))return console.warn("Progressive: Got an array of textures for a texture slot, this should not happen..."),null;if(s?.isTexture===!0){if(s!=t&&r&&n){const o=r[n];if(o&&!p){const l=this.getAssignedLODInformation(o);if(l&&l?.level<e)return p==="verbose"&&console.warn("Assigned texture level is already higher: ",l.level,e,r,o,s),null}if(Qe&&s.mipmaps){const l=s.mipmaps.length;s.mipmaps.length=Math.min(s.mipmaps.length,3),l!==s.mipmaps.length&&p&&console.debug(`Reduced mipmap count from ${l} to ${s.mipmaps.length} for ${s.uuid}: ${s.image?.width}x${s.image?.height}.`)}r[n]=s}return s}else p=="verbose"&&console.warn("No LOD found for",t,e);return null}).catch(s=>(console.error("Error loading LOD",t,s),null))}parser;url;constructor(t,e){p&&console.log("Progressive extension registered for",e),this.parser=t,this.url=e}_isLoadingMesh;loadMesh=t=>{if(this._isLoadingMesh)return null;const e=this.parser.json.meshes[t]?.extensions?.[F];return e?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",t).then(r=>(this._isLoadingMesh=!1,r&&x.registerMesh(this.url,e.guid,r,e.lods?.length,0,e),r))):null};afterRoot(t){return p&&console.log("AFTER",this.url,t),this.parser.json.textures?.forEach((e,r)=>{if(e?.extensions){const n=e?.extensions[F];if(n){if(!n.lods){p&&console.warn("Texture has no LODs",n);return}let s=!1;for(const o of this.parser.associations.keys())o.isTexture===!0&&this.parser.associations.get(o)?.textures===r&&(s=!0,x.registerTexture(this.url,o,n.lods?.length,r,n));s||this.parser.getDependency("texture",r).then(o=>{o&&x.registerTexture(this.url,o,n.lods?.length,r,n)})}}}),this.parser.json.meshes?.forEach((e,r)=>{if(e?.extensions){const n=e?.extensions[F];if(n&&n.lods){for(const s of this.parser.associations.keys())if(s.isMesh){const o=this.parser.associations.get(s);o?.meshes===r&&x.registerMesh(this.url,n.guid,s,n.lods.length,o.primitives,n)}}}}),null}static registerTexture=(t,e,r,n,s)=>{if(!e){p&&console.error("gltf-progressive: Called register texture without texture");return}if(p){const l=e.image?.width||e.source?.data?.width||0,a=e.image?.height||e.source?.data?.height||0;console.log(`> Progressive: register texture[${n}] "${e.name||e.uuid}", Current: ${l}x${a}, Max: ${s.lods[0]?.width}x${s.lods[0]?.height}, uuid: ${e.uuid}`,s,e)}e.source&&(e.source[ue]=s);const o=s.guid;x.assignLODInformation(t,e,o,r,n),x.lodInfos.set(o,s),x.lowresCache.set(o,e)};static registerMesh=(t,e,r,n,s,o)=>{const l=r.geometry;if(!l){p&&console.warn("gltf-progressive: Register mesh without geometry");return}l.userData||(l.userData={}),p&&console.log("> Progressive: register mesh "+r.name,{index:s,uuid:r.uuid},o,r),x.assignLODInformation(t,l,e,n,s),x.lodInfos.set(e,o);let a=x.lowresCache.get(e);a?a.push(r.geometry):a=[r.geometry],x.lowresCache.set(e,a),n>0&&!X(r)&&Ve(r,l);for(const u of E)u.onRegisteredNewMesh?.(r,o)};static lodInfos=new Map;static previouslyLoaded=new Map;static lowresCache=new Map;static workers=[];static _workersIndex=0;static async getOrLoadLOD(t,e){const r=p=="verbose",n=this.getAssignedLODInformation(t);if(!n)return p&&console.warn(`[gltf-progressive] No LOD information found: ${t.name}, uuid: ${t.uuid}, type: ${t.type}`,t),null;const s=n?.key;let o;if(t.isTexture===!0){const a=t;a.source&&a.source[ue]&&(o=a.source[ue])}if(o||(o=x.lodInfos.get(s)),o){if(e>0){let c=!1;const m=Array.isArray(o.lods);if(m&&e>=o.lods.length?c=!0:m||(c=!0),c)return this.lowresCache.get(s)}const a=Array.isArray(o.lods)?o.lods[e]?.path:o.lods;if(!a)return p&&!o["missing:uri"]&&(o["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+e,o)),null;const u=Ee(n.url,a);if(u.endsWith(".glb")||u.endsWith(".gltf")){if(!o.guid)return console.warn("missing pointer for glb/gltf texture",o),null;const c=u+"_"+o.guid,m=await this.queue.slot(u),_=this.previouslyLoaded.get(c);if(_!==void 0){r&&console.log(`LOD ${e} was already loading/loaded: ${c}`);let f=await _.catch(S=>(console.error(`Error loading LOD ${e} from ${u}
1
+ "use strict";const d=require("./three-B_hneGZr.umd.cjs"),q=require("./three-examples-CNRuT27G.umd.cjs");var ae=typeof document<"u"?document.currentScript:null;const be="3.2.0";globalThis.GLTF_PROGRESSIVE_VERSION=be;console.debug(`[gltf-progressive] version ${be}`);let k="https://www.gstatic.com/draco/versioned/decoders/1.5.7/",N="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";const Be=k,$e=N,ve=new URL(k+"draco_decoder.js");ve.searchParams.append("range","true");fetch(ve,{method:"GET",headers:{Range:"bytes=0-1"}}).catch(i=>{console.debug(`Failed to fetch remote Draco decoder from ${k} (offline: ${typeof navigator<"u"?navigator.onLine:"unknown"})`),k===Be&&Oe("./include/draco/"),N===$e&&Se("./include/ktx2/")}).finally(()=>{Te()});const Ge=()=>({dracoDecoderPath:k,ktx2TranscoderPath:N});function Oe(i){k=i,A&&A[ge]!=k?(console.debug("Updating Draco decoder path to "+i),A[ge]=k,A.setDecoderPath(k),A.preload()):console.debug("Setting Draco decoder path to "+i)}function Se(i){N=i,R&&R.transcoderPath!=N?(console.debug("Updating KTX2 transcoder path to "+i),R.setTranscoderPath(N),R.init()):console.debug("Setting KTX2 transcoder path to "+i)}function ne(i){return Te(),i?R.detectSupport(i):i!==null&&console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"),{dracoLoader:A,ktx2Loader:R,meshoptDecoder:se}}function ye(i){i.dracoLoader||i.setDRACOLoader(A),i.ktx2Loader||i.setKTX2Loader(R),i.meshoptDecoder||i.setMeshoptDecoder(se)}const ge=Symbol("dracoDecoderPath");let A,se,R;function Te(){A||(A=new q.DRACOLoader,A[ge]=k,A.setDecoderPath(k),A.setDecoderConfig({type:"js"}),A.preload()),R||(R=new q.KTX2Loader,R.setTranscoderPath(N),R.init()),se||(se=q.MeshoptDecoder)}const pe=new WeakMap;function xe(i,t){let e=pe.get(i);e?e=Object.assign(e,t):e=t,pe.set(i,e)}const Fe=q.GLTFLoader.prototype.load;function Ue(...i){const t=pe.get(this);let e=i[0];const r=new URL(e,window.location.href);if(r.hostname.endsWith("needle.tools")){const s=t?.progressive!==void 0?t.progressive:!0,o=t?.usecase?t.usecase:"default";s?this.requestHeader.Accept=`*/*;progressive=allowed;usecase=${o}`:this.requestHeader.Accept=`*/*;usecase=${o}`,e=r.toString()}return i[0]=e,Fe?.call(this,...i)}q.GLTFLoader.prototype.load=Ue;V("debugprogressive");function V(i){if(typeof window>"u")return!1;const e=new URL(window.location.href).searchParams.get(i);return e==null||e==="0"||e==="false"?!1:e===""?!0:e}function Ee(i,t){if(t===void 0||t.startsWith("./")||t.startsWith("http")||i===void 0)return t;const e=i.lastIndexOf("/");if(e>=0){const r=i.substring(0,e+1);for(;r.endsWith("/")&&t.startsWith("/");)t=t.substring(1);return r+t}return t}let j;function Pe(){return j!==void 0||(j=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),V("debugprogressive")&&console.log("[glTF Progressive]: isMobileDevice",j)),j}function Le(){if(typeof window>"u")return!1;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);return i.hostname==="127.0.0.1"||t}class We{maxConcurrent;_running=new Map;_queue=[];debug=!1;constructor(t=100,e={}){this.maxConcurrent=t,this.debug=e.debug??!1,window.requestAnimationFrame(this.tick)}tick=()=>{this.internalUpdate(),setTimeout(this.tick,10)};slot(t){return this.debug&&console.debug(`[PromiseQueue]: Requesting slot for key ${t}, running: ${this._running.size}, waiting: ${this._queue.length}`),new Promise(e=>{this._queue.push({key:t,resolve:e})})}add(t,e){this._running.has(t)||(this._running.set(t,e),e.finally(()=>{this._running.delete(t),this.debug&&console.debug(`[PromiseQueue]: Promise finished now running: ${this._running.size}, waiting: ${this._queue.length}. (finished ${t})`)}),this.debug&&console.debug(`[PromiseQueue]: Added new promise, now running: ${this._running.size}, waiting: ${this._queue.length}. (added ${t})`))}internalUpdate(){const t=this.maxConcurrent-this._running.size;for(let e=0;e<t&&this._queue.length>0;e++){this.debug&&console.debug(`[PromiseQueue]: Running ${this._running.size} promises, waiting for ${this._queue.length} more.`);const{key:r,resolve:n}=this._queue.shift();n({use:s=>this.add(r,s)})}}}const ze=typeof window>"u"&&typeof document>"u",me=Symbol("needle:raycast-mesh");function X(i){return i?.[me]instanceof d.BufferGeometry?i[me]:null}function Ne(i,t){if((i.type==="Mesh"||i.type==="SkinnedMesh")&&!X(i)){const r=qe(t);r.userData={isRaycastMesh:!0},i[me]=r}}function Ve(i=!0){if(i){if(Y)return;const t=Y=d.Mesh.prototype.raycast;d.Mesh.prototype.raycast=function(e,r){const n=this,s=X(n);let o;s&&n.isMesh&&(o=n.geometry,n.geometry=s),t.call(this,e,r),o&&(n.geometry=o)}}else{if(!Y)return;d.Mesh.prototype.raycast=Y,Y=null}}let Y=null;function qe(i){const t=new d.BufferGeometry;for(const e in i.attributes)t.setAttribute(e,i.getAttribute(e));return t.setIndex(i.getIndex()),t}const E=new Array,p=V("debugprogressive");let re,z=-1;if(p){let t=function(){z+=1,z>=i&&(z=-1),console.log(`Toggle LOD level [${z}]`)},i=6;window.addEventListener("keyup",e=>{e.key==="p"&&t(),e.key==="w"&&(re=!re,console.log(`Toggle wireframe [${re}]`));const r=parseInt(e.key);!isNaN(r)&&r>=0&&(z=r,console.log(`Set LOD level to [${z}]`))})}function Ae(i){if(p)if(Array.isArray(i))for(const t of i)Ae(t);else i&&"wireframe"in i&&(i.wireframe=re===!0)}const H=new Array;let Xe=0;const Ke=Pe()?2:10;function je(i){if(H.length<Ke){const r=H.length;p&&console.warn(`[Worker] Creating new worker #${r}`);const n=we.createWorker(i||{});return H.push(n),n}const t=Xe++%H.length;return H[t]}class we{worker;static async createWorker(t){const e=new Worker(new URL("/loader.worker-CrU5fNbR.js",typeof document>"u"?require("url").pathToFileURL(__filename).href:ae&&ae.tagName.toUpperCase()==="SCRIPT"&&ae.src||new URL("gltf-progressive-VK6wRj74.umd.cjs",document.baseURI).href),{type:"module"});return new we(e,t)}_running=[];_webglRenderer=null;async load(t,e){const r=Ge();let n=e?.renderer;n||(this._webglRenderer??=(async()=>{const{WebGLRenderer:u}=await Promise.resolve().then(()=>require("./three-B_hneGZr.umd.cjs")).then(c=>c.THREE);return new u})(),n=await this._webglRenderer);const l=ne(n).ktx2Loader.workerConfig;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());const a={type:"load",url:t,dracoDecoderPath:r.dracoDecoderPath,ktx2TranscoderPath:r.ktx2TranscoderPath,ktx2LoaderConfig:l};return this._debug&&console.debug("[Worker] Sending load request",a),this.worker.postMessage(a),new Promise(u=>{this._running.push({url:t.toString(),resolve:u})})}_debug=!1;constructor(t,e){this.worker=t,this._debug=e.debug??!1,t.onmessage=r=>{const n=r.data;switch(this._debug&&console.log("[Worker] EVENT",n),n.type){case"loaded-gltf":for(const s of this._running)if(s.url===n.result.url){Ye(n.result),s.resolve(n.result);const o=s.url;o.startsWith("blob:")&&URL.revokeObjectURL(o)}}},t.onerror=r=>{console.error("[Worker] Error in gltf-progressive worker:",r)},t.postMessage({type:"init"})}}function Ye(i){for(const t of i.geometries){const e=t.geometry,r=new d.BufferGeometry;if(r.name=e.name||"",e.index){const n=e.index;r.setIndex(le(n))}for(const n in e.attributes){const s=e.attributes[n],o=le(s);r.setAttribute(n,o)}if(e.morphAttributes)for(const n in e.morphAttributes){const o=e.morphAttributes[n].map(l=>le(l));r.morphAttributes[n]=o}if(r.morphTargetsRelative=e.morphTargetsRelative??!1,r.boundingBox=new d.Box3,r.boundingBox.min=new d.Vector3(e.boundingBox?.min.x,e.boundingBox?.min.y,e.boundingBox?.min.z),r.boundingBox.max=new d.Vector3(e.boundingBox?.max.x,e.boundingBox?.max.y,e.boundingBox?.max.z),r.boundingSphere=new d.Sphere(new d.Vector3(e.boundingSphere?.center.x,e.boundingSphere?.center.y,e.boundingSphere?.center.z),e.boundingSphere?.radius),e.groups)for(const n of e.groups)r.addGroup(n.start,n.count,n.materialIndex);e.userData&&(r.userData=e.userData),t.geometry=r}for(const t of i.textures){const e=t.texture;let r=null;if(e.isCompressedTexture){const n=e.mipmaps,s=e.image?.width||e.source?.data?.width||-1,o=e.image?.height||e.source?.data?.height||-1;r=new d.CompressedTexture(n,s,o,e.format,e.type,e.mapping,e.wrapS,e.wrapT,e.magFilter,e.minFilter,e.anisotropy,e.colorSpace)}else r=new d.Texture(e.image,e.mapping,e.wrapS,e.wrapT,e.magFilter,e.minFilter,e.format,e.type,e.anisotropy,e.colorSpace),r.mipmaps=e.mipmaps,r.channel=e.channel,r.source.data=e.source.data,r.flipY=e.flipY,r.premultiplyAlpha=e.premultiplyAlpha,r.unpackAlignment=e.unpackAlignment,r.matrix=new d.Matrix3(...e.matrix.elements);if(!r){console.error("[Worker] Failed to create new texture from received data. Texture is not a CompressedTexture or Texture.");continue}t.texture=r}return i}function le(i){let t=i;if("isInterleavedBufferAttribute"in i&&i.isInterleavedBufferAttribute){const e=i.data,r=e.array,n=new d.InterleavedBuffer(r,e.stride);t=new d.InterleavedBufferAttribute(n,i.itemSize,r.byteOffset,i.normalized),t.offset=i.offset}else"isBufferAttribute"in i&&i.isBufferAttribute&&(t=new d.BufferAttribute(i.array,i.itemSize,i.normalized),t.usage=i.usage,t.gpuType=i.gpuType,t.updateRanges=i.updateRanges);return t}const He=V("gltf-progressive-worker"),Qe=V("gltf-progressive-reduce-mipmaps"),ue=Symbol("needle-progressive-texture"),F="NEEDLE_progressive";class x{get name(){return F}static getMeshLODExtension(t){const e=this.getAssignedLODInformation(t);return e?.key?this.lodInfos.get(e.key):null}static getPrimitiveIndex(t){const e=this.getAssignedLODInformation(t)?.index;return e??-1}static getMaterialMinMaxLODsCount(t,e){const r=this,n="LODS:minmax",s=t[n];if(s!=null)return s;if(e||(e={min_count:1/0,max_count:0,lods:[]}),Array.isArray(t)){for(const l of t)this.getMaterialMinMaxLODsCount(l,e);return t[n]=e,e}if(p==="verbose"&&console.log("getMaterialMinMaxLODsCount",t),t.type==="ShaderMaterial"||t.type==="RawShaderMaterial"){const l=t;for(const a of Object.keys(l.uniforms)){const u=l.uniforms[a].value;u?.isTexture===!0&&o(u,e)}}else if(t.isMaterial)for(const l of Object.keys(t)){const a=t[l];a?.isTexture===!0&&o(a,e)}else p&&console.warn(`[getMaterialMinMaxLODsCount] Unsupported material type: ${t.type}`);return t[n]=e,e;function o(l,a){const u=r.getAssignedLODInformation(l);if(u){const c=r.lodInfos.get(u.key);if(c&&c.lods){a.min_count=Math.min(a.min_count,c.lods.length),a.max_count=Math.max(a.max_count,c.lods.length);for(let m=0;m<c.lods.length;m++){const _=c.lods[m];_.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,_.height),a.lods[m].max_height=Math.max(a.lods[m].max_height,_.height))}}}}}static hasLODLevelAvailable(t,e){if(Array.isArray(t)){for(const s of t)if(this.hasLODLevelAvailable(s,e))return!0;return!1}if(t.isMaterial===!0){for(const s of Object.keys(t)){const o=t[s];if(o&&o.isTexture&&this.hasLODLevelAvailable(o,e))return!0}return!1}else if(t.isGroup===!0){for(const s of t.children)if(s.isMesh===!0&&this.hasLODLevelAvailable(s,e))return!0}let r,n;if(t.isMesh?r=t.geometry:(t.isBufferGeometry||t.isTexture)&&(r=t),r&&r?.userData?.LODS){const s=r.userData.LODS;if(n=this.lodInfos.get(s.key),e===void 0)return n!=null;if(n)return Array.isArray(n.lods)?e<n.lods.length:e===0}return!1}static assignMeshLOD(t,e){if(!t)return Promise.resolve(null);if(t instanceof d.Mesh||t.isMesh===!0){const r=t.geometry,n=this.getAssignedLODInformation(r);if(!n)return Promise.resolve(null);for(const s of E)s.onBeforeGetLODMesh?.(t,e);return t["LOD:requested level"]=e,x.getOrLoadLOD(r,e).then(s=>{if(Array.isArray(s)){const o=n.index||0;s=s[o]}return t["LOD:requested level"]===e&&(delete t["LOD:requested level"],s&&r!=s&&(s?.isBufferGeometry?t.geometry=s:p&&console.error("Invalid LOD geometry",s))),s}).catch(s=>(console.error("Error loading mesh LOD",t,s),null))}else p&&console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh",t);return Promise.resolve(null)}static assignTextureLOD(t,e=0){if(!t)return Promise.resolve(null);if(t.isMesh===!0){const r=t;if(Array.isArray(r.material)){const n=new Array;for(const s of r.material){const o=this.assignTextureLOD(s,e);n.push(o)}return Promise.all(n).then(s=>{const o=new Array;for(const l of s)Array.isArray(l)&&o.push(...l);return o})}else return this.assignTextureLOD(r.material,e)}if(t.isMaterial===!0){const r=t,n=[],s=new Array;if(r.uniforms&&(r.isRawShaderMaterial||r.isShaderMaterial===!0)){const o=r;for(const l of Object.keys(o.uniforms)){const a=o.uniforms[l].value;if(a?.isTexture===!0){const u=this.assignTextureLODForSlot(a,e,r,l).then(c=>(c&&o.uniforms[l].value!=c&&(o.uniforms[l].value=c,o.uniformsNeedUpdate=!0),c));n.push(u),s.push(l)}}}else for(const o of Object.keys(r)){const l=r[o];if(l?.isTexture===!0){const a=this.assignTextureLODForSlot(l,e,r,o);n.push(a),s.push(o)}}return Promise.all(n).then(o=>{const l=new Array;for(let a=0;a<o.length;a++){const u=o[a],c=s[a];u&&u.isTexture===!0?l.push({material:r,slot:c,texture:u,level:e}):l.push({material:r,slot:c,texture:null,level:e})}return l})}if(t instanceof d.Texture||t.isTexture===!0){const r=t;return this.assignTextureLODForSlot(r,e,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(t,e,r,n){return t?.isTexture!==!0?Promise.resolve(null):n==="glyphMap"?Promise.resolve(t):x.getOrLoadLOD(t,e).then(s=>{if(Array.isArray(s))return console.warn("Progressive: Got an array of textures for a texture slot, this should not happen..."),null;if(s?.isTexture===!0){if(s!=t&&r&&n){const o=r[n];if(o&&!p){const l=this.getAssignedLODInformation(o);if(l&&l?.level<e)return p==="verbose"&&console.warn("Assigned texture level is already higher: ",l.level,e,r,o,s),null}if(Qe&&s.mipmaps){const l=s.mipmaps.length;s.mipmaps.length=Math.min(s.mipmaps.length,3),l!==s.mipmaps.length&&p&&console.debug(`Reduced mipmap count from ${l} to ${s.mipmaps.length} for ${s.uuid}: ${s.image?.width}x${s.image?.height}.`)}r[n]=s}return s}else p=="verbose"&&console.warn("No LOD found for",t,e);return null}).catch(s=>(console.error("Error loading LOD",t,s),null))}parser;url;constructor(t){const e=t.options.path;p&&console.log("Progressive extension registered for",e),this.parser=t,this.url=e}_isLoadingMesh;loadMesh=t=>{if(this._isLoadingMesh)return null;const e=this.parser.json.meshes[t]?.extensions?.[F];return e?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",t).then(r=>(this._isLoadingMesh=!1,r&&x.registerMesh(this.url,e.guid,r,e.lods?.length,0,e),r))):null};afterRoot(t){return p&&console.log("AFTER",this.url,t),this.parser.json.textures?.forEach((e,r)=>{if(e?.extensions){const n=e?.extensions[F];if(n){if(!n.lods){p&&console.warn("Texture has no LODs",n);return}let s=!1;for(const o of this.parser.associations.keys())o.isTexture===!0&&this.parser.associations.get(o)?.textures===r&&(s=!0,x.registerTexture(this.url,o,n.lods?.length,r,n));s||this.parser.getDependency("texture",r).then(o=>{o&&x.registerTexture(this.url,o,n.lods?.length,r,n)})}}}),this.parser.json.meshes?.forEach((e,r)=>{if(e?.extensions){const n=e?.extensions[F];if(n&&n.lods){for(const s of this.parser.associations.keys())if(s.isMesh){const o=this.parser.associations.get(s);o?.meshes===r&&x.registerMesh(this.url,n.guid,s,n.lods.length,o.primitives,n)}}}}),null}static registerTexture=(t,e,r,n,s)=>{if(!e){p&&console.error("gltf-progressive: Called register texture without texture");return}if(p){const l=e.image?.width||e.source?.data?.width||0,a=e.image?.height||e.source?.data?.height||0;console.log(`> Progressive: register texture[${n}] "${e.name||e.uuid}", Current: ${l}x${a}, Max: ${s.lods[0]?.width}x${s.lods[0]?.height}, uuid: ${e.uuid}`,s,e)}e.source&&(e.source[ue]=s);const o=s.guid;x.assignLODInformation(t,e,o,r,n),x.lodInfos.set(o,s),x.lowresCache.set(o,e)};static registerMesh=(t,e,r,n,s,o)=>{const l=r.geometry;if(!l){p&&console.warn("gltf-progressive: Register mesh without geometry");return}l.userData||(l.userData={}),p&&console.log("> Progressive: register mesh "+r.name,{index:s,uuid:r.uuid},o,r),x.assignLODInformation(t,l,e,n,s),x.lodInfos.set(e,o);let a=x.lowresCache.get(e);a?a.push(r.geometry):a=[r.geometry],x.lowresCache.set(e,a),n>0&&!X(r)&&Ne(r,l);for(const u of E)u.onRegisteredNewMesh?.(r,o)};static lodInfos=new Map;static previouslyLoaded=new Map;static lowresCache=new Map;static workers=[];static _workersIndex=0;static async getOrLoadLOD(t,e){const r=p=="verbose",n=this.getAssignedLODInformation(t);if(!n)return p&&console.warn(`[gltf-progressive] No LOD information found: ${t.name}, uuid: ${t.uuid}, type: ${t.type}`,t),null;const s=n?.key;let o;if(t.isTexture===!0){const a=t;a.source&&a.source[ue]&&(o=a.source[ue])}if(o||(o=x.lodInfos.get(s)),o){if(e>0){let c=!1;const m=Array.isArray(o.lods);if(m&&e>=o.lods.length?c=!0:m||(c=!0),c)return this.lowresCache.get(s)}const a=Array.isArray(o.lods)?o.lods[e]?.path:o.lods;if(!a)return p&&!o["missing:uri"]&&(o["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+e,o)),null;const u=Ee(n.url,a);if(u.endsWith(".glb")||u.endsWith(".gltf")){if(!o.guid)return console.warn("missing pointer for glb/gltf texture",o),null;const c=u+"_"+o.guid,m=await this.queue.slot(u),_=this.previouslyLoaded.get(c);if(_!==void 0){r&&console.log(`LOD ${e} was already loading/loaded: ${c}`);let f=await _.catch(S=>(console.error(`Error loading LOD ${e} from ${u}
2
2
  `,S),null)),w=!1;if(f==null||(f instanceof d.Texture&&t instanceof d.Texture?f.image?.data||f.source?.data?f=this.copySettings(t,f):(w=!0,this.previouslyLoaded.delete(c)):f instanceof d.BufferGeometry&&t instanceof d.BufferGeometry&&(f.attributes.position?.array||(w=!0,this.previouslyLoaded.delete(c)))),!w)return f}if(!m.use)return p&&console.log(`LOD ${e} was aborted: ${u}`),null;const M=o,I=new Promise(async(f,w)=>{if(He){const y=await(await je({})).load(u);if(y.textures.length>0)for(const h of y.textures){let g=h.texture;return x.assignLODInformation(n.url,g,s,e,void 0),t instanceof d.Texture&&(g=this.copySettings(t,g)),g&&(g.guid=M.guid),f(g)}if(y.geometries.length>0){const h=new Array;for(const g of y.geometries){const v=g.geometry;x.assignLODInformation(n.url,v,s,e,g.primitiveIndex),h.push(v)}return f(h)}return f(null)}const S=new q.GLTFLoader;ye(S),p&&(await new Promise(L=>setTimeout(L,1e3)),r&&console.warn("Start loading (delayed) "+u,M.guid));let B=u;if(M&&Array.isArray(M.lods)){const L=M.lods[e];L.hash&&(B+="?v="+L.hash)}const b=await S.loadAsync(B).catch(L=>(console.error(`Error loading LOD ${e} from ${u}
3
3
  `,L),f(null)));if(!b)return f(null);const W=b.parser;r&&console.log("Loading finished "+u,M.guid);let T=0;if(b.parser.json.textures){let L=!1;for(const y of b.parser.json.textures){if(y?.extensions){const h=y?.extensions[F];if(h?.guid&&h.guid===M.guid){L=!0;break}}T++}if(L){let y=await W.getDependency("texture",T);return y&&x.assignLODInformation(n.url,y,s,e,void 0),r&&console.log('change "'+t.name+'" → "'+y.name+'"',u,T,y,c),t instanceof d.Texture&&(y=this.copySettings(t,y)),y&&(y.guid=M.guid),f(y)}else p&&console.warn("Could not find texture with guid",M.guid,b.parser.json)}if(T=0,b.parser.json.meshes){let L=!1;for(const y of b.parser.json.meshes){if(y?.extensions){const h=y?.extensions[F];if(h?.guid&&h.guid===M.guid){L=!0;break}}T++}if(L){const y=await W.getDependency("mesh",T);if(r&&console.log(`Loaded Mesh "${y.name}"`,u,T,y,c),y.isMesh===!0){const h=y.geometry;return x.assignLODInformation(n.url,h,s,e,0),f(h)}else{const h=new Array;for(let g=0;g<y.children.length;g++){const v=y.children[g];if(v.isMesh===!0){const O=v.geometry;x.assignLODInformation(n.url,O,s,e,g),h.push(O)}}return f(h)}}else p&&console.warn("Could not find mesh with guid",M.guid,b.parser.json)}return f(null)});return this.previouslyLoaded.set(c,I),m.use(I),await I}else if(t instanceof d.Texture){r&&console.log("Load texture from uri: "+u);const m=await new d.TextureLoader().loadAsync(u);return m?(m.guid=o.guid,m.flipY=!1,m.needsUpdate=!0,m.colorSpace=t.colorSpace,r&&console.log(o,m)):p&&console.warn("failed loading",u),m}}else p&&console.warn(`Can not load LOD ${e}: no LOD info found for "${s}" ${t.name}`,t.type);return null}static maxConcurrent=50;static queue=new We(x.maxConcurrent,{debug:p!=!1});static assignLODInformation(t,e,r,n,s){if(!e)return;e.userData||(e.userData={});const o=new Je(t,r,n,s);e.userData.LODS=o,"source"in e&&typeof e.source=="object"&&(e.source.LODS=o)}static getAssignedLODInformation(t){return t?t.userData?.LODS?t.userData.LODS:"source"in t&&t.source?.LODS?t.source.LODS:null:null}static copySettings(t,e){return e?(p==="verbose"&&console.debug(`Copy texture settings
4
4
  `,t.uuid,`
5
- `,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}}class Je{url;key;level;index;constructor(t,e,r,n){this.url=t,this.key=e,this.level=r,n!=null&&(this.index=n)}}class de{static addPromise=(t,e,r,n)=>{n.forEach(s=>{s.add(t,e,r)})};frame_start;frame_capture_end;ready;_resolve;_signal;get awaitedCount(){return this._addedCount}get resolvedCount(){return this._resolvedCount}get currentlyAwaiting(){return this._awaiting.length}_resolved=!1;_addedCount=0;_resolvedCount=0;_awaiting=[];_maxPromisesPerObject=1;constructor(t,e){const n=Math.max(e.frames??2,2);this.frame_start=t,this.frame_capture_end=t+n,this.ready=new Promise(s=>{this._resolve=s}),this.ready.finally(()=>{this._resolved=!0,this._awaiting.length=0}),this._signal=e.signal,this._signal?.addEventListener("abort",()=>{this.resolveNow()}),this._maxPromisesPerObject=Math.max(1,e.maxPromisesPerObject??1)}_currentFrame=0;update(t){this._currentFrame=t,(this._signal?.aborted||this._currentFrame>this.frame_capture_end&&this._awaiting.length===0)&&this.resolveNow()}_seen=new WeakMap;add(t,e,r){if(this._resolved){p&&console.warn("PromiseGroup: Trying to add a promise to a resolved group, ignoring.");return}if(!(this._currentFrame>this.frame_capture_end)){if(this._maxPromisesPerObject>=1)if(this._seen.has(e)){let n=this._seen.get(e);if(n>=this._maxPromisesPerObject){p&&console.warn("PromiseGroup: Already awaiting object ignoring new promise for it.");return}this._seen.set(e,n+1)}else this._seen.set(e,1);this._awaiting.push(r),this._addedCount++,r.finally(()=>{this._resolvedCount++,this._awaiting.splice(this._awaiting.indexOf(r),1)})}}resolveNow(){this._resolved||this._resolve?.({awaited_count:this._addedCount,resolved_count:this._resolvedCount,cancelled:this._signal?.aborted??!1})}}const C=N("debugprogressive"),Ze=N("noprogressive"),ce=Symbol("Needle:LODSManager"),fe=Symbol("Needle:LODState"),U=Symbol("Needle:CurrentLOD"),P={mesh_lod:-1,texture_lod:-1};let Q=class D{static debugDrawLine;static overrideGlobalLodLevel;static getObjectLODState(t){return t[fe]}static addPlugin(t){E.push(t)}static removePlugin(t){const e=E.indexOf(t);e>=0&&E.splice(e,1)}static get(t,e){if(t[ce])return console.debug("[gltf-progressive] LODsManager already exists for this renderer"),t[ce];const r=new D(t,{engine:"unknown",...e});return t[ce]=r,r}renderer;context;projectionScreenMatrix=new d.Matrix4;get plugins(){return E}targetTriangleDensity=2e5;skinnedMeshAutoUpdateBoundsInterval=30;updateInterval="auto";#e=1;pause=!1;manual=!1;_newPromiseGroups=[];_promiseGroupIds=0;awaitLoading(t){const e=this._promiseGroupIds++,r=new de(this.#s,{...t});this._newPromiseGroups.push(r);const n=performance.now();return r.ready.finally(()=>{const s=this._newPromiseGroups.indexOf(r);s>=0&&(this._newPromiseGroups.splice(s,1),Le()&&performance.measure("LODsManager:awaitLoading",{start:n,detail:{id:e,name:t?.name,awaited:r.awaitedCount,resolved:r.resolvedCount}}))}),r.ready}_postprocessPromiseGroups(){if(this._newPromiseGroups.length!==0)for(let t=this._newPromiseGroups.length-1;t>=0;t--)this._newPromiseGroups[t].update(this.#s)}_lodchangedlisteners=[];addEventListener(t,e){t==="changed"&&this._lodchangedlisteners.push(e)}removeEventListener(t,e){if(t==="changed"){const r=this._lodchangedlisteners.indexOf(e);r>=0&&this._lodchangedlisteners.splice(r,1)}}constructor(t,e){this.renderer=t,this.context={...e}}#t;#o=new d.Clock;#s=0;#n=0;#i=0;#r=0;_fpsBuffer=[60,60,60,60,60];enable(){if(this.#t)return;console.debug("[gltf-progressive] Enabling LODsManager for renderer");let t=0;this.#t=this.renderer.render;const e=this;ne(this.renderer),this.renderer.render=function(r,n){const s=e.renderer.getRenderTarget();(s==null||"isXRRenderTarget"in s&&s.isXRRenderTarget)&&(t=0,e.#s+=1,e.#n=e.#o.getDelta(),e.#i+=e.#n,e._fpsBuffer.shift(),e._fpsBuffer.push(1/e.#n),e.#r=e._fpsBuffer.reduce((l,a)=>l+a)/e._fpsBuffer.length,C&&e.#s%200===0&&console.log("FPS",Math.round(e.#r),"Interval:",e.#e));const o=t++;e.#t.call(this,r,n),e.onAfterRender(r,n,o)}}disable(){this.#t&&(console.debug("[gltf-progressive] Disabling LODsManager for renderer"),this.renderer.render=this.#t,this.#t=void 0)}update(t,e){this.internalUpdate(t,e)}onAfterRender(t,e,r){if(this.pause)return;const s=this.renderer.renderLists.get(t,0).opaque;let o=!0;if(s.length===1){const l=s[0].material;(l.name==="EffectMaterial"||l.name==="CopyShader")&&(o=!1)}if((e.parent&&e.parent.type==="CubeCamera"||r>=1&&e.type==="OrthographicCamera")&&(o=!1),o){if(Ze||(this.updateInterval==="auto"?this.#r<40&&this.#e<10?(this.#e+=1,C&&console.warn("↓ Reducing LOD updates",this.#e,this.#r.toFixed(0))):this.#r>=60&&this.#e>1&&(this.#e-=1,C&&console.warn("↑ Increasing LOD updates",this.#e,this.#r.toFixed(0))):this.#e=this.updateInterval,this.#e>0&&this.#s%this.#e!=0))return;this.internalUpdate(t,e),this._postprocessPromiseGroups()}}internalUpdate(t,e){const r=this.renderer.renderLists.get(t,0),n=r.opaque;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse);const s=this.targetTriangleDensity;for(const a of n){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")){C&&(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)));continue}switch(a.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}if(C==="color"&&a.material&&!a.object.progressive_debug_color){a.object.progressive_debug_color=!0;const c=Math.random()*16777215,m=new d.MeshStandardMaterial({color:c});a.object.material=m}const u=a.object;(u instanceof d.Mesh||u.isMesh)&&this.updateLODs(t,e,u,s)}const o=r.transparent;for(const a of o){const u=a.object;(u instanceof d.Mesh||u.isMesh)&&this.updateLODs(t,e,u,s)}const l=r.transmissive;for(const a of l){const u=a.object;(u instanceof d.Mesh||u.isMesh)&&this.updateLODs(t,e,u,s)}}updateLODs(t,e,r,n){r.userData||(r.userData={});let s=r[fe];if(s||(s=new et,r[fe]=s),s.frames++<2)return;for(const l of E)l.onBeforeUpdateLOD?.(this.renderer,t,e,r);const o=D.overrideGlobalLodLevel!==void 0?D.overrideGlobalLodLevel:z;o>=0?(P.mesh_lod=o,P.texture_lod=o):(this.calculateLodLevel(e,r,s,n,P),P.mesh_lod=Math.round(P.mesh_lod),P.texture_lod=Math.round(P.texture_lod)),P.mesh_lod>=0&&this.loadProgressiveMeshes(r,P.mesh_lod),r.material&&P.texture_lod>=0&&this.loadProgressiveTextures(r.material,P.texture_lod,o),p&&r.material&&!r.isGizmo&&Ae(r.material);for(const l of E)l.onAfterUpdatedLOD?.(this.renderer,t,e,r,P);s.lastLodLevel_Mesh=P.mesh_lod,s.lastLodLevel_Texture=P.texture_lod}loadProgressiveTextures(t,e,r){if(!t)return;if(Array.isArray(t)){for(const s of t)this.loadProgressiveTextures(s,e);return}let n=!1;if((t[U]===void 0||e<t[U])&&(n=!0),r!==void 0&&r>=0&&(n=t[U]!=r,e=r),n){t[U]=e;const s=x.assignTextureLOD(t,e).then(o=>{this._lodchangedlisteners.forEach(l=>l({type:"texture",level:e,object:t}))});de.addPromise("texture",t,s,this._newPromiseGroups)}}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);let r=t[U]!==e;const n=t["DEBUG:LOD"];if(n!=null&&(r=t[U]!=n,e=n),r){t[U]=e;const s=t.geometry,o=x.assignMeshLOD(t,e).then(l=>(l&&t[U]==e&&s!=t.geometry&&this._lodchangedlisteners.forEach(a=>a({type:"mesh",level:e,object:t})),l));return de.addPromise("mesh",t,o,this._newPromiseGroups),o}return Promise.resolve(null)}_sphere=new d.Sphere;_tempBox=new d.Box3;_tempBox2=new d.Box3;tempMatrix=new d.Matrix4;_tempWorldPosition=new d.Vector3;_tempBoxSize=new d.Vector3;_tempBox2Size=new d.Vector3;static corner0=new d.Vector3;static corner1=new d.Vector3;static corner2=new d.Vector3;static corner3=new d.Vector3;static _tempPtInside=new d.Vector3;static isInside(t,e){const r=t.min,n=t.max,s=(r.x+n.x)*.5,o=(r.y+n.y)*.5;return this._tempPtInside.set(s,o,r.z).applyMatrix4(e).z<0}static skinnedMeshBoundsFrameOffsetCounter=0;static $skinnedMeshBoundsOffset=Symbol("gltf-progressive-skinnedMeshBoundsOffset");calculateLodLevel(t,e,r,n,s){if(!e){s.mesh_lod=-1,s.texture_lod=-1;return}if(!t){s.mesh_lod=-1,s.texture_lod=-1;return}let l=10+1,a=!1;if(C&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const u=x.getMeshLODExtension(e.geometry)?.lods,c=x.getPrimitiveIndex(e.geometry),m=u&&u.length>0,_=x.getMaterialMinMaxLODsCount(e.material),M=_.min_count!==1/0&&_.min_count>=0&&_.max_count>=0;if(!m&&!M){s.mesh_lod=0,s.texture_lod=0;return}m||(a=!0,l=0);const I=this.renderer.domElement.clientHeight||this.renderer.domElement.height;let G=e.geometry.boundingBox;if(e.type==="SkinnedMesh"){const f=e;if(!f.boundingBox)f.computeBoundingBox();else if(this.skinnedMeshAutoUpdateBoundsInterval>0){if(!f[D.$skinnedMeshBoundsOffset]){const S=D.skinnedMeshBoundsFrameOffsetCounter++;f[D.$skinnedMeshBoundsOffset]=S}const w=f[D.$skinnedMeshBoundsOffset];if((r.frames+w)%this.skinnedMeshAutoUpdateBoundsInterval===0){const S=X(f),B=f.geometry;S&&(f.geometry=S),f.computeBoundingBox(),f.geometry=B}}G=f.boundingBox}if(G){const f=t;if(e.geometry.attributes.color&&e.geometry.attributes.color.count<100&&e.geometry.boundingSphere){this._sphere.copy(e.geometry.boundingSphere),this._sphere.applyMatrix4(e.matrixWorld);const h=t.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(h)){s.mesh_lod=0,s.texture_lod=0;return}}if(this._tempBox.copy(G),this._tempBox.applyMatrix4(e.matrixWorld),f.isPerspectiveCamera&&D.isInside(this._tempBox,this.projectionScreenMatrix)){s.mesh_lod=0,s.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&f.isPerspectiveCamera&&f.fov>70){const h=this._tempBox.min,g=this._tempBox.max;let v=h.x,O=h.y,$=g.x,K=g.y;const J=2,oe=1.5,Z=(h.x+g.x)*.5,ee=(h.y+g.y)*.5;v=(v-Z)*J+Z,O=(O-ee)*J+ee,$=($-Z)*J+Z,K=(K-ee)*J+ee;const ke=v<0&&$>0?0:Math.min(Math.abs(h.x),Math.abs(g.x)),Re=O<0&&K>0?0:Math.min(Math.abs(h.y),Math.abs(g.y)),ie=Math.max(ke,Re);r.lastCentrality=(oe-ie)*(oe-ie)*(oe-ie)}else r.lastCentrality=1;const w=this._tempBox.getSize(this._tempBoxSize);w.multiplyScalar(.5),screen.availHeight>0&&I>0&&w.multiplyScalar(I/screen.availHeight),t.isPerspectiveCamera?w.x*=t.aspect:t.isOrthographicCamera;const S=t.matrixWorldInverse,B=this._tempBox2;B.copy(G),B.applyMatrix4(e.matrixWorld),B.applyMatrix4(S);const b=B.getSize(this._tempBox2Size),W=Math.max(b.x,b.y);if(Math.max(w.x,w.y)!=0&&W!=0&&(w.z=b.z/Math.max(b.x,b.y)*Math.max(w.x,w.y)),r.lastScreenCoverage=Math.max(w.x,w.y,w.z),r.lastScreenspaceVolume.copy(w),r.lastScreenCoverage*=r.lastCentrality,C&&D.debugDrawLine){const h=this.tempMatrix.copy(this.projectionScreenMatrix);h.invert();const g=D.corner0,v=D.corner1,O=D.corner2,$=D.corner3;g.copy(this._tempBox.min),v.copy(this._tempBox.max),v.x=g.x,O.copy(this._tempBox.max),O.y=g.y,$.copy(this._tempBox.max);const K=(g.z+$.z)*.5;g.z=v.z=O.z=$.z=K,g.applyMatrix4(h),v.applyMatrix4(h),O.applyMatrix4(h),$.applyMatrix4(h),D.debugDrawLine(g,v,255),D.debugDrawLine(g,O,255),D.debugDrawLine(v,$,255),D.debugDrawLine(O,$,255)}let L=999;if(u&&r.lastScreenCoverage>0)for(let h=0;h<u.length;h++){const g=u[h],O=(g.densities?.[c]||g.density||1e-5)/r.lastScreenCoverage;if(c>0&&Le()&&!g.densities&&!globalThis["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"]&&(window["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"]=!0,console.warn("[Needle Progressive] Detected usage of mesh without primitive densities. This might cause incorrect LOD level selection: Consider re-optimizing your model by updating your Needle Integration, Needle glTF Pipeline or running optimization again on Needle Cloud.")),O<n){L=h;break}}L<l&&(l=L,a=!0)}if(a?s.mesh_lod=l:s.mesh_lod=r.lastLodLevel_Mesh,C&&s.mesh_lod!=r.lastLodLevel_Mesh){const w=u?.[s.mesh_lod];w&&console.debug(`Mesh LOD changed: ${r.lastLodLevel_Mesh} → ${s.mesh_lod} (density: ${w.densities?.[c].toFixed(0)}) | ${e.name}`)}if(M){const f="saveData"in globalThis.navigator&&globalThis.navigator.saveData===!0;if(r.lastLodLevel_Texture<0){if(s.texture_lod=_.max_count-1,C){const w=_.lods[_.max_count-1];C&&console.log(`First Texture LOD ${s.texture_lod} (${w.max_height}px) - ${e.name}`)}}else{const w=r.lastScreenspaceVolume.x+r.lastScreenspaceVolume.y+r.lastScreenspaceVolume.z;let S=r.lastScreenCoverage*4;this.context?.engine==="model-viewer"&&(S*=1.5);const b=I/window.devicePixelRatio*S;let W=!1;for(let T=_.lods.length-1;T>=0;T--){const L=_.lods[T];if(!(f&&L.max_height>=2048)&&!(Pe()&&L.max_height>4096)&&(L.max_height>b||!W&&T===0)){if(W=!0,s.texture_lod=T,C&&s.texture_lod<r.lastLodLevel_Texture){const y=L.max_height;console.log(`Texture LOD changed: ${r.lastLodLevel_Texture} → ${s.texture_lod} = ${y}px
5
+ `,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}}class Je{url;key;level;index;constructor(t,e,r,n){this.url=t,this.key=e,this.level=r,n!=null&&(this.index=n)}}class de{static addPromise=(t,e,r,n)=>{n.forEach(s=>{s.add(t,e,r)})};frame_start;frame_capture_end;ready;_resolve;_signal;get awaitedCount(){return this._addedCount}get resolvedCount(){return this._resolvedCount}get currentlyAwaiting(){return this._awaiting.length}_resolved=!1;_addedCount=0;_resolvedCount=0;_awaiting=[];_maxPromisesPerObject=1;constructor(t,e){const n=Math.max(e.frames??2,2);this.frame_start=t,this.frame_capture_end=t+n,this.ready=new Promise(s=>{this._resolve=s}),this.ready.finally(()=>{this._resolved=!0,this._awaiting.length=0}),this._signal=e.signal,this._signal?.addEventListener("abort",()=>{this.resolveNow()}),this._maxPromisesPerObject=Math.max(1,e.maxPromisesPerObject??1)}_currentFrame=0;update(t){this._currentFrame=t,(this._signal?.aborted||this._currentFrame>this.frame_capture_end&&this._awaiting.length===0)&&this.resolveNow()}_seen=new WeakMap;add(t,e,r){if(this._resolved){p&&console.warn("PromiseGroup: Trying to add a promise to a resolved group, ignoring.");return}if(!(this._currentFrame>this.frame_capture_end)){if(this._maxPromisesPerObject>=1)if(this._seen.has(e)){let n=this._seen.get(e);if(n>=this._maxPromisesPerObject){p&&console.warn("PromiseGroup: Already awaiting object ignoring new promise for it.");return}this._seen.set(e,n+1)}else this._seen.set(e,1);this._awaiting.push(r),this._addedCount++,r.finally(()=>{this._resolvedCount++,this._awaiting.splice(this._awaiting.indexOf(r),1)})}}resolveNow(){this._resolved||this._resolve?.({awaited_count:this._addedCount,resolved_count:this._resolvedCount,cancelled:this._signal?.aborted??!1})}}const C=V("debugprogressive"),Ze=V("noprogressive"),ce=Symbol("Needle:LODSManager"),fe=Symbol("Needle:LODState"),U=Symbol("Needle:CurrentLOD"),P={mesh_lod:-1,texture_lod:-1};let Q=class D{static debugDrawLine;static overrideGlobalLodLevel;static getObjectLODState(t){return t[fe]}static addPlugin(t){E.push(t)}static removePlugin(t){const e=E.indexOf(t);e>=0&&E.splice(e,1)}static get(t,e){if(t[ce])return console.debug("[gltf-progressive] LODsManager already exists for this renderer"),t[ce];const r=new D(t,{engine:"unknown",...e});return t[ce]=r,r}renderer;context;projectionScreenMatrix=new d.Matrix4;get plugins(){return E}targetTriangleDensity=2e5;skinnedMeshAutoUpdateBoundsInterval=30;updateInterval="auto";#e=1;pause=!1;manual=!1;_newPromiseGroups=[];_promiseGroupIds=0;awaitLoading(t){const e=this._promiseGroupIds++,r=new de(this.#s,{...t});this._newPromiseGroups.push(r);const n=performance.now();return r.ready.finally(()=>{const s=this._newPromiseGroups.indexOf(r);s>=0&&(this._newPromiseGroups.splice(s,1),Le()&&performance.measure("LODsManager:awaitLoading",{start:n,detail:{id:e,name:t?.name,awaited:r.awaitedCount,resolved:r.resolvedCount}}))}),r.ready}_postprocessPromiseGroups(){if(this._newPromiseGroups.length!==0)for(let t=this._newPromiseGroups.length-1;t>=0;t--)this._newPromiseGroups[t].update(this.#s)}_lodchangedlisteners=[];addEventListener(t,e){t==="changed"&&this._lodchangedlisteners.push(e)}removeEventListener(t,e){if(t==="changed"){const r=this._lodchangedlisteners.indexOf(e);r>=0&&this._lodchangedlisteners.splice(r,1)}}constructor(t,e){this.renderer=t,this.context={...e}}#t;#o=new d.Clock;#s=0;#n=0;#i=0;#r=0;_fpsBuffer=[60,60,60,60,60];enable(){if(this.#t)return;console.debug("[gltf-progressive] Enabling LODsManager for renderer");let t=0;this.#t=this.renderer.render;const e=this;ne(this.renderer),this.renderer.render=function(r,n){const s=e.renderer.getRenderTarget();(s==null||"isXRRenderTarget"in s&&s.isXRRenderTarget)&&(t=0,e.#s+=1,e.#n=e.#o.getDelta(),e.#i+=e.#n,e._fpsBuffer.shift(),e._fpsBuffer.push(1/e.#n),e.#r=e._fpsBuffer.reduce((l,a)=>l+a)/e._fpsBuffer.length,C&&e.#s%200===0&&console.log("FPS",Math.round(e.#r),"Interval:",e.#e));const o=t++;e.#t.call(this,r,n),e.onAfterRender(r,n,o)}}disable(){this.#t&&(console.debug("[gltf-progressive] Disabling LODsManager for renderer"),this.renderer.render=this.#t,this.#t=void 0)}update(t,e){this.internalUpdate(t,e)}onAfterRender(t,e,r){if(this.pause)return;const s=this.renderer.renderLists.get(t,0).opaque;let o=!0;if(s.length===1){const l=s[0].material;(l.name==="EffectMaterial"||l.name==="CopyShader")&&(o=!1)}if((e.parent&&e.parent.type==="CubeCamera"||r>=1&&e.type==="OrthographicCamera")&&(o=!1),o){if(Ze||(this.updateInterval==="auto"?this.#r<40&&this.#e<10?(this.#e+=1,C&&console.warn("↓ Reducing LOD updates",this.#e,this.#r.toFixed(0))):this.#r>=60&&this.#e>1&&(this.#e-=1,C&&console.warn("↑ Increasing LOD updates",this.#e,this.#r.toFixed(0))):this.#e=this.updateInterval,this.#e>0&&this.#s%this.#e!=0))return;this.internalUpdate(t,e),this._postprocessPromiseGroups()}}internalUpdate(t,e){const r=this.renderer.renderLists.get(t,0),n=r.opaque;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse);const s=this.targetTriangleDensity;for(const a of n){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")){C&&(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)));continue}switch(a.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}if(C==="color"&&a.material&&!a.object.progressive_debug_color){a.object.progressive_debug_color=!0;const c=Math.random()*16777215,m=new d.MeshStandardMaterial({color:c});a.object.material=m}const u=a.object;(u instanceof d.Mesh||u.isMesh)&&this.updateLODs(t,e,u,s)}const o=r.transparent;for(const a of o){const u=a.object;(u instanceof d.Mesh||u.isMesh)&&this.updateLODs(t,e,u,s)}const l=r.transmissive;for(const a of l){const u=a.object;(u instanceof d.Mesh||u.isMesh)&&this.updateLODs(t,e,u,s)}}updateLODs(t,e,r,n){r.userData||(r.userData={});let s=r[fe];if(s||(s=new et,r[fe]=s),s.frames++<2)return;for(const l of E)l.onBeforeUpdateLOD?.(this.renderer,t,e,r);const o=D.overrideGlobalLodLevel!==void 0?D.overrideGlobalLodLevel:z;o>=0?(P.mesh_lod=o,P.texture_lod=o):(this.calculateLodLevel(e,r,s,n,P),P.mesh_lod=Math.round(P.mesh_lod),P.texture_lod=Math.round(P.texture_lod)),P.mesh_lod>=0&&this.loadProgressiveMeshes(r,P.mesh_lod),r.material&&P.texture_lod>=0&&this.loadProgressiveTextures(r.material,P.texture_lod,o),p&&r.material&&!r.isGizmo&&Ae(r.material);for(const l of E)l.onAfterUpdatedLOD?.(this.renderer,t,e,r,P);s.lastLodLevel_Mesh=P.mesh_lod,s.lastLodLevel_Texture=P.texture_lod}loadProgressiveTextures(t,e,r){if(!t)return;if(Array.isArray(t)){for(const s of t)this.loadProgressiveTextures(s,e);return}let n=!1;if((t[U]===void 0||e<t[U])&&(n=!0),r!==void 0&&r>=0&&(n=t[U]!=r,e=r),n){t[U]=e;const s=x.assignTextureLOD(t,e).then(o=>{this._lodchangedlisteners.forEach(l=>l({type:"texture",level:e,object:t}))});de.addPromise("texture",t,s,this._newPromiseGroups)}}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);let r=t[U]!==e;const n=t["DEBUG:LOD"];if(n!=null&&(r=t[U]!=n,e=n),r){t[U]=e;const s=t.geometry,o=x.assignMeshLOD(t,e).then(l=>(l&&t[U]==e&&s!=t.geometry&&this._lodchangedlisteners.forEach(a=>a({type:"mesh",level:e,object:t})),l));return de.addPromise("mesh",t,o,this._newPromiseGroups),o}return Promise.resolve(null)}_sphere=new d.Sphere;_tempBox=new d.Box3;_tempBox2=new d.Box3;tempMatrix=new d.Matrix4;_tempWorldPosition=new d.Vector3;_tempBoxSize=new d.Vector3;_tempBox2Size=new d.Vector3;static corner0=new d.Vector3;static corner1=new d.Vector3;static corner2=new d.Vector3;static corner3=new d.Vector3;static _tempPtInside=new d.Vector3;static isInside(t,e){const r=t.min,n=t.max,s=(r.x+n.x)*.5,o=(r.y+n.y)*.5;return this._tempPtInside.set(s,o,r.z).applyMatrix4(e).z<0}static skinnedMeshBoundsFrameOffsetCounter=0;static $skinnedMeshBoundsOffset=Symbol("gltf-progressive-skinnedMeshBoundsOffset");calculateLodLevel(t,e,r,n,s){if(!e){s.mesh_lod=-1,s.texture_lod=-1;return}if(!t){s.mesh_lod=-1,s.texture_lod=-1;return}let l=10+1,a=!1;if(C&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const u=x.getMeshLODExtension(e.geometry)?.lods,c=x.getPrimitiveIndex(e.geometry),m=u&&u.length>0,_=x.getMaterialMinMaxLODsCount(e.material),M=_.min_count!==1/0&&_.min_count>=0&&_.max_count>=0;if(!m&&!M){s.mesh_lod=0,s.texture_lod=0;return}m||(a=!0,l=0);const I=this.renderer.domElement.clientHeight||this.renderer.domElement.height;let G=e.geometry.boundingBox;if(e.type==="SkinnedMesh"){const f=e;if(!f.boundingBox)f.computeBoundingBox();else if(this.skinnedMeshAutoUpdateBoundsInterval>0){if(!f[D.$skinnedMeshBoundsOffset]){const S=D.skinnedMeshBoundsFrameOffsetCounter++;f[D.$skinnedMeshBoundsOffset]=S}const w=f[D.$skinnedMeshBoundsOffset];if((r.frames+w)%this.skinnedMeshAutoUpdateBoundsInterval===0){const S=X(f),B=f.geometry;S&&(f.geometry=S),f.computeBoundingBox(),f.geometry=B}}G=f.boundingBox}if(G){const f=t;if(e.geometry.attributes.color&&e.geometry.attributes.color.count<100&&e.geometry.boundingSphere){this._sphere.copy(e.geometry.boundingSphere),this._sphere.applyMatrix4(e.matrixWorld);const h=t.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(h)){s.mesh_lod=0,s.texture_lod=0;return}}if(this._tempBox.copy(G),this._tempBox.applyMatrix4(e.matrixWorld),f.isPerspectiveCamera&&D.isInside(this._tempBox,this.projectionScreenMatrix)){s.mesh_lod=0,s.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&f.isPerspectiveCamera&&f.fov>70){const h=this._tempBox.min,g=this._tempBox.max;let v=h.x,O=h.y,$=g.x,K=g.y;const J=2,oe=1.5,Z=(h.x+g.x)*.5,ee=(h.y+g.y)*.5;v=(v-Z)*J+Z,O=(O-ee)*J+ee,$=($-Z)*J+Z,K=(K-ee)*J+ee;const ke=v<0&&$>0?0:Math.min(Math.abs(h.x),Math.abs(g.x)),Re=O<0&&K>0?0:Math.min(Math.abs(h.y),Math.abs(g.y)),ie=Math.max(ke,Re);r.lastCentrality=(oe-ie)*(oe-ie)*(oe-ie)}else r.lastCentrality=1;const w=this._tempBox.getSize(this._tempBoxSize);w.multiplyScalar(.5),screen.availHeight>0&&I>0&&w.multiplyScalar(I/screen.availHeight),t.isPerspectiveCamera?w.x*=t.aspect:t.isOrthographicCamera;const S=t.matrixWorldInverse,B=this._tempBox2;B.copy(G),B.applyMatrix4(e.matrixWorld),B.applyMatrix4(S);const b=B.getSize(this._tempBox2Size),W=Math.max(b.x,b.y);if(Math.max(w.x,w.y)!=0&&W!=0&&(w.z=b.z/Math.max(b.x,b.y)*Math.max(w.x,w.y)),r.lastScreenCoverage=Math.max(w.x,w.y,w.z),r.lastScreenspaceVolume.copy(w),r.lastScreenCoverage*=r.lastCentrality,C&&D.debugDrawLine){const h=this.tempMatrix.copy(this.projectionScreenMatrix);h.invert();const g=D.corner0,v=D.corner1,O=D.corner2,$=D.corner3;g.copy(this._tempBox.min),v.copy(this._tempBox.max),v.x=g.x,O.copy(this._tempBox.max),O.y=g.y,$.copy(this._tempBox.max);const K=(g.z+$.z)*.5;g.z=v.z=O.z=$.z=K,g.applyMatrix4(h),v.applyMatrix4(h),O.applyMatrix4(h),$.applyMatrix4(h),D.debugDrawLine(g,v,255),D.debugDrawLine(g,O,255),D.debugDrawLine(v,$,255),D.debugDrawLine(O,$,255)}let L=999;if(u&&r.lastScreenCoverage>0)for(let h=0;h<u.length;h++){const g=u[h],O=(g.densities?.[c]||g.density||1e-5)/r.lastScreenCoverage;if(c>0&&Le()&&!g.densities&&!globalThis["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"]&&(window["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"]=!0,console.warn("[Needle Progressive] Detected usage of mesh without primitive densities. This might cause incorrect LOD level selection: Consider re-optimizing your model by updating your Needle Integration, Needle glTF Pipeline or running optimization again on Needle Cloud.")),O<n){L=h;break}}L<l&&(l=L,a=!0)}if(a?s.mesh_lod=l:s.mesh_lod=r.lastLodLevel_Mesh,C&&s.mesh_lod!=r.lastLodLevel_Mesh){const w=u?.[s.mesh_lod];w&&console.debug(`Mesh LOD changed: ${r.lastLodLevel_Mesh} → ${s.mesh_lod} (density: ${w.densities?.[c].toFixed(0)}) | ${e.name}`)}if(M){const f="saveData"in globalThis.navigator&&globalThis.navigator.saveData===!0;if(r.lastLodLevel_Texture<0){if(s.texture_lod=_.max_count-1,C){const w=_.lods[_.max_count-1];C&&console.log(`First Texture LOD ${s.texture_lod} (${w.max_height}px) - ${e.name}`)}}else{const w=r.lastScreenspaceVolume.x+r.lastScreenspaceVolume.y+r.lastScreenspaceVolume.z;let S=r.lastScreenCoverage*4;this.context?.engine==="model-viewer"&&(S*=1.5);const b=I/window.devicePixelRatio*S;let W=!1;for(let T=_.lods.length-1;T>=0;T--){const L=_.lods[T];if(!(f&&L.max_height>=2048)&&!(Pe()&&L.max_height>4096)&&(L.max_height>b||!W&&T===0)){if(W=!0,s.texture_lod=T,C&&s.texture_lod<r.lastLodLevel_Texture){const y=L.max_height;console.log(`Texture LOD changed: ${r.lastLodLevel_Texture} → ${s.texture_lod} = ${y}px
6
6
  Screensize: ${b.toFixed(0)}px, Coverage: ${(100*r.lastScreenCoverage).toFixed(2)}%, Volume ${w.toFixed(1)}
7
7
  ${e.name}`)}break}}}}else s.texture_lod=0}};class et{frames=0;lastLodLevel_Mesh=-1;lastLodLevel_Texture=-1;lastScreenCoverage=0;lastScreenspaceVolume=new d.Vector3;lastCentrality=0}const _e=Symbol("NEEDLE_mesh_lod"),te=Symbol("NEEDLE_texture_lod");let he=null;function Ie(){const i=tt();i&&(i.mapURLs(function(t){return Me(),t}),Me(),he?.disconnect(),he=new MutationObserver(t=>{t.forEach(e=>{e.addedNodes.forEach(r=>{r instanceof HTMLElement&&r.tagName.toLowerCase()==="model-viewer"&&Ce(r)})})}),he.observe(document,{childList:!0,subtree:!0}))}function tt(){if(typeof customElements>"u")return null;const i=customElements.get("model-viewer");return i||(customElements.whenDefined("model-viewer").then(()=>{console.debug("[gltf-progressive] model-viewer defined"),Ie()}),null)}function Me(){if(typeof document>"u")return;document.querySelectorAll("model-viewer").forEach(t=>{Ce(t)})}const De=new WeakSet;let rt=0;function Ce(i){if(!i||De.has(i))return null;De.add(i),console.debug("[gltf-progressive] found new model-viewer..."+ ++rt+`
8
- `,i.getAttribute("src"));let t=null,e=null,r=null;for(let n=i;n!=null;n=Object.getPrototypeOf(n)){const s=Object.getOwnPropertySymbols(n),o=s.find(u=>u.toString()=="Symbol(renderer)"),l=s.find(u=>u.toString()=="Symbol(scene)"),a=s.find(u=>u.toString()=="Symbol(needsRender)");!t&&o!=null&&(t=i[o].threeRenderer),!e&&l!=null&&(e=i[l]),!r&&a!=null&&(r=i[a])}if(t&&e){let s=function(){if(r){let o=0,l=setInterval(()=>{if(o++>5){clearInterval(l);return}r?.call(i)},300)}};console.debug("[gltf-progressive] setup model-viewer");const n=Q.get(t,{engine:"model-viewer"});return Q.addPlugin(new st),n.enable(),n.addEventListener("changed",()=>{r?.call(i)}),i.addEventListener("model-visibility",o=>{o.detail.visible&&r?.call(i)}),i.addEventListener("load",()=>{s()}),()=>{n.disable()}}return null}class st{_didWarnAboutMissingUrl=!1;onBeforeUpdateLOD(t,e,r,n){this.tryParseMeshLOD(e,n),this.tryParseTextureLOD(e,n)}getUrl(t){if(!t)return null;let e=t.getAttribute("src");return e||(e=t.src),e||(this._didWarnAboutMissingUrl||console.warn("No url found in modelviewer",t),this._didWarnAboutMissingUrl=!0),e}tryGetCurrentGLTF(t){return t._currentGLTF}tryGetCurrentModelViewer(t){return t.element}tryParseTextureLOD(t,e){if(e[te]==!0)return;e[te]=!0;const r=this.tryGetCurrentGLTF(t),n=this.tryGetCurrentModelViewer(t),s=this.getUrl(n);if(s&&r&&e.material){let l=function(a){if(a[te]==!0)return;a[te]=!0,a.userData&&(a.userData.LOD=-1);const u=Object.keys(a);for(let c=0;c<u.length;c++){const m=u[c],_=a[m];if(_?.isTexture===!0){const M=_.userData?.associations?.textures;if(M==null)continue;const I=r.parser.json.textures[M];if(!I){console.warn("Texture data not found for texture index "+M);continue}if(I?.extensions?.[F]){const G=I.extensions[F];G&&s&&x.registerTexture(s,_,G.lods.length,M,G)}}}};const o=e.material;if(Array.isArray(o))for(const a of o)l(a);else l(o)}}tryParseMeshLOD(t,e){if(e[_e]==!0)return;e[_e]=!0;const r=this.tryGetCurrentModelViewer(t),n=this.getUrl(r);if(!n)return;const s=e.userData?.gltfExtensions?.[F];if(s&&n){const o=e.uuid;x.registerMesh(n,o,e,0,s.lods.length,s)}}}function nt(i,t,e,r){ne(t),ye(e),xe(e,{progressive:!0,...r?.hints}),e.register(s=>new x(s,i));const n=Q.get(t);return r?.enableLODsManager!==!1&&n.enable(),n}Ie();if(!ze){const i={gltfProgressive:{useNeedleProgressive:nt,LODsManager:Q,configureLoader:xe,getRaycastMesh:X,useRaycastMeshes:Ne}};if(!globalThis.Needle)globalThis.Needle=i;else for(const t in i)globalThis.Needle[t]=i[t]}exports.LODsManager=Q;exports.NEEDLE_progressive=x;exports.addDracoAndKTX2Loaders=ye;exports.configureLoader=xe;exports.createLoaders=ne;exports.getRaycastMesh=X;exports.setDracoDecoderLocation=Oe;exports.setKTX2TranscoderLocation=Se;
8
+ `,i.getAttribute("src"));let t=null,e=null,r=null;for(let n=i;n!=null;n=Object.getPrototypeOf(n)){const s=Object.getOwnPropertySymbols(n),o=s.find(u=>u.toString()=="Symbol(renderer)"),l=s.find(u=>u.toString()=="Symbol(scene)"),a=s.find(u=>u.toString()=="Symbol(needsRender)");!t&&o!=null&&(t=i[o].threeRenderer),!e&&l!=null&&(e=i[l]),!r&&a!=null&&(r=i[a])}if(t&&e){let s=function(){if(r){let o=0,l=setInterval(()=>{if(o++>5){clearInterval(l);return}r?.call(i)},300)}};console.debug("[gltf-progressive] setup model-viewer");const n=Q.get(t,{engine:"model-viewer"});return Q.addPlugin(new st),n.enable(),n.addEventListener("changed",()=>{r?.call(i)}),i.addEventListener("model-visibility",o=>{o.detail.visible&&r?.call(i)}),i.addEventListener("load",()=>{s()}),()=>{n.disable()}}return null}class st{_didWarnAboutMissingUrl=!1;onBeforeUpdateLOD(t,e,r,n){this.tryParseMeshLOD(e,n),this.tryParseTextureLOD(e,n)}getUrl(t){if(!t)return null;let e=t.getAttribute("src");return e||(e=t.src),e||(this._didWarnAboutMissingUrl||console.warn("No url found in modelviewer",t),this._didWarnAboutMissingUrl=!0),e}tryGetCurrentGLTF(t){return t._currentGLTF}tryGetCurrentModelViewer(t){return t.element}tryParseTextureLOD(t,e){if(e[te]==!0)return;e[te]=!0;const r=this.tryGetCurrentGLTF(t),n=this.tryGetCurrentModelViewer(t),s=this.getUrl(n);if(s&&r&&e.material){let l=function(a){if(a[te]==!0)return;a[te]=!0,a.userData&&(a.userData.LOD=-1);const u=Object.keys(a);for(let c=0;c<u.length;c++){const m=u[c],_=a[m];if(_?.isTexture===!0){const M=_.userData?.associations?.textures;if(M==null)continue;const I=r.parser.json.textures[M];if(!I){console.warn("Texture data not found for texture index "+M);continue}if(I?.extensions?.[F]){const G=I.extensions[F];G&&s&&x.registerTexture(s,_,G.lods.length,M,G)}}}};const o=e.material;if(Array.isArray(o))for(const a of o)l(a);else l(o)}}tryParseMeshLOD(t,e){if(e[_e]==!0)return;e[_e]=!0;const r=this.tryGetCurrentModelViewer(t),n=this.getUrl(r);if(!n)return;const s=e.userData?.gltfExtensions?.[F];if(s&&n){const o=e.uuid;x.registerMesh(n,o,e,0,s.lods.length,s)}}}function nt(...i){let t,e,r,n;switch(i.length){case 2:[r,e]=i,n={};break;case 3:[r,e,n]=i;break;case 4:[t,e,r,n]=i;break;default:throw new Error("Invalid arguments")}ne(e),ye(r),xe(r,{progressive:!0,...n?.hints}),r.register(o=>new x(o));const s=Q.get(e);return n?.enableLODsManager!==!1&&s.enable(),s}Ie();if(!ze){const i={gltfProgressive:{useNeedleProgressive:nt,LODsManager:Q,configureLoader:xe,getRaycastMesh:X,useRaycastMeshes:Ve}};if(!globalThis.Needle)globalThis.Needle=i;else for(const t in i)globalThis.Needle[t]=i[t]}exports.LODsManager=Q;exports.NEEDLE_progressive=x;exports.addDracoAndKTX2Loaders=ye;exports.configureLoader=xe;exports.createLoaders=ne;exports.getRaycastMesh=X;exports.setDracoDecoderLocation=Oe;exports.setKTX2TranscoderLocation=Se;