@needle-tools/gltf-progressive 1.2.3-beta → 1.2.4-beta

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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,9 @@ All notable changes to this package will be documented in this file.
4
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [1.2.4-beta] - 2023-07-05
8
+ - Change: `createLoaders` now returns created loaders and decoders to be re-used
9
+
7
10
  ## [1.2.3-beta] - 2023-07-04
8
11
  - Add: support for transmissive objects
9
12
 
@@ -9,7 +9,7 @@ var x = (a, t, e) => (Se(a, t, "read from private field"), e ? e.call(a) : t.get
9
9
  throw TypeError("Cannot add the same private member more than once");
10
10
  t instanceof WeakSet ? t.add(a) : t.set(a, e);
11
11
  }, F = (a, t, e, r) => (Se(a, t, "write to private field"), r ? r.call(a, e) : t.set(a, e), e);
12
- import { BufferGeometry as de, Mesh as H, Material as Ne, Texture as ee, TextureLoader as Ue, Matrix4 as be, Frustum as We, Clock as Ke, MeshStandardMaterial as qe, Sphere as Xe, Box3 as Te, Vector3 as N } from "three";
12
+ import { BufferGeometry as he, Mesh as H, Material as Ne, Texture as re, TextureLoader as Ue, Matrix4 as be, Frustum as We, Clock as Ke, MeshStandardMaterial as qe, Sphere as Xe, Box3 as Te, Vector3 as N } from "three";
13
13
  import { GLTFLoader as Ye } from "three/examples/jsm/loaders/GLTFLoader.js";
14
14
  import { MeshoptDecoder as He } from "three/examples/jsm/libs/meshopt_decoder.module.js";
15
15
  import { DRACOLoader as Je } from "three/examples/jsm/loaders/DRACOLoader.js";
@@ -17,22 +17,22 @@ import { KTX2Loader as Qe } from "three/examples/jsm/loaders/KTX2Loader.js";
17
17
  const Be = "";
18
18
  globalThis.GLTF_PROGRESSIVE_VERSION = Be;
19
19
  console.debug(`[gltf-progressive] version ${Be}`);
20
- let he = "https://www.gstatic.com/draco/versioned/decoders/1.4.1/", _e = "https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";
21
- fetch(he + "draco_decoder.js", { method: "head" }).catch((a) => {
22
- he = "./include/draco/", _e = "./include/ktx2/";
20
+ let ge = "https://www.gstatic.com/draco/versioned/decoders/1.4.1/", _e = "https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";
21
+ fetch(ge + "draco_decoder.js", { method: "head" }).catch((a) => {
22
+ ge = "./include/draco/", _e = "./include/ktx2/";
23
23
  });
24
24
  function gt(a) {
25
- he = a;
25
+ ge = a;
26
26
  }
27
27
  function pt(a) {
28
28
  _e = a;
29
29
  }
30
- let ie, De, oe;
30
+ let Q, de, Z;
31
31
  function ke(a) {
32
- ie || (ie = new Je(), ie.setDecoderPath(he), ie.setDecoderConfig({ type: "js" })), oe || (oe = new Qe(), oe.setTranscoderPath(_e)), De || (De = He), a ? oe.detectSupport(a) : console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures will probably fail");
32
+ return Q || (Q = new Je(), Q.setDecoderPath(ge), Q.setDecoderConfig({ type: "js" })), Z || (Z = new Qe(), Z.setTranscoderPath(_e)), de || (de = He), a ? Z.detectSupport(a) : a !== null && console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"), { dracoLoader: Q, ktx2Loader: Z, meshoptDecoder: de };
33
33
  }
34
34
  function Ie(a) {
35
- a.dracoLoader || a.setDRACOLoader(ie), a.ktx2Loader || a.setKTX2Loader(oe), a.meshoptDecoder || a.setMeshoptDecoder(De);
35
+ a.dracoLoader || a.setDRACOLoader(Q), a.ktx2Loader || a.setKTX2Loader(Z), a.meshoptDecoder || a.setMeshoptDecoder(de);
36
36
  }
37
37
  ae("debugprogressive");
38
38
  function ae(a) {
@@ -51,13 +51,13 @@ function Ze(a, t) {
51
51
  }
52
52
  return t;
53
53
  }
54
- let te;
54
+ let se;
55
55
  function je() {
56
- return te !== void 0 || (te = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent), ae("debugprogressive") && console.log("[glTF Progressive]: isMobileDevice", te)), te;
56
+ return se !== void 0 || (se = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent), ae("debugprogressive") && console.log("[glTF Progressive]: isMobileDevice", se)), se;
57
57
  }
58
58
  const we = Symbol("needle:raycast-mesh");
59
59
  function Oe(a) {
60
- return (a == null ? void 0 : a[we]) instanceof de ? a[we] : null;
60
+ return (a == null ? void 0 : a[we]) instanceof he ? a[we] : null;
61
61
  }
62
62
  function et(a, t) {
63
63
  if ((a.type === "Mesh" || a.type === "SkinnedMesh") && !Oe(a)) {
@@ -67,28 +67,28 @@ function et(a, t) {
67
67
  }
68
68
  function yt(a = !0) {
69
69
  if (a) {
70
- if (re)
70
+ if (ie)
71
71
  return;
72
- const t = re = H.prototype.raycast;
72
+ const t = ie = H.prototype.raycast;
73
73
  H.prototype.raycast = function(e, r) {
74
74
  const o = this, i = Oe(o);
75
75
  let s;
76
76
  i && o.isMesh && (s = o.geometry, o.geometry = i), t.call(this, e, r), s && (o.geometry = s);
77
77
  };
78
78
  } else {
79
- if (!re)
79
+ if (!ie)
80
80
  return;
81
- H.prototype.raycast = re, re = null;
81
+ H.prototype.raycast = ie, ie = null;
82
82
  }
83
83
  }
84
- let re = null;
84
+ let ie = null;
85
85
  function tt(a) {
86
- const t = new de();
86
+ const t = new he();
87
87
  for (const e in a.attributes)
88
88
  t.setAttribute(e, a.getAttribute(e));
89
89
  return t.setIndex(a.getIndex()), t;
90
90
  }
91
- const Y = new Array(), U = "NEEDLE_progressive", M = ae("debugprogressive"), xe = Symbol("needle-progressive-texture"), ne = /* @__PURE__ */ new Map(), ve = /* @__PURE__ */ new Set();
91
+ const Y = new Array(), U = "NEEDLE_progressive", M = ae("debugprogressive"), Le = Symbol("needle-progressive-texture"), ne = /* @__PURE__ */ new Map(), ve = /* @__PURE__ */ new Set();
92
92
  if (M) {
93
93
  let a = function() {
94
94
  t += 1, console.log("Toggle LOD level", t, ne), ne.forEach((o, i) => {
@@ -295,7 +295,7 @@ const _ = class {
295
295
  return n;
296
296
  });
297
297
  }
298
- if (t instanceof ee || t.isTexture === !0) {
298
+ if (t instanceof re || t.isTexture === !0) {
299
299
  const r = t;
300
300
  return this.assignTextureLODForSlot(r, e, null, null);
301
301
  }
@@ -372,7 +372,7 @@ const _ = class {
372
372
  let s;
373
373
  if (t.isTexture === !0) {
374
374
  const D = t;
375
- D.source && D.source[xe] && (s = D.source[xe]);
375
+ D.source && D.source[Le] && (s = D.source[Le]);
376
376
  }
377
377
  if (s || (s = _.lodInfos.get(i)), s) {
378
378
  if (e > 0) {
@@ -393,7 +393,7 @@ const _ = class {
393
393
  r && console.log(`LOD ${e} was already loading/loaded: ${d}`);
394
394
  let m = await p.catch((z) => (console.error(`Error loading LOD ${e} from ${h}
395
395
  `, z), null)), w = !1;
396
- if (m == null || (m instanceof ee && t instanceof ee ? (l = m.image) != null && l.data || (u = m.source) != null && u.data ? m = this.copySettings(t, m) : (w = !0, this.previouslyLoaded.delete(d)) : m instanceof de && t instanceof de && ((c = m.attributes.position) != null && c.array || (w = !0, this.previouslyLoaded.delete(d)))), !w)
396
+ if (m == null || (m instanceof re && t instanceof re ? (l = m.image) != null && l.data || (u = m.source) != null && u.data ? m = this.copySettings(t, m) : (w = !0, this.previouslyLoaded.delete(d)) : m instanceof he && t instanceof he && ((c = m.attributes.position) != null && c.array || (w = !0, this.previouslyLoaded.delete(d)))), !w)
397
397
  return m;
398
398
  }
399
399
  const L = s, k = new Promise(async (m, w) => {
@@ -425,7 +425,7 @@ const _ = class {
425
425
  }
426
426
  if (O) {
427
427
  let y = await V.getDependency("texture", A);
428
- return y && _.assignLODInformation(o.url, y, i, e, void 0, void 0), r && console.log('change "' + t.name + '" → "' + y.name + '"', h, A, y, d), t instanceof ee && (y = this.copySettings(t, y)), y && (y.guid = L.guid), m(y);
428
+ return y && _.assignLODInformation(o.url, y, i, e, void 0, void 0), r && console.log('change "' + t.name + '" → "' + y.name + '"', h, A, y, d), t instanceof re && (y = this.copySettings(t, y)), y && (y.guid = L.guid), m(y);
429
429
  } else
430
430
  M && console.warn("Could not find texture with guid", L.guid, S.parser.json);
431
431
  }
@@ -463,7 +463,7 @@ const _ = class {
463
463
  return m(null);
464
464
  });
465
465
  return this.previouslyLoaded.set(d, k), await k;
466
- } else if (t instanceof ee) {
466
+ } else if (t instanceof re) {
467
467
  r && console.log("Load texture from uri: " + h);
468
468
  const p = await new Ue().loadAsync(h);
469
469
  return p ? (p.guid = s.guid, p.flipY = !1, p.needsUpdate = !0, p.colorSpace = t.colorSpace, r && console.log(s, p)) : M && console.warn("failed loading", h), p;
@@ -499,7 +499,7 @@ f(b, "registerTexture", (t, e, r, o, i) => {
499
499
  M && console.error("gltf-progressive: Register texture without texture");
500
500
  return;
501
501
  }
502
- e.source && (e.source[xe] = i);
502
+ e.source && (e.source[Le] = i);
503
503
  const s = i.guid;
504
504
  _.assignLODInformation(t, e, s, r, o, void 0), _.lodInfos.set(s, i), _.lowresCache.set(s, e);
505
505
  }), /**
@@ -535,8 +535,8 @@ class rt {
535
535
  this.url = t, this.key = e, this.level = r, o != null && (this.index = o), i != null && (this.density = i);
536
536
  }
537
537
  }
538
- const I = ae("debugprogressive"), st = ae("noprogressive"), Le = Symbol("Needle:LODSManager"), Me = Symbol("Needle:LODState"), J = Symbol("Needle:CurrentLOD"), R = { mesh_lod: -1, texture_lod: -1 };
539
- var B, W, ge, Q, Z, pe, K;
538
+ const I = ae("debugprogressive"), st = ae("noprogressive"), Me = Symbol("Needle:LODSManager"), De = Symbol("Needle:LODState"), J = Symbol("Needle:CurrentLOD"), R = { mesh_lod: -1, texture_lod: -1 };
539
+ var B, W, pe, j, ee, ye, K;
540
540
  const C = class {
541
541
  // readonly plugins: NEEDLE_progressive_plugin[] = [];
542
542
  constructor(t, e) {
@@ -560,10 +560,10 @@ const C = class {
560
560
  f(this, "pause", !1);
561
561
  f(this, "_lodchangedlisteners", []);
562
562
  X(this, W, void 0);
563
- X(this, ge, new Ke());
564
- X(this, Q, 0);
565
- X(this, Z, 0);
566
- X(this, pe, 0);
563
+ X(this, pe, new Ke());
564
+ X(this, j, 0);
565
+ X(this, ee, 0);
566
+ X(this, ye, 0);
567
567
  X(this, K, 0);
568
568
  f(this, "_fpsBuffer", [60, 60, 60, 60, 60]);
569
569
  // private testIfLODLevelsAreAvailable() {
@@ -578,7 +578,7 @@ const C = class {
578
578
  }
579
579
  /** @internal */
580
580
  static getObjectLODState(t) {
581
- return t[Me];
581
+ return t[De];
582
582
  }
583
583
  static addPlugin(t) {
584
584
  Y.push(t);
@@ -593,13 +593,13 @@ const C = class {
593
593
  * @returns The LODsManager instance.
594
594
  */
595
595
  static get(t, e) {
596
- if (t[Le])
597
- return console.debug("[gltf-progressive] LODsManager already exists for this renderer"), t[Le];
596
+ if (t[Me])
597
+ return console.debug("[gltf-progressive] LODsManager already exists for this renderer"), t[Me];
598
598
  const r = new C(t, {
599
599
  engine: "unknown",
600
600
  ...e
601
601
  });
602
- return t[Le] = r, r;
602
+ return t[Me] = r, r;
603
603
  }
604
604
  /** @deprecated use static `LODsManager.addPlugin()` method. This getter will be removed in later versions */
605
605
  get plugins() {
@@ -619,8 +619,8 @@ const C = class {
619
619
  F(this, W, this.renderer.render);
620
620
  const e = this;
621
621
  ke(this.renderer), this.renderer.render = function(r, o) {
622
- e.renderer.getRenderTarget() == null && (t = 0, F(e, Q, x(e, Q) + 1), F(e, Z, x(e, ge).getDelta()), F(e, pe, x(e, pe) + x(e, Z)), e._fpsBuffer.shift(), e._fpsBuffer.push(1 / x(e, Z)), F(e, K, e._fpsBuffer.reduce((l, u) => l + u) / e._fpsBuffer.length), I && x(e, Q) % 30 === 0 && console.log("FPS", Math.round(x(e, K)), "Interval:", x(e, B)));
623
- const s = x(e, Q), n = t++;
622
+ e.renderer.getRenderTarget() == null && (t = 0, F(e, j, x(e, j) + 1), F(e, ee, x(e, pe).getDelta()), F(e, ye, x(e, ye) + x(e, ee)), e._fpsBuffer.shift(), e._fpsBuffer.push(1 / x(e, ee)), F(e, K, e._fpsBuffer.reduce((l, u) => l + u) / e._fpsBuffer.length), I && x(e, j) % 30 === 0 && console.log("FPS", Math.round(x(e, K)), "Interval:", x(e, B)));
623
+ const s = x(e, j), n = t++;
624
624
  e.onBeforeRender(r, o, n, s), x(e, W).call(this, r, o), e.onAfterRender(r, o, n, s);
625
625
  };
626
626
  }
@@ -682,8 +682,8 @@ const C = class {
682
682
  updateLODs(t, e, r, o, i) {
683
683
  var l, u;
684
684
  r.userData || (r.userData = {});
685
- let s = r[Me];
686
- if (s || (s = new it(), r[Me] = s), s.frames++ < 2)
685
+ let s = r[De];
686
+ if (s || (s = new it(), r[De] = s), s.frames++ < 2)
687
687
  return;
688
688
  for (const c of Y)
689
689
  (l = c.onBeforeUpdateLOD) == null || l.call(c, this.renderer, t, e, r);
@@ -779,11 +779,11 @@ const C = class {
779
779
  }
780
780
  if (this._tempBox.applyMatrix4(this.projectionScreenMatrix), this.renderer.xr.enabled && m.fov > 70) {
781
781
  const g = this._tempBox.min, v = this._tempBox.max;
782
- let T = g.x, P = g.y, E = v.x, j = v.y;
783
- const le = 2, ye = 1.5, ce = (g.x + v.x) * 0.5, ue = (g.y + v.y) * 0.5;
784
- T = (T - ce) * le + ce, P = (P - ue) * le + ue, E = (E - ce) * le + ce, j = (j - ue) * le + ue;
785
- const Fe = T < 0 && E > 0 ? 0 : Math.min(Math.abs(g.x), Math.abs(v.x)), $e = P < 0 && j > 0 ? 0 : Math.min(Math.abs(g.y), Math.abs(v.y)), me = Math.max(Fe, $e);
786
- r.lastCentrality = (ye - me) * (ye - me) * (ye - me);
782
+ let T = g.x, P = g.y, E = v.x, te = v.y;
783
+ const le = 2, me = 1.5, ce = (g.x + v.x) * 0.5, ue = (g.y + v.y) * 0.5;
784
+ T = (T - ce) * le + ce, P = (P - ue) * le + ue, E = (E - ce) * le + ce, te = (te - ue) * le + ue;
785
+ const Fe = T < 0 && E > 0 ? 0 : Math.min(Math.abs(g.x), Math.abs(v.x)), $e = P < 0 && te > 0 ? 0 : Math.min(Math.abs(g.y), Math.abs(v.y)), xe = Math.max(Fe, $e);
786
+ r.lastCentrality = (me - xe) * (me - xe) * (me - xe);
787
787
  } else
788
788
  r.lastCentrality = 1;
789
789
  const w = this._tempBox.getSize(this._tempBoxSize);
@@ -796,8 +796,8 @@ const C = class {
796
796
  g.invert();
797
797
  const v = C.corner0, T = C.corner1, P = C.corner2, E = C.corner3;
798
798
  v.copy(this._tempBox.min), T.copy(this._tempBox.max), T.x = v.x, P.copy(this._tempBox.max), P.y = v.y, E.copy(this._tempBox.max);
799
- const j = (v.z + E.z) * 0.5;
800
- v.z = T.z = P.z = E.z = j, v.applyMatrix4(g), T.applyMatrix4(g), P.applyMatrix4(g), E.applyMatrix4(g), C.debugDrawLine(v, T, 255), C.debugDrawLine(v, P, 255), C.debugDrawLine(T, E, 255), C.debugDrawLine(P, E, 255);
799
+ const te = (v.z + E.z) * 0.5;
800
+ v.z = T.z = P.z = E.z = te, v.applyMatrix4(g), T.applyMatrix4(g), P.applyMatrix4(g), E.applyMatrix4(g), C.debugDrawLine(v, T, 255), C.debugDrawLine(v, P, 255), C.debugDrawLine(T, E, 255), C.debugDrawLine(P, E, 255);
801
801
  }
802
802
  let O = 999;
803
803
  if (c && r.lastScreenCoverage > 0) {
@@ -843,7 +843,7 @@ ${e.name}`);
843
843
  }
844
844
  };
845
845
  let G = C;
846
- B = new WeakMap(), W = new WeakMap(), ge = new WeakMap(), Q = new WeakMap(), Z = new WeakMap(), pe = new WeakMap(), K = new WeakMap(), /** 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.
846
+ B = new WeakMap(), W = new WeakMap(), pe = new WeakMap(), j = new WeakMap(), ee = new WeakMap(), ye = new WeakMap(), K = new WeakMap(), /** 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.
847
847
  */
848
848
  f(G, "debugDrawLine"), f(G, "corner0", new N()), f(G, "corner1", new N()), f(G, "corner2", new N()), f(G, "corner3", new N()), f(G, "_tempPtInside", new N());
849
849
  class it {
@@ -857,18 +857,18 @@ class it {
857
857
  }
858
858
  }
859
859
  const Pe = Symbol("NEEDLE_mesh_lod"), fe = Symbol("NEEDLE_texture_lod");
860
- let se = null;
860
+ let oe = null;
861
861
  function Re() {
862
862
  const a = ot();
863
863
  a && (a.mapURLs(function(t) {
864
864
  return Ee(), t;
865
- }), Ee(), se == null || se.disconnect(), se = new MutationObserver((t) => {
865
+ }), Ee(), oe == null || oe.disconnect(), oe = new MutationObserver((t) => {
866
866
  t.forEach((e) => {
867
867
  e.addedNodes.forEach((r) => {
868
868
  r instanceof HTMLElement && r.tagName.toLowerCase() === "model-viewer" && Ge(r);
869
869
  });
870
870
  });
871
- }), se.observe(document, { childList: !0, subtree: !0 }));
871
+ }), oe.observe(document, { childList: !0, subtree: !0 }));
872
872
  }
873
873
  function ot() {
874
874
  const a = customElements.get("model-viewer");
@@ -1,8 +1,8 @@
1
- var Re=Object.defineProperty,Ge=(t,e,s)=>e in t?Re(t,e,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[e]=s,d=(t,e,s)=>(Ge(t,typeof e!="symbol"?e+"":e,s),s),be=(t,e,s)=>{if(!e.has(t))throw TypeError("Cannot "+s)},x=(t,e,s)=>(be(t,e,"read from private field"),s?s.call(t):e.get(t)),q=(t,e,s)=>{if(e.has(t))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(t):e.set(t,s)},F=(t,e,s,o)=>(be(t,e,"write to private field"),o?o.call(t,s):e.set(t,s),s);import{BufferGeometry as oe,Mesh as X,Material as Fe,Texture as Y,TextureLoader as We,Matrix4 as Se,Frustum as Ne,Clock as $e,MeshStandardMaterial as ze,Sphere as Ve,Box3 as Te,Vector3 as W}from"three";import{GLTFLoader as Ue}from"three/examples/jsm/loaders/GLTFLoader.js";import{MeshoptDecoder as qe}from"three/examples/jsm/libs/meshopt_decoder.module.js";import{DRACOLoader as Xe}from"three/examples/jsm/loaders/DRACOLoader.js";import{KTX2Loader as Ke}from"three/examples/jsm/loaders/KTX2Loader.js";const ge="";globalThis.GLTF_PROGRESSIVE_VERSION=ge,console.debug(`[gltf-progressive] version ${ge}`);let ie="https://www.gstatic.com/draco/versioned/decoders/1.4.1/",me="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";fetch(ie+"draco_decoder.js",{method:"head"}).catch(t=>{ie="./include/draco/",me="./include/ktx2/"});function He(t){ie=t}function Ye(t){me=t}let J,pe,Q;function ve(t){J||(J=new Xe,J.setDecoderPath(ie),J.setDecoderConfig({type:"js"})),Q||(Q=new Ke,Q.setTranscoderPath(me)),pe||(pe=qe),t?Q.detectSupport(t):console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures will probably fail")}function xe(t){t.dracoLoader||t.setDRACOLoader(J),t.ktx2Loader||t.setKTX2Loader(Q),t.meshoptDecoder||t.setMeshoptDecoder(pe)}Z("debugprogressive");function Z(t){const e=new URL(window.location.href).searchParams.get(t);return e==null||e==="0"||e==="false"?!1:e===""?!0:e}function Je(t,e){if(e===void 0||e.startsWith("./")||e.startsWith("http")||t===void 0)return e;const s=t.lastIndexOf("/");if(s>=0){const o=t.substring(0,s+1);for(;o.endsWith("/")&&e.startsWith("/");)e=e.substring(1);return o+e}return e}let le;function Qe(){return le!==void 0||(le=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),Z("debugprogressive")&&console.log("[glTF Progressive]: isMobileDevice",le)),le}const ye=Symbol("needle:raycast-mesh");function ae(t){return t?.[ye]instanceof oe?t[ye]:null}function Ee(t,e){if((t.type==="Mesh"||t.type==="SkinnedMesh")&&!ae(t)){const s=et(e);s.userData={isRaycastMesh:!0},t[ye]=s}}function Ze(t=!0){if(t){if(ee)return;const e=ee=X.prototype.raycast;X.prototype.raycast=function(s,o){const r=this,n=ae(r);let i;n&&r.isMesh&&(i=r.geometry,r.geometry=n),e.call(this,s,o),i&&(r.geometry=i)}}else{if(!ee)return;X.prototype.raycast=ee,ee=null}}let ee=null;function et(t){const e=new oe;for(const s in t.attributes)e.setAttribute(s,t.getAttribute(s));return e.setIndex(t.getIndex()),e}const $=new Array,j="NEEDLE_progressive",y=Z("debugprogressive"),Le=Symbol("needle-progressive-texture"),te=new Map,Me=new Set;if(y){let t=function(){e+=1,console.log("Toggle LOD level",e,te),te.forEach((r,n)=>{for(const i of r.keys){const l=n[i];if(l!=null){if(l.isBufferGeometry===!0){const u=b.getMeshLODInformation(l),a=u?Math.min(e,u.lods.length):0;n["DEBUG:LOD"]=e,b.assignMeshLOD(n,a),u&&(s=Math.max(s,u.lods.length-1))}else if(n.isMaterial===!0){n["DEBUG:LOD"]=e,b.assignTextureLOD(n,e);break}}}}),e>=s&&(e=-1)},e=-1,s=2,o=!1;window.addEventListener("keyup",r=>{r.key==="p"&&t(),r.key==="w"&&(o=!o,Me&&Me.forEach(n=>{n.name!="BackgroundCubeMaterial"&&n.glyphMap==null&&"wireframe"in n&&(n.wireframe=o)}))})}function Ae(t,e,s){var o;if(!y)return;te.has(t)||te.set(t,{keys:[],sourceId:s});const r=te.get(t);((o=r?.keys)==null?void 0:o.includes(e))==!1&&r.keys.push(e)}const _=class{constructor(t,e){d(this,"parser"),d(this,"url"),d(this,"_isLoadingMesh"),d(this,"loadMesh",s=>{var o,r;if(this._isLoadingMesh)return null;const n=(r=(o=this.parser.json.meshes[s])==null?void 0:o.extensions)==null?void 0:r[j];return n?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",s).then(i=>{var l;return this._isLoadingMesh=!1,i&&_.registerMesh(this.url,n.guid,i,(l=n.lods)==null?void 0:l.length,void 0,n),i})):null}),y&&console.log("Progressive extension registered for",e),this.parser=t,this.url=e}get name(){return j}static getMeshLODInformation(t){const e=this.getAssignedLODInformation(t);return e!=null&&e.key?this.lodInfos.get(e.key):null}static getMaterialMinMaxLODsCount(t,e){const s=this,o="LODS:minmax",r=t[o];if(r!=null)return r;if(e||(e={min_count:1/0,max_count:0,lods:[]}),Array.isArray(t)){for(const i of t)this.getMaterialMinMaxLODsCount(i,e);return t[o]=e,e}if(y==="verbose"&&console.log("getMaterialMinMaxLODsCount",t),t.type==="ShaderMaterial"||t.type==="RawShaderMaterial"){const i=t;for(const l of Object.keys(i.uniforms)){const u=i.uniforms[l].value;u?.isTexture===!0&&n(u,e)}}else if(t.isMaterial)for(const i of Object.keys(t)){const l=t[i];l?.isTexture===!0&&n(l,e)}return t[o]=e,e;function n(i,l){const u=s.getAssignedLODInformation(i);if(u){const a=s.lodInfos.get(u.key);if(a&&a.lods){l.min_count=Math.min(l.min_count,a.lods.length),l.max_count=Math.max(l.max_count,a.lods.length);for(let m=0;m<a.lods.length;m++){const v=a.lods[m];v.width&&(l.lods[m]=l.lods[m]||{min_height:1/0,max_height:0},l.lods[m].min_height=Math.min(l.lods[m].min_height,v.height),l.lods[m].max_height=Math.max(l.lods[m].max_height,v.height))}}}}}static hasLODLevelAvailable(t,e){var s;if(Array.isArray(t)){for(const n of t)if(this.hasLODLevelAvailable(n,e))return!0;return!1}if(t.isMaterial===!0){for(const n of Object.keys(t)){const i=t[n];if(i&&i.isTexture&&this.hasLODLevelAvailable(i,e))return!0}return!1}else if(t.isGroup===!0){for(const n of t.children)if(n.isMesh===!0&&this.hasLODLevelAvailable(n,e))return!0}let o,r;if(t.isMesh?o=t.geometry:(t.isBufferGeometry||t.isTexture)&&(o=t),o&&(s=o?.userData)!=null&&s.LODS){const n=o.userData.LODS;if(r=this.lodInfos.get(n.key),e===void 0)return r!=null;if(r)return Array.isArray(r.lods)?e<r.lods.length:e===0}return!1}static assignMeshLOD(t,e){var s;if(!t)return Promise.resolve(null);if(t instanceof X||t.isMesh===!0){const o=t.geometry,r=this.getAssignedLODInformation(o);if(!r)return Promise.resolve(null);for(const n of $)(s=n.onBeforeGetLODMesh)==null||s.call(n,t,e);return t["LOD:requested level"]=e,_.getOrLoadLOD(o,e).then(n=>{if(t["LOD:requested level"]===e){if(delete t["LOD:requested level"],Array.isArray(n)){const i=r.index||0;n=n[i]}n&&o!=n&&(n?.isBufferGeometry?(t.geometry=n,y&&Ae(t,"geometry",r.url)):y&&console.error("Invalid LOD geometry",n))}return n}).catch(n=>(console.error("Error loading mesh LOD",t,n),null))}else y&&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 instanceof Fe||t.isMaterial===!0){const s=t,o=[],r=new Array;if(y&&Me.add(s),s.uniforms&&s.isRawShaderMaterial||s.isShaderMaterial===!0){const n=s;for(const i of Object.keys(n.uniforms)){const l=n.uniforms[i].value;if(l?.isTexture===!0){const u=this.assignTextureLODForSlot(l,e,s,i);o.push(u),r.push(i)}}}else for(const n of Object.keys(s)){const i=s[n];if(i?.isTexture===!0){const l=this.assignTextureLODForSlot(i,e,s,n);o.push(l),r.push(n)}}return Promise.all(o).then(n=>{const i=new Array;for(let l=0;l<n.length;l++){const u=n[l],a=r[l];u&&u.isTexture===!0?i.push({material:s,slot:a,texture:u,level:e}):i.push({material:s,slot:a,texture:null,level:e})}return i})}if(t instanceof Y||t.isTexture===!0){const s=t;return this.assignTextureLODForSlot(s,e,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(t,e,s,o){return t?.isTexture!==!0?Promise.resolve(null):o==="glyphMap"?Promise.resolve(t):_.getOrLoadLOD(t,e).then(r=>{if(Array.isArray(r))return null;if(r?.isTexture===!0){if(r!=t){if(s&&o){const n=s[o];if(n){const i=this.getAssignedLODInformation(n);if(i&&i?.level<e)return y==="verbose"&&console.warn("Assigned texture level is already higher: ",i.level,e,s,n,r),null}s[o]=r}if(y&&o&&s){const n=this.getAssignedLODInformation(t);n&&Ae(s,o,n.url)}}return r}else y=="verbose"&&console.warn("No LOD found for",t,e);return null}).catch(r=>(console.error("Error loading LOD",t,r),null))}afterRoot(t){var e,s;return y&&console.log("AFTER",this.url,t),(e=this.parser.json.textures)==null||e.forEach((o,r)=>{var n;if(o!=null&&o.extensions){const i=o?.extensions[j];if(i){if(!i.lods){y&&console.warn("Texture has no LODs",i);return}let l=!1;for(const u of this.parser.associations.keys())if(u.isTexture===!0){const a=this.parser.associations.get(u);a?.textures===r&&(l=!0,_.registerTexture(this.url,u,(n=i.lods)==null?void 0:n.length,r,i))}l||this.parser.getDependency("texture",r).then(u=>{var a;u&&_.registerTexture(this.url,u,(a=i.lods)==null?void 0:a.length,r,i)})}}}),(s=this.parser.json.meshes)==null||s.forEach((o,r)=>{if(o!=null&&o.extensions){const n=o?.extensions[j];if(n&&n.lods){for(const i of this.parser.associations.keys())if(i.isMesh){const l=this.parser.associations.get(i);l?.meshes===r&&_.registerMesh(this.url,n.guid,i,n.lods.length,l.primitives,n)}}}}),null}static async getOrLoadLOD(t,e){var s,o,r,n;const i=y=="verbose",l=t.userData.LODS;if(!l)return null;const u=l?.key;let a;if(t.isTexture===!0){const m=t;m.source&&m.source[Le]&&(a=m.source[Le])}if(a||(a=_.lodInfos.get(u)),a){if(e>0){let c=!1;const L=Array.isArray(a.lods);if(L&&e>=a.lods.length?c=!0:L||(c=!0),c)return this.lowresCache.get(u)}const m=Array.isArray(a.lods)?(s=a.lods[e])==null?void 0:s.path:a.lods;if(!m)return y&&!a["missing:uri"]&&(a["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+e,a)),null;const v=Je(l.url,m);if(v.endsWith(".glb")||v.endsWith(".gltf")){if(!a.guid)return console.warn("missing pointer for glb/gltf texture",a),null;const c=v+"_"+a.guid,L=this.previouslyLoaded.get(c);if(L!==void 0){i&&console.log(`LOD ${e} was already loading/loaded: ${c}`);let g=await L.catch(A=>(console.error(`Error loading LOD ${e} from ${v}
2
- `,A),null)),p=!1;if(g==null||(g instanceof Y&&t instanceof Y?(o=g.image)!=null&&o.data||(r=g.source)!=null&&r.data?g=this.copySettings(t,g):(p=!0,this.previouslyLoaded.delete(c)):g instanceof oe&&t instanceof oe&&((n=g.attributes.position)!=null&&n.array||(p=!0,this.previouslyLoaded.delete(c)))),!p)return g}const D=a,T=new Promise(async(g,p)=>{const A=new Ue;xe(A),y&&(await new Promise(f=>setTimeout(f,1e3)),i&&console.warn("Start loading (delayed) "+v,D.guid));let C=v;if(D&&Array.isArray(D.lods)){const f=D.lods[e];f.hash&&(C+="?v="+f.hash)}const w=await A.loadAsync(C).catch(f=>(console.error(`Error loading LOD ${e} from ${v}
3
- `,f),null));if(!w)return null;const G=w.parser;i&&console.log("Loading finished "+v,D.guid);let I=0;if(w.parser.json.textures){let f=!1;for(const h of w.parser.json.textures){if(h!=null&&h.extensions){const M=h?.extensions[j];if(M!=null&&M.guid&&M.guid===D.guid){f=!0;break}}I++}if(f){let h=await G.getDependency("texture",I);return h&&_.assignLODInformation(l.url,h,u,e,void 0,void 0),i&&console.log('change "'+t.name+'" \u2192 "'+h.name+'"',v,I,h,c),t instanceof Y&&(h=this.copySettings(t,h)),h&&(h.guid=D.guid),g(h)}else y&&console.warn("Could not find texture with guid",D.guid,w.parser.json)}if(I=0,w.parser.json.meshes){let f=!1;for(const h of w.parser.json.meshes){if(h!=null&&h.extensions){const M=h?.extensions[j];if(M!=null&&M.guid&&M.guid===D.guid){f=!0;break}}I++}if(f){const h=await G.getDependency("mesh",I),M=D;if(i&&console.log(`Loaded Mesh "${h.name}"`,v,I,h,c),h.isMesh===!0){const O=h.geometry;return _.assignLODInformation(l.url,O,u,e,void 0,M.density),g(O)}else{const O=new Array;for(let S=0;S<h.children.length;S++){const N=h.children[S];if(N.isMesh===!0){const U=N.geometry;_.assignLODInformation(l.url,U,u,e,S,M.density),O.push(U)}}return g(O)}}else y&&console.warn("Could not find mesh with guid",D.guid,w.parser.json)}return g(null)});return this.previouslyLoaded.set(c,T),await T}else if(t instanceof Y){i&&console.log("Load texture from uri: "+v);const c=await new We().loadAsync(v);return c?(c.guid=a.guid,c.flipY=!1,c.needsUpdate=!0,c.colorSpace=t.colorSpace,i&&console.log(a,c)):y&&console.warn("failed loading",v),c}}else y&&console.warn(`Can not load LOD ${e}: no LOD info found for "${u}" ${t.name}`,t.type);return null}static assignLODInformation(t,e,s,o,r,n){if(!e)return;e.userData||(e.userData={});const i=new tt(t,s,o,r,n);e.userData.LODS=i}static getAssignedLODInformation(t){var e;return((e=t?.userData)==null?void 0:e.LODS)||null}static copySettings(t,e){return e=e.clone(),y&&console.warn(`Copying texture settings
1
+ var Re=Object.defineProperty,Ge=(t,e,s)=>e in t?Re(t,e,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[e]=s,d=(t,e,s)=>(Ge(t,typeof e!="symbol"?e+"":e,s),s),be=(t,e,s)=>{if(!e.has(t))throw TypeError("Cannot "+s)},v=(t,e,s)=>(be(t,e,"read from private field"),s?s.call(t):e.get(t)),q=(t,e,s)=>{if(e.has(t))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(t):e.set(t,s)},F=(t,e,s,o)=>(be(t,e,"write to private field"),o?o.call(t,s):e.set(t,s),s);import{BufferGeometry as oe,Mesh as X,Material as Fe,Texture as Q,TextureLoader as We,Matrix4 as Se,Frustum as Ne,Clock as $e,MeshStandardMaterial as ze,Sphere as Ve,Box3 as Te,Vector3 as W}from"three";import{GLTFLoader as Ue}from"three/examples/jsm/loaders/GLTFLoader.js";import{MeshoptDecoder as qe}from"three/examples/jsm/libs/meshopt_decoder.module.js";import{DRACOLoader as Xe}from"three/examples/jsm/loaders/DRACOLoader.js";import{KTX2Loader as Ke}from"three/examples/jsm/loaders/KTX2Loader.js";const me="";globalThis.GLTF_PROGRESSIVE_VERSION=me,console.debug(`[gltf-progressive] version ${me}`);let ie="https://www.gstatic.com/draco/versioned/decoders/1.4.1/",pe="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";fetch(ie+"draco_decoder.js",{method:"head"}).catch(t=>{ie="./include/draco/",pe="./include/ktx2/"});function He(t){ie=t}function Ye(t){pe=t}let K,le,H;function xe(t){return K||(K=new Xe,K.setDecoderPath(ie),K.setDecoderConfig({type:"js"})),H||(H=new Ke,H.setTranscoderPath(pe)),le||(le=qe),t?H.detectSupport(t):t!==null&&console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"),{dracoLoader:K,ktx2Loader:H,meshoptDecoder:le}}function ve(t){t.dracoLoader||t.setDRACOLoader(K),t.ktx2Loader||t.setKTX2Loader(H),t.meshoptDecoder||t.setMeshoptDecoder(le)}Z("debugprogressive");function Z(t){const e=new URL(window.location.href).searchParams.get(t);return e==null||e==="0"||e==="false"?!1:e===""?!0:e}function Je(t,e){if(e===void 0||e.startsWith("./")||e.startsWith("http")||t===void 0)return e;const s=t.lastIndexOf("/");if(s>=0){const o=t.substring(0,s+1);for(;o.endsWith("/")&&e.startsWith("/");)e=e.substring(1);return o+e}return e}let ae;function Qe(){return ae!==void 0||(ae=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),Z("debugprogressive")&&console.log("[glTF Progressive]: isMobileDevice",ae)),ae}const ye=Symbol("needle:raycast-mesh");function ue(t){return t?.[ye]instanceof oe?t[ye]:null}function Ee(t,e){if((t.type==="Mesh"||t.type==="SkinnedMesh")&&!ue(t)){const s=et(e);s.userData={isRaycastMesh:!0},t[ye]=s}}function Ze(t=!0){if(t){if(ee)return;const e=ee=X.prototype.raycast;X.prototype.raycast=function(s,o){const r=this,n=ue(r);let i;n&&r.isMesh&&(i=r.geometry,r.geometry=n),e.call(this,s,o),i&&(r.geometry=i)}}else{if(!ee)return;X.prototype.raycast=ee,ee=null}}let ee=null;function et(t){const e=new oe;for(const s in t.attributes)e.setAttribute(s,t.getAttribute(s));return e.setIndex(t.getIndex()),e}const $=new Array,j="NEEDLE_progressive",y=Z("debugprogressive"),Le=Symbol("needle-progressive-texture"),te=new Map,Me=new Set;if(y){let t=function(){e+=1,console.log("Toggle LOD level",e,te),te.forEach((r,n)=>{for(const i of r.keys){const l=n[i];if(l!=null){if(l.isBufferGeometry===!0){const u=b.getMeshLODInformation(l),a=u?Math.min(e,u.lods.length):0;n["DEBUG:LOD"]=e,b.assignMeshLOD(n,a),u&&(s=Math.max(s,u.lods.length-1))}else if(n.isMaterial===!0){n["DEBUG:LOD"]=e,b.assignTextureLOD(n,e);break}}}}),e>=s&&(e=-1)},e=-1,s=2,o=!1;window.addEventListener("keyup",r=>{r.key==="p"&&t(),r.key==="w"&&(o=!o,Me&&Me.forEach(n=>{n.name!="BackgroundCubeMaterial"&&n.glyphMap==null&&"wireframe"in n&&(n.wireframe=o)}))})}function Ae(t,e,s){var o;if(!y)return;te.has(t)||te.set(t,{keys:[],sourceId:s});const r=te.get(t);((o=r?.keys)==null?void 0:o.includes(e))==!1&&r.keys.push(e)}const _=class{constructor(t,e){d(this,"parser"),d(this,"url"),d(this,"_isLoadingMesh"),d(this,"loadMesh",s=>{var o,r;if(this._isLoadingMesh)return null;const n=(r=(o=this.parser.json.meshes[s])==null?void 0:o.extensions)==null?void 0:r[j];return n?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",s).then(i=>{var l;return this._isLoadingMesh=!1,i&&_.registerMesh(this.url,n.guid,i,(l=n.lods)==null?void 0:l.length,void 0,n),i})):null}),y&&console.log("Progressive extension registered for",e),this.parser=t,this.url=e}get name(){return j}static getMeshLODInformation(t){const e=this.getAssignedLODInformation(t);return e!=null&&e.key?this.lodInfos.get(e.key):null}static getMaterialMinMaxLODsCount(t,e){const s=this,o="LODS:minmax",r=t[o];if(r!=null)return r;if(e||(e={min_count:1/0,max_count:0,lods:[]}),Array.isArray(t)){for(const i of t)this.getMaterialMinMaxLODsCount(i,e);return t[o]=e,e}if(y==="verbose"&&console.log("getMaterialMinMaxLODsCount",t),t.type==="ShaderMaterial"||t.type==="RawShaderMaterial"){const i=t;for(const l of Object.keys(i.uniforms)){const u=i.uniforms[l].value;u?.isTexture===!0&&n(u,e)}}else if(t.isMaterial)for(const i of Object.keys(t)){const l=t[i];l?.isTexture===!0&&n(l,e)}return t[o]=e,e;function n(i,l){const u=s.getAssignedLODInformation(i);if(u){const a=s.lodInfos.get(u.key);if(a&&a.lods){l.min_count=Math.min(l.min_count,a.lods.length),l.max_count=Math.max(l.max_count,a.lods.length);for(let m=0;m<a.lods.length;m++){const x=a.lods[m];x.width&&(l.lods[m]=l.lods[m]||{min_height:1/0,max_height:0},l.lods[m].min_height=Math.min(l.lods[m].min_height,x.height),l.lods[m].max_height=Math.max(l.lods[m].max_height,x.height))}}}}}static hasLODLevelAvailable(t,e){var s;if(Array.isArray(t)){for(const n of t)if(this.hasLODLevelAvailable(n,e))return!0;return!1}if(t.isMaterial===!0){for(const n of Object.keys(t)){const i=t[n];if(i&&i.isTexture&&this.hasLODLevelAvailable(i,e))return!0}return!1}else if(t.isGroup===!0){for(const n of t.children)if(n.isMesh===!0&&this.hasLODLevelAvailable(n,e))return!0}let o,r;if(t.isMesh?o=t.geometry:(t.isBufferGeometry||t.isTexture)&&(o=t),o&&(s=o?.userData)!=null&&s.LODS){const n=o.userData.LODS;if(r=this.lodInfos.get(n.key),e===void 0)return r!=null;if(r)return Array.isArray(r.lods)?e<r.lods.length:e===0}return!1}static assignMeshLOD(t,e){var s;if(!t)return Promise.resolve(null);if(t instanceof X||t.isMesh===!0){const o=t.geometry,r=this.getAssignedLODInformation(o);if(!r)return Promise.resolve(null);for(const n of $)(s=n.onBeforeGetLODMesh)==null||s.call(n,t,e);return t["LOD:requested level"]=e,_.getOrLoadLOD(o,e).then(n=>{if(t["LOD:requested level"]===e){if(delete t["LOD:requested level"],Array.isArray(n)){const i=r.index||0;n=n[i]}n&&o!=n&&(n?.isBufferGeometry?(t.geometry=n,y&&Ae(t,"geometry",r.url)):y&&console.error("Invalid LOD geometry",n))}return n}).catch(n=>(console.error("Error loading mesh LOD",t,n),null))}else y&&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 instanceof Fe||t.isMaterial===!0){const s=t,o=[],r=new Array;if(y&&Me.add(s),s.uniforms&&s.isRawShaderMaterial||s.isShaderMaterial===!0){const n=s;for(const i of Object.keys(n.uniforms)){const l=n.uniforms[i].value;if(l?.isTexture===!0){const u=this.assignTextureLODForSlot(l,e,s,i);o.push(u),r.push(i)}}}else for(const n of Object.keys(s)){const i=s[n];if(i?.isTexture===!0){const l=this.assignTextureLODForSlot(i,e,s,n);o.push(l),r.push(n)}}return Promise.all(o).then(n=>{const i=new Array;for(let l=0;l<n.length;l++){const u=n[l],a=r[l];u&&u.isTexture===!0?i.push({material:s,slot:a,texture:u,level:e}):i.push({material:s,slot:a,texture:null,level:e})}return i})}if(t instanceof Q||t.isTexture===!0){const s=t;return this.assignTextureLODForSlot(s,e,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(t,e,s,o){return t?.isTexture!==!0?Promise.resolve(null):o==="glyphMap"?Promise.resolve(t):_.getOrLoadLOD(t,e).then(r=>{if(Array.isArray(r))return null;if(r?.isTexture===!0){if(r!=t){if(s&&o){const n=s[o];if(n){const i=this.getAssignedLODInformation(n);if(i&&i?.level<e)return y==="verbose"&&console.warn("Assigned texture level is already higher: ",i.level,e,s,n,r),null}s[o]=r}if(y&&o&&s){const n=this.getAssignedLODInformation(t);n&&Ae(s,o,n.url)}}return r}else y=="verbose"&&console.warn("No LOD found for",t,e);return null}).catch(r=>(console.error("Error loading LOD",t,r),null))}afterRoot(t){var e,s;return y&&console.log("AFTER",this.url,t),(e=this.parser.json.textures)==null||e.forEach((o,r)=>{var n;if(o!=null&&o.extensions){const i=o?.extensions[j];if(i){if(!i.lods){y&&console.warn("Texture has no LODs",i);return}let l=!1;for(const u of this.parser.associations.keys())if(u.isTexture===!0){const a=this.parser.associations.get(u);a?.textures===r&&(l=!0,_.registerTexture(this.url,u,(n=i.lods)==null?void 0:n.length,r,i))}l||this.parser.getDependency("texture",r).then(u=>{var a;u&&_.registerTexture(this.url,u,(a=i.lods)==null?void 0:a.length,r,i)})}}}),(s=this.parser.json.meshes)==null||s.forEach((o,r)=>{if(o!=null&&o.extensions){const n=o?.extensions[j];if(n&&n.lods){for(const i of this.parser.associations.keys())if(i.isMesh){const l=this.parser.associations.get(i);l?.meshes===r&&_.registerMesh(this.url,n.guid,i,n.lods.length,l.primitives,n)}}}}),null}static async getOrLoadLOD(t,e){var s,o,r,n;const i=y=="verbose",l=t.userData.LODS;if(!l)return null;const u=l?.key;let a;if(t.isTexture===!0){const m=t;m.source&&m.source[Le]&&(a=m.source[Le])}if(a||(a=_.lodInfos.get(u)),a){if(e>0){let c=!1;const L=Array.isArray(a.lods);if(L&&e>=a.lods.length?c=!0:L||(c=!0),c)return this.lowresCache.get(u)}const m=Array.isArray(a.lods)?(s=a.lods[e])==null?void 0:s.path:a.lods;if(!m)return y&&!a["missing:uri"]&&(a["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+e,a)),null;const x=Je(l.url,m);if(x.endsWith(".glb")||x.endsWith(".gltf")){if(!a.guid)return console.warn("missing pointer for glb/gltf texture",a),null;const c=x+"_"+a.guid,L=this.previouslyLoaded.get(c);if(L!==void 0){i&&console.log(`LOD ${e} was already loading/loaded: ${c}`);let f=await L.catch(A=>(console.error(`Error loading LOD ${e} from ${x}
2
+ `,A),null)),p=!1;if(f==null||(f instanceof Q&&t instanceof Q?(o=f.image)!=null&&o.data||(r=f.source)!=null&&r.data?f=this.copySettings(t,f):(p=!0,this.previouslyLoaded.delete(c)):f instanceof oe&&t instanceof oe&&((n=f.attributes.position)!=null&&n.array||(p=!0,this.previouslyLoaded.delete(c)))),!p)return f}const D=a,T=new Promise(async(f,p)=>{const A=new Ue;ve(A),y&&(await new Promise(g=>setTimeout(g,1e3)),i&&console.warn("Start loading (delayed) "+x,D.guid));let C=x;if(D&&Array.isArray(D.lods)){const g=D.lods[e];g.hash&&(C+="?v="+g.hash)}const w=await A.loadAsync(C).catch(g=>(console.error(`Error loading LOD ${e} from ${x}
3
+ `,g),null));if(!w)return null;const G=w.parser;i&&console.log("Loading finished "+x,D.guid);let I=0;if(w.parser.json.textures){let g=!1;for(const h of w.parser.json.textures){if(h!=null&&h.extensions){const M=h?.extensions[j];if(M!=null&&M.guid&&M.guid===D.guid){g=!0;break}}I++}if(g){let h=await G.getDependency("texture",I);return h&&_.assignLODInformation(l.url,h,u,e,void 0,void 0),i&&console.log('change "'+t.name+'" \u2192 "'+h.name+'"',x,I,h,c),t instanceof Q&&(h=this.copySettings(t,h)),h&&(h.guid=D.guid),f(h)}else y&&console.warn("Could not find texture with guid",D.guid,w.parser.json)}if(I=0,w.parser.json.meshes){let g=!1;for(const h of w.parser.json.meshes){if(h!=null&&h.extensions){const M=h?.extensions[j];if(M!=null&&M.guid&&M.guid===D.guid){g=!0;break}}I++}if(g){const h=await G.getDependency("mesh",I),M=D;if(i&&console.log(`Loaded Mesh "${h.name}"`,x,I,h,c),h.isMesh===!0){const O=h.geometry;return _.assignLODInformation(l.url,O,u,e,void 0,M.density),f(O)}else{const O=new Array;for(let S=0;S<h.children.length;S++){const N=h.children[S];if(N.isMesh===!0){const U=N.geometry;_.assignLODInformation(l.url,U,u,e,S,M.density),O.push(U)}}return f(O)}}else y&&console.warn("Could not find mesh with guid",D.guid,w.parser.json)}return f(null)});return this.previouslyLoaded.set(c,T),await T}else if(t instanceof Q){i&&console.log("Load texture from uri: "+x);const c=await new We().loadAsync(x);return c?(c.guid=a.guid,c.flipY=!1,c.needsUpdate=!0,c.colorSpace=t.colorSpace,i&&console.log(a,c)):y&&console.warn("failed loading",x),c}}else y&&console.warn(`Can not load LOD ${e}: no LOD info found for "${u}" ${t.name}`,t.type);return null}static assignLODInformation(t,e,s,o,r,n){if(!e)return;e.userData||(e.userData={});const i=new tt(t,s,o,r,n);e.userData.LODS=i}static getAssignedLODInformation(t){var e;return((e=t?.userData)==null?void 0:e.LODS)||null}static copySettings(t,e){return e=e.clone(),y&&console.warn(`Copying texture settings
4
4
  `,t.uuid,`
5
- `,e.uuid),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}};let b=_;d(b,"registerTexture",(t,e,s,o,r)=>{if(y&&console.log("> Progressive: register texture",o,e.name,e.uuid,e,r),!e){y&&console.error("gltf-progressive: Register texture without texture");return}e.source&&(e.source[Le]=r);const n=r.guid;_.assignLODInformation(t,e,n,s,o,void 0),_.lodInfos.set(n,r),_.lowresCache.set(n,e)}),d(b,"registerMesh",(t,e,s,o,r,n)=>{var i;y&&console.log("> Progressive: register mesh",r,s.name,n,s.uuid,s);const l=s.geometry;if(!l){y&&console.warn("gltf-progressive: Register mesh without geometry");return}l.userData||(l.userData={}),_.assignLODInformation(t,l,e,o,r,n.density),_.lodInfos.set(e,n);let u=_.lowresCache.get(e);u?u.push(s.geometry):u=[s.geometry],_.lowresCache.set(e,u),o>0&&!ae(s)&&Ee(s,l);for(const a of $)(i=a.onRegisteredNewMesh)==null||i.call(a,s,n)}),d(b,"lodInfos",new Map),d(b,"previouslyLoaded",new Map),d(b,"lowresCache",new Map);class tt{constructor(e,s,o,r,n){d(this,"url"),d(this,"key"),d(this,"level"),d(this,"index"),d(this,"density"),this.url=e,this.key=s,this.level=o,r!=null&&(this.index=r),n!=null&&(this.density=n)}}const B=Z("debugprogressive"),st=Z("noprogressive"),De=Symbol("Needle:LODSManager"),we=Symbol("Needle:LODState"),K=Symbol("Needle:CurrentLOD"),k={mesh_lod:-1,texture_lod:-1};var E,z,_e,H,se,ue,V;const P=class{constructor(t,e){d(this,"context"),d(this,"renderer"),d(this,"projectionScreenMatrix",new Se),d(this,"cameraFrustrum",new Ne),d(this,"targetTriangleDensity",2e5),d(this,"updateInterval","auto"),q(this,E,1),d(this,"pause",!1),d(this,"_lodchangedlisteners",[]),q(this,z,void 0),q(this,_e,new $e),q(this,H,0),q(this,se,0),q(this,ue,0),q(this,V,0),d(this,"_fpsBuffer",[60,60,60,60,60]),d(this,"_sphere",new Ve),d(this,"_tempBox",new Te),d(this,"_tempBox2",new Te),d(this,"tempMatrix",new Se),d(this,"_tempWorldPosition",new W),d(this,"_tempBoxSize",new W),d(this,"_tempBox2Size",new W),this.renderer=t,this.context={...e}}static getObjectLODState(t){return t[we]}static addPlugin(t){$.push(t)}static removePlugin(t){const e=$.indexOf(t);e>=0&&$.splice(e,1)}static get(t,e){if(t[De])return console.debug("[gltf-progressive] LODsManager already exists for this renderer"),t[De];const s=new P(t,{engine:"unknown",...e});return t[De]=s,s}get plugins(){return $}addEventListener(t,e){t==="changed"&&this._lodchangedlisteners.push(e)}enable(){if(x(this,z))return;console.debug("[gltf-progressive] Enabling LODsManager for renderer");let t=0;F(this,z,this.renderer.render);const e=this;ve(this.renderer),this.renderer.render=function(s,o){e.renderer.getRenderTarget()==null&&(t=0,F(e,H,x(e,H)+1),F(e,se,x(e,_e).getDelta()),F(e,ue,x(e,ue)+x(e,se)),e._fpsBuffer.shift(),e._fpsBuffer.push(1/x(e,se)),F(e,V,e._fpsBuffer.reduce((i,l)=>i+l)/e._fpsBuffer.length),B&&x(e,H)%30===0&&console.log("FPS",Math.round(x(e,V)),"Interval:",x(e,E)));const r=x(e,H),n=t++;e.onBeforeRender(s,o,n,r),x(e,z).call(this,s,o),e.onAfterRender(s,o,n,r)}}disable(){x(this,z)&&(this.renderer.render=x(this,z),F(this,z,void 0))}onBeforeRender(t,e,s,o){}onAfterRender(t,e,s,o){var r,n;if(this.pause)return;const i=this.renderer.renderLists.get(t,0),l=i.opaque;let u=!0;if(l.length===1){const a=l[0].material;(a.name==="EffectMaterial"||a.name==="CopyShader")&&(u=!1)}if((e.parent&&e.parent.type==="CubeCamera"||s>=1&&e.type==="OrthographicCamera")&&(u=!1),u){if(st||(this.updateInterval==="auto"?x(this,V)<40&&x(this,E)<10?(F(this,E,x(this,E)+1),B&&console.warn("\u2193 Reducing LOD updates",x(this,E),x(this,V).toFixed(0))):x(this,V)>=60&&x(this,E)>1&&(F(this,E,x(this,E)-1),B&&console.warn("\u2191 Increasing LOD updates",x(this,E),x(this,V).toFixed(0))):F(this,E,this.updateInterval),x(this,E)>0&&o%x(this,E)!=0))return;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse),this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix,this.renderer.coordinateSystem);const a=this.targetTriangleDensity;for(const c of l){if(c.material&&(((r=c.geometry)==null?void 0:r.type)==="BoxGeometry"||((n=c.geometry)==null?void 0:n.type)==="BufferGeometry")&&(c.material.name==="SphericalGaussianBlur"||c.material.name=="BackgroundCubeMaterial"||c.material.name==="CubemapFromEquirect"||c.material.name==="EquirectangularToCubeUV")){B&&(c.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(c.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",c,c.material.name,c.material.type)));continue}switch(c.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}if(B==="color"&&c.material&&!c.object.progressive_debug_color){c.object.progressive_debug_color=!0;const D=Math.random()*16777215,T=new ze({color:D});c.object.material=T}const L=c.object;(L instanceof X||L.isMesh)&&this.updateLODs(t,e,L,a,o)}const m=i.transparent;for(const c of m){const L=c.object;(L instanceof X||L.isMesh)&&this.updateLODs(t,e,L,a,o)}const v=i.transmissive;for(const c of v){const L=c.object;(L instanceof X||L.isMesh)&&this.updateLODs(t,e,L,a,o)}}}updateLODs(t,e,s,o,r){var n,i;s.userData||(s.userData={});let l=s[we];if(l||(l=new rt,s[we]=l),l.frames++<2)return;for(const a of $)(n=a.onBeforeUpdateLOD)==null||n.call(a,this.renderer,t,e,s);this.calculateLodLevel(e,s,l,o,k),k.mesh_lod=Math.round(k.mesh_lod),k.texture_lod=Math.round(k.texture_lod),k.mesh_lod>=0&&this.loadProgressiveMeshes(s,k.mesh_lod);let u=k.texture_lod;if(s.material&&u>=0){const a=s["DEBUG:LOD"];a!=null&&(u=a),this.loadProgressiveTextures(s.material,u)}for(const a of $)(i=a.onAfterUpdatedLOD)==null||i.call(a,this.renderer,t,e,s,k);l.lastLodLevel_Mesh=k.mesh_lod,l.lastLodLevel_Texture=k.texture_lod}loadProgressiveTextures(t,e){if(!t)return;if(Array.isArray(t)){for(const o of t)this.loadProgressiveTextures(o,e);return}let s=!1;(t[K]===void 0||e<t[K])&&(s=!0),s&&(t[K]=e,b.assignTextureLOD(t,e).then(o=>{this._lodchangedlisteners.forEach(r=>r({type:"texture",level:e,object:t}))}))}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);if(t[K]!==e){t[K]=e;const s=t.geometry;return b.assignMeshLOD(t,e).then(o=>(o&&t[K]==e&&s!=t.geometry&&this._lodchangedlisteners.forEach(r=>r({type:"mesh",level:e,object:t})),o))}return Promise.resolve(null)}static isInside(t,e){const s=t.min,o=t.max,r=(s.x+o.x)*.5,n=(s.y+o.y)*.5;return this._tempPtInside.set(r,n,s.z).applyMatrix4(e).z<0}calculateLodLevel(t,e,s,o,r){var n,i;if(!e){r.mesh_lod=-1,r.texture_lod=-1;return}if(!t){r.mesh_lod=-1,r.texture_lod=-1;return}let l=10+1,u=!1;if(B&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const a=b.getMeshLODInformation(e.geometry),m=a?.lods,v=m&&m.length>0,c=b.getMaterialMinMaxLODsCount(e.material),L=c?.min_count!=1/0&&c.min_count>0&&c.max_count>0;if(!v&&!L){r.mesh_lod=0,r.texture_lod=0;return}if(v||(u=!0,l=0),!((n=this.cameraFrustrum)!=null&&n.intersectsObject(e))){r.mesh_lod=99,r.texture_lod=99;return}const D=this.renderer.domElement.clientHeight||this.renderer.domElement.height;let T=e.geometry.boundingBox;if(e.type==="SkinnedMesh"){const g=e;g.boundingBox||g.computeBoundingBox(),T=g.boundingBox}if(T&&t.isPerspectiveCamera){const g=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 f=t.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(f)){r.mesh_lod=0,r.texture_lod=0;return}}if(this._tempBox.copy(T),this._tempBox.applyMatrix4(e.matrixWorld),P.isInside(this._tempBox,this.projectionScreenMatrix)){r.mesh_lod=0,r.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&g.fov>70){const f=this._tempBox.min,h=this._tempBox.max;let M=f.x,O=f.y,S=h.x,N=h.y;const U=2,he=1.5,re=(f.x+h.x)*.5,ne=(f.y+h.y)*.5;M=(M-re)*U+re,O=(O-ne)*U+ne,S=(S-re)*U+re,N=(N-ne)*U+ne;const Ce=M<0&&S>0?0:Math.min(Math.abs(f.x),Math.abs(h.x)),je=O<0&&N>0?0:Math.min(Math.abs(f.y),Math.abs(h.y)),fe=Math.max(Ce,je);s.lastCentrality=(he-fe)*(he-fe)*(he-fe)}else s.lastCentrality=1;const p=this._tempBox.getSize(this._tempBoxSize);p.multiplyScalar(.5),screen.availHeight>0&&D>0&&p.multiplyScalar(D/screen.availHeight),p.x*=g.aspect;const A=t.matrixWorldInverse,C=this._tempBox2;C.copy(T),C.applyMatrix4(e.matrixWorld),C.applyMatrix4(A);const w=C.getSize(this._tempBox2Size),G=Math.max(w.x,w.y);if(Math.max(p.x,p.y)!=0&&G!=0&&(p.z=w.z/Math.max(w.x,w.y)*Math.max(p.x,p.y)),s.lastScreenCoverage=Math.max(p.x,p.y,p.z),s.lastScreenspaceVolume.copy(p),s.lastScreenCoverage*=s.lastCentrality,B&&P.debugDrawLine){const f=this.tempMatrix.copy(this.projectionScreenMatrix);f.invert();const h=P.corner0,M=P.corner1,O=P.corner2,S=P.corner3;h.copy(this._tempBox.min),M.copy(this._tempBox.max),M.x=h.x,O.copy(this._tempBox.max),O.y=h.y,S.copy(this._tempBox.max);const N=(h.z+S.z)*.5;h.z=M.z=O.z=S.z=N,h.applyMatrix4(f),M.applyMatrix4(f),O.applyMatrix4(f),S.applyMatrix4(f),P.debugDrawLine(h,M,255),P.debugDrawLine(h,O,255),P.debugDrawLine(M,S,255),P.debugDrawLine(O,S,255)}let I=999;if(m&&s.lastScreenCoverage>0){for(let f=0;f<m.length;f++)if(m[f].density/s.lastScreenCoverage<o){I=f;break}}I<l&&(l=I,u=!0)}if(u?r.mesh_lod=l:r.mesh_lod=s.lastLodLevel_Mesh,B&&r.mesh_lod!=s.lastLodLevel_Mesh){const g=m?.[r.mesh_lod];g&&console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} \u2192 ${r.mesh_lod} (${g.density.toFixed(0)}) - ${e.name}`)}if(L){const g="saveData"in globalThis.navigator&&globalThis.navigator.saveData===!0;if(s.lastLodLevel_Texture<0){if(r.texture_lod=c.max_count-1,B){const p=c.lods[c.max_count-1];B&&console.log(`First Texture LOD ${r.texture_lod} (${p.max_height}px) - ${e.name}`)}}else{const p=s.lastScreenspaceVolume.x+s.lastScreenspaceVolume.y+s.lastScreenspaceVolume.z;let A=s.lastScreenCoverage*2;((i=this.context)==null?void 0:i.engine)==="model-viewer"&&(A*=2);const C=D/window.devicePixelRatio*A;for(let w=c.lods.length-1;w>=0;w--){let G=c.lods[w];if(!(g&&G.max_height>=2048)&&!(Qe()&&G.max_height>4096)&&G.max_height>C){if(r.texture_lod=w,r.texture_lod<s.lastLodLevel_Texture){const I=G.max_height;B&&console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} \u2192 ${r.texture_lod} = ${I}px
5
+ `,e.uuid),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}};let b=_;d(b,"registerTexture",(t,e,s,o,r)=>{if(y&&console.log("> Progressive: register texture",o,e.name,e.uuid,e,r),!e){y&&console.error("gltf-progressive: Register texture without texture");return}e.source&&(e.source[Le]=r);const n=r.guid;_.assignLODInformation(t,e,n,s,o,void 0),_.lodInfos.set(n,r),_.lowresCache.set(n,e)}),d(b,"registerMesh",(t,e,s,o,r,n)=>{var i;y&&console.log("> Progressive: register mesh",r,s.name,n,s.uuid,s);const l=s.geometry;if(!l){y&&console.warn("gltf-progressive: Register mesh without geometry");return}l.userData||(l.userData={}),_.assignLODInformation(t,l,e,o,r,n.density),_.lodInfos.set(e,n);let u=_.lowresCache.get(e);u?u.push(s.geometry):u=[s.geometry],_.lowresCache.set(e,u),o>0&&!ue(s)&&Ee(s,l);for(const a of $)(i=a.onRegisteredNewMesh)==null||i.call(a,s,n)}),d(b,"lodInfos",new Map),d(b,"previouslyLoaded",new Map),d(b,"lowresCache",new Map);class tt{constructor(e,s,o,r,n){d(this,"url"),d(this,"key"),d(this,"level"),d(this,"index"),d(this,"density"),this.url=e,this.key=s,this.level=o,r!=null&&(this.index=r),n!=null&&(this.density=n)}}const k=Z("debugprogressive"),st=Z("noprogressive"),De=Symbol("Needle:LODSManager"),we=Symbol("Needle:LODState"),Y=Symbol("Needle:CurrentLOD"),B={mesh_lod:-1,texture_lod:-1};var E,z,_e,J,se,ce,V;const P=class{constructor(t,e){d(this,"context"),d(this,"renderer"),d(this,"projectionScreenMatrix",new Se),d(this,"cameraFrustrum",new Ne),d(this,"targetTriangleDensity",2e5),d(this,"updateInterval","auto"),q(this,E,1),d(this,"pause",!1),d(this,"_lodchangedlisteners",[]),q(this,z,void 0),q(this,_e,new $e),q(this,J,0),q(this,se,0),q(this,ce,0),q(this,V,0),d(this,"_fpsBuffer",[60,60,60,60,60]),d(this,"_sphere",new Ve),d(this,"_tempBox",new Te),d(this,"_tempBox2",new Te),d(this,"tempMatrix",new Se),d(this,"_tempWorldPosition",new W),d(this,"_tempBoxSize",new W),d(this,"_tempBox2Size",new W),this.renderer=t,this.context={...e}}static getObjectLODState(t){return t[we]}static addPlugin(t){$.push(t)}static removePlugin(t){const e=$.indexOf(t);e>=0&&$.splice(e,1)}static get(t,e){if(t[De])return console.debug("[gltf-progressive] LODsManager already exists for this renderer"),t[De];const s=new P(t,{engine:"unknown",...e});return t[De]=s,s}get plugins(){return $}addEventListener(t,e){t==="changed"&&this._lodchangedlisteners.push(e)}enable(){if(v(this,z))return;console.debug("[gltf-progressive] Enabling LODsManager for renderer");let t=0;F(this,z,this.renderer.render);const e=this;xe(this.renderer),this.renderer.render=function(s,o){e.renderer.getRenderTarget()==null&&(t=0,F(e,J,v(e,J)+1),F(e,se,v(e,_e).getDelta()),F(e,ce,v(e,ce)+v(e,se)),e._fpsBuffer.shift(),e._fpsBuffer.push(1/v(e,se)),F(e,V,e._fpsBuffer.reduce((i,l)=>i+l)/e._fpsBuffer.length),k&&v(e,J)%30===0&&console.log("FPS",Math.round(v(e,V)),"Interval:",v(e,E)));const r=v(e,J),n=t++;e.onBeforeRender(s,o,n,r),v(e,z).call(this,s,o),e.onAfterRender(s,o,n,r)}}disable(){v(this,z)&&(this.renderer.render=v(this,z),F(this,z,void 0))}onBeforeRender(t,e,s,o){}onAfterRender(t,e,s,o){var r,n;if(this.pause)return;const i=this.renderer.renderLists.get(t,0),l=i.opaque;let u=!0;if(l.length===1){const a=l[0].material;(a.name==="EffectMaterial"||a.name==="CopyShader")&&(u=!1)}if((e.parent&&e.parent.type==="CubeCamera"||s>=1&&e.type==="OrthographicCamera")&&(u=!1),u){if(st||(this.updateInterval==="auto"?v(this,V)<40&&v(this,E)<10?(F(this,E,v(this,E)+1),k&&console.warn("\u2193 Reducing LOD updates",v(this,E),v(this,V).toFixed(0))):v(this,V)>=60&&v(this,E)>1&&(F(this,E,v(this,E)-1),k&&console.warn("\u2191 Increasing LOD updates",v(this,E),v(this,V).toFixed(0))):F(this,E,this.updateInterval),v(this,E)>0&&o%v(this,E)!=0))return;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse),this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix,this.renderer.coordinateSystem);const a=this.targetTriangleDensity;for(const c of l){if(c.material&&(((r=c.geometry)==null?void 0:r.type)==="BoxGeometry"||((n=c.geometry)==null?void 0:n.type)==="BufferGeometry")&&(c.material.name==="SphericalGaussianBlur"||c.material.name=="BackgroundCubeMaterial"||c.material.name==="CubemapFromEquirect"||c.material.name==="EquirectangularToCubeUV")){k&&(c.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(c.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",c,c.material.name,c.material.type)));continue}switch(c.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}if(k==="color"&&c.material&&!c.object.progressive_debug_color){c.object.progressive_debug_color=!0;const D=Math.random()*16777215,T=new ze({color:D});c.object.material=T}const L=c.object;(L instanceof X||L.isMesh)&&this.updateLODs(t,e,L,a,o)}const m=i.transparent;for(const c of m){const L=c.object;(L instanceof X||L.isMesh)&&this.updateLODs(t,e,L,a,o)}const x=i.transmissive;for(const c of x){const L=c.object;(L instanceof X||L.isMesh)&&this.updateLODs(t,e,L,a,o)}}}updateLODs(t,e,s,o,r){var n,i;s.userData||(s.userData={});let l=s[we];if(l||(l=new rt,s[we]=l),l.frames++<2)return;for(const a of $)(n=a.onBeforeUpdateLOD)==null||n.call(a,this.renderer,t,e,s);this.calculateLodLevel(e,s,l,o,B),B.mesh_lod=Math.round(B.mesh_lod),B.texture_lod=Math.round(B.texture_lod),B.mesh_lod>=0&&this.loadProgressiveMeshes(s,B.mesh_lod);let u=B.texture_lod;if(s.material&&u>=0){const a=s["DEBUG:LOD"];a!=null&&(u=a),this.loadProgressiveTextures(s.material,u)}for(const a of $)(i=a.onAfterUpdatedLOD)==null||i.call(a,this.renderer,t,e,s,B);l.lastLodLevel_Mesh=B.mesh_lod,l.lastLodLevel_Texture=B.texture_lod}loadProgressiveTextures(t,e){if(!t)return;if(Array.isArray(t)){for(const o of t)this.loadProgressiveTextures(o,e);return}let s=!1;(t[Y]===void 0||e<t[Y])&&(s=!0),s&&(t[Y]=e,b.assignTextureLOD(t,e).then(o=>{this._lodchangedlisteners.forEach(r=>r({type:"texture",level:e,object:t}))}))}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);if(t[Y]!==e){t[Y]=e;const s=t.geometry;return b.assignMeshLOD(t,e).then(o=>(o&&t[Y]==e&&s!=t.geometry&&this._lodchangedlisteners.forEach(r=>r({type:"mesh",level:e,object:t})),o))}return Promise.resolve(null)}static isInside(t,e){const s=t.min,o=t.max,r=(s.x+o.x)*.5,n=(s.y+o.y)*.5;return this._tempPtInside.set(r,n,s.z).applyMatrix4(e).z<0}calculateLodLevel(t,e,s,o,r){var n,i;if(!e){r.mesh_lod=-1,r.texture_lod=-1;return}if(!t){r.mesh_lod=-1,r.texture_lod=-1;return}let l=10+1,u=!1;if(k&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const a=b.getMeshLODInformation(e.geometry),m=a?.lods,x=m&&m.length>0,c=b.getMaterialMinMaxLODsCount(e.material),L=c?.min_count!=1/0&&c.min_count>0&&c.max_count>0;if(!x&&!L){r.mesh_lod=0,r.texture_lod=0;return}if(x||(u=!0,l=0),!((n=this.cameraFrustrum)!=null&&n.intersectsObject(e))){r.mesh_lod=99,r.texture_lod=99;return}const D=this.renderer.domElement.clientHeight||this.renderer.domElement.height;let T=e.geometry.boundingBox;if(e.type==="SkinnedMesh"){const f=e;f.boundingBox||f.computeBoundingBox(),T=f.boundingBox}if(T&&t.isPerspectiveCamera){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 g=t.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(g)){r.mesh_lod=0,r.texture_lod=0;return}}if(this._tempBox.copy(T),this._tempBox.applyMatrix4(e.matrixWorld),P.isInside(this._tempBox,this.projectionScreenMatrix)){r.mesh_lod=0,r.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&f.fov>70){const g=this._tempBox.min,h=this._tempBox.max;let M=g.x,O=g.y,S=h.x,N=h.y;const U=2,ge=1.5,re=(g.x+h.x)*.5,ne=(g.y+h.y)*.5;M=(M-re)*U+re,O=(O-ne)*U+ne,S=(S-re)*U+re,N=(N-ne)*U+ne;const Ce=M<0&&S>0?0:Math.min(Math.abs(g.x),Math.abs(h.x)),je=O<0&&N>0?0:Math.min(Math.abs(g.y),Math.abs(h.y)),fe=Math.max(Ce,je);s.lastCentrality=(ge-fe)*(ge-fe)*(ge-fe)}else s.lastCentrality=1;const p=this._tempBox.getSize(this._tempBoxSize);p.multiplyScalar(.5),screen.availHeight>0&&D>0&&p.multiplyScalar(D/screen.availHeight),p.x*=f.aspect;const A=t.matrixWorldInverse,C=this._tempBox2;C.copy(T),C.applyMatrix4(e.matrixWorld),C.applyMatrix4(A);const w=C.getSize(this._tempBox2Size),G=Math.max(w.x,w.y);if(Math.max(p.x,p.y)!=0&&G!=0&&(p.z=w.z/Math.max(w.x,w.y)*Math.max(p.x,p.y)),s.lastScreenCoverage=Math.max(p.x,p.y,p.z),s.lastScreenspaceVolume.copy(p),s.lastScreenCoverage*=s.lastCentrality,k&&P.debugDrawLine){const g=this.tempMatrix.copy(this.projectionScreenMatrix);g.invert();const h=P.corner0,M=P.corner1,O=P.corner2,S=P.corner3;h.copy(this._tempBox.min),M.copy(this._tempBox.max),M.x=h.x,O.copy(this._tempBox.max),O.y=h.y,S.copy(this._tempBox.max);const N=(h.z+S.z)*.5;h.z=M.z=O.z=S.z=N,h.applyMatrix4(g),M.applyMatrix4(g),O.applyMatrix4(g),S.applyMatrix4(g),P.debugDrawLine(h,M,255),P.debugDrawLine(h,O,255),P.debugDrawLine(M,S,255),P.debugDrawLine(O,S,255)}let I=999;if(m&&s.lastScreenCoverage>0){for(let g=0;g<m.length;g++)if(m[g].density/s.lastScreenCoverage<o){I=g;break}}I<l&&(l=I,u=!0)}if(u?r.mesh_lod=l:r.mesh_lod=s.lastLodLevel_Mesh,k&&r.mesh_lod!=s.lastLodLevel_Mesh){const f=m?.[r.mesh_lod];f&&console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} \u2192 ${r.mesh_lod} (${f.density.toFixed(0)}) - ${e.name}`)}if(L){const f="saveData"in globalThis.navigator&&globalThis.navigator.saveData===!0;if(s.lastLodLevel_Texture<0){if(r.texture_lod=c.max_count-1,k){const p=c.lods[c.max_count-1];k&&console.log(`First Texture LOD ${r.texture_lod} (${p.max_height}px) - ${e.name}`)}}else{const p=s.lastScreenspaceVolume.x+s.lastScreenspaceVolume.y+s.lastScreenspaceVolume.z;let A=s.lastScreenCoverage*2;((i=this.context)==null?void 0:i.engine)==="model-viewer"&&(A*=2);const C=D/window.devicePixelRatio*A;for(let w=c.lods.length-1;w>=0;w--){let G=c.lods[w];if(!(f&&G.max_height>=2048)&&!(Qe()&&G.max_height>4096)&&G.max_height>C){if(r.texture_lod=w,r.texture_lod<s.lastLodLevel_Texture){const I=G.max_height;k&&console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} \u2192 ${r.texture_lod} = ${I}px
6
6
  Screensize: ${C.toFixed(0)}px, Coverage: ${(100*s.lastScreenCoverage).toFixed(2)}%, Volume ${p.toFixed(1)}
7
- ${e.name}`)}break}}}}else r.texture_lod=0}};let R=P;E=new WeakMap,z=new WeakMap,_e=new WeakMap,H=new WeakMap,se=new WeakMap,ue=new WeakMap,V=new WeakMap,d(R,"debugDrawLine"),d(R,"corner0",new W),d(R,"corner1",new W),d(R,"corner2",new W),d(R,"corner3",new W),d(R,"_tempPtInside",new W);class rt{constructor(){d(this,"frames",0),d(this,"lastLodLevel_Mesh",-1),d(this,"lastLodLevel_Texture",-1),d(this,"lastScreenCoverage",0),d(this,"lastScreenspaceVolume",new W),d(this,"lastCentrality",0)}}const Ie=Symbol("NEEDLE_mesh_lod"),ce=Symbol("NEEDLE_texture_lod");let de=null;function Oe(){const t=nt();t&&(t.mapURLs(function(e){return Pe(),e}),Pe(),de?.disconnect(),de=new MutationObserver(e=>{e.forEach(s=>{s.addedNodes.forEach(o=>{o instanceof HTMLElement&&o.tagName.toLowerCase()==="model-viewer"&&ke(o)})})}),de.observe(document,{childList:!0,subtree:!0}))}function nt(){return customElements.get("model-viewer")||(customElements.whenDefined("model-viewer").then(()=>{console.debug("[gltf-progressive] model-viewer defined"),Oe()}),null)}function Pe(){document.querySelectorAll("model-viewer").forEach(t=>{ke(t)})}const Be=new WeakSet;let ot=0;function ke(t){if(!t||Be.has(t))return null;Be.add(t),console.debug("[gltf-progressive] found new model-viewer..."+ ++ot+`
8
- `,t.getAttribute("src"));let e=null,s=null,o=null;for(let r=t;r!=null;r=Object.getPrototypeOf(r)){const n=Object.getOwnPropertySymbols(r),i=n.find(a=>a.toString()=="Symbol(renderer)"),l=n.find(a=>a.toString()=="Symbol(scene)"),u=n.find(a=>a.toString()=="Symbol(needsRender)");!e&&i!=null&&(e=t[i].threeRenderer),!s&&l!=null&&(s=t[l]),!o&&u!=null&&(o=t[u])}if(e&&s){let r=function(){if(o){let i=0,l=setInterval(()=>{if(i++>5){clearInterval(l);return}o?.call(t)},300)}};console.debug("[gltf-progressive] setup model-viewer");const n=R.get(e,{engine:"model-viewer"});return R.addPlugin(new it),n.enable(),n.addEventListener("changed",()=>{o?.call(t)}),t.addEventListener("model-visibility",i=>{i.detail.visible&&o?.call(t)}),t.addEventListener("load",()=>{r()}),()=>{n.disable()}}return null}class it{constructor(){d(this,"_didWarnAboutMissingUrl",!1)}onBeforeUpdateLOD(e,s,o,r){this.tryParseMeshLOD(s,r),this.tryParseTextureLOD(s,r)}getUrl(e){if(!e)return null;let s=e.getAttribute("src");return s||(s=e.src),s||(this._didWarnAboutMissingUrl||console.warn("No url found in modelviewer",e),this._didWarnAboutMissingUrl=!0),s}tryGetCurrentGLTF(e){return e._currentGLTF}tryGetCurrentModelViewer(e){return e.element}tryParseTextureLOD(e,s){if(s[ce]==!0)return;s[ce]=!0;const o=this.tryGetCurrentGLTF(e),r=this.tryGetCurrentModelViewer(e),n=this.getUrl(r);if(n&&o&&s.material){let i=function(u){var a,m,v;if(u[ce]==!0)return;u[ce]=!0,u.userData&&(u.userData.LOD=-1);const c=Object.keys(u);for(let L=0;L<c.length;L++){const D=c[L],T=u[D];if(T?.isTexture===!0){const g=(m=(a=T.userData)==null?void 0:a.associations)==null?void 0:m.textures;if(g==null)continue;const p=o.parser.json.textures[g];if(!p){console.warn("Texture data not found for texture index "+g);continue}if((v=p?.extensions)!=null&&v[j]){const A=p.extensions[j];A&&n&&b.registerTexture(n,T,A.lods.length,g,A)}}}};const l=s.material;if(Array.isArray(l))for(const u of l)i(u);else i(l)}}tryParseMeshLOD(e,s){var o,r;if(s[Ie]==!0)return;s[Ie]=!0;const n=this.tryGetCurrentModelViewer(e),i=this.getUrl(n);if(!i)return;const l=(r=(o=s.userData)==null?void 0:o.gltfExtensions)==null?void 0:r[j];if(l&&i){const u=s.uuid;b.registerMesh(i,u,s,0,l.lods.length,l)}}}function lt(t,e,s,o){ve(e),xe(s),s.register(n=>new b(n,t));const r=R.get(e);return o?.enableLODsManager!==!1&&r.enable(),r}Oe();export{j as EXTENSION_NAME,R as LODsManager,b as NEEDLE_progressive,ge as VERSION,xe as addDracoAndKTX2Loaders,ve as createLoaders,ae as getRaycastMesh,Oe as patchModelViewer,Ee as registerRaycastMesh,He as setDracoDecoderLocation,Ye as setKTX2TranscoderLocation,lt as useNeedleProgressive,Ze as useRaycastMeshes};
7
+ ${e.name}`)}break}}}}else r.texture_lod=0}};let R=P;E=new WeakMap,z=new WeakMap,_e=new WeakMap,J=new WeakMap,se=new WeakMap,ce=new WeakMap,V=new WeakMap,d(R,"debugDrawLine"),d(R,"corner0",new W),d(R,"corner1",new W),d(R,"corner2",new W),d(R,"corner3",new W),d(R,"_tempPtInside",new W);class rt{constructor(){d(this,"frames",0),d(this,"lastLodLevel_Mesh",-1),d(this,"lastLodLevel_Texture",-1),d(this,"lastScreenCoverage",0),d(this,"lastScreenspaceVolume",new W),d(this,"lastCentrality",0)}}const Ie=Symbol("NEEDLE_mesh_lod"),de=Symbol("NEEDLE_texture_lod");let he=null;function Oe(){const t=nt();t&&(t.mapURLs(function(e){return Pe(),e}),Pe(),he?.disconnect(),he=new MutationObserver(e=>{e.forEach(s=>{s.addedNodes.forEach(o=>{o instanceof HTMLElement&&o.tagName.toLowerCase()==="model-viewer"&&Be(o)})})}),he.observe(document,{childList:!0,subtree:!0}))}function nt(){return customElements.get("model-viewer")||(customElements.whenDefined("model-viewer").then(()=>{console.debug("[gltf-progressive] model-viewer defined"),Oe()}),null)}function Pe(){document.querySelectorAll("model-viewer").forEach(t=>{Be(t)})}const ke=new WeakSet;let ot=0;function Be(t){if(!t||ke.has(t))return null;ke.add(t),console.debug("[gltf-progressive] found new model-viewer..."+ ++ot+`
8
+ `,t.getAttribute("src"));let e=null,s=null,o=null;for(let r=t;r!=null;r=Object.getPrototypeOf(r)){const n=Object.getOwnPropertySymbols(r),i=n.find(a=>a.toString()=="Symbol(renderer)"),l=n.find(a=>a.toString()=="Symbol(scene)"),u=n.find(a=>a.toString()=="Symbol(needsRender)");!e&&i!=null&&(e=t[i].threeRenderer),!s&&l!=null&&(s=t[l]),!o&&u!=null&&(o=t[u])}if(e&&s){let r=function(){if(o){let i=0,l=setInterval(()=>{if(i++>5){clearInterval(l);return}o?.call(t)},300)}};console.debug("[gltf-progressive] setup model-viewer");const n=R.get(e,{engine:"model-viewer"});return R.addPlugin(new it),n.enable(),n.addEventListener("changed",()=>{o?.call(t)}),t.addEventListener("model-visibility",i=>{i.detail.visible&&o?.call(t)}),t.addEventListener("load",()=>{r()}),()=>{n.disable()}}return null}class it{constructor(){d(this,"_didWarnAboutMissingUrl",!1)}onBeforeUpdateLOD(e,s,o,r){this.tryParseMeshLOD(s,r),this.tryParseTextureLOD(s,r)}getUrl(e){if(!e)return null;let s=e.getAttribute("src");return s||(s=e.src),s||(this._didWarnAboutMissingUrl||console.warn("No url found in modelviewer",e),this._didWarnAboutMissingUrl=!0),s}tryGetCurrentGLTF(e){return e._currentGLTF}tryGetCurrentModelViewer(e){return e.element}tryParseTextureLOD(e,s){if(s[de]==!0)return;s[de]=!0;const o=this.tryGetCurrentGLTF(e),r=this.tryGetCurrentModelViewer(e),n=this.getUrl(r);if(n&&o&&s.material){let i=function(u){var a,m,x;if(u[de]==!0)return;u[de]=!0,u.userData&&(u.userData.LOD=-1);const c=Object.keys(u);for(let L=0;L<c.length;L++){const D=c[L],T=u[D];if(T?.isTexture===!0){const f=(m=(a=T.userData)==null?void 0:a.associations)==null?void 0:m.textures;if(f==null)continue;const p=o.parser.json.textures[f];if(!p){console.warn("Texture data not found for texture index "+f);continue}if((x=p?.extensions)!=null&&x[j]){const A=p.extensions[j];A&&n&&b.registerTexture(n,T,A.lods.length,f,A)}}}};const l=s.material;if(Array.isArray(l))for(const u of l)i(u);else i(l)}}tryParseMeshLOD(e,s){var o,r;if(s[Ie]==!0)return;s[Ie]=!0;const n=this.tryGetCurrentModelViewer(e),i=this.getUrl(n);if(!i)return;const l=(r=(o=s.userData)==null?void 0:o.gltfExtensions)==null?void 0:r[j];if(l&&i){const u=s.uuid;b.registerMesh(i,u,s,0,l.lods.length,l)}}}function lt(t,e,s,o){xe(e),ve(s),s.register(n=>new b(n,t));const r=R.get(e);return o?.enableLODsManager!==!1&&r.enable(),r}Oe();export{j as EXTENSION_NAME,R as LODsManager,b as NEEDLE_progressive,me as VERSION,ve as addDracoAndKTX2Loaders,xe as createLoaders,ue as getRaycastMesh,Oe as patchModelViewer,Ee as registerRaycastMesh,He as setDracoDecoderLocation,Ye as setKTX2TranscoderLocation,lt as useNeedleProgressive,Ze as useRaycastMeshes};
@@ -1,8 +1,8 @@
1
- "use strict";var Re=Object.defineProperty;var Ge=(a,t,e)=>t in a?Re(a,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):a[t]=e;var f=(a,t,e)=>(Ge(a,typeof t!="symbol"?t+"":t,e),e),be=(a,t,e)=>{if(!t.has(a))throw TypeError("Cannot "+e)};var L=(a,t,e)=>(be(a,t,"read from private field"),e?e.call(a):t.get(a)),X=(a,t,e)=>{if(t.has(a))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(a):t.set(a,e)},V=(a,t,e,r)=>(be(a,t,"write to private field"),r?r.call(a,e):t.set(a,e),e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("three"),Fe=require("three/examples/jsm/loaders/GLTFLoader.js"),Ve=require("three/examples/jsm/libs/meshopt_decoder.module.js"),$e=require("three/examples/jsm/loaders/DRACOLoader.js"),Ne=require("three/examples/jsm/loaders/KTX2Loader.js"),we="";globalThis.GLTF_PROGRESSIVE_VERSION=we;console.debug(`[gltf-progressive] version ${we}`);let ue="https://www.gstatic.com/draco/versioned/decoders/1.4.1/",ve="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";fetch(ue+"draco_decoder.js",{method:"head"}).catch(a=>{ue="./include/draco/",ve="./include/ktx2/"});function ze(a){ue=a}function Ue(a){ve=a}let re,Le,se;function _e(a){re||(re=new $e.DRACOLoader,re.setDecoderPath(ue),re.setDecoderConfig({type:"js"})),se||(se=new Ne.KTX2Loader,se.setTranscoderPath(ve)),Le||(Le=Ve.MeshoptDecoder),a?se.detectSupport(a):console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures will probably fail")}function Oe(a){a.dracoLoader||a.setDRACOLoader(re),a.ktx2Loader||a.setKTX2Loader(se),a.meshoptDecoder||a.setMeshoptDecoder(Le)}oe("debugprogressive");function oe(a){const e=new URL(window.location.href).searchParams.get(a);return e==null||e==="0"||e==="false"?!1:e===""?!0:e}function We(a,t){if(t===void 0||t.startsWith("./")||t.startsWith("http")||a===void 0)return t;const e=a.lastIndexOf("/");if(e>=0){const r=a.substring(0,e+1);for(;r.endsWith("/")&&t.startsWith("/");)t=t.substring(1);return r+t}return t}let Z;function qe(){return Z!==void 0||(Z=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),oe("debugprogressive")&&console.log("[glTF Progressive]: isMobileDevice",Z)),Z}const Me=Symbol("needle:raycast-mesh");function he(a){return(a==null?void 0:a[Me])instanceof h.BufferGeometry?a[Me]:null}function Ce(a,t){if((a.type==="Mesh"||a.type==="SkinnedMesh")&&!he(a)){const r=Xe(t);r.userData={isRaycastMesh:!0},a[Me]=r}}function Ke(a=!0){if(a){if(ee)return;const t=ee=h.Mesh.prototype.raycast;h.Mesh.prototype.raycast=function(e,r){const o=this,i=he(o);let s;i&&o.isMesh&&(s=o.geometry,o.geometry=i),t.call(this,e,r),s&&(o.geometry=s)}}else{if(!ee)return;h.Mesh.prototype.raycast=ee,ee=null}}let ee=null;function Xe(a){const t=new h.BufferGeometry;for(const e in a.attributes)t.setAttribute(e,a.getAttribute(e));return t.setIndex(a.getIndex()),t}const Y=new Array,$="NEEDLE_progressive",D=oe("debugprogressive"),ye=Symbol("needle-progressive-texture"),ie=new Map,De=new Set;if(D){let a=function(){t+=1,console.log("Toggle LOD level",t,ie),ie.forEach((o,i)=>{for(const s of o.keys){const n=i[s];if(n!=null){if(n.isBufferGeometry===!0){const l=b.getMeshLODInformation(n),u=l?Math.min(t,l.lods.length):0;i["DEBUG:LOD"]=t,b.assignMeshLOD(i,u),l&&(e=Math.max(e,l.lods.length-1))}else if(i.isMaterial===!0){i["DEBUG:LOD"]=t,b.assignTextureLOD(i,t);break}}}}),t>=e&&(t=-1)},t=-1,e=2,r=!1;window.addEventListener("keyup",o=>{o.key==="p"&&a(),o.key==="w"&&(r=!r,De&&De.forEach(i=>{i.name!="BackgroundCubeMaterial"&&i.glyphMap==null&&"wireframe"in i&&(i.wireframe=r)}))})}function Te(a,t,e){var o;if(!D)return;ie.has(a)||ie.set(a,{keys:[],sourceId:e});const r=ie.get(a);((o=r==null?void 0:r.keys)==null?void 0:o.includes(t))==!1&&r.keys.push(t)}const O=class{constructor(t,e){f(this,"parser");f(this,"url");f(this,"_isLoadingMesh");f(this,"loadMesh",t=>{var r,o;if(this._isLoadingMesh)return null;const e=(o=(r=this.parser.json.meshes[t])==null?void 0:r.extensions)==null?void 0:o[$];return e?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",t).then(i=>{var s;return this._isLoadingMesh=!1,i&&O.registerMesh(this.url,e.guid,i,(s=e.lods)==null?void 0:s.length,void 0,e),i})):null});D&&console.log("Progressive extension registered for",e),this.parser=t,this.url=e}get name(){return $}static getMeshLODInformation(t){const e=this.getAssignedLODInformation(t);return e!=null&&e.key?this.lodInfos.get(e.key):null}static getMaterialMinMaxLODsCount(t,e){const r=this,o="LODS:minmax",i=t[o];if(i!=null)return i;if(e||(e={min_count:1/0,max_count:0,lods:[]}),Array.isArray(t)){for(const n of t)this.getMaterialMinMaxLODsCount(n,e);return t[o]=e,e}if(D==="verbose"&&console.log("getMaterialMinMaxLODsCount",t),t.type==="ShaderMaterial"||t.type==="RawShaderMaterial"){const n=t;for(const l of Object.keys(n.uniforms)){const u=n.uniforms[l].value;(u==null?void 0:u.isTexture)===!0&&s(u,e)}}else if(t.isMaterial)for(const n of Object.keys(t)){const l=t[n];(l==null?void 0:l.isTexture)===!0&&s(l,e)}return t[o]=e,e;function s(n,l){const u=r.getAssignedLODInformation(n);if(u){const c=r.lodInfos.get(u.key);if(c&&c.lods){l.min_count=Math.min(l.min_count,c.lods.length),l.max_count=Math.max(l.max_count,c.lods.length);for(let w=0;w<c.lods.length;w++){const g=c.lods[w];g.width&&(l.lods[w]=l.lods[w]||{min_height:1/0,max_height:0},l.lods[w].min_height=Math.min(l.lods[w].min_height,g.height),l.lods[w].max_height=Math.max(l.lods[w].max_height,g.height))}}}}}static hasLODLevelAvailable(t,e){var i;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 n=t[s];if(n&&n.isTexture&&this.hasLODLevelAvailable(n,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,o;if(t.isMesh?r=t.geometry:(t.isBufferGeometry||t.isTexture)&&(r=t),r&&(i=r==null?void 0:r.userData)!=null&&i.LODS){const s=r.userData.LODS;if(o=this.lodInfos.get(s.key),e===void 0)return o!=null;if(o)return Array.isArray(o.lods)?e<o.lods.length:e===0}return!1}static assignMeshLOD(t,e){var r;if(!t)return Promise.resolve(null);if(t instanceof h.Mesh||t.isMesh===!0){const o=t.geometry,i=this.getAssignedLODInformation(o);if(!i)return Promise.resolve(null);for(const s of Y)(r=s.onBeforeGetLODMesh)==null||r.call(s,t,e);return t["LOD:requested level"]=e,O.getOrLoadLOD(o,e).then(s=>{if(t["LOD:requested level"]===e){if(delete t["LOD:requested level"],Array.isArray(s)){const n=i.index||0;s=s[n]}s&&o!=s&&((s==null?void 0:s.isBufferGeometry)?(t.geometry=s,D&&Te(t,"geometry",i.url)):D&&console.error("Invalid LOD geometry",s))}return s}).catch(s=>(console.error("Error loading mesh LOD",t,s),null))}else D&&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 instanceof h.Material||t.isMaterial===!0){const r=t,o=[],i=new Array;if(D&&De.add(r),r.uniforms&&r.isRawShaderMaterial||r.isShaderMaterial===!0){const s=r;for(const n of Object.keys(s.uniforms)){const l=s.uniforms[n].value;if((l==null?void 0:l.isTexture)===!0){const u=this.assignTextureLODForSlot(l,e,r,n);o.push(u),i.push(n)}}}else for(const s of Object.keys(r)){const n=r[s];if((n==null?void 0:n.isTexture)===!0){const l=this.assignTextureLODForSlot(n,e,r,s);o.push(l),i.push(s)}}return Promise.all(o).then(s=>{const n=new Array;for(let l=0;l<s.length;l++){const u=s[l],c=i[l];u&&u.isTexture===!0?n.push({material:r,slot:c,texture:u,level:e}):n.push({material:r,slot:c,texture:null,level:e})}return n})}if(t instanceof h.Texture||t.isTexture===!0){const r=t;return this.assignTextureLODForSlot(r,e,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(t,e,r,o){return(t==null?void 0:t.isTexture)!==!0?Promise.resolve(null):o==="glyphMap"?Promise.resolve(t):O.getOrLoadLOD(t,e).then(i=>{if(Array.isArray(i))return null;if((i==null?void 0:i.isTexture)===!0){if(i!=t){if(r&&o){const s=r[o];if(s){const n=this.getAssignedLODInformation(s);if(n&&(n==null?void 0:n.level)<e)return D==="verbose"&&console.warn("Assigned texture level is already higher: ",n.level,e,r,s,i),null}r[o]=i}if(D&&o&&r){const s=this.getAssignedLODInformation(t);s&&Te(r,o,s.url)}}return i}else D=="verbose"&&console.warn("No LOD found for",t,e);return null}).catch(i=>(console.error("Error loading LOD",t,i),null))}afterRoot(t){var e,r;return D&&console.log("AFTER",this.url,t),(e=this.parser.json.textures)==null||e.forEach((o,i)=>{var s;if(o!=null&&o.extensions){const n=o==null?void 0:o.extensions[$];if(n){if(!n.lods){D&&console.warn("Texture has no LODs",n);return}let l=!1;for(const u of this.parser.associations.keys())if(u.isTexture===!0){const c=this.parser.associations.get(u);(c==null?void 0:c.textures)===i&&(l=!0,O.registerTexture(this.url,u,(s=n.lods)==null?void 0:s.length,i,n))}l||this.parser.getDependency("texture",i).then(u=>{var c;u&&O.registerTexture(this.url,u,(c=n.lods)==null?void 0:c.length,i,n)})}}}),(r=this.parser.json.meshes)==null||r.forEach((o,i)=>{if(o!=null&&o.extensions){const s=o==null?void 0:o.extensions[$];if(s&&s.lods){for(const n of this.parser.associations.keys())if(n.isMesh){const l=this.parser.associations.get(n);(l==null?void 0:l.meshes)===i&&O.registerMesh(this.url,s.guid,n,s.lods.length,l.primitives,s)}}}}),null}static async getOrLoadLOD(t,e){var n,l,u,c;const r=D=="verbose",o=t.userData.LODS;if(!o)return null;const i=o==null?void 0:o.key;let s;if(t.isTexture===!0){const w=t;w.source&&w.source[ye]&&(s=w.source[ye])}if(s||(s=O.lodInfos.get(i)),s){if(e>0){let d=!1;const y=Array.isArray(s.lods);if(y&&e>=s.lods.length?d=!0:y||(d=!0),d)return this.lowresCache.get(i)}const w=Array.isArray(s.lods)?(n=s.lods[e])==null?void 0:n.path:s.lods;if(!w)return D&&!s["missing:uri"]&&(s["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+e,s)),null;const g=We(o.url,w);if(g.endsWith(".glb")||g.endsWith(".gltf")){if(!s.guid)return console.warn("missing pointer for glb/gltf texture",s),null;const d=g+"_"+s.guid,y=this.previouslyLoaded.get(d);if(y!==void 0){r&&console.log(`LOD ${e} was already loading/loaded: ${d}`);let x=await y.catch(z=>(console.error(`Error loading LOD ${e} from ${g}
1
+ "use strict";var Re=Object.defineProperty;var Ge=(a,t,e)=>t in a?Re(a,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):a[t]=e;var f=(a,t,e)=>(Ge(a,typeof t!="symbol"?t+"":t,e),e),be=(a,t,e)=>{if(!t.has(a))throw TypeError("Cannot "+e)};var L=(a,t,e)=>(be(a,t,"read from private field"),e?e.call(a):t.get(a)),X=(a,t,e)=>{if(t.has(a))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(a):t.set(a,e)},V=(a,t,e,r)=>(be(a,t,"write to private field"),r?r.call(a,e):t.set(a,e),e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("three"),Fe=require("three/examples/jsm/loaders/GLTFLoader.js"),Ve=require("three/examples/jsm/libs/meshopt_decoder.module.js"),$e=require("three/examples/jsm/loaders/DRACOLoader.js"),Ne=require("three/examples/jsm/loaders/KTX2Loader.js"),we="";globalThis.GLTF_PROGRESSIVE_VERSION=we;console.debug(`[gltf-progressive] version ${we}`);let fe="https://www.gstatic.com/draco/versioned/decoders/1.4.1/",ve="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";fetch(fe+"draco_decoder.js",{method:"head"}).catch(a=>{fe="./include/draco/",ve="./include/ktx2/"});function ze(a){fe=a}function Ue(a){ve=a}let j,ue,J;function _e(a){return j||(j=new $e.DRACOLoader,j.setDecoderPath(fe),j.setDecoderConfig({type:"js"})),J||(J=new Ne.KTX2Loader,J.setTranscoderPath(ve)),ue||(ue=Ve.MeshoptDecoder),a?J.detectSupport(a):a!==null&&console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"),{dracoLoader:j,ktx2Loader:J,meshoptDecoder:ue}}function Oe(a){a.dracoLoader||a.setDRACOLoader(j),a.ktx2Loader||a.setKTX2Loader(J),a.meshoptDecoder||a.setMeshoptDecoder(ue)}oe("debugprogressive");function oe(a){const e=new URL(window.location.href).searchParams.get(a);return e==null||e==="0"||e==="false"?!1:e===""?!0:e}function We(a,t){if(t===void 0||t.startsWith("./")||t.startsWith("http")||a===void 0)return t;const e=a.lastIndexOf("/");if(e>=0){const r=a.substring(0,e+1);for(;r.endsWith("/")&&t.startsWith("/");)t=t.substring(1);return r+t}return t}let te;function qe(){return te!==void 0||(te=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),oe("debugprogressive")&&console.log("[glTF Progressive]: isMobileDevice",te)),te}const Me=Symbol("needle:raycast-mesh");function ge(a){return(a==null?void 0:a[Me])instanceof h.BufferGeometry?a[Me]:null}function Ce(a,t){if((a.type==="Mesh"||a.type==="SkinnedMesh")&&!ge(a)){const r=Xe(t);r.userData={isRaycastMesh:!0},a[Me]=r}}function Ke(a=!0){if(a){if(re)return;const t=re=h.Mesh.prototype.raycast;h.Mesh.prototype.raycast=function(e,r){const o=this,i=ge(o);let s;i&&o.isMesh&&(s=o.geometry,o.geometry=i),t.call(this,e,r),s&&(o.geometry=s)}}else{if(!re)return;h.Mesh.prototype.raycast=re,re=null}}let re=null;function Xe(a){const t=new h.BufferGeometry;for(const e in a.attributes)t.setAttribute(e,a.getAttribute(e));return t.setIndex(a.getIndex()),t}const Y=new Array,$="NEEDLE_progressive",D=oe("debugprogressive"),me=Symbol("needle-progressive-texture"),ie=new Map,De=new Set;if(D){let a=function(){t+=1,console.log("Toggle LOD level",t,ie),ie.forEach((o,i)=>{for(const s of o.keys){const n=i[s];if(n!=null){if(n.isBufferGeometry===!0){const l=b.getMeshLODInformation(n),u=l?Math.min(t,l.lods.length):0;i["DEBUG:LOD"]=t,b.assignMeshLOD(i,u),l&&(e=Math.max(e,l.lods.length-1))}else if(i.isMaterial===!0){i["DEBUG:LOD"]=t,b.assignTextureLOD(i,t);break}}}}),t>=e&&(t=-1)},t=-1,e=2,r=!1;window.addEventListener("keyup",o=>{o.key==="p"&&a(),o.key==="w"&&(r=!r,De&&De.forEach(i=>{i.name!="BackgroundCubeMaterial"&&i.glyphMap==null&&"wireframe"in i&&(i.wireframe=r)}))})}function Te(a,t,e){var o;if(!D)return;ie.has(a)||ie.set(a,{keys:[],sourceId:e});const r=ie.get(a);((o=r==null?void 0:r.keys)==null?void 0:o.includes(t))==!1&&r.keys.push(t)}const O=class{constructor(t,e){f(this,"parser");f(this,"url");f(this,"_isLoadingMesh");f(this,"loadMesh",t=>{var r,o;if(this._isLoadingMesh)return null;const e=(o=(r=this.parser.json.meshes[t])==null?void 0:r.extensions)==null?void 0:o[$];return e?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",t).then(i=>{var s;return this._isLoadingMesh=!1,i&&O.registerMesh(this.url,e.guid,i,(s=e.lods)==null?void 0:s.length,void 0,e),i})):null});D&&console.log("Progressive extension registered for",e),this.parser=t,this.url=e}get name(){return $}static getMeshLODInformation(t){const e=this.getAssignedLODInformation(t);return e!=null&&e.key?this.lodInfos.get(e.key):null}static getMaterialMinMaxLODsCount(t,e){const r=this,o="LODS:minmax",i=t[o];if(i!=null)return i;if(e||(e={min_count:1/0,max_count:0,lods:[]}),Array.isArray(t)){for(const n of t)this.getMaterialMinMaxLODsCount(n,e);return t[o]=e,e}if(D==="verbose"&&console.log("getMaterialMinMaxLODsCount",t),t.type==="ShaderMaterial"||t.type==="RawShaderMaterial"){const n=t;for(const l of Object.keys(n.uniforms)){const u=n.uniforms[l].value;(u==null?void 0:u.isTexture)===!0&&s(u,e)}}else if(t.isMaterial)for(const n of Object.keys(t)){const l=t[n];(l==null?void 0:l.isTexture)===!0&&s(l,e)}return t[o]=e,e;function s(n,l){const u=r.getAssignedLODInformation(n);if(u){const c=r.lodInfos.get(u.key);if(c&&c.lods){l.min_count=Math.min(l.min_count,c.lods.length),l.max_count=Math.max(l.max_count,c.lods.length);for(let w=0;w<c.lods.length;w++){const g=c.lods[w];g.width&&(l.lods[w]=l.lods[w]||{min_height:1/0,max_height:0},l.lods[w].min_height=Math.min(l.lods[w].min_height,g.height),l.lods[w].max_height=Math.max(l.lods[w].max_height,g.height))}}}}}static hasLODLevelAvailable(t,e){var i;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 n=t[s];if(n&&n.isTexture&&this.hasLODLevelAvailable(n,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,o;if(t.isMesh?r=t.geometry:(t.isBufferGeometry||t.isTexture)&&(r=t),r&&(i=r==null?void 0:r.userData)!=null&&i.LODS){const s=r.userData.LODS;if(o=this.lodInfos.get(s.key),e===void 0)return o!=null;if(o)return Array.isArray(o.lods)?e<o.lods.length:e===0}return!1}static assignMeshLOD(t,e){var r;if(!t)return Promise.resolve(null);if(t instanceof h.Mesh||t.isMesh===!0){const o=t.geometry,i=this.getAssignedLODInformation(o);if(!i)return Promise.resolve(null);for(const s of Y)(r=s.onBeforeGetLODMesh)==null||r.call(s,t,e);return t["LOD:requested level"]=e,O.getOrLoadLOD(o,e).then(s=>{if(t["LOD:requested level"]===e){if(delete t["LOD:requested level"],Array.isArray(s)){const n=i.index||0;s=s[n]}s&&o!=s&&((s==null?void 0:s.isBufferGeometry)?(t.geometry=s,D&&Te(t,"geometry",i.url)):D&&console.error("Invalid LOD geometry",s))}return s}).catch(s=>(console.error("Error loading mesh LOD",t,s),null))}else D&&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 instanceof h.Material||t.isMaterial===!0){const r=t,o=[],i=new Array;if(D&&De.add(r),r.uniforms&&r.isRawShaderMaterial||r.isShaderMaterial===!0){const s=r;for(const n of Object.keys(s.uniforms)){const l=s.uniforms[n].value;if((l==null?void 0:l.isTexture)===!0){const u=this.assignTextureLODForSlot(l,e,r,n);o.push(u),i.push(n)}}}else for(const s of Object.keys(r)){const n=r[s];if((n==null?void 0:n.isTexture)===!0){const l=this.assignTextureLODForSlot(n,e,r,s);o.push(l),i.push(s)}}return Promise.all(o).then(s=>{const n=new Array;for(let l=0;l<s.length;l++){const u=s[l],c=i[l];u&&u.isTexture===!0?n.push({material:r,slot:c,texture:u,level:e}):n.push({material:r,slot:c,texture:null,level:e})}return n})}if(t instanceof h.Texture||t.isTexture===!0){const r=t;return this.assignTextureLODForSlot(r,e,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(t,e,r,o){return(t==null?void 0:t.isTexture)!==!0?Promise.resolve(null):o==="glyphMap"?Promise.resolve(t):O.getOrLoadLOD(t,e).then(i=>{if(Array.isArray(i))return null;if((i==null?void 0:i.isTexture)===!0){if(i!=t){if(r&&o){const s=r[o];if(s){const n=this.getAssignedLODInformation(s);if(n&&(n==null?void 0:n.level)<e)return D==="verbose"&&console.warn("Assigned texture level is already higher: ",n.level,e,r,s,i),null}r[o]=i}if(D&&o&&r){const s=this.getAssignedLODInformation(t);s&&Te(r,o,s.url)}}return i}else D=="verbose"&&console.warn("No LOD found for",t,e);return null}).catch(i=>(console.error("Error loading LOD",t,i),null))}afterRoot(t){var e,r;return D&&console.log("AFTER",this.url,t),(e=this.parser.json.textures)==null||e.forEach((o,i)=>{var s;if(o!=null&&o.extensions){const n=o==null?void 0:o.extensions[$];if(n){if(!n.lods){D&&console.warn("Texture has no LODs",n);return}let l=!1;for(const u of this.parser.associations.keys())if(u.isTexture===!0){const c=this.parser.associations.get(u);(c==null?void 0:c.textures)===i&&(l=!0,O.registerTexture(this.url,u,(s=n.lods)==null?void 0:s.length,i,n))}l||this.parser.getDependency("texture",i).then(u=>{var c;u&&O.registerTexture(this.url,u,(c=n.lods)==null?void 0:c.length,i,n)})}}}),(r=this.parser.json.meshes)==null||r.forEach((o,i)=>{if(o!=null&&o.extensions){const s=o==null?void 0:o.extensions[$];if(s&&s.lods){for(const n of this.parser.associations.keys())if(n.isMesh){const l=this.parser.associations.get(n);(l==null?void 0:l.meshes)===i&&O.registerMesh(this.url,s.guid,n,s.lods.length,l.primitives,s)}}}}),null}static async getOrLoadLOD(t,e){var n,l,u,c;const r=D=="verbose",o=t.userData.LODS;if(!o)return null;const i=o==null?void 0:o.key;let s;if(t.isTexture===!0){const w=t;w.source&&w.source[me]&&(s=w.source[me])}if(s||(s=O.lodInfos.get(i)),s){if(e>0){let d=!1;const y=Array.isArray(s.lods);if(y&&e>=s.lods.length?d=!0:y||(d=!0),d)return this.lowresCache.get(i)}const w=Array.isArray(s.lods)?(n=s.lods[e])==null?void 0:n.path:s.lods;if(!w)return D&&!s["missing:uri"]&&(s["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+e,s)),null;const g=We(o.url,w);if(g.endsWith(".glb")||g.endsWith(".gltf")){if(!s.guid)return console.warn("missing pointer for glb/gltf texture",s),null;const d=g+"_"+s.guid,y=this.previouslyLoaded.get(d);if(y!==void 0){r&&console.log(`LOD ${e} was already loading/loaded: ${d}`);let x=await y.catch(z=>(console.error(`Error loading LOD ${e} from ${g}
2
2
  `,z),null)),v=!1;if(x==null||(x instanceof h.Texture&&t instanceof h.Texture?(l=x.image)!=null&&l.data||(u=x.source)!=null&&u.data?x=this.copySettings(t,x):(v=!0,this.previouslyLoaded.delete(d)):x instanceof h.BufferGeometry&&t instanceof h.BufferGeometry&&((c=x.attributes.position)!=null&&c.array||(v=!0,this.previouslyLoaded.delete(d)))),!v)return x}const M=s,k=new Promise(async(x,v)=>{const z=new Fe.GLTFLoader;Oe(z),D&&(await new Promise(S=>setTimeout(S,1e3)),r&&console.warn("Start loading (delayed) "+g,M.guid));let K=g;if(M&&Array.isArray(M.lods)){const S=M.lods[e];S.hash&&(K+="?v="+S.hash)}const T=await z.loadAsync(K).catch(S=>(console.error(`Error loading LOD ${e} from ${g}
3
3
  `,S),null));if(!T)return null;const U=T.parser;r&&console.log("Loading finished "+g,M.guid);let E=0;if(T.parser.json.textures){let S=!1;for(const m of T.parser.json.textures){if(m!=null&&m.extensions){const p=m==null?void 0:m.extensions[$];if(p!=null&&p.guid&&p.guid===M.guid){S=!0;break}}E++}if(S){let m=await U.getDependency("texture",E);return m&&O.assignLODInformation(o.url,m,i,e,void 0,void 0),r&&console.log('change "'+t.name+'" → "'+m.name+'"',g,E,m,d),t instanceof h.Texture&&(m=this.copySettings(t,m)),m&&(m.guid=M.guid),x(m)}else D&&console.warn("Could not find texture with guid",M.guid,T.parser.json)}if(E=0,T.parser.json.meshes){let S=!1;for(const m of T.parser.json.meshes){if(m!=null&&m.extensions){const p=m==null?void 0:m.extensions[$];if(p!=null&&p.guid&&p.guid===M.guid){S=!0;break}}E++}if(S){const m=await U.getDependency("mesh",E),p=M;if(r&&console.log(`Loaded Mesh "${m.name}"`,g,E,m,d),m.isMesh===!0){const _=m.geometry;return O.assignLODInformation(o.url,_,i,e,void 0,p.density),x(_)}else{const _=new Array;for(let A=0;A<m.children.length;A++){const P=m.children[A];if(P.isMesh===!0){const C=P.geometry;O.assignLODInformation(o.url,C,i,e,A,p.density),_.push(C)}}return x(_)}}else D&&console.warn("Could not find mesh with guid",M.guid,T.parser.json)}return x(null)});return this.previouslyLoaded.set(d,k),await k}else if(t instanceof h.Texture){r&&console.log("Load texture from uri: "+g);const y=await new h.TextureLoader().loadAsync(g);return y?(y.guid=s.guid,y.flipY=!1,y.needsUpdate=!0,y.colorSpace=t.colorSpace,r&&console.log(s,y)):D&&console.warn("failed loading",g),y}}else D&&console.warn(`Can not load LOD ${e}: no LOD info found for "${i}" ${t.name}`,t.type);return null}static assignLODInformation(t,e,r,o,i,s){if(!e)return;e.userData||(e.userData={});const n=new Ye(t,r,o,i,s);e.userData.LODS=n}static getAssignedLODInformation(t){var e;return((e=t==null?void 0:t.userData)==null?void 0:e.LODS)||null}static copySettings(t,e){return e=e.clone(),D&&console.warn(`Copying texture settings
4
4
  `,t.uuid,`
5
- `,e.uuid),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}};let b=O;f(b,"registerTexture",(t,e,r,o,i)=>{if(D&&console.log("> Progressive: register texture",o,e.name,e.uuid,e,i),!e){D&&console.error("gltf-progressive: Register texture without texture");return}e.source&&(e.source[ye]=i);const s=i.guid;O.assignLODInformation(t,e,s,r,o,void 0),O.lodInfos.set(s,i),O.lowresCache.set(s,e)}),f(b,"registerMesh",(t,e,r,o,i,s)=>{var u;D&&console.log("> Progressive: register mesh",i,r.name,s,r.uuid,r);const n=r.geometry;if(!n){D&&console.warn("gltf-progressive: Register mesh without geometry");return}n.userData||(n.userData={}),O.assignLODInformation(t,n,e,o,i,s.density),O.lodInfos.set(e,s);let l=O.lowresCache.get(e);l?l.push(r.geometry):l=[r.geometry],O.lowresCache.set(e,l),o>0&&!he(r)&&Ce(r,n);for(const c of Y)(u=c.onRegisteredNewMesh)==null||u.call(c,r,s)}),f(b,"lodInfos",new Map),f(b,"previouslyLoaded",new Map),f(b,"lowresCache",new Map);class Ye{constructor(t,e,r,o,i){f(this,"url");f(this,"key");f(this,"level");f(this,"index");f(this,"density");this.url=t,this.key=e,this.level=r,o!=null&&(this.index=o),i!=null&&(this.density=i)}}const G=oe("debugprogressive"),He=oe("noprogressive"),me=Symbol("Needle:LODSManager"),xe=Symbol("Needle:LODState"),H=Symbol("Needle:CurrentLOD"),F={mesh_lod:-1,texture_lod:-1};var I,W,fe,j,J,de,q;const B=class{constructor(t,e){f(this,"context");f(this,"renderer");f(this,"projectionScreenMatrix",new h.Matrix4);f(this,"cameraFrustrum",new h.Frustum);f(this,"targetTriangleDensity",2e5);f(this,"updateInterval","auto");X(this,I,1);f(this,"pause",!1);f(this,"_lodchangedlisteners",[]);X(this,W,void 0);X(this,fe,new h.Clock);X(this,j,0);X(this,J,0);X(this,de,0);X(this,q,0);f(this,"_fpsBuffer",[60,60,60,60,60]);f(this,"_sphere",new h.Sphere);f(this,"_tempBox",new h.Box3);f(this,"_tempBox2",new h.Box3);f(this,"tempMatrix",new h.Matrix4);f(this,"_tempWorldPosition",new h.Vector3);f(this,"_tempBoxSize",new h.Vector3);f(this,"_tempBox2Size",new h.Vector3);this.renderer=t,this.context={...e}}static getObjectLODState(t){return t[xe]}static addPlugin(t){Y.push(t)}static removePlugin(t){const e=Y.indexOf(t);e>=0&&Y.splice(e,1)}static get(t,e){if(t[me])return console.debug("[gltf-progressive] LODsManager already exists for this renderer"),t[me];const r=new B(t,{engine:"unknown",...e});return t[me]=r,r}get plugins(){return Y}addEventListener(t,e){t==="changed"&&this._lodchangedlisteners.push(e)}enable(){if(L(this,W))return;console.debug("[gltf-progressive] Enabling LODsManager for renderer");let t=0;V(this,W,this.renderer.render);const e=this;_e(this.renderer),this.renderer.render=function(r,o){e.renderer.getRenderTarget()==null&&(t=0,V(e,j,L(e,j)+1),V(e,J,L(e,fe).getDelta()),V(e,de,L(e,de)+L(e,J)),e._fpsBuffer.shift(),e._fpsBuffer.push(1/L(e,J)),V(e,q,e._fpsBuffer.reduce((l,u)=>l+u)/e._fpsBuffer.length),G&&L(e,j)%30===0&&console.log("FPS",Math.round(L(e,q)),"Interval:",L(e,I)));const s=L(e,j),n=t++;e.onBeforeRender(r,o,n,s),L(e,W).call(this,r,o),e.onAfterRender(r,o,n,s)}}disable(){L(this,W)&&(this.renderer.render=L(this,W),V(this,W,void 0))}onBeforeRender(t,e,r,o){}onAfterRender(t,e,r,o){var l,u;if(this.pause)return;const i=this.renderer.renderLists.get(t,0),s=i.opaque;let n=!0;if(s.length===1){const c=s[0].material;(c.name==="EffectMaterial"||c.name==="CopyShader")&&(n=!1)}if((e.parent&&e.parent.type==="CubeCamera"||r>=1&&e.type==="OrthographicCamera")&&(n=!1),n){if(He||(this.updateInterval==="auto"?L(this,q)<40&&L(this,I)<10?(V(this,I,L(this,I)+1),G&&console.warn("↓ Reducing LOD updates",L(this,I),L(this,q).toFixed(0))):L(this,q)>=60&&L(this,I)>1&&(V(this,I,L(this,I)-1),G&&console.warn("↑ Increasing LOD updates",L(this,I),L(this,q).toFixed(0))):V(this,I,this.updateInterval),L(this,I)>0&&o%L(this,I)!=0))return;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse),this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix,this.renderer.coordinateSystem);const c=this.targetTriangleDensity;for(const d of s){if(d.material&&(((l=d.geometry)==null?void 0:l.type)==="BoxGeometry"||((u=d.geometry)==null?void 0:u.type)==="BufferGeometry")&&(d.material.name==="SphericalGaussianBlur"||d.material.name=="BackgroundCubeMaterial"||d.material.name==="CubemapFromEquirect"||d.material.name==="EquirectangularToCubeUV")){G&&(d.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(d.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",d,d.material.name,d.material.type)));continue}switch(d.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}if(G==="color"&&d.material&&!d.object.progressive_debug_color){d.object.progressive_debug_color=!0;const M=Math.random()*16777215,k=new h.MeshStandardMaterial({color:M});d.object.material=k}const y=d.object;(y instanceof h.Mesh||y.isMesh)&&this.updateLODs(t,e,y,c,o)}const w=i.transparent;for(const d of w){const y=d.object;(y instanceof h.Mesh||y.isMesh)&&this.updateLODs(t,e,y,c,o)}const g=i.transmissive;for(const d of g){const y=d.object;(y instanceof h.Mesh||y.isMesh)&&this.updateLODs(t,e,y,c,o)}}}updateLODs(t,e,r,o,i){var l,u;r.userData||(r.userData={});let s=r[xe];if(s||(s=new je,r[xe]=s),s.frames++<2)return;for(const c of Y)(l=c.onBeforeUpdateLOD)==null||l.call(c,this.renderer,t,e,r);this.calculateLodLevel(e,r,s,o,F),F.mesh_lod=Math.round(F.mesh_lod),F.texture_lod=Math.round(F.texture_lod),F.mesh_lod>=0&&this.loadProgressiveMeshes(r,F.mesh_lod);let n=F.texture_lod;if(r.material&&n>=0){const c=r["DEBUG:LOD"];c!=null&&(n=c),this.loadProgressiveTextures(r.material,n)}for(const c of Y)(u=c.onAfterUpdatedLOD)==null||u.call(c,this.renderer,t,e,r,F);s.lastLodLevel_Mesh=F.mesh_lod,s.lastLodLevel_Texture=F.texture_lod}loadProgressiveTextures(t,e){if(!t)return;if(Array.isArray(t)){for(const o of t)this.loadProgressiveTextures(o,e);return}let r=!1;(t[H]===void 0||e<t[H])&&(r=!0),r&&(t[H]=e,b.assignTextureLOD(t,e).then(o=>{this._lodchangedlisteners.forEach(i=>i({type:"texture",level:e,object:t}))}))}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);if(t[H]!==e){t[H]=e;const r=t.geometry;return b.assignMeshLOD(t,e).then(o=>(o&&t[H]==e&&r!=t.geometry&&this._lodchangedlisteners.forEach(i=>i({type:"mesh",level:e,object:t})),o))}return Promise.resolve(null)}static isInside(t,e){const r=t.min,o=t.max,i=(r.x+o.x)*.5,s=(r.y+o.y)*.5;return this._tempPtInside.set(i,s,r.z).applyMatrix4(e).z<0}calculateLodLevel(t,e,r,o,i){var k,N;if(!e){i.mesh_lod=-1,i.texture_lod=-1;return}if(!t){i.mesh_lod=-1,i.texture_lod=-1;return}let n=10+1,l=!1;if(G&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const u=b.getMeshLODInformation(e.geometry),c=u==null?void 0:u.lods,w=c&&c.length>0,g=b.getMaterialMinMaxLODsCount(e.material),d=(g==null?void 0:g.min_count)!=1/0&&g.min_count>0&&g.max_count>0;if(!w&&!d){i.mesh_lod=0,i.texture_lod=0;return}if(w||(l=!0,n=0),!((k=this.cameraFrustrum)!=null&&k.intersectsObject(e))){i.mesh_lod=99,i.texture_lod=99;return}const y=this.renderer.domElement.clientHeight||this.renderer.domElement.height;let M=e.geometry.boundingBox;if(e.type==="SkinnedMesh"){const x=e;x.boundingBox||x.computeBoundingBox(),M=x.boundingBox}if(M&&t.isPerspectiveCamera){const x=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 p=t.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(p)){i.mesh_lod=0,i.texture_lod=0;return}}if(this._tempBox.copy(M),this._tempBox.applyMatrix4(e.matrixWorld),B.isInside(this._tempBox,this.projectionScreenMatrix)){i.mesh_lod=0,i.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&x.fov>70){const p=this._tempBox.min,_=this._tempBox.max;let A=p.x,P=p.y,C=_.x,Q=_.y;const ne=2,ge=1.5,ae=(p.x+_.x)*.5,le=(p.y+_.y)*.5;A=(A-ae)*ne+ae,P=(P-le)*ne+le,C=(C-ae)*ne+ae,Q=(Q-le)*ne+le;const Ie=A<0&&C>0?0:Math.min(Math.abs(p.x),Math.abs(_.x)),ke=P<0&&Q>0?0:Math.min(Math.abs(p.y),Math.abs(_.y)),pe=Math.max(Ie,ke);r.lastCentrality=(ge-pe)*(ge-pe)*(ge-pe)}else r.lastCentrality=1;const v=this._tempBox.getSize(this._tempBoxSize);v.multiplyScalar(.5),screen.availHeight>0&&y>0&&v.multiplyScalar(y/screen.availHeight),v.x*=x.aspect;const z=t.matrixWorldInverse,K=this._tempBox2;K.copy(M),K.applyMatrix4(e.matrixWorld),K.applyMatrix4(z);const T=K.getSize(this._tempBox2Size),U=Math.max(T.x,T.y);if(Math.max(v.x,v.y)!=0&&U!=0&&(v.z=T.z/Math.max(T.x,T.y)*Math.max(v.x,v.y)),r.lastScreenCoverage=Math.max(v.x,v.y,v.z),r.lastScreenspaceVolume.copy(v),r.lastScreenCoverage*=r.lastCentrality,G&&B.debugDrawLine){const p=this.tempMatrix.copy(this.projectionScreenMatrix);p.invert();const _=B.corner0,A=B.corner1,P=B.corner2,C=B.corner3;_.copy(this._tempBox.min),A.copy(this._tempBox.max),A.x=_.x,P.copy(this._tempBox.max),P.y=_.y,C.copy(this._tempBox.max);const Q=(_.z+C.z)*.5;_.z=A.z=P.z=C.z=Q,_.applyMatrix4(p),A.applyMatrix4(p),P.applyMatrix4(p),C.applyMatrix4(p),B.debugDrawLine(_,A,255),B.debugDrawLine(_,P,255),B.debugDrawLine(A,C,255),B.debugDrawLine(P,C,255)}let S=999;if(c&&r.lastScreenCoverage>0){for(let p=0;p<c.length;p++)if(c[p].density/r.lastScreenCoverage<o){S=p;break}}S<n&&(n=S,l=!0)}if(l?i.mesh_lod=n:i.mesh_lod=r.lastLodLevel_Mesh,G&&i.mesh_lod!=r.lastLodLevel_Mesh){const v=c==null?void 0:c[i.mesh_lod];v&&console.log(`Mesh LOD changed: ${r.lastLodLevel_Mesh} → ${i.mesh_lod} (${v.density.toFixed(0)}) - ${e.name}`)}if(d){const x="saveData"in globalThis.navigator&&globalThis.navigator.saveData===!0;if(r.lastLodLevel_Texture<0){if(i.texture_lod=g.max_count-1,G){const v=g.lods[g.max_count-1];G&&console.log(`First Texture LOD ${i.texture_lod} (${v.max_height}px) - ${e.name}`)}}else{const v=r.lastScreenspaceVolume.x+r.lastScreenspaceVolume.y+r.lastScreenspaceVolume.z;let z=r.lastScreenCoverage*2;((N=this.context)==null?void 0:N.engine)==="model-viewer"&&(z*=2);const T=y/window.devicePixelRatio*z;for(let U=g.lods.length-1;U>=0;U--){let E=g.lods[U];if(!(x&&E.max_height>=2048)&&!(qe()&&E.max_height>4096)&&E.max_height>T){if(i.texture_lod=U,i.texture_lod<r.lastLodLevel_Texture){const S=E.max_height;G&&console.log(`Texture LOD changed: ${r.lastLodLevel_Texture} → ${i.texture_lod} = ${S}px
5
+ `,e.uuid),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}};let b=O;f(b,"registerTexture",(t,e,r,o,i)=>{if(D&&console.log("> Progressive: register texture",o,e.name,e.uuid,e,i),!e){D&&console.error("gltf-progressive: Register texture without texture");return}e.source&&(e.source[me]=i);const s=i.guid;O.assignLODInformation(t,e,s,r,o,void 0),O.lodInfos.set(s,i),O.lowresCache.set(s,e)}),f(b,"registerMesh",(t,e,r,o,i,s)=>{var u;D&&console.log("> Progressive: register mesh",i,r.name,s,r.uuid,r);const n=r.geometry;if(!n){D&&console.warn("gltf-progressive: Register mesh without geometry");return}n.userData||(n.userData={}),O.assignLODInformation(t,n,e,o,i,s.density),O.lodInfos.set(e,s);let l=O.lowresCache.get(e);l?l.push(r.geometry):l=[r.geometry],O.lowresCache.set(e,l),o>0&&!ge(r)&&Ce(r,n);for(const c of Y)(u=c.onRegisteredNewMesh)==null||u.call(c,r,s)}),f(b,"lodInfos",new Map),f(b,"previouslyLoaded",new Map),f(b,"lowresCache",new Map);class Ye{constructor(t,e,r,o,i){f(this,"url");f(this,"key");f(this,"level");f(this,"index");f(this,"density");this.url=t,this.key=e,this.level=r,o!=null&&(this.index=o),i!=null&&(this.density=i)}}const G=oe("debugprogressive"),He=oe("noprogressive"),xe=Symbol("Needle:LODSManager"),Le=Symbol("Needle:LODState"),H=Symbol("Needle:CurrentLOD"),F={mesh_lod:-1,texture_lod:-1};var I,W,de,Q,Z,he,q;const B=class{constructor(t,e){f(this,"context");f(this,"renderer");f(this,"projectionScreenMatrix",new h.Matrix4);f(this,"cameraFrustrum",new h.Frustum);f(this,"targetTriangleDensity",2e5);f(this,"updateInterval","auto");X(this,I,1);f(this,"pause",!1);f(this,"_lodchangedlisteners",[]);X(this,W,void 0);X(this,de,new h.Clock);X(this,Q,0);X(this,Z,0);X(this,he,0);X(this,q,0);f(this,"_fpsBuffer",[60,60,60,60,60]);f(this,"_sphere",new h.Sphere);f(this,"_tempBox",new h.Box3);f(this,"_tempBox2",new h.Box3);f(this,"tempMatrix",new h.Matrix4);f(this,"_tempWorldPosition",new h.Vector3);f(this,"_tempBoxSize",new h.Vector3);f(this,"_tempBox2Size",new h.Vector3);this.renderer=t,this.context={...e}}static getObjectLODState(t){return t[Le]}static addPlugin(t){Y.push(t)}static removePlugin(t){const e=Y.indexOf(t);e>=0&&Y.splice(e,1)}static get(t,e){if(t[xe])return console.debug("[gltf-progressive] LODsManager already exists for this renderer"),t[xe];const r=new B(t,{engine:"unknown",...e});return t[xe]=r,r}get plugins(){return Y}addEventListener(t,e){t==="changed"&&this._lodchangedlisteners.push(e)}enable(){if(L(this,W))return;console.debug("[gltf-progressive] Enabling LODsManager for renderer");let t=0;V(this,W,this.renderer.render);const e=this;_e(this.renderer),this.renderer.render=function(r,o){e.renderer.getRenderTarget()==null&&(t=0,V(e,Q,L(e,Q)+1),V(e,Z,L(e,de).getDelta()),V(e,he,L(e,he)+L(e,Z)),e._fpsBuffer.shift(),e._fpsBuffer.push(1/L(e,Z)),V(e,q,e._fpsBuffer.reduce((l,u)=>l+u)/e._fpsBuffer.length),G&&L(e,Q)%30===0&&console.log("FPS",Math.round(L(e,q)),"Interval:",L(e,I)));const s=L(e,Q),n=t++;e.onBeforeRender(r,o,n,s),L(e,W).call(this,r,o),e.onAfterRender(r,o,n,s)}}disable(){L(this,W)&&(this.renderer.render=L(this,W),V(this,W,void 0))}onBeforeRender(t,e,r,o){}onAfterRender(t,e,r,o){var l,u;if(this.pause)return;const i=this.renderer.renderLists.get(t,0),s=i.opaque;let n=!0;if(s.length===1){const c=s[0].material;(c.name==="EffectMaterial"||c.name==="CopyShader")&&(n=!1)}if((e.parent&&e.parent.type==="CubeCamera"||r>=1&&e.type==="OrthographicCamera")&&(n=!1),n){if(He||(this.updateInterval==="auto"?L(this,q)<40&&L(this,I)<10?(V(this,I,L(this,I)+1),G&&console.warn("↓ Reducing LOD updates",L(this,I),L(this,q).toFixed(0))):L(this,q)>=60&&L(this,I)>1&&(V(this,I,L(this,I)-1),G&&console.warn("↑ Increasing LOD updates",L(this,I),L(this,q).toFixed(0))):V(this,I,this.updateInterval),L(this,I)>0&&o%L(this,I)!=0))return;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse),this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix,this.renderer.coordinateSystem);const c=this.targetTriangleDensity;for(const d of s){if(d.material&&(((l=d.geometry)==null?void 0:l.type)==="BoxGeometry"||((u=d.geometry)==null?void 0:u.type)==="BufferGeometry")&&(d.material.name==="SphericalGaussianBlur"||d.material.name=="BackgroundCubeMaterial"||d.material.name==="CubemapFromEquirect"||d.material.name==="EquirectangularToCubeUV")){G&&(d.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(d.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",d,d.material.name,d.material.type)));continue}switch(d.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}if(G==="color"&&d.material&&!d.object.progressive_debug_color){d.object.progressive_debug_color=!0;const M=Math.random()*16777215,k=new h.MeshStandardMaterial({color:M});d.object.material=k}const y=d.object;(y instanceof h.Mesh||y.isMesh)&&this.updateLODs(t,e,y,c,o)}const w=i.transparent;for(const d of w){const y=d.object;(y instanceof h.Mesh||y.isMesh)&&this.updateLODs(t,e,y,c,o)}const g=i.transmissive;for(const d of g){const y=d.object;(y instanceof h.Mesh||y.isMesh)&&this.updateLODs(t,e,y,c,o)}}}updateLODs(t,e,r,o,i){var l,u;r.userData||(r.userData={});let s=r[Le];if(s||(s=new je,r[Le]=s),s.frames++<2)return;for(const c of Y)(l=c.onBeforeUpdateLOD)==null||l.call(c,this.renderer,t,e,r);this.calculateLodLevel(e,r,s,o,F),F.mesh_lod=Math.round(F.mesh_lod),F.texture_lod=Math.round(F.texture_lod),F.mesh_lod>=0&&this.loadProgressiveMeshes(r,F.mesh_lod);let n=F.texture_lod;if(r.material&&n>=0){const c=r["DEBUG:LOD"];c!=null&&(n=c),this.loadProgressiveTextures(r.material,n)}for(const c of Y)(u=c.onAfterUpdatedLOD)==null||u.call(c,this.renderer,t,e,r,F);s.lastLodLevel_Mesh=F.mesh_lod,s.lastLodLevel_Texture=F.texture_lod}loadProgressiveTextures(t,e){if(!t)return;if(Array.isArray(t)){for(const o of t)this.loadProgressiveTextures(o,e);return}let r=!1;(t[H]===void 0||e<t[H])&&(r=!0),r&&(t[H]=e,b.assignTextureLOD(t,e).then(o=>{this._lodchangedlisteners.forEach(i=>i({type:"texture",level:e,object:t}))}))}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);if(t[H]!==e){t[H]=e;const r=t.geometry;return b.assignMeshLOD(t,e).then(o=>(o&&t[H]==e&&r!=t.geometry&&this._lodchangedlisteners.forEach(i=>i({type:"mesh",level:e,object:t})),o))}return Promise.resolve(null)}static isInside(t,e){const r=t.min,o=t.max,i=(r.x+o.x)*.5,s=(r.y+o.y)*.5;return this._tempPtInside.set(i,s,r.z).applyMatrix4(e).z<0}calculateLodLevel(t,e,r,o,i){var k,N;if(!e){i.mesh_lod=-1,i.texture_lod=-1;return}if(!t){i.mesh_lod=-1,i.texture_lod=-1;return}let n=10+1,l=!1;if(G&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const u=b.getMeshLODInformation(e.geometry),c=u==null?void 0:u.lods,w=c&&c.length>0,g=b.getMaterialMinMaxLODsCount(e.material),d=(g==null?void 0:g.min_count)!=1/0&&g.min_count>0&&g.max_count>0;if(!w&&!d){i.mesh_lod=0,i.texture_lod=0;return}if(w||(l=!0,n=0),!((k=this.cameraFrustrum)!=null&&k.intersectsObject(e))){i.mesh_lod=99,i.texture_lod=99;return}const y=this.renderer.domElement.clientHeight||this.renderer.domElement.height;let M=e.geometry.boundingBox;if(e.type==="SkinnedMesh"){const x=e;x.boundingBox||x.computeBoundingBox(),M=x.boundingBox}if(M&&t.isPerspectiveCamera){const x=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 p=t.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(p)){i.mesh_lod=0,i.texture_lod=0;return}}if(this._tempBox.copy(M),this._tempBox.applyMatrix4(e.matrixWorld),B.isInside(this._tempBox,this.projectionScreenMatrix)){i.mesh_lod=0,i.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&x.fov>70){const p=this._tempBox.min,_=this._tempBox.max;let A=p.x,P=p.y,C=_.x,ee=_.y;const ne=2,pe=1.5,ae=(p.x+_.x)*.5,le=(p.y+_.y)*.5;A=(A-ae)*ne+ae,P=(P-le)*ne+le,C=(C-ae)*ne+ae,ee=(ee-le)*ne+le;const Ie=A<0&&C>0?0:Math.min(Math.abs(p.x),Math.abs(_.x)),ke=P<0&&ee>0?0:Math.min(Math.abs(p.y),Math.abs(_.y)),ye=Math.max(Ie,ke);r.lastCentrality=(pe-ye)*(pe-ye)*(pe-ye)}else r.lastCentrality=1;const v=this._tempBox.getSize(this._tempBoxSize);v.multiplyScalar(.5),screen.availHeight>0&&y>0&&v.multiplyScalar(y/screen.availHeight),v.x*=x.aspect;const z=t.matrixWorldInverse,K=this._tempBox2;K.copy(M),K.applyMatrix4(e.matrixWorld),K.applyMatrix4(z);const T=K.getSize(this._tempBox2Size),U=Math.max(T.x,T.y);if(Math.max(v.x,v.y)!=0&&U!=0&&(v.z=T.z/Math.max(T.x,T.y)*Math.max(v.x,v.y)),r.lastScreenCoverage=Math.max(v.x,v.y,v.z),r.lastScreenspaceVolume.copy(v),r.lastScreenCoverage*=r.lastCentrality,G&&B.debugDrawLine){const p=this.tempMatrix.copy(this.projectionScreenMatrix);p.invert();const _=B.corner0,A=B.corner1,P=B.corner2,C=B.corner3;_.copy(this._tempBox.min),A.copy(this._tempBox.max),A.x=_.x,P.copy(this._tempBox.max),P.y=_.y,C.copy(this._tempBox.max);const ee=(_.z+C.z)*.5;_.z=A.z=P.z=C.z=ee,_.applyMatrix4(p),A.applyMatrix4(p),P.applyMatrix4(p),C.applyMatrix4(p),B.debugDrawLine(_,A,255),B.debugDrawLine(_,P,255),B.debugDrawLine(A,C,255),B.debugDrawLine(P,C,255)}let S=999;if(c&&r.lastScreenCoverage>0){for(let p=0;p<c.length;p++)if(c[p].density/r.lastScreenCoverage<o){S=p;break}}S<n&&(n=S,l=!0)}if(l?i.mesh_lod=n:i.mesh_lod=r.lastLodLevel_Mesh,G&&i.mesh_lod!=r.lastLodLevel_Mesh){const v=c==null?void 0:c[i.mesh_lod];v&&console.log(`Mesh LOD changed: ${r.lastLodLevel_Mesh} → ${i.mesh_lod} (${v.density.toFixed(0)}) - ${e.name}`)}if(d){const x="saveData"in globalThis.navigator&&globalThis.navigator.saveData===!0;if(r.lastLodLevel_Texture<0){if(i.texture_lod=g.max_count-1,G){const v=g.lods[g.max_count-1];G&&console.log(`First Texture LOD ${i.texture_lod} (${v.max_height}px) - ${e.name}`)}}else{const v=r.lastScreenspaceVolume.x+r.lastScreenspaceVolume.y+r.lastScreenspaceVolume.z;let z=r.lastScreenCoverage*2;((N=this.context)==null?void 0:N.engine)==="model-viewer"&&(z*=2);const T=y/window.devicePixelRatio*z;for(let U=g.lods.length-1;U>=0;U--){let E=g.lods[U];if(!(x&&E.max_height>=2048)&&!(qe()&&E.max_height>4096)&&E.max_height>T){if(i.texture_lod=U,i.texture_lod<r.lastLodLevel_Texture){const S=E.max_height;G&&console.log(`Texture LOD changed: ${r.lastLodLevel_Texture} → ${i.texture_lod} = ${S}px
6
6
  Screensize: ${T.toFixed(0)}px, Coverage: ${(100*r.lastScreenCoverage).toFixed(2)}%, Volume ${v.toFixed(1)}
7
- ${e.name}`)}break}}}}else i.texture_lod=0}};let R=B;I=new WeakMap,W=new WeakMap,fe=new WeakMap,j=new WeakMap,J=new WeakMap,de=new WeakMap,q=new WeakMap,f(R,"debugDrawLine"),f(R,"corner0",new h.Vector3),f(R,"corner1",new h.Vector3),f(R,"corner2",new h.Vector3),f(R,"corner3",new h.Vector3),f(R,"_tempPtInside",new h.Vector3);class je{constructor(){f(this,"frames",0);f(this,"lastLodLevel_Mesh",-1);f(this,"lastLodLevel_Texture",-1);f(this,"lastScreenCoverage",0);f(this,"lastScreenspaceVolume",new h.Vector3);f(this,"lastCentrality",0)}}const Ae=Symbol("NEEDLE_mesh_lod"),ce=Symbol("NEEDLE_texture_lod");let te=null;function Se(){const a=Je();a&&(a.mapURLs(function(t){return Ee(),t}),Ee(),te==null||te.disconnect(),te=new MutationObserver(t=>{t.forEach(e=>{e.addedNodes.forEach(r=>{r instanceof HTMLElement&&r.tagName.toLowerCase()==="model-viewer"&&Be(r)})})}),te.observe(document,{childList:!0,subtree:!0}))}function Je(){const a=customElements.get("model-viewer");return a||(customElements.whenDefined("model-viewer").then(()=>{console.debug("[gltf-progressive] model-viewer defined"),Se()}),null)}function Ee(){document.querySelectorAll("model-viewer").forEach(t=>{Be(t)})}const Pe=new WeakSet;let Qe=0;function Be(a){if(!a||Pe.has(a))return null;Pe.add(a),console.debug("[gltf-progressive] found new model-viewer..."+ ++Qe+`
8
- `,a.getAttribute("src"));let t=null,e=null,r=null;for(let o=a;o!=null;o=Object.getPrototypeOf(o)){const i=Object.getOwnPropertySymbols(o),s=i.find(u=>u.toString()=="Symbol(renderer)"),n=i.find(u=>u.toString()=="Symbol(scene)"),l=i.find(u=>u.toString()=="Symbol(needsRender)");!t&&s!=null&&(t=a[s].threeRenderer),!e&&n!=null&&(e=a[n]),!r&&l!=null&&(r=a[l])}if(t&&e){let o=function(){if(r){let s=0,n=setInterval(()=>{if(s++>5){clearInterval(n);return}r==null||r.call(a)},300)}};console.debug("[gltf-progressive] setup model-viewer");const i=R.get(t,{engine:"model-viewer"});return R.addPlugin(new Ze),i.enable(),i.addEventListener("changed",()=>{r==null||r.call(a)}),a.addEventListener("model-visibility",s=>{s.detail.visible&&(r==null||r.call(a))}),a.addEventListener("load",()=>{o()}),()=>{i.disable()}}return null}class Ze{constructor(){f(this,"_didWarnAboutMissingUrl",!1)}onBeforeUpdateLOD(t,e,r,o){this.tryParseMeshLOD(e,o),this.tryParseTextureLOD(e,o)}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[ce]==!0)return;e[ce]=!0;const r=this.tryGetCurrentGLTF(t),o=this.tryGetCurrentModelViewer(t),i=this.getUrl(o);if(i&&r&&e.material){let s=function(l){var c,w,g;if(l[ce]==!0)return;l[ce]=!0,l.userData&&(l.userData.LOD=-1);const u=Object.keys(l);for(let d=0;d<u.length;d++){const y=u[d],M=l[y];if((M==null?void 0:M.isTexture)===!0){const k=(w=(c=M.userData)==null?void 0:c.associations)==null?void 0:w.textures;if(k==null)continue;const N=r.parser.json.textures[k];if(!N){console.warn("Texture data not found for texture index "+k);continue}if((g=N==null?void 0:N.extensions)!=null&&g[$]){const x=N.extensions[$];x&&i&&b.registerTexture(i,M,x.lods.length,k,x)}}}};const n=e.material;if(Array.isArray(n))for(const l of n)s(l);else s(n)}}tryParseMeshLOD(t,e){var s,n;if(e[Ae]==!0)return;e[Ae]=!0;const r=this.tryGetCurrentModelViewer(t),o=this.getUrl(r);if(!o)return;const i=(n=(s=e.userData)==null?void 0:s.gltfExtensions)==null?void 0:n[$];if(i&&o){const l=e.uuid;b.registerMesh(o,l,e,0,i.lods.length,i)}}}function et(a,t,e,r){_e(t),Oe(e),e.register(i=>new b(i,a));const o=R.get(t);return(r==null?void 0:r.enableLODsManager)!==!1&&o.enable(),o}Se();exports.EXTENSION_NAME=$;exports.LODsManager=R;exports.NEEDLE_progressive=b;exports.VERSION=we;exports.addDracoAndKTX2Loaders=Oe;exports.createLoaders=_e;exports.getRaycastMesh=he;exports.patchModelViewer=Se;exports.registerRaycastMesh=Ce;exports.setDracoDecoderLocation=ze;exports.setKTX2TranscoderLocation=Ue;exports.useNeedleProgressive=et;exports.useRaycastMeshes=Ke;
7
+ ${e.name}`)}break}}}}else i.texture_lod=0}};let R=B;I=new WeakMap,W=new WeakMap,de=new WeakMap,Q=new WeakMap,Z=new WeakMap,he=new WeakMap,q=new WeakMap,f(R,"debugDrawLine"),f(R,"corner0",new h.Vector3),f(R,"corner1",new h.Vector3),f(R,"corner2",new h.Vector3),f(R,"corner3",new h.Vector3),f(R,"_tempPtInside",new h.Vector3);class je{constructor(){f(this,"frames",0);f(this,"lastLodLevel_Mesh",-1);f(this,"lastLodLevel_Texture",-1);f(this,"lastScreenCoverage",0);f(this,"lastScreenspaceVolume",new h.Vector3);f(this,"lastCentrality",0)}}const Ae=Symbol("NEEDLE_mesh_lod"),ce=Symbol("NEEDLE_texture_lod");let se=null;function Se(){const a=Je();a&&(a.mapURLs(function(t){return Ee(),t}),Ee(),se==null||se.disconnect(),se=new MutationObserver(t=>{t.forEach(e=>{e.addedNodes.forEach(r=>{r instanceof HTMLElement&&r.tagName.toLowerCase()==="model-viewer"&&Be(r)})})}),se.observe(document,{childList:!0,subtree:!0}))}function Je(){const a=customElements.get("model-viewer");return a||(customElements.whenDefined("model-viewer").then(()=>{console.debug("[gltf-progressive] model-viewer defined"),Se()}),null)}function Ee(){document.querySelectorAll("model-viewer").forEach(t=>{Be(t)})}const Pe=new WeakSet;let Qe=0;function Be(a){if(!a||Pe.has(a))return null;Pe.add(a),console.debug("[gltf-progressive] found new model-viewer..."+ ++Qe+`
8
+ `,a.getAttribute("src"));let t=null,e=null,r=null;for(let o=a;o!=null;o=Object.getPrototypeOf(o)){const i=Object.getOwnPropertySymbols(o),s=i.find(u=>u.toString()=="Symbol(renderer)"),n=i.find(u=>u.toString()=="Symbol(scene)"),l=i.find(u=>u.toString()=="Symbol(needsRender)");!t&&s!=null&&(t=a[s].threeRenderer),!e&&n!=null&&(e=a[n]),!r&&l!=null&&(r=a[l])}if(t&&e){let o=function(){if(r){let s=0,n=setInterval(()=>{if(s++>5){clearInterval(n);return}r==null||r.call(a)},300)}};console.debug("[gltf-progressive] setup model-viewer");const i=R.get(t,{engine:"model-viewer"});return R.addPlugin(new Ze),i.enable(),i.addEventListener("changed",()=>{r==null||r.call(a)}),a.addEventListener("model-visibility",s=>{s.detail.visible&&(r==null||r.call(a))}),a.addEventListener("load",()=>{o()}),()=>{i.disable()}}return null}class Ze{constructor(){f(this,"_didWarnAboutMissingUrl",!1)}onBeforeUpdateLOD(t,e,r,o){this.tryParseMeshLOD(e,o),this.tryParseTextureLOD(e,o)}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[ce]==!0)return;e[ce]=!0;const r=this.tryGetCurrentGLTF(t),o=this.tryGetCurrentModelViewer(t),i=this.getUrl(o);if(i&&r&&e.material){let s=function(l){var c,w,g;if(l[ce]==!0)return;l[ce]=!0,l.userData&&(l.userData.LOD=-1);const u=Object.keys(l);for(let d=0;d<u.length;d++){const y=u[d],M=l[y];if((M==null?void 0:M.isTexture)===!0){const k=(w=(c=M.userData)==null?void 0:c.associations)==null?void 0:w.textures;if(k==null)continue;const N=r.parser.json.textures[k];if(!N){console.warn("Texture data not found for texture index "+k);continue}if((g=N==null?void 0:N.extensions)!=null&&g[$]){const x=N.extensions[$];x&&i&&b.registerTexture(i,M,x.lods.length,k,x)}}}};const n=e.material;if(Array.isArray(n))for(const l of n)s(l);else s(n)}}tryParseMeshLOD(t,e){var s,n;if(e[Ae]==!0)return;e[Ae]=!0;const r=this.tryGetCurrentModelViewer(t),o=this.getUrl(r);if(!o)return;const i=(n=(s=e.userData)==null?void 0:s.gltfExtensions)==null?void 0:n[$];if(i&&o){const l=e.uuid;b.registerMesh(o,l,e,0,i.lods.length,i)}}}function et(a,t,e,r){_e(t),Oe(e),e.register(i=>new b(i,a));const o=R.get(t);return(r==null?void 0:r.enableLODsManager)!==!1&&o.enable(),o}Se();exports.EXTENSION_NAME=$;exports.LODsManager=R;exports.NEEDLE_progressive=b;exports.VERSION=we;exports.addDracoAndKTX2Loaders=Oe;exports.createLoaders=_e;exports.getRaycastMesh=ge;exports.patchModelViewer=Se;exports.registerRaycastMesh=Ce;exports.setDracoDecoderLocation=ze;exports.setKTX2TranscoderLocation=Ue;exports.useNeedleProgressive=et;exports.useRaycastMeshes=Ke;
package/lib/loaders.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import { WebGLRenderer } from 'three';
2
+ import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
2
3
  import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
4
+ import { KTX2Loader } from 'three/examples/jsm/loaders/KTX2Loader.js';
3
5
  /**
4
6
  * Set the location of the Draco decoder.
5
7
  * @default 'https://www.gstatic.com/draco/versioned/decoders/1.4.1/'
@@ -10,5 +12,21 @@ export declare function setDracoDecoderLocation(location: string): void;
10
12
  * @default 'https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/'
11
13
  */
12
14
  export declare function setKTX2TranscoderLocation(location: string): void;
13
- export declare function createLoaders(renderer: WebGLRenderer): void;
15
+ /**
16
+ * Create loaders/decoders for Draco, KTX2 and Meshopt to be used with GLTFLoader.
17
+ * @param renderer - Provide a renderer to detect KTX2 support.
18
+ * @returns The loaders/decoders.
19
+ */
20
+ export declare function createLoaders(renderer: WebGLRenderer | null): {
21
+ dracoLoader: DRACOLoader;
22
+ ktx2Loader: KTX2Loader;
23
+ meshoptDecoder: {
24
+ supported: boolean;
25
+ ready: Promise<void>;
26
+ decodeVertexBuffer: (target: Uint8Array, count: number, size: number, source: Uint8Array, filter?: string | undefined) => void;
27
+ decodeIndexBuffer: (target: Uint8Array, count: number, size: number, source: Uint8Array) => void;
28
+ decodeIndexSequence: (target: Uint8Array, count: number, size: number, source: Uint8Array) => void;
29
+ decodeGltfBuffer: (target: Uint8Array, count: number, size: number, source: Uint8Array, mode: string, filter?: string | undefined) => void;
30
+ };
31
+ };
14
32
  export declare function addDracoAndKTX2Loaders(loader: GLTFLoader): void;
package/lib/loaders.js CHANGED
@@ -25,6 +25,11 @@ export function setKTX2TranscoderLocation(location) {
25
25
  let dracoLoader;
26
26
  let meshoptDecoder;
27
27
  let ktx2Loader;
28
+ /**
29
+ * Create loaders/decoders for Draco, KTX2 and Meshopt to be used with GLTFLoader.
30
+ * @param renderer - Provide a renderer to detect KTX2 support.
31
+ * @returns The loaders/decoders.
32
+ */
28
33
  export function createLoaders(renderer) {
29
34
  if (!dracoLoader) {
30
35
  dracoLoader = new DRACOLoader();
@@ -41,8 +46,9 @@ export function createLoaders(renderer) {
41
46
  if (renderer) {
42
47
  ktx2Loader.detectSupport(renderer);
43
48
  }
44
- else
45
- console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures will probably fail");
49
+ else if (renderer !== null)
50
+ console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail");
51
+ return { dracoLoader, ktx2Loader, meshoptDecoder };
46
52
  }
47
53
  export function addDracoAndKTX2Loaders(loader) {
48
54
  if (!loader.dracoLoader)
package/lib/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  // replaced at build time
2
- export const version = "1.2.3-beta";
2
+ export const version = "1.2.4-beta";
3
3
  globalThis["GLTF_PROGRESSIVE_VERSION"] = version;
4
4
  console.debug(`[gltf-progressive] version ${version}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@needle-tools/gltf-progressive",
3
- "version": "1.2.3-beta",
3
+ "version": "1.2.4-beta",
4
4
  "description": "three.js support for loading glTF or GLB files that contain progressive loading data",
5
5
  "homepage": "https://needle.tools",
6
6
  "author": {