@needle-tools/gltf-progressive 1.2.10 → 1.2.11

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.11] - 2024-09-11
8
+ - Fix: draco and KTX decoder path handling when gstatic can not be reached and user set path
9
+
7
10
  ## [1.2.10] - 2024-09-10
8
11
  - Fix: loading and assigning texture LOD for ShaderMaterial and RawShaderMaterial
9
12
 
@@ -9,37 +9,38 @@ var m = (a, t, e) => (_e(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
  }, U = (a, t, e, s) => (_e(a, t, "write to private field"), s ? s.call(a, e) : t.set(a, e), e);
12
- import { BufferGeometry as de, Mesh as H, Material as ze, Texture as te, TextureLoader as Ve, Matrix4 as Se, Clock as Ne, MeshStandardMaterial as We, Sphere as qe, Box3 as be, Vector3 as z } from "three";
13
- import { GLTFLoader as Xe } from "three/examples/jsm/loaders/GLTFLoader.js";
12
+ import { BufferGeometry as ge, Mesh as H, Material as ze, Texture as se, TextureLoader as Ve, Matrix4 as Se, Clock as Ne, MeshStandardMaterial as We, Sphere as Xe, Box3 as be, Vector3 as z } from "three";
13
+ import { GLTFLoader as qe } from "three/examples/jsm/loaders/GLTFLoader.js";
14
14
  import { MeshoptDecoder as Ke } from "three/examples/jsm/libs/meshopt_decoder.module.js";
15
15
  import { DRACOLoader as Ye } from "three/examples/jsm/loaders/DRACOLoader.js";
16
16
  import { KTX2Loader as He } from "three/examples/jsm/loaders/KTX2Loader.js";
17
17
  const Ce = "";
18
18
  globalThis.GLTF_PROGRESSIVE_VERSION = Ce;
19
19
  console.debug(`[gltf-progressive] version ${Ce}`);
20
- let he = "https://www.gstatic.com/draco/versioned/decoders/1.4.1/", Oe = "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/", Oe = "./include/ktx2/";
20
+ let j = "https://www.gstatic.com/draco/versioned/decoders/1.5.7/", ae = "https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";
21
+ const Je = j, Qe = ae;
22
+ fetch(j + "draco_decoder.js", { method: "head" }).catch((a) => {
23
+ j === Je && (j = "./include/draco/"), ae === Qe && (ae = "./include/ktx2/");
23
24
  });
24
- function dt(a) {
25
- he = a;
25
+ function gt(a) {
26
+ j = a;
26
27
  }
27
- function ht(a) {
28
- Oe = a;
28
+ function pt(a) {
29
+ ae = a;
29
30
  }
30
- let Q, fe, Z;
31
+ let Q, he, Z;
31
32
  function Be(a) {
32
- return Q || (Q = new Ye(), Q.setDecoderPath(he), Q.setDecoderConfig({ type: "js" })), Z || (Z = new He(), Z.setTranscoderPath(Oe)), fe || (fe = Ke), 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: fe };
33
+ return Q || (Q = new Ye(), Q.setDecoderPath(j), Q.setDecoderConfig({ type: "js" })), Z || (Z = new He(), Z.setTranscoderPath(ae)), he || (he = Ke), 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: he };
33
34
  }
34
35
  function Ie(a) {
35
- a.dracoLoader || a.setDRACOLoader(Q), a.ktx2Loader || a.setKTX2Loader(Z), a.meshoptDecoder || a.setMeshoptDecoder(fe);
36
+ a.dracoLoader || a.setDRACOLoader(Q), a.ktx2Loader || a.setKTX2Loader(Z), a.meshoptDecoder || a.setMeshoptDecoder(he);
36
37
  }
37
- oe("debugprogressive");
38
- function oe(a) {
38
+ le("debugprogressive");
39
+ function le(a) {
39
40
  const e = new URL(window.location.href).searchParams.get(a);
40
41
  return e == null || e === "0" || e === "false" ? !1 : e === "" ? !0 : e;
41
42
  }
42
- function Je(a, t) {
43
+ function Ze(a, t) {
43
44
  if (t === void 0 || t.startsWith("./") || t.startsWith("http") || a === void 0)
44
45
  return t;
45
46
  const e = a.lastIndexOf("/");
@@ -51,47 +52,47 @@ function Je(a, t) {
51
52
  }
52
53
  return t;
53
54
  }
54
- let se;
55
- function Qe() {
56
- return se !== void 0 || (se = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent), oe("debugprogressive") && console.log("[glTF Progressive]: isMobileDevice", se)), se;
55
+ let re;
56
+ function je() {
57
+ return re !== void 0 || (re = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent), le("debugprogressive") && console.log("[glTF Progressive]: isMobileDevice", re)), re;
57
58
  }
58
- const we = Symbol("needle:raycast-mesh");
59
- function ye(a) {
60
- return (a == null ? void 0 : a[we]) instanceof de ? a[we] : null;
59
+ const ve = Symbol("needle:raycast-mesh");
60
+ function me(a) {
61
+ return (a == null ? void 0 : a[ve]) instanceof ge ? a[ve] : null;
61
62
  }
62
- function Ze(a, t) {
63
- if ((a.type === "Mesh" || a.type === "SkinnedMesh") && !ye(a)) {
64
- const s = je(t);
65
- s.userData = { isRaycastMesh: !0 }, a[we] = s;
63
+ function et(a, t) {
64
+ if ((a.type === "Mesh" || a.type === "SkinnedMesh") && !me(a)) {
65
+ const s = tt(t);
66
+ s.userData = { isRaycastMesh: !0 }, a[ve] = s;
66
67
  }
67
68
  }
68
- function gt(a = !0) {
69
+ function yt(a = !0) {
69
70
  if (a) {
70
- if (re)
71
+ if (ie)
71
72
  return;
72
- const t = re = H.prototype.raycast;
73
+ const t = ie = H.prototype.raycast;
73
74
  H.prototype.raycast = function(e, s) {
74
- const n = this, r = ye(n);
75
+ const n = this, r = me(n);
75
76
  let i;
76
77
  r && n.isMesh && (i = n.geometry, n.geometry = r), t.call(this, e, s), i && (n.geometry = i);
77
78
  };
78
79
  } else {
79
- if (!re)
80
+ if (!ie)
80
81
  return;
81
- H.prototype.raycast = re, re = null;
82
+ H.prototype.raycast = ie, ie = null;
82
83
  }
83
84
  }
84
- let re = null;
85
- function je(a) {
86
- const t = new de();
85
+ let ie = null;
86
+ function tt(a) {
87
+ const t = new ge();
87
88
  for (const e in a.attributes)
88
89
  t.setAttribute(e, a.getAttribute(e));
89
90
  return t.setIndex(a.getIndex()), t;
90
91
  }
91
- const Y = new Array(), V = "NEEDLE_progressive", x = oe("debugprogressive"), Le = Symbol("needle-progressive-texture"), ne = /* @__PURE__ */ new Map(), ve = /* @__PURE__ */ new Set();
92
+ const Y = new Array(), V = "NEEDLE_progressive", x = le("debugprogressive"), Me = Symbol("needle-progressive-texture"), oe = /* @__PURE__ */ new Map(), Oe = /* @__PURE__ */ new Set();
92
93
  if (x) {
93
94
  let a = function() {
94
- t += 1, console.log("Toggle LOD level", t, ne), ne.forEach((n, r) => {
95
+ t += 1, console.log("Toggle LOD level", t, oe), oe.forEach((n, r) => {
95
96
  for (const i of n.keys) {
96
97
  const o = r[i];
97
98
  if (o != null) {
@@ -107,7 +108,7 @@ if (x) {
107
108
  }), t >= e && (t = -1);
108
109
  }, t = -1, e = 2, s = !1;
109
110
  window.addEventListener("keyup", (n) => {
110
- n.key === "p" && a(), n.key === "w" && (s = !s, ve && ve.forEach((r) => {
111
+ n.key === "p" && a(), n.key === "w" && (s = !s, Oe && Oe.forEach((r) => {
111
112
  r.name != "BackgroundCubeMaterial" && r.glyphMap == null && "wireframe" in r && (r.wireframe = s);
112
113
  }));
113
114
  });
@@ -116,8 +117,8 @@ function Te(a, t, e) {
116
117
  var n;
117
118
  if (!x)
118
119
  return;
119
- ne.has(a) || ne.set(a, { keys: [], sourceId: e });
120
- const s = ne.get(a);
120
+ oe.has(a) || oe.set(a, { keys: [], sourceId: e });
121
+ const s = oe.get(a);
121
122
  ((n = s == null ? void 0 : s.keys) == null ? void 0 : n.includes(t)) == !1 && s.keys.push(t);
122
123
  }
123
124
  const v = class {
@@ -269,7 +270,7 @@ const v = class {
269
270
  return Promise.resolve(null);
270
271
  if (t instanceof ze || t.isMaterial === !0) {
271
272
  const s = t, n = [], r = new Array();
272
- if (x && ve.add(s), s.uniforms && (s.isRawShaderMaterial || s.isShaderMaterial === !0)) {
273
+ if (x && Oe.add(s), s.uniforms && (s.isRawShaderMaterial || s.isShaderMaterial === !0)) {
273
274
  const i = s;
274
275
  for (const o of Object.keys(i.uniforms)) {
275
276
  const l = i.uniforms[o].value;
@@ -295,7 +296,7 @@ const v = class {
295
296
  return o;
296
297
  });
297
298
  }
298
- if (t instanceof te || t.isTexture === !0) {
299
+ if (t instanceof se || t.isTexture === !0) {
299
300
  const s = t;
300
301
  return this.assignTextureLODForSlot(s, e, null, null);
301
302
  }
@@ -372,7 +373,7 @@ const v = class {
372
373
  let i;
373
374
  if (t.isTexture === !0) {
374
375
  const g = t;
375
- g.source && g.source[Le] && (i = g.source[Le]);
376
+ g.source && g.source[Me] && (i = g.source[Me]);
376
377
  }
377
378
  if (i || (i = v.lodInfos.get(r)), i) {
378
379
  if (e > 0) {
@@ -384,7 +385,7 @@ const v = class {
384
385
  const g = Array.isArray(i.lods) ? (o = i.lods[e]) == null ? void 0 : o.path : i.lods;
385
386
  if (!g)
386
387
  return x && !i["missing:uri"] && (i["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + e, i)), null;
387
- const p = Je(n.url, g);
388
+ const p = Ze(n.url, g);
388
389
  if (p.endsWith(".glb") || p.endsWith(".gltf")) {
389
390
  if (!i.guid)
390
391
  return console.warn("missing pointer for glb/gltf texture", i), null;
@@ -393,11 +394,11 @@ const v = class {
393
394
  s && console.log(`LOD ${e} was already loading/loaded: ${M}`);
394
395
  let h = await w.catch(($) => (console.error(`Error loading LOD ${e} from ${p}
395
396
  `, $), null)), B = !1;
396
- if (h == null || (h instanceof te && t instanceof te ? (l = h.image) != null && l.data || (u = h.source) != null && u.data ? h = this.copySettings(t, h) : (B = !0, this.previouslyLoaded.delete(M)) : h instanceof de && t instanceof de && ((c = h.attributes.position) != null && c.array || (B = !0, this.previouslyLoaded.delete(M)))), !B)
397
+ if (h == null || (h instanceof se && t instanceof se ? (l = h.image) != null && l.data || (u = h.source) != null && u.data ? h = this.copySettings(t, h) : (B = !0, this.previouslyLoaded.delete(M)) : h instanceof ge && t instanceof ge && ((c = h.attributes.position) != null && c.array || (B = !0, this.previouslyLoaded.delete(M)))), !B)
397
398
  return h;
398
399
  }
399
400
  const L = i, F = new Promise(async (h, B) => {
400
- const $ = new Xe();
401
+ const $ = new qe();
401
402
  Ie($), x && (await new Promise((A) => setTimeout(A, 1e3)), s && console.warn("Start loading (delayed) " + p, L.guid));
402
403
  let I = p;
403
404
  if (L && Array.isArray(L.lods)) {
@@ -408,7 +409,7 @@ const v = class {
408
409
  `, A), null));
409
410
  if (!S)
410
411
  return null;
411
- const q = S.parser;
412
+ const X = S.parser;
412
413
  s && console.log("Loading finished " + p, L.guid);
413
414
  let T = 0;
414
415
  if (S.parser.json.textures) {
@@ -424,8 +425,8 @@ const v = class {
424
425
  T++;
425
426
  }
426
427
  if (A) {
427
- let f = await q.getDependency("texture", T);
428
- return f && v.assignLODInformation(n.url, f, r, e, void 0, void 0), s && console.log('change "' + t.name + '" → "' + f.name + '"', p, T, f, M), t instanceof te && (f = this.copySettings(t, f)), f && (f.guid = L.guid), h(f);
428
+ let f = await X.getDependency("texture", T);
429
+ return f && v.assignLODInformation(n.url, f, r, e, void 0, void 0), s && console.log('change "' + t.name + '" → "' + f.name + '"', p, T, f, M), t instanceof se && (f = this.copySettings(t, f)), f && (f.guid = L.guid), h(f);
429
430
  } else
430
431
  x && console.warn("Could not find texture with guid", L.guid, S.parser.json);
431
432
  }
@@ -442,7 +443,7 @@ const v = class {
442
443
  T++;
443
444
  }
444
445
  if (A) {
445
- const f = await q.getDependency("mesh", T), y = L;
446
+ const f = await X.getDependency("mesh", T), y = L;
446
447
  if (s && console.log(`Loaded Mesh "${f.name}"`, p, T, f, M), f.isMesh === !0) {
447
448
  const O = f.geometry;
448
449
  return v.assignLODInformation(n.url, O, r, e, void 0, y.density), h(O);
@@ -451,8 +452,8 @@ const v = class {
451
452
  for (let b = 0; b < f.children.length; b++) {
452
453
  const E = f.children[b];
453
454
  if (E.isMesh === !0) {
454
- const X = E.geometry;
455
- v.assignLODInformation(n.url, X, r, e, b, y.density), O.push(X);
455
+ const q = E.geometry;
456
+ v.assignLODInformation(n.url, q, r, e, b, y.density), O.push(q);
456
457
  }
457
458
  }
458
459
  return h(O);
@@ -463,7 +464,7 @@ const v = class {
463
464
  return h(null);
464
465
  });
465
466
  return this.previouslyLoaded.set(M, F), await F;
466
- } else if (t instanceof te) {
467
+ } else if (t instanceof se) {
467
468
  s && console.log("Load texture from uri: " + p);
468
469
  const w = await new Ve().loadAsync(p);
469
470
  return w ? (w.guid = i.guid, w.flipY = !1, w.needsUpdate = !0, w.colorSpace = t.colorSpace, s && console.log(i, w)) : x && console.warn("failed loading", p), w;
@@ -476,7 +477,7 @@ const v = class {
476
477
  if (!e)
477
478
  return;
478
479
  e.userData || (e.userData = {});
479
- const o = new et(t, s, n, r, i);
480
+ const o = new st(t, s, n, r, i);
480
481
  e.userData.LODS = o;
481
482
  }
482
483
  static getAssignedLODInformation(t) {
@@ -499,7 +500,7 @@ d(_, "registerTexture", (t, e, s, n, r) => {
499
500
  x && console.error("gltf-progressive: Register texture without texture");
500
501
  return;
501
502
  }
502
- e.source && (e.source[Le] = r);
503
+ e.source && (e.source[Me] = r);
503
504
  const i = r.guid;
504
505
  v.assignLODInformation(t, e, i, s, n, void 0), v.lodInfos.set(i, r), v.lowresCache.set(i, e);
505
506
  }), /**
@@ -515,14 +516,14 @@ d(_, "registerMesh", (t, e, s, n, r, i) => {
515
516
  }
516
517
  o.userData || (o.userData = {}), v.assignLODInformation(t, o, e, n, r, i.density), v.lodInfos.set(e, i);
517
518
  let l = v.lowresCache.get(e);
518
- l ? l.push(s.geometry) : l = [s.geometry], v.lowresCache.set(e, l), n > 0 && !ye(s) && Ze(s, o);
519
+ l ? l.push(s.geometry) : l = [s.geometry], v.lowresCache.set(e, l), n > 0 && !me(s) && et(s, o);
519
520
  for (const c of Y)
520
521
  (u = c.onRegisteredNewMesh) == null || u.call(c, s, i);
521
522
  }), /** A map of key = asset uuid and value = LOD information */
522
523
  d(_, "lodInfos", /* @__PURE__ */ new Map()), /** cache of already loaded mesh lods */
523
524
  d(_, "previouslyLoaded", /* @__PURE__ */ new Map()), /** this contains the geometry/textures that were originally loaded */
524
525
  d(_, "lowresCache", /* @__PURE__ */ new Map());
525
- class et {
526
+ class st {
526
527
  constructor(t, e, s, n, r) {
527
528
  d(this, "url");
528
529
  /** the key to lookup the LOD information */
@@ -535,8 +536,8 @@ class et {
535
536
  this.url = t, this.key = e, this.level = s, n != null && (this.index = n), r != null && (this.density = r);
536
537
  }
537
538
  }
538
- const k = oe("debugprogressive"), tt = oe("noprogressive"), Me = Symbol("Needle:LODSManager"), De = Symbol("Needle:LODState"), J = Symbol("Needle:CurrentLOD"), R = { mesh_lod: -1, texture_lod: -1 };
539
- var C, N, ge, j, ee, pe, W;
539
+ const k = le("debugprogressive"), rt = le("noprogressive"), De = Symbol("Needle:LODSManager"), we = Symbol("Needle:LODState"), J = Symbol("Needle:CurrentLOD"), R = { mesh_lod: -1, texture_lod: -1 };
540
+ var C, N, pe, ee, te, ye, W;
540
541
  const P = class {
541
542
  // readonly plugins: NEEDLE_progressive_plugin[] = [];
542
543
  constructor(t, e) {
@@ -567,14 +568,14 @@ const P = class {
567
568
  d(this, "manual", !1);
568
569
  d(this, "_lodchangedlisteners", []);
569
570
  K(this, N, void 0);
570
- K(this, ge, new Ne());
571
- K(this, j, 0);
571
+ K(this, pe, new Ne());
572
572
  K(this, ee, 0);
573
- K(this, pe, 0);
573
+ K(this, te, 0);
574
+ K(this, ye, 0);
574
575
  K(this, W, 0);
575
576
  d(this, "_fpsBuffer", [60, 60, 60, 60, 60]);
576
577
  // private testIfLODLevelsAreAvailable() {
577
- d(this, "_sphere", new qe());
578
+ d(this, "_sphere", new Xe());
578
579
  d(this, "_tempBox", new be());
579
580
  d(this, "_tempBox2", new be());
580
581
  d(this, "tempMatrix", new Se());
@@ -585,7 +586,7 @@ const P = class {
585
586
  }
586
587
  /** @internal */
587
588
  static getObjectLODState(t) {
588
- return t[De];
589
+ return t[we];
589
590
  }
590
591
  static addPlugin(t) {
591
592
  Y.push(t);
@@ -600,13 +601,13 @@ const P = class {
600
601
  * @returns The LODsManager instance.
601
602
  */
602
603
  static get(t, e) {
603
- if (t[Me])
604
- return console.debug("[gltf-progressive] LODsManager already exists for this renderer"), t[Me];
604
+ if (t[De])
605
+ return console.debug("[gltf-progressive] LODsManager already exists for this renderer"), t[De];
605
606
  const s = new P(t, {
606
607
  engine: "unknown",
607
608
  ...e
608
609
  });
609
- return t[Me] = s, s;
610
+ return t[De] = s, s;
610
611
  }
611
612
  /** @deprecated use static `LODsManager.addPlugin()` method. This getter will be removed in later versions */
612
613
  get plugins() {
@@ -633,7 +634,7 @@ const P = class {
633
634
  const e = this;
634
635
  Be(this.renderer), this.renderer.render = function(s, n) {
635
636
  const r = e.renderer.getRenderTarget();
636
- (r == null || "isXRRenderTarget" in r && r.isXRRenderTarget) && (t = 0, U(e, j, m(e, j) + 1), U(e, ee, m(e, ge).getDelta()), U(e, pe, m(e, pe) + m(e, ee)), e._fpsBuffer.shift(), e._fpsBuffer.push(1 / m(e, ee)), U(e, W, e._fpsBuffer.reduce((o, l) => o + l) / e._fpsBuffer.length), k && m(e, j) % 200 === 0 && console.log("FPS", Math.round(m(e, W)), "Interval:", m(e, C)));
637
+ (r == null || "isXRRenderTarget" in r && r.isXRRenderTarget) && (t = 0, U(e, ee, m(e, ee) + 1), U(e, te, m(e, pe).getDelta()), U(e, ye, m(e, ye) + m(e, te)), e._fpsBuffer.shift(), e._fpsBuffer.push(1 / m(e, te)), U(e, W, e._fpsBuffer.reduce((o, l) => o + l) / e._fpsBuffer.length), k && m(e, ee) % 200 === 0 && console.log("FPS", Math.round(m(e, W)), "Interval:", m(e, C)));
637
638
  const i = t++;
638
639
  m(e, N).call(this, s, n), e.onAfterRender(s, n, i);
639
640
  };
@@ -654,7 +655,7 @@ const P = class {
654
655
  (o.name === "EffectMaterial" || o.name === "CopyShader") && (i = !1);
655
656
  }
656
657
  if ((e.parent && e.parent.type === "CubeCamera" || s >= 1 && e.type === "OrthographicCamera") && (i = !1), i) {
657
- if (tt || (this.updateInterval === "auto" ? m(this, W) < 40 && m(this, C) < 10 ? (U(this, C, m(this, C) + 1), k && console.warn("↓ Reducing LOD updates", m(this, C), m(this, W).toFixed(0))) : m(this, W) >= 60 && m(this, C) > 1 && (U(this, C, m(this, C) - 1), k && console.warn("↑ Increasing LOD updates", m(this, C), m(this, W).toFixed(0))) : U(this, C, this.updateInterval), m(this, C) > 0 && m(this, j) % m(this, C) != 0))
658
+ if (rt || (this.updateInterval === "auto" ? m(this, W) < 40 && m(this, C) < 10 ? (U(this, C, m(this, C) + 1), k && console.warn("↓ Reducing LOD updates", m(this, C), m(this, W).toFixed(0))) : m(this, W) >= 60 && m(this, C) > 1 && (U(this, C, m(this, C) - 1), k && console.warn("↑ Increasing LOD updates", m(this, C), m(this, W).toFixed(0))) : U(this, C, this.updateInterval), m(this, C) > 0 && m(this, ee) % m(this, C) != 0))
658
659
  return;
659
660
  this.internalUpdate(t, e);
660
661
  }
@@ -704,8 +705,8 @@ const P = class {
704
705
  updateLODs(t, e, s, n) {
705
706
  var o, l;
706
707
  s.userData || (s.userData = {});
707
- let r = s[De];
708
- if (r || (r = new st(), s[De] = r), r.frames++ < 2)
708
+ let r = s[we];
709
+ if (r || (r = new it(), s[we] = r), r.frames++ < 2)
709
710
  return;
710
711
  for (const u of Y)
711
712
  (o = u.onBeforeUpdateLOD) == null || o.call(u, this.renderer, t, e, s);
@@ -783,7 +784,7 @@ const P = class {
783
784
  if (!D.boundingBox)
784
785
  D.computeBoundingBox();
785
786
  else if (s.frames % 30 === 0) {
786
- const h = ye(D), B = D.geometry;
787
+ const h = me(D), B = D.geometry;
787
788
  h && (D.geometry = h), D.computeBoundingBox(), D.geometry = B;
788
789
  }
789
790
  L = D.boundingBox;
@@ -804,11 +805,11 @@ const P = class {
804
805
  }
805
806
  if (this._tempBox.applyMatrix4(this.projectionScreenMatrix), this.renderer.xr.enabled && D.fov > 70) {
806
807
  const f = this._tempBox.min, y = this._tempBox.max;
807
- let O = f.x, b = f.y, E = y.x, X = y.y;
808
- const ae = 2, me = 1.5, le = (f.x + y.x) * 0.5, ce = (f.y + y.y) * 0.5;
809
- O = (O - le) * ae + le, b = (b - ce) * ae + ce, E = (E - le) * ae + le, X = (X - ce) * ae + ce;
810
- const Ge = O < 0 && E > 0 ? 0 : Math.min(Math.abs(f.x), Math.abs(y.x)), Fe = b < 0 && X > 0 ? 0 : Math.min(Math.abs(f.y), Math.abs(y.y)), xe = Math.max(Ge, Fe);
811
- s.lastCentrality = (me - xe) * (me - xe) * (me - xe);
808
+ let O = f.x, b = f.y, E = y.x, q = y.y;
809
+ const ce = 2, xe = 1.5, ue = (f.x + y.x) * 0.5, fe = (f.y + y.y) * 0.5;
810
+ O = (O - ue) * ce + ue, b = (b - fe) * ce + fe, E = (E - ue) * ce + ue, q = (q - fe) * ce + fe;
811
+ const Ge = O < 0 && E > 0 ? 0 : Math.min(Math.abs(f.x), Math.abs(y.x)), Fe = b < 0 && q > 0 ? 0 : Math.min(Math.abs(f.y), Math.abs(y.y)), Le = Math.max(Ge, Fe);
812
+ s.lastCentrality = (xe - Le) * (xe - Le) * (xe - Le);
812
813
  } else
813
814
  s.lastCentrality = 1;
814
815
  const h = this._tempBox.getSize(this._tempBoxSize);
@@ -821,8 +822,8 @@ const P = class {
821
822
  f.invert();
822
823
  const y = P.corner0, O = P.corner1, b = P.corner2, E = P.corner3;
823
824
  y.copy(this._tempBox.min), O.copy(this._tempBox.max), O.x = y.x, b.copy(this._tempBox.max), b.y = y.y, E.copy(this._tempBox.max);
824
- const X = (y.z + E.z) * 0.5;
825
- y.z = O.z = b.z = E.z = X, y.applyMatrix4(f), O.applyMatrix4(f), b.applyMatrix4(f), E.applyMatrix4(f), P.debugDrawLine(y, O, 255), P.debugDrawLine(y, b, 255), P.debugDrawLine(O, E, 255), P.debugDrawLine(b, E, 255);
825
+ const q = (y.z + E.z) * 0.5;
826
+ y.z = O.z = b.z = E.z = q, y.applyMatrix4(f), O.applyMatrix4(f), b.applyMatrix4(f), E.applyMatrix4(f), P.debugDrawLine(y, O, 255), P.debugDrawLine(y, b, 255), P.debugDrawLine(O, E, 255), P.debugDrawLine(b, E, 255);
826
827
  }
827
828
  let T = 999;
828
829
  if (c && s.lastScreenCoverage > 0) {
@@ -851,10 +852,10 @@ const P = class {
851
852
  ((F = this.context) == null ? void 0 : F.engine) === "model-viewer" && (B *= 2);
852
853
  const I = w / window.devicePixelRatio * B;
853
854
  for (let S = p.lods.length - 1; S >= 0; S--) {
854
- let q = p.lods[S];
855
- if (!(D && q.max_height >= 2048) && !(Qe() && q.max_height > 4096) && q.max_height > I) {
855
+ let X = p.lods[S];
856
+ if (!(D && X.max_height >= 2048) && !(je() && X.max_height > 4096) && X.max_height > I) {
856
857
  if (r.texture_lod = S, r.texture_lod < s.lastLodLevel_Texture) {
857
- const T = q.max_height;
858
+ const T = X.max_height;
858
859
  k && console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${r.texture_lod} = ${T}px
859
860
  Screensize: ${I.toFixed(0)}px, Coverage: ${(100 * s.lastScreenCoverage).toFixed(2)}%, Volume ${h.toFixed(1)}
860
861
  ${e.name}`);
@@ -868,10 +869,10 @@ ${e.name}`);
868
869
  }
869
870
  };
870
871
  let G = P;
871
- C = new WeakMap(), N = new WeakMap(), ge = new WeakMap(), j = new WeakMap(), ee = new WeakMap(), pe = new WeakMap(), W = 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.
872
+ C = new WeakMap(), N = new WeakMap(), pe = new WeakMap(), ee = new WeakMap(), te = new WeakMap(), ye = new WeakMap(), W = 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.
872
873
  */
873
874
  d(G, "debugDrawLine"), d(G, "corner0", new z()), d(G, "corner1", new z()), d(G, "corner2", new z()), d(G, "corner3", new z()), d(G, "_tempPtInside", new z());
874
- class st {
875
+ class it {
875
876
  constructor() {
876
877
  d(this, "frames", 0);
877
878
  d(this, "lastLodLevel_Mesh", -1);
@@ -881,21 +882,21 @@ class st {
881
882
  d(this, "lastCentrality", 0);
882
883
  }
883
884
  }
884
- const Ae = Symbol("NEEDLE_mesh_lod"), ue = Symbol("NEEDLE_texture_lod");
885
- let ie = null;
885
+ const Ae = Symbol("NEEDLE_mesh_lod"), de = Symbol("NEEDLE_texture_lod");
886
+ let ne = null;
886
887
  function ke() {
887
- const a = rt();
888
+ const a = nt();
888
889
  a && (a.mapURLs(function(t) {
889
890
  return Ee(), t;
890
- }), Ee(), ie == null || ie.disconnect(), ie = new MutationObserver((t) => {
891
+ }), Ee(), ne == null || ne.disconnect(), ne = new MutationObserver((t) => {
891
892
  t.forEach((e) => {
892
893
  e.addedNodes.forEach((s) => {
893
894
  s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" && Re(s);
894
895
  });
895
896
  });
896
- }), ie.observe(document, { childList: !0, subtree: !0 }));
897
+ }), ne.observe(document, { childList: !0, subtree: !0 }));
897
898
  }
898
- function rt() {
899
+ function nt() {
899
900
  if (typeof customElements > "u")
900
901
  return null;
901
902
  const a = customElements.get("model-viewer");
@@ -911,11 +912,11 @@ function Ee() {
911
912
  });
912
913
  }
913
914
  const Pe = /* @__PURE__ */ new WeakSet();
914
- let it = 0;
915
+ let ot = 0;
915
916
  function Re(a) {
916
917
  if (!a || Pe.has(a))
917
918
  return null;
918
- Pe.add(a), console.debug("[gltf-progressive] found new model-viewer..." + ++it + `
919
+ Pe.add(a), console.debug("[gltf-progressive] found new model-viewer..." + ++ot + `
919
920
  `, a.getAttribute("src"));
920
921
  let t = null, e = null, s = null;
921
922
  for (let n = a; n != null; n = Object.getPrototypeOf(n)) {
@@ -936,7 +937,7 @@ function Re(a) {
936
937
  };
937
938
  console.debug("[gltf-progressive] setup model-viewer");
938
939
  const r = G.get(t, { engine: "model-viewer" });
939
- return G.addPlugin(new nt()), r.enable(), r.addEventListener("changed", () => {
940
+ return G.addPlugin(new at()), r.enable(), r.addEventListener("changed", () => {
940
941
  s == null || s.call(a);
941
942
  }), a.addEventListener("model-visibility", (i) => {
942
943
  i.detail.visible && (s == null || s.call(a));
@@ -948,7 +949,7 @@ function Re(a) {
948
949
  }
949
950
  return null;
950
951
  }
951
- class nt {
952
+ class at {
952
953
  constructor() {
953
954
  d(this, "_didWarnAboutMissingUrl", !1);
954
955
  }
@@ -968,16 +969,16 @@ class nt {
968
969
  return t.element;
969
970
  }
970
971
  tryParseTextureLOD(t, e) {
971
- if (e[ue] == !0)
972
+ if (e[de] == !0)
972
973
  return;
973
- e[ue] = !0;
974
+ e[de] = !0;
974
975
  const s = this.tryGetCurrentGLTF(t), n = this.tryGetCurrentModelViewer(t), r = this.getUrl(n);
975
976
  if (r && s && e.material) {
976
977
  let i = function(l) {
977
978
  var c, g, p;
978
- if (l[ue] == !0)
979
+ if (l[de] == !0)
979
980
  return;
980
- l[ue] = !0, l.userData && (l.userData.LOD = -1);
981
+ l[de] = !0, l.userData && (l.userData.LOD = -1);
981
982
  const u = Object.keys(l);
982
983
  for (let M = 0; M < u.length; M++) {
983
984
  const w = u[M], L = l[w];
@@ -1020,7 +1021,7 @@ class nt {
1020
1021
  }
1021
1022
  }
1022
1023
  }
1023
- function pt(a, t, e, s) {
1024
+ function mt(a, t, e, s) {
1024
1025
  Be(t), Ie(e), e.register((r) => new _(r, a));
1025
1026
  const n = G.get(t);
1026
1027
  return (s == null ? void 0 : s.enableLODsManager) !== !1 && n.enable(), n;
@@ -1033,11 +1034,11 @@ export {
1033
1034
  Ce as VERSION,
1034
1035
  Ie as addDracoAndKTX2Loaders,
1035
1036
  Be as createLoaders,
1036
- ye as getRaycastMesh,
1037
+ me as getRaycastMesh,
1037
1038
  ke as patchModelViewer,
1038
- Ze as registerRaycastMesh,
1039
- dt as setDracoDecoderLocation,
1040
- ht as setKTX2TranscoderLocation,
1041
- pt as useNeedleProgressive,
1042
- gt as useRaycastMeshes
1039
+ et as registerRaycastMesh,
1040
+ gt as setDracoDecoderLocation,
1041
+ pt as setKTX2TranscoderLocation,
1042
+ mt as useNeedleProgressive,
1043
+ yt as useRaycastMeshes
1043
1044
  };
@@ -1,8 +1,8 @@
1
- var Re=Object.defineProperty,je=(t,e,r)=>e in t?Re(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,c=(t,e,r)=>(je(t,typeof e!="symbol"?e+"":e,r),r),Oe=(t,e,r)=>{if(!e.has(t))throw TypeError("Cannot "+r)},x=(t,e,r)=>(Oe(t,e,"read from private field"),r?r.call(t):e.get(t)),V=(t,e,r)=>{if(e.has(t))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(t):e.set(t,r)},G=(t,e,r,n)=>(Oe(t,e,"write to private field"),n?n.call(t,r):e.set(t,r),r);import{BufferGeometry as ie,Mesh as q,Material as Ge,Texture as Q,TextureLoader as Ne,Matrix4 as be,Clock as We,MeshStandardMaterial as Fe,Sphere as $e,Box3 as Se,Vector3 as N}from"three";import{GLTFLoader as Ue}from"three/examples/jsm/loaders/GLTFLoader.js";import{MeshoptDecoder as ze}from"three/examples/jsm/libs/meshopt_decoder.module.js";import{DRACOLoader as Ve}from"three/examples/jsm/loaders/DRACOLoader.js";import{KTX2Loader as qe}from"three/examples/jsm/loaders/KTX2Loader.js";const ge="";globalThis.GLTF_PROGRESSIVE_VERSION=ge,console.debug(`[gltf-progressive] version ${ge}`);let le="https://www.gstatic.com/draco/versioned/decoders/1.4.1/",me="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";fetch(le+"draco_decoder.js",{method:"head"}).catch(t=>{le="./include/draco/",me="./include/ktx2/"});function Xe(t){le=t}function Ke(t){me=t}let K,ae,H;function pe(t){return K||(K=new Ve,K.setDecoderPath(le),K.setDecoderConfig({type:"js"})),H||(H=new qe,H.setTranscoderPath(me)),ae||(ae=ze),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:ae}}function ve(t){t.dracoLoader||t.setDRACOLoader(K),t.ktx2Loader||t.setKTX2Loader(H),t.meshoptDecoder||t.setMeshoptDecoder(ae)}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 He(t,e){if(e===void 0||e.startsWith("./")||e.startsWith("http")||t===void 0)return e;const r=t.lastIndexOf("/");if(r>=0){const n=t.substring(0,r+1);for(;n.endsWith("/")&&e.startsWith("/");)e=e.substring(1);return n+e}return e}let ue;function Ye(){return ue!==void 0||(ue=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),Z("debugprogressive")&&console.log("[glTF Progressive]: isMobileDevice",ue)),ue}const xe=Symbol("needle:raycast-mesh");function ee(t){return t?.[xe]instanceof ie?t[xe]:null}function Te(t,e){if((t.type==="Mesh"||t.type==="SkinnedMesh")&&!ee(t)){const r=Qe(e);r.userData={isRaycastMesh:!0},t[xe]=r}}function Je(t=!0){if(t){if(te)return;const e=te=q.prototype.raycast;q.prototype.raycast=function(r,n){const s=this,o=ee(s);let i;o&&s.isMesh&&(i=s.geometry,s.geometry=o),e.call(this,r,n),i&&(s.geometry=i)}}else{if(!te)return;q.prototype.raycast=te,te=null}}let te=null;function Qe(t){const e=new ie;for(const r in t.attributes)e.setAttribute(r,t.getAttribute(r));return e.setIndex(t.getIndex()),e}const F=new Array,R="NEEDLE_progressive",y=Z("debugprogressive"),ye=Symbol("needle-progressive-texture"),re=new Map,Le=new Set;if(y){let t=function(){e+=1,console.log("Toggle LOD level",e,re),re.forEach((s,o)=>{for(const i of s.keys){const a=o[i];if(a!=null){if(a.isBufferGeometry===!0){const u=S.getMeshLODInformation(a),l=u?Math.min(e,u.lods.length):0;o["DEBUG:LOD"]=e,S.assignMeshLOD(o,l),u&&(r=Math.max(r,u.lods.length-1))}else if(o.isMaterial===!0){o["DEBUG:LOD"]=e,S.assignTextureLOD(o,e);break}}}}),e>=r&&(e=-1)},e=-1,r=2,n=!1;window.addEventListener("keyup",s=>{s.key==="p"&&t(),s.key==="w"&&(n=!n,Le&&Le.forEach(o=>{o.name!="BackgroundCubeMaterial"&&o.glyphMap==null&&"wireframe"in o&&(o.wireframe=n)}))})}function Ee(t,e,r){var n;if(!y)return;re.has(t)||re.set(t,{keys:[],sourceId:r});const s=re.get(t);((n=s?.keys)==null?void 0:n.includes(e))==!1&&s.keys.push(e)}const w=class{constructor(t,e){c(this,"parser"),c(this,"url"),c(this,"_isLoadingMesh"),c(this,"loadMesh",r=>{var n,s;if(this._isLoadingMesh)return null;const o=(s=(n=this.parser.json.meshes[r])==null?void 0:n.extensions)==null?void 0:s[R];return o?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",r).then(i=>{var a;return this._isLoadingMesh=!1,i&&w.registerMesh(this.url,o.guid,i,(a=o.lods)==null?void 0:a.length,void 0,o),i})):null}),y&&console.log("Progressive extension registered for",e),this.parser=t,this.url=e}get name(){return R}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,n="LODS:minmax",s=t[n];if(s!=null)return s;if(e||(e={min_count:1/0,max_count:0,lods:[]}),Array.isArray(t)){for(const i of t)this.getMaterialMinMaxLODsCount(i,e);return t[n]=e,e}if(y==="verbose"&&console.log("getMaterialMinMaxLODsCount",t),t.type==="ShaderMaterial"||t.type==="RawShaderMaterial"){const i=t;for(const a of Object.keys(i.uniforms)){const u=i.uniforms[a].value;u?.isTexture===!0&&o(u,e)}}else if(t.isMaterial)for(const i of Object.keys(t)){const a=t[i];a?.isTexture===!0&&o(a,e)}return t[n]=e,e;function o(i,a){const u=r.getAssignedLODInformation(i);if(u){const l=r.lodInfos.get(u.key);if(l&&l.lods){a.min_count=Math.min(a.min_count,l.lods.length),a.max_count=Math.max(a.max_count,l.lods.length);for(let f=0;f<l.lods.length;f++){const g=l.lods[f];g.width&&(a.lods[f]=a.lods[f]||{min_height:1/0,max_height:0},a.lods[f].min_height=Math.min(a.lods[f].min_height,g.height),a.lods[f].max_height=Math.max(a.lods[f].max_height,g.height))}}}}}static hasLODLevelAvailable(t,e){var r;if(Array.isArray(t)){for(const o of t)if(this.hasLODLevelAvailable(o,e))return!0;return!1}if(t.isMaterial===!0){for(const o of Object.keys(t)){const i=t[o];if(i&&i.isTexture&&this.hasLODLevelAvailable(i,e))return!0}return!1}else if(t.isGroup===!0){for(const o of t.children)if(o.isMesh===!0&&this.hasLODLevelAvailable(o,e))return!0}let n,s;if(t.isMesh?n=t.geometry:(t.isBufferGeometry||t.isTexture)&&(n=t),n&&(r=n?.userData)!=null&&r.LODS){const o=n.userData.LODS;if(s=this.lodInfos.get(o.key),e===void 0)return s!=null;if(s)return Array.isArray(s.lods)?e<s.lods.length:e===0}return!1}static assignMeshLOD(t,e){var r;if(!t)return Promise.resolve(null);if(t instanceof q||t.isMesh===!0){const n=t.geometry,s=this.getAssignedLODInformation(n);if(!s)return Promise.resolve(null);for(const o of F)(r=o.onBeforeGetLODMesh)==null||r.call(o,t,e);return t["LOD:requested level"]=e,w.getOrLoadLOD(n,e).then(o=>{if(t["LOD:requested level"]===e){if(delete t["LOD:requested level"],Array.isArray(o)){const i=s.index||0;o=o[i]}o&&n!=o&&(o?.isBufferGeometry?(t.geometry=o,y&&Ee(t,"geometry",s.url)):y&&console.error("Invalid LOD geometry",o))}return o}).catch(o=>(console.error("Error loading mesh LOD",t,o),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 Ge||t.isMaterial===!0){const r=t,n=[],s=new Array;if(y&&Le.add(r),r.uniforms&&(r.isRawShaderMaterial||r.isShaderMaterial===!0)){const o=r;for(const i of Object.keys(o.uniforms)){const a=o.uniforms[i].value;if(a?.isTexture===!0){const u=this.assignTextureLODForSlot(a,e,r,i).then(l=>(l&&o.uniforms[i].value!=l&&(o.uniforms[i].value=l,o.uniformsNeedUpdate=!0),l));n.push(u),s.push(i)}}}else for(const o of Object.keys(r)){const i=r[o];if(i?.isTexture===!0){const a=this.assignTextureLODForSlot(i,e,r,o);n.push(a),s.push(o)}}return Promise.all(n).then(o=>{const i=new Array;for(let a=0;a<o.length;a++){const u=o[a],l=s[a];u&&u.isTexture===!0?i.push({material:r,slot:l,texture:u,level:e}):i.push({material:r,slot:l,texture:null,level:e})}return i})}if(t instanceof Q||t.isTexture===!0){const r=t;return this.assignTextureLODForSlot(r,e,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(t,e,r,n){return t?.isTexture!==!0?Promise.resolve(null):n==="glyphMap"?Promise.resolve(t):w.getOrLoadLOD(t,e).then(s=>{if(Array.isArray(s))return null;if(s?.isTexture===!0){if(s!=t){if(r&&n){const o=r[n];if(o){const i=this.getAssignedLODInformation(o);if(i&&i?.level<e)return y==="verbose"&&console.warn("Assigned texture level is already higher: ",i.level,e,r,o,s),null}r[n]=s}if(y&&n&&r){const o=this.getAssignedLODInformation(t);o&&Ee(r,n,o.url)}}return s}else y=="verbose"&&console.warn("No LOD found for",t,e);return null}).catch(s=>(console.error("Error loading LOD",t,s),null))}afterRoot(t){var e,r;return y&&console.log("AFTER",this.url,t),(e=this.parser.json.textures)==null||e.forEach((n,s)=>{var o;if(n!=null&&n.extensions){const i=n?.extensions[R];if(i){if(!i.lods){y&&console.warn("Texture has no LODs",i);return}let a=!1;for(const u of this.parser.associations.keys())if(u.isTexture===!0){const l=this.parser.associations.get(u);l?.textures===s&&(a=!0,w.registerTexture(this.url,u,(o=i.lods)==null?void 0:o.length,s,i))}a||this.parser.getDependency("texture",s).then(u=>{var l;u&&w.registerTexture(this.url,u,(l=i.lods)==null?void 0:l.length,s,i)})}}}),(r=this.parser.json.meshes)==null||r.forEach((n,s)=>{if(n!=null&&n.extensions){const o=n?.extensions[R];if(o&&o.lods){for(const i of this.parser.associations.keys())if(i.isMesh){const a=this.parser.associations.get(i);a?.meshes===s&&w.registerMesh(this.url,o.guid,i,o.lods.length,a.primitives,o)}}}}),null}static async getOrLoadLOD(t,e){var r,n,s,o;const i=y=="verbose",a=t.userData.LODS;if(!a)return null;const u=a?.key;let l;if(t.isTexture===!0){const f=t;f.source&&f.source[ye]&&(l=f.source[ye])}if(l||(l=w.lodInfos.get(u)),l){if(e>0){let p=!1;const A=Array.isArray(l.lods);if(A&&e>=l.lods.length?p=!0:A||(p=!0),p)return this.lowresCache.get(u)}const f=Array.isArray(l.lods)?(r=l.lods[e])==null?void 0:r.path:l.lods;if(!f)return y&&!l["missing:uri"]&&(l["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+e,l)),null;const g=He(a.url,f);if(g.endsWith(".glb")||g.endsWith(".gltf")){if(!l.guid)return console.warn("missing pointer for glb/gltf texture",l),null;const p=g+"_"+l.guid,A=this.previouslyLoaded.get(p);if(A!==void 0){i&&console.log(`LOD ${e} was already loading/loaded: ${p}`);let d=await A.catch(O=>(console.error(`Error loading LOD ${e} from ${g}
2
- `,O),null)),_=!1;if(d==null||(d instanceof Q&&t instanceof Q?(n=d.image)!=null&&n.data||(s=d.source)!=null&&s.data?d=this.copySettings(t,d):(_=!0,this.previouslyLoaded.delete(p)):d instanceof ie&&t instanceof ie&&((o=d.attributes.position)!=null&&o.array||(_=!0,this.previouslyLoaded.delete(p)))),!_)return d}const D=l,L=new Promise(async(d,_)=>{const O=new Ue;ve(O),y&&(await new Promise(m=>setTimeout(m,1e3)),i&&console.warn("Start loading (delayed) "+g,D.guid));let I=g;if(D&&Array.isArray(D.lods)){const m=D.lods[e];m.hash&&(I+="?v="+m.hash)}const T=await O.loadAsync(I).catch(m=>(console.error(`Error loading LOD ${e} from ${g}
3
- `,m),null));if(!T)return null;const W=T.parser;i&&console.log("Loading finished "+g,D.guid);let v=0;if(T.parser.json.textures){let m=!1;for(const h of T.parser.json.textures){if(h!=null&&h.extensions){const M=h?.extensions[R];if(M!=null&&M.guid&&M.guid===D.guid){m=!0;break}}v++}if(m){let h=await W.getDependency("texture",v);return h&&w.assignLODInformation(a.url,h,u,e,void 0,void 0),i&&console.log('change "'+t.name+'" \u2192 "'+h.name+'"',g,v,h,p),t instanceof Q&&(h=this.copySettings(t,h)),h&&(h.guid=D.guid),d(h)}else y&&console.warn("Could not find texture with guid",D.guid,T.parser.json)}if(v=0,T.parser.json.meshes){let m=!1;for(const h of T.parser.json.meshes){if(h!=null&&h.extensions){const M=h?.extensions[R];if(M!=null&&M.guid&&M.guid===D.guid){m=!0;break}}v++}if(m){const h=await W.getDependency("mesh",v),M=D;if(i&&console.log(`Loaded Mesh "${h.name}"`,g,v,h,p),h.isMesh===!0){const b=h.geometry;return w.assignLODInformation(a.url,b,u,e,void 0,M.density),d(b)}else{const b=new Array;for(let C=0;C<h.children.length;C++){const z=h.children[C];if(z.isMesh===!0){const X=z.geometry;w.assignLODInformation(a.url,X,u,e,C,M.density),b.push(X)}}return d(b)}}else y&&console.warn("Could not find mesh with guid",D.guid,T.parser.json)}return d(null)});return this.previouslyLoaded.set(p,L),await L}else if(t instanceof Q){i&&console.log("Load texture from uri: "+g);const p=await new Ne().loadAsync(g);return p?(p.guid=l.guid,p.flipY=!1,p.needsUpdate=!0,p.colorSpace=t.colorSpace,i&&console.log(l,p)):y&&console.warn("failed loading",g),p}}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,r,n,s,o){if(!e)return;e.userData||(e.userData={});const i=new Ze(t,r,n,s,o);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,je=(t,e,r)=>e in t?Re(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,c=(t,e,r)=>(je(t,typeof e!="symbol"?e+"":e,r),r),Oe=(t,e,r)=>{if(!e.has(t))throw TypeError("Cannot "+r)},x=(t,e,r)=>(Oe(t,e,"read from private field"),r?r.call(t):e.get(t)),V=(t,e,r)=>{if(e.has(t))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(t):e.set(t,r)},G=(t,e,r,n)=>(Oe(t,e,"write to private field"),n?n.call(t,r):e.set(t,r),r);import{BufferGeometry as ae,Mesh as q,Material as Ge,Texture as Z,TextureLoader as Ne,Matrix4 as be,Clock as We,MeshStandardMaterial as Fe,Sphere as $e,Box3 as Se,Vector3 as N}from"three";import{GLTFLoader as Ue}from"three/examples/jsm/loaders/GLTFLoader.js";import{MeshoptDecoder as ze}from"three/examples/jsm/libs/meshopt_decoder.module.js";import{DRACOLoader as Ve}from"three/examples/jsm/loaders/DRACOLoader.js";import{KTX2Loader as qe}from"three/examples/jsm/loaders/KTX2Loader.js";const me="";globalThis.GLTF_PROGRESSIVE_VERSION=me,console.debug(`[gltf-progressive] version ${me}`);let K="https://www.gstatic.com/draco/versioned/decoders/1.5.7/",ee="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";const Xe=K,Ke=ee;fetch(K+"draco_decoder.js",{method:"head"}).catch(t=>{K===Xe&&(K="./include/draco/"),ee===Ke&&(ee="./include/ktx2/")});function He(t){K=t}function Ye(t){ee=t}let H,ue,Y;function pe(t){return H||(H=new Ve,H.setDecoderPath(K),H.setDecoderConfig({type:"js"})),Y||(Y=new qe,Y.setTranscoderPath(ee)),ue||(ue=ze),t?Y.detectSupport(t):t!==null&&console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"),{dracoLoader:H,ktx2Loader:Y,meshoptDecoder:ue}}function ve(t){t.dracoLoader||t.setDRACOLoader(H),t.ktx2Loader||t.setKTX2Loader(Y),t.meshoptDecoder||t.setMeshoptDecoder(ue)}te("debugprogressive");function te(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 r=t.lastIndexOf("/");if(r>=0){const n=t.substring(0,r+1);for(;n.endsWith("/")&&e.startsWith("/");)e=e.substring(1);return n+e}return e}let ce;function Qe(){return ce!==void 0||(ce=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),te("debugprogressive")&&console.log("[glTF Progressive]: isMobileDevice",ce)),ce}const xe=Symbol("needle:raycast-mesh");function re(t){return t?.[xe]instanceof ae?t[xe]:null}function Te(t,e){if((t.type==="Mesh"||t.type==="SkinnedMesh")&&!re(t)){const r=et(e);r.userData={isRaycastMesh:!0},t[xe]=r}}function Ze(t=!0){if(t){if(se)return;const e=se=q.prototype.raycast;q.prototype.raycast=function(r,n){const s=this,o=re(s);let i;o&&s.isMesh&&(i=s.geometry,s.geometry=o),e.call(this,r,n),i&&(s.geometry=i)}}else{if(!se)return;q.prototype.raycast=se,se=null}}let se=null;function et(t){const e=new ae;for(const r in t.attributes)e.setAttribute(r,t.getAttribute(r));return e.setIndex(t.getIndex()),e}const F=new Array,R="NEEDLE_progressive",y=te("debugprogressive"),ye=Symbol("needle-progressive-texture"),oe=new Map,Le=new Set;if(y){let t=function(){e+=1,console.log("Toggle LOD level",e,oe),oe.forEach((s,o)=>{for(const i of s.keys){const a=o[i];if(a!=null){if(a.isBufferGeometry===!0){const u=S.getMeshLODInformation(a),l=u?Math.min(e,u.lods.length):0;o["DEBUG:LOD"]=e,S.assignMeshLOD(o,l),u&&(r=Math.max(r,u.lods.length-1))}else if(o.isMaterial===!0){o["DEBUG:LOD"]=e,S.assignTextureLOD(o,e);break}}}}),e>=r&&(e=-1)},e=-1,r=2,n=!1;window.addEventListener("keyup",s=>{s.key==="p"&&t(),s.key==="w"&&(n=!n,Le&&Le.forEach(o=>{o.name!="BackgroundCubeMaterial"&&o.glyphMap==null&&"wireframe"in o&&(o.wireframe=n)}))})}function Ee(t,e,r){var n;if(!y)return;oe.has(t)||oe.set(t,{keys:[],sourceId:r});const s=oe.get(t);((n=s?.keys)==null?void 0:n.includes(e))==!1&&s.keys.push(e)}const w=class{constructor(t,e){c(this,"parser"),c(this,"url"),c(this,"_isLoadingMesh"),c(this,"loadMesh",r=>{var n,s;if(this._isLoadingMesh)return null;const o=(s=(n=this.parser.json.meshes[r])==null?void 0:n.extensions)==null?void 0:s[R];return o?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",r).then(i=>{var a;return this._isLoadingMesh=!1,i&&w.registerMesh(this.url,o.guid,i,(a=o.lods)==null?void 0:a.length,void 0,o),i})):null}),y&&console.log("Progressive extension registered for",e),this.parser=t,this.url=e}get name(){return R}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,n="LODS:minmax",s=t[n];if(s!=null)return s;if(e||(e={min_count:1/0,max_count:0,lods:[]}),Array.isArray(t)){for(const i of t)this.getMaterialMinMaxLODsCount(i,e);return t[n]=e,e}if(y==="verbose"&&console.log("getMaterialMinMaxLODsCount",t),t.type==="ShaderMaterial"||t.type==="RawShaderMaterial"){const i=t;for(const a of Object.keys(i.uniforms)){const u=i.uniforms[a].value;u?.isTexture===!0&&o(u,e)}}else if(t.isMaterial)for(const i of Object.keys(t)){const a=t[i];a?.isTexture===!0&&o(a,e)}return t[n]=e,e;function o(i,a){const u=r.getAssignedLODInformation(i);if(u){const l=r.lodInfos.get(u.key);if(l&&l.lods){a.min_count=Math.min(a.min_count,l.lods.length),a.max_count=Math.max(a.max_count,l.lods.length);for(let f=0;f<l.lods.length;f++){const g=l.lods[f];g.width&&(a.lods[f]=a.lods[f]||{min_height:1/0,max_height:0},a.lods[f].min_height=Math.min(a.lods[f].min_height,g.height),a.lods[f].max_height=Math.max(a.lods[f].max_height,g.height))}}}}}static hasLODLevelAvailable(t,e){var r;if(Array.isArray(t)){for(const o of t)if(this.hasLODLevelAvailable(o,e))return!0;return!1}if(t.isMaterial===!0){for(const o of Object.keys(t)){const i=t[o];if(i&&i.isTexture&&this.hasLODLevelAvailable(i,e))return!0}return!1}else if(t.isGroup===!0){for(const o of t.children)if(o.isMesh===!0&&this.hasLODLevelAvailable(o,e))return!0}let n,s;if(t.isMesh?n=t.geometry:(t.isBufferGeometry||t.isTexture)&&(n=t),n&&(r=n?.userData)!=null&&r.LODS){const o=n.userData.LODS;if(s=this.lodInfos.get(o.key),e===void 0)return s!=null;if(s)return Array.isArray(s.lods)?e<s.lods.length:e===0}return!1}static assignMeshLOD(t,e){var r;if(!t)return Promise.resolve(null);if(t instanceof q||t.isMesh===!0){const n=t.geometry,s=this.getAssignedLODInformation(n);if(!s)return Promise.resolve(null);for(const o of F)(r=o.onBeforeGetLODMesh)==null||r.call(o,t,e);return t["LOD:requested level"]=e,w.getOrLoadLOD(n,e).then(o=>{if(t["LOD:requested level"]===e){if(delete t["LOD:requested level"],Array.isArray(o)){const i=s.index||0;o=o[i]}o&&n!=o&&(o?.isBufferGeometry?(t.geometry=o,y&&Ee(t,"geometry",s.url)):y&&console.error("Invalid LOD geometry",o))}return o}).catch(o=>(console.error("Error loading mesh LOD",t,o),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 Ge||t.isMaterial===!0){const r=t,n=[],s=new Array;if(y&&Le.add(r),r.uniforms&&(r.isRawShaderMaterial||r.isShaderMaterial===!0)){const o=r;for(const i of Object.keys(o.uniforms)){const a=o.uniforms[i].value;if(a?.isTexture===!0){const u=this.assignTextureLODForSlot(a,e,r,i).then(l=>(l&&o.uniforms[i].value!=l&&(o.uniforms[i].value=l,o.uniformsNeedUpdate=!0),l));n.push(u),s.push(i)}}}else for(const o of Object.keys(r)){const i=r[o];if(i?.isTexture===!0){const a=this.assignTextureLODForSlot(i,e,r,o);n.push(a),s.push(o)}}return Promise.all(n).then(o=>{const i=new Array;for(let a=0;a<o.length;a++){const u=o[a],l=s[a];u&&u.isTexture===!0?i.push({material:r,slot:l,texture:u,level:e}):i.push({material:r,slot:l,texture:null,level:e})}return i})}if(t instanceof Z||t.isTexture===!0){const r=t;return this.assignTextureLODForSlot(r,e,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(t,e,r,n){return t?.isTexture!==!0?Promise.resolve(null):n==="glyphMap"?Promise.resolve(t):w.getOrLoadLOD(t,e).then(s=>{if(Array.isArray(s))return null;if(s?.isTexture===!0){if(s!=t){if(r&&n){const o=r[n];if(o){const i=this.getAssignedLODInformation(o);if(i&&i?.level<e)return y==="verbose"&&console.warn("Assigned texture level is already higher: ",i.level,e,r,o,s),null}r[n]=s}if(y&&n&&r){const o=this.getAssignedLODInformation(t);o&&Ee(r,n,o.url)}}return s}else y=="verbose"&&console.warn("No LOD found for",t,e);return null}).catch(s=>(console.error("Error loading LOD",t,s),null))}afterRoot(t){var e,r;return y&&console.log("AFTER",this.url,t),(e=this.parser.json.textures)==null||e.forEach((n,s)=>{var o;if(n!=null&&n.extensions){const i=n?.extensions[R];if(i){if(!i.lods){y&&console.warn("Texture has no LODs",i);return}let a=!1;for(const u of this.parser.associations.keys())if(u.isTexture===!0){const l=this.parser.associations.get(u);l?.textures===s&&(a=!0,w.registerTexture(this.url,u,(o=i.lods)==null?void 0:o.length,s,i))}a||this.parser.getDependency("texture",s).then(u=>{var l;u&&w.registerTexture(this.url,u,(l=i.lods)==null?void 0:l.length,s,i)})}}}),(r=this.parser.json.meshes)==null||r.forEach((n,s)=>{if(n!=null&&n.extensions){const o=n?.extensions[R];if(o&&o.lods){for(const i of this.parser.associations.keys())if(i.isMesh){const a=this.parser.associations.get(i);a?.meshes===s&&w.registerMesh(this.url,o.guid,i,o.lods.length,a.primitives,o)}}}}),null}static async getOrLoadLOD(t,e){var r,n,s,o;const i=y=="verbose",a=t.userData.LODS;if(!a)return null;const u=a?.key;let l;if(t.isTexture===!0){const f=t;f.source&&f.source[ye]&&(l=f.source[ye])}if(l||(l=w.lodInfos.get(u)),l){if(e>0){let p=!1;const A=Array.isArray(l.lods);if(A&&e>=l.lods.length?p=!0:A||(p=!0),p)return this.lowresCache.get(u)}const f=Array.isArray(l.lods)?(r=l.lods[e])==null?void 0:r.path:l.lods;if(!f)return y&&!l["missing:uri"]&&(l["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+e,l)),null;const g=Je(a.url,f);if(g.endsWith(".glb")||g.endsWith(".gltf")){if(!l.guid)return console.warn("missing pointer for glb/gltf texture",l),null;const p=g+"_"+l.guid,A=this.previouslyLoaded.get(p);if(A!==void 0){i&&console.log(`LOD ${e} was already loading/loaded: ${p}`);let d=await A.catch(O=>(console.error(`Error loading LOD ${e} from ${g}
2
+ `,O),null)),_=!1;if(d==null||(d instanceof Z&&t instanceof Z?(n=d.image)!=null&&n.data||(s=d.source)!=null&&s.data?d=this.copySettings(t,d):(_=!0,this.previouslyLoaded.delete(p)):d instanceof ae&&t instanceof ae&&((o=d.attributes.position)!=null&&o.array||(_=!0,this.previouslyLoaded.delete(p)))),!_)return d}const D=l,L=new Promise(async(d,_)=>{const O=new Ue;ve(O),y&&(await new Promise(m=>setTimeout(m,1e3)),i&&console.warn("Start loading (delayed) "+g,D.guid));let I=g;if(D&&Array.isArray(D.lods)){const m=D.lods[e];m.hash&&(I+="?v="+m.hash)}const T=await O.loadAsync(I).catch(m=>(console.error(`Error loading LOD ${e} from ${g}
3
+ `,m),null));if(!T)return null;const W=T.parser;i&&console.log("Loading finished "+g,D.guid);let v=0;if(T.parser.json.textures){let m=!1;for(const h of T.parser.json.textures){if(h!=null&&h.extensions){const M=h?.extensions[R];if(M!=null&&M.guid&&M.guid===D.guid){m=!0;break}}v++}if(m){let h=await W.getDependency("texture",v);return h&&w.assignLODInformation(a.url,h,u,e,void 0,void 0),i&&console.log('change "'+t.name+'" \u2192 "'+h.name+'"',g,v,h,p),t instanceof Z&&(h=this.copySettings(t,h)),h&&(h.guid=D.guid),d(h)}else y&&console.warn("Could not find texture with guid",D.guid,T.parser.json)}if(v=0,T.parser.json.meshes){let m=!1;for(const h of T.parser.json.meshes){if(h!=null&&h.extensions){const M=h?.extensions[R];if(M!=null&&M.guid&&M.guid===D.guid){m=!0;break}}v++}if(m){const h=await W.getDependency("mesh",v),M=D;if(i&&console.log(`Loaded Mesh "${h.name}"`,g,v,h,p),h.isMesh===!0){const b=h.geometry;return w.assignLODInformation(a.url,b,u,e,void 0,M.density),d(b)}else{const b=new Array;for(let C=0;C<h.children.length;C++){const z=h.children[C];if(z.isMesh===!0){const X=z.geometry;w.assignLODInformation(a.url,X,u,e,C,M.density),b.push(X)}}return d(b)}}else y&&console.warn("Could not find mesh with guid",D.guid,T.parser.json)}return d(null)});return this.previouslyLoaded.set(p,L),await L}else if(t instanceof Z){i&&console.log("Load texture from uri: "+g);const p=await new Ne().loadAsync(g);return p?(p.guid=l.guid,p.flipY=!1,p.needsUpdate=!0,p.colorSpace=t.colorSpace,i&&console.log(l,p)):y&&console.warn("failed loading",g),p}}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,r,n,s,o){if(!e)return;e.userData||(e.userData={});const i=new tt(t,r,n,s,o);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 S=w;c(S,"registerTexture",(t,e,r,n,s)=>{if(y&&console.log("> Progressive: register texture",n,e.name,e.uuid,e,s),!e){y&&console.error("gltf-progressive: Register texture without texture");return}e.source&&(e.source[ye]=s);const o=s.guid;w.assignLODInformation(t,e,o,r,n,void 0),w.lodInfos.set(o,s),w.lowresCache.set(o,e)}),c(S,"registerMesh",(t,e,r,n,s,o)=>{var i;y&&console.log("> Progressive: register mesh",s,r.name,o,r.uuid,r);const a=r.geometry;if(!a){y&&console.warn("gltf-progressive: Register mesh without geometry");return}a.userData||(a.userData={}),w.assignLODInformation(t,a,e,n,s,o.density),w.lodInfos.set(e,o);let u=w.lowresCache.get(e);u?u.push(r.geometry):u=[r.geometry],w.lowresCache.set(e,u),n>0&&!ee(r)&&Te(r,a);for(const l of F)(i=l.onRegisteredNewMesh)==null||i.call(l,r,o)}),c(S,"lodInfos",new Map),c(S,"previouslyLoaded",new Map),c(S,"lowresCache",new Map);class Ze{constructor(e,r,n,s,o){c(this,"url"),c(this,"key"),c(this,"level"),c(this,"index"),c(this,"density"),this.url=e,this.key=r,this.level=n,s!=null&&(this.index=s),o!=null&&(this.density=o)}}const P=Z("debugprogressive"),et=Z("noprogressive"),Me=Symbol("Needle:LODSManager"),De=Symbol("Needle:LODState"),Y=Symbol("Needle:CurrentLOD"),k={mesh_lod:-1,texture_lod:-1};var E,$,we,J,se,ce,U;const B=class{constructor(t,e){c(this,"context"),c(this,"renderer"),c(this,"projectionScreenMatrix",new be),c(this,"targetTriangleDensity",2e5),c(this,"updateInterval","auto"),V(this,E,1),c(this,"pause",!1),c(this,"manual",!1),c(this,"_lodchangedlisteners",[]),V(this,$,void 0),V(this,we,new We),V(this,J,0),V(this,se,0),V(this,ce,0),V(this,U,0),c(this,"_fpsBuffer",[60,60,60,60,60]),c(this,"_sphere",new $e),c(this,"_tempBox",new Se),c(this,"_tempBox2",new Se),c(this,"tempMatrix",new be),c(this,"_tempWorldPosition",new N),c(this,"_tempBoxSize",new N),c(this,"_tempBox2Size",new N),this.renderer=t,this.context={...e}}static getObjectLODState(t){return t[De]}static addPlugin(t){F.push(t)}static removePlugin(t){const e=F.indexOf(t);e>=0&&F.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 F}addEventListener(t,e){t==="changed"&&this._lodchangedlisteners.push(e)}removeEventListener(t,e){if(t==="changed"){const r=this._lodchangedlisteners.indexOf(e);r>=0&&this._lodchangedlisteners.splice(r,1)}}enable(){if(x(this,$))return;console.debug("[gltf-progressive] Enabling LODsManager for renderer");let t=0;G(this,$,this.renderer.render);const e=this;pe(this.renderer),this.renderer.render=function(r,n){const s=e.renderer.getRenderTarget();(s==null||"isXRRenderTarget"in s&&s.isXRRenderTarget)&&(t=0,G(e,J,x(e,J)+1),G(e,se,x(e,we).getDelta()),G(e,ce,x(e,ce)+x(e,se)),e._fpsBuffer.shift(),e._fpsBuffer.push(1/x(e,se)),G(e,U,e._fpsBuffer.reduce((i,a)=>i+a)/e._fpsBuffer.length),P&&x(e,J)%200===0&&console.log("FPS",Math.round(x(e,U)),"Interval:",x(e,E)));const o=t++;x(e,$).call(this,r,n),e.onAfterRender(r,n,o)}}disable(){x(this,$)&&(this.renderer.render=x(this,$),G(this,$,void 0))}update(t,e){this.internalUpdate(t,e)}onAfterRender(t,e,r){if(this.pause)return;const n=this.renderer.renderLists.get(t,0).opaque;let s=!0;if(n.length===1){const o=n[0].material;(o.name==="EffectMaterial"||o.name==="CopyShader")&&(s=!1)}if((e.parent&&e.parent.type==="CubeCamera"||r>=1&&e.type==="OrthographicCamera")&&(s=!1),s){if(et||(this.updateInterval==="auto"?x(this,U)<40&&x(this,E)<10?(G(this,E,x(this,E)+1),P&&console.warn("\u2193 Reducing LOD updates",x(this,E),x(this,U).toFixed(0))):x(this,U)>=60&&x(this,E)>1&&(G(this,E,x(this,E)-1),P&&console.warn("\u2191 Increasing LOD updates",x(this,E),x(this,U).toFixed(0))):G(this,E,this.updateInterval),x(this,E)>0&&x(this,J)%x(this,E)!=0))return;this.internalUpdate(t,e)}}internalUpdate(t,e){var r,n;const s=this.renderer.renderLists.get(t,0),o=s.opaque;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse);const i=this.targetTriangleDensity;for(const l of o){if(l.material&&(((r=l.geometry)==null?void 0:r.type)==="BoxGeometry"||((n=l.geometry)==null?void 0:n.type)==="BufferGeometry")&&(l.material.name==="SphericalGaussianBlur"||l.material.name=="BackgroundCubeMaterial"||l.material.name==="CubemapFromEquirect"||l.material.name==="EquirectangularToCubeUV")){P&&(l.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(l.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",l,l.material.name,l.material.type)));continue}switch(l.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}if(P==="color"&&l.material&&!l.object.progressive_debug_color){l.object.progressive_debug_color=!0;const g=Math.random()*16777215,p=new Fe({color:g});l.object.material=p}const f=l.object;(f instanceof q||f.isMesh)&&this.updateLODs(t,e,f,i)}const a=s.transparent;for(const l of a){const f=l.object;(f instanceof q||f.isMesh)&&this.updateLODs(t,e,f,i)}const u=s.transmissive;for(const l of u){const f=l.object;(f instanceof q||f.isMesh)&&this.updateLODs(t,e,f,i)}}updateLODs(t,e,r,n){var s,o;r.userData||(r.userData={});let i=r[De];if(i||(i=new tt,r[De]=i),i.frames++<2)return;for(const u of F)(s=u.onBeforeUpdateLOD)==null||s.call(u,this.renderer,t,e,r);this.calculateLodLevel(e,r,i,n,k),k.mesh_lod=Math.round(k.mesh_lod),k.texture_lod=Math.round(k.texture_lod),k.mesh_lod>=0&&this.loadProgressiveMeshes(r,k.mesh_lod);let a=k.texture_lod;if(r.material&&a>=0){const u=r["DEBUG:LOD"];u!=null&&(a=u),this.loadProgressiveTextures(r.material,a)}for(const u of F)(o=u.onAfterUpdatedLOD)==null||o.call(u,this.renderer,t,e,r,k);i.lastLodLevel_Mesh=k.mesh_lod,i.lastLodLevel_Texture=k.texture_lod}loadProgressiveTextures(t,e){if(!t)return;if(Array.isArray(t)){for(const n of t)this.loadProgressiveTextures(n,e);return}let r=!1;(t[Y]===void 0||e<t[Y])&&(r=!0),r&&(t[Y]=e,S.assignTextureLOD(t,e).then(n=>{this._lodchangedlisteners.forEach(s=>s({type:"texture",level:e,object:t}))}))}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);if(t[Y]!==e){t[Y]=e;const r=t.geometry;return S.assignMeshLOD(t,e).then(n=>(n&&t[Y]==e&&r!=t.geometry&&this._lodchangedlisteners.forEach(s=>s({type:"mesh",level:e,object:t})),n))}return Promise.resolve(null)}static isInside(t,e){const r=t.min,n=t.max,s=(r.x+n.x)*.5,o=(r.y+n.y)*.5;return this._tempPtInside.set(s,o,r.z).applyMatrix4(e).z<0}calculateLodLevel(t,e,r,n,s){var o;if(!e){s.mesh_lod=-1,s.texture_lod=-1;return}if(!t){s.mesh_lod=-1,s.texture_lod=-1;return}let i=10+1,a=!1;if(P&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const u=S.getMeshLODInformation(e.geometry),l=u?.lods,f=l&&l.length>0,g=S.getMaterialMinMaxLODsCount(e.material),p=g?.min_count!=1/0&&g.min_count>0&&g.max_count>0;if(!f&&!p){s.mesh_lod=0,s.texture_lod=0;return}f||(a=!0,i=0);const A=this.renderer.domElement.clientHeight||this.renderer.domElement.height;let D=e.geometry.boundingBox;if(e.type==="SkinnedMesh"){const L=e;if(!L.boundingBox)L.computeBoundingBox();else if(r.frames%30===0){const d=ee(L),_=L.geometry;d&&(L.geometry=d),L.computeBoundingBox(),L.geometry=_}D=L.boundingBox}if(D&&t.isPerspectiveCamera){const L=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 v=t.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(v)){s.mesh_lod=0,s.texture_lod=0;return}}if(this._tempBox.copy(D),this._tempBox.applyMatrix4(e.matrixWorld),B.isInside(this._tempBox,this.projectionScreenMatrix)){s.mesh_lod=0,s.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&L.fov>70){const v=this._tempBox.min,m=this._tempBox.max;let h=v.x,M=v.y,b=m.x,C=m.y;const z=2,X=1.5,oe=(v.x+m.x)*.5,ne=(v.y+m.y)*.5;h=(h-oe)*z+oe,M=(M-ne)*z+ne,b=(b-oe)*z+oe,C=(C-ne)*z+ne;const ke=h<0&&b>0?0:Math.min(Math.abs(v.x),Math.abs(m.x)),Ce=M<0&&C>0?0:Math.min(Math.abs(v.y),Math.abs(m.y)),fe=Math.max(ke,Ce);r.lastCentrality=(X-fe)*(X-fe)*(X-fe)}else r.lastCentrality=1;const d=this._tempBox.getSize(this._tempBoxSize);d.multiplyScalar(.5),screen.availHeight>0&&A>0&&d.multiplyScalar(A/screen.availHeight),d.x*=L.aspect;const _=t.matrixWorldInverse,O=this._tempBox2;O.copy(D),O.applyMatrix4(e.matrixWorld),O.applyMatrix4(_);const I=O.getSize(this._tempBox2Size),T=Math.max(I.x,I.y);if(Math.max(d.x,d.y)!=0&&T!=0&&(d.z=I.z/Math.max(I.x,I.y)*Math.max(d.x,d.y)),r.lastScreenCoverage=Math.max(d.x,d.y,d.z),r.lastScreenspaceVolume.copy(d),r.lastScreenCoverage*=r.lastCentrality,P&&B.debugDrawLine){const v=this.tempMatrix.copy(this.projectionScreenMatrix);v.invert();const m=B.corner0,h=B.corner1,M=B.corner2,b=B.corner3;m.copy(this._tempBox.min),h.copy(this._tempBox.max),h.x=m.x,M.copy(this._tempBox.max),M.y=m.y,b.copy(this._tempBox.max);const C=(m.z+b.z)*.5;m.z=h.z=M.z=b.z=C,m.applyMatrix4(v),h.applyMatrix4(v),M.applyMatrix4(v),b.applyMatrix4(v),B.debugDrawLine(m,h,255),B.debugDrawLine(m,M,255),B.debugDrawLine(h,b,255),B.debugDrawLine(M,b,255)}let W=999;if(l&&r.lastScreenCoverage>0){for(let v=0;v<l.length;v++)if(l[v].density/r.lastScreenCoverage<n){W=v;break}}W<i&&(i=W,a=!0)}if(a?s.mesh_lod=i:s.mesh_lod=r.lastLodLevel_Mesh,P&&s.mesh_lod!=r.lastLodLevel_Mesh){const L=l?.[s.mesh_lod];L&&console.log(`Mesh LOD changed: ${r.lastLodLevel_Mesh} \u2192 ${s.mesh_lod} (${L.density.toFixed(0)}) - ${e.name}`)}if(p){const L="saveData"in globalThis.navigator&&globalThis.navigator.saveData===!0;if(r.lastLodLevel_Texture<0){if(s.texture_lod=g.max_count-1,P){const d=g.lods[g.max_count-1];P&&console.log(`First Texture LOD ${s.texture_lod} (${d.max_height}px) - ${e.name}`)}}else{const d=r.lastScreenspaceVolume.x+r.lastScreenspaceVolume.y+r.lastScreenspaceVolume.z;let _=r.lastScreenCoverage*2;((o=this.context)==null?void 0:o.engine)==="model-viewer"&&(_*=2);const O=A/window.devicePixelRatio*_;for(let I=g.lods.length-1;I>=0;I--){let T=g.lods[I];if(!(L&&T.max_height>=2048)&&!(Ye()&&T.max_height>4096)&&T.max_height>O){if(s.texture_lod=I,s.texture_lod<r.lastLodLevel_Texture){const W=T.max_height;P&&console.log(`Texture LOD changed: ${r.lastLodLevel_Texture} \u2192 ${s.texture_lod} = ${W}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 S=w;c(S,"registerTexture",(t,e,r,n,s)=>{if(y&&console.log("> Progressive: register texture",n,e.name,e.uuid,e,s),!e){y&&console.error("gltf-progressive: Register texture without texture");return}e.source&&(e.source[ye]=s);const o=s.guid;w.assignLODInformation(t,e,o,r,n,void 0),w.lodInfos.set(o,s),w.lowresCache.set(o,e)}),c(S,"registerMesh",(t,e,r,n,s,o)=>{var i;y&&console.log("> Progressive: register mesh",s,r.name,o,r.uuid,r);const a=r.geometry;if(!a){y&&console.warn("gltf-progressive: Register mesh without geometry");return}a.userData||(a.userData={}),w.assignLODInformation(t,a,e,n,s,o.density),w.lodInfos.set(e,o);let u=w.lowresCache.get(e);u?u.push(r.geometry):u=[r.geometry],w.lowresCache.set(e,u),n>0&&!re(r)&&Te(r,a);for(const l of F)(i=l.onRegisteredNewMesh)==null||i.call(l,r,o)}),c(S,"lodInfos",new Map),c(S,"previouslyLoaded",new Map),c(S,"lowresCache",new Map);class tt{constructor(e,r,n,s,o){c(this,"url"),c(this,"key"),c(this,"level"),c(this,"index"),c(this,"density"),this.url=e,this.key=r,this.level=n,s!=null&&(this.index=s),o!=null&&(this.density=o)}}const P=te("debugprogressive"),rt=te("noprogressive"),Me=Symbol("Needle:LODSManager"),De=Symbol("Needle:LODState"),J=Symbol("Needle:CurrentLOD"),k={mesh_lod:-1,texture_lod:-1};var E,$,we,Q,ne,de,U;const B=class{constructor(t,e){c(this,"context"),c(this,"renderer"),c(this,"projectionScreenMatrix",new be),c(this,"targetTriangleDensity",2e5),c(this,"updateInterval","auto"),V(this,E,1),c(this,"pause",!1),c(this,"manual",!1),c(this,"_lodchangedlisteners",[]),V(this,$,void 0),V(this,we,new We),V(this,Q,0),V(this,ne,0),V(this,de,0),V(this,U,0),c(this,"_fpsBuffer",[60,60,60,60,60]),c(this,"_sphere",new $e),c(this,"_tempBox",new Se),c(this,"_tempBox2",new Se),c(this,"tempMatrix",new be),c(this,"_tempWorldPosition",new N),c(this,"_tempBoxSize",new N),c(this,"_tempBox2Size",new N),this.renderer=t,this.context={...e}}static getObjectLODState(t){return t[De]}static addPlugin(t){F.push(t)}static removePlugin(t){const e=F.indexOf(t);e>=0&&F.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 F}addEventListener(t,e){t==="changed"&&this._lodchangedlisteners.push(e)}removeEventListener(t,e){if(t==="changed"){const r=this._lodchangedlisteners.indexOf(e);r>=0&&this._lodchangedlisteners.splice(r,1)}}enable(){if(x(this,$))return;console.debug("[gltf-progressive] Enabling LODsManager for renderer");let t=0;G(this,$,this.renderer.render);const e=this;pe(this.renderer),this.renderer.render=function(r,n){const s=e.renderer.getRenderTarget();(s==null||"isXRRenderTarget"in s&&s.isXRRenderTarget)&&(t=0,G(e,Q,x(e,Q)+1),G(e,ne,x(e,we).getDelta()),G(e,de,x(e,de)+x(e,ne)),e._fpsBuffer.shift(),e._fpsBuffer.push(1/x(e,ne)),G(e,U,e._fpsBuffer.reduce((i,a)=>i+a)/e._fpsBuffer.length),P&&x(e,Q)%200===0&&console.log("FPS",Math.round(x(e,U)),"Interval:",x(e,E)));const o=t++;x(e,$).call(this,r,n),e.onAfterRender(r,n,o)}}disable(){x(this,$)&&(this.renderer.render=x(this,$),G(this,$,void 0))}update(t,e){this.internalUpdate(t,e)}onAfterRender(t,e,r){if(this.pause)return;const n=this.renderer.renderLists.get(t,0).opaque;let s=!0;if(n.length===1){const o=n[0].material;(o.name==="EffectMaterial"||o.name==="CopyShader")&&(s=!1)}if((e.parent&&e.parent.type==="CubeCamera"||r>=1&&e.type==="OrthographicCamera")&&(s=!1),s){if(rt||(this.updateInterval==="auto"?x(this,U)<40&&x(this,E)<10?(G(this,E,x(this,E)+1),P&&console.warn("\u2193 Reducing LOD updates",x(this,E),x(this,U).toFixed(0))):x(this,U)>=60&&x(this,E)>1&&(G(this,E,x(this,E)-1),P&&console.warn("\u2191 Increasing LOD updates",x(this,E),x(this,U).toFixed(0))):G(this,E,this.updateInterval),x(this,E)>0&&x(this,Q)%x(this,E)!=0))return;this.internalUpdate(t,e)}}internalUpdate(t,e){var r,n;const s=this.renderer.renderLists.get(t,0),o=s.opaque;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse);const i=this.targetTriangleDensity;for(const l of o){if(l.material&&(((r=l.geometry)==null?void 0:r.type)==="BoxGeometry"||((n=l.geometry)==null?void 0:n.type)==="BufferGeometry")&&(l.material.name==="SphericalGaussianBlur"||l.material.name=="BackgroundCubeMaterial"||l.material.name==="CubemapFromEquirect"||l.material.name==="EquirectangularToCubeUV")){P&&(l.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(l.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",l,l.material.name,l.material.type)));continue}switch(l.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}if(P==="color"&&l.material&&!l.object.progressive_debug_color){l.object.progressive_debug_color=!0;const g=Math.random()*16777215,p=new Fe({color:g});l.object.material=p}const f=l.object;(f instanceof q||f.isMesh)&&this.updateLODs(t,e,f,i)}const a=s.transparent;for(const l of a){const f=l.object;(f instanceof q||f.isMesh)&&this.updateLODs(t,e,f,i)}const u=s.transmissive;for(const l of u){const f=l.object;(f instanceof q||f.isMesh)&&this.updateLODs(t,e,f,i)}}updateLODs(t,e,r,n){var s,o;r.userData||(r.userData={});let i=r[De];if(i||(i=new st,r[De]=i),i.frames++<2)return;for(const u of F)(s=u.onBeforeUpdateLOD)==null||s.call(u,this.renderer,t,e,r);this.calculateLodLevel(e,r,i,n,k),k.mesh_lod=Math.round(k.mesh_lod),k.texture_lod=Math.round(k.texture_lod),k.mesh_lod>=0&&this.loadProgressiveMeshes(r,k.mesh_lod);let a=k.texture_lod;if(r.material&&a>=0){const u=r["DEBUG:LOD"];u!=null&&(a=u),this.loadProgressiveTextures(r.material,a)}for(const u of F)(o=u.onAfterUpdatedLOD)==null||o.call(u,this.renderer,t,e,r,k);i.lastLodLevel_Mesh=k.mesh_lod,i.lastLodLevel_Texture=k.texture_lod}loadProgressiveTextures(t,e){if(!t)return;if(Array.isArray(t)){for(const n of t)this.loadProgressiveTextures(n,e);return}let r=!1;(t[J]===void 0||e<t[J])&&(r=!0),r&&(t[J]=e,S.assignTextureLOD(t,e).then(n=>{this._lodchangedlisteners.forEach(s=>s({type:"texture",level:e,object:t}))}))}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);if(t[J]!==e){t[J]=e;const r=t.geometry;return S.assignMeshLOD(t,e).then(n=>(n&&t[J]==e&&r!=t.geometry&&this._lodchangedlisteners.forEach(s=>s({type:"mesh",level:e,object:t})),n))}return Promise.resolve(null)}static isInside(t,e){const r=t.min,n=t.max,s=(r.x+n.x)*.5,o=(r.y+n.y)*.5;return this._tempPtInside.set(s,o,r.z).applyMatrix4(e).z<0}calculateLodLevel(t,e,r,n,s){var o;if(!e){s.mesh_lod=-1,s.texture_lod=-1;return}if(!t){s.mesh_lod=-1,s.texture_lod=-1;return}let i=10+1,a=!1;if(P&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const u=S.getMeshLODInformation(e.geometry),l=u?.lods,f=l&&l.length>0,g=S.getMaterialMinMaxLODsCount(e.material),p=g?.min_count!=1/0&&g.min_count>0&&g.max_count>0;if(!f&&!p){s.mesh_lod=0,s.texture_lod=0;return}f||(a=!0,i=0);const A=this.renderer.domElement.clientHeight||this.renderer.domElement.height;let D=e.geometry.boundingBox;if(e.type==="SkinnedMesh"){const L=e;if(!L.boundingBox)L.computeBoundingBox();else if(r.frames%30===0){const d=re(L),_=L.geometry;d&&(L.geometry=d),L.computeBoundingBox(),L.geometry=_}D=L.boundingBox}if(D&&t.isPerspectiveCamera){const L=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 v=t.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(v)){s.mesh_lod=0,s.texture_lod=0;return}}if(this._tempBox.copy(D),this._tempBox.applyMatrix4(e.matrixWorld),B.isInside(this._tempBox,this.projectionScreenMatrix)){s.mesh_lod=0,s.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&L.fov>70){const v=this._tempBox.min,m=this._tempBox.max;let h=v.x,M=v.y,b=m.x,C=m.y;const z=2,X=1.5,ie=(v.x+m.x)*.5,le=(v.y+m.y)*.5;h=(h-ie)*z+ie,M=(M-le)*z+le,b=(b-ie)*z+ie,C=(C-le)*z+le;const ke=h<0&&b>0?0:Math.min(Math.abs(v.x),Math.abs(m.x)),Ce=M<0&&C>0?0:Math.min(Math.abs(v.y),Math.abs(m.y)),ge=Math.max(ke,Ce);r.lastCentrality=(X-ge)*(X-ge)*(X-ge)}else r.lastCentrality=1;const d=this._tempBox.getSize(this._tempBoxSize);d.multiplyScalar(.5),screen.availHeight>0&&A>0&&d.multiplyScalar(A/screen.availHeight),d.x*=L.aspect;const _=t.matrixWorldInverse,O=this._tempBox2;O.copy(D),O.applyMatrix4(e.matrixWorld),O.applyMatrix4(_);const I=O.getSize(this._tempBox2Size),T=Math.max(I.x,I.y);if(Math.max(d.x,d.y)!=0&&T!=0&&(d.z=I.z/Math.max(I.x,I.y)*Math.max(d.x,d.y)),r.lastScreenCoverage=Math.max(d.x,d.y,d.z),r.lastScreenspaceVolume.copy(d),r.lastScreenCoverage*=r.lastCentrality,P&&B.debugDrawLine){const v=this.tempMatrix.copy(this.projectionScreenMatrix);v.invert();const m=B.corner0,h=B.corner1,M=B.corner2,b=B.corner3;m.copy(this._tempBox.min),h.copy(this._tempBox.max),h.x=m.x,M.copy(this._tempBox.max),M.y=m.y,b.copy(this._tempBox.max);const C=(m.z+b.z)*.5;m.z=h.z=M.z=b.z=C,m.applyMatrix4(v),h.applyMatrix4(v),M.applyMatrix4(v),b.applyMatrix4(v),B.debugDrawLine(m,h,255),B.debugDrawLine(m,M,255),B.debugDrawLine(h,b,255),B.debugDrawLine(M,b,255)}let W=999;if(l&&r.lastScreenCoverage>0){for(let v=0;v<l.length;v++)if(l[v].density/r.lastScreenCoverage<n){W=v;break}}W<i&&(i=W,a=!0)}if(a?s.mesh_lod=i:s.mesh_lod=r.lastLodLevel_Mesh,P&&s.mesh_lod!=r.lastLodLevel_Mesh){const L=l?.[s.mesh_lod];L&&console.log(`Mesh LOD changed: ${r.lastLodLevel_Mesh} \u2192 ${s.mesh_lod} (${L.density.toFixed(0)}) - ${e.name}`)}if(p){const L="saveData"in globalThis.navigator&&globalThis.navigator.saveData===!0;if(r.lastLodLevel_Texture<0){if(s.texture_lod=g.max_count-1,P){const d=g.lods[g.max_count-1];P&&console.log(`First Texture LOD ${s.texture_lod} (${d.max_height}px) - ${e.name}`)}}else{const d=r.lastScreenspaceVolume.x+r.lastScreenspaceVolume.y+r.lastScreenspaceVolume.z;let _=r.lastScreenCoverage*2;((o=this.context)==null?void 0:o.engine)==="model-viewer"&&(_*=2);const O=A/window.devicePixelRatio*_;for(let I=g.lods.length-1;I>=0;I--){let T=g.lods[I];if(!(L&&T.max_height>=2048)&&!(Qe()&&T.max_height>4096)&&T.max_height>O){if(s.texture_lod=I,s.texture_lod<r.lastLodLevel_Texture){const W=T.max_height;P&&console.log(`Texture LOD changed: ${r.lastLodLevel_Texture} \u2192 ${s.texture_lod} = ${W}px
6
6
  Screensize: ${O.toFixed(0)}px, Coverage: ${(100*r.lastScreenCoverage).toFixed(2)}%, Volume ${d.toFixed(1)}
7
- ${e.name}`)}break}}}}else s.texture_lod=0}};let j=B;E=new WeakMap,$=new WeakMap,we=new WeakMap,J=new WeakMap,se=new WeakMap,ce=new WeakMap,U=new WeakMap,c(j,"debugDrawLine"),c(j,"corner0",new N),c(j,"corner1",new N),c(j,"corner2",new N),c(j,"corner3",new N),c(j,"_tempPtInside",new N);class tt{constructor(){c(this,"frames",0),c(this,"lastLodLevel_Mesh",-1),c(this,"lastLodLevel_Texture",-1),c(this,"lastScreenCoverage",0),c(this,"lastScreenspaceVolume",new N),c(this,"lastCentrality",0)}}const Ae=Symbol("NEEDLE_mesh_lod"),de=Symbol("NEEDLE_texture_lod");let he=null;function _e(){const t=rt();t&&(t.mapURLs(function(e){return Ie(),e}),Ie(),he?.disconnect(),he=new MutationObserver(e=>{e.forEach(r=>{r.addedNodes.forEach(n=>{n instanceof HTMLElement&&n.tagName.toLowerCase()==="model-viewer"&&Pe(n)})})}),he.observe(document,{childList:!0,subtree:!0}))}function rt(){return typeof customElements>"u"?null:customElements.get("model-viewer")||(customElements.whenDefined("model-viewer").then(()=>{console.debug("[gltf-progressive] model-viewer defined"),_e()}),null)}function Ie(){typeof document>"u"||document.querySelectorAll("model-viewer").forEach(t=>{Pe(t)})}const Be=new WeakSet;let st=0;function Pe(t){if(!t||Be.has(t))return null;Be.add(t),console.debug("[gltf-progressive] found new model-viewer..."+ ++st+`
8
- `,t.getAttribute("src"));let e=null,r=null,n=null;for(let s=t;s!=null;s=Object.getPrototypeOf(s)){const o=Object.getOwnPropertySymbols(s),i=o.find(l=>l.toString()=="Symbol(renderer)"),a=o.find(l=>l.toString()=="Symbol(scene)"),u=o.find(l=>l.toString()=="Symbol(needsRender)");!e&&i!=null&&(e=t[i].threeRenderer),!r&&a!=null&&(r=t[a]),!n&&u!=null&&(n=t[u])}if(e&&r){let s=function(){if(n){let i=0,a=setInterval(()=>{if(i++>5){clearInterval(a);return}n?.call(t)},300)}};console.debug("[gltf-progressive] setup model-viewer");const o=j.get(e,{engine:"model-viewer"});return j.addPlugin(new ot),o.enable(),o.addEventListener("changed",()=>{n?.call(t)}),t.addEventListener("model-visibility",i=>{i.detail.visible&&n?.call(t)}),t.addEventListener("load",()=>{s()}),()=>{o.disable()}}return null}class ot{constructor(){c(this,"_didWarnAboutMissingUrl",!1)}onBeforeUpdateLOD(e,r,n,s){this.tryParseMeshLOD(r,s),this.tryParseTextureLOD(r,s)}getUrl(e){if(!e)return null;let r=e.getAttribute("src");return r||(r=e.src),r||(this._didWarnAboutMissingUrl||console.warn("No url found in modelviewer",e),this._didWarnAboutMissingUrl=!0),r}tryGetCurrentGLTF(e){return e._currentGLTF}tryGetCurrentModelViewer(e){return e.element}tryParseTextureLOD(e,r){if(r[de]==!0)return;r[de]=!0;const n=this.tryGetCurrentGLTF(e),s=this.tryGetCurrentModelViewer(e),o=this.getUrl(s);if(o&&n&&r.material){let i=function(u){var l,f,g;if(u[de]==!0)return;u[de]=!0,u.userData&&(u.userData.LOD=-1);const p=Object.keys(u);for(let A=0;A<p.length;A++){const D=p[A],L=u[D];if(L?.isTexture===!0){const d=(f=(l=L.userData)==null?void 0:l.associations)==null?void 0:f.textures;if(d==null)continue;const _=n.parser.json.textures[d];if(!_){console.warn("Texture data not found for texture index "+d);continue}if((g=_?.extensions)!=null&&g[R]){const O=_.extensions[R];O&&o&&S.registerTexture(o,L,O.lods.length,d,O)}}}};const a=r.material;if(Array.isArray(a))for(const u of a)i(u);else i(a)}}tryParseMeshLOD(e,r){var n,s;if(r[Ae]==!0)return;r[Ae]=!0;const o=this.tryGetCurrentModelViewer(e),i=this.getUrl(o);if(!i)return;const a=(s=(n=r.userData)==null?void 0:n.gltfExtensions)==null?void 0:s[R];if(a&&i){const u=r.uuid;S.registerMesh(i,u,r,0,a.lods.length,a)}}}function nt(t,e,r,n){pe(e),ve(r),r.register(o=>new S(o,t));const s=j.get(e);return n?.enableLODsManager!==!1&&s.enable(),s}_e();export{R as EXTENSION_NAME,j as LODsManager,S as NEEDLE_progressive,ge as VERSION,ve as addDracoAndKTX2Loaders,pe as createLoaders,ee as getRaycastMesh,_e as patchModelViewer,Te as registerRaycastMesh,Xe as setDracoDecoderLocation,Ke as setKTX2TranscoderLocation,nt as useNeedleProgressive,Je as useRaycastMeshes};
7
+ ${e.name}`)}break}}}}else s.texture_lod=0}};let j=B;E=new WeakMap,$=new WeakMap,we=new WeakMap,Q=new WeakMap,ne=new WeakMap,de=new WeakMap,U=new WeakMap,c(j,"debugDrawLine"),c(j,"corner0",new N),c(j,"corner1",new N),c(j,"corner2",new N),c(j,"corner3",new N),c(j,"_tempPtInside",new N);class st{constructor(){c(this,"frames",0),c(this,"lastLodLevel_Mesh",-1),c(this,"lastLodLevel_Texture",-1),c(this,"lastScreenCoverage",0),c(this,"lastScreenspaceVolume",new N),c(this,"lastCentrality",0)}}const Ae=Symbol("NEEDLE_mesh_lod"),he=Symbol("NEEDLE_texture_lod");let fe=null;function _e(){const t=ot();t&&(t.mapURLs(function(e){return Ie(),e}),Ie(),fe?.disconnect(),fe=new MutationObserver(e=>{e.forEach(r=>{r.addedNodes.forEach(n=>{n instanceof HTMLElement&&n.tagName.toLowerCase()==="model-viewer"&&Pe(n)})})}),fe.observe(document,{childList:!0,subtree:!0}))}function ot(){return typeof customElements>"u"?null:customElements.get("model-viewer")||(customElements.whenDefined("model-viewer").then(()=>{console.debug("[gltf-progressive] model-viewer defined"),_e()}),null)}function Ie(){typeof document>"u"||document.querySelectorAll("model-viewer").forEach(t=>{Pe(t)})}const Be=new WeakSet;let nt=0;function Pe(t){if(!t||Be.has(t))return null;Be.add(t),console.debug("[gltf-progressive] found new model-viewer..."+ ++nt+`
8
+ `,t.getAttribute("src"));let e=null,r=null,n=null;for(let s=t;s!=null;s=Object.getPrototypeOf(s)){const o=Object.getOwnPropertySymbols(s),i=o.find(l=>l.toString()=="Symbol(renderer)"),a=o.find(l=>l.toString()=="Symbol(scene)"),u=o.find(l=>l.toString()=="Symbol(needsRender)");!e&&i!=null&&(e=t[i].threeRenderer),!r&&a!=null&&(r=t[a]),!n&&u!=null&&(n=t[u])}if(e&&r){let s=function(){if(n){let i=0,a=setInterval(()=>{if(i++>5){clearInterval(a);return}n?.call(t)},300)}};console.debug("[gltf-progressive] setup model-viewer");const o=j.get(e,{engine:"model-viewer"});return j.addPlugin(new it),o.enable(),o.addEventListener("changed",()=>{n?.call(t)}),t.addEventListener("model-visibility",i=>{i.detail.visible&&n?.call(t)}),t.addEventListener("load",()=>{s()}),()=>{o.disable()}}return null}class it{constructor(){c(this,"_didWarnAboutMissingUrl",!1)}onBeforeUpdateLOD(e,r,n,s){this.tryParseMeshLOD(r,s),this.tryParseTextureLOD(r,s)}getUrl(e){if(!e)return null;let r=e.getAttribute("src");return r||(r=e.src),r||(this._didWarnAboutMissingUrl||console.warn("No url found in modelviewer",e),this._didWarnAboutMissingUrl=!0),r}tryGetCurrentGLTF(e){return e._currentGLTF}tryGetCurrentModelViewer(e){return e.element}tryParseTextureLOD(e,r){if(r[he]==!0)return;r[he]=!0;const n=this.tryGetCurrentGLTF(e),s=this.tryGetCurrentModelViewer(e),o=this.getUrl(s);if(o&&n&&r.material){let i=function(u){var l,f,g;if(u[he]==!0)return;u[he]=!0,u.userData&&(u.userData.LOD=-1);const p=Object.keys(u);for(let A=0;A<p.length;A++){const D=p[A],L=u[D];if(L?.isTexture===!0){const d=(f=(l=L.userData)==null?void 0:l.associations)==null?void 0:f.textures;if(d==null)continue;const _=n.parser.json.textures[d];if(!_){console.warn("Texture data not found for texture index "+d);continue}if((g=_?.extensions)!=null&&g[R]){const O=_.extensions[R];O&&o&&S.registerTexture(o,L,O.lods.length,d,O)}}}};const a=r.material;if(Array.isArray(a))for(const u of a)i(u);else i(a)}}tryParseMeshLOD(e,r){var n,s;if(r[Ae]==!0)return;r[Ae]=!0;const o=this.tryGetCurrentModelViewer(e),i=this.getUrl(o);if(!i)return;const a=(s=(n=r.userData)==null?void 0:n.gltfExtensions)==null?void 0:s[R];if(a&&i){const u=r.uuid;S.registerMesh(i,u,r,0,a.lods.length,a)}}}function lt(t,e,r,n){pe(e),ve(r),r.register(o=>new S(o,t));const s=j.get(e);return n?.enableLODsManager!==!1&&s.enable(),s}_e();export{R as EXTENSION_NAME,j as LODsManager,S as NEEDLE_progressive,me as VERSION,ve as addDracoAndKTX2Loaders,pe as createLoaders,re as getRaycastMesh,_e as patchModelViewer,Te 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 ke=(a,t,e)=>t in a?Re(a,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):a[t]=e;var d=(a,t,e)=>(ke(a,typeof t!="symbol"?t+"":t,e),e),Se=(a,t,e)=>{if(!t.has(a))throw TypeError("Cannot "+e)};var L=(a,t,e)=>(Se(a,t,"read from private field"),e?e.call(a):t.get(a)),K=(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)},N=(a,t,e,r)=>(Se(a,t,"write to private field"),r?r.call(a,e):t.set(a,e),e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("three"),Ge=require("three/examples/jsm/loaders/GLTFLoader.js"),Ve=require("three/examples/jsm/libs/meshopt_decoder.module.js"),Fe=require("three/examples/jsm/loaders/DRACOLoader.js"),$e=require("three/examples/jsm/loaders/KTX2Loader.js"),De="";globalThis.GLTF_PROGRESSIVE_VERSION=De;console.debug(`[gltf-progressive] version ${De}`);let fe="https://www.gstatic.com/draco/versioned/decoders/1.4.1/",we="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";fetch(fe+"draco_decoder.js",{method:"head"}).catch(a=>{fe="./include/draco/",we="./include/ktx2/"});function Ne(a){fe=a}function Ue(a){we=a}let J,ue,Q;function ve(a){return J||(J=new Fe.DRACOLoader,J.setDecoderPath(fe),J.setDecoderConfig({type:"js"})),Q||(Q=new $e.KTX2Loader,Q.setTranscoderPath(we)),ue||(ue=Ve.MeshoptDecoder),a?Q.detectSupport(a):a!==null&&console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"),{dracoLoader:J,ktx2Loader:Q,meshoptDecoder:ue}}function _e(a){a.dracoLoader||a.setDRACOLoader(J),a.ktx2Loader||a.setKTX2Loader(Q),a.meshoptDecoder||a.setMeshoptDecoder(ue)}ie("debugprogressive");function ie(a){const e=new URL(window.location.href).searchParams.get(a);return e==null||e==="0"||e==="false"?!1:e===""?!0:e}function ze(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 ee;function We(){return ee!==void 0||(ee=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),ie("debugprogressive")&&console.log("[glTF Progressive]: isMobileDevice",ee)),ee}const xe=Symbol("needle:raycast-mesh");function oe(a){return(a==null?void 0:a[xe])instanceof p.BufferGeometry?a[xe]:null}function Pe(a,t){if((a.type==="Mesh"||a.type==="SkinnedMesh")&&!oe(a)){const r=Xe(t);r.userData={isRaycastMesh:!0},a[xe]=r}}function qe(a=!0){if(a){if(te)return;const t=te=p.Mesh.prototype.raycast;p.Mesh.prototype.raycast=function(e,r){const o=this,s=oe(o);let i;s&&o.isMesh&&(i=o.geometry,o.geometry=s),t.call(this,e,r),i&&(o.geometry=i)}}else{if(!te)return;p.Mesh.prototype.raycast=te,te=null}}let te=null;function Xe(a){const t=new p.BufferGeometry;for(const e in a.attributes)t.setAttribute(e,a.getAttribute(e));return t.setIndex(a.getIndex()),t}const Y=new Array,U="NEEDLE_progressive",x=ie("debugprogressive"),ye=Symbol("needle-progressive-texture"),se=new Map,Me=new Set;if(x){let a=function(){t+=1,console.log("Toggle LOD level",t,se),se.forEach((o,s)=>{for(const i of o.keys){const n=s[i];if(n!=null){if(n.isBufferGeometry===!0){const l=O.getMeshLODInformation(n),u=l?Math.min(t,l.lods.length):0;s["DEBUG:LOD"]=t,O.assignMeshLOD(s,u),l&&(e=Math.max(e,l.lods.length-1))}else if(s.isMaterial===!0){s["DEBUG:LOD"]=t,O.assignTextureLOD(s,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,Me&&Me.forEach(s=>{s.name!="BackgroundCubeMaterial"&&s.glyphMap==null&&"wireframe"in s&&(s.wireframe=r)}))})}function be(a,t,e){var o;if(!x)return;se.has(a)||se.set(a,{keys:[],sourceId:e});const r=se.get(a);((o=r==null?void 0:r.keys)==null?void 0:o.includes(t))==!1&&r.keys.push(t)}const _=class{constructor(t,e){d(this,"parser");d(this,"url");d(this,"_isLoadingMesh");d(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[U];return e?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",t).then(s=>{var i;return this._isLoadingMesh=!1,s&&_.registerMesh(this.url,e.guid,s,(i=e.lods)==null?void 0:i.length,void 0,e),s})):null});x&&console.log("Progressive extension registered for",e),this.parser=t,this.url=e}get name(){return U}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",s=t[o];if(s!=null)return s;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(x==="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&&i(u,e)}}else if(t.isMaterial)for(const n of Object.keys(t)){const l=t[n];(l==null?void 0:l.isTexture)===!0&&i(l,e)}return t[o]=e,e;function i(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 g=0;g<c.lods.length;g++){const y=c.lods[g];y.width&&(l.lods[g]=l.lods[g]||{min_height:1/0,max_height:0},l.lods[g].min_height=Math.min(l.lods[g].min_height,y.height),l.lods[g].max_height=Math.max(l.lods[g].max_height,y.height))}}}}}static hasLODLevelAvailable(t,e){var s;if(Array.isArray(t)){for(const i of t)if(this.hasLODLevelAvailable(i,e))return!0;return!1}if(t.isMaterial===!0){for(const i of Object.keys(t)){const n=t[i];if(n&&n.isTexture&&this.hasLODLevelAvailable(n,e))return!0}return!1}else if(t.isGroup===!0){for(const i of t.children)if(i.isMesh===!0&&this.hasLODLevelAvailable(i,e))return!0}let r,o;if(t.isMesh?r=t.geometry:(t.isBufferGeometry||t.isTexture)&&(r=t),r&&(s=r==null?void 0:r.userData)!=null&&s.LODS){const i=r.userData.LODS;if(o=this.lodInfos.get(i.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 p.Mesh||t.isMesh===!0){const o=t.geometry,s=this.getAssignedLODInformation(o);if(!s)return Promise.resolve(null);for(const i of Y)(r=i.onBeforeGetLODMesh)==null||r.call(i,t,e);return t["LOD:requested level"]=e,_.getOrLoadLOD(o,e).then(i=>{if(t["LOD:requested level"]===e){if(delete t["LOD:requested level"],Array.isArray(i)){const n=s.index||0;i=i[n]}i&&o!=i&&((i==null?void 0:i.isBufferGeometry)?(t.geometry=i,x&&be(t,"geometry",s.url)):x&&console.error("Invalid LOD geometry",i))}return i}).catch(i=>(console.error("Error loading mesh LOD",t,i),null))}else x&&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 p.Material||t.isMaterial===!0){const r=t,o=[],s=new Array;if(x&&Me.add(r),r.uniforms&&(r.isRawShaderMaterial||r.isShaderMaterial===!0)){const i=r;for(const n of Object.keys(i.uniforms)){const l=i.uniforms[n].value;if((l==null?void 0:l.isTexture)===!0){const u=this.assignTextureLODForSlot(l,e,r,n).then(c=>(c&&i.uniforms[n].value!=c&&(i.uniforms[n].value=c,i.uniformsNeedUpdate=!0),c));o.push(u),s.push(n)}}}else for(const i of Object.keys(r)){const n=r[i];if((n==null?void 0:n.isTexture)===!0){const l=this.assignTextureLODForSlot(n,e,r,i);o.push(l),s.push(i)}}return Promise.all(o).then(i=>{const n=new Array;for(let l=0;l<i.length;l++){const u=i[l],c=s[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 p.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):_.getOrLoadLOD(t,e).then(s=>{if(Array.isArray(s))return null;if((s==null?void 0:s.isTexture)===!0){if(s!=t){if(r&&o){const i=r[o];if(i){const n=this.getAssignedLODInformation(i);if(n&&(n==null?void 0:n.level)<e)return x==="verbose"&&console.warn("Assigned texture level is already higher: ",n.level,e,r,i,s),null}r[o]=s}if(x&&o&&r){const i=this.getAssignedLODInformation(t);i&&be(r,o,i.url)}}return s}else x=="verbose"&&console.warn("No LOD found for",t,e);return null}).catch(s=>(console.error("Error loading LOD",t,s),null))}afterRoot(t){var e,r;return x&&console.log("AFTER",this.url,t),(e=this.parser.json.textures)==null||e.forEach((o,s)=>{var i;if(o!=null&&o.extensions){const n=o==null?void 0:o.extensions[U];if(n){if(!n.lods){x&&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)===s&&(l=!0,_.registerTexture(this.url,u,(i=n.lods)==null?void 0:i.length,s,n))}l||this.parser.getDependency("texture",s).then(u=>{var c;u&&_.registerTexture(this.url,u,(c=n.lods)==null?void 0:c.length,s,n)})}}}),(r=this.parser.json.meshes)==null||r.forEach((o,s)=>{if(o!=null&&o.extensions){const i=o==null?void 0:o.extensions[U];if(i&&i.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)===s&&_.registerMesh(this.url,i.guid,n,i.lods.length,l.primitives,i)}}}}),null}static async getOrLoadLOD(t,e){var n,l,u,c;const r=x=="verbose",o=t.userData.LODS;if(!o)return null;const s=o==null?void 0:o.key;let i;if(t.isTexture===!0){const g=t;g.source&&g.source[ye]&&(i=g.source[ye])}if(i||(i=_.lodInfos.get(s)),i){if(e>0){let D=!1;const v=Array.isArray(i.lods);if(v&&e>=i.lods.length?D=!0:v||(D=!0),D)return this.lowresCache.get(s)}const g=Array.isArray(i.lods)?(n=i.lods[e])==null?void 0:n.path:i.lods;if(!g)return x&&!i["missing:uri"]&&(i["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+e,i)),null;const y=ze(o.url,g);if(y.endsWith(".glb")||y.endsWith(".gltf")){if(!i.guid)return console.warn("missing pointer for glb/gltf texture",i),null;const D=y+"_"+i.guid,v=this.previouslyLoaded.get(D);if(v!==void 0){r&&console.log(`LOD ${e} was already loading/loaded: ${D}`);let h=await v.catch($=>(console.error(`Error loading LOD ${e} from ${y}
1
+ "use strict";var Re=Object.defineProperty;var ke=(a,t,e)=>t in a?Re(a,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):a[t]=e;var d=(a,t,e)=>(ke(a,typeof t!="symbol"?t+"":t,e),e),Se=(a,t,e)=>{if(!t.has(a))throw TypeError("Cannot "+e)};var L=(a,t,e)=>(Se(a,t,"read from private field"),e?e.call(a):t.get(a)),K=(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)},N=(a,t,e,r)=>(Se(a,t,"write to private field"),r?r.call(a,e):t.set(a,e),e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("three"),Ge=require("three/examples/jsm/loaders/GLTFLoader.js"),Ve=require("three/examples/jsm/libs/meshopt_decoder.module.js"),Fe=require("three/examples/jsm/loaders/DRACOLoader.js"),$e=require("three/examples/jsm/loaders/KTX2Loader.js"),we="";globalThis.GLTF_PROGRESSIVE_VERSION=we;console.debug(`[gltf-progressive] version ${we}`);let Z="https://www.gstatic.com/draco/versioned/decoders/1.5.7/",oe="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";const Ne=Z,Ue=oe;fetch(Z+"draco_decoder.js",{method:"head"}).catch(a=>{Z===Ne&&(Z="./include/draco/"),oe===Ue&&(oe="./include/ktx2/")});function ze(a){Z=a}function We(a){oe=a}let J,de,Q;function ve(a){return J||(J=new Fe.DRACOLoader,J.setDecoderPath(Z),J.setDecoderConfig({type:"js"})),Q||(Q=new $e.KTX2Loader,Q.setTranscoderPath(oe)),de||(de=Ve.MeshoptDecoder),a?Q.detectSupport(a):a!==null&&console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"),{dracoLoader:J,ktx2Loader:Q,meshoptDecoder:de}}function _e(a){a.dracoLoader||a.setDRACOLoader(J),a.ktx2Loader||a.setKTX2Loader(Q),a.meshoptDecoder||a.setMeshoptDecoder(de)}ne("debugprogressive");function ne(a){const e=new URL(window.location.href).searchParams.get(a);return e==null||e==="0"||e==="false"?!1:e===""?!0:e}function qe(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 Xe(){return te!==void 0||(te=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),ne("debugprogressive")&&console.log("[glTF Progressive]: isMobileDevice",te)),te}const Me=Symbol("needle:raycast-mesh");function ae(a){return(a==null?void 0:a[Me])instanceof p.BufferGeometry?a[Me]:null}function Pe(a,t){if((a.type==="Mesh"||a.type==="SkinnedMesh")&&!ae(a)){const r=Ye(t);r.userData={isRaycastMesh:!0},a[Me]=r}}function Ke(a=!0){if(a){if(re)return;const t=re=p.Mesh.prototype.raycast;p.Mesh.prototype.raycast=function(e,r){const o=this,s=ae(o);let i;s&&o.isMesh&&(i=o.geometry,o.geometry=s),t.call(this,e,r),i&&(o.geometry=i)}}else{if(!re)return;p.Mesh.prototype.raycast=re,re=null}}let re=null;function Ye(a){const t=new p.BufferGeometry;for(const e in a.attributes)t.setAttribute(e,a.getAttribute(e));return t.setIndex(a.getIndex()),t}const Y=new Array,U="NEEDLE_progressive",x=ne("debugprogressive"),me=Symbol("needle-progressive-texture"),ie=new Map,De=new Set;if(x){let a=function(){t+=1,console.log("Toggle LOD level",t,ie),ie.forEach((o,s)=>{for(const i of o.keys){const n=s[i];if(n!=null){if(n.isBufferGeometry===!0){const l=O.getMeshLODInformation(n),u=l?Math.min(t,l.lods.length):0;s["DEBUG:LOD"]=t,O.assignMeshLOD(s,u),l&&(e=Math.max(e,l.lods.length-1))}else if(s.isMaterial===!0){s["DEBUG:LOD"]=t,O.assignTextureLOD(s,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(s=>{s.name!="BackgroundCubeMaterial"&&s.glyphMap==null&&"wireframe"in s&&(s.wireframe=r)}))})}function be(a,t,e){var o;if(!x)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 _=class{constructor(t,e){d(this,"parser");d(this,"url");d(this,"_isLoadingMesh");d(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[U];return e?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",t).then(s=>{var i;return this._isLoadingMesh=!1,s&&_.registerMesh(this.url,e.guid,s,(i=e.lods)==null?void 0:i.length,void 0,e),s})):null});x&&console.log("Progressive extension registered for",e),this.parser=t,this.url=e}get name(){return U}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",s=t[o];if(s!=null)return s;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(x==="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&&i(u,e)}}else if(t.isMaterial)for(const n of Object.keys(t)){const l=t[n];(l==null?void 0:l.isTexture)===!0&&i(l,e)}return t[o]=e,e;function i(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 g=0;g<c.lods.length;g++){const y=c.lods[g];y.width&&(l.lods[g]=l.lods[g]||{min_height:1/0,max_height:0},l.lods[g].min_height=Math.min(l.lods[g].min_height,y.height),l.lods[g].max_height=Math.max(l.lods[g].max_height,y.height))}}}}}static hasLODLevelAvailable(t,e){var s;if(Array.isArray(t)){for(const i of t)if(this.hasLODLevelAvailable(i,e))return!0;return!1}if(t.isMaterial===!0){for(const i of Object.keys(t)){const n=t[i];if(n&&n.isTexture&&this.hasLODLevelAvailable(n,e))return!0}return!1}else if(t.isGroup===!0){for(const i of t.children)if(i.isMesh===!0&&this.hasLODLevelAvailable(i,e))return!0}let r,o;if(t.isMesh?r=t.geometry:(t.isBufferGeometry||t.isTexture)&&(r=t),r&&(s=r==null?void 0:r.userData)!=null&&s.LODS){const i=r.userData.LODS;if(o=this.lodInfos.get(i.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 p.Mesh||t.isMesh===!0){const o=t.geometry,s=this.getAssignedLODInformation(o);if(!s)return Promise.resolve(null);for(const i of Y)(r=i.onBeforeGetLODMesh)==null||r.call(i,t,e);return t["LOD:requested level"]=e,_.getOrLoadLOD(o,e).then(i=>{if(t["LOD:requested level"]===e){if(delete t["LOD:requested level"],Array.isArray(i)){const n=s.index||0;i=i[n]}i&&o!=i&&((i==null?void 0:i.isBufferGeometry)?(t.geometry=i,x&&be(t,"geometry",s.url)):x&&console.error("Invalid LOD geometry",i))}return i}).catch(i=>(console.error("Error loading mesh LOD",t,i),null))}else x&&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 p.Material||t.isMaterial===!0){const r=t,o=[],s=new Array;if(x&&De.add(r),r.uniforms&&(r.isRawShaderMaterial||r.isShaderMaterial===!0)){const i=r;for(const n of Object.keys(i.uniforms)){const l=i.uniforms[n].value;if((l==null?void 0:l.isTexture)===!0){const u=this.assignTextureLODForSlot(l,e,r,n).then(c=>(c&&i.uniforms[n].value!=c&&(i.uniforms[n].value=c,i.uniformsNeedUpdate=!0),c));o.push(u),s.push(n)}}}else for(const i of Object.keys(r)){const n=r[i];if((n==null?void 0:n.isTexture)===!0){const l=this.assignTextureLODForSlot(n,e,r,i);o.push(l),s.push(i)}}return Promise.all(o).then(i=>{const n=new Array;for(let l=0;l<i.length;l++){const u=i[l],c=s[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 p.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):_.getOrLoadLOD(t,e).then(s=>{if(Array.isArray(s))return null;if((s==null?void 0:s.isTexture)===!0){if(s!=t){if(r&&o){const i=r[o];if(i){const n=this.getAssignedLODInformation(i);if(n&&(n==null?void 0:n.level)<e)return x==="verbose"&&console.warn("Assigned texture level is already higher: ",n.level,e,r,i,s),null}r[o]=s}if(x&&o&&r){const i=this.getAssignedLODInformation(t);i&&be(r,o,i.url)}}return s}else x=="verbose"&&console.warn("No LOD found for",t,e);return null}).catch(s=>(console.error("Error loading LOD",t,s),null))}afterRoot(t){var e,r;return x&&console.log("AFTER",this.url,t),(e=this.parser.json.textures)==null||e.forEach((o,s)=>{var i;if(o!=null&&o.extensions){const n=o==null?void 0:o.extensions[U];if(n){if(!n.lods){x&&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)===s&&(l=!0,_.registerTexture(this.url,u,(i=n.lods)==null?void 0:i.length,s,n))}l||this.parser.getDependency("texture",s).then(u=>{var c;u&&_.registerTexture(this.url,u,(c=n.lods)==null?void 0:c.length,s,n)})}}}),(r=this.parser.json.meshes)==null||r.forEach((o,s)=>{if(o!=null&&o.extensions){const i=o==null?void 0:o.extensions[U];if(i&&i.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)===s&&_.registerMesh(this.url,i.guid,n,i.lods.length,l.primitives,i)}}}}),null}static async getOrLoadLOD(t,e){var n,l,u,c;const r=x=="verbose",o=t.userData.LODS;if(!o)return null;const s=o==null?void 0:o.key;let i;if(t.isTexture===!0){const g=t;g.source&&g.source[me]&&(i=g.source[me])}if(i||(i=_.lodInfos.get(s)),i){if(e>0){let D=!1;const v=Array.isArray(i.lods);if(v&&e>=i.lods.length?D=!0:v||(D=!0),D)return this.lowresCache.get(s)}const g=Array.isArray(i.lods)?(n=i.lods[e])==null?void 0:n.path:i.lods;if(!g)return x&&!i["missing:uri"]&&(i["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+e,i)),null;const y=qe(o.url,g);if(y.endsWith(".glb")||y.endsWith(".gltf")){if(!i.guid)return console.warn("missing pointer for glb/gltf texture",i),null;const D=y+"_"+i.guid,v=this.previouslyLoaded.get(D);if(v!==void 0){r&&console.log(`LOD ${e} was already loading/loaded: ${D}`);let h=await v.catch($=>(console.error(`Error loading LOD ${e} from ${y}
2
2
  `,$),null)),R=!1;if(h==null||(h instanceof p.Texture&&t instanceof p.Texture?(l=h.image)!=null&&l.data||(u=h.source)!=null&&u.data?h=this.copySettings(t,h):(R=!0,this.previouslyLoaded.delete(D)):h instanceof p.BufferGeometry&&t instanceof p.BufferGeometry&&((c=h.attributes.position)!=null&&c.array||(R=!0,this.previouslyLoaded.delete(D)))),!R)return h}const M=i,F=new Promise(async(h,R)=>{const $=new Ge.GLTFLoader;_e($),x&&(await new Promise(E=>setTimeout(E,1e3)),r&&console.warn("Start loading (delayed) "+y,M.guid));let k=y;if(M&&Array.isArray(M.lods)){const E=M.lods[e];E.hash&&(k+="?v="+E.hash)}const b=await $.loadAsync(k).catch(E=>(console.error(`Error loading LOD ${e} from ${y}
3
- `,E),null));if(!b)return null;const q=b.parser;r&&console.log("Loading finished "+y,M.guid);let A=0;if(b.parser.json.textures){let E=!1;for(const f of b.parser.json.textures){if(f!=null&&f.extensions){const m=f==null?void 0:f.extensions[U];if(m!=null&&m.guid&&m.guid===M.guid){E=!0;break}}A++}if(E){let f=await q.getDependency("texture",A);return f&&_.assignLODInformation(o.url,f,s,e,void 0,void 0),r&&console.log('change "'+t.name+'" → "'+f.name+'"',y,A,f,D),t instanceof p.Texture&&(f=this.copySettings(t,f)),f&&(f.guid=M.guid),h(f)}else x&&console.warn("Could not find texture with guid",M.guid,b.parser.json)}if(A=0,b.parser.json.meshes){let E=!1;for(const f of b.parser.json.meshes){if(f!=null&&f.extensions){const m=f==null?void 0:f.extensions[U];if(m!=null&&m.guid&&m.guid===M.guid){E=!0;break}}A++}if(E){const f=await q.getDependency("mesh",A),m=M;if(r&&console.log(`Loaded Mesh "${f.name}"`,y,A,f,D),f.isMesh===!0){const S=f.geometry;return _.assignLODInformation(o.url,S,s,e,void 0,m.density),h(S)}else{const S=new Array;for(let T=0;T<f.children.length;T++){const P=f.children[T];if(P.isMesh===!0){const X=P.geometry;_.assignLODInformation(o.url,X,s,e,T,m.density),S.push(X)}}return h(S)}}else x&&console.warn("Could not find mesh with guid",M.guid,b.parser.json)}return h(null)});return this.previouslyLoaded.set(D,F),await F}else if(t instanceof p.Texture){r&&console.log("Load texture from uri: "+y);const v=await new p.TextureLoader().loadAsync(y);return v?(v.guid=i.guid,v.flipY=!1,v.needsUpdate=!0,v.colorSpace=t.colorSpace,r&&console.log(i,v)):x&&console.warn("failed loading",y),v}}else x&&console.warn(`Can not load LOD ${e}: no LOD info found for "${s}" ${t.name}`,t.type);return null}static assignLODInformation(t,e,r,o,s,i){if(!e)return;e.userData||(e.userData={});const n=new Ke(t,r,o,s,i);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(),x&&console.warn(`Copying texture settings
3
+ `,E),null));if(!b)return null;const q=b.parser;r&&console.log("Loading finished "+y,M.guid);let A=0;if(b.parser.json.textures){let E=!1;for(const f of b.parser.json.textures){if(f!=null&&f.extensions){const m=f==null?void 0:f.extensions[U];if(m!=null&&m.guid&&m.guid===M.guid){E=!0;break}}A++}if(E){let f=await q.getDependency("texture",A);return f&&_.assignLODInformation(o.url,f,s,e,void 0,void 0),r&&console.log('change "'+t.name+'" → "'+f.name+'"',y,A,f,D),t instanceof p.Texture&&(f=this.copySettings(t,f)),f&&(f.guid=M.guid),h(f)}else x&&console.warn("Could not find texture with guid",M.guid,b.parser.json)}if(A=0,b.parser.json.meshes){let E=!1;for(const f of b.parser.json.meshes){if(f!=null&&f.extensions){const m=f==null?void 0:f.extensions[U];if(m!=null&&m.guid&&m.guid===M.guid){E=!0;break}}A++}if(E){const f=await q.getDependency("mesh",A),m=M;if(r&&console.log(`Loaded Mesh "${f.name}"`,y,A,f,D),f.isMesh===!0){const S=f.geometry;return _.assignLODInformation(o.url,S,s,e,void 0,m.density),h(S)}else{const S=new Array;for(let T=0;T<f.children.length;T++){const P=f.children[T];if(P.isMesh===!0){const X=P.geometry;_.assignLODInformation(o.url,X,s,e,T,m.density),S.push(X)}}return h(S)}}else x&&console.warn("Could not find mesh with guid",M.guid,b.parser.json)}return h(null)});return this.previouslyLoaded.set(D,F),await F}else if(t instanceof p.Texture){r&&console.log("Load texture from uri: "+y);const v=await new p.TextureLoader().loadAsync(y);return v?(v.guid=i.guid,v.flipY=!1,v.needsUpdate=!0,v.colorSpace=t.colorSpace,r&&console.log(i,v)):x&&console.warn("failed loading",y),v}}else x&&console.warn(`Can not load LOD ${e}: no LOD info found for "${s}" ${t.name}`,t.type);return null}static assignLODInformation(t,e,r,o,s,i){if(!e)return;e.userData||(e.userData={});const n=new He(t,r,o,s,i);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(),x&&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 O=_;d(O,"registerTexture",(t,e,r,o,s)=>{if(x&&console.log("> Progressive: register texture",o,e.name,e.uuid,e,s),!e){x&&console.error("gltf-progressive: Register texture without texture");return}e.source&&(e.source[ye]=s);const i=s.guid;_.assignLODInformation(t,e,i,r,o,void 0),_.lodInfos.set(i,s),_.lowresCache.set(i,e)}),d(O,"registerMesh",(t,e,r,o,s,i)=>{var u;x&&console.log("> Progressive: register mesh",s,r.name,i,r.uuid,r);const n=r.geometry;if(!n){x&&console.warn("gltf-progressive: Register mesh without geometry");return}n.userData||(n.userData={}),_.assignLODInformation(t,n,e,o,s,i.density),_.lodInfos.set(e,i);let l=_.lowresCache.get(e);l?l.push(r.geometry):l=[r.geometry],_.lowresCache.set(e,l),o>0&&!oe(r)&&Pe(r,n);for(const c of Y)(u=c.onRegisteredNewMesh)==null||u.call(c,r,i)}),d(O,"lodInfos",new Map),d(O,"previouslyLoaded",new Map),d(O,"lowresCache",new Map);class Ke{constructor(t,e,r,o,s){d(this,"url");d(this,"key");d(this,"level");d(this,"index");d(this,"density");this.url=t,this.key=e,this.level=r,o!=null&&(this.index=o),s!=null&&(this.density=s)}}const G=ie("debugprogressive"),Ye=ie("noprogressive"),me=Symbol("Needle:LODSManager"),Le=Symbol("Needle:LODState"),H=Symbol("Needle:CurrentLOD"),V={mesh_lod:-1,texture_lod:-1};var B,z,de,Z,j,he,W;const C=class{constructor(t,e){d(this,"context");d(this,"renderer");d(this,"projectionScreenMatrix",new p.Matrix4);d(this,"targetTriangleDensity",2e5);d(this,"updateInterval","auto");K(this,B,1);d(this,"pause",!1);d(this,"manual",!1);d(this,"_lodchangedlisteners",[]);K(this,z,void 0);K(this,de,new p.Clock);K(this,Z,0);K(this,j,0);K(this,he,0);K(this,W,0);d(this,"_fpsBuffer",[60,60,60,60,60]);d(this,"_sphere",new p.Sphere);d(this,"_tempBox",new p.Box3);d(this,"_tempBox2",new p.Box3);d(this,"tempMatrix",new p.Matrix4);d(this,"_tempWorldPosition",new p.Vector3);d(this,"_tempBoxSize",new p.Vector3);d(this,"_tempBox2Size",new p.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[me])return console.debug("[gltf-progressive] LODsManager already exists for this renderer"),t[me];const r=new C(t,{engine:"unknown",...e});return t[me]=r,r}get plugins(){return Y}addEventListener(t,e){t==="changed"&&this._lodchangedlisteners.push(e)}removeEventListener(t,e){if(t==="changed"){const r=this._lodchangedlisteners.indexOf(e);r>=0&&this._lodchangedlisteners.splice(r,1)}}enable(){if(L(this,z))return;console.debug("[gltf-progressive] Enabling LODsManager for renderer");let t=0;N(this,z,this.renderer.render);const e=this;ve(this.renderer),this.renderer.render=function(r,o){const s=e.renderer.getRenderTarget();(s==null||"isXRRenderTarget"in s&&s.isXRRenderTarget)&&(t=0,N(e,Z,L(e,Z)+1),N(e,j,L(e,de).getDelta()),N(e,he,L(e,he)+L(e,j)),e._fpsBuffer.shift(),e._fpsBuffer.push(1/L(e,j)),N(e,W,e._fpsBuffer.reduce((n,l)=>n+l)/e._fpsBuffer.length),G&&L(e,Z)%200===0&&console.log("FPS",Math.round(L(e,W)),"Interval:",L(e,B)));const i=t++;L(e,z).call(this,r,o),e.onAfterRender(r,o,i)}}disable(){L(this,z)&&(this.renderer.render=L(this,z),N(this,z,void 0))}update(t,e){this.internalUpdate(t,e)}onAfterRender(t,e,r){if(this.pause)return;const s=this.renderer.renderLists.get(t,0).opaque;let i=!0;if(s.length===1){const n=s[0].material;(n.name==="EffectMaterial"||n.name==="CopyShader")&&(i=!1)}if((e.parent&&e.parent.type==="CubeCamera"||r>=1&&e.type==="OrthographicCamera")&&(i=!1),i){if(Ye||(this.updateInterval==="auto"?L(this,W)<40&&L(this,B)<10?(N(this,B,L(this,B)+1),G&&console.warn("↓ Reducing LOD updates",L(this,B),L(this,W).toFixed(0))):L(this,W)>=60&&L(this,B)>1&&(N(this,B,L(this,B)-1),G&&console.warn("↑ Increasing LOD updates",L(this,B),L(this,W).toFixed(0))):N(this,B,this.updateInterval),L(this,B)>0&&L(this,Z)%L(this,B)!=0))return;this.internalUpdate(t,e)}}internalUpdate(t,e){var l,u;const r=this.renderer.renderLists.get(t,0),o=r.opaque;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse);const s=this.targetTriangleDensity;for(const c of o){if(c.material&&(((l=c.geometry)==null?void 0:l.type)==="BoxGeometry"||((u=c.geometry)==null?void 0:u.type)==="BufferGeometry")&&(c.material.name==="SphericalGaussianBlur"||c.material.name=="BackgroundCubeMaterial"||c.material.name==="CubemapFromEquirect"||c.material.name==="EquirectangularToCubeUV")){G&&(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(G==="color"&&c.material&&!c.object.progressive_debug_color){c.object.progressive_debug_color=!0;const y=Math.random()*16777215,D=new p.MeshStandardMaterial({color:y});c.object.material=D}const g=c.object;(g instanceof p.Mesh||g.isMesh)&&this.updateLODs(t,e,g,s)}const i=r.transparent;for(const c of i){const g=c.object;(g instanceof p.Mesh||g.isMesh)&&this.updateLODs(t,e,g,s)}const n=r.transmissive;for(const c of n){const g=c.object;(g instanceof p.Mesh||g.isMesh)&&this.updateLODs(t,e,g,s)}}updateLODs(t,e,r,o){var n,l;r.userData||(r.userData={});let s=r[Le];if(s||(s=new He,r[Le]=s),s.frames++<2)return;for(const u of Y)(n=u.onBeforeUpdateLOD)==null||n.call(u,this.renderer,t,e,r);this.calculateLodLevel(e,r,s,o,V),V.mesh_lod=Math.round(V.mesh_lod),V.texture_lod=Math.round(V.texture_lod),V.mesh_lod>=0&&this.loadProgressiveMeshes(r,V.mesh_lod);let i=V.texture_lod;if(r.material&&i>=0){const u=r["DEBUG:LOD"];u!=null&&(i=u),this.loadProgressiveTextures(r.material,i)}for(const u of Y)(l=u.onAfterUpdatedLOD)==null||l.call(u,this.renderer,t,e,r,V);s.lastLodLevel_Mesh=V.mesh_lod,s.lastLodLevel_Texture=V.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,O.assignTextureLOD(t,e).then(o=>{this._lodchangedlisteners.forEach(s=>s({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 O.assignMeshLOD(t,e).then(o=>(o&&t[H]==e&&r!=t.geometry&&this._lodchangedlisteners.forEach(s=>s({type:"mesh",level:e,object:t})),o))}return Promise.resolve(null)}static isInside(t,e){const r=t.min,o=t.max,s=(r.x+o.x)*.5,i=(r.y+o.y)*.5;return this._tempPtInside.set(s,i,r.z).applyMatrix4(e).z<0}calculateLodLevel(t,e,r,o,s){var F;if(!e){s.mesh_lod=-1,s.texture_lod=-1;return}if(!t){s.mesh_lod=-1,s.texture_lod=-1;return}let n=10+1,l=!1;if(G&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const u=O.getMeshLODInformation(e.geometry),c=u==null?void 0:u.lods,g=c&&c.length>0,y=O.getMaterialMinMaxLODsCount(e.material),D=(y==null?void 0:y.min_count)!=1/0&&y.min_count>0&&y.max_count>0;if(!g&&!D){s.mesh_lod=0,s.texture_lod=0;return}g||(l=!0,n=0);const v=this.renderer.domElement.clientHeight||this.renderer.domElement.height;let M=e.geometry.boundingBox;if(e.type==="SkinnedMesh"){const w=e;if(!w.boundingBox)w.computeBoundingBox();else if(r.frames%30===0){const h=oe(w),R=w.geometry;h&&(w.geometry=h),w.computeBoundingBox(),w.geometry=R}M=w.boundingBox}if(M&&t.isPerspectiveCamera){const w=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)){s.mesh_lod=0,s.texture_lod=0;return}}if(this._tempBox.copy(M),this._tempBox.applyMatrix4(e.matrixWorld),C.isInside(this._tempBox,this.projectionScreenMatrix)){s.mesh_lod=0,s.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&w.fov>70){const f=this._tempBox.min,m=this._tempBox.max;let S=f.x,T=f.y,P=m.x,X=m.y;const ne=2,ge=1.5,ae=(f.x+m.x)*.5,le=(f.y+m.y)*.5;S=(S-ae)*ne+ae,T=(T-le)*ne+le,P=(P-ae)*ne+ae,X=(X-le)*ne+le;const Be=S<0&&P>0?0:Math.min(Math.abs(f.x),Math.abs(m.x)),Ie=T<0&&X>0?0:Math.min(Math.abs(f.y),Math.abs(m.y)),pe=Math.max(Be,Ie);r.lastCentrality=(ge-pe)*(ge-pe)*(ge-pe)}else r.lastCentrality=1;const h=this._tempBox.getSize(this._tempBoxSize);h.multiplyScalar(.5),screen.availHeight>0&&v>0&&h.multiplyScalar(v/screen.availHeight),h.x*=w.aspect;const R=t.matrixWorldInverse,$=this._tempBox2;$.copy(M),$.applyMatrix4(e.matrixWorld),$.applyMatrix4(R);const k=$.getSize(this._tempBox2Size),b=Math.max(k.x,k.y);if(Math.max(h.x,h.y)!=0&&b!=0&&(h.z=k.z/Math.max(k.x,k.y)*Math.max(h.x,h.y)),r.lastScreenCoverage=Math.max(h.x,h.y,h.z),r.lastScreenspaceVolume.copy(h),r.lastScreenCoverage*=r.lastCentrality,G&&C.debugDrawLine){const f=this.tempMatrix.copy(this.projectionScreenMatrix);f.invert();const m=C.corner0,S=C.corner1,T=C.corner2,P=C.corner3;m.copy(this._tempBox.min),S.copy(this._tempBox.max),S.x=m.x,T.copy(this._tempBox.max),T.y=m.y,P.copy(this._tempBox.max);const X=(m.z+P.z)*.5;m.z=S.z=T.z=P.z=X,m.applyMatrix4(f),S.applyMatrix4(f),T.applyMatrix4(f),P.applyMatrix4(f),C.debugDrawLine(m,S,255),C.debugDrawLine(m,T,255),C.debugDrawLine(S,P,255),C.debugDrawLine(T,P,255)}let A=999;if(c&&r.lastScreenCoverage>0){for(let f=0;f<c.length;f++)if(c[f].density/r.lastScreenCoverage<o){A=f;break}}A<n&&(n=A,l=!0)}if(l?s.mesh_lod=n:s.mesh_lod=r.lastLodLevel_Mesh,G&&s.mesh_lod!=r.lastLodLevel_Mesh){const h=c==null?void 0:c[s.mesh_lod];h&&console.log(`Mesh LOD changed: ${r.lastLodLevel_Mesh} → ${s.mesh_lod} (${h.density.toFixed(0)}) - ${e.name}`)}if(D){const w="saveData"in globalThis.navigator&&globalThis.navigator.saveData===!0;if(r.lastLodLevel_Texture<0){if(s.texture_lod=y.max_count-1,G){const h=y.lods[y.max_count-1];G&&console.log(`First Texture LOD ${s.texture_lod} (${h.max_height}px) - ${e.name}`)}}else{const h=r.lastScreenspaceVolume.x+r.lastScreenspaceVolume.y+r.lastScreenspaceVolume.z;let R=r.lastScreenCoverage*2;((F=this.context)==null?void 0:F.engine)==="model-viewer"&&(R*=2);const k=v/window.devicePixelRatio*R;for(let b=y.lods.length-1;b>=0;b--){let q=y.lods[b];if(!(w&&q.max_height>=2048)&&!(We()&&q.max_height>4096)&&q.max_height>k){if(s.texture_lod=b,s.texture_lod<r.lastLodLevel_Texture){const A=q.max_height;G&&console.log(`Texture LOD changed: ${r.lastLodLevel_Texture} → ${s.texture_lod} = ${A}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 O=_;d(O,"registerTexture",(t,e,r,o,s)=>{if(x&&console.log("> Progressive: register texture",o,e.name,e.uuid,e,s),!e){x&&console.error("gltf-progressive: Register texture without texture");return}e.source&&(e.source[me]=s);const i=s.guid;_.assignLODInformation(t,e,i,r,o,void 0),_.lodInfos.set(i,s),_.lowresCache.set(i,e)}),d(O,"registerMesh",(t,e,r,o,s,i)=>{var u;x&&console.log("> Progressive: register mesh",s,r.name,i,r.uuid,r);const n=r.geometry;if(!n){x&&console.warn("gltf-progressive: Register mesh without geometry");return}n.userData||(n.userData={}),_.assignLODInformation(t,n,e,o,s,i.density),_.lodInfos.set(e,i);let l=_.lowresCache.get(e);l?l.push(r.geometry):l=[r.geometry],_.lowresCache.set(e,l),o>0&&!ae(r)&&Pe(r,n);for(const c of Y)(u=c.onRegisteredNewMesh)==null||u.call(c,r,i)}),d(O,"lodInfos",new Map),d(O,"previouslyLoaded",new Map),d(O,"lowresCache",new Map);class He{constructor(t,e,r,o,s){d(this,"url");d(this,"key");d(this,"level");d(this,"index");d(this,"density");this.url=t,this.key=e,this.level=r,o!=null&&(this.index=o),s!=null&&(this.density=s)}}const G=ne("debugprogressive"),Je=ne("noprogressive"),Le=Symbol("Needle:LODSManager"),xe=Symbol("Needle:LODState"),H=Symbol("Needle:CurrentLOD"),V={mesh_lod:-1,texture_lod:-1};var B,z,he,j,ee,ge,W;const C=class{constructor(t,e){d(this,"context");d(this,"renderer");d(this,"projectionScreenMatrix",new p.Matrix4);d(this,"targetTriangleDensity",2e5);d(this,"updateInterval","auto");K(this,B,1);d(this,"pause",!1);d(this,"manual",!1);d(this,"_lodchangedlisteners",[]);K(this,z,void 0);K(this,he,new p.Clock);K(this,j,0);K(this,ee,0);K(this,ge,0);K(this,W,0);d(this,"_fpsBuffer",[60,60,60,60,60]);d(this,"_sphere",new p.Sphere);d(this,"_tempBox",new p.Box3);d(this,"_tempBox2",new p.Box3);d(this,"tempMatrix",new p.Matrix4);d(this,"_tempWorldPosition",new p.Vector3);d(this,"_tempBoxSize",new p.Vector3);d(this,"_tempBox2Size",new p.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[Le])return console.debug("[gltf-progressive] LODsManager already exists for this renderer"),t[Le];const r=new C(t,{engine:"unknown",...e});return t[Le]=r,r}get plugins(){return Y}addEventListener(t,e){t==="changed"&&this._lodchangedlisteners.push(e)}removeEventListener(t,e){if(t==="changed"){const r=this._lodchangedlisteners.indexOf(e);r>=0&&this._lodchangedlisteners.splice(r,1)}}enable(){if(L(this,z))return;console.debug("[gltf-progressive] Enabling LODsManager for renderer");let t=0;N(this,z,this.renderer.render);const e=this;ve(this.renderer),this.renderer.render=function(r,o){const s=e.renderer.getRenderTarget();(s==null||"isXRRenderTarget"in s&&s.isXRRenderTarget)&&(t=0,N(e,j,L(e,j)+1),N(e,ee,L(e,he).getDelta()),N(e,ge,L(e,ge)+L(e,ee)),e._fpsBuffer.shift(),e._fpsBuffer.push(1/L(e,ee)),N(e,W,e._fpsBuffer.reduce((n,l)=>n+l)/e._fpsBuffer.length),G&&L(e,j)%200===0&&console.log("FPS",Math.round(L(e,W)),"Interval:",L(e,B)));const i=t++;L(e,z).call(this,r,o),e.onAfterRender(r,o,i)}}disable(){L(this,z)&&(this.renderer.render=L(this,z),N(this,z,void 0))}update(t,e){this.internalUpdate(t,e)}onAfterRender(t,e,r){if(this.pause)return;const s=this.renderer.renderLists.get(t,0).opaque;let i=!0;if(s.length===1){const n=s[0].material;(n.name==="EffectMaterial"||n.name==="CopyShader")&&(i=!1)}if((e.parent&&e.parent.type==="CubeCamera"||r>=1&&e.type==="OrthographicCamera")&&(i=!1),i){if(Je||(this.updateInterval==="auto"?L(this,W)<40&&L(this,B)<10?(N(this,B,L(this,B)+1),G&&console.warn("↓ Reducing LOD updates",L(this,B),L(this,W).toFixed(0))):L(this,W)>=60&&L(this,B)>1&&(N(this,B,L(this,B)-1),G&&console.warn("↑ Increasing LOD updates",L(this,B),L(this,W).toFixed(0))):N(this,B,this.updateInterval),L(this,B)>0&&L(this,j)%L(this,B)!=0))return;this.internalUpdate(t,e)}}internalUpdate(t,e){var l,u;const r=this.renderer.renderLists.get(t,0),o=r.opaque;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse);const s=this.targetTriangleDensity;for(const c of o){if(c.material&&(((l=c.geometry)==null?void 0:l.type)==="BoxGeometry"||((u=c.geometry)==null?void 0:u.type)==="BufferGeometry")&&(c.material.name==="SphericalGaussianBlur"||c.material.name=="BackgroundCubeMaterial"||c.material.name==="CubemapFromEquirect"||c.material.name==="EquirectangularToCubeUV")){G&&(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(G==="color"&&c.material&&!c.object.progressive_debug_color){c.object.progressive_debug_color=!0;const y=Math.random()*16777215,D=new p.MeshStandardMaterial({color:y});c.object.material=D}const g=c.object;(g instanceof p.Mesh||g.isMesh)&&this.updateLODs(t,e,g,s)}const i=r.transparent;for(const c of i){const g=c.object;(g instanceof p.Mesh||g.isMesh)&&this.updateLODs(t,e,g,s)}const n=r.transmissive;for(const c of n){const g=c.object;(g instanceof p.Mesh||g.isMesh)&&this.updateLODs(t,e,g,s)}}updateLODs(t,e,r,o){var n,l;r.userData||(r.userData={});let s=r[xe];if(s||(s=new Qe,r[xe]=s),s.frames++<2)return;for(const u of Y)(n=u.onBeforeUpdateLOD)==null||n.call(u,this.renderer,t,e,r);this.calculateLodLevel(e,r,s,o,V),V.mesh_lod=Math.round(V.mesh_lod),V.texture_lod=Math.round(V.texture_lod),V.mesh_lod>=0&&this.loadProgressiveMeshes(r,V.mesh_lod);let i=V.texture_lod;if(r.material&&i>=0){const u=r["DEBUG:LOD"];u!=null&&(i=u),this.loadProgressiveTextures(r.material,i)}for(const u of Y)(l=u.onAfterUpdatedLOD)==null||l.call(u,this.renderer,t,e,r,V);s.lastLodLevel_Mesh=V.mesh_lod,s.lastLodLevel_Texture=V.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,O.assignTextureLOD(t,e).then(o=>{this._lodchangedlisteners.forEach(s=>s({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 O.assignMeshLOD(t,e).then(o=>(o&&t[H]==e&&r!=t.geometry&&this._lodchangedlisteners.forEach(s=>s({type:"mesh",level:e,object:t})),o))}return Promise.resolve(null)}static isInside(t,e){const r=t.min,o=t.max,s=(r.x+o.x)*.5,i=(r.y+o.y)*.5;return this._tempPtInside.set(s,i,r.z).applyMatrix4(e).z<0}calculateLodLevel(t,e,r,o,s){var F;if(!e){s.mesh_lod=-1,s.texture_lod=-1;return}if(!t){s.mesh_lod=-1,s.texture_lod=-1;return}let n=10+1,l=!1;if(G&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const u=O.getMeshLODInformation(e.geometry),c=u==null?void 0:u.lods,g=c&&c.length>0,y=O.getMaterialMinMaxLODsCount(e.material),D=(y==null?void 0:y.min_count)!=1/0&&y.min_count>0&&y.max_count>0;if(!g&&!D){s.mesh_lod=0,s.texture_lod=0;return}g||(l=!0,n=0);const v=this.renderer.domElement.clientHeight||this.renderer.domElement.height;let M=e.geometry.boundingBox;if(e.type==="SkinnedMesh"){const w=e;if(!w.boundingBox)w.computeBoundingBox();else if(r.frames%30===0){const h=ae(w),R=w.geometry;h&&(w.geometry=h),w.computeBoundingBox(),w.geometry=R}M=w.boundingBox}if(M&&t.isPerspectiveCamera){const w=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)){s.mesh_lod=0,s.texture_lod=0;return}}if(this._tempBox.copy(M),this._tempBox.applyMatrix4(e.matrixWorld),C.isInside(this._tempBox,this.projectionScreenMatrix)){s.mesh_lod=0,s.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&w.fov>70){const f=this._tempBox.min,m=this._tempBox.max;let S=f.x,T=f.y,P=m.x,X=m.y;const le=2,pe=1.5,ce=(f.x+m.x)*.5,ue=(f.y+m.y)*.5;S=(S-ce)*le+ce,T=(T-ue)*le+ue,P=(P-ce)*le+ce,X=(X-ue)*le+ue;const Be=S<0&&P>0?0:Math.min(Math.abs(f.x),Math.abs(m.x)),Ie=T<0&&X>0?0:Math.min(Math.abs(f.y),Math.abs(m.y)),ye=Math.max(Be,Ie);r.lastCentrality=(pe-ye)*(pe-ye)*(pe-ye)}else r.lastCentrality=1;const h=this._tempBox.getSize(this._tempBoxSize);h.multiplyScalar(.5),screen.availHeight>0&&v>0&&h.multiplyScalar(v/screen.availHeight),h.x*=w.aspect;const R=t.matrixWorldInverse,$=this._tempBox2;$.copy(M),$.applyMatrix4(e.matrixWorld),$.applyMatrix4(R);const k=$.getSize(this._tempBox2Size),b=Math.max(k.x,k.y);if(Math.max(h.x,h.y)!=0&&b!=0&&(h.z=k.z/Math.max(k.x,k.y)*Math.max(h.x,h.y)),r.lastScreenCoverage=Math.max(h.x,h.y,h.z),r.lastScreenspaceVolume.copy(h),r.lastScreenCoverage*=r.lastCentrality,G&&C.debugDrawLine){const f=this.tempMatrix.copy(this.projectionScreenMatrix);f.invert();const m=C.corner0,S=C.corner1,T=C.corner2,P=C.corner3;m.copy(this._tempBox.min),S.copy(this._tempBox.max),S.x=m.x,T.copy(this._tempBox.max),T.y=m.y,P.copy(this._tempBox.max);const X=(m.z+P.z)*.5;m.z=S.z=T.z=P.z=X,m.applyMatrix4(f),S.applyMatrix4(f),T.applyMatrix4(f),P.applyMatrix4(f),C.debugDrawLine(m,S,255),C.debugDrawLine(m,T,255),C.debugDrawLine(S,P,255),C.debugDrawLine(T,P,255)}let A=999;if(c&&r.lastScreenCoverage>0){for(let f=0;f<c.length;f++)if(c[f].density/r.lastScreenCoverage<o){A=f;break}}A<n&&(n=A,l=!0)}if(l?s.mesh_lod=n:s.mesh_lod=r.lastLodLevel_Mesh,G&&s.mesh_lod!=r.lastLodLevel_Mesh){const h=c==null?void 0:c[s.mesh_lod];h&&console.log(`Mesh LOD changed: ${r.lastLodLevel_Mesh} → ${s.mesh_lod} (${h.density.toFixed(0)}) - ${e.name}`)}if(D){const w="saveData"in globalThis.navigator&&globalThis.navigator.saveData===!0;if(r.lastLodLevel_Texture<0){if(s.texture_lod=y.max_count-1,G){const h=y.lods[y.max_count-1];G&&console.log(`First Texture LOD ${s.texture_lod} (${h.max_height}px) - ${e.name}`)}}else{const h=r.lastScreenspaceVolume.x+r.lastScreenspaceVolume.y+r.lastScreenspaceVolume.z;let R=r.lastScreenCoverage*2;((F=this.context)==null?void 0:F.engine)==="model-viewer"&&(R*=2);const k=v/window.devicePixelRatio*R;for(let b=y.lods.length-1;b>=0;b--){let q=y.lods[b];if(!(w&&q.max_height>=2048)&&!(Xe()&&q.max_height>4096)&&q.max_height>k){if(s.texture_lod=b,s.texture_lod<r.lastLodLevel_Texture){const A=q.max_height;G&&console.log(`Texture LOD changed: ${r.lastLodLevel_Texture} → ${s.texture_lod} = ${A}px
6
6
  Screensize: ${k.toFixed(0)}px, Coverage: ${(100*r.lastScreenCoverage).toFixed(2)}%, Volume ${h.toFixed(1)}
7
- ${e.name}`)}break}}}}else s.texture_lod=0}};let I=C;B=new WeakMap,z=new WeakMap,de=new WeakMap,Z=new WeakMap,j=new WeakMap,he=new WeakMap,W=new WeakMap,d(I,"debugDrawLine"),d(I,"corner0",new p.Vector3),d(I,"corner1",new p.Vector3),d(I,"corner2",new p.Vector3),d(I,"corner3",new p.Vector3),d(I,"_tempPtInside",new p.Vector3);class He{constructor(){d(this,"frames",0);d(this,"lastLodLevel_Mesh",-1);d(this,"lastLodLevel_Texture",-1);d(this,"lastScreenCoverage",0);d(this,"lastScreenspaceVolume",new p.Vector3);d(this,"lastCentrality",0)}}const Te=Symbol("NEEDLE_mesh_lod"),ce=Symbol("NEEDLE_texture_lod");let re=null;function Oe(){const a=Je();a&&(a.mapURLs(function(t){return Ae(),t}),Ae(),re==null||re.disconnect(),re=new MutationObserver(t=>{t.forEach(e=>{e.addedNodes.forEach(r=>{r instanceof HTMLElement&&r.tagName.toLowerCase()==="model-viewer"&&Ce(r)})})}),re.observe(document,{childList:!0,subtree:!0}))}function Je(){if(typeof customElements>"u")return null;const a=customElements.get("model-viewer");return a||(customElements.whenDefined("model-viewer").then(()=>{console.debug("[gltf-progressive] model-viewer defined"),Oe()}),null)}function Ae(){if(typeof document>"u")return;document.querySelectorAll("model-viewer").forEach(t=>{Ce(t)})}const Ee=new WeakSet;let Qe=0;function Ce(a){if(!a||Ee.has(a))return null;Ee.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 s=Object.getOwnPropertySymbols(o),i=s.find(u=>u.toString()=="Symbol(renderer)"),n=s.find(u=>u.toString()=="Symbol(scene)"),l=s.find(u=>u.toString()=="Symbol(needsRender)");!t&&i!=null&&(t=a[i].threeRenderer),!e&&n!=null&&(e=a[n]),!r&&l!=null&&(r=a[l])}if(t&&e){let o=function(){if(r){let i=0,n=setInterval(()=>{if(i++>5){clearInterval(n);return}r==null||r.call(a)},300)}};console.debug("[gltf-progressive] setup model-viewer");const s=I.get(t,{engine:"model-viewer"});return I.addPlugin(new Ze),s.enable(),s.addEventListener("changed",()=>{r==null||r.call(a)}),a.addEventListener("model-visibility",i=>{i.detail.visible&&(r==null||r.call(a))}),a.addEventListener("load",()=>{o()}),()=>{s.disable()}}return null}class Ze{constructor(){d(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),s=this.getUrl(o);if(s&&r&&e.material){let i=function(l){var c,g,y;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 v=u[D],M=l[v];if((M==null?void 0:M.isTexture)===!0){const F=(g=(c=M.userData)==null?void 0:c.associations)==null?void 0:g.textures;if(F==null)continue;const w=r.parser.json.textures[F];if(!w){console.warn("Texture data not found for texture index "+F);continue}if((y=w==null?void 0:w.extensions)!=null&&y[U]){const h=w.extensions[U];h&&s&&O.registerTexture(s,M,h.lods.length,F,h)}}}};const n=e.material;if(Array.isArray(n))for(const l of n)i(l);else i(n)}}tryParseMeshLOD(t,e){var i,n;if(e[Te]==!0)return;e[Te]=!0;const r=this.tryGetCurrentModelViewer(t),o=this.getUrl(r);if(!o)return;const s=(n=(i=e.userData)==null?void 0:i.gltfExtensions)==null?void 0:n[U];if(s&&o){const l=e.uuid;O.registerMesh(o,l,e,0,s.lods.length,s)}}}function je(a,t,e,r){ve(t),_e(e),e.register(s=>new O(s,a));const o=I.get(t);return(r==null?void 0:r.enableLODsManager)!==!1&&o.enable(),o}Oe();exports.EXTENSION_NAME=U;exports.LODsManager=I;exports.NEEDLE_progressive=O;exports.VERSION=De;exports.addDracoAndKTX2Loaders=_e;exports.createLoaders=ve;exports.getRaycastMesh=oe;exports.patchModelViewer=Oe;exports.registerRaycastMesh=Pe;exports.setDracoDecoderLocation=Ne;exports.setKTX2TranscoderLocation=Ue;exports.useNeedleProgressive=je;exports.useRaycastMeshes=qe;
7
+ ${e.name}`)}break}}}}else s.texture_lod=0}};let I=C;B=new WeakMap,z=new WeakMap,he=new WeakMap,j=new WeakMap,ee=new WeakMap,ge=new WeakMap,W=new WeakMap,d(I,"debugDrawLine"),d(I,"corner0",new p.Vector3),d(I,"corner1",new p.Vector3),d(I,"corner2",new p.Vector3),d(I,"corner3",new p.Vector3),d(I,"_tempPtInside",new p.Vector3);class Qe{constructor(){d(this,"frames",0);d(this,"lastLodLevel_Mesh",-1);d(this,"lastLodLevel_Texture",-1);d(this,"lastScreenCoverage",0);d(this,"lastScreenspaceVolume",new p.Vector3);d(this,"lastCentrality",0)}}const Te=Symbol("NEEDLE_mesh_lod"),fe=Symbol("NEEDLE_texture_lod");let se=null;function Oe(){const a=Ze();a&&(a.mapURLs(function(t){return Ae(),t}),Ae(),se==null||se.disconnect(),se=new MutationObserver(t=>{t.forEach(e=>{e.addedNodes.forEach(r=>{r instanceof HTMLElement&&r.tagName.toLowerCase()==="model-viewer"&&Ce(r)})})}),se.observe(document,{childList:!0,subtree:!0}))}function Ze(){if(typeof customElements>"u")return null;const a=customElements.get("model-viewer");return a||(customElements.whenDefined("model-viewer").then(()=>{console.debug("[gltf-progressive] model-viewer defined"),Oe()}),null)}function Ae(){if(typeof document>"u")return;document.querySelectorAll("model-viewer").forEach(t=>{Ce(t)})}const Ee=new WeakSet;let je=0;function Ce(a){if(!a||Ee.has(a))return null;Ee.add(a),console.debug("[gltf-progressive] found new model-viewer..."+ ++je+`
8
+ `,a.getAttribute("src"));let t=null,e=null,r=null;for(let o=a;o!=null;o=Object.getPrototypeOf(o)){const s=Object.getOwnPropertySymbols(o),i=s.find(u=>u.toString()=="Symbol(renderer)"),n=s.find(u=>u.toString()=="Symbol(scene)"),l=s.find(u=>u.toString()=="Symbol(needsRender)");!t&&i!=null&&(t=a[i].threeRenderer),!e&&n!=null&&(e=a[n]),!r&&l!=null&&(r=a[l])}if(t&&e){let o=function(){if(r){let i=0,n=setInterval(()=>{if(i++>5){clearInterval(n);return}r==null||r.call(a)},300)}};console.debug("[gltf-progressive] setup model-viewer");const s=I.get(t,{engine:"model-viewer"});return I.addPlugin(new et),s.enable(),s.addEventListener("changed",()=>{r==null||r.call(a)}),a.addEventListener("model-visibility",i=>{i.detail.visible&&(r==null||r.call(a))}),a.addEventListener("load",()=>{o()}),()=>{s.disable()}}return null}class et{constructor(){d(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[fe]==!0)return;e[fe]=!0;const r=this.tryGetCurrentGLTF(t),o=this.tryGetCurrentModelViewer(t),s=this.getUrl(o);if(s&&r&&e.material){let i=function(l){var c,g,y;if(l[fe]==!0)return;l[fe]=!0,l.userData&&(l.userData.LOD=-1);const u=Object.keys(l);for(let D=0;D<u.length;D++){const v=u[D],M=l[v];if((M==null?void 0:M.isTexture)===!0){const F=(g=(c=M.userData)==null?void 0:c.associations)==null?void 0:g.textures;if(F==null)continue;const w=r.parser.json.textures[F];if(!w){console.warn("Texture data not found for texture index "+F);continue}if((y=w==null?void 0:w.extensions)!=null&&y[U]){const h=w.extensions[U];h&&s&&O.registerTexture(s,M,h.lods.length,F,h)}}}};const n=e.material;if(Array.isArray(n))for(const l of n)i(l);else i(n)}}tryParseMeshLOD(t,e){var i,n;if(e[Te]==!0)return;e[Te]=!0;const r=this.tryGetCurrentModelViewer(t),o=this.getUrl(r);if(!o)return;const s=(n=(i=e.userData)==null?void 0:i.gltfExtensions)==null?void 0:n[U];if(s&&o){const l=e.uuid;O.registerMesh(o,l,e,0,s.lods.length,s)}}}function tt(a,t,e,r){ve(t),_e(e),e.register(s=>new O(s,a));const o=I.get(t);return(r==null?void 0:r.enableLODsManager)!==!1&&o.enable(),o}Oe();exports.EXTENSION_NAME=U;exports.LODsManager=I;exports.NEEDLE_progressive=O;exports.VERSION=we;exports.addDracoAndKTX2Loaders=_e;exports.createLoaders=ve;exports.getRaycastMesh=ae;exports.patchModelViewer=Oe;exports.registerRaycastMesh=Pe;exports.setDracoDecoderLocation=ze;exports.setKTX2TranscoderLocation=We;exports.useNeedleProgressive=tt;exports.useRaycastMeshes=Ke;
package/lib/loaders.js CHANGED
@@ -1,12 +1,18 @@
1
1
  import { MeshoptDecoder } from 'three/examples/jsm/libs/meshopt_decoder.module.js';
2
2
  import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
3
3
  import { KTX2Loader } from 'three/examples/jsm/loaders/KTX2Loader.js';
4
- let DEFAULT_DRACO_DECODER_LOCATION = 'https://www.gstatic.com/draco/versioned/decoders/1.4.1/';
4
+ let DEFAULT_DRACO_DECODER_LOCATION = 'https://www.gstatic.com/draco/versioned/decoders/1.5.7/';
5
5
  let DEFAULT_KTX2_TRANSCODER_LOCATION = 'https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/';
6
+ const defaultDraco = DEFAULT_DRACO_DECODER_LOCATION;
7
+ const defaultKTX2 = DEFAULT_KTX2_TRANSCODER_LOCATION;
6
8
  fetch(DEFAULT_DRACO_DECODER_LOCATION + "draco_decoder.js", { method: "head" })
7
9
  .catch(_ => {
8
- DEFAULT_DRACO_DECODER_LOCATION = "./include/draco/";
9
- DEFAULT_KTX2_TRANSCODER_LOCATION = "./include/ktx2/";
10
+ // check if the default values have been changed by the user.
11
+ // If they didnt change / the default paths are not reachable, fall back to local versions
12
+ if (DEFAULT_DRACO_DECODER_LOCATION === defaultDraco)
13
+ DEFAULT_DRACO_DECODER_LOCATION = "./include/draco/";
14
+ if (DEFAULT_KTX2_TRANSCODER_LOCATION === defaultKTX2)
15
+ DEFAULT_KTX2_TRANSCODER_LOCATION = "./include/ktx2/";
10
16
  });
11
17
  /**
12
18
  * Set the location of the Draco decoder.
package/lib/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  // replaced at build time
2
- export const version = "1.2.10";
2
+ export const version = "1.2.11";
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.10",
3
+ "version": "1.2.11",
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": {