@needle-tools/gltf-progressive 2.1.0-alpha.1 → 2.1.0-alpha.2

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
+ ## [2.1.0-alpha.2] - 2025-01-17
8
+ - Add: expose methods in globalThis/window at `Needle.gltfProgressive`
9
+
7
10
  ## [2.1.0-alpha.1] - 2025-01-15
8
11
  - Fix: issue where `getMeshLOD` for multi-material meshes would not return the correct index if called multiple times at the same time
9
12
 
@@ -1,48 +1,48 @@
1
- var Ve = Object.defineProperty;
2
- var Ne = (o, t, e) => t in o ? Ve(o, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[t] = e;
3
- var d = (o, t, e) => (Ne(o, typeof t != "symbol" ? t + "" : t, e), e), Te = (o, t, e) => {
1
+ var We = Object.defineProperty;
2
+ var qe = (o, t, e) => t in o ? We(o, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[t] = e;
3
+ var d = (o, t, e) => (qe(o, typeof t != "symbol" ? t + "" : t, e), e), Ae = (o, t, e) => {
4
4
  if (!t.has(o))
5
5
  throw TypeError("Cannot " + e);
6
6
  };
7
- var m = (o, t, e) => (Te(o, t, "read from private field"), e ? e.call(o) : t.get(o)), K = (o, t, e) => {
7
+ var m = (o, t, e) => (Ae(o, t, "read from private field"), e ? e.call(o) : t.get(o)), K = (o, t, e) => {
8
8
  if (t.has(o))
9
9
  throw TypeError("Cannot add the same private member more than once");
10
10
  t instanceof WeakSet ? t.add(o) : t.set(o, e);
11
- }, U = (o, t, e, s) => (Te(o, t, "write to private field"), s ? s.call(o, e) : t.set(o, e), e);
12
- import { BufferGeometry as ge, Mesh as H, Material as We, Texture as se, TextureLoader as qe, Matrix4 as Ae, Clock as Xe, MeshStandardMaterial as Ke, Sphere as Ye, Box3 as Ee, Vector3 as z } from "three";
13
- import { GLTFLoader as be } from "three/examples/jsm/loaders/GLTFLoader.js";
14
- import { MeshoptDecoder as He } from "three/examples/jsm/libs/meshopt_decoder.module.js";
15
- import { DRACOLoader as Je } from "three/examples/jsm/loaders/DRACOLoader.js";
16
- import { KTX2Loader as Qe } from "three/examples/jsm/loaders/KTX2Loader.js";
17
- const Ie = "";
18
- globalThis.GLTF_PROGRESSIVE_VERSION = Ie;
19
- console.debug(`[gltf-progressive] version ${Ie}`);
11
+ }, U = (o, t, e, s) => (Ae(o, t, "write to private field"), s ? s.call(o, e) : t.set(o, e), e);
12
+ import { BufferGeometry as pe, Mesh as H, Material as Xe, Texture as se, TextureLoader as Ke, Matrix4 as Ee, Clock as Ye, MeshStandardMaterial as He, Sphere as Je, Box3 as Pe, Vector3 as N } from "three";
13
+ import { GLTFLoader as Te } from "three/examples/jsm/loaders/GLTFLoader.js";
14
+ import { MeshoptDecoder as Qe } from "three/examples/jsm/libs/meshopt_decoder.module.js";
15
+ import { DRACOLoader as Ze } from "three/examples/jsm/loaders/DRACOLoader.js";
16
+ import { KTX2Loader as je } from "three/examples/jsm/loaders/KTX2Loader.js";
17
+ const Re = "";
18
+ globalThis.GLTF_PROGRESSIVE_VERSION = Re;
19
+ console.debug(`[gltf-progressive] version ${Re}`);
20
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 Ze = j, je = ae;
21
+ const et = j, tt = ae;
22
22
  fetch(j + "draco_decoder.js", { method: "head" }).catch((o) => {
23
- j === Ze && (j = "./include/draco/"), ae === je && (ae = "./include/ktx2/");
23
+ j === et && (j = "./include/draco/"), ae === tt && (ae = "./include/ktx2/");
24
24
  });
25
- function Lt(o) {
25
+ function Dt(o) {
26
26
  j = o;
27
27
  }
28
- function xt(o) {
28
+ function wt(o) {
29
29
  ae = o;
30
30
  }
31
- let Q, he, Z;
32
- function Re(o) {
33
- return Q || (Q = new Je(), Q.setDecoderPath(j), Q.setDecoderConfig({ type: "js" })), Z || (Z = new Qe(), Z.setTranscoderPath(ae)), he || (he = He), o ? Z.detectSupport(o) : o !== null && console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"), { dracoLoader: Q, ktx2Loader: Z, meshoptDecoder: he };
34
- }
31
+ let Q, ge, Z;
35
32
  function Ge(o) {
36
- o.dracoLoader || o.setDRACOLoader(Q), o.ktx2Loader || o.setKTX2Loader(Z), o.meshoptDecoder || o.setMeshoptDecoder(he);
33
+ return Q || (Q = new Ze(), Q.setDecoderPath(j), Q.setDecoderConfig({ type: "js" })), Z || (Z = new je(), Z.setTranscoderPath(ae)), ge || (ge = Qe), o ? Z.detectSupport(o) : o !== null && console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"), { dracoLoader: Q, ktx2Loader: Z, meshoptDecoder: ge };
34
+ }
35
+ function $e(o) {
36
+ o.dracoLoader || o.setDRACOLoader(Q), o.ktx2Loader || o.setKTX2Loader(Z), o.meshoptDecoder || o.setMeshoptDecoder(ge);
37
37
  }
38
- const Oe = /* @__PURE__ */ new WeakMap();
39
- function et(o, t) {
40
- let e = Oe.get(o);
41
- e ? e = Object.assign(e, t) : e = t, Oe.set(o, e);
38
+ const _e = /* @__PURE__ */ new WeakMap();
39
+ function Fe(o, t) {
40
+ let e = _e.get(o);
41
+ e ? e = Object.assign(e, t) : e = t, _e.set(o, e);
42
42
  }
43
- const Me = be.prototype.load;
44
- function tt(...o) {
45
- const t = Oe.get(this);
43
+ const Me = Te.prototype.load;
44
+ function st(...o) {
45
+ const t = _e.get(this);
46
46
  let e = o[0];
47
47
  const s = new URL(e, window.location.href);
48
48
  if (s.hostname.endsWith("needle.tools")) {
@@ -51,7 +51,7 @@ function tt(...o) {
51
51
  }
52
52
  return o[0] = e, Me == null ? void 0 : Me.call(this, ...o);
53
53
  }
54
- be.prototype.load = tt;
54
+ Te.prototype.load = st;
55
55
  le("debugprogressive");
56
56
  function le(o) {
57
57
  if (typeof window > "u")
@@ -59,7 +59,7 @@ function le(o) {
59
59
  const e = new URL(window.location.href).searchParams.get(o);
60
60
  return e == null || e === "0" || e === "false" ? !1 : e === "" ? !0 : e;
61
61
  }
62
- function st(o, t) {
62
+ function rt(o, t) {
63
63
  if (t === void 0 || t.startsWith("./") || t.startsWith("http") || o === void 0)
64
64
  return t;
65
65
  const e = o.lastIndexOf("/");
@@ -72,26 +72,26 @@ function st(o, t) {
72
72
  return t;
73
73
  }
74
74
  let re;
75
- function rt() {
75
+ function it() {
76
76
  return re !== void 0 || (re = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent), le("debugprogressive") && console.log("[glTF Progressive]: isMobileDevice", re)), re;
77
77
  }
78
- const _e = Symbol("needle:raycast-mesh");
79
- function me(o) {
80
- return (o == null ? void 0 : o[_e]) instanceof ge ? o[_e] : null;
78
+ const Se = Symbol("needle:raycast-mesh");
79
+ function ce(o) {
80
+ return (o == null ? void 0 : o[Se]) instanceof pe ? o[Se] : null;
81
81
  }
82
- function it(o, t) {
83
- if ((o.type === "Mesh" || o.type === "SkinnedMesh") && !me(o)) {
84
- const s = nt(t);
85
- s.userData = { isRaycastMesh: !0 }, o[_e] = s;
82
+ function nt(o, t) {
83
+ if ((o.type === "Mesh" || o.type === "SkinnedMesh") && !ce(o)) {
84
+ const s = at(t);
85
+ s.userData = { isRaycastMesh: !0 }, o[Se] = s;
86
86
  }
87
87
  }
88
- function Mt(o = !0) {
88
+ function ot(o = !0) {
89
89
  if (o) {
90
90
  if (ie)
91
91
  return;
92
92
  const t = ie = H.prototype.raycast;
93
93
  H.prototype.raycast = function(e, s) {
94
- const n = this, r = me(n);
94
+ const n = this, r = ce(n);
95
95
  let i;
96
96
  r && n.isMesh && (i = n.geometry, n.geometry = r), t.call(this, e, s), i && (n.geometry = i);
97
97
  };
@@ -102,13 +102,13 @@ function Mt(o = !0) {
102
102
  }
103
103
  }
104
104
  let ie = null;
105
- function nt(o) {
106
- const t = new ge();
105
+ function at(o) {
106
+ const t = new pe();
107
107
  for (const e in o.attributes)
108
108
  t.setAttribute(e, o.getAttribute(e));
109
109
  return t.setIndex(o.getIndex()), t;
110
110
  }
111
- const Y = new Array(), V = "NEEDLE_progressive", L = le("debugprogressive"), De = Symbol("needle-progressive-texture"), oe = /* @__PURE__ */ new Map(), Se = /* @__PURE__ */ new Set();
111
+ const Y = new Array(), z = "NEEDLE_progressive", L = le("debugprogressive"), De = Symbol("needle-progressive-texture"), oe = /* @__PURE__ */ new Map(), be = /* @__PURE__ */ new Set();
112
112
  if (L) {
113
113
  let o = function() {
114
114
  t += 1, console.log("Toggle LOD level", t, oe), oe.forEach((n, r) => {
@@ -127,12 +127,12 @@ if (L) {
127
127
  }), t >= e && (t = -1);
128
128
  }, t = -1, e = 2, s = !1;
129
129
  window.addEventListener("keyup", (n) => {
130
- n.key === "p" && o(), n.key === "w" && (s = !s, Se && Se.forEach((r) => {
130
+ n.key === "p" && o(), n.key === "w" && (s = !s, be && be.forEach((r) => {
131
131
  r.name != "BackgroundCubeMaterial" && r.glyphMap == null && "wireframe" in r && (r.wireframe = s);
132
132
  }));
133
133
  });
134
134
  }
135
- function Pe(o, t, e) {
135
+ function Ce(o, t, e) {
136
136
  var n;
137
137
  if (!L)
138
138
  return;
@@ -149,7 +149,7 @@ const v = class {
149
149
  var s, n;
150
150
  if (this._isLoadingMesh)
151
151
  return null;
152
- const e = (n = (s = this.parser.json.meshes[t]) == null ? void 0 : s.extensions) == null ? void 0 : n[V];
152
+ const e = (n = (s = this.parser.json.meshes[t]) == null ? void 0 : s.extensions) == null ? void 0 : n[z];
153
153
  return e ? (this._isLoadingMesh = !0, this.parser.getDependency("mesh", t).then((r) => {
154
154
  var i;
155
155
  return this._isLoadingMesh = !1, r && v.registerMesh(this.url, e.guid, r, (i = e.lods) == null ? void 0 : i.length, void 0, e), r;
@@ -159,7 +159,7 @@ const v = class {
159
159
  }
160
160
  /** The name of the extension */
161
161
  get name() {
162
- return V;
162
+ return z;
163
163
  }
164
164
  static getMeshLODInformation(t) {
165
165
  const e = this.getAssignedLODInformation(t);
@@ -268,7 +268,7 @@ const v = class {
268
268
  const a = r.index || 0;
269
269
  i = i[a];
270
270
  }
271
- return t["LOD:requested level"] === e && (delete t["LOD:requested level"], i && n != i && ((i == null ? void 0 : i.isBufferGeometry) ? (t.geometry = i, L && Pe(t, "geometry", r.url)) : L && console.error("Invalid LOD geometry", i))), i;
271
+ return t["LOD:requested level"] === e && (delete t["LOD:requested level"], i && n != i && ((i == null ? void 0 : i.isBufferGeometry) ? (t.geometry = i, L && Ce(t, "geometry", r.url)) : L && console.error("Invalid LOD geometry", i))), i;
272
272
  }).catch((i) => (console.error("Error loading mesh LOD", t, i), null));
273
273
  } else
274
274
  L && console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh", t);
@@ -294,9 +294,9 @@ const v = class {
294
294
  } else
295
295
  return this.assignTextureLOD(s.material, e);
296
296
  }
297
- if (t instanceof We || t.isMaterial === !0) {
297
+ if (t instanceof Xe || t.isMaterial === !0) {
298
298
  const s = t, n = [], r = new Array();
299
- if (L && Se.add(s), s.uniforms && (s.isRawShaderMaterial || s.isShaderMaterial === !0)) {
299
+ if (L && be.add(s), s.uniforms && (s.isRawShaderMaterial || s.isShaderMaterial === !0)) {
300
300
  const i = s;
301
301
  for (const a of Object.keys(i.uniforms)) {
302
302
  const l = i.uniforms[a].value;
@@ -345,7 +345,7 @@ const v = class {
345
345
  }
346
346
  if (L && n && s) {
347
347
  const i = this.getAssignedLODInformation(t);
348
- i && Pe(s, n, i.url);
348
+ i && Ce(s, n, i.url);
349
349
  }
350
350
  }
351
351
  return r;
@@ -359,7 +359,7 @@ const v = class {
359
359
  return L && console.log("AFTER", this.url, t), (e = this.parser.json.textures) == null || e.forEach((n, r) => {
360
360
  var i;
361
361
  if (n != null && n.extensions) {
362
- const a = n == null ? void 0 : n.extensions[V];
362
+ const a = n == null ? void 0 : n.extensions[z];
363
363
  if (a) {
364
364
  if (!a.lods) {
365
365
  L && console.warn("Texture has no LODs", a);
@@ -379,7 +379,7 @@ const v = class {
379
379
  }
380
380
  }), (s = this.parser.json.meshes) == null || s.forEach((n, r) => {
381
381
  if (n != null && n.extensions) {
382
- const i = n == null ? void 0 : n.extensions[V];
382
+ const i = n == null ? void 0 : n.extensions[z];
383
383
  if (i && i.lods) {
384
384
  for (const a of this.parser.associations.keys())
385
385
  if (a.isMesh) {
@@ -411,7 +411,7 @@ const v = class {
411
411
  const g = Array.isArray(i.lods) ? (a = i.lods[e]) == null ? void 0 : a.path : i.lods;
412
412
  if (!g)
413
413
  return L && !i["missing:uri"] && (i["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + e, i)), null;
414
- const p = st(n.url, g);
414
+ const p = rt(n.url, g);
415
415
  if (p.endsWith(".glb") || p.endsWith(".gltf")) {
416
416
  if (!i.guid)
417
417
  return console.warn("missing pointer for glb/gltf texture", i), null;
@@ -419,19 +419,19 @@ const v = class {
419
419
  if (w !== void 0) {
420
420
  s && console.log(`LOD ${e} was already loading/loaded: ${M}`);
421
421
  let h = await w.catch((F) => (console.error(`Error loading LOD ${e} from ${p}
422
- `, F), null)), B = !1;
423
- 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)
422
+ `, F), null)), k = !1;
423
+ 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) : (k = !0, this.previouslyLoaded.delete(M)) : h instanceof pe && t instanceof pe && ((c = h.attributes.position) != null && c.array || (k = !0, this.previouslyLoaded.delete(M)))), !k)
424
424
  return h;
425
425
  }
426
- const x = i, $ = new Promise(async (h, B) => {
427
- const F = new be();
428
- Ge(F), L && (await new Promise((A) => setTimeout(A, 1e3)), s && console.warn("Start loading (delayed) " + p, x.guid));
429
- let k = p;
426
+ const x = i, $ = new Promise(async (h, k) => {
427
+ const F = new Te();
428
+ $e(F), L && (await new Promise((A) => setTimeout(A, 1e3)), s && console.warn("Start loading (delayed) " + p, x.guid));
429
+ let I = p;
430
430
  if (x && Array.isArray(x.lods)) {
431
431
  const A = x.lods[e];
432
- A.hash && (k += "?v=" + A.hash);
432
+ A.hash && (I += "?v=" + A.hash);
433
433
  }
434
- const S = await F.loadAsync(k).catch((A) => (console.error(`Error loading LOD ${e} from ${p}
434
+ const S = await F.loadAsync(I).catch((A) => (console.error(`Error loading LOD ${e} from ${p}
435
435
  `, A), null));
436
436
  if (!S)
437
437
  return null;
@@ -442,7 +442,7 @@ const v = class {
442
442
  let A = !1;
443
443
  for (const f of S.parser.json.textures) {
444
444
  if (f != null && f.extensions) {
445
- const y = f == null ? void 0 : f.extensions[V];
445
+ const y = f == null ? void 0 : f.extensions[z];
446
446
  if (y != null && y.guid && y.guid === x.guid) {
447
447
  A = !0;
448
448
  break;
@@ -460,7 +460,7 @@ const v = class {
460
460
  let A = !1;
461
461
  for (const f of S.parser.json.meshes) {
462
462
  if (f != null && f.extensions) {
463
- const y = f == null ? void 0 : f.extensions[V];
463
+ const y = f == null ? void 0 : f.extensions[z];
464
464
  if (y != null && y.guid && y.guid === x.guid) {
465
465
  A = !0;
466
466
  break;
@@ -492,7 +492,7 @@ const v = class {
492
492
  return this.previouslyLoaded.set(M, $), await $;
493
493
  } else if (t instanceof se) {
494
494
  s && console.log("Load texture from uri: " + p);
495
- const w = await new qe().loadAsync(p);
495
+ const w = await new Ke().loadAsync(p);
496
496
  return w ? (w.guid = i.guid, w.flipY = !1, w.needsUpdate = !0, w.colorSpace = t.colorSpace, s && console.log(i, w)) : L && console.warn("failed loading", p), w;
497
497
  }
498
498
  } else
@@ -503,7 +503,7 @@ const v = class {
503
503
  if (!e)
504
504
  return;
505
505
  e.userData || (e.userData = {});
506
- const a = new ot(t, s, n, r, i);
506
+ const a = new lt(t, s, n, r, i);
507
507
  e.userData.LODS = a;
508
508
  }
509
509
  static getAssignedLODInformation(t) {
@@ -542,14 +542,14 @@ d(_, "registerMesh", (t, e, s, n, r, i) => {
542
542
  }
543
543
  a.userData || (a.userData = {}), v.assignLODInformation(t, a, e, n, r, i.density), v.lodInfos.set(e, i);
544
544
  let l = v.lowresCache.get(e);
545
- l ? l.push(s.geometry) : l = [s.geometry], v.lowresCache.set(e, l), n > 0 && !me(s) && it(s, a);
545
+ l ? l.push(s.geometry) : l = [s.geometry], v.lowresCache.set(e, l), n > 0 && !ce(s) && nt(s, a);
546
546
  for (const c of Y)
547
547
  (u = c.onRegisteredNewMesh) == null || u.call(c, s, i);
548
548
  }), /** A map of key = asset uuid and value = LOD information */
549
549
  d(_, "lodInfos", /* @__PURE__ */ new Map()), /** cache of already loaded mesh lods */
550
550
  d(_, "previouslyLoaded", /* @__PURE__ */ new Map()), /** this contains the geometry/textures that were originally loaded */
551
551
  d(_, "lowresCache", /* @__PURE__ */ new Map());
552
- class ot {
552
+ class lt {
553
553
  constructor(t, e, s, n, r) {
554
554
  d(this, "url");
555
555
  /** the key to lookup the LOD information */
@@ -562,14 +562,14 @@ class ot {
562
562
  this.url = t, this.key = e, this.level = s, n != null && (this.index = n), r != null && (this.density = r);
563
563
  }
564
564
  }
565
- const I = le("debugprogressive"), at = le("noprogressive"), we = Symbol("Needle:LODSManager"), ve = Symbol("Needle:LODState"), J = Symbol("Needle:CurrentLOD"), R = { mesh_lod: -1, texture_lod: -1 };
566
- var C, N, pe, ee, te, ye, W;
565
+ const R = le("debugprogressive"), ct = le("noprogressive"), we = Symbol("Needle:LODSManager"), ve = Symbol("Needle:LODState"), J = Symbol("Needle:CurrentLOD"), G = { mesh_lod: -1, texture_lod: -1 };
566
+ var C, V, ye, ee, te, me, W;
567
567
  const P = class {
568
568
  // readonly plugins: NEEDLE_progressive_plugin[] = [];
569
569
  constructor(t, e) {
570
570
  d(this, "context");
571
571
  d(this, "renderer");
572
- d(this, "projectionScreenMatrix", new Ae());
572
+ d(this, "projectionScreenMatrix", new Ee());
573
573
  /**
574
574
  * The target triangle density is the desired max amount of triangles on screen when the mesh is filling the screen.
575
575
  * @default 200_000
@@ -593,21 +593,21 @@ const P = class {
593
593
  */
594
594
  d(this, "manual", !1);
595
595
  d(this, "_lodchangedlisteners", []);
596
- K(this, N, void 0);
597
- K(this, pe, new Xe());
596
+ K(this, V, void 0);
597
+ K(this, ye, new Ye());
598
598
  K(this, ee, 0);
599
599
  K(this, te, 0);
600
- K(this, ye, 0);
600
+ K(this, me, 0);
601
601
  K(this, W, 0);
602
602
  d(this, "_fpsBuffer", [60, 60, 60, 60, 60]);
603
603
  // private testIfLODLevelsAreAvailable() {
604
- d(this, "_sphere", new Ye());
605
- d(this, "_tempBox", new Ee());
606
- d(this, "_tempBox2", new Ee());
607
- d(this, "tempMatrix", new Ae());
608
- d(this, "_tempWorldPosition", new z());
609
- d(this, "_tempBoxSize", new z());
610
- d(this, "_tempBox2Size", new z());
604
+ d(this, "_sphere", new Je());
605
+ d(this, "_tempBox", new Pe());
606
+ d(this, "_tempBox2", new Pe());
607
+ d(this, "tempMatrix", new Ee());
608
+ d(this, "_tempWorldPosition", new N());
609
+ d(this, "_tempBoxSize", new N());
610
+ d(this, "_tempBox2Size", new N());
611
611
  this.renderer = t, this.context = { ...e };
612
612
  }
613
613
  /** @internal */
@@ -652,21 +652,21 @@ const P = class {
652
652
  * Enable the LODsManager. This will replace the render method of the renderer with a method that updates the LODs.
653
653
  */
654
654
  enable() {
655
- if (m(this, N))
655
+ if (m(this, V))
656
656
  return;
657
657
  console.debug("[gltf-progressive] Enabling LODsManager for renderer");
658
658
  let t = 0;
659
- U(this, N, this.renderer.render);
659
+ U(this, V, this.renderer.render);
660
660
  const e = this;
661
- Re(this.renderer), this.renderer.render = function(s, n) {
661
+ Ge(this.renderer), this.renderer.render = function(s, n) {
662
662
  const r = e.renderer.getRenderTarget();
663
- (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((a, l) => a + l) / e._fpsBuffer.length), I && m(e, ee) % 200 === 0 && console.log("FPS", Math.round(m(e, W)), "Interval:", m(e, C)));
663
+ (r == null || "isXRRenderTarget" in r && r.isXRRenderTarget) && (t = 0, U(e, ee, m(e, ee) + 1), U(e, te, m(e, ye).getDelta()), U(e, me, m(e, me) + m(e, te)), e._fpsBuffer.shift(), e._fpsBuffer.push(1 / m(e, te)), U(e, W, e._fpsBuffer.reduce((a, l) => a + l) / e._fpsBuffer.length), R && m(e, ee) % 200 === 0 && console.log("FPS", Math.round(m(e, W)), "Interval:", m(e, C)));
664
664
  const i = t++;
665
- m(e, N).call(this, s, n), e.onAfterRender(s, n, i);
665
+ m(e, V).call(this, s, n), e.onAfterRender(s, n, i);
666
666
  };
667
667
  }
668
668
  disable() {
669
- m(this, N) && (console.debug("[gltf-progressive] Disabling LODsManager for renderer"), this.renderer.render = m(this, N), U(this, N, void 0));
669
+ m(this, V) && (console.debug("[gltf-progressive] Disabling LODsManager for renderer"), this.renderer.render = m(this, V), U(this, V, void 0));
670
670
  }
671
671
  update(t, e) {
672
672
  this.internalUpdate(t, e);
@@ -681,7 +681,7 @@ const P = class {
681
681
  (a.name === "EffectMaterial" || a.name === "CopyShader") && (i = !1);
682
682
  }
683
683
  if ((e.parent && e.parent.type === "CubeCamera" || s >= 1 && e.type === "OrthographicCamera") && (i = !1), i) {
684
- if (at || (this.updateInterval === "auto" ? m(this, W) < 40 && m(this, C) < 10 ? (U(this, C, m(this, C) + 1), I && 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), I && 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))
684
+ if (ct || (this.updateInterval === "auto" ? m(this, W) < 40 && m(this, C) < 10 ? (U(this, C, m(this, C) + 1), R && 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), R && 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))
685
685
  return;
686
686
  this.internalUpdate(t, e);
687
687
  }
@@ -696,7 +696,7 @@ const P = class {
696
696
  const r = this.targetTriangleDensity;
697
697
  for (const c of n) {
698
698
  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")) {
699
- I && (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)));
699
+ R && (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)));
700
700
  continue;
701
701
  }
702
702
  switch (c.material.type) {
@@ -708,9 +708,9 @@ const P = class {
708
708
  case "MeshDepthMaterial":
709
709
  continue;
710
710
  }
711
- if (I === "color" && c.material && !c.object.progressive_debug_color) {
711
+ if (R === "color" && c.material && !c.object.progressive_debug_color) {
712
712
  c.object.progressive_debug_color = !0;
713
- const p = Math.random() * 16777215, M = new Ke({ color: p });
713
+ const p = Math.random() * 16777215, M = new He({ color: p });
714
714
  c.object.material = M;
715
715
  }
716
716
  const g = c.object;
@@ -732,19 +732,19 @@ const P = class {
732
732
  var a, l;
733
733
  s.userData || (s.userData = {});
734
734
  let r = s[ve];
735
- if (r || (r = new lt(), s[ve] = r), r.frames++ < 2)
735
+ if (r || (r = new ut(), s[ve] = r), r.frames++ < 2)
736
736
  return;
737
737
  for (const u of Y)
738
738
  (a = u.onBeforeUpdateLOD) == null || a.call(u, this.renderer, t, e, s);
739
- this.calculateLodLevel(e, s, r, n, R), R.mesh_lod = Math.round(R.mesh_lod), R.texture_lod = Math.round(R.texture_lod), R.mesh_lod >= 0 && this.loadProgressiveMeshes(s, R.mesh_lod);
740
- let i = R.texture_lod;
739
+ this.calculateLodLevel(e, s, r, n, G), G.mesh_lod = Math.round(G.mesh_lod), G.texture_lod = Math.round(G.texture_lod), G.mesh_lod >= 0 && this.loadProgressiveMeshes(s, G.mesh_lod);
740
+ let i = G.texture_lod;
741
741
  if (s.material && i >= 0) {
742
742
  const u = s["DEBUG:LOD"];
743
743
  u != null && (i = u), this.loadProgressiveTextures(s.material, i);
744
744
  }
745
745
  for (const u of Y)
746
- (l = u.onAfterUpdatedLOD) == null || l.call(u, this.renderer, t, e, s, R);
747
- r.lastLodLevel_Mesh = R.mesh_lod, r.lastLodLevel_Texture = R.texture_lod;
746
+ (l = u.onAfterUpdatedLOD) == null || l.call(u, this.renderer, t, e, s, G);
747
+ r.lastLodLevel_Mesh = G.mesh_lod, r.lastLodLevel_Texture = G.texture_lod;
748
748
  }
749
749
  /** Load progressive textures for the given material
750
750
  * @param material the material to load the textures for
@@ -795,7 +795,7 @@ const P = class {
795
795
  return;
796
796
  }
797
797
  let a = 10 + 1, l = !1;
798
- if (I && e["DEBUG:LOD"] != null)
798
+ if (R && e["DEBUG:LOD"] != null)
799
799
  return e["DEBUG:LOD"];
800
800
  const u = _.getMeshLODInformation(e.geometry), c = u == null ? void 0 : u.lods, g = c && c.length > 0, p = _.getMaterialMinMaxLODsCount(e.material), M = (p == null ? void 0 : p.min_count) != 1 / 0 && p.min_count > 0 && p.max_count > 0;
801
801
  if (!g && !M) {
@@ -810,8 +810,8 @@ const P = class {
810
810
  if (!D.boundingBox)
811
811
  D.computeBoundingBox();
812
812
  else if (s.frames % 30 === 0) {
813
- const h = me(D), B = D.geometry;
814
- h && (D.geometry = h), D.computeBoundingBox(), D.geometry = B;
813
+ const h = ce(D), k = D.geometry;
814
+ h && (D.geometry = h), D.computeBoundingBox(), D.geometry = k;
815
815
  }
816
816
  x = D.boundingBox;
817
817
  }
@@ -832,18 +832,18 @@ const P = class {
832
832
  if (this._tempBox.applyMatrix4(this.projectionScreenMatrix), this.renderer.xr.enabled && D.fov > 70) {
833
833
  const f = this._tempBox.min, y = this._tempBox.max;
834
834
  let O = f.x, b = f.y, E = y.x, X = y.y;
835
- const ce = 2, Le = 1.5, ue = (f.x + y.x) * 0.5, fe = (f.y + y.y) * 0.5;
836
- O = (O - ue) * ce + ue, b = (b - fe) * ce + fe, E = (E - ue) * ce + ue, X = (X - fe) * ce + fe;
837
- const Ue = O < 0 && E > 0 ? 0 : Math.min(Math.abs(f.x), Math.abs(y.x)), ze = b < 0 && X > 0 ? 0 : Math.min(Math.abs(f.y), Math.abs(y.y)), xe = Math.max(Ue, ze);
835
+ const ue = 2, Le = 1.5, fe = (f.x + y.x) * 0.5, de = (f.y + y.y) * 0.5;
836
+ O = (O - fe) * ue + fe, b = (b - de) * ue + de, E = (E - fe) * ue + fe, X = (X - de) * ue + de;
837
+ const ze = O < 0 && E > 0 ? 0 : Math.min(Math.abs(f.x), Math.abs(y.x)), Ve = b < 0 && X > 0 ? 0 : Math.min(Math.abs(f.y), Math.abs(y.y)), xe = Math.max(ze, Ve);
838
838
  s.lastCentrality = (Le - xe) * (Le - xe) * (Le - xe);
839
839
  } else
840
840
  s.lastCentrality = 1;
841
841
  const h = this._tempBox.getSize(this._tempBoxSize);
842
842
  h.multiplyScalar(0.5), screen.availHeight > 0 && w > 0 && h.multiplyScalar(w / screen.availHeight), h.x *= D.aspect;
843
- const B = t.matrixWorldInverse, F = this._tempBox2;
844
- F.copy(x), F.applyMatrix4(e.matrixWorld), F.applyMatrix4(B);
845
- const k = F.getSize(this._tempBox2Size), S = Math.max(k.x, k.y);
846
- if (Math.max(h.x, h.y) != 0 && S != 0 && (h.z = k.z / Math.max(k.x, k.y) * Math.max(h.x, h.y)), s.lastScreenCoverage = Math.max(h.x, h.y, h.z), s.lastScreenspaceVolume.copy(h), s.lastScreenCoverage *= s.lastCentrality, I && P.debugDrawLine) {
843
+ const k = t.matrixWorldInverse, F = this._tempBox2;
844
+ F.copy(x), F.applyMatrix4(e.matrixWorld), F.applyMatrix4(k);
845
+ const I = F.getSize(this._tempBox2Size), S = Math.max(I.x, I.y);
846
+ if (Math.max(h.x, h.y) != 0 && S != 0 && (h.z = I.z / Math.max(I.x, I.y) * Math.max(h.x, h.y)), s.lastScreenCoverage = Math.max(h.x, h.y, h.z), s.lastScreenspaceVolume.copy(h), s.lastScreenCoverage *= s.lastCentrality, R && P.debugDrawLine) {
847
847
  const f = this.tempMatrix.copy(this.projectionScreenMatrix);
848
848
  f.invert();
849
849
  const y = P.corner0, O = P.corner1, b = P.corner2, E = P.corner3;
@@ -861,29 +861,29 @@ const P = class {
861
861
  }
862
862
  T < a && (a = T, l = !0);
863
863
  }
864
- if (l ? r.mesh_lod = a : r.mesh_lod = s.lastLodLevel_Mesh, I && r.mesh_lod != s.lastLodLevel_Mesh) {
864
+ if (l ? r.mesh_lod = a : r.mesh_lod = s.lastLodLevel_Mesh, R && r.mesh_lod != s.lastLodLevel_Mesh) {
865
865
  const h = c == null ? void 0 : c[r.mesh_lod];
866
866
  h && console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} → ${r.mesh_lod} (${h.density.toFixed(0)}) - ${e.name}`);
867
867
  }
868
868
  if (M) {
869
869
  const D = "saveData" in globalThis.navigator && globalThis.navigator.saveData === !0;
870
870
  if (s.lastLodLevel_Texture < 0) {
871
- if (r.texture_lod = p.max_count - 1, I) {
871
+ if (r.texture_lod = p.max_count - 1, R) {
872
872
  const h = p.lods[p.max_count - 1];
873
- I && console.log(`First Texture LOD ${r.texture_lod} (${h.max_height}px) - ${e.name}`);
873
+ R && console.log(`First Texture LOD ${r.texture_lod} (${h.max_height}px) - ${e.name}`);
874
874
  }
875
875
  } else {
876
876
  const h = s.lastScreenspaceVolume.x + s.lastScreenspaceVolume.y + s.lastScreenspaceVolume.z;
877
- let B = s.lastScreenCoverage * 4;
878
- (($ = this.context) == null ? void 0 : $.engine) === "model-viewer" && (B *= 1.5);
879
- const k = w / window.devicePixelRatio * B;
877
+ let k = s.lastScreenCoverage * 4;
878
+ (($ = this.context) == null ? void 0 : $.engine) === "model-viewer" && (k *= 1.5);
879
+ const I = w / window.devicePixelRatio * k;
880
880
  for (let S = p.lods.length - 1; S >= 0; S--) {
881
881
  let q = p.lods[S];
882
- if (!(D && q.max_height >= 2048) && !(rt() && q.max_height > 4096) && q.max_height > k) {
882
+ if (!(D && q.max_height >= 2048) && !(it() && q.max_height > 4096) && q.max_height > I) {
883
883
  if (r.texture_lod = S, r.texture_lod < s.lastLodLevel_Texture) {
884
884
  const T = q.max_height;
885
- I && console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${r.texture_lod} = ${T}px
886
- Screensize: ${k.toFixed(0)}px, Coverage: ${(100 * s.lastScreenCoverage).toFixed(2)}%, Volume ${h.toFixed(1)}
885
+ R && console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${r.texture_lod} = ${T}px
886
+ Screensize: ${I.toFixed(0)}px, Coverage: ${(100 * s.lastScreenCoverage).toFixed(2)}%, Volume ${h.toFixed(1)}
887
887
  ${e.name}`);
888
888
  }
889
889
  break;
@@ -894,55 +894,55 @@ ${e.name}`);
894
894
  r.texture_lod = 0;
895
895
  }
896
896
  };
897
- let G = P;
898
- 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.
897
+ let B = P;
898
+ C = new WeakMap(), V = new WeakMap(), ye = new WeakMap(), ee = new WeakMap(), te = new WeakMap(), me = 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.
899
899
  */
900
- 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());
901
- class lt {
900
+ d(B, "debugDrawLine"), d(B, "corner0", new N()), d(B, "corner1", new N()), d(B, "corner2", new N()), d(B, "corner3", new N()), d(B, "_tempPtInside", new N());
901
+ class ut {
902
902
  constructor() {
903
903
  d(this, "frames", 0);
904
904
  d(this, "lastLodLevel_Mesh", -1);
905
905
  d(this, "lastLodLevel_Texture", -1);
906
906
  d(this, "lastScreenCoverage", 0);
907
- d(this, "lastScreenspaceVolume", new z());
907
+ d(this, "lastScreenspaceVolume", new N());
908
908
  d(this, "lastCentrality", 0);
909
909
  }
910
910
  }
911
- const Ce = Symbol("NEEDLE_mesh_lod"), de = Symbol("NEEDLE_texture_lod");
911
+ const Be = Symbol("NEEDLE_mesh_lod"), he = Symbol("NEEDLE_texture_lod");
912
912
  let ne = null;
913
- function $e() {
914
- const o = ct();
913
+ function Ue() {
914
+ const o = ft();
915
915
  o && (o.mapURLs(function(t) {
916
- return Be(), t;
917
- }), Be(), ne == null || ne.disconnect(), ne = new MutationObserver((t) => {
916
+ return ke(), t;
917
+ }), ke(), ne == null || ne.disconnect(), ne = new MutationObserver((t) => {
918
918
  t.forEach((e) => {
919
919
  e.addedNodes.forEach((s) => {
920
- s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" && Fe(s);
920
+ s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" && Ne(s);
921
921
  });
922
922
  });
923
923
  }), ne.observe(document, { childList: !0, subtree: !0 }));
924
924
  }
925
- function ct() {
925
+ function ft() {
926
926
  if (typeof customElements > "u")
927
927
  return null;
928
928
  const o = customElements.get("model-viewer");
929
929
  return o || (customElements.whenDefined("model-viewer").then(() => {
930
- console.debug("[gltf-progressive] model-viewer defined"), $e();
930
+ console.debug("[gltf-progressive] model-viewer defined"), Ue();
931
931
  }), null);
932
932
  }
933
- function Be() {
933
+ function ke() {
934
934
  if (typeof document > "u")
935
935
  return;
936
936
  document.querySelectorAll("model-viewer").forEach((t) => {
937
- Fe(t);
937
+ Ne(t);
938
938
  });
939
939
  }
940
- const ke = /* @__PURE__ */ new WeakSet();
941
- let ut = 0;
942
- function Fe(o) {
943
- if (!o || ke.has(o))
940
+ const Ie = /* @__PURE__ */ new WeakSet();
941
+ let dt = 0;
942
+ function Ne(o) {
943
+ if (!o || Ie.has(o))
944
944
  return null;
945
- ke.add(o), console.debug("[gltf-progressive] found new model-viewer..." + ++ut + `
945
+ Ie.add(o), console.debug("[gltf-progressive] found new model-viewer..." + ++dt + `
946
946
  `, o.getAttribute("src"));
947
947
  let t = null, e = null, s = null;
948
948
  for (let n = o; n != null; n = Object.getPrototypeOf(n)) {
@@ -962,8 +962,8 @@ function Fe(o) {
962
962
  }
963
963
  };
964
964
  console.debug("[gltf-progressive] setup model-viewer");
965
- const r = G.get(t, { engine: "model-viewer" });
966
- return G.addPlugin(new ft()), r.enable(), r.addEventListener("changed", () => {
965
+ const r = B.get(t, { engine: "model-viewer" });
966
+ return B.addPlugin(new ht()), r.enable(), r.addEventListener("changed", () => {
967
967
  s == null || s.call(o);
968
968
  }), o.addEventListener("model-visibility", (i) => {
969
969
  i.detail.visible && (s == null || s.call(o));
@@ -975,7 +975,7 @@ function Fe(o) {
975
975
  }
976
976
  return null;
977
977
  }
978
- class ft {
978
+ class ht {
979
979
  constructor() {
980
980
  d(this, "_didWarnAboutMissingUrl", !1);
981
981
  }
@@ -995,16 +995,16 @@ class ft {
995
995
  return t.element;
996
996
  }
997
997
  tryParseTextureLOD(t, e) {
998
- if (e[de] == !0)
998
+ if (e[he] == !0)
999
999
  return;
1000
- e[de] = !0;
1000
+ e[he] = !0;
1001
1001
  const s = this.tryGetCurrentGLTF(t), n = this.tryGetCurrentModelViewer(t), r = this.getUrl(n);
1002
1002
  if (r && s && e.material) {
1003
1003
  let i = function(l) {
1004
1004
  var c, g, p;
1005
- if (l[de] == !0)
1005
+ if (l[he] == !0)
1006
1006
  return;
1007
- l[de] = !0, l.userData && (l.userData.LOD = -1);
1007
+ l[he] = !0, l.userData && (l.userData.LOD = -1);
1008
1008
  const u = Object.keys(l);
1009
1009
  for (let M = 0; M < u.length; M++) {
1010
1010
  const w = u[M], x = l[w];
@@ -1017,8 +1017,8 @@ class ft {
1017
1017
  console.warn("Texture data not found for texture index " + $);
1018
1018
  continue;
1019
1019
  }
1020
- if ((p = D == null ? void 0 : D.extensions) != null && p[V]) {
1021
- const h = D.extensions[V];
1020
+ if ((p = D == null ? void 0 : D.extensions) != null && p[z]) {
1021
+ const h = D.extensions[z];
1022
1022
  h && r && _.registerTexture(r, x, h.lods.length, $, h);
1023
1023
  }
1024
1024
  }
@@ -1034,41 +1034,55 @@ class ft {
1034
1034
  }
1035
1035
  tryParseMeshLOD(t, e) {
1036
1036
  var i, a;
1037
- if (e[Ce] == !0)
1037
+ if (e[Be] == !0)
1038
1038
  return;
1039
- e[Ce] = !0;
1039
+ e[Be] = !0;
1040
1040
  const s = this.tryGetCurrentModelViewer(t), n = this.getUrl(s);
1041
1041
  if (!n)
1042
1042
  return;
1043
- const r = (a = (i = e.userData) == null ? void 0 : i.gltfExtensions) == null ? void 0 : a[V];
1043
+ const r = (a = (i = e.userData) == null ? void 0 : i.gltfExtensions) == null ? void 0 : a[z];
1044
1044
  if (r && n) {
1045
1045
  const l = e.uuid;
1046
1046
  _.registerMesh(n, l, e, 0, r.lods.length, r);
1047
1047
  }
1048
1048
  }
1049
1049
  }
1050
- function Dt(o, t, e, s) {
1051
- Re(t), Ge(e), et(e, {
1050
+ function gt(o, t, e, s) {
1051
+ Ge(t), $e(e), Fe(e, {
1052
1052
  progressive: !0,
1053
1053
  ...s == null ? void 0 : s.hints
1054
1054
  }), e.register((r) => new _(r, o));
1055
- const n = G.get(t);
1055
+ const n = B.get(t);
1056
1056
  return (s == null ? void 0 : s.enableLODsManager) !== !1 && n.enable(), n;
1057
1057
  }
1058
- $e();
1058
+ Ue();
1059
+ const Oe = {
1060
+ gltfProgressive: {
1061
+ useNeedleProgressive: gt,
1062
+ LODsManager: B,
1063
+ configureLoader: Fe,
1064
+ getRaycastMesh: ce,
1065
+ useRaycastMeshes: ot
1066
+ }
1067
+ };
1068
+ if (!globalThis.Needle)
1069
+ globalThis.Needle = Oe;
1070
+ else
1071
+ for (const o in Oe)
1072
+ globalThis.Needle[o] = Oe[o];
1059
1073
  export {
1060
- V as EXTENSION_NAME,
1061
- G as LODsManager,
1074
+ z as EXTENSION_NAME,
1075
+ B as LODsManager,
1062
1076
  _ as NEEDLE_progressive,
1063
- Ie as VERSION,
1064
- Ge as addDracoAndKTX2Loaders,
1065
- et as configureLoader,
1066
- Re as createLoaders,
1067
- me as getRaycastMesh,
1068
- $e as patchModelViewer,
1069
- it as registerRaycastMesh,
1070
- Lt as setDracoDecoderLocation,
1071
- xt as setKTX2TranscoderLocation,
1072
- Dt as useNeedleProgressive,
1073
- Mt as useRaycastMeshes
1077
+ Re as VERSION,
1078
+ $e as addDracoAndKTX2Loaders,
1079
+ Fe as configureLoader,
1080
+ Ge as createLoaders,
1081
+ ce as getRaycastMesh,
1082
+ Ue as patchModelViewer,
1083
+ nt as registerRaycastMesh,
1084
+ Dt as setDracoDecoderLocation,
1085
+ wt as setKTX2TranscoderLocation,
1086
+ gt as useNeedleProgressive,
1087
+ ot as useRaycastMeshes
1074
1088
  };
@@ -1,8 +1,8 @@
1
- var $e=Object.defineProperty,Ne=(t,e,r)=>e in t?$e(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,c=(t,e,r)=>(Ne(t,typeof e!="symbol"?e+"":e,r),r),Se=(t,e,r)=>{if(!e.has(t))throw TypeError("Cannot "+r)},y=(t,e,r)=>(Se(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,o)=>(Se(t,e,"write to private field"),o?o.call(t,r):e.set(t,r),r);import{BufferGeometry as le,Mesh as q,Material as Fe,Texture as Z,TextureLoader as Ue,Matrix4 as Te,Clock as ze,MeshStandardMaterial as Ve,Sphere as qe,Box3 as Ee,Vector3 as W}from"three";import{GLTFLoader as me}from"three/examples/jsm/loaders/GLTFLoader.js";import{MeshoptDecoder as Xe}from"three/examples/jsm/libs/meshopt_decoder.module.js";import{DRACOLoader as He}from"three/examples/jsm/loaders/DRACOLoader.js";import{KTX2Loader as Ke}from"three/examples/jsm/loaders/KTX2Loader.js";const pe="";globalThis.GLTF_PROGRESSIVE_VERSION=pe,console.debug(`[gltf-progressive] version ${pe}`);let H="https://www.gstatic.com/draco/versioned/decoders/1.5.7/",ee="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";const Ye=H,Je=ee;fetch(H+"draco_decoder.js",{method:"head"}).catch(t=>{H===Ye&&(H="./include/draco/"),ee===Je&&(ee="./include/ktx2/")});function Qe(t){H=t}function Ze(t){ee=t}let K,ue,Y;function ve(t){return K||(K=new He,K.setDecoderPath(H),K.setDecoderConfig({type:"js"})),Y||(Y=new Ke,Y.setTranscoderPath(ee)),ue||(ue=Xe),t?Y.detectSupport(t):t!==null&&console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"),{dracoLoader:K,ktx2Loader:Y,meshoptDecoder:ue}}function ye(t){t.dracoLoader||t.setDRACOLoader(K),t.ktx2Loader||t.setKTX2Loader(Y),t.meshoptDecoder||t.setMeshoptDecoder(ue)}const xe=new WeakMap;function Ae(t,e){let r=xe.get(t);r?r=Object.assign(r,e):r=e,xe.set(t,r)}const Be=me.prototype.load;function et(...t){const e=xe.get(this);let r=t[0];const o=new URL(r,window.location.href);if(o.hostname.endsWith("needle.tools")){const s=e?.progressive!==void 0?e.progressive:!0,n=e!=null&&e.usecase?e.usecase:"default";s?this.requestHeader.Accept=`*/*;progressive=allowed;usecase=${n}`:this.requestHeader.Accept=`*/*;usecase=${n}`,r=o.toString()}return t[0]=r,Be?.call(this,...t)}me.prototype.load=et,te("debugprogressive");function te(t){if(typeof window>"u")return!1;const e=new URL(window.location.href).searchParams.get(t);return e==null||e==="0"||e==="false"?!1:e===""?!0:e}function tt(t,e){if(e===void 0||e.startsWith("./")||e.startsWith("http")||t===void 0)return e;const r=t.lastIndexOf("/");if(r>=0){const o=t.substring(0,r+1);for(;o.endsWith("/")&&e.startsWith("/");)e=e.substring(1);return o+e}return e}let ce;function rt(){return ce!==void 0||(ce=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),te("debugprogressive")&&console.log("[glTF Progressive]: isMobileDevice",ce)),ce}const Le=Symbol("needle:raycast-mesh");function re(t){return t?.[Le]instanceof le?t[Le]:null}function Ie(t,e){if((t.type==="Mesh"||t.type==="SkinnedMesh")&&!re(t)){const r=nt(e);r.userData={isRaycastMesh:!0},t[Le]=r}}function st(t=!0){if(t){if(se)return;const e=se=q.prototype.raycast;q.prototype.raycast=function(r,o){const s=this,n=re(s);let i;n&&s.isMesh&&(i=s.geometry,s.geometry=n),e.call(this,r,o),i&&(s.geometry=i)}}else{if(!se)return;q.prototype.raycast=se,se=null}}let se=null;function nt(t){const e=new le;for(const r in t.attributes)e.setAttribute(r,t.getAttribute(r));return e.setIndex(t.getIndex()),e}const N=new Array,R="NEEDLE_progressive",x=te("debugprogressive"),Me=Symbol("needle-progressive-texture"),ne=new Map,De=new Set;if(x){let t=function(){e+=1,console.log("Toggle LOD level",e,ne),ne.forEach((s,n)=>{for(const i of s.keys){const l=n[i];if(l!=null){if(l.isBufferGeometry===!0){const u=S.getMeshLODInformation(l),a=u?Math.min(e,u.lods.length):0;n["DEBUG:LOD"]=e,S.assignMeshLOD(n,a),u&&(r=Math.max(r,u.lods.length-1))}else if(n.isMaterial===!0){n["DEBUG:LOD"]=e,S.assignTextureLOD(n,e);break}}}}),e>=r&&(e=-1)},e=-1,r=2,o=!1;window.addEventListener("keyup",s=>{s.key==="p"&&t(),s.key==="w"&&(o=!o,De&&De.forEach(n=>{n.name!="BackgroundCubeMaterial"&&n.glyphMap==null&&"wireframe"in n&&(n.wireframe=o)}))})}function Pe(t,e,r){var o;if(!x)return;ne.has(t)||ne.set(t,{keys:[],sourceId:r});const s=ne.get(t);((o=s?.keys)==null?void 0:o.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 o,s;if(this._isLoadingMesh)return null;const n=(s=(o=this.parser.json.meshes[r])==null?void 0:o.extensions)==null?void 0:s[R];return n?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",r).then(i=>{var l;return this._isLoadingMesh=!1,i&&w.registerMesh(this.url,n.guid,i,(l=n.lods)==null?void 0:l.length,void 0,n),i})):null}),x&&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,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 i of t)this.getMaterialMinMaxLODsCount(i,e);return t[o]=e,e}if(x==="verbose"&&console.log("getMaterialMinMaxLODsCount",t),t.type==="ShaderMaterial"||t.type==="RawShaderMaterial"){const i=t;for(const l of Object.keys(i.uniforms)){const u=i.uniforms[l].value;u?.isTexture===!0&&n(u,e)}}else if(t.isMaterial)for(const i of Object.keys(t)){const l=t[i];l?.isTexture===!0&&n(l,e)}return t[o]=e,e;function n(i,l){const u=r.getAssignedLODInformation(i);if(u){const a=r.lodInfos.get(u.key);if(a&&a.lods){l.min_count=Math.min(l.min_count,a.lods.length),l.max_count=Math.max(l.max_count,a.lods.length);for(let f=0;f<a.lods.length;f++){const g=a.lods[f];g.width&&(l.lods[f]=l.lods[f]||{min_height:1/0,max_height:0},l.lods[f].min_height=Math.min(l.lods[f].min_height,g.height),l.lods[f].max_height=Math.max(l.lods[f].max_height,g.height))}}}}}static hasLODLevelAvailable(t,e){var r;if(Array.isArray(t)){for(const n of t)if(this.hasLODLevelAvailable(n,e))return!0;return!1}if(t.isMaterial===!0){for(const n of Object.keys(t)){const i=t[n];if(i&&i.isTexture&&this.hasLODLevelAvailable(i,e))return!0}return!1}else if(t.isGroup===!0){for(const n of t.children)if(n.isMesh===!0&&this.hasLODLevelAvailable(n,e))return!0}let o,s;if(t.isMesh?o=t.geometry:(t.isBufferGeometry||t.isTexture)&&(o=t),o&&(r=o?.userData)!=null&&r.LODS){const n=o.userData.LODS;if(s=this.lodInfos.get(n.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 o=t.geometry,s=this.getAssignedLODInformation(o);if(!s)return Promise.resolve(null);for(const n of N)(r=n.onBeforeGetLODMesh)==null||r.call(n,t,e);return t["LOD:requested level"]=e,w.getOrLoadLOD(o,e).then(n=>{if(Array.isArray(n)){const i=s.index||0;n=n[i]}return t["LOD:requested level"]===e&&(delete t["LOD:requested level"],n&&o!=n&&(n?.isBufferGeometry?(t.geometry=n,x&&Pe(t,"geometry",s.url)):x&&console.error("Invalid LOD geometry",n))),n}).catch(n=>(console.error("Error loading mesh LOD",t,n),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.isMesh===!0){const r=t;if(Array.isArray(r.material)){const o=new Array;for(const s of r.material){const n=this.assignTextureLOD(s,e);o.push(n)}return Promise.all(o).then(s=>{const n=new Array;for(const i of s)Array.isArray(i)&&n.push(...i);return n})}else return this.assignTextureLOD(r.material,e)}if(t instanceof Fe||t.isMaterial===!0){const r=t,o=[],s=new Array;if(x&&De.add(r),r.uniforms&&(r.isRawShaderMaterial||r.isShaderMaterial===!0)){const n=r;for(const i of Object.keys(n.uniforms)){const l=n.uniforms[i].value;if(l?.isTexture===!0){const u=this.assignTextureLODForSlot(l,e,r,i).then(a=>(a&&n.uniforms[i].value!=a&&(n.uniforms[i].value=a,n.uniformsNeedUpdate=!0),a));o.push(u),s.push(i)}}}else for(const n of Object.keys(r)){const i=r[n];if(i?.isTexture===!0){const l=this.assignTextureLODForSlot(i,e,r,n);o.push(l),s.push(n)}}return Promise.all(o).then(n=>{const i=new Array;for(let l=0;l<n.length;l++){const u=n[l],a=s[l];u&&u.isTexture===!0?i.push({material:r,slot:a,texture:u,level:e}):i.push({material:r,slot:a,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,o){return t?.isTexture!==!0?Promise.resolve(null):o==="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&&o){const n=r[o];if(n){const i=this.getAssignedLODInformation(n);if(i&&i?.level<e)return x==="verbose"&&console.warn("Assigned texture level is already higher: ",i.level,e,r,n,s),null}r[o]=s}if(x&&o&&r){const n=this.getAssignedLODInformation(t);n&&Pe(r,o,n.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 n;if(o!=null&&o.extensions){const i=o?.extensions[R];if(i){if(!i.lods){x&&console.warn("Texture has no LODs",i);return}let l=!1;for(const u of this.parser.associations.keys())if(u.isTexture===!0){const a=this.parser.associations.get(u);a?.textures===s&&(l=!0,w.registerTexture(this.url,u,(n=i.lods)==null?void 0:n.length,s,i))}l||this.parser.getDependency("texture",s).then(u=>{var a;u&&w.registerTexture(this.url,u,(a=i.lods)==null?void 0:a.length,s,i)})}}}),(r=this.parser.json.meshes)==null||r.forEach((o,s)=>{if(o!=null&&o.extensions){const n=o?.extensions[R];if(n&&n.lods){for(const i of this.parser.associations.keys())if(i.isMesh){const l=this.parser.associations.get(i);l?.meshes===s&&w.registerMesh(this.url,n.guid,i,n.lods.length,l.primitives,n)}}}}),null}static async getOrLoadLOD(t,e){var r,o,s,n;const i=x=="verbose",l=t.userData.LODS;if(!l)return null;const u=l?.key;let a;if(t.isTexture===!0){const f=t;f.source&&f.source[Me]&&(a=f.source[Me])}if(a||(a=w.lodInfos.get(u)),a){if(e>0){let p=!1;const A=Array.isArray(a.lods);if(A&&e>=a.lods.length?p=!0:A||(p=!0),p)return this.lowresCache.get(u)}const f=Array.isArray(a.lods)?(r=a.lods[e])==null?void 0:r.path:a.lods;if(!f)return x&&!a["missing:uri"]&&(a["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+e,a)),null;const g=tt(l.url,f);if(g.endsWith(".glb")||g.endsWith(".gltf")){if(!a.guid)return console.warn("missing pointer for glb/gltf texture",a),null;const p=g+"_"+a.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(_=>(console.error(`Error loading LOD ${e} from ${g}
2
- `,_),null)),O=!1;if(d==null||(d instanceof Z&&t instanceof Z?(o=d.image)!=null&&o.data||(s=d.source)!=null&&s.data?d=this.copySettings(t,d):(O=!0,this.previouslyLoaded.delete(p)):d instanceof le&&t instanceof le&&((n=d.attributes.position)!=null&&n.array||(O=!0,this.previouslyLoaded.delete(p)))),!O)return d}const D=a,L=new Promise(async(d,O)=>{const _=new me;ye(_),x&&(await new Promise(m=>setTimeout(m,1e3)),i&&console.warn("Start loading (delayed) "+g,D.guid));let B=g;if(D&&Array.isArray(D.lods)){const m=D.lods[e];m.hash&&(B+="?v="+m.hash)}const T=await _.loadAsync(B).catch(m=>(console.error(`Error loading LOD ${e} from ${g}
3
- `,m),null));if(!T)return null;const $=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 $.getDependency("texture",v);return h&&w.assignLODInformation(l.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 x&&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 $.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(l.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(l.url,X,u,e,C,M.density),b.push(X)}}return d(b)}}else x&&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 Ue().loadAsync(g);return p?(p.guid=a.guid,p.flipY=!1,p.needsUpdate=!0,p.colorSpace=t.colorSpace,i&&console.log(a,p)):x&&console.warn("failed loading",g),p}}else x&&console.warn(`Can not load LOD ${e}: no LOD info found for "${u}" ${t.name}`,t.type);return null}static assignLODInformation(t,e,r,o,s,n){if(!e)return;e.userData||(e.userData={});const i=new ot(t,r,o,s,n);e.userData.LODS=i}static getAssignedLODInformation(t){var e;return((e=t?.userData)==null?void 0:e.LODS)||null}static copySettings(t,e){return e=e.clone(),x&&console.warn(`Copying texture settings
1
+ var Ue=Object.defineProperty,ze=(t,e,s)=>e in t?Ue(t,e,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[e]=s,c=(t,e,s)=>(ze(t,typeof e!="symbol"?e+"":e,s),s),Ee=(t,e,s)=>{if(!e.has(t))throw TypeError("Cannot "+s)},y=(t,e,s)=>(Ee(t,e,"read from private field"),s?s.call(t):e.get(t)),V=(t,e,s)=>{if(e.has(t))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(t):e.set(t,s)},N=(t,e,s,o)=>(Ee(t,e,"write to private field"),o?o.call(t,s):e.set(t,s),s);import{BufferGeometry as le,Mesh as q,Material as Ve,Texture as ee,TextureLoader as qe,Matrix4 as Ae,Clock as Xe,MeshStandardMaterial as He,Sphere as Ke,Box3 as Ie,Vector3 as G}from"three";import{GLTFLoader as me}from"three/examples/jsm/loaders/GLTFLoader.js";import{MeshoptDecoder as Ye}from"three/examples/jsm/libs/meshopt_decoder.module.js";import{DRACOLoader as Je}from"three/examples/jsm/loaders/DRACOLoader.js";import{KTX2Loader as Qe}from"three/examples/jsm/loaders/KTX2Loader.js";const pe="";globalThis.GLTF_PROGRESSIVE_VERSION=pe,console.debug(`[gltf-progressive] version ${pe}`);let H="https://www.gstatic.com/draco/versioned/decoders/1.5.7/",te="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";const Ze=H,et=te;fetch(H+"draco_decoder.js",{method:"head"}).catch(t=>{H===Ze&&(H="./include/draco/"),te===et&&(te="./include/ktx2/")});function tt(t){H=t}function st(t){te=t}let K,ue,Y;function ve(t){return K||(K=new Je,K.setDecoderPath(H),K.setDecoderConfig({type:"js"})),Y||(Y=new Qe,Y.setTranscoderPath(te)),ue||(ue=Ye),t?Y.detectSupport(t):t!==null&&console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"),{dracoLoader:K,ktx2Loader:Y,meshoptDecoder:ue}}function ye(t){t.dracoLoader||t.setDRACOLoader(K),t.ktx2Loader||t.setKTX2Loader(Y),t.meshoptDecoder||t.setMeshoptDecoder(ue)}const xe=new WeakMap;function Le(t,e){let s=xe.get(t);s?s=Object.assign(s,e):s=e,xe.set(t,s)}const Pe=me.prototype.load;function rt(...t){const e=xe.get(this);let s=t[0];const o=new URL(s,window.location.href);if(o.hostname.endsWith("needle.tools")){const r=e?.progressive!==void 0?e.progressive:!0,n=e!=null&&e.usecase?e.usecase:"default";r?this.requestHeader.Accept=`*/*;progressive=allowed;usecase=${n}`:this.requestHeader.Accept=`*/*;usecase=${n}`,s=o.toString()}return t[0]=s,Pe?.call(this,...t)}me.prototype.load=rt,se("debugprogressive");function se(t){if(typeof window>"u")return!1;const e=new URL(window.location.href).searchParams.get(t);return e==null||e==="0"||e==="false"?!1:e===""?!0:e}function nt(t,e){if(e===void 0||e.startsWith("./")||e.startsWith("http")||t===void 0)return e;const s=t.lastIndexOf("/");if(s>=0){const o=t.substring(0,s+1);for(;o.endsWith("/")&&e.startsWith("/");)e=e.substring(1);return o+e}return e}let ce;function ot(){return ce!==void 0||(ce=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),se("debugprogressive")&&console.log("[glTF Progressive]: isMobileDevice",ce)),ce}const Me=Symbol("needle:raycast-mesh");function J(t){return t?.[Me]instanceof le?t[Me]:null}function ke(t,e){if((t.type==="Mesh"||t.type==="SkinnedMesh")&&!J(t)){const s=it(e);s.userData={isRaycastMesh:!0},t[Me]=s}}function Be(t=!0){if(t){if(re)return;const e=re=q.prototype.raycast;q.prototype.raycast=function(s,o){const r=this,n=J(r);let i;n&&r.isMesh&&(i=r.geometry,r.geometry=n),e.call(this,s,o),i&&(r.geometry=i)}}else{if(!re)return;q.prototype.raycast=re,re=null}}let re=null;function it(t){const e=new le;for(const s in t.attributes)e.setAttribute(s,t.getAttribute(s));return e.setIndex(t.getIndex()),e}const $=new Array,j="NEEDLE_progressive",x=se("debugprogressive"),De=Symbol("needle-progressive-texture"),ne=new Map,we=new Set;if(x){let t=function(){e+=1,console.log("Toggle LOD level",e,ne),ne.forEach((r,n)=>{for(const i of r.keys){const l=n[i];if(l!=null){if(l.isBufferGeometry===!0){const u=S.getMeshLODInformation(l),a=u?Math.min(e,u.lods.length):0;n["DEBUG:LOD"]=e,S.assignMeshLOD(n,a),u&&(s=Math.max(s,u.lods.length-1))}else if(n.isMaterial===!0){n["DEBUG:LOD"]=e,S.assignTextureLOD(n,e);break}}}}),e>=s&&(e=-1)},e=-1,s=2,o=!1;window.addEventListener("keyup",r=>{r.key==="p"&&t(),r.key==="w"&&(o=!o,we&&we.forEach(n=>{n.name!="BackgroundCubeMaterial"&&n.glyphMap==null&&"wireframe"in n&&(n.wireframe=o)}))})}function Ce(t,e,s){var o;if(!x)return;ne.has(t)||ne.set(t,{keys:[],sourceId:s});const r=ne.get(t);((o=r?.keys)==null?void 0:o.includes(e))==!1&&r.keys.push(e)}const w=class{constructor(t,e){c(this,"parser"),c(this,"url"),c(this,"_isLoadingMesh"),c(this,"loadMesh",s=>{var o,r;if(this._isLoadingMesh)return null;const n=(r=(o=this.parser.json.meshes[s])==null?void 0:o.extensions)==null?void 0:r[j];return n?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",s).then(i=>{var l;return this._isLoadingMesh=!1,i&&w.registerMesh(this.url,n.guid,i,(l=n.lods)==null?void 0:l.length,void 0,n),i})):null}),x&&console.log("Progressive extension registered for",e),this.parser=t,this.url=e}get name(){return j}static getMeshLODInformation(t){const e=this.getAssignedLODInformation(t);return e!=null&&e.key?this.lodInfos.get(e.key):null}static getMaterialMinMaxLODsCount(t,e){const s=this,o="LODS:minmax",r=t[o];if(r!=null)return r;if(e||(e={min_count:1/0,max_count:0,lods:[]}),Array.isArray(t)){for(const i of t)this.getMaterialMinMaxLODsCount(i,e);return t[o]=e,e}if(x==="verbose"&&console.log("getMaterialMinMaxLODsCount",t),t.type==="ShaderMaterial"||t.type==="RawShaderMaterial"){const i=t;for(const l of Object.keys(i.uniforms)){const u=i.uniforms[l].value;u?.isTexture===!0&&n(u,e)}}else if(t.isMaterial)for(const i of Object.keys(t)){const l=t[i];l?.isTexture===!0&&n(l,e)}return t[o]=e,e;function n(i,l){const u=s.getAssignedLODInformation(i);if(u){const a=s.lodInfos.get(u.key);if(a&&a.lods){l.min_count=Math.min(l.min_count,a.lods.length),l.max_count=Math.max(l.max_count,a.lods.length);for(let g=0;g<a.lods.length;g++){const f=a.lods[g];f.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,f.height),l.lods[g].max_height=Math.max(l.lods[g].max_height,f.height))}}}}}static hasLODLevelAvailable(t,e){var s;if(Array.isArray(t)){for(const n of t)if(this.hasLODLevelAvailable(n,e))return!0;return!1}if(t.isMaterial===!0){for(const n of Object.keys(t)){const i=t[n];if(i&&i.isTexture&&this.hasLODLevelAvailable(i,e))return!0}return!1}else if(t.isGroup===!0){for(const n of t.children)if(n.isMesh===!0&&this.hasLODLevelAvailable(n,e))return!0}let o,r;if(t.isMesh?o=t.geometry:(t.isBufferGeometry||t.isTexture)&&(o=t),o&&(s=o?.userData)!=null&&s.LODS){const n=o.userData.LODS;if(r=this.lodInfos.get(n.key),e===void 0)return r!=null;if(r)return Array.isArray(r.lods)?e<r.lods.length:e===0}return!1}static assignMeshLOD(t,e){var s;if(!t)return Promise.resolve(null);if(t instanceof q||t.isMesh===!0){const o=t.geometry,r=this.getAssignedLODInformation(o);if(!r)return Promise.resolve(null);for(const n of $)(s=n.onBeforeGetLODMesh)==null||s.call(n,t,e);return t["LOD:requested level"]=e,w.getOrLoadLOD(o,e).then(n=>{if(Array.isArray(n)){const i=r.index||0;n=n[i]}return t["LOD:requested level"]===e&&(delete t["LOD:requested level"],n&&o!=n&&(n?.isBufferGeometry?(t.geometry=n,x&&Ce(t,"geometry",r.url)):x&&console.error("Invalid LOD geometry",n))),n}).catch(n=>(console.error("Error loading mesh LOD",t,n),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.isMesh===!0){const s=t;if(Array.isArray(s.material)){const o=new Array;for(const r of s.material){const n=this.assignTextureLOD(r,e);o.push(n)}return Promise.all(o).then(r=>{const n=new Array;for(const i of r)Array.isArray(i)&&n.push(...i);return n})}else return this.assignTextureLOD(s.material,e)}if(t instanceof Ve||t.isMaterial===!0){const s=t,o=[],r=new Array;if(x&&we.add(s),s.uniforms&&(s.isRawShaderMaterial||s.isShaderMaterial===!0)){const n=s;for(const i of Object.keys(n.uniforms)){const l=n.uniforms[i].value;if(l?.isTexture===!0){const u=this.assignTextureLODForSlot(l,e,s,i).then(a=>(a&&n.uniforms[i].value!=a&&(n.uniforms[i].value=a,n.uniformsNeedUpdate=!0),a));o.push(u),r.push(i)}}}else for(const n of Object.keys(s)){const i=s[n];if(i?.isTexture===!0){const l=this.assignTextureLODForSlot(i,e,s,n);o.push(l),r.push(n)}}return Promise.all(o).then(n=>{const i=new Array;for(let l=0;l<n.length;l++){const u=n[l],a=r[l];u&&u.isTexture===!0?i.push({material:s,slot:a,texture:u,level:e}):i.push({material:s,slot:a,texture:null,level:e})}return i})}if(t instanceof ee||t.isTexture===!0){const s=t;return this.assignTextureLODForSlot(s,e,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(t,e,s,o){return t?.isTexture!==!0?Promise.resolve(null):o==="glyphMap"?Promise.resolve(t):w.getOrLoadLOD(t,e).then(r=>{if(Array.isArray(r))return null;if(r?.isTexture===!0){if(r!=t){if(s&&o){const n=s[o];if(n){const i=this.getAssignedLODInformation(n);if(i&&i?.level<e)return x==="verbose"&&console.warn("Assigned texture level is already higher: ",i.level,e,s,n,r),null}s[o]=r}if(x&&o&&s){const n=this.getAssignedLODInformation(t);n&&Ce(s,o,n.url)}}return r}else x=="verbose"&&console.warn("No LOD found for",t,e);return null}).catch(r=>(console.error("Error loading LOD",t,r),null))}afterRoot(t){var e,s;return x&&console.log("AFTER",this.url,t),(e=this.parser.json.textures)==null||e.forEach((o,r)=>{var n;if(o!=null&&o.extensions){const i=o?.extensions[j];if(i){if(!i.lods){x&&console.warn("Texture has no LODs",i);return}let l=!1;for(const u of this.parser.associations.keys())if(u.isTexture===!0){const a=this.parser.associations.get(u);a?.textures===r&&(l=!0,w.registerTexture(this.url,u,(n=i.lods)==null?void 0:n.length,r,i))}l||this.parser.getDependency("texture",r).then(u=>{var a;u&&w.registerTexture(this.url,u,(a=i.lods)==null?void 0:a.length,r,i)})}}}),(s=this.parser.json.meshes)==null||s.forEach((o,r)=>{if(o!=null&&o.extensions){const n=o?.extensions[j];if(n&&n.lods){for(const i of this.parser.associations.keys())if(i.isMesh){const l=this.parser.associations.get(i);l?.meshes===r&&w.registerMesh(this.url,n.guid,i,n.lods.length,l.primitives,n)}}}}),null}static async getOrLoadLOD(t,e){var s,o,r,n;const i=x=="verbose",l=t.userData.LODS;if(!l)return null;const u=l?.key;let a;if(t.isTexture===!0){const g=t;g.source&&g.source[De]&&(a=g.source[De])}if(a||(a=w.lodInfos.get(u)),a){if(e>0){let p=!1;const A=Array.isArray(a.lods);if(A&&e>=a.lods.length?p=!0:A||(p=!0),p)return this.lowresCache.get(u)}const g=Array.isArray(a.lods)?(s=a.lods[e])==null?void 0:s.path:a.lods;if(!g)return x&&!a["missing:uri"]&&(a["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+e,a)),null;const f=nt(l.url,g);if(f.endsWith(".glb")||f.endsWith(".gltf")){if(!a.guid)return console.warn("missing pointer for glb/gltf texture",a),null;const p=f+"_"+a.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(b=>(console.error(`Error loading LOD ${e} from ${f}
2
+ `,b),null)),O=!1;if(d==null||(d instanceof ee&&t instanceof ee?(o=d.image)!=null&&o.data||(r=d.source)!=null&&r.data?d=this.copySettings(t,d):(O=!0,this.previouslyLoaded.delete(p)):d instanceof le&&t instanceof le&&((n=d.attributes.position)!=null&&n.array||(O=!0,this.previouslyLoaded.delete(p)))),!O)return d}const D=a,L=new Promise(async(d,O)=>{const b=new me;ye(b),x&&(await new Promise(m=>setTimeout(m,1e3)),i&&console.warn("Start loading (delayed) "+f,D.guid));let I=f;if(D&&Array.isArray(D.lods)){const m=D.lods[e];m.hash&&(I+="?v="+m.hash)}const T=await b.loadAsync(I).catch(m=>(console.error(`Error loading LOD ${e} from ${f}
3
+ `,m),null));if(!T)return null;const W=T.parser;i&&console.log("Loading finished "+f,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[j];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(l.url,h,u,e,void 0,void 0),i&&console.log('change "'+t.name+'" \u2192 "'+h.name+'"',f,v,h,p),t instanceof ee&&(h=this.copySettings(t,h)),h&&(h.guid=D.guid),d(h)}else x&&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[j];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}"`,f,v,h,p),h.isMesh===!0){const _=h.geometry;return w.assignLODInformation(l.url,_,u,e,void 0,M.density),d(_)}else{const _=new Array;for(let R=0;R<h.children.length;R++){const z=h.children[R];if(z.isMesh===!0){const X=z.geometry;w.assignLODInformation(l.url,X,u,e,R,M.density),_.push(X)}}return d(_)}}else x&&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 ee){i&&console.log("Load texture from uri: "+f);const p=await new qe().loadAsync(f);return p?(p.guid=a.guid,p.flipY=!1,p.needsUpdate=!0,p.colorSpace=t.colorSpace,i&&console.log(a,p)):x&&console.warn("failed loading",f),p}}else x&&console.warn(`Can not load LOD ${e}: no LOD info found for "${u}" ${t.name}`,t.type);return null}static assignLODInformation(t,e,s,o,r,n){if(!e)return;e.userData||(e.userData={});const i=new at(t,s,o,r,n);e.userData.LODS=i}static getAssignedLODInformation(t){var e;return((e=t?.userData)==null?void 0:e.LODS)||null}static copySettings(t,e){return e=e.clone(),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 S=w;c(S,"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 n=s.guid;w.assignLODInformation(t,e,n,r,o,void 0),w.lodInfos.set(n,s),w.lowresCache.set(n,e)}),c(S,"registerMesh",(t,e,r,o,s,n)=>{var i;x&&console.log("> Progressive: register mesh",s,r.name,n,r.uuid,r);const l=r.geometry;if(!l){x&&console.warn("gltf-progressive: Register mesh without geometry");return}l.userData||(l.userData={}),w.assignLODInformation(t,l,e,o,s,n.density),w.lodInfos.set(e,n);let u=w.lowresCache.get(e);u?u.push(r.geometry):u=[r.geometry],w.lowresCache.set(e,u),o>0&&!re(r)&&Ie(r,l);for(const a of N)(i=a.onRegisteredNewMesh)==null||i.call(a,r,n)}),c(S,"lodInfos",new Map),c(S,"previouslyLoaded",new Map),c(S,"lowresCache",new Map);class ot{constructor(e,r,o,s,n){c(this,"url"),c(this,"key"),c(this,"level"),c(this,"index"),c(this,"density"),this.url=e,this.key=r,this.level=o,s!=null&&(this.index=s),n!=null&&(this.density=n)}}const P=te("debugprogressive"),it=te("noprogressive"),we=Symbol("Needle:LODSManager"),Oe=Symbol("Needle:LODState"),J=Symbol("Needle:CurrentLOD"),k={mesh_lod:-1,texture_lod:-1};var E,F,_e,Q,oe,de,U;const I=class{constructor(t,e){c(this,"context"),c(this,"renderer"),c(this,"projectionScreenMatrix",new Te),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,F,void 0),V(this,_e,new ze),V(this,Q,0),V(this,oe,0),V(this,de,0),V(this,U,0),c(this,"_fpsBuffer",[60,60,60,60,60]),c(this,"_sphere",new qe),c(this,"_tempBox",new Ee),c(this,"_tempBox2",new Ee),c(this,"tempMatrix",new Te),c(this,"_tempWorldPosition",new W),c(this,"_tempBoxSize",new W),c(this,"_tempBox2Size",new W),this.renderer=t,this.context={...e}}static getObjectLODState(t){return t[Oe]}static addPlugin(t){N.push(t)}static removePlugin(t){const e=N.indexOf(t);e>=0&&N.splice(e,1)}static get(t,e){if(t[we])return console.debug("[gltf-progressive] LODsManager already exists for this renderer"),t[we];const r=new I(t,{engine:"unknown",...e});return t[we]=r,r}get plugins(){return N}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(y(this,F))return;console.debug("[gltf-progressive] Enabling LODsManager for renderer");let t=0;G(this,F,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,G(e,Q,y(e,Q)+1),G(e,oe,y(e,_e).getDelta()),G(e,de,y(e,de)+y(e,oe)),e._fpsBuffer.shift(),e._fpsBuffer.push(1/y(e,oe)),G(e,U,e._fpsBuffer.reduce((i,l)=>i+l)/e._fpsBuffer.length),P&&y(e,Q)%200===0&&console.log("FPS",Math.round(y(e,U)),"Interval:",y(e,E)));const n=t++;y(e,F).call(this,r,o),e.onAfterRender(r,o,n)}}disable(){y(this,F)&&(console.debug("[gltf-progressive] Disabling LODsManager for renderer"),this.renderer.render=y(this,F),G(this,F,void 0))}update(t,e){this.internalUpdate(t,e)}onAfterRender(t,e,r){if(this.pause)return;const o=this.renderer.renderLists.get(t,0).opaque;let s=!0;if(o.length===1){const n=o[0].material;(n.name==="EffectMaterial"||n.name==="CopyShader")&&(s=!1)}if((e.parent&&e.parent.type==="CubeCamera"||r>=1&&e.type==="OrthographicCamera")&&(s=!1),s){if(it||(this.updateInterval==="auto"?y(this,U)<40&&y(this,E)<10?(G(this,E,y(this,E)+1),P&&console.warn("\u2193 Reducing LOD updates",y(this,E),y(this,U).toFixed(0))):y(this,U)>=60&&y(this,E)>1&&(G(this,E,y(this,E)-1),P&&console.warn("\u2191 Increasing LOD updates",y(this,E),y(this,U).toFixed(0))):G(this,E,this.updateInterval),y(this,E)>0&&y(this,Q)%y(this,E)!=0))return;this.internalUpdate(t,e)}}internalUpdate(t,e){var r,o;const s=this.renderer.renderLists.get(t,0),n=s.opaque;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse);const i=this.targetTriangleDensity;for(const a of n){if(a.material&&(((r=a.geometry)==null?void 0:r.type)==="BoxGeometry"||((o=a.geometry)==null?void 0:o.type)==="BufferGeometry")&&(a.material.name==="SphericalGaussianBlur"||a.material.name=="BackgroundCubeMaterial"||a.material.name==="CubemapFromEquirect"||a.material.name==="EquirectangularToCubeUV")){P&&(a.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(a.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",a,a.material.name,a.material.type)));continue}switch(a.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}if(P==="color"&&a.material&&!a.object.progressive_debug_color){a.object.progressive_debug_color=!0;const g=Math.random()*16777215,p=new Ve({color:g});a.object.material=p}const f=a.object;(f instanceof q||f.isMesh)&&this.updateLODs(t,e,f,i)}const l=s.transparent;for(const a of l){const f=a.object;(f instanceof q||f.isMesh)&&this.updateLODs(t,e,f,i)}const u=s.transmissive;for(const a of u){const f=a.object;(f instanceof q||f.isMesh)&&this.updateLODs(t,e,f,i)}}updateLODs(t,e,r,o){var s,n;r.userData||(r.userData={});let i=r[Oe];if(i||(i=new at,r[Oe]=i),i.frames++<2)return;for(const u of N)(s=u.onBeforeUpdateLOD)==null||s.call(u,this.renderer,t,e,r);this.calculateLodLevel(e,r,i,o,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 l=k.texture_lod;if(r.material&&l>=0){const u=r["DEBUG:LOD"];u!=null&&(l=u),this.loadProgressiveTextures(r.material,l)}for(const u of N)(n=u.onAfterUpdatedLOD)==null||n.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 o of t)this.loadProgressiveTextures(o,e);return}let r=!1;(t[J]===void 0||e<t[J])&&(r=!0),r&&(t[J]=e,S.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[J]!==e){t[J]=e;const r=t.geometry;return S.assignMeshLOD(t,e).then(o=>(o&&t[J]==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,n=(r.y+o.y)*.5;return this._tempPtInside.set(s,n,r.z).applyMatrix4(e).z<0}calculateLodLevel(t,e,r,o,s){var n;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,l=!1;if(P&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const u=S.getMeshLODInformation(e.geometry),a=u?.lods,f=a&&a.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||(l=!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),O=L.geometry;d&&(L.geometry=d),L.computeBoundingBox(),L.geometry=O}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),I.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,ae=(v.y+m.y)*.5;h=(h-ie)*z+ie,M=(M-ae)*z+ae,b=(b-ie)*z+ie,C=(C-ae)*z+ae;const Ge=h<0&&b>0?0:Math.min(Math.abs(v.x),Math.abs(m.x)),We=M<0&&C>0?0:Math.min(Math.abs(v.y),Math.abs(m.y)),ge=Math.max(Ge,We);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 O=t.matrixWorldInverse,_=this._tempBox2;_.copy(D),_.applyMatrix4(e.matrixWorld),_.applyMatrix4(O);const B=_.getSize(this._tempBox2Size),T=Math.max(B.x,B.y);if(Math.max(d.x,d.y)!=0&&T!=0&&(d.z=B.z/Math.max(B.x,B.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&&I.debugDrawLine){const v=this.tempMatrix.copy(this.projectionScreenMatrix);v.invert();const m=I.corner0,h=I.corner1,M=I.corner2,b=I.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),I.debugDrawLine(m,h,255),I.debugDrawLine(m,M,255),I.debugDrawLine(h,b,255),I.debugDrawLine(M,b,255)}let $=999;if(a&&r.lastScreenCoverage>0){for(let v=0;v<a.length;v++)if(a[v].density/r.lastScreenCoverage<o){$=v;break}}$<i&&(i=$,l=!0)}if(l?s.mesh_lod=i:s.mesh_lod=r.lastLodLevel_Mesh,P&&s.mesh_lod!=r.lastLodLevel_Mesh){const L=a?.[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 O=r.lastScreenCoverage*4;((n=this.context)==null?void 0:n.engine)==="model-viewer"&&(O*=1.5);const _=A/window.devicePixelRatio*O;for(let B=g.lods.length-1;B>=0;B--){let T=g.lods[B];if(!(L&&T.max_height>=2048)&&!(rt()&&T.max_height>4096)&&T.max_height>_){if(s.texture_lod=B,s.texture_lod<r.lastLodLevel_Texture){const $=T.max_height;P&&console.log(`Texture LOD changed: ${r.lastLodLevel_Texture} \u2192 ${s.texture_lod} = ${$}px
6
- Screensize: ${_.toFixed(0)}px, Coverage: ${(100*r.lastScreenCoverage).toFixed(2)}%, Volume ${d.toFixed(1)}
7
- ${e.name}`)}break}}}}else s.texture_lod=0}};let j=I;E=new WeakMap,F=new WeakMap,_e=new WeakMap,Q=new WeakMap,oe=new WeakMap,de=new WeakMap,U=new WeakMap,c(j,"debugDrawLine"),c(j,"corner0",new W),c(j,"corner1",new W),c(j,"corner2",new W),c(j,"corner3",new W),c(j,"_tempPtInside",new W);class at{constructor(){c(this,"frames",0),c(this,"lastLodLevel_Mesh",-1),c(this,"lastLodLevel_Texture",-1),c(this,"lastScreenCoverage",0),c(this,"lastScreenspaceVolume",new W),c(this,"lastCentrality",0)}}const ke=Symbol("NEEDLE_mesh_lod"),he=Symbol("NEEDLE_texture_lod");let fe=null;function be(){const t=lt();t&&(t.mapURLs(function(e){return Ce(),e}),Ce(),fe?.disconnect(),fe=new MutationObserver(e=>{e.forEach(r=>{r.addedNodes.forEach(o=>{o instanceof HTMLElement&&o.tagName.toLowerCase()==="model-viewer"&&je(o)})})}),fe.observe(document,{childList:!0,subtree:!0}))}function lt(){return typeof customElements>"u"?null:customElements.get("model-viewer")||(customElements.whenDefined("model-viewer").then(()=>{console.debug("[gltf-progressive] model-viewer defined"),be()}),null)}function Ce(){typeof document>"u"||document.querySelectorAll("model-viewer").forEach(t=>{je(t)})}const Re=new WeakSet;let ut=0;function je(t){if(!t||Re.has(t))return null;Re.add(t),console.debug("[gltf-progressive] found new model-viewer..."+ ++ut+`
8
- `,t.getAttribute("src"));let e=null,r=null,o=null;for(let s=t;s!=null;s=Object.getPrototypeOf(s)){const n=Object.getOwnPropertySymbols(s),i=n.find(a=>a.toString()=="Symbol(renderer)"),l=n.find(a=>a.toString()=="Symbol(scene)"),u=n.find(a=>a.toString()=="Symbol(needsRender)");!e&&i!=null&&(e=t[i].threeRenderer),!r&&l!=null&&(r=t[l]),!o&&u!=null&&(o=t[u])}if(e&&r){let s=function(){if(o){let i=0,l=setInterval(()=>{if(i++>5){clearInterval(l);return}o?.call(t)},300)}};console.debug("[gltf-progressive] setup model-viewer");const n=j.get(e,{engine:"model-viewer"});return j.addPlugin(new ct),n.enable(),n.addEventListener("changed",()=>{o?.call(t)}),t.addEventListener("model-visibility",i=>{i.detail.visible&&o?.call(t)}),t.addEventListener("load",()=>{s()}),()=>{n.disable()}}return null}class ct{constructor(){c(this,"_didWarnAboutMissingUrl",!1)}onBeforeUpdateLOD(e,r,o,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 o=this.tryGetCurrentGLTF(e),s=this.tryGetCurrentModelViewer(e),n=this.getUrl(s);if(n&&o&&r.material){let i=function(u){var a,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=(a=L.userData)==null?void 0:a.associations)==null?void 0:f.textures;if(d==null)continue;const O=o.parser.json.textures[d];if(!O){console.warn("Texture data not found for texture index "+d);continue}if((g=O?.extensions)!=null&&g[R]){const _=O.extensions[R];_&&n&&S.registerTexture(n,L,_.lods.length,d,_)}}}};const l=r.material;if(Array.isArray(l))for(const u of l)i(u);else i(l)}}tryParseMeshLOD(e,r){var o,s;if(r[ke]==!0)return;r[ke]=!0;const n=this.tryGetCurrentModelViewer(e),i=this.getUrl(n);if(!i)return;const l=(s=(o=r.userData)==null?void 0:o.gltfExtensions)==null?void 0:s[R];if(l&&i){const u=r.uuid;S.registerMesh(i,u,r,0,l.lods.length,l)}}}function dt(t,e,r,o){ve(e),ye(r),Ae(r,{progressive:!0,...o?.hints}),r.register(n=>new S(n,t));const s=j.get(e);return o?.enableLODsManager!==!1&&s.enable(),s}be();export{R as EXTENSION_NAME,j as LODsManager,S as NEEDLE_progressive,pe as VERSION,ye as addDracoAndKTX2Loaders,Ae as configureLoader,ve as createLoaders,re as getRaycastMesh,be as patchModelViewer,Ie as registerRaycastMesh,Qe as setDracoDecoderLocation,Ze as setKTX2TranscoderLocation,dt as useNeedleProgressive,st as useRaycastMeshes};
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,s,o,r)=>{if(x&&console.log("> Progressive: register texture",o,e.name,e.uuid,e,r),!e){x&&console.error("gltf-progressive: Register texture without texture");return}e.source&&(e.source[De]=r);const n=r.guid;w.assignLODInformation(t,e,n,s,o,void 0),w.lodInfos.set(n,r),w.lowresCache.set(n,e)}),c(S,"registerMesh",(t,e,s,o,r,n)=>{var i;x&&console.log("> Progressive: register mesh",r,s.name,n,s.uuid,s);const l=s.geometry;if(!l){x&&console.warn("gltf-progressive: Register mesh without geometry");return}l.userData||(l.userData={}),w.assignLODInformation(t,l,e,o,r,n.density),w.lodInfos.set(e,n);let u=w.lowresCache.get(e);u?u.push(s.geometry):u=[s.geometry],w.lowresCache.set(e,u),o>0&&!J(s)&&ke(s,l);for(const a of $)(i=a.onRegisteredNewMesh)==null||i.call(a,s,n)}),c(S,"lodInfos",new Map),c(S,"previouslyLoaded",new Map),c(S,"lowresCache",new Map);class at{constructor(e,s,o,r,n){c(this,"url"),c(this,"key"),c(this,"level"),c(this,"index"),c(this,"density"),this.url=e,this.key=s,this.level=o,r!=null&&(this.index=r),n!=null&&(this.density=n)}}const k=se("debugprogressive"),lt=se("noprogressive"),Oe=Symbol("Needle:LODSManager"),be=Symbol("Needle:LODState"),Q=Symbol("Needle:CurrentLOD"),B={mesh_lod:-1,texture_lod:-1};var E,F,_e,Z,oe,de,U;const P=class{constructor(t,e){c(this,"context"),c(this,"renderer"),c(this,"projectionScreenMatrix",new Ae),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,F,void 0),V(this,_e,new Xe),V(this,Z,0),V(this,oe,0),V(this,de,0),V(this,U,0),c(this,"_fpsBuffer",[60,60,60,60,60]),c(this,"_sphere",new Ke),c(this,"_tempBox",new Ie),c(this,"_tempBox2",new Ie),c(this,"tempMatrix",new Ae),c(this,"_tempWorldPosition",new G),c(this,"_tempBoxSize",new G),c(this,"_tempBox2Size",new G),this.renderer=t,this.context={...e}}static getObjectLODState(t){return t[be]}static addPlugin(t){$.push(t)}static removePlugin(t){const e=$.indexOf(t);e>=0&&$.splice(e,1)}static get(t,e){if(t[Oe])return console.debug("[gltf-progressive] LODsManager already exists for this renderer"),t[Oe];const s=new P(t,{engine:"unknown",...e});return t[Oe]=s,s}get plugins(){return $}addEventListener(t,e){t==="changed"&&this._lodchangedlisteners.push(e)}removeEventListener(t,e){if(t==="changed"){const s=this._lodchangedlisteners.indexOf(e);s>=0&&this._lodchangedlisteners.splice(s,1)}}enable(){if(y(this,F))return;console.debug("[gltf-progressive] Enabling LODsManager for renderer");let t=0;N(this,F,this.renderer.render);const e=this;ve(this.renderer),this.renderer.render=function(s,o){const r=e.renderer.getRenderTarget();(r==null||"isXRRenderTarget"in r&&r.isXRRenderTarget)&&(t=0,N(e,Z,y(e,Z)+1),N(e,oe,y(e,_e).getDelta()),N(e,de,y(e,de)+y(e,oe)),e._fpsBuffer.shift(),e._fpsBuffer.push(1/y(e,oe)),N(e,U,e._fpsBuffer.reduce((i,l)=>i+l)/e._fpsBuffer.length),k&&y(e,Z)%200===0&&console.log("FPS",Math.round(y(e,U)),"Interval:",y(e,E)));const n=t++;y(e,F).call(this,s,o),e.onAfterRender(s,o,n)}}disable(){y(this,F)&&(console.debug("[gltf-progressive] Disabling LODsManager for renderer"),this.renderer.render=y(this,F),N(this,F,void 0))}update(t,e){this.internalUpdate(t,e)}onAfterRender(t,e,s){if(this.pause)return;const o=this.renderer.renderLists.get(t,0).opaque;let r=!0;if(o.length===1){const n=o[0].material;(n.name==="EffectMaterial"||n.name==="CopyShader")&&(r=!1)}if((e.parent&&e.parent.type==="CubeCamera"||s>=1&&e.type==="OrthographicCamera")&&(r=!1),r){if(lt||(this.updateInterval==="auto"?y(this,U)<40&&y(this,E)<10?(N(this,E,y(this,E)+1),k&&console.warn("\u2193 Reducing LOD updates",y(this,E),y(this,U).toFixed(0))):y(this,U)>=60&&y(this,E)>1&&(N(this,E,y(this,E)-1),k&&console.warn("\u2191 Increasing LOD updates",y(this,E),y(this,U).toFixed(0))):N(this,E,this.updateInterval),y(this,E)>0&&y(this,Z)%y(this,E)!=0))return;this.internalUpdate(t,e)}}internalUpdate(t,e){var s,o;const r=this.renderer.renderLists.get(t,0),n=r.opaque;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse);const i=this.targetTriangleDensity;for(const a of n){if(a.material&&(((s=a.geometry)==null?void 0:s.type)==="BoxGeometry"||((o=a.geometry)==null?void 0:o.type)==="BufferGeometry")&&(a.material.name==="SphericalGaussianBlur"||a.material.name=="BackgroundCubeMaterial"||a.material.name==="CubemapFromEquirect"||a.material.name==="EquirectangularToCubeUV")){k&&(a.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(a.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",a,a.material.name,a.material.type)));continue}switch(a.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}if(k==="color"&&a.material&&!a.object.progressive_debug_color){a.object.progressive_debug_color=!0;const f=Math.random()*16777215,p=new He({color:f});a.object.material=p}const g=a.object;(g instanceof q||g.isMesh)&&this.updateLODs(t,e,g,i)}const l=r.transparent;for(const a of l){const g=a.object;(g instanceof q||g.isMesh)&&this.updateLODs(t,e,g,i)}const u=r.transmissive;for(const a of u){const g=a.object;(g instanceof q||g.isMesh)&&this.updateLODs(t,e,g,i)}}updateLODs(t,e,s,o){var r,n;s.userData||(s.userData={});let i=s[be];if(i||(i=new ut,s[be]=i),i.frames++<2)return;for(const u of $)(r=u.onBeforeUpdateLOD)==null||r.call(u,this.renderer,t,e,s);this.calculateLodLevel(e,s,i,o,B),B.mesh_lod=Math.round(B.mesh_lod),B.texture_lod=Math.round(B.texture_lod),B.mesh_lod>=0&&this.loadProgressiveMeshes(s,B.mesh_lod);let l=B.texture_lod;if(s.material&&l>=0){const u=s["DEBUG:LOD"];u!=null&&(l=u),this.loadProgressiveTextures(s.material,l)}for(const u of $)(n=u.onAfterUpdatedLOD)==null||n.call(u,this.renderer,t,e,s,B);i.lastLodLevel_Mesh=B.mesh_lod,i.lastLodLevel_Texture=B.texture_lod}loadProgressiveTextures(t,e){if(!t)return;if(Array.isArray(t)){for(const o of t)this.loadProgressiveTextures(o,e);return}let s=!1;(t[Q]===void 0||e<t[Q])&&(s=!0),s&&(t[Q]=e,S.assignTextureLOD(t,e).then(o=>{this._lodchangedlisteners.forEach(r=>r({type:"texture",level:e,object:t}))}))}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);if(t[Q]!==e){t[Q]=e;const s=t.geometry;return S.assignMeshLOD(t,e).then(o=>(o&&t[Q]==e&&s!=t.geometry&&this._lodchangedlisteners.forEach(r=>r({type:"mesh",level:e,object:t})),o))}return Promise.resolve(null)}static isInside(t,e){const s=t.min,o=t.max,r=(s.x+o.x)*.5,n=(s.y+o.y)*.5;return this._tempPtInside.set(r,n,s.z).applyMatrix4(e).z<0}calculateLodLevel(t,e,s,o,r){var n;if(!e){r.mesh_lod=-1,r.texture_lod=-1;return}if(!t){r.mesh_lod=-1,r.texture_lod=-1;return}let i=10+1,l=!1;if(k&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const u=S.getMeshLODInformation(e.geometry),a=u?.lods,g=a&&a.length>0,f=S.getMaterialMinMaxLODsCount(e.material),p=f?.min_count!=1/0&&f.min_count>0&&f.max_count>0;if(!g&&!p){r.mesh_lod=0,r.texture_lod=0;return}g||(l=!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(s.frames%30===0){const d=J(L),O=L.geometry;d&&(L.geometry=d),L.computeBoundingBox(),L.geometry=O}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)){r.mesh_lod=0,r.texture_lod=0;return}}if(this._tempBox.copy(D),this._tempBox.applyMatrix4(e.matrixWorld),P.isInside(this._tempBox,this.projectionScreenMatrix)){r.mesh_lod=0,r.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&L.fov>70){const v=this._tempBox.min,m=this._tempBox.max;let h=v.x,M=v.y,_=m.x,R=m.y;const z=2,X=1.5,ie=(v.x+m.x)*.5,ae=(v.y+m.y)*.5;h=(h-ie)*z+ie,M=(M-ae)*z+ae,_=(_-ie)*z+ie,R=(R-ae)*z+ae;const $e=h<0&&_>0?0:Math.min(Math.abs(v.x),Math.abs(m.x)),Fe=M<0&&R>0?0:Math.min(Math.abs(v.y),Math.abs(m.y)),fe=Math.max($e,Fe);s.lastCentrality=(X-fe)*(X-fe)*(X-fe)}else s.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 O=t.matrixWorldInverse,b=this._tempBox2;b.copy(D),b.applyMatrix4(e.matrixWorld),b.applyMatrix4(O);const I=b.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)),s.lastScreenCoverage=Math.max(d.x,d.y,d.z),s.lastScreenspaceVolume.copy(d),s.lastScreenCoverage*=s.lastCentrality,k&&P.debugDrawLine){const v=this.tempMatrix.copy(this.projectionScreenMatrix);v.invert();const m=P.corner0,h=P.corner1,M=P.corner2,_=P.corner3;m.copy(this._tempBox.min),h.copy(this._tempBox.max),h.x=m.x,M.copy(this._tempBox.max),M.y=m.y,_.copy(this._tempBox.max);const R=(m.z+_.z)*.5;m.z=h.z=M.z=_.z=R,m.applyMatrix4(v),h.applyMatrix4(v),M.applyMatrix4(v),_.applyMatrix4(v),P.debugDrawLine(m,h,255),P.debugDrawLine(m,M,255),P.debugDrawLine(h,_,255),P.debugDrawLine(M,_,255)}let W=999;if(a&&s.lastScreenCoverage>0){for(let v=0;v<a.length;v++)if(a[v].density/s.lastScreenCoverage<o){W=v;break}}W<i&&(i=W,l=!0)}if(l?r.mesh_lod=i:r.mesh_lod=s.lastLodLevel_Mesh,k&&r.mesh_lod!=s.lastLodLevel_Mesh){const L=a?.[r.mesh_lod];L&&console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} \u2192 ${r.mesh_lod} (${L.density.toFixed(0)}) - ${e.name}`)}if(p){const L="saveData"in globalThis.navigator&&globalThis.navigator.saveData===!0;if(s.lastLodLevel_Texture<0){if(r.texture_lod=f.max_count-1,k){const d=f.lods[f.max_count-1];k&&console.log(`First Texture LOD ${r.texture_lod} (${d.max_height}px) - ${e.name}`)}}else{const d=s.lastScreenspaceVolume.x+s.lastScreenspaceVolume.y+s.lastScreenspaceVolume.z;let O=s.lastScreenCoverage*4;((n=this.context)==null?void 0:n.engine)==="model-viewer"&&(O*=1.5);const b=A/window.devicePixelRatio*O;for(let I=f.lods.length-1;I>=0;I--){let T=f.lods[I];if(!(L&&T.max_height>=2048)&&!(ot()&&T.max_height>4096)&&T.max_height>b){if(r.texture_lod=I,r.texture_lod<s.lastLodLevel_Texture){const W=T.max_height;k&&console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} \u2192 ${r.texture_lod} = ${W}px
6
+ Screensize: ${b.toFixed(0)}px, Coverage: ${(100*s.lastScreenCoverage).toFixed(2)}%, Volume ${d.toFixed(1)}
7
+ ${e.name}`)}break}}}}else r.texture_lod=0}};let C=P;E=new WeakMap,F=new WeakMap,_e=new WeakMap,Z=new WeakMap,oe=new WeakMap,de=new WeakMap,U=new WeakMap,c(C,"debugDrawLine"),c(C,"corner0",new G),c(C,"corner1",new G),c(C,"corner2",new G),c(C,"corner3",new G),c(C,"_tempPtInside",new G);class ut{constructor(){c(this,"frames",0),c(this,"lastLodLevel_Mesh",-1),c(this,"lastLodLevel_Texture",-1),c(this,"lastScreenCoverage",0),c(this,"lastScreenspaceVolume",new G),c(this,"lastCentrality",0)}}const Re=Symbol("NEEDLE_mesh_lod"),he=Symbol("NEEDLE_texture_lod");let ge=null;function Se(){const t=ct();t&&(t.mapURLs(function(e){return je(),e}),je(),ge?.disconnect(),ge=new MutationObserver(e=>{e.forEach(s=>{s.addedNodes.forEach(o=>{o instanceof HTMLElement&&o.tagName.toLowerCase()==="model-viewer"&&Ge(o)})})}),ge.observe(document,{childList:!0,subtree:!0}))}function ct(){return typeof customElements>"u"?null:customElements.get("model-viewer")||(customElements.whenDefined("model-viewer").then(()=>{console.debug("[gltf-progressive] model-viewer defined"),Se()}),null)}function je(){typeof document>"u"||document.querySelectorAll("model-viewer").forEach(t=>{Ge(t)})}const Ne=new WeakSet;let dt=0;function Ge(t){if(!t||Ne.has(t))return null;Ne.add(t),console.debug("[gltf-progressive] found new model-viewer..."+ ++dt+`
8
+ `,t.getAttribute("src"));let e=null,s=null,o=null;for(let r=t;r!=null;r=Object.getPrototypeOf(r)){const n=Object.getOwnPropertySymbols(r),i=n.find(a=>a.toString()=="Symbol(renderer)"),l=n.find(a=>a.toString()=="Symbol(scene)"),u=n.find(a=>a.toString()=="Symbol(needsRender)");!e&&i!=null&&(e=t[i].threeRenderer),!s&&l!=null&&(s=t[l]),!o&&u!=null&&(o=t[u])}if(e&&s){let r=function(){if(o){let i=0,l=setInterval(()=>{if(i++>5){clearInterval(l);return}o?.call(t)},300)}};console.debug("[gltf-progressive] setup model-viewer");const n=C.get(e,{engine:"model-viewer"});return C.addPlugin(new ht),n.enable(),n.addEventListener("changed",()=>{o?.call(t)}),t.addEventListener("model-visibility",i=>{i.detail.visible&&o?.call(t)}),t.addEventListener("load",()=>{r()}),()=>{n.disable()}}return null}class ht{constructor(){c(this,"_didWarnAboutMissingUrl",!1)}onBeforeUpdateLOD(e,s,o,r){this.tryParseMeshLOD(s,r),this.tryParseTextureLOD(s,r)}getUrl(e){if(!e)return null;let s=e.getAttribute("src");return s||(s=e.src),s||(this._didWarnAboutMissingUrl||console.warn("No url found in modelviewer",e),this._didWarnAboutMissingUrl=!0),s}tryGetCurrentGLTF(e){return e._currentGLTF}tryGetCurrentModelViewer(e){return e.element}tryParseTextureLOD(e,s){if(s[he]==!0)return;s[he]=!0;const o=this.tryGetCurrentGLTF(e),r=this.tryGetCurrentModelViewer(e),n=this.getUrl(r);if(n&&o&&s.material){let i=function(u){var a,g,f;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=(g=(a=L.userData)==null?void 0:a.associations)==null?void 0:g.textures;if(d==null)continue;const O=o.parser.json.textures[d];if(!O){console.warn("Texture data not found for texture index "+d);continue}if((f=O?.extensions)!=null&&f[j]){const b=O.extensions[j];b&&n&&S.registerTexture(n,L,b.lods.length,d,b)}}}};const l=s.material;if(Array.isArray(l))for(const u of l)i(u);else i(l)}}tryParseMeshLOD(e,s){var o,r;if(s[Re]==!0)return;s[Re]=!0;const n=this.tryGetCurrentModelViewer(e),i=this.getUrl(n);if(!i)return;const l=(r=(o=s.userData)==null?void 0:o.gltfExtensions)==null?void 0:r[j];if(l&&i){const u=s.uuid;S.registerMesh(i,u,s,0,l.lods.length,l)}}}function We(t,e,s,o){ve(e),ye(s),Le(s,{progressive:!0,...o?.hints}),s.register(n=>new S(n,t));const r=C.get(e);return o?.enableLODsManager!==!1&&r.enable(),r}Se();const Te={gltfProgressive:{useNeedleProgressive:We,LODsManager:C,configureLoader:Le,getRaycastMesh:J,useRaycastMeshes:Be}};if(!globalThis.Needle)globalThis.Needle=Te;else for(const t in Te)globalThis.Needle[t]=Te[t];export{j as EXTENSION_NAME,C as LODsManager,S as NEEDLE_progressive,pe as VERSION,ye as addDracoAndKTX2Loaders,Le as configureLoader,ve as createLoaders,J as getRaycastMesh,Se as patchModelViewer,ke as registerRaycastMesh,tt as setDracoDecoderLocation,st as setKTX2TranscoderLocation,We as useNeedleProgressive,Be as useRaycastMeshes};
@@ -1,8 +1,8 @@
1
- "use strict";var Ve=Object.defineProperty;var $e=(n,t,e)=>t in n?Ve(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var d=(n,t,e)=>($e(n,typeof t!="symbol"?t+"":t,e),e),Ae=(n,t,e)=>{if(!t.has(n))throw TypeError("Cannot "+e)};var L=(n,t,e)=>(Ae(n,t,"read from private field"),e?e.call(n):t.get(n)),K=(n,t,e)=>{if(t.has(n))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(n):t.set(n,e)},N=(n,t,e,s)=>(Ae(n,t,"write to private field"),s?s.call(n,e):t.set(n,e),e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("three"),_e=require("three/examples/jsm/loaders/GLTFLoader.js"),Ne=require("three/examples/jsm/libs/meshopt_decoder.module.js"),Ue=require("three/examples/jsm/loaders/DRACOLoader.js"),ze=require("three/examples/jsm/loaders/KTX2Loader.js"),Oe="";globalThis.GLTF_PROGRESSIVE_VERSION=Oe;console.debug(`[gltf-progressive] version ${Oe}`);let Q="https://www.gstatic.com/draco/versioned/decoders/1.5.7/",oe="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";const We=Q,qe=oe;fetch(Q+"draco_decoder.js",{method:"head"}).catch(n=>{Q===We&&(Q="./include/draco/"),oe===qe&&(oe="./include/ktx2/")});function Xe(n){Q=n}function Ke(n){oe=n}let j,de,J;function Se(n){return j||(j=new Ue.DRACOLoader,j.setDecoderPath(Q),j.setDecoderConfig({type:"js"})),J||(J=new ze.KTX2Loader,J.setTranscoderPath(oe)),de||(de=Ne.MeshoptDecoder),n?J.detectSupport(n):n!==null&&console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"),{dracoLoader:j,ktx2Loader:J,meshoptDecoder:de}}function be(n){n.dracoLoader||n.setDRACOLoader(j),n.ktx2Loader||n.setKTX2Loader(J),n.meshoptDecoder||n.setMeshoptDecoder(de)}const De=new WeakMap;function Ie(n,t){let e=De.get(n);e?e=Object.assign(e,t):e=t,De.set(n,e)}const me=_e.GLTFLoader.prototype.load;function Ye(...n){const t=De.get(this);let e=n[0];const s=new URL(e,window.location.href);if(s.hostname.endsWith("needle.tools")){const r=(t==null?void 0:t.progressive)!==void 0?t.progressive:!0,i=t!=null&&t.usecase?t.usecase:"default";r?this.requestHeader.Accept=`*/*;progressive=allowed;usecase=${i}`:this.requestHeader.Accept=`*/*;usecase=${i}`,e=s.toString()}return n[0]=e,me==null?void 0:me.call(this,...n)}_e.GLTFLoader.prototype.load=Ye;ne("debugprogressive");function ne(n){if(typeof window>"u")return!1;const e=new URL(window.location.href).searchParams.get(n);return e==null||e==="0"||e==="false"?!1:e===""?!0:e}function He(n,t){if(t===void 0||t.startsWith("./")||t.startsWith("http")||n===void 0)return t;const e=n.lastIndexOf("/");if(e>=0){const s=n.substring(0,e+1);for(;s.endsWith("/")&&t.startsWith("/");)t=t.substring(1);return s+t}return t}let te;function je(){return te!==void 0||(te=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),ne("debugprogressive")&&console.log("[glTF Progressive]: isMobileDevice",te)),te}const we=Symbol("needle:raycast-mesh");function ae(n){return(n==null?void 0:n[we])instanceof p.BufferGeometry?n[we]:null}function Re(n,t){if((n.type==="Mesh"||n.type==="SkinnedMesh")&&!ae(n)){const s=Qe(t);s.userData={isRaycastMesh:!0},n[we]=s}}function Je(n=!0){if(n){if(se)return;const t=se=p.Mesh.prototype.raycast;p.Mesh.prototype.raycast=function(e,s){const o=this,r=ae(o);let i;r&&o.isMesh&&(i=o.geometry,o.geometry=r),t.call(this,e,s),i&&(o.geometry=i)}}else{if(!se)return;p.Mesh.prototype.raycast=se,se=null}}let se=null;function Qe(n){const t=new p.BufferGeometry;for(const e in n.attributes)t.setAttribute(e,n.getAttribute(e));return t.setIndex(n.getIndex()),t}const Y=new Array,U="NEEDLE_progressive",x=ne("debugprogressive"),Le=Symbol("needle-progressive-texture"),ie=new Map,ve=new Set;if(x){let n=function(){t+=1,console.log("Toggle LOD level",t,ie),ie.forEach((o,r)=>{for(const i of o.keys){const a=r[i];if(a!=null){if(a.isBufferGeometry===!0){const l=O.getMeshLODInformation(a),u=l?Math.min(t,l.lods.length):0;r["DEBUG:LOD"]=t,O.assignMeshLOD(r,u),l&&(e=Math.max(e,l.lods.length-1))}else if(r.isMaterial===!0){r["DEBUG:LOD"]=t,O.assignTextureLOD(r,t);break}}}}),t>=e&&(t=-1)},t=-1,e=2,s=!1;window.addEventListener("keyup",o=>{o.key==="p"&&n(),o.key==="w"&&(s=!s,ve&&ve.forEach(r=>{r.name!="BackgroundCubeMaterial"&&r.glyphMap==null&&"wireframe"in r&&(r.wireframe=s)}))})}function Ee(n,t,e){var o;if(!x)return;ie.has(n)||ie.set(n,{keys:[],sourceId:e});const s=ie.get(n);((o=s==null?void 0:s.keys)==null?void 0:o.includes(t))==!1&&s.keys.push(t)}const _=class{constructor(t,e){d(this,"parser");d(this,"url");d(this,"_isLoadingMesh");d(this,"loadMesh",t=>{var s,o;if(this._isLoadingMesh)return null;const e=(o=(s=this.parser.json.meshes[t])==null?void 0:s.extensions)==null?void 0:o[U];return e?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",t).then(r=>{var i;return this._isLoadingMesh=!1,r&&_.registerMesh(this.url,e.guid,r,(i=e.lods)==null?void 0:i.length,void 0,e),r})):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 s=this,o="LODS:minmax",r=t[o];if(r!=null)return r;if(e||(e={min_count:1/0,max_count:0,lods:[]}),Array.isArray(t)){for(const a of t)this.getMaterialMinMaxLODsCount(a,e);return t[o]=e,e}if(x==="verbose"&&console.log("getMaterialMinMaxLODsCount",t),t.type==="ShaderMaterial"||t.type==="RawShaderMaterial"){const a=t;for(const l of Object.keys(a.uniforms)){const u=a.uniforms[l].value;(u==null?void 0:u.isTexture)===!0&&i(u,e)}}else if(t.isMaterial)for(const a of Object.keys(t)){const l=t[a];(l==null?void 0:l.isTexture)===!0&&i(l,e)}return t[o]=e,e;function i(a,l){const u=s.getAssignedLODInformation(a);if(u){const c=s.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 r;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 a=t[i];if(a&&a.isTexture&&this.hasLODLevelAvailable(a,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 s,o;if(t.isMesh?s=t.geometry:(t.isBufferGeometry||t.isTexture)&&(s=t),s&&(r=s==null?void 0:s.userData)!=null&&r.LODS){const i=s.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 s;if(!t)return Promise.resolve(null);if(t instanceof p.Mesh||t.isMesh===!0){const o=t.geometry,r=this.getAssignedLODInformation(o);if(!r)return Promise.resolve(null);for(const i of Y)(s=i.onBeforeGetLODMesh)==null||s.call(i,t,e);return t["LOD:requested level"]=e,_.getOrLoadLOD(o,e).then(i=>{if(Array.isArray(i)){const a=r.index||0;i=i[a]}return t["LOD:requested level"]===e&&(delete t["LOD:requested level"],i&&o!=i&&((i==null?void 0:i.isBufferGeometry)?(t.geometry=i,x&&Ee(t,"geometry",r.url)):x&&console.error("Invalid LOD geometry",i))),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.isMesh===!0){const s=t;if(Array.isArray(s.material)){const o=new Array;for(const r of s.material){const i=this.assignTextureLOD(r,e);o.push(i)}return Promise.all(o).then(r=>{const i=new Array;for(const a of r)Array.isArray(a)&&i.push(...a);return i})}else return this.assignTextureLOD(s.material,e)}if(t instanceof p.Material||t.isMaterial===!0){const s=t,o=[],r=new Array;if(x&&ve.add(s),s.uniforms&&(s.isRawShaderMaterial||s.isShaderMaterial===!0)){const i=s;for(const a of Object.keys(i.uniforms)){const l=i.uniforms[a].value;if((l==null?void 0:l.isTexture)===!0){const u=this.assignTextureLODForSlot(l,e,s,a).then(c=>(c&&i.uniforms[a].value!=c&&(i.uniforms[a].value=c,i.uniformsNeedUpdate=!0),c));o.push(u),r.push(a)}}}else for(const i of Object.keys(s)){const a=s[i];if((a==null?void 0:a.isTexture)===!0){const l=this.assignTextureLODForSlot(a,e,s,i);o.push(l),r.push(i)}}return Promise.all(o).then(i=>{const a=new Array;for(let l=0;l<i.length;l++){const u=i[l],c=r[l];u&&u.isTexture===!0?a.push({material:s,slot:c,texture:u,level:e}):a.push({material:s,slot:c,texture:null,level:e})}return a})}if(t instanceof p.Texture||t.isTexture===!0){const s=t;return this.assignTextureLODForSlot(s,e,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(t,e,s,o){return(t==null?void 0:t.isTexture)!==!0?Promise.resolve(null):o==="glyphMap"?Promise.resolve(t):_.getOrLoadLOD(t,e).then(r=>{if(Array.isArray(r))return null;if((r==null?void 0:r.isTexture)===!0){if(r!=t){if(s&&o){const i=s[o];if(i){const a=this.getAssignedLODInformation(i);if(a&&(a==null?void 0:a.level)<e)return x==="verbose"&&console.warn("Assigned texture level is already higher: ",a.level,e,s,i,r),null}s[o]=r}if(x&&o&&s){const i=this.getAssignedLODInformation(t);i&&Ee(s,o,i.url)}}return r}else x=="verbose"&&console.warn("No LOD found for",t,e);return null}).catch(r=>(console.error("Error loading LOD",t,r),null))}afterRoot(t){var e,s;return x&&console.log("AFTER",this.url,t),(e=this.parser.json.textures)==null||e.forEach((o,r)=>{var i;if(o!=null&&o.extensions){const a=o==null?void 0:o.extensions[U];if(a){if(!a.lods){x&&console.warn("Texture has no LODs",a);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)===r&&(l=!0,_.registerTexture(this.url,u,(i=a.lods)==null?void 0:i.length,r,a))}l||this.parser.getDependency("texture",r).then(u=>{var c;u&&_.registerTexture(this.url,u,(c=a.lods)==null?void 0:c.length,r,a)})}}}),(s=this.parser.json.meshes)==null||s.forEach((o,r)=>{if(o!=null&&o.extensions){const i=o==null?void 0:o.extensions[U];if(i&&i.lods){for(const a of this.parser.associations.keys())if(a.isMesh){const l=this.parser.associations.get(a);(l==null?void 0:l.meshes)===r&&_.registerMesh(this.url,i.guid,a,i.lods.length,l.primitives,i)}}}}),null}static async getOrLoadLOD(t,e){var a,l,u,c;const s=x=="verbose",o=t.userData.LODS;if(!o)return null;const r=o==null?void 0:o.key;let i;if(t.isTexture===!0){const g=t;g.source&&g.source[Le]&&(i=g.source[Le])}if(i||(i=_.lodInfos.get(r)),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(r)}const g=Array.isArray(i.lods)?(a=i.lods[e])==null?void 0:a.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=He(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){s&&console.log(`LOD ${e} was already loading/loaded: ${D}`);let h=await v.catch($=>(console.error(`Error loading LOD ${e} from ${y}
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,V=new Promise(async(h,R)=>{const $=new _e.GLTFLoader;be($),x&&(await new Promise(E=>setTimeout(E,1e3)),s&&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;s&&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,r,e,void 0,void 0),s&&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(s&&console.log(`Loaded Mesh "${f.name}"`,y,A,f,D),f.isMesh===!0){const S=f.geometry;return _.assignLODInformation(o.url,S,r,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,r,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,V),await V}else if(t instanceof p.Texture){s&&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,s&&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 "${r}" ${t.name}`,t.type);return null}static assignLODInformation(t,e,s,o,r,i){if(!e)return;e.userData||(e.userData={});const a=new Ze(t,s,o,r,i);e.userData.LODS=a}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
1
+ "use strict";var Ue=Object.defineProperty;var ze=(n,t,e)=>t in n?Ue(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var d=(n,t,e)=>(ze(n,typeof t!="symbol"?t+"":t,e),e),Pe=(n,t,e)=>{if(!t.has(n))throw TypeError("Cannot "+e)};var L=(n,t,e)=>(Pe(n,t,"read from private field"),e?e.call(n):t.get(n)),K=(n,t,e)=>{if(t.has(n))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(n):t.set(n,e)},N=(n,t,e,s)=>(Pe(n,t,"write to private field"),s?s.call(n,e):t.set(n,e),e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("three"),Oe=require("three/examples/jsm/loaders/GLTFLoader.js"),We=require("three/examples/jsm/libs/meshopt_decoder.module.js"),qe=require("three/examples/jsm/loaders/DRACOLoader.js"),Xe=require("three/examples/jsm/loaders/KTX2Loader.js"),Se="";globalThis.GLTF_PROGRESSIVE_VERSION=Se;console.debug(`[gltf-progressive] version ${Se}`);let Q="https://www.gstatic.com/draco/versioned/decoders/1.5.7/",ne="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";const Ke=Q,Ye=ne;fetch(Q+"draco_decoder.js",{method:"head"}).catch(n=>{Q===Ke&&(Q="./include/draco/"),ne===Ye&&(ne="./include/ktx2/")});function He(n){Q=n}function je(n){ne=n}let j,de,J;function be(n){return j||(j=new qe.DRACOLoader,j.setDecoderPath(Q),j.setDecoderConfig({type:"js"})),J||(J=new Xe.KTX2Loader,J.setTranscoderPath(ne)),de||(de=We.MeshoptDecoder),n?J.detectSupport(n):n!==null&&console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"),{dracoLoader:j,ktx2Loader:J,meshoptDecoder:de}}function Te(n){n.dracoLoader||n.setDRACOLoader(j),n.ktx2Loader||n.setKTX2Loader(J),n.meshoptDecoder||n.setMeshoptDecoder(de)}const we=new WeakMap;function Ae(n,t){let e=we.get(n);e?e=Object.assign(e,t):e=t,we.set(n,e)}const me=Oe.GLTFLoader.prototype.load;function Je(...n){const t=we.get(this);let e=n[0];const s=new URL(e,window.location.href);if(s.hostname.endsWith("needle.tools")){const r=(t==null?void 0:t.progressive)!==void 0?t.progressive:!0,i=t!=null&&t.usecase?t.usecase:"default";r?this.requestHeader.Accept=`*/*;progressive=allowed;usecase=${i}`:this.requestHeader.Accept=`*/*;usecase=${i}`,e=s.toString()}return n[0]=e,me==null?void 0:me.call(this,...n)}Oe.GLTFLoader.prototype.load=Je;ae("debugprogressive");function ae(n){if(typeof window>"u")return!1;const e=new URL(window.location.href).searchParams.get(n);return e==null||e==="0"||e==="false"?!1:e===""?!0:e}function Qe(n,t){if(t===void 0||t.startsWith("./")||t.startsWith("http")||n===void 0)return t;const e=n.lastIndexOf("/");if(e>=0){const s=n.substring(0,e+1);for(;s.endsWith("/")&&t.startsWith("/");)t=t.substring(1);return s+t}return t}let se;function Ze(){return se!==void 0||(se=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),ae("debugprogressive")&&console.log("[glTF Progressive]: isMobileDevice",se)),se}const ve=Symbol("needle:raycast-mesh");function te(n){return(n==null?void 0:n[ve])instanceof p.BufferGeometry?n[ve]:null}function Re(n,t){if((n.type==="Mesh"||n.type==="SkinnedMesh")&&!te(n)){const s=et(t);s.userData={isRaycastMesh:!0},n[ve]=s}}function Ge(n=!0){if(n){if(re)return;const t=re=p.Mesh.prototype.raycast;p.Mesh.prototype.raycast=function(e,s){const o=this,r=te(o);let i;r&&o.isMesh&&(i=o.geometry,o.geometry=r),t.call(this,e,s),i&&(o.geometry=i)}}else{if(!re)return;p.Mesh.prototype.raycast=re,re=null}}let re=null;function et(n){const t=new p.BufferGeometry;for(const e in n.attributes)t.setAttribute(e,n.getAttribute(e));return t.setIndex(n.getIndex()),t}const Y=new Array,U="NEEDLE_progressive",x=ae("debugprogressive"),Le=Symbol("needle-progressive-texture"),oe=new Map,_e=new Set;if(x){let n=function(){t+=1,console.log("Toggle LOD level",t,oe),oe.forEach((o,r)=>{for(const i of o.keys){const a=r[i];if(a!=null){if(a.isBufferGeometry===!0){const l=O.getMeshLODInformation(a),u=l?Math.min(t,l.lods.length):0;r["DEBUG:LOD"]=t,O.assignMeshLOD(r,u),l&&(e=Math.max(e,l.lods.length-1))}else if(r.isMaterial===!0){r["DEBUG:LOD"]=t,O.assignTextureLOD(r,t);break}}}}),t>=e&&(t=-1)},t=-1,e=2,s=!1;window.addEventListener("keyup",o=>{o.key==="p"&&n(),o.key==="w"&&(s=!s,_e&&_e.forEach(r=>{r.name!="BackgroundCubeMaterial"&&r.glyphMap==null&&"wireframe"in r&&(r.wireframe=s)}))})}function Ce(n,t,e){var o;if(!x)return;oe.has(n)||oe.set(n,{keys:[],sourceId:e});const s=oe.get(n);((o=s==null?void 0:s.keys)==null?void 0:o.includes(t))==!1&&s.keys.push(t)}const _=class{constructor(t,e){d(this,"parser");d(this,"url");d(this,"_isLoadingMesh");d(this,"loadMesh",t=>{var s,o;if(this._isLoadingMesh)return null;const e=(o=(s=this.parser.json.meshes[t])==null?void 0:s.extensions)==null?void 0:o[U];return e?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",t).then(r=>{var i;return this._isLoadingMesh=!1,r&&_.registerMesh(this.url,e.guid,r,(i=e.lods)==null?void 0:i.length,void 0,e),r})):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 s=this,o="LODS:minmax",r=t[o];if(r!=null)return r;if(e||(e={min_count:1/0,max_count:0,lods:[]}),Array.isArray(t)){for(const a of t)this.getMaterialMinMaxLODsCount(a,e);return t[o]=e,e}if(x==="verbose"&&console.log("getMaterialMinMaxLODsCount",t),t.type==="ShaderMaterial"||t.type==="RawShaderMaterial"){const a=t;for(const l of Object.keys(a.uniforms)){const u=a.uniforms[l].value;(u==null?void 0:u.isTexture)===!0&&i(u,e)}}else if(t.isMaterial)for(const a of Object.keys(t)){const l=t[a];(l==null?void 0:l.isTexture)===!0&&i(l,e)}return t[o]=e,e;function i(a,l){const u=s.getAssignedLODInformation(a);if(u){const c=s.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 r;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 a=t[i];if(a&&a.isTexture&&this.hasLODLevelAvailable(a,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 s,o;if(t.isMesh?s=t.geometry:(t.isBufferGeometry||t.isTexture)&&(s=t),s&&(r=s==null?void 0:s.userData)!=null&&r.LODS){const i=s.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 s;if(!t)return Promise.resolve(null);if(t instanceof p.Mesh||t.isMesh===!0){const o=t.geometry,r=this.getAssignedLODInformation(o);if(!r)return Promise.resolve(null);for(const i of Y)(s=i.onBeforeGetLODMesh)==null||s.call(i,t,e);return t["LOD:requested level"]=e,_.getOrLoadLOD(o,e).then(i=>{if(Array.isArray(i)){const a=r.index||0;i=i[a]}return t["LOD:requested level"]===e&&(delete t["LOD:requested level"],i&&o!=i&&((i==null?void 0:i.isBufferGeometry)?(t.geometry=i,x&&Ce(t,"geometry",r.url)):x&&console.error("Invalid LOD geometry",i))),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.isMesh===!0){const s=t;if(Array.isArray(s.material)){const o=new Array;for(const r of s.material){const i=this.assignTextureLOD(r,e);o.push(i)}return Promise.all(o).then(r=>{const i=new Array;for(const a of r)Array.isArray(a)&&i.push(...a);return i})}else return this.assignTextureLOD(s.material,e)}if(t instanceof p.Material||t.isMaterial===!0){const s=t,o=[],r=new Array;if(x&&_e.add(s),s.uniforms&&(s.isRawShaderMaterial||s.isShaderMaterial===!0)){const i=s;for(const a of Object.keys(i.uniforms)){const l=i.uniforms[a].value;if((l==null?void 0:l.isTexture)===!0){const u=this.assignTextureLODForSlot(l,e,s,a).then(c=>(c&&i.uniforms[a].value!=c&&(i.uniforms[a].value=c,i.uniformsNeedUpdate=!0),c));o.push(u),r.push(a)}}}else for(const i of Object.keys(s)){const a=s[i];if((a==null?void 0:a.isTexture)===!0){const l=this.assignTextureLODForSlot(a,e,s,i);o.push(l),r.push(i)}}return Promise.all(o).then(i=>{const a=new Array;for(let l=0;l<i.length;l++){const u=i[l],c=r[l];u&&u.isTexture===!0?a.push({material:s,slot:c,texture:u,level:e}):a.push({material:s,slot:c,texture:null,level:e})}return a})}if(t instanceof p.Texture||t.isTexture===!0){const s=t;return this.assignTextureLODForSlot(s,e,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(t,e,s,o){return(t==null?void 0:t.isTexture)!==!0?Promise.resolve(null):o==="glyphMap"?Promise.resolve(t):_.getOrLoadLOD(t,e).then(r=>{if(Array.isArray(r))return null;if((r==null?void 0:r.isTexture)===!0){if(r!=t){if(s&&o){const i=s[o];if(i){const a=this.getAssignedLODInformation(i);if(a&&(a==null?void 0:a.level)<e)return x==="verbose"&&console.warn("Assigned texture level is already higher: ",a.level,e,s,i,r),null}s[o]=r}if(x&&o&&s){const i=this.getAssignedLODInformation(t);i&&Ce(s,o,i.url)}}return r}else x=="verbose"&&console.warn("No LOD found for",t,e);return null}).catch(r=>(console.error("Error loading LOD",t,r),null))}afterRoot(t){var e,s;return x&&console.log("AFTER",this.url,t),(e=this.parser.json.textures)==null||e.forEach((o,r)=>{var i;if(o!=null&&o.extensions){const a=o==null?void 0:o.extensions[U];if(a){if(!a.lods){x&&console.warn("Texture has no LODs",a);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)===r&&(l=!0,_.registerTexture(this.url,u,(i=a.lods)==null?void 0:i.length,r,a))}l||this.parser.getDependency("texture",r).then(u=>{var c;u&&_.registerTexture(this.url,u,(c=a.lods)==null?void 0:c.length,r,a)})}}}),(s=this.parser.json.meshes)==null||s.forEach((o,r)=>{if(o!=null&&o.extensions){const i=o==null?void 0:o.extensions[U];if(i&&i.lods){for(const a of this.parser.associations.keys())if(a.isMesh){const l=this.parser.associations.get(a);(l==null?void 0:l.meshes)===r&&_.registerMesh(this.url,i.guid,a,i.lods.length,l.primitives,i)}}}}),null}static async getOrLoadLOD(t,e){var a,l,u,c;const s=x=="verbose",o=t.userData.LODS;if(!o)return null;const r=o==null?void 0:o.key;let i;if(t.isTexture===!0){const g=t;g.source&&g.source[Le]&&(i=g.source[Le])}if(i||(i=_.lodInfos.get(r)),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(r)}const g=Array.isArray(i.lods)?(a=i.lods[e])==null?void 0:a.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){s&&console.log(`LOD ${e} was already loading/loaded: ${D}`);let h=await v.catch($=>(console.error(`Error loading LOD ${e} from ${y}
2
+ `,$),null)),I=!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):(I=!0,this.previouslyLoaded.delete(D)):h instanceof p.BufferGeometry&&t instanceof p.BufferGeometry&&((c=h.attributes.position)!=null&&c.array||(I=!0,this.previouslyLoaded.delete(D)))),!I)return h}const M=i,V=new Promise(async(h,I)=>{const $=new Oe.GLTFLoader;Te($),x&&(await new Promise(E=>setTimeout(E,1e3)),s&&console.warn("Start loading (delayed) "+y,M.guid));let R=y;if(M&&Array.isArray(M.lods)){const E=M.lods[e];E.hash&&(R+="?v="+E.hash)}const b=await $.loadAsync(R).catch(E=>(console.error(`Error loading LOD ${e} from ${y}
3
+ `,E),null));if(!b)return null;const q=b.parser;s&&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,r,e,void 0,void 0),s&&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(s&&console.log(`Loaded Mesh "${f.name}"`,y,A,f,D),f.isMesh===!0){const S=f.geometry;return _.assignLODInformation(o.url,S,r,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,r,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,V),await V}else if(t instanceof p.Texture){s&&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,s&&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 "${r}" ${t.name}`,t.type);return null}static assignLODInformation(t,e,s,o,r,i){if(!e)return;e.userData||(e.userData={});const a=new tt(t,s,o,r,i);e.userData.LODS=a}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,s,o,r)=>{if(x&&console.log("> Progressive: register texture",o,e.name,e.uuid,e,r),!e){x&&console.error("gltf-progressive: Register texture without texture");return}e.source&&(e.source[Le]=r);const i=r.guid;_.assignLODInformation(t,e,i,s,o,void 0),_.lodInfos.set(i,r),_.lowresCache.set(i,e)}),d(O,"registerMesh",(t,e,s,o,r,i)=>{var u;x&&console.log("> Progressive: register mesh",r,s.name,i,s.uuid,s);const a=s.geometry;if(!a){x&&console.warn("gltf-progressive: Register mesh without geometry");return}a.userData||(a.userData={}),_.assignLODInformation(t,a,e,o,r,i.density),_.lodInfos.set(e,i);let l=_.lowresCache.get(e);l?l.push(s.geometry):l=[s.geometry],_.lowresCache.set(e,l),o>0&&!ae(s)&&Re(s,a);for(const c of Y)(u=c.onRegisteredNewMesh)==null||u.call(c,s,i)}),d(O,"lodInfos",new Map),d(O,"previouslyLoaded",new Map),d(O,"lowresCache",new Map);class Ze{constructor(t,e,s,o,r){d(this,"url");d(this,"key");d(this,"level");d(this,"index");d(this,"density");this.url=t,this.key=e,this.level=s,o!=null&&(this.index=o),r!=null&&(this.density=r)}}const G=ne("debugprogressive"),et=ne("noprogressive"),xe=Symbol("Needle:LODSManager"),Me=Symbol("Needle:LODState"),H=Symbol("Needle:CurrentLOD"),F={mesh_lod:-1,texture_lod:-1};var B,z,he,Z,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,Z,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[Me]}static addPlugin(t){Y.push(t)}static removePlugin(t){const e=Y.indexOf(t);e>=0&&Y.splice(e,1)}static get(t,e){if(t[xe])return console.debug("[gltf-progressive] LODsManager already exists for this renderer"),t[xe];const s=new C(t,{engine:"unknown",...e});return t[xe]=s,s}get plugins(){return Y}addEventListener(t,e){t==="changed"&&this._lodchangedlisteners.push(e)}removeEventListener(t,e){if(t==="changed"){const s=this._lodchangedlisteners.indexOf(e);s>=0&&this._lodchangedlisteners.splice(s,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;Se(this.renderer),this.renderer.render=function(s,o){const r=e.renderer.getRenderTarget();(r==null||"isXRRenderTarget"in r&&r.isXRRenderTarget)&&(t=0,N(e,Z,L(e,Z)+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((a,l)=>a+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,s,o),e.onAfterRender(s,o,i)}}disable(){L(this,z)&&(console.debug("[gltf-progressive] Disabling LODsManager for renderer"),this.renderer.render=L(this,z),N(this,z,void 0))}update(t,e){this.internalUpdate(t,e)}onAfterRender(t,e,s){if(this.pause)return;const r=this.renderer.renderLists.get(t,0).opaque;let i=!0;if(r.length===1){const a=r[0].material;(a.name==="EffectMaterial"||a.name==="CopyShader")&&(i=!1)}if((e.parent&&e.parent.type==="CubeCamera"||s>=1&&e.type==="OrthographicCamera")&&(i=!1),i){if(et||(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 s=this.renderer.renderLists.get(t,0),o=s.opaque;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse);const r=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,r)}const i=s.transparent;for(const c of i){const g=c.object;(g instanceof p.Mesh||g.isMesh)&&this.updateLODs(t,e,g,r)}const a=s.transmissive;for(const c of a){const g=c.object;(g instanceof p.Mesh||g.isMesh)&&this.updateLODs(t,e,g,r)}}updateLODs(t,e,s,o){var a,l;s.userData||(s.userData={});let r=s[Me];if(r||(r=new tt,s[Me]=r),r.frames++<2)return;for(const u of Y)(a=u.onBeforeUpdateLOD)==null||a.call(u,this.renderer,t,e,s);this.calculateLodLevel(e,s,r,o,F),F.mesh_lod=Math.round(F.mesh_lod),F.texture_lod=Math.round(F.texture_lod),F.mesh_lod>=0&&this.loadProgressiveMeshes(s,F.mesh_lod);let i=F.texture_lod;if(s.material&&i>=0){const u=s["DEBUG:LOD"];u!=null&&(i=u),this.loadProgressiveTextures(s.material,i)}for(const u of Y)(l=u.onAfterUpdatedLOD)==null||l.call(u,this.renderer,t,e,s,F);r.lastLodLevel_Mesh=F.mesh_lod,r.lastLodLevel_Texture=F.texture_lod}loadProgressiveTextures(t,e){if(!t)return;if(Array.isArray(t)){for(const o of t)this.loadProgressiveTextures(o,e);return}let s=!1;(t[H]===void 0||e<t[H])&&(s=!0),s&&(t[H]=e,O.assignTextureLOD(t,e).then(o=>{this._lodchangedlisteners.forEach(r=>r({type:"texture",level:e,object:t}))}))}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);if(t[H]!==e){t[H]=e;const s=t.geometry;return O.assignMeshLOD(t,e).then(o=>(o&&t[H]==e&&s!=t.geometry&&this._lodchangedlisteners.forEach(r=>r({type:"mesh",level:e,object:t})),o))}return Promise.resolve(null)}static isInside(t,e){const s=t.min,o=t.max,r=(s.x+o.x)*.5,i=(s.y+o.y)*.5;return this._tempPtInside.set(r,i,s.z).applyMatrix4(e).z<0}calculateLodLevel(t,e,s,o,r){var V;if(!e){r.mesh_lod=-1,r.texture_lod=-1;return}if(!t){r.mesh_lod=-1,r.texture_lod=-1;return}let a=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){r.mesh_lod=0,r.texture_lod=0;return}g||(l=!0,a=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(s.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)){r.mesh_lod=0,r.texture_lod=0;return}}if(this._tempBox.copy(M),this._tempBox.applyMatrix4(e.matrixWorld),C.isInside(this._tempBox,this.projectionScreenMatrix)){r.mesh_lod=0,r.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 Ge=S<0&&P>0?0:Math.min(Math.abs(f.x),Math.abs(m.x)),Fe=T<0&&X>0?0:Math.min(Math.abs(f.y),Math.abs(m.y)),ye=Math.max(Ge,Fe);s.lastCentrality=(pe-ye)*(pe-ye)*(pe-ye)}else s.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)),s.lastScreenCoverage=Math.max(h.x,h.y,h.z),s.lastScreenspaceVolume.copy(h),s.lastScreenCoverage*=s.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&&s.lastScreenCoverage>0){for(let f=0;f<c.length;f++)if(c[f].density/s.lastScreenCoverage<o){A=f;break}}A<a&&(a=A,l=!0)}if(l?r.mesh_lod=a:r.mesh_lod=s.lastLodLevel_Mesh,G&&r.mesh_lod!=s.lastLodLevel_Mesh){const h=c==null?void 0:c[r.mesh_lod];h&&console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} → ${r.mesh_lod} (${h.density.toFixed(0)}) - ${e.name}`)}if(D){const w="saveData"in globalThis.navigator&&globalThis.navigator.saveData===!0;if(s.lastLodLevel_Texture<0){if(r.texture_lod=y.max_count-1,G){const h=y.lods[y.max_count-1];G&&console.log(`First Texture LOD ${r.texture_lod} (${h.max_height}px) - ${e.name}`)}}else{const h=s.lastScreenspaceVolume.x+s.lastScreenspaceVolume.y+s.lastScreenspaceVolume.z;let R=s.lastScreenCoverage*4;((V=this.context)==null?void 0:V.engine)==="model-viewer"&&(R*=1.5);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)&&!(je()&&q.max_height>4096)&&q.max_height>k){if(r.texture_lod=b,r.texture_lod<s.lastLodLevel_Texture){const A=q.max_height;G&&console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${r.texture_lod} = ${A}px
6
- Screensize: ${k.toFixed(0)}px, Coverage: ${(100*s.lastScreenCoverage).toFixed(2)}%, Volume ${h.toFixed(1)}
7
- ${e.name}`)}break}}}}else r.texture_lod=0}};let I=C;B=new WeakMap,z=new WeakMap,he=new WeakMap,Z=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 tt{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 Pe=Symbol("NEEDLE_mesh_lod"),fe=Symbol("NEEDLE_texture_lod");let re=null;function Te(){const n=st();n&&(n.mapURLs(function(t){return Ce(),t}),Ce(),re==null||re.disconnect(),re=new MutationObserver(t=>{t.forEach(e=>{e.addedNodes.forEach(s=>{s instanceof HTMLElement&&s.tagName.toLowerCase()==="model-viewer"&&ke(s)})})}),re.observe(document,{childList:!0,subtree:!0}))}function st(){if(typeof customElements>"u")return null;const n=customElements.get("model-viewer");return n||(customElements.whenDefined("model-viewer").then(()=>{console.debug("[gltf-progressive] model-viewer defined"),Te()}),null)}function Ce(){if(typeof document>"u")return;document.querySelectorAll("model-viewer").forEach(t=>{ke(t)})}const Be=new WeakSet;let rt=0;function ke(n){if(!n||Be.has(n))return null;Be.add(n),console.debug("[gltf-progressive] found new model-viewer..."+ ++rt+`
8
- `,n.getAttribute("src"));let t=null,e=null,s=null;for(let o=n;o!=null;o=Object.getPrototypeOf(o)){const r=Object.getOwnPropertySymbols(o),i=r.find(u=>u.toString()=="Symbol(renderer)"),a=r.find(u=>u.toString()=="Symbol(scene)"),l=r.find(u=>u.toString()=="Symbol(needsRender)");!t&&i!=null&&(t=n[i].threeRenderer),!e&&a!=null&&(e=n[a]),!s&&l!=null&&(s=n[l])}if(t&&e){let o=function(){if(s){let i=0,a=setInterval(()=>{if(i++>5){clearInterval(a);return}s==null||s.call(n)},300)}};console.debug("[gltf-progressive] setup model-viewer");const r=I.get(t,{engine:"model-viewer"});return I.addPlugin(new it),r.enable(),r.addEventListener("changed",()=>{s==null||s.call(n)}),n.addEventListener("model-visibility",i=>{i.detail.visible&&(s==null||s.call(n))}),n.addEventListener("load",()=>{o()}),()=>{r.disable()}}return null}class it{constructor(){d(this,"_didWarnAboutMissingUrl",!1)}onBeforeUpdateLOD(t,e,s,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 s=this.tryGetCurrentGLTF(t),o=this.tryGetCurrentModelViewer(t),r=this.getUrl(o);if(r&&s&&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 V=(g=(c=M.userData)==null?void 0:c.associations)==null?void 0:g.textures;if(V==null)continue;const w=s.parser.json.textures[V];if(!w){console.warn("Texture data not found for texture index "+V);continue}if((y=w==null?void 0:w.extensions)!=null&&y[U]){const h=w.extensions[U];h&&r&&O.registerTexture(r,M,h.lods.length,V,h)}}}};const a=e.material;if(Array.isArray(a))for(const l of a)i(l);else i(a)}}tryParseMeshLOD(t,e){var i,a;if(e[Pe]==!0)return;e[Pe]=!0;const s=this.tryGetCurrentModelViewer(t),o=this.getUrl(s);if(!o)return;const r=(a=(i=e.userData)==null?void 0:i.gltfExtensions)==null?void 0:a[U];if(r&&o){const l=e.uuid;O.registerMesh(o,l,e,0,r.lods.length,r)}}}function ot(n,t,e,s){Se(t),be(e),Ie(e,{progressive:!0,...s==null?void 0:s.hints}),e.register(r=>new O(r,n));const o=I.get(t);return(s==null?void 0:s.enableLODsManager)!==!1&&o.enable(),o}Te();exports.EXTENSION_NAME=U;exports.LODsManager=I;exports.NEEDLE_progressive=O;exports.VERSION=Oe;exports.addDracoAndKTX2Loaders=be;exports.configureLoader=Ie;exports.createLoaders=Se;exports.getRaycastMesh=ae;exports.patchModelViewer=Te;exports.registerRaycastMesh=Re;exports.setDracoDecoderLocation=Xe;exports.setKTX2TranscoderLocation=Ke;exports.useNeedleProgressive=ot;exports.useRaycastMeshes=Je;
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,s,o,r)=>{if(x&&console.log("> Progressive: register texture",o,e.name,e.uuid,e,r),!e){x&&console.error("gltf-progressive: Register texture without texture");return}e.source&&(e.source[Le]=r);const i=r.guid;_.assignLODInformation(t,e,i,s,o,void 0),_.lodInfos.set(i,r),_.lowresCache.set(i,e)}),d(O,"registerMesh",(t,e,s,o,r,i)=>{var u;x&&console.log("> Progressive: register mesh",r,s.name,i,s.uuid,s);const a=s.geometry;if(!a){x&&console.warn("gltf-progressive: Register mesh without geometry");return}a.userData||(a.userData={}),_.assignLODInformation(t,a,e,o,r,i.density),_.lodInfos.set(e,i);let l=_.lowresCache.get(e);l?l.push(s.geometry):l=[s.geometry],_.lowresCache.set(e,l),o>0&&!te(s)&&Re(s,a);for(const c of Y)(u=c.onRegisteredNewMesh)==null||u.call(c,s,i)}),d(O,"lodInfos",new Map),d(O,"previouslyLoaded",new Map),d(O,"lowresCache",new Map);class tt{constructor(t,e,s,o,r){d(this,"url");d(this,"key");d(this,"level");d(this,"index");d(this,"density");this.url=t,this.key=e,this.level=s,o!=null&&(this.index=o),r!=null&&(this.density=r)}}const G=ae("debugprogressive"),st=ae("noprogressive"),xe=Symbol("Needle:LODSManager"),Me=Symbol("Needle:LODState"),H=Symbol("Needle:CurrentLOD"),F={mesh_lod:-1,texture_lod:-1};var B,z,he,Z,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,Z,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[Me]}static addPlugin(t){Y.push(t)}static removePlugin(t){const e=Y.indexOf(t);e>=0&&Y.splice(e,1)}static get(t,e){if(t[xe])return console.debug("[gltf-progressive] LODsManager already exists for this renderer"),t[xe];const s=new C(t,{engine:"unknown",...e});return t[xe]=s,s}get plugins(){return Y}addEventListener(t,e){t==="changed"&&this._lodchangedlisteners.push(e)}removeEventListener(t,e){if(t==="changed"){const s=this._lodchangedlisteners.indexOf(e);s>=0&&this._lodchangedlisteners.splice(s,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;be(this.renderer),this.renderer.render=function(s,o){const r=e.renderer.getRenderTarget();(r==null||"isXRRenderTarget"in r&&r.isXRRenderTarget)&&(t=0,N(e,Z,L(e,Z)+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((a,l)=>a+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,s,o),e.onAfterRender(s,o,i)}}disable(){L(this,z)&&(console.debug("[gltf-progressive] Disabling LODsManager for renderer"),this.renderer.render=L(this,z),N(this,z,void 0))}update(t,e){this.internalUpdate(t,e)}onAfterRender(t,e,s){if(this.pause)return;const r=this.renderer.renderLists.get(t,0).opaque;let i=!0;if(r.length===1){const a=r[0].material;(a.name==="EffectMaterial"||a.name==="CopyShader")&&(i=!1)}if((e.parent&&e.parent.type==="CubeCamera"||s>=1&&e.type==="OrthographicCamera")&&(i=!1),i){if(st||(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 s=this.renderer.renderLists.get(t,0),o=s.opaque;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse);const r=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,r)}const i=s.transparent;for(const c of i){const g=c.object;(g instanceof p.Mesh||g.isMesh)&&this.updateLODs(t,e,g,r)}const a=s.transmissive;for(const c of a){const g=c.object;(g instanceof p.Mesh||g.isMesh)&&this.updateLODs(t,e,g,r)}}updateLODs(t,e,s,o){var a,l;s.userData||(s.userData={});let r=s[Me];if(r||(r=new rt,s[Me]=r),r.frames++<2)return;for(const u of Y)(a=u.onBeforeUpdateLOD)==null||a.call(u,this.renderer,t,e,s);this.calculateLodLevel(e,s,r,o,F),F.mesh_lod=Math.round(F.mesh_lod),F.texture_lod=Math.round(F.texture_lod),F.mesh_lod>=0&&this.loadProgressiveMeshes(s,F.mesh_lod);let i=F.texture_lod;if(s.material&&i>=0){const u=s["DEBUG:LOD"];u!=null&&(i=u),this.loadProgressiveTextures(s.material,i)}for(const u of Y)(l=u.onAfterUpdatedLOD)==null||l.call(u,this.renderer,t,e,s,F);r.lastLodLevel_Mesh=F.mesh_lod,r.lastLodLevel_Texture=F.texture_lod}loadProgressiveTextures(t,e){if(!t)return;if(Array.isArray(t)){for(const o of t)this.loadProgressiveTextures(o,e);return}let s=!1;(t[H]===void 0||e<t[H])&&(s=!0),s&&(t[H]=e,O.assignTextureLOD(t,e).then(o=>{this._lodchangedlisteners.forEach(r=>r({type:"texture",level:e,object:t}))}))}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);if(t[H]!==e){t[H]=e;const s=t.geometry;return O.assignMeshLOD(t,e).then(o=>(o&&t[H]==e&&s!=t.geometry&&this._lodchangedlisteners.forEach(r=>r({type:"mesh",level:e,object:t})),o))}return Promise.resolve(null)}static isInside(t,e){const s=t.min,o=t.max,r=(s.x+o.x)*.5,i=(s.y+o.y)*.5;return this._tempPtInside.set(r,i,s.z).applyMatrix4(e).z<0}calculateLodLevel(t,e,s,o,r){var V;if(!e){r.mesh_lod=-1,r.texture_lod=-1;return}if(!t){r.mesh_lod=-1,r.texture_lod=-1;return}let a=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){r.mesh_lod=0,r.texture_lod=0;return}g||(l=!0,a=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(s.frames%30===0){const h=te(w),I=w.geometry;h&&(w.geometry=h),w.computeBoundingBox(),w.geometry=I}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)){r.mesh_lod=0,r.texture_lod=0;return}}if(this._tempBox.copy(M),this._tempBox.applyMatrix4(e.matrixWorld),C.isInside(this._tempBox,this.projectionScreenMatrix)){r.mesh_lod=0,r.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 $e=S<0&&P>0?0:Math.min(Math.abs(f.x),Math.abs(m.x)),Ne=T<0&&X>0?0:Math.min(Math.abs(f.y),Math.abs(m.y)),ye=Math.max($e,Ne);s.lastCentrality=(pe-ye)*(pe-ye)*(pe-ye)}else s.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 I=t.matrixWorldInverse,$=this._tempBox2;$.copy(M),$.applyMatrix4(e.matrixWorld),$.applyMatrix4(I);const R=$.getSize(this._tempBox2Size),b=Math.max(R.x,R.y);if(Math.max(h.x,h.y)!=0&&b!=0&&(h.z=R.z/Math.max(R.x,R.y)*Math.max(h.x,h.y)),s.lastScreenCoverage=Math.max(h.x,h.y,h.z),s.lastScreenspaceVolume.copy(h),s.lastScreenCoverage*=s.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&&s.lastScreenCoverage>0){for(let f=0;f<c.length;f++)if(c[f].density/s.lastScreenCoverage<o){A=f;break}}A<a&&(a=A,l=!0)}if(l?r.mesh_lod=a:r.mesh_lod=s.lastLodLevel_Mesh,G&&r.mesh_lod!=s.lastLodLevel_Mesh){const h=c==null?void 0:c[r.mesh_lod];h&&console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} → ${r.mesh_lod} (${h.density.toFixed(0)}) - ${e.name}`)}if(D){const w="saveData"in globalThis.navigator&&globalThis.navigator.saveData===!0;if(s.lastLodLevel_Texture<0){if(r.texture_lod=y.max_count-1,G){const h=y.lods[y.max_count-1];G&&console.log(`First Texture LOD ${r.texture_lod} (${h.max_height}px) - ${e.name}`)}}else{const h=s.lastScreenspaceVolume.x+s.lastScreenspaceVolume.y+s.lastScreenspaceVolume.z;let I=s.lastScreenCoverage*4;((V=this.context)==null?void 0:V.engine)==="model-viewer"&&(I*=1.5);const R=v/window.devicePixelRatio*I;for(let b=y.lods.length-1;b>=0;b--){let q=y.lods[b];if(!(w&&q.max_height>=2048)&&!(Ze()&&q.max_height>4096)&&q.max_height>R){if(r.texture_lod=b,r.texture_lod<s.lastLodLevel_Texture){const A=q.max_height;G&&console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${r.texture_lod} = ${A}px
6
+ Screensize: ${R.toFixed(0)}px, Coverage: ${(100*s.lastScreenCoverage).toFixed(2)}%, Volume ${h.toFixed(1)}
7
+ ${e.name}`)}break}}}}else r.texture_lod=0}};let k=C;B=new WeakMap,z=new WeakMap,he=new WeakMap,Z=new WeakMap,ee=new WeakMap,ge=new WeakMap,W=new WeakMap,d(k,"debugDrawLine"),d(k,"corner0",new p.Vector3),d(k,"corner1",new p.Vector3),d(k,"corner2",new p.Vector3),d(k,"corner3",new p.Vector3),d(k,"_tempPtInside",new p.Vector3);class rt{constructor(){d(this,"frames",0);d(this,"lastLodLevel_Mesh",-1);d(this,"lastLodLevel_Texture",-1);d(this,"lastScreenCoverage",0);d(this,"lastScreenspaceVolume",new p.Vector3);d(this,"lastCentrality",0)}}const Be=Symbol("NEEDLE_mesh_lod"),fe=Symbol("NEEDLE_texture_lod");let ie=null;function Ee(){const n=it();n&&(n.mapURLs(function(t){return ke(),t}),ke(),ie==null||ie.disconnect(),ie=new MutationObserver(t=>{t.forEach(e=>{e.addedNodes.forEach(s=>{s instanceof HTMLElement&&s.tagName.toLowerCase()==="model-viewer"&&Fe(s)})})}),ie.observe(document,{childList:!0,subtree:!0}))}function it(){if(typeof customElements>"u")return null;const n=customElements.get("model-viewer");return n||(customElements.whenDefined("model-viewer").then(()=>{console.debug("[gltf-progressive] model-viewer defined"),Ee()}),null)}function ke(){if(typeof document>"u")return;document.querySelectorAll("model-viewer").forEach(t=>{Fe(t)})}const Ie=new WeakSet;let ot=0;function Fe(n){if(!n||Ie.has(n))return null;Ie.add(n),console.debug("[gltf-progressive] found new model-viewer..."+ ++ot+`
8
+ `,n.getAttribute("src"));let t=null,e=null,s=null;for(let o=n;o!=null;o=Object.getPrototypeOf(o)){const r=Object.getOwnPropertySymbols(o),i=r.find(u=>u.toString()=="Symbol(renderer)"),a=r.find(u=>u.toString()=="Symbol(scene)"),l=r.find(u=>u.toString()=="Symbol(needsRender)");!t&&i!=null&&(t=n[i].threeRenderer),!e&&a!=null&&(e=n[a]),!s&&l!=null&&(s=n[l])}if(t&&e){let o=function(){if(s){let i=0,a=setInterval(()=>{if(i++>5){clearInterval(a);return}s==null||s.call(n)},300)}};console.debug("[gltf-progressive] setup model-viewer");const r=k.get(t,{engine:"model-viewer"});return k.addPlugin(new nt),r.enable(),r.addEventListener("changed",()=>{s==null||s.call(n)}),n.addEventListener("model-visibility",i=>{i.detail.visible&&(s==null||s.call(n))}),n.addEventListener("load",()=>{o()}),()=>{r.disable()}}return null}class nt{constructor(){d(this,"_didWarnAboutMissingUrl",!1)}onBeforeUpdateLOD(t,e,s,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 s=this.tryGetCurrentGLTF(t),o=this.tryGetCurrentModelViewer(t),r=this.getUrl(o);if(r&&s&&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 V=(g=(c=M.userData)==null?void 0:c.associations)==null?void 0:g.textures;if(V==null)continue;const w=s.parser.json.textures[V];if(!w){console.warn("Texture data not found for texture index "+V);continue}if((y=w==null?void 0:w.extensions)!=null&&y[U]){const h=w.extensions[U];h&&r&&O.registerTexture(r,M,h.lods.length,V,h)}}}};const a=e.material;if(Array.isArray(a))for(const l of a)i(l);else i(a)}}tryParseMeshLOD(t,e){var i,a;if(e[Be]==!0)return;e[Be]=!0;const s=this.tryGetCurrentModelViewer(t),o=this.getUrl(s);if(!o)return;const r=(a=(i=e.userData)==null?void 0:i.gltfExtensions)==null?void 0:a[U];if(r&&o){const l=e.uuid;O.registerMesh(o,l,e,0,r.lods.length,r)}}}function Ve(n,t,e,s){be(t),Te(e),Ae(e,{progressive:!0,...s==null?void 0:s.hints}),e.register(r=>new O(r,n));const o=k.get(t);return(s==null?void 0:s.enableLODsManager)!==!1&&o.enable(),o}Ee();const De={gltfProgressive:{useNeedleProgressive:Ve,LODsManager:k,configureLoader:Ae,getRaycastMesh:te,useRaycastMeshes:Ge}};if(!globalThis.Needle)globalThis.Needle=De;else for(const n in De)globalThis.Needle[n]=De[n];exports.EXTENSION_NAME=U;exports.LODsManager=k;exports.NEEDLE_progressive=O;exports.VERSION=Se;exports.addDracoAndKTX2Loaders=Te;exports.configureLoader=Ae;exports.createLoaders=be;exports.getRaycastMesh=te;exports.patchModelViewer=Ee;exports.registerRaycastMesh=Re;exports.setDracoDecoderLocation=He;exports.setKTX2TranscoderLocation=je;exports.useNeedleProgressive=Ve;exports.useRaycastMeshes=Ge;
package/lib/index.js CHANGED
@@ -39,3 +39,21 @@ export function useNeedleProgressive(url, renderer, loader, opts) {
39
39
  /** Modelviewer */
40
40
  import { patchModelViewer } from "./plugins/modelviewer.js";
41
41
  patchModelViewer();
42
+ import { getRaycastMesh, useRaycastMeshes } from "./utils.js";
43
+ const global = {
44
+ gltfProgressive: {
45
+ useNeedleProgressive,
46
+ LODsManager,
47
+ configureLoader,
48
+ getRaycastMesh,
49
+ useRaycastMeshes,
50
+ }
51
+ };
52
+ if (!globalThis["Needle"]) {
53
+ globalThis["Needle"] = global;
54
+ }
55
+ else {
56
+ for (const key in global) {
57
+ globalThis["Needle"][key] = global[key];
58
+ }
59
+ }
package/lib/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  // replaced at build time
2
- export const version = "2.1.0-alpha.1";
2
+ export const version = "2.1.0-alpha.2";
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": "2.1.0-alpha.1",
3
+ "version": "2.1.0-alpha.2",
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": {