@needle-tools/gltf-progressive 1.2.0-alpha.5 → 1.2.0-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,9 @@ All notable changes to this package will be documented in this file.
4
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [1.2.0-alpha.6] - 2023-06-12
8
+ - fix: minor bug where opened glTF has `NEEDLE_progressive` extension but no lods array because the glTF is a LOD variant
9
+
7
10
  ## [1.2.0-alpha.5] - 2023-06-10
8
11
  - fix: safeguard when `registerMesh` or `registerTexture` are being called with invalid data
9
12
  - examples: update vanilla threejs example
package/README.md CHANGED
@@ -15,6 +15,7 @@ Examples are in the `/examples` directory. Live versions can be found in the lin
15
15
  - [Vanilla three.js](https://engine.needle.tools/demos/gltf-progressive/threejs/) - multiple models and animations
16
16
  - [\<model-viewer\>](https://engine.needle.tools/demos/gltf-progressive/modelviewer)
17
17
  - [React Three Fiber](https://engine.needle.tools/demos/gltf-progressive/r3f/)
18
+ - [Needle Engine](https://stackblitz.com/edit/needle-engine-gltf-progressive?file=src%2Fmain.ts) - Interactive Example on StackBlitz
18
19
 
19
20
 
20
21
  <br/>
@@ -105,6 +106,10 @@ The example can be found in `examples/modelviewer.html`
105
106
  </body>
106
107
  ```
107
108
 
109
+ ### Needle Engine
110
+
111
+ [Needle Engine](https://needle.tools) natively supports progressive loading of these glTF files! See [docs.needle.tools](https://docs.needle.tools) for more information.
112
+
108
113
 
109
114
  # Contact ✒️
110
115
  <b>[🌵 needle — tools for creators](https://needle.tools)</b> •
@@ -59,9 +59,9 @@ function Ke(l = !0) {
59
59
  return;
60
60
  const e = K = F.prototype.raycast;
61
61
  F.prototype.raycast = function(t, r) {
62
- const s = this, n = ae(s);
63
- let i;
64
- n && s.isMesh && (i = s.geometry, s.geometry = n), e.call(this, t, r), i && (s.geometry = i);
62
+ const i = this, n = ae(i);
63
+ let s;
64
+ n && i.isMesh && (s = i.geometry, i.geometry = n), e.call(this, t, r), s && (i.geometry = s);
65
65
  };
66
66
  } else {
67
67
  if (!K)
@@ -76,12 +76,12 @@ function Pe(l) {
76
76
  e.setAttribute(t, l.getAttribute(t));
77
77
  return e.setIndex(l.getIndex()), e;
78
78
  }
79
- const I = new Array(), B = "NEEDLE_progressive", O = j("debugprogressive"), se = Symbol("needle-progressive-texture"), V = /* @__PURE__ */ new Map(), ne = /* @__PURE__ */ new Set();
80
- if (O) {
79
+ const I = new Array(), B = "NEEDLE_progressive", D = j("debugprogressive"), se = Symbol("needle-progressive-texture"), V = /* @__PURE__ */ new Map(), ne = /* @__PURE__ */ new Set();
80
+ if (D) {
81
81
  let l = function() {
82
- e += 1, console.log("Toggle LOD level", e, V), V.forEach((s, n) => {
83
- for (const i of s.keys) {
84
- const o = n[i];
82
+ e += 1, console.log("Toggle LOD level", e, V), V.forEach((i, n) => {
83
+ for (const s of i.keys) {
84
+ const o = n[s];
85
85
  if (o.isBufferGeometry === !0) {
86
86
  const a = v.getMeshLODInformation(o), h = a ? Math.min(e, a.lods.length) : 0;
87
87
  n["DEBUG:LOD"] = e, v.assignMeshLOD(n, h), a && (t = Math.max(t, a.lods.length - 1));
@@ -92,19 +92,19 @@ if (O) {
92
92
  }
93
93
  }), e >= t && (e = -1);
94
94
  }, e = -1, t = 2, r = !1;
95
- window.addEventListener("keyup", (s) => {
96
- s.key === "p" && l(), s.key === "w" && (r = !r, ne && ne.forEach((n) => {
95
+ window.addEventListener("keyup", (i) => {
96
+ i.key === "p" && l(), i.key === "w" && (r = !r, ne && ne.forEach((n) => {
97
97
  n.name != "BackgroundCubeMaterial" && "wireframe" in n && (n.wireframe = r);
98
98
  }));
99
99
  });
100
100
  }
101
101
  function ue(l, e, t) {
102
- var s;
103
- if (!O)
102
+ var i;
103
+ if (!D)
104
104
  return;
105
105
  V.has(l) || V.set(l, { keys: [], sourceId: t });
106
106
  const r = V.get(l);
107
- ((s = r == null ? void 0 : r.keys) == null ? void 0 : s.includes(e)) == !1 && r.keys.push(e);
107
+ ((i = r == null ? void 0 : r.keys) == null ? void 0 : i.includes(e)) == !1 && r.keys.push(e);
108
108
  }
109
109
  const _ = class {
110
110
  constructor(e, t) {
@@ -112,13 +112,13 @@ const _ = class {
112
112
  c(this, "url");
113
113
  c(this, "_isLoadingMesh");
114
114
  c(this, "loadMesh", (e) => {
115
- var r, s;
115
+ var r, i;
116
116
  if (this._isLoadingMesh)
117
117
  return null;
118
- const t = (s = (r = this.parser.json.meshes[e]) == null ? void 0 : r.extensions) == null ? void 0 : s[B];
118
+ const t = (i = (r = this.parser.json.meshes[e]) == null ? void 0 : r.extensions) == null ? void 0 : i[B];
119
119
  return t ? (this._isLoadingMesh = !0, this.parser.getDependency("mesh", e).then((n) => (this._isLoadingMesh = !1, n && _.registerMesh(this.url, t.guid, n, t.lods.length, void 0, t), n))) : null;
120
120
  });
121
- O && console.log("Progressive extension registered for", t), this.parser = e, this.url = t;
121
+ D && console.log("Progressive extension registered for", t), this.parser = e, this.url = t;
122
122
  }
123
123
  /** The name of the extension */
124
124
  get name() {
@@ -129,7 +129,7 @@ const _ = class {
129
129
  return t != null && t.key ? this.lodInfos.get(t.key) : null;
130
130
  }
131
131
  static getMaterialMinMaxLODsCount(e, t) {
132
- const r = this, s = "LODS:minmax", n = e[s];
132
+ const r = this, i = "LODS:minmax", n = e[i];
133
133
  if (n != null)
134
134
  return n;
135
135
  if (t || (t = {
@@ -139,21 +139,21 @@ const _ = class {
139
139
  }), Array.isArray(e)) {
140
140
  for (const o of e)
141
141
  this.getMaterialMinMaxLODsCount(o, t);
142
- return e[s] = t, t;
142
+ return e[i] = t, t;
143
143
  }
144
- if (O === "verbose" && console.log("getMaterialMinMaxLODsCount", e), e.type === "ShaderMaterial" || e.type === "RawShaderMaterial") {
144
+ if (D === "verbose" && console.log("getMaterialMinMaxLODsCount", e), e.type === "ShaderMaterial" || e.type === "RawShaderMaterial") {
145
145
  const o = e;
146
146
  for (const a of Object.keys(o.uniforms)) {
147
147
  const h = o.uniforms[a].value;
148
- (h == null ? void 0 : h.isTexture) === !0 && i(h, t);
148
+ (h == null ? void 0 : h.isTexture) === !0 && s(h, t);
149
149
  }
150
150
  } else if (e.isMaterial)
151
151
  for (const o of Object.keys(e)) {
152
152
  const a = e[o];
153
- (a == null ? void 0 : a.isTexture) === !0 && i(a, t);
153
+ (a == null ? void 0 : a.isTexture) === !0 && s(a, t);
154
154
  }
155
- return e[s] = t, t;
156
- function i(o, a) {
155
+ return e[i] = t, t;
156
+ function s(o, a) {
157
157
  const h = r.getAssignedLODInformation(o);
158
158
  if (h) {
159
159
  const d = r.lodInfos.get(h.key);
@@ -175,30 +175,30 @@ const _ = class {
175
175
  static hasLODLevelAvailable(e, t) {
176
176
  var n;
177
177
  if (Array.isArray(e)) {
178
- for (const i of e)
179
- if (this.hasLODLevelAvailable(i, t))
178
+ for (const s of e)
179
+ if (this.hasLODLevelAvailable(s, t))
180
180
  return !0;
181
181
  return !1;
182
182
  }
183
183
  if (e.isMaterial === !0) {
184
- for (const i of Object.keys(e)) {
185
- const o = e[i];
184
+ for (const s of Object.keys(e)) {
185
+ const o = e[s];
186
186
  if (o && o.isTexture && this.hasLODLevelAvailable(o, t))
187
187
  return !0;
188
188
  }
189
189
  return !1;
190
190
  } else if (e.isGroup === !0) {
191
- for (const i of e.children)
192
- if (i.isMesh === !0 && this.hasLODLevelAvailable(i, t))
191
+ for (const s of e.children)
192
+ if (s.isMesh === !0 && this.hasLODLevelAvailable(s, t))
193
193
  return !0;
194
194
  }
195
- let r, s;
195
+ let r, i;
196
196
  if (e.isMesh ? r = e.geometry : (e.isBufferGeometry || e.isTexture) && (r = e), r && (n = r == null ? void 0 : r.userData) != null && n.LODS) {
197
- const i = r.userData.LODS;
198
- if (s = this.lodInfos.get(i.key), t === void 0)
199
- return s != null;
200
- if (s)
201
- return Array.isArray(s.lods) ? t < s.lods.length : t === 0;
197
+ const s = r.userData.LODS;
198
+ if (i = this.lodInfos.get(s.key), t === void 0)
199
+ return i != null;
200
+ if (i)
201
+ return Array.isArray(i.lods) ? t < i.lods.length : t === 0;
202
202
  }
203
203
  return !1;
204
204
  }
@@ -221,23 +221,23 @@ const _ = class {
221
221
  if (!e)
222
222
  return Promise.resolve(null);
223
223
  if (e instanceof F || e.isMesh === !0) {
224
- const s = e.geometry, n = this.getAssignedLODInformation(s);
224
+ const i = e.geometry, n = this.getAssignedLODInformation(i);
225
225
  if (!n)
226
226
  return Promise.resolve(null);
227
- for (const i of I)
228
- (r = i.onBeforeGetLODMesh) == null || r.call(i, e, t);
229
- return e["LOD:requested level"] = t, _.getOrLoadLOD(s, t).then((i) => {
227
+ for (const s of I)
228
+ (r = s.onBeforeGetLODMesh) == null || r.call(s, e, t);
229
+ return e["LOD:requested level"] = t, _.getOrLoadLOD(i, t).then((s) => {
230
230
  if (e["LOD:requested level"] === t) {
231
- if (delete e["LOD:requested level"], Array.isArray(i)) {
231
+ if (delete e["LOD:requested level"], Array.isArray(s)) {
232
232
  const o = n.index || 0;
233
- i = i[o];
233
+ s = s[o];
234
234
  }
235
- i && s != i && i instanceof Y && (e.geometry = i, O && ue(e, "geometry", n.url));
235
+ s && i != s && s instanceof Y && (e.geometry = s, D && ue(e, "geometry", n.url));
236
236
  }
237
- return i;
238
- }).catch((i) => (console.error("Error loading mesh LOD", e, i), null));
237
+ return s;
238
+ }).catch((s) => (console.error("Error loading mesh LOD", e, s), null));
239
239
  } else
240
- O && console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh", e);
240
+ D && console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh", e);
241
241
  return Promise.resolve(null);
242
242
  }
243
243
  /** Load a different resolution of a texture (if available)
@@ -251,28 +251,28 @@ const _ = class {
251
251
  if (!e)
252
252
  return Promise.resolve(null);
253
253
  if (e instanceof we || e.isMaterial === !0) {
254
- const r = e, s = [], n = new Array();
255
- if (O && ne.add(r), r.uniforms && r.isRawShaderMaterial || r.isShaderMaterial === !0) {
256
- const i = r;
257
- for (const o of Object.keys(i.uniforms)) {
258
- const a = i.uniforms[o].value;
254
+ const r = e, i = [], n = new Array();
255
+ if (D && ne.add(r), r.uniforms && r.isRawShaderMaterial || r.isShaderMaterial === !0) {
256
+ const s = r;
257
+ for (const o of Object.keys(s.uniforms)) {
258
+ const a = s.uniforms[o].value;
259
259
  if ((a == null ? void 0 : a.isTexture) === !0) {
260
260
  const h = this.assignTextureLODForSlot(a, t, r, o);
261
- s.push(h), n.push(o);
261
+ i.push(h), n.push(o);
262
262
  }
263
263
  }
264
264
  } else
265
- for (const i of Object.keys(r)) {
266
- const o = r[i];
265
+ for (const s of Object.keys(r)) {
266
+ const o = r[s];
267
267
  if ((o == null ? void 0 : o.isTexture) === !0) {
268
- const a = this.assignTextureLODForSlot(o, t, r, i);
269
- s.push(a), n.push(i);
268
+ const a = this.assignTextureLODForSlot(o, t, r, s);
269
+ i.push(a), n.push(s);
270
270
  }
271
271
  }
272
- return Promise.all(s).then((i) => {
272
+ return Promise.all(i).then((s) => {
273
273
  const o = new Array();
274
- for (let a = 0; a < i.length; a++) {
275
- const h = i[a], d = n[a];
274
+ for (let a = 0; a < s.length; a++) {
275
+ const h = s[a], d = n[a];
276
276
  h && h.isTexture === !0 ? o.push({ material: r, slot: d, texture: h, level: t }) : o.push({ material: r, slot: d, texture: null, level: t });
277
277
  }
278
278
  return o;
@@ -284,54 +284,58 @@ const _ = class {
284
284
  }
285
285
  return Promise.resolve(null);
286
286
  }
287
- static assignTextureLODForSlot(e, t, r, s) {
288
- return (e == null ? void 0 : e.isTexture) !== !0 ? Promise.resolve(null) : s === "glyphMap" ? Promise.resolve(e) : _.getOrLoadLOD(e, t).then((n) => {
287
+ static assignTextureLODForSlot(e, t, r, i) {
288
+ return (e == null ? void 0 : e.isTexture) !== !0 ? Promise.resolve(null) : i === "glyphMap" ? Promise.resolve(e) : _.getOrLoadLOD(e, t).then((n) => {
289
289
  if (Array.isArray(n))
290
290
  return null;
291
291
  if ((n == null ? void 0 : n.isTexture) === !0) {
292
292
  if (n != e) {
293
- if (r && s) {
294
- const i = r[s];
295
- if (i) {
296
- const o = this.getAssignedLODInformation(i);
293
+ if (r && i) {
294
+ const s = r[i];
295
+ if (s) {
296
+ const o = this.getAssignedLODInformation(s);
297
297
  if (o && (o == null ? void 0 : o.level) < t)
298
- return O === "verbose" && console.warn("Assigned texture level is already higher: ", o.level, t, r, i, n), null;
298
+ return D === "verbose" && console.warn("Assigned texture level is already higher: ", o.level, t, r, s, n), null;
299
299
  }
300
- r[s] = n;
300
+ r[i] = n;
301
301
  }
302
- if (O && s && r) {
303
- const i = this.getAssignedLODInformation(e);
304
- i && ue(r, s, i.url);
302
+ if (D && i && r) {
303
+ const s = this.getAssignedLODInformation(e);
304
+ s && ue(r, i, s.url);
305
305
  }
306
306
  }
307
307
  return n;
308
308
  } else
309
- O == "verbose" && console.warn("No LOD found for", e, t);
309
+ D == "verbose" && console.warn("No LOD found for", e, t);
310
310
  return null;
311
311
  }).catch((n) => (console.error("Error loading LOD", e, n), null));
312
312
  }
313
313
  afterRoot(e) {
314
314
  var t, r;
315
- return O && console.log("AFTER", this.url, e), (t = this.parser.json.textures) == null || t.forEach((s, n) => {
316
- if (s != null && s.extensions) {
317
- const i = s == null ? void 0 : s.extensions[B];
318
- if (i) {
315
+ return D && console.log("AFTER", this.url, e), (t = this.parser.json.textures) == null || t.forEach((i, n) => {
316
+ if (i != null && i.extensions) {
317
+ const s = i == null ? void 0 : i.extensions[B];
318
+ if (s) {
319
+ if (!s.lods) {
320
+ D && console.warn("Texture has no LODs", s);
321
+ return;
322
+ }
319
323
  let o = !1;
320
324
  for (const a of this.parser.associations.keys())
321
- a.isTexture === !0 && this.parser.associations.get(a).textures === n && (o = !0, _.registerTexture(this.url, a, i.lods.length, n, i));
325
+ a.isTexture === !0 && this.parser.associations.get(a).textures === n && (o = !0, _.registerTexture(this.url, a, s.lods.length, n, s));
322
326
  o || this.parser.getDependency("texture", n).then((a) => {
323
- a && _.registerTexture(this.url, a, i.lods.length, n, i);
327
+ a && _.registerTexture(this.url, a, s.lods.length, n, s);
324
328
  });
325
329
  }
326
330
  }
327
- }), (r = this.parser.json.meshes) == null || r.forEach((s, n) => {
328
- if (s != null && s.extensions) {
329
- const i = s == null ? void 0 : s.extensions[B];
330
- if (i && i.lods) {
331
+ }), (r = this.parser.json.meshes) == null || r.forEach((i, n) => {
332
+ if (i != null && i.extensions) {
333
+ const s = i == null ? void 0 : i.extensions[B];
334
+ if (s && s.lods) {
331
335
  for (const o of this.parser.associations.keys())
332
336
  if (o.isMesh) {
333
337
  const a = this.parser.associations.get(o);
334
- a.meshes === n && _.registerMesh(this.url, i.guid, o, i.lods.length, a.primitives, i);
338
+ a.meshes === n && _.registerMesh(this.url, s.guid, o, s.lods.length, a.primitives, s);
335
339
  }
336
340
  }
337
341
  }
@@ -339,43 +343,43 @@ const _ = class {
339
343
  }
340
344
  static async getOrLoadLOD(e, t) {
341
345
  var o, a, h, d;
342
- const r = O == "verbose", s = e.userData.LODS;
343
- if (!s)
346
+ const r = D == "verbose", i = e.userData.LODS;
347
+ if (!i)
344
348
  return null;
345
- const n = s == null ? void 0 : s.key;
346
- let i;
349
+ const n = i == null ? void 0 : i.key;
350
+ let s;
347
351
  if (e.isTexture === !0) {
348
352
  const g = e;
349
- g.source && g.source[se] && (i = g.source[se]);
353
+ g.source && g.source[se] && (s = g.source[se]);
350
354
  }
351
- if (i || (i = _.lodInfos.get(n)), i) {
355
+ if (s || (s = _.lodInfos.get(n)), s) {
352
356
  if (t > 0) {
353
357
  let m = !1;
354
- const D = Array.isArray(i.lods);
355
- if (D && t >= i.lods.length ? m = !0 : D || (m = !0), m)
358
+ const M = Array.isArray(s.lods);
359
+ if (M && t >= s.lods.length ? m = !0 : M || (m = !0), m)
356
360
  return this.lowresCache.get(n);
357
361
  }
358
- const g = Array.isArray(i.lods) ? (o = i.lods[t]) == null ? void 0 : o.path : i.lods;
362
+ const g = Array.isArray(s.lods) ? (o = s.lods[t]) == null ? void 0 : o.path : s.lods;
359
363
  if (!g)
360
- return O && !i["missing:uri"] && (i["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + t, i)), null;
361
- const f = Te(s.url, g);
364
+ return D && !s["missing:uri"] && (s["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + t, s)), null;
365
+ const f = Te(i.url, g);
362
366
  if (f.endsWith(".glb") || f.endsWith(".gltf")) {
363
- if (!i.guid)
364
- return console.warn("missing pointer for glb/gltf texture", i), null;
365
- const m = f + "_" + i.guid, D = this.previouslyLoaded.get(m);
366
- if (D !== void 0) {
367
+ if (!s.guid)
368
+ return console.warn("missing pointer for glb/gltf texture", s), null;
369
+ const m = f + "_" + s.guid, M = this.previouslyLoaded.get(m);
370
+ if (M !== void 0) {
367
371
  r && console.log(`LOD ${t} was already loading/loaded: ${m}`);
368
- let x = await D.catch((z) => (console.error(`Error loading LOD ${t} from ${f}
372
+ let x = await M.catch((z) => (console.error(`Error loading LOD ${t} from ${f}
369
373
  `, z), null)), T = !1;
370
374
  if (x == null || (x instanceof N && e instanceof N ? (a = x.image) != null && a.data || (h = x.source) != null && h.data ? x = this.copySettings(e, x) : (T = !0, this.previouslyLoaded.delete(m)) : x instanceof Y && e instanceof Y && ((d = x.attributes.position) != null && d.array || (T = !0, this.previouslyLoaded.delete(m)))), !T)
371
375
  return x;
372
376
  }
373
- const M = i, w = new Promise(async (x, T) => {
377
+ const w = s, O = new Promise(async (x, T) => {
374
378
  const z = new Se();
375
- ge(z), O && (await new Promise((p) => setTimeout(p, 1e3)), r && console.warn("Start loading (delayed) " + f, M.guid));
379
+ ge(z), D && (await new Promise((p) => setTimeout(p, 1e3)), r && console.warn("Start loading (delayed) " + f, w.guid));
376
380
  let ee = f;
377
- if (M && Array.isArray(M.lods)) {
378
- const p = M.lods[t];
381
+ if (w && Array.isArray(w.lods)) {
382
+ const p = w.lods[t];
379
383
  p.hash && (ee += "?v=" + p.hash);
380
384
  }
381
385
  const E = await z.loadAsync(ee).catch((p) => (console.error(`Error loading LOD ${t} from ${f}
@@ -383,14 +387,14 @@ const _ = class {
383
387
  if (!E)
384
388
  return null;
385
389
  const te = E.parser;
386
- r && console.log("Loading finished " + f, M.guid);
390
+ r && console.log("Loading finished " + f, w.guid);
387
391
  let y = 0;
388
392
  if (E.parser.json.textures) {
389
393
  let p = !1;
390
394
  for (const u of E.parser.json.textures) {
391
395
  if (u != null && u.extensions) {
392
396
  const L = u == null ? void 0 : u.extensions[B];
393
- if (L != null && L.guid && L.guid === M.guid) {
397
+ if (L != null && L.guid && L.guid === w.guid) {
394
398
  p = !0;
395
399
  break;
396
400
  }
@@ -399,16 +403,16 @@ const _ = class {
399
403
  }
400
404
  if (p) {
401
405
  let u = await te.getDependency("texture", y);
402
- return u && _.assignLODInformation(s.url, u, n, t, void 0, void 0), r && console.log('change "' + e.name + '" → "' + u.name + '"', f, y, u, m), e instanceof N && (u = this.copySettings(e, u)), u && (u.guid = M.guid), x(u);
406
+ return u && _.assignLODInformation(i.url, u, n, t, void 0, void 0), r && console.log('change "' + e.name + '" → "' + u.name + '"', f, y, u, m), e instanceof N && (u = this.copySettings(e, u)), u && (u.guid = w.guid), x(u);
403
407
  } else
404
- O && console.warn("Could not find texture with guid", M.guid);
408
+ D && console.warn("Could not find texture with guid", w.guid);
405
409
  }
406
410
  if (y = 0, E.parser.json.meshes) {
407
411
  let p = !1;
408
412
  for (const u of E.parser.json.meshes) {
409
413
  if (u != null && u.extensions) {
410
414
  const L = u == null ? void 0 : u.extensions[B];
411
- if (L != null && L.guid && L.guid === M.guid) {
415
+ if (L != null && L.guid && L.guid === w.guid) {
412
416
  p = !0;
413
417
  break;
414
418
  }
@@ -416,17 +420,17 @@ const _ = class {
416
420
  y++;
417
421
  }
418
422
  if (p) {
419
- const u = await te.getDependency("mesh", y), L = M;
423
+ const u = await te.getDependency("mesh", y), L = w;
420
424
  if (r && console.log(`Loaded Mesh "${u.name}"`, f, y, u, m), u.isMesh === !0) {
421
425
  const S = u.geometry;
422
- return _.assignLODInformation(s.url, S, n, t, void 0, L.density), x(S);
426
+ return _.assignLODInformation(i.url, S, n, t, void 0, L.density), x(S);
423
427
  } else {
424
428
  const S = new Array();
425
429
  for (let C = 0; C < u.children.length; C++) {
426
430
  const G = u.children[C];
427
431
  if (G instanceof F) {
428
432
  const $ = G.geometry;
429
- _.assignLODInformation(s.url, $, n, t, C, L.density), S.push($);
433
+ _.assignLODInformation(i.url, $, n, t, C, L.density), S.push($);
430
434
  }
431
435
  }
432
436
  return x(S);
@@ -435,22 +439,22 @@ const _ = class {
435
439
  }
436
440
  return x(null);
437
441
  });
438
- return this.previouslyLoaded.set(m, w), await w;
442
+ return this.previouslyLoaded.set(m, O), await O;
439
443
  } else if (e instanceof N) {
440
444
  r && console.log("Load texture from uri: " + f);
441
- const D = await new Oe().loadAsync(f);
442
- return D ? (D.guid = i.guid, D.flipY = !1, D.needsUpdate = !0, D.colorSpace = e.colorSpace, r && console.log(i, D)) : O && console.warn("failed loading", f), D;
445
+ const M = await new Oe().loadAsync(f);
446
+ return M ? (M.guid = s.guid, M.flipY = !1, M.needsUpdate = !0, M.colorSpace = e.colorSpace, r && console.log(s, M)) : D && console.warn("failed loading", f), M;
443
447
  }
444
448
  } else
445
- O && console.warn(`Can not load LOD ${t}: no LOD info found for "${n}" ${e.name}`, e.type);
449
+ D && console.warn(`Can not load LOD ${t}: no LOD info found for "${n}" ${e.name}`, e.type);
446
450
  return null;
447
451
  }
448
- static assignLODInformation(e, t, r, s, n, i) {
452
+ static assignLODInformation(e, t, r, i, n, s) {
449
453
  if (!t)
450
454
  return;
451
455
  t.userData || (t.userData = {});
452
- const o = new Ee(e, r, s, n, i);
453
- t.userData.LODS = o, t.userData.LOD = s;
456
+ const o = new Ee(e, r, i, n, s);
457
+ t.userData.LODS = o, t.userData.LOD = i;
454
458
  }
455
459
  static getAssignedLODInformation(e) {
456
460
  var t;
@@ -458,7 +462,7 @@ const _ = class {
458
462
  }
459
463
  // private static readonly _copiedTextures: WeakMap<Texture, Texture> = new Map();
460
464
  static copySettings(e, t) {
461
- return t = t.clone(), O && console.warn(`Copying texture settings
465
+ return t = t.clone(), D && console.warn(`Copying texture settings
462
466
  `, e.uuid, `
463
467
  `, t.uuid), t.offset = e.offset, t.repeat = e.repeat, t.colorSpace = e.colorSpace, t.magFilter = e.magFilter, t.minFilter = e.minFilter, t.wrapS = e.wrapS, t.wrapT = e.wrapT, t.flipY = e.flipY, t.anisotropy = e.anisotropy, t.mipmaps || (t.generateMipmaps = e.generateMipmaps), t;
464
468
  }
@@ -467,36 +471,36 @@ let v = _;
467
471
  /**
468
472
  * Register a texture with LOD information
469
473
  */
470
- c(v, "registerTexture", (e, t, r, s, n) => {
471
- if (O && console.log("> Progressive: register texture", s, t.name, t.uuid, t, n), !t) {
472
- O && console.error("gltf-progressive: Register texture without texture");
474
+ c(v, "registerTexture", (e, t, r, i, n) => {
475
+ if (D && console.log("> Progressive: register texture", i, t.name, t.uuid, t, n), !t) {
476
+ D && console.error("gltf-progressive: Register texture without texture");
473
477
  return;
474
478
  }
475
479
  t.source && (t.source[se] = n);
476
- const i = n.guid;
477
- _.assignLODInformation(e, t, i, r, s, void 0), _.lodInfos.set(i, n), _.lowresCache.set(i, t);
480
+ const s = n.guid;
481
+ _.assignLODInformation(e, t, s, r, i, void 0), _.lodInfos.set(s, n), _.lowresCache.set(s, t);
478
482
  }), /**
479
483
  * Register a mesh with LOD information
480
484
  */
481
- c(v, "registerMesh", (e, t, r, s, n, i) => {
485
+ c(v, "registerMesh", (e, t, r, i, n, s) => {
482
486
  var h;
483
- O && console.log("> Progressive: register mesh", n, r.name, i, r.uuid, r);
487
+ D && console.log("> Progressive: register mesh", n, r.name, s, r.uuid, r);
484
488
  const o = r.geometry;
485
489
  if (!o) {
486
- O && console.warn("gltf-progressive: Register mesh without geometry");
490
+ D && console.warn("gltf-progressive: Register mesh without geometry");
487
491
  return;
488
492
  }
489
- o.userData || (o.userData = {}), _.assignLODInformation(e, o, t, s, n, i.density), _.lodInfos.set(t, i);
493
+ o.userData || (o.userData = {}), _.assignLODInformation(e, o, t, i, n, s.density), _.lodInfos.set(t, s);
490
494
  let a = _.lowresCache.get(t);
491
- a ? a.push(r.geometry) : a = [r.geometry], _.lowresCache.set(t, a), s > 0 && !ae(r) && be(r, o);
495
+ a ? a.push(r.geometry) : a = [r.geometry], _.lowresCache.set(t, a), i > 0 && !ae(r) && be(r, o);
492
496
  for (const d of I)
493
- (h = d.onRegisteredNewMesh) == null || h.call(d, r, i);
497
+ (h = d.onRegisteredNewMesh) == null || h.call(d, r, s);
494
498
  }), /** A map of key = asset uuid and value = LOD information */
495
499
  c(v, "lodInfos", /* @__PURE__ */ new Map()), /** cache of already loaded mesh lods */
496
500
  c(v, "previouslyLoaded", /* @__PURE__ */ new Map()), /** this contains the geometry/textures that were originally loaded */
497
501
  c(v, "lowresCache", /* @__PURE__ */ new Map());
498
502
  class Ee {
499
- constructor(e, t, r, s, n) {
503
+ constructor(e, t, r, i, n) {
500
504
  c(this, "url");
501
505
  /** the key to lookup the LOD information */
502
506
  c(this, "key");
@@ -505,7 +509,7 @@ class Ee {
505
509
  c(this, "index");
506
510
  /** the mesh density */
507
511
  c(this, "density");
508
- this.url = e, this.key = t, this.level = r, s != null && (this.index = s), n != null && (this.density = n);
512
+ this.url = e, this.key = t, this.level = r, i != null && (this.index = i), n != null && (this.density = n);
509
513
  }
510
514
  }
511
515
  const U = j("debugprogressive"), Ce = j("noprogressive"), fe = Symbol("Needle:LODSManager"), b = { mesh_lod: -1, texture_lod: -1 }, A = class {
@@ -572,33 +576,33 @@ const U = j("debugprogressive"), Ce = j("noprogressive"), fe = Symbol("Needle:LO
572
576
  let e = 0;
573
577
  this._originalRender = this.renderer.render;
574
578
  const t = this;
575
- he(this.renderer), this.renderer.render = function(r, s) {
579
+ he(this.renderer), this.renderer.render = function(r, i) {
576
580
  t.renderer.getRenderTarget() == null && (e = 0, t._frame += 1);
577
- const i = t._frame, o = e++;
578
- t.onBeforeRender(r, s, o, i), t._originalRender.call(this, r, s), t.onAfterRender(r, s, o, i);
581
+ const s = t._frame, o = e++;
582
+ t.onBeforeRender(r, i, o, s), t._originalRender.call(this, r, i), t.onAfterRender(r, i, o, s);
579
583
  };
580
584
  }
581
585
  disable() {
582
586
  this._originalRender && (this.renderer.render = this._originalRender, this._originalRender = void 0);
583
587
  }
584
- onBeforeRender(e, t, r, s) {
588
+ onBeforeRender(e, t, r, i) {
585
589
  }
586
- onAfterRender(e, t, r, s) {
590
+ onAfterRender(e, t, r, i) {
587
591
  var a, h;
588
592
  if (this.pause)
589
593
  return;
590
- const n = this.renderer.renderLists.get(e, 0), i = n.opaque;
594
+ const n = this.renderer.renderLists.get(e, 0), s = n.opaque;
591
595
  let o = !0;
592
- if (i.length === 1) {
593
- const d = i[0].material;
596
+ if (s.length === 1) {
597
+ const d = s[0].material;
594
598
  (d.name === "EffectMaterial" || d.name === "CopyShader") && (o = !1);
595
599
  }
596
600
  if (t.parent && t.parent.type === "CubeCamera" && (o = !1), o) {
597
- if (Ce || this.updateInterval > 0 && s % this.updateInterval != 0)
601
+ if (Ce || this.updateInterval > 0 && i % this.updateInterval != 0)
598
602
  return;
599
603
  this.projectionScreenMatrix.multiplyMatrices(t.projectionMatrix, t.matrixWorldInverse), this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix, this.renderer.coordinateSystem);
600
604
  const d = this.targetTriangleDensity;
601
- for (const f of i) {
605
+ for (const f of s) {
602
606
  if (f.material && (((a = f.geometry) == null ? void 0 : a.type) === "BoxGeometry" || ((h = f.geometry) == null ? void 0 : h.type) === "BufferGeometry") && (f.material.name === "SphericalGaussianBlur" || f.material.name == "BackgroundCubeMaterial" || f.material.name === "CubemapFromEquirect" || f.material.name === "EquirectangularToCubeUV")) {
603
607
  U && (f.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"] || (f.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"] = !0, console.warn("Ignoring skybox or BLIT object", f, f.material.name, f.material.type)));
604
608
  continue;
@@ -613,25 +617,25 @@ const U = j("debugprogressive"), Ce = j("noprogressive"), fe = Symbol("Needle:LO
613
617
  continue;
614
618
  }
615
619
  const m = f.object;
616
- (m instanceof F || m.isMesh) && this.updateLODs(e, t, m, d, s);
620
+ (m instanceof F || m.isMesh) && this.updateLODs(e, t, m, d, i);
617
621
  }
618
622
  const g = n.transparent;
619
623
  for (const f of g) {
620
624
  const m = f.object;
621
- (m instanceof F || m.isMesh) && this.updateLODs(e, t, m, d, s);
625
+ (m instanceof F || m.isMesh) && this.updateLODs(e, t, m, d, i);
622
626
  }
623
627
  }
624
628
  }
625
629
  /** Update the LOD levels for the renderer. */
626
- updateLODs(e, t, r, s, n) {
630
+ updateLODs(e, t, r, i, n) {
627
631
  var a, h;
628
632
  r.userData || (r.userData = {});
629
- let i = r.userData.LOD_state;
630
- if (i || (i = new Re(), r.userData.LOD_state = i), i.frames++ < 2)
633
+ let s = r.userData.LOD_state;
634
+ if (s || (s = new Re(), r.userData.LOD_state = s), s.frames++ < 2)
631
635
  return;
632
636
  for (const d of I)
633
637
  (a = d.onBeforeUpdateLOD) == null || a.call(d, this.renderer, e, t, r);
634
- this.calculateLodLevel(t, r, i, s, b), b.mesh_lod = Math.round(b.mesh_lod), b.texture_lod = Math.round(b.texture_lod), b.mesh_lod >= 0 && this.loadProgressiveMeshes(r, b.mesh_lod);
638
+ this.calculateLodLevel(t, r, s, i, b), b.mesh_lod = Math.round(b.mesh_lod), b.texture_lod = Math.round(b.texture_lod), b.mesh_lod >= 0 && this.loadProgressiveMeshes(r, b.mesh_lod);
635
639
  let o = b.texture_lod;
636
640
  if (r.material && o >= 0) {
637
641
  const d = r["DEBUG:LOD"];
@@ -639,7 +643,7 @@ const U = j("debugprogressive"), Ce = j("noprogressive"), fe = Symbol("Needle:LO
639
643
  }
640
644
  for (const d of I)
641
645
  (h = d.onAfterUpdatedLOD) == null || h.call(d, this.renderer, e, t, r, b);
642
- i.lastLodLevel_Mesh = b.mesh_lod, i.lastLodLevel_Texture = b.texture_lod;
646
+ s.lastLodLevel_Mesh = b.mesh_lod, s.lastLodLevel_Texture = b.texture_lod;
643
647
  }
644
648
  /** Load progressive textures for the given material
645
649
  * @param material the material to load the textures for
@@ -655,8 +659,8 @@ const U = j("debugprogressive"), Ce = j("noprogressive"), fe = Symbol("Needle:LO
655
659
  return;
656
660
  }
657
661
  const r = e;
658
- let s = !1;
659
- (r.NEEDLE_LOD == null || t < r.NEEDLE_LOD) && (s = !0), s && (r.NEEDLE_LOD = t, v.assignTextureLOD(e, t));
662
+ let i = !1;
663
+ (r.NEEDLE_LOD == null || t < r.NEEDLE_LOD) && (i = !0), i && (r.NEEDLE_LOD = t, v.assignTextureLOD(e, t));
660
664
  }
661
665
  /** Load progressive meshes for the given mesh
662
666
  * @param mesh the mesh to load the LOD for
@@ -670,16 +674,16 @@ const U = j("debugprogressive"), Ce = j("noprogressive"), fe = Symbol("Needle:LO
670
674
  if (e.userData || (e.userData = {}), e.userData.LOD !== t) {
671
675
  e.userData.LOD = t;
672
676
  const r = e.geometry;
673
- return v.assignMeshLOD(e, t).then((s) => (s && e.userData.LOD == t && r != e.geometry, s));
677
+ return v.assignMeshLOD(e, t).then((i) => (i && e.userData.LOD == t && r != e.geometry, i));
674
678
  }
675
679
  return Promise.resolve(null);
676
680
  }
677
681
  static isInside(e, t) {
678
- const r = e.min, s = e.max, n = (r.x + s.x) * 0.5, i = (r.y + s.y) * 0.5;
679
- return this._tempPtInside.set(n, i, r.z).applyMatrix4(t).z < 0;
682
+ const r = e.min, i = e.max, n = (r.x + i.x) * 0.5, s = (r.y + i.y) * 0.5;
683
+ return this._tempPtInside.set(n, s, r.z).applyMatrix4(t).z < 0;
680
684
  }
681
- calculateLodLevel(e, t, r, s, n) {
682
- var D;
685
+ calculateLodLevel(e, t, r, i, n) {
686
+ var M;
683
687
  if (!t) {
684
688
  n.mesh_lod = -1, n.texture_lod = -1;
685
689
  return;
@@ -696,13 +700,13 @@ const U = j("debugprogressive"), Ce = j("noprogressive"), fe = Symbol("Needle:LO
696
700
  n.mesh_lod = 0, n.texture_lod = 0;
697
701
  return;
698
702
  }
699
- if (d || (o = 0), !((D = this.cameraFrustrum) != null && D.intersectsObject(t))) {
703
+ if (d || (o = 0), !((M = this.cameraFrustrum) != null && M.intersectsObject(t))) {
700
704
  n.mesh_lod = 99, n.texture_lod = 99;
701
705
  return;
702
706
  }
703
707
  const m = t.geometry.boundingBox;
704
708
  if (m && e.isPerspectiveCamera) {
705
- const M = e;
709
+ const w = e;
706
710
  if (t.geometry.attributes.color && t.geometry.attributes.color.count < 100 && t.geometry.boundingSphere) {
707
711
  this._sphere.copy(t.geometry.boundingSphere), this._sphere.applyMatrix4(t.matrixWorld);
708
712
  const y = e.getWorldPosition(this._tempWorldPosition);
@@ -715,7 +719,7 @@ const U = j("debugprogressive"), Ce = j("noprogressive"), fe = Symbol("Needle:LO
715
719
  n.mesh_lod = 0, n.texture_lod = 0;
716
720
  return;
717
721
  }
718
- if (this._tempBox.applyMatrix4(this.projectionScreenMatrix), this.renderer.xr.enabled && M.fov > 70) {
722
+ if (this._tempBox.applyMatrix4(this.projectionScreenMatrix), this.renderer.xr.enabled && w.fov > 70) {
719
723
  const y = this._tempBox.min, p = this._tempBox.max;
720
724
  let u = y.x, L = y.y, S = p.x, C = p.y;
721
725
  const G = 2, $ = 1.5, H = (y.x + p.x) * 0.5, J = (y.y + p.y) * 0.5;
@@ -724,12 +728,12 @@ const U = j("debugprogressive"), Ce = j("noprogressive"), fe = Symbol("Needle:LO
724
728
  r.lastCentrality = ($ - re) * ($ - re) * ($ - re);
725
729
  } else
726
730
  r.lastCentrality = 1;
727
- const w = this._tempBox.getSize(this._tempBoxSize);
728
- w.multiplyScalar(0.5), screen.availHeight > 0 && w.multiplyScalar(this.renderer.domElement.clientHeight / screen.availHeight), w.x *= M.aspect;
731
+ const O = this._tempBox.getSize(this._tempBoxSize);
732
+ O.multiplyScalar(0.5), screen.availHeight > 0 && O.multiplyScalar(this.renderer.domElement.clientHeight / screen.availHeight), O.x *= w.aspect;
729
733
  const R = e.matrixWorldInverse, x = this._tempBox2;
730
734
  x.copy(m), x.applyMatrix4(t.matrixWorld), x.applyMatrix4(R);
731
735
  const T = x.getSize(this._tempBox2Size), z = Math.max(T.x, T.y);
732
- if (Math.max(w.x, w.y) != 0 && z != 0 && (w.z = T.z / Math.max(T.x, T.y) * Math.max(w.x, w.y)), r.lastScreenCoverage = Math.max(w.x, w.y, w.z), r.lastScreenspaceVolume.copy(w), r.lastScreenCoverage *= r.lastCentrality, U && A.debugDrawLine) {
736
+ if (Math.max(O.x, O.y) != 0 && z != 0 && (O.z = T.z / Math.max(T.x, T.y) * Math.max(O.x, O.y)), r.lastScreenCoverage = Math.max(O.x, O.y, O.z), r.lastScreenspaceVolume.copy(O), r.lastScreenCoverage *= r.lastCentrality, U && A.debugDrawLine) {
733
737
  const y = this.tempMatrix.copy(this.projectionScreenMatrix);
734
738
  y.invert();
735
739
  const p = A.corner0, u = A.corner1, L = A.corner2, S = A.corner3;
@@ -740,7 +744,7 @@ const U = j("debugprogressive"), Ce = j("noprogressive"), fe = Symbol("Needle:LO
740
744
  let E = 999;
741
745
  if (h && r.lastScreenCoverage > 0) {
742
746
  for (let y = 0; y < h.length; y++)
743
- if (h[y].density / r.lastScreenCoverage < s) {
747
+ if (h[y].density / r.lastScreenCoverage < i) {
744
748
  E = y;
745
749
  break;
746
750
  }
@@ -750,11 +754,11 @@ const U = j("debugprogressive"), Ce = j("noprogressive"), fe = Symbol("Needle:LO
750
754
  if (n.mesh_lod = o, f)
751
755
  if (r.lastLodLevel_Texture < 0) {
752
756
  if (n.texture_lod = g.max_count - 1, U) {
753
- const M = g.lods[g.max_count - 1];
754
- U && console.log(`First Texture LOD ${n.texture_lod} (${M.max_height}px) - ${t.name}`);
757
+ const w = g.lods[g.max_count - 1];
758
+ U && console.log(`First Texture LOD ${n.texture_lod} (${w.max_height}px) - ${t.name}`);
755
759
  }
756
760
  } else {
757
- const M = r.lastScreenCoverage * 1.5, R = this.renderer.domElement.clientHeight / window.devicePixelRatio * M;
761
+ const w = r.lastScreenCoverage * 1.5, R = this.renderer.domElement.clientHeight / window.devicePixelRatio * w;
758
762
  for (let x = g.lods.length - 1; x >= 0; x--) {
759
763
  const T = g.lods[x];
760
764
  if (!(Ae() && T.max_height > 4096) && T.max_height > R) {
@@ -787,15 +791,15 @@ function ke(l) {
787
791
  return null;
788
792
  let e = null, t = null;
789
793
  for (let r = l; r != null; r = Object.getPrototypeOf(r)) {
790
- const s = Object.getOwnPropertySymbols(r), n = s.find((o) => o.toString() == "Symbol(renderer)"), i = s.find((o) => o.toString() == "Symbol(scene)");
791
- !e && n != null && (e = l[n].threeRenderer), !t && i != null && (t = l[i]);
794
+ const i = Object.getOwnPropertySymbols(r), n = i.find((o) => o.toString() == "Symbol(renderer)"), s = i.find((o) => o.toString() == "Symbol(scene)");
795
+ !e && n != null && (e = l[n].threeRenderer), !t && s != null && (t = l[s]);
792
796
  }
793
797
  if (e) {
794
798
  console.log("Adding Needle LODs to modelviewer");
795
799
  const r = P.get(e);
796
800
  if (P.addPlugin(new Be(l)), r.enable(), t) {
797
- const s = t.camera || t.traverse((n) => n.type == "PerspectiveCamera")[0];
798
- s && e.render(t, s);
801
+ const i = t.camera || t.traverse((n) => n.type == "PerspectiveCamera")[0];
802
+ i && e.render(t, i);
799
803
  }
800
804
  return () => {
801
805
  r.disable();
@@ -809,8 +813,8 @@ class Be {
809
813
  c(this, "_didWarnAboutMissingUrl", !1);
810
814
  this.modelviewer = e;
811
815
  }
812
- onBeforeUpdateLOD(e, t, r, s) {
813
- this.tryParseMeshLOD(t, s), this.tryParseTextureLOD(t, s);
816
+ onBeforeUpdateLOD(e, t, r, i) {
817
+ this.tryParseMeshLOD(t, i), this.tryParseTextureLOD(t, i);
814
818
  }
815
819
  getUrl() {
816
820
  let e = this.modelviewer.getAttribute("src");
@@ -823,8 +827,8 @@ class Be {
823
827
  if (t[Q] == !0)
824
828
  return;
825
829
  t[Q] = !0;
826
- const r = this.tryGetCurrentGLTF(e), s = this.getUrl();
827
- if (s && r && t.material) {
830
+ const r = this.tryGetCurrentGLTF(e), i = this.getUrl();
831
+ if (i && r && t.material) {
828
832
  let n = function(o) {
829
833
  var h, d, g;
830
834
  if (o[Q] == !0)
@@ -832,47 +836,47 @@ class Be {
832
836
  o[Q] = !0, o.userData && (o.userData.LOD = -1);
833
837
  const a = Object.keys(o);
834
838
  for (let f = 0; f < a.length; f++) {
835
- const m = a[f], D = o[m];
836
- if ((D == null ? void 0 : D.isTexture) === !0) {
837
- const M = (d = (h = D.userData) == null ? void 0 : h.associations) == null ? void 0 : d.textures, w = r.parser.json.textures[M];
838
- if (!w) {
839
- console.warn("Texture data not found for texture index " + M);
839
+ const m = a[f], M = o[m];
840
+ if ((M == null ? void 0 : M.isTexture) === !0) {
841
+ const w = (d = (h = M.userData) == null ? void 0 : h.associations) == null ? void 0 : d.textures, O = r.parser.json.textures[w];
842
+ if (!O) {
843
+ console.warn("Texture data not found for texture index " + w);
840
844
  continue;
841
845
  }
842
- if ((g = w == null ? void 0 : w.extensions) != null && g[B]) {
843
- const R = w.extensions[B];
844
- R && s && v.registerTexture(s, D, R.lods.length, M, R);
846
+ if ((g = O == null ? void 0 : O.extensions) != null && g[B]) {
847
+ const R = O.extensions[B];
848
+ R && i && v.registerTexture(i, M, R.lods.length, w, R);
845
849
  }
846
850
  }
847
851
  }
848
852
  };
849
- const i = t.material;
850
- if (Array.isArray(i))
851
- for (const o of i)
853
+ const s = t.material;
854
+ if (Array.isArray(s))
855
+ for (const o of s)
852
856
  n(o);
853
857
  else
854
- n(i);
858
+ n(s);
855
859
  }
856
860
  }
857
861
  tryParseMeshLOD(e, t) {
858
- var n, i;
862
+ var n, s;
859
863
  if (t[de] == !0)
860
864
  return;
861
865
  t[de] = !0;
862
866
  const r = this.getUrl();
863
867
  if (!r)
864
868
  return;
865
- const s = (i = (n = t.userData) == null ? void 0 : n.gltfExtensions) == null ? void 0 : i[B];
866
- if (s && r) {
869
+ const i = (s = (n = t.userData) == null ? void 0 : n.gltfExtensions) == null ? void 0 : s[B];
870
+ if (i && r) {
867
871
  const o = t.uuid;
868
- v.registerMesh(r, o, t, 0, s.lods.length, s);
872
+ v.registerMesh(r, o, t, 0, i.lods.length, i);
869
873
  }
870
874
  }
871
875
  }
872
876
  function qe(l, e, t, r) {
873
877
  he(e), ge(t), t.register((n) => new v(n, l));
874
- const s = P.get(e);
875
- return (r == null ? void 0 : r.enableLODsManager) !== !1 && s.enable(), s;
878
+ const i = P.get(e);
879
+ return (r == null ? void 0 : r.enableLODsManager) !== !1 && i.enable(), i;
876
880
  }
877
881
  document.addEventListener("DOMContentLoaded", () => {
878
882
  ke(document.querySelector("model-viewer"));
@@ -1,5 +1,5 @@
1
- var me=Object.defineProperty,pe=(t,e,r)=>e in t?me(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,c=(t,e,r)=>(pe(t,typeof e!="symbol"?e+"":e,r),r);import{MeshoptDecoder as xe}from"three/examples/jsm/libs/meshopt_decoder.module.js";import{DRACOLoader as ye}from"three/examples/jsm/loaders/DRACOLoader.js";import{KTX2Loader as ve}from"three/examples/jsm/loaders/KTX2Loader.js";import{BufferGeometry as $,Mesh as G,Material as Le,Texture as z,TextureLoader as De,Matrix4 as ie,Frustum as Me,Sphere as _e,Box3 as ae,Vector3 as B}from"three";import{GLTFLoader as Oe}from"three/examples/jsm/loaders/GLTFLoader.js";let X="https://www.gstatic.com/draco/versioned/decoders/1.4.1/",ee="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";fetch(X+"draco_decoder.js",{method:"head"}).catch(t=>{X="./include/draco/",ee="./include/ktx2/"});function we(t){X=t}function be(t){ee=t}let U,te,q;function re(t){U||(U=new ye,U.setDecoderPath(X),U.setDecoderConfig({type:"js"})),q||(q=new ve,q.setTranscoderPath(ee)),te||(te=xe),t?q.detectSupport(t):console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures will probably fail")}function se(t){t.dracoLoader||t.setDRACOLoader(U),t.ktx2Loader||t.setKTX2Loader(q),t.meshoptDecoder||t.setMeshoptDecoder(te)}function H(t){const e=new URL(window.location.href).searchParams.get(t);return e==null||e==="0"||e==="false"?!1:e===""?!0:e}function Se(t,e){if(e===void 0||e.startsWith("./")||e.startsWith("http")||t===void 0)return e;const r=t.lastIndexOf("/");if(r>=0){const n=t.substring(0,r+1);for(;n.endsWith("/")&&e.startsWith("/");)e=e.substring(1);return n+e}return e}let Y;function Te(){return Y!==void 0||(Y=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),H("debugprogressive")&&console.log("isMobileDevice",Y)),Y}function J(t){var e;return((e=t?.userData)==null?void 0:e["needle:raycast-mesh"])instanceof $?t.userData["needle:raycast-mesh"]:null}function le(t,e){if((t.type==="Mesh"||t.type==="SkinnedMesh")&&!J(t)){const r=Ae(e);r.userData={isRaycastMesh:!0},t.userData||(t.userData={}),t.userData["needle:raycast-mesh"]=r}}function Ee(t=!0){if(t){if(V)return;const e=V=G.prototype.raycast;G.prototype.raycast=function(r,n){const o=this,s=J(o);let a;s&&o.isMesh&&(a=o.geometry,o.geometry=s),e.call(this,r,n),a&&(o.geometry=a)}}else{if(!V)return;G.prototype.raycast=V,V=null}}let V=null;function Ae(t){const e=new $;for(const r in t.attributes)e.setAttribute(r,t.getAttribute(r));return e.setIndex(t.getIndex()),e}const R=new Array,P="NEEDLE_progressive",v=H("debugprogressive"),oe=Symbol("needle-progressive-texture"),K=new Map,ne=new Set;if(v){let t=function(){e+=1,console.log("Toggle LOD level",e,K),K.forEach((o,s)=>{for(const a of o.keys){const i=s[a];if(i.isBufferGeometry===!0){const u=O.getMeshLODInformation(i),l=u?Math.min(e,u.lods.length):0;s["DEBUG:LOD"]=e,O.assignMeshLOD(s,l),u&&(r=Math.max(r,u.lods.length-1))}else if(s.isMaterial===!0){s["DEBUG:LOD"]=e,O.assignTextureLOD(s,e);break}}}),e>=r&&(e=-1)},e=-1,r=2,n=!1;window.addEventListener("keyup",o=>{o.key==="p"&&t(),o.key==="w"&&(n=!n,ne&&ne.forEach(s=>{s.name!="BackgroundCubeMaterial"&&"wireframe"in s&&(s.wireframe=n)}))})}function ue(t,e,r){var n;if(!v)return;K.has(t)||K.set(t,{keys:[],sourceId:r});const o=K.get(t);((n=o?.keys)==null?void 0:n.includes(e))==!1&&o.keys.push(e)}const M=class{constructor(t,e){c(this,"parser"),c(this,"url"),c(this,"_isLoadingMesh"),c(this,"loadMesh",r=>{var n,o;if(this._isLoadingMesh)return null;const s=(o=(n=this.parser.json.meshes[r])==null?void 0:n.extensions)==null?void 0:o[P];return s?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",r).then(a=>(this._isLoadingMesh=!1,a&&M.registerMesh(this.url,s.guid,a,s.lods.length,void 0,s),a))):null}),v&&console.log("Progressive extension registered for",e),this.parser=t,this.url=e}get name(){return P}static getMeshLODInformation(t){const e=this.getAssignedLODInformation(t);return e!=null&&e.key?this.lodInfos.get(e.key):null}static getMaterialMinMaxLODsCount(t,e){const r=this,n="LODS:minmax",o=t[n];if(o!=null)return o;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[n]=e,e}if(v==="verbose"&&console.log("getMaterialMinMaxLODsCount",t),t.type==="ShaderMaterial"||t.type==="RawShaderMaterial"){const a=t;for(const i of Object.keys(a.uniforms)){const u=a.uniforms[i].value;u?.isTexture===!0&&s(u,e)}}else if(t.isMaterial)for(const a of Object.keys(t)){const i=t[a];i?.isTexture===!0&&s(i,e)}return t[n]=e,e;function s(a,i){const u=r.getAssignedLODInformation(a);if(u){const l=r.lodInfos.get(u.key);if(l&&l.lods){i.min_count=Math.min(i.min_count,l.lods.length),i.max_count=Math.max(i.max_count,l.lods.length);for(let g=0;g<l.lods.length;g++){const d=l.lods[g];d.width&&(i.lods[g]=i.lods[g]||{min_height:1/0,max_height:0},i.lods[g].min_height=Math.min(i.lods[g].min_height,d.height),i.lods[g].max_height=Math.max(i.lods[g].max_height,d.height))}}}}}static hasLODLevelAvailable(t,e){var r;if(Array.isArray(t)){for(const s of t)if(this.hasLODLevelAvailable(s,e))return!0;return!1}if(t.isMaterial===!0){for(const s of Object.keys(t)){const a=t[s];if(a&&a.isTexture&&this.hasLODLevelAvailable(a,e))return!0}return!1}else if(t.isGroup===!0){for(const s of t.children)if(s.isMesh===!0&&this.hasLODLevelAvailable(s,e))return!0}let n,o;if(t.isMesh?n=t.geometry:(t.isBufferGeometry||t.isTexture)&&(n=t),n&&(r=n?.userData)!=null&&r.LODS){const s=n.userData.LODS;if(o=this.lodInfos.get(s.key),e===void 0)return o!=null;if(o)return Array.isArray(o.lods)?e<o.lods.length:e===0}return!1}static assignMeshLOD(t,e){var r;if(!t)return Promise.resolve(null);if(t instanceof G||t.isMesh===!0){const n=t.geometry,o=this.getAssignedLODInformation(n);if(!o)return Promise.resolve(null);for(const s of R)(r=s.onBeforeGetLODMesh)==null||r.call(s,t,e);return t["LOD:requested level"]=e,M.getOrLoadLOD(n,e).then(s=>{if(t["LOD:requested level"]===e){if(delete t["LOD:requested level"],Array.isArray(s)){const a=o.index||0;s=s[a]}s&&n!=s&&s instanceof $&&(t.geometry=s,v&&ue(t,"geometry",o.url))}return s}).catch(s=>(console.error("Error loading mesh LOD",t,s),null))}else v&&console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh",t);return Promise.resolve(null)}static assignTextureLOD(t,e=0){if(!t)return Promise.resolve(null);if(t instanceof Le||t.isMaterial===!0){const r=t,n=[],o=new Array;if(v&&ne.add(r),r.uniforms&&r.isRawShaderMaterial||r.isShaderMaterial===!0){const s=r;for(const a of Object.keys(s.uniforms)){const i=s.uniforms[a].value;if(i?.isTexture===!0){const u=this.assignTextureLODForSlot(i,e,r,a);n.push(u),o.push(a)}}}else for(const s of Object.keys(r)){const a=r[s];if(a?.isTexture===!0){const i=this.assignTextureLODForSlot(a,e,r,s);n.push(i),o.push(s)}}return Promise.all(n).then(s=>{const a=new Array;for(let i=0;i<s.length;i++){const u=s[i],l=o[i];u&&u.isTexture===!0?a.push({material:r,slot:l,texture:u,level:e}):a.push({material:r,slot:l,texture:null,level:e})}return a})}if(t instanceof z||t.isTexture===!0){const r=t;return this.assignTextureLODForSlot(r,e,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(t,e,r,n){return t?.isTexture!==!0?Promise.resolve(null):n==="glyphMap"?Promise.resolve(t):M.getOrLoadLOD(t,e).then(o=>{if(Array.isArray(o))return null;if(o?.isTexture===!0){if(o!=t){if(r&&n){const s=r[n];if(s){const a=this.getAssignedLODInformation(s);if(a&&a?.level<e)return v==="verbose"&&console.warn("Assigned texture level is already higher: ",a.level,e,r,s,o),null}r[n]=o}if(v&&n&&r){const s=this.getAssignedLODInformation(t);s&&ue(r,n,s.url)}}return o}else v=="verbose"&&console.warn("No LOD found for",t,e);return null}).catch(o=>(console.error("Error loading LOD",t,o),null))}afterRoot(t){var e,r;return v&&console.log("AFTER",this.url,t),(e=this.parser.json.textures)==null||e.forEach((n,o)=>{if(n!=null&&n.extensions){const s=n?.extensions[P];if(s){let a=!1;for(const i of this.parser.associations.keys())i.isTexture===!0&&this.parser.associations.get(i).textures===o&&(a=!0,M.registerTexture(this.url,i,s.lods.length,o,s));a||this.parser.getDependency("texture",o).then(i=>{i&&M.registerTexture(this.url,i,s.lods.length,o,s)})}}}),(r=this.parser.json.meshes)==null||r.forEach((n,o)=>{if(n!=null&&n.extensions){const s=n?.extensions[P];if(s&&s.lods){for(const a of this.parser.associations.keys())if(a.isMesh){const i=this.parser.associations.get(a);i.meshes===o&&M.registerMesh(this.url,s.guid,a,s.lods.length,i.primitives,s)}}}}),null}static async getOrLoadLOD(t,e){var r,n,o,s;const a=v=="verbose",i=t.userData.LODS;if(!i)return null;const u=i?.key;let l;if(t.isTexture===!0){const g=t;g.source&&g.source[oe]&&(l=g.source[oe])}if(l||(l=M.lodInfos.get(u)),l){if(e>0){let f=!1;const w=Array.isArray(l.lods);if(w&&e>=l.lods.length?f=!0:w||(f=!0),f)return this.lowresCache.get(u)}const g=Array.isArray(l.lods)?(r=l.lods[e])==null?void 0:r.path:l.lods;if(!g)return v&&!l["missing:uri"]&&(l["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+e,l)),null;const d=Se(i.url,g);if(d.endsWith(".glb")||d.endsWith(".gltf")){if(!l.guid)return console.warn("missing pointer for glb/gltf texture",l),null;const f=d+"_"+l.guid,w=this.previouslyLoaded.get(f);if(w!==void 0){a&&console.log(`LOD ${e} was already loading/loaded: ${f}`);let p=await w.catch(N=>(console.error(`Error loading LOD ${e} from ${d}
2
- `,N),null)),b=!1;if(p==null||(p instanceof z&&t instanceof z?(n=p.image)!=null&&n.data||(o=p.source)!=null&&o.data?p=this.copySettings(t,p):(b=!0,this.previouslyLoaded.delete(f)):p instanceof $&&t instanceof $&&((s=p.attributes.position)!=null&&s.array||(b=!0,this.previouslyLoaded.delete(f)))),!b)return p}const m=l,S=new Promise(async(p,b)=>{const N=new Oe;se(N),v&&(await new Promise(y=>setTimeout(y,1e3)),a&&console.warn("Start loading (delayed) "+d,m.guid));let F=d;if(m&&Array.isArray(m.lods)){const y=m.lods[e];y.hash&&(F+="?v="+y.hash)}const x=await N.loadAsync(F).catch(y=>(console.error(`Error loading LOD ${e} from ${d}
3
- `,y),null));if(!x)return null;const L=x.parser;a&&console.log("Loading finished "+d,m.guid);let D=0;if(x.parser.json.textures){let y=!1;for(const h of x.parser.json.textures){if(h!=null&&h.extensions){const _=h?.extensions[P];if(_!=null&&_.guid&&_.guid===m.guid){y=!0;break}}D++}if(y){let h=await L.getDependency("texture",D);return h&&M.assignLODInformation(i.url,h,u,e,void 0,void 0),a&&console.log('change "'+t.name+'" \u2192 "'+h.name+'"',d,D,h,f),t instanceof z&&(h=this.copySettings(t,h)),h&&(h.guid=m.guid),p(h)}else v&&console.warn("Could not find texture with guid",m.guid)}if(D=0,x.parser.json.meshes){let y=!1;for(const h of x.parser.json.meshes){if(h!=null&&h.extensions){const _=h?.extensions[P];if(_!=null&&_.guid&&_.guid===m.guid){y=!0;break}}D++}if(y){const h=await L.getDependency("mesh",D),_=m;if(a&&console.log(`Loaded Mesh "${h.name}"`,d,D,h,f),h.isMesh===!0){const A=h.geometry;return M.assignLODInformation(i.url,A,u,e,void 0,_.density),p(A)}else{const A=new Array;for(let C=0;C<h.children.length;C++){const k=h.children[C];if(k instanceof G){const j=k.geometry;M.assignLODInformation(i.url,j,u,e,C,_.density),A.push(j)}}return p(A)}}}return p(null)});return this.previouslyLoaded.set(f,S),await S}else if(t instanceof z){a&&console.log("Load texture from uri: "+d);const f=await new De().loadAsync(d);return f?(f.guid=l.guid,f.flipY=!1,f.needsUpdate=!0,f.colorSpace=t.colorSpace,a&&console.log(l,f)):v&&console.warn("failed loading",d),f}}else v&&console.warn(`Can not load LOD ${e}: no LOD info found for "${u}" ${t.name}`,t.type);return null}static assignLODInformation(t,e,r,n,o,s){if(!e)return;e.userData||(e.userData={});const a=new Pe(t,r,n,o,s);e.userData.LODS=a,e.userData.LOD=n}static getAssignedLODInformation(t){var e;return((e=t?.userData)==null?void 0:e.LODS)||null}static copySettings(t,e){return e=e.clone(),v&&console.warn(`Copying texture settings
1
+ var me=Object.defineProperty,pe=(t,e,r)=>e in t?me(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,c=(t,e,r)=>(pe(t,typeof e!="symbol"?e+"":e,r),r);import{MeshoptDecoder as xe}from"three/examples/jsm/libs/meshopt_decoder.module.js";import{DRACOLoader as ye}from"three/examples/jsm/loaders/DRACOLoader.js";import{KTX2Loader as Le}from"three/examples/jsm/loaders/KTX2Loader.js";import{BufferGeometry as $,Mesh as G,Material as ve,Texture as z,TextureLoader as De,Matrix4 as ie,Frustum as Me,Sphere as Oe,Box3 as ae,Vector3 as B}from"three";import{GLTFLoader as _e}from"three/examples/jsm/loaders/GLTFLoader.js";let X="https://www.gstatic.com/draco/versioned/decoders/1.4.1/",ee="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";fetch(X+"draco_decoder.js",{method:"head"}).catch(t=>{X="./include/draco/",ee="./include/ktx2/"});function we(t){X=t}function be(t){ee=t}let U,te,q;function re(t){U||(U=new ye,U.setDecoderPath(X),U.setDecoderConfig({type:"js"})),q||(q=new Le,q.setTranscoderPath(ee)),te||(te=xe),t?q.detectSupport(t):console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures will probably fail")}function se(t){t.dracoLoader||t.setDRACOLoader(U),t.ktx2Loader||t.setKTX2Loader(q),t.meshoptDecoder||t.setMeshoptDecoder(te)}function H(t){const e=new URL(window.location.href).searchParams.get(t);return e==null||e==="0"||e==="false"?!1:e===""?!0:e}function Se(t,e){if(e===void 0||e.startsWith("./")||e.startsWith("http")||t===void 0)return e;const r=t.lastIndexOf("/");if(r>=0){const n=t.substring(0,r+1);for(;n.endsWith("/")&&e.startsWith("/");)e=e.substring(1);return n+e}return e}let Y;function Te(){return Y!==void 0||(Y=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),H("debugprogressive")&&console.log("isMobileDevice",Y)),Y}function J(t){var e;return((e=t?.userData)==null?void 0:e["needle:raycast-mesh"])instanceof $?t.userData["needle:raycast-mesh"]:null}function le(t,e){if((t.type==="Mesh"||t.type==="SkinnedMesh")&&!J(t)){const r=Ae(e);r.userData={isRaycastMesh:!0},t.userData||(t.userData={}),t.userData["needle:raycast-mesh"]=r}}function Ee(t=!0){if(t){if(V)return;const e=V=G.prototype.raycast;G.prototype.raycast=function(r,n){const o=this,s=J(o);let a;s&&o.isMesh&&(a=o.geometry,o.geometry=s),e.call(this,r,n),a&&(o.geometry=a)}}else{if(!V)return;G.prototype.raycast=V,V=null}}let V=null;function Ae(t){const e=new $;for(const r in t.attributes)e.setAttribute(r,t.getAttribute(r));return e.setIndex(t.getIndex()),e}const R=new Array,P="NEEDLE_progressive",L=H("debugprogressive"),oe=Symbol("needle-progressive-texture"),K=new Map,ne=new Set;if(L){let t=function(){e+=1,console.log("Toggle LOD level",e,K),K.forEach((o,s)=>{for(const a of o.keys){const i=s[a];if(i.isBufferGeometry===!0){const u=_.getMeshLODInformation(i),l=u?Math.min(e,u.lods.length):0;s["DEBUG:LOD"]=e,_.assignMeshLOD(s,l),u&&(r=Math.max(r,u.lods.length-1))}else if(s.isMaterial===!0){s["DEBUG:LOD"]=e,_.assignTextureLOD(s,e);break}}}),e>=r&&(e=-1)},e=-1,r=2,n=!1;window.addEventListener("keyup",o=>{o.key==="p"&&t(),o.key==="w"&&(n=!n,ne&&ne.forEach(s=>{s.name!="BackgroundCubeMaterial"&&"wireframe"in s&&(s.wireframe=n)}))})}function ue(t,e,r){var n;if(!L)return;K.has(t)||K.set(t,{keys:[],sourceId:r});const o=K.get(t);((n=o?.keys)==null?void 0:n.includes(e))==!1&&o.keys.push(e)}const M=class{constructor(t,e){c(this,"parser"),c(this,"url"),c(this,"_isLoadingMesh"),c(this,"loadMesh",r=>{var n,o;if(this._isLoadingMesh)return null;const s=(o=(n=this.parser.json.meshes[r])==null?void 0:n.extensions)==null?void 0:o[P];return s?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",r).then(a=>(this._isLoadingMesh=!1,a&&M.registerMesh(this.url,s.guid,a,s.lods.length,void 0,s),a))):null}),L&&console.log("Progressive extension registered for",e),this.parser=t,this.url=e}get name(){return P}static getMeshLODInformation(t){const e=this.getAssignedLODInformation(t);return e!=null&&e.key?this.lodInfos.get(e.key):null}static getMaterialMinMaxLODsCount(t,e){const r=this,n="LODS:minmax",o=t[n];if(o!=null)return o;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[n]=e,e}if(L==="verbose"&&console.log("getMaterialMinMaxLODsCount",t),t.type==="ShaderMaterial"||t.type==="RawShaderMaterial"){const a=t;for(const i of Object.keys(a.uniforms)){const u=a.uniforms[i].value;u?.isTexture===!0&&s(u,e)}}else if(t.isMaterial)for(const a of Object.keys(t)){const i=t[a];i?.isTexture===!0&&s(i,e)}return t[n]=e,e;function s(a,i){const u=r.getAssignedLODInformation(a);if(u){const l=r.lodInfos.get(u.key);if(l&&l.lods){i.min_count=Math.min(i.min_count,l.lods.length),i.max_count=Math.max(i.max_count,l.lods.length);for(let g=0;g<l.lods.length;g++){const d=l.lods[g];d.width&&(i.lods[g]=i.lods[g]||{min_height:1/0,max_height:0},i.lods[g].min_height=Math.min(i.lods[g].min_height,d.height),i.lods[g].max_height=Math.max(i.lods[g].max_height,d.height))}}}}}static hasLODLevelAvailable(t,e){var r;if(Array.isArray(t)){for(const s of t)if(this.hasLODLevelAvailable(s,e))return!0;return!1}if(t.isMaterial===!0){for(const s of Object.keys(t)){const a=t[s];if(a&&a.isTexture&&this.hasLODLevelAvailable(a,e))return!0}return!1}else if(t.isGroup===!0){for(const s of t.children)if(s.isMesh===!0&&this.hasLODLevelAvailable(s,e))return!0}let n,o;if(t.isMesh?n=t.geometry:(t.isBufferGeometry||t.isTexture)&&(n=t),n&&(r=n?.userData)!=null&&r.LODS){const s=n.userData.LODS;if(o=this.lodInfos.get(s.key),e===void 0)return o!=null;if(o)return Array.isArray(o.lods)?e<o.lods.length:e===0}return!1}static assignMeshLOD(t,e){var r;if(!t)return Promise.resolve(null);if(t instanceof G||t.isMesh===!0){const n=t.geometry,o=this.getAssignedLODInformation(n);if(!o)return Promise.resolve(null);for(const s of R)(r=s.onBeforeGetLODMesh)==null||r.call(s,t,e);return t["LOD:requested level"]=e,M.getOrLoadLOD(n,e).then(s=>{if(t["LOD:requested level"]===e){if(delete t["LOD:requested level"],Array.isArray(s)){const a=o.index||0;s=s[a]}s&&n!=s&&s instanceof $&&(t.geometry=s,L&&ue(t,"geometry",o.url))}return s}).catch(s=>(console.error("Error loading mesh LOD",t,s),null))}else L&&console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh",t);return Promise.resolve(null)}static assignTextureLOD(t,e=0){if(!t)return Promise.resolve(null);if(t instanceof ve||t.isMaterial===!0){const r=t,n=[],o=new Array;if(L&&ne.add(r),r.uniforms&&r.isRawShaderMaterial||r.isShaderMaterial===!0){const s=r;for(const a of Object.keys(s.uniforms)){const i=s.uniforms[a].value;if(i?.isTexture===!0){const u=this.assignTextureLODForSlot(i,e,r,a);n.push(u),o.push(a)}}}else for(const s of Object.keys(r)){const a=r[s];if(a?.isTexture===!0){const i=this.assignTextureLODForSlot(a,e,r,s);n.push(i),o.push(s)}}return Promise.all(n).then(s=>{const a=new Array;for(let i=0;i<s.length;i++){const u=s[i],l=o[i];u&&u.isTexture===!0?a.push({material:r,slot:l,texture:u,level:e}):a.push({material:r,slot:l,texture:null,level:e})}return a})}if(t instanceof z||t.isTexture===!0){const r=t;return this.assignTextureLODForSlot(r,e,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(t,e,r,n){return t?.isTexture!==!0?Promise.resolve(null):n==="glyphMap"?Promise.resolve(t):M.getOrLoadLOD(t,e).then(o=>{if(Array.isArray(o))return null;if(o?.isTexture===!0){if(o!=t){if(r&&n){const s=r[n];if(s){const a=this.getAssignedLODInformation(s);if(a&&a?.level<e)return L==="verbose"&&console.warn("Assigned texture level is already higher: ",a.level,e,r,s,o),null}r[n]=o}if(L&&n&&r){const s=this.getAssignedLODInformation(t);s&&ue(r,n,s.url)}}return o}else L=="verbose"&&console.warn("No LOD found for",t,e);return null}).catch(o=>(console.error("Error loading LOD",t,o),null))}afterRoot(t){var e,r;return L&&console.log("AFTER",this.url,t),(e=this.parser.json.textures)==null||e.forEach((n,o)=>{if(n!=null&&n.extensions){const s=n?.extensions[P];if(s){if(!s.lods){L&&console.warn("Texture has no LODs",s);return}let a=!1;for(const i of this.parser.associations.keys())i.isTexture===!0&&this.parser.associations.get(i).textures===o&&(a=!0,M.registerTexture(this.url,i,s.lods.length,o,s));a||this.parser.getDependency("texture",o).then(i=>{i&&M.registerTexture(this.url,i,s.lods.length,o,s)})}}}),(r=this.parser.json.meshes)==null||r.forEach((n,o)=>{if(n!=null&&n.extensions){const s=n?.extensions[P];if(s&&s.lods){for(const a of this.parser.associations.keys())if(a.isMesh){const i=this.parser.associations.get(a);i.meshes===o&&M.registerMesh(this.url,s.guid,a,s.lods.length,i.primitives,s)}}}}),null}static async getOrLoadLOD(t,e){var r,n,o,s;const a=L=="verbose",i=t.userData.LODS;if(!i)return null;const u=i?.key;let l;if(t.isTexture===!0){const g=t;g.source&&g.source[oe]&&(l=g.source[oe])}if(l||(l=M.lodInfos.get(u)),l){if(e>0){let f=!1;const w=Array.isArray(l.lods);if(w&&e>=l.lods.length?f=!0:w||(f=!0),f)return this.lowresCache.get(u)}const g=Array.isArray(l.lods)?(r=l.lods[e])==null?void 0:r.path:l.lods;if(!g)return L&&!l["missing:uri"]&&(l["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+e,l)),null;const d=Se(i.url,g);if(d.endsWith(".glb")||d.endsWith(".gltf")){if(!l.guid)return console.warn("missing pointer for glb/gltf texture",l),null;const f=d+"_"+l.guid,w=this.previouslyLoaded.get(f);if(w!==void 0){a&&console.log(`LOD ${e} was already loading/loaded: ${f}`);let p=await w.catch(N=>(console.error(`Error loading LOD ${e} from ${d}
2
+ `,N),null)),b=!1;if(p==null||(p instanceof z&&t instanceof z?(n=p.image)!=null&&n.data||(o=p.source)!=null&&o.data?p=this.copySettings(t,p):(b=!0,this.previouslyLoaded.delete(f)):p instanceof $&&t instanceof $&&((s=p.attributes.position)!=null&&s.array||(b=!0,this.previouslyLoaded.delete(f)))),!b)return p}const m=l,S=new Promise(async(p,b)=>{const N=new _e;se(N),L&&(await new Promise(y=>setTimeout(y,1e3)),a&&console.warn("Start loading (delayed) "+d,m.guid));let F=d;if(m&&Array.isArray(m.lods)){const y=m.lods[e];y.hash&&(F+="?v="+y.hash)}const x=await N.loadAsync(F).catch(y=>(console.error(`Error loading LOD ${e} from ${d}
3
+ `,y),null));if(!x)return null;const v=x.parser;a&&console.log("Loading finished "+d,m.guid);let D=0;if(x.parser.json.textures){let y=!1;for(const h of x.parser.json.textures){if(h!=null&&h.extensions){const O=h?.extensions[P];if(O!=null&&O.guid&&O.guid===m.guid){y=!0;break}}D++}if(y){let h=await v.getDependency("texture",D);return h&&M.assignLODInformation(i.url,h,u,e,void 0,void 0),a&&console.log('change "'+t.name+'" \u2192 "'+h.name+'"',d,D,h,f),t instanceof z&&(h=this.copySettings(t,h)),h&&(h.guid=m.guid),p(h)}else L&&console.warn("Could not find texture with guid",m.guid)}if(D=0,x.parser.json.meshes){let y=!1;for(const h of x.parser.json.meshes){if(h!=null&&h.extensions){const O=h?.extensions[P];if(O!=null&&O.guid&&O.guid===m.guid){y=!0;break}}D++}if(y){const h=await v.getDependency("mesh",D),O=m;if(a&&console.log(`Loaded Mesh "${h.name}"`,d,D,h,f),h.isMesh===!0){const A=h.geometry;return M.assignLODInformation(i.url,A,u,e,void 0,O.density),p(A)}else{const A=new Array;for(let C=0;C<h.children.length;C++){const k=h.children[C];if(k instanceof G){const j=k.geometry;M.assignLODInformation(i.url,j,u,e,C,O.density),A.push(j)}}return p(A)}}}return p(null)});return this.previouslyLoaded.set(f,S),await S}else if(t instanceof z){a&&console.log("Load texture from uri: "+d);const f=await new De().loadAsync(d);return f?(f.guid=l.guid,f.flipY=!1,f.needsUpdate=!0,f.colorSpace=t.colorSpace,a&&console.log(l,f)):L&&console.warn("failed loading",d),f}}else L&&console.warn(`Can not load LOD ${e}: no LOD info found for "${u}" ${t.name}`,t.type);return null}static assignLODInformation(t,e,r,n,o,s){if(!e)return;e.userData||(e.userData={});const a=new Pe(t,r,n,o,s);e.userData.LODS=a,e.userData.LOD=n}static getAssignedLODInformation(t){var e;return((e=t?.userData)==null?void 0:e.LODS)||null}static copySettings(t,e){return e=e.clone(),L&&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=M;c(O,"registerTexture",(t,e,r,n,o)=>{if(v&&console.log("> Progressive: register texture",n,e.name,e.uuid,e,o),!e){v&&console.error("gltf-progressive: Register texture without texture");return}e.source&&(e.source[oe]=o);const s=o.guid;M.assignLODInformation(t,e,s,r,n,void 0),M.lodInfos.set(s,o),M.lowresCache.set(s,e)}),c(O,"registerMesh",(t,e,r,n,o,s)=>{var a;v&&console.log("> Progressive: register mesh",o,r.name,s,r.uuid,r);const i=r.geometry;if(!i){v&&console.warn("gltf-progressive: Register mesh without geometry");return}i.userData||(i.userData={}),M.assignLODInformation(t,i,e,n,o,s.density),M.lodInfos.set(e,s);let u=M.lowresCache.get(e);u?u.push(r.geometry):u=[r.geometry],M.lowresCache.set(e,u),n>0&&!J(r)&&le(r,i);for(const l of R)(a=l.onRegisteredNewMesh)==null||a.call(l,r,s)}),c(O,"lodInfos",new Map),c(O,"previouslyLoaded",new Map),c(O,"lowresCache",new Map);class Pe{constructor(e,r,n,o,s){c(this,"url"),c(this,"key"),c(this,"level"),c(this,"index"),c(this,"density"),this.url=e,this.key=r,this.level=n,o!=null&&(this.index=o),s!=null&&(this.density=s)}}const W=H("debugprogressive"),Ie=H("noprogressive"),ce=Symbol("Needle:LODSManager"),E={mesh_lod:-1,texture_lod:-1},T=class{constructor(t){c(this,"renderer"),c(this,"projectionScreenMatrix",new ie),c(this,"cameraFrustrum",new Me),c(this,"targetTriangleDensity",2e5),c(this,"updateInterval",0),c(this,"pause",!1),c(this,"_frame",0),c(this,"_originalRender"),c(this,"_sphere",new _e),c(this,"_tempBox",new ae),c(this,"_tempBox2",new ae),c(this,"tempMatrix",new ie),c(this,"_tempWorldPosition",new B),c(this,"_tempBoxSize",new B),c(this,"_tempBox2Size",new B),this.renderer=t}static getObjectLODState(t){var e;return(e=t.userData)==null?void 0:e.LOD_state}static addPlugin(t){R.push(t)}static removePlugin(t){const e=R.indexOf(t);e>=0&&R.splice(e,1)}static get(t){return t[ce]?t[ce]:new T(t)}get plugins(){return R}enable(){if(this._originalRender)return;let t=0;this._originalRender=this.renderer.render;const e=this;re(this.renderer),this.renderer.render=function(r,n){e.renderer.getRenderTarget()==null&&(t=0,e._frame+=1);const o=e._frame,s=t++;e.onBeforeRender(r,n,s,o),e._originalRender.call(this,r,n),e.onAfterRender(r,n,s,o)}}disable(){this._originalRender&&(this.renderer.render=this._originalRender,this._originalRender=void 0)}onBeforeRender(t,e,r,n){}onAfterRender(t,e,r,n){var o,s;if(this.pause)return;const a=this.renderer.renderLists.get(t,0),i=a.opaque;let u=!0;if(i.length===1){const l=i[0].material;(l.name==="EffectMaterial"||l.name==="CopyShader")&&(u=!1)}if(e.parent&&e.parent.type==="CubeCamera"&&(u=!1),u){if(Ie||this.updateInterval>0&&n%this.updateInterval!=0)return;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse),this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix,this.renderer.coordinateSystem);const l=this.targetTriangleDensity;for(const d of i){if(d.material&&(((o=d.geometry)==null?void 0:o.type)==="BoxGeometry"||((s=d.geometry)==null?void 0:s.type)==="BufferGeometry")&&(d.material.name==="SphericalGaussianBlur"||d.material.name=="BackgroundCubeMaterial"||d.material.name==="CubemapFromEquirect"||d.material.name==="EquirectangularToCubeUV")){W&&(d.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(d.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",d,d.material.name,d.material.type)));continue}switch(d.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}const f=d.object;(f instanceof G||f.isMesh)&&this.updateLODs(t,e,f,l,n)}const g=a.transparent;for(const d of g){const f=d.object;(f instanceof G||f.isMesh)&&this.updateLODs(t,e,f,l,n)}}}updateLODs(t,e,r,n,o){var s,a;r.userData||(r.userData={});let i=r.userData.LOD_state;if(i||(i=new Be,r.userData.LOD_state=i),i.frames++<2)return;for(const l of R)(s=l.onBeforeUpdateLOD)==null||s.call(l,this.renderer,t,e,r);this.calculateLodLevel(e,r,i,n,E),E.mesh_lod=Math.round(E.mesh_lod),E.texture_lod=Math.round(E.texture_lod),E.mesh_lod>=0&&this.loadProgressiveMeshes(r,E.mesh_lod);let u=E.texture_lod;if(r.material&&u>=0){const l=r["DEBUG:LOD"];l!=null&&(u=l),this.loadProgressiveTextures(r.material,u)}for(const l of R)(a=l.onAfterUpdatedLOD)==null||a.call(l,this.renderer,t,e,r,E);i.lastLodLevel_Mesh=E.mesh_lod,i.lastLodLevel_Texture=E.texture_lod}loadProgressiveTextures(t,e){if(!t)return;if(Array.isArray(t)){for(const o of t)this.loadProgressiveTextures(o,e);return}const r=t;let n=!1;(r.NEEDLE_LOD==null||e<r.NEEDLE_LOD)&&(n=!0),n&&(r.NEEDLE_LOD=e,O.assignTextureLOD(t,e))}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);if(t.userData||(t.userData={}),t.userData.LOD!==e){t.userData.LOD=e;const r=t.geometry;return O.assignMeshLOD(t,e).then(n=>(n&&t.userData.LOD==e&&r!=t.geometry,n))}return Promise.resolve(null)}static isInside(t,e){const r=t.min,n=t.max,o=(r.x+n.x)*.5,s=(r.y+n.y)*.5;return this._tempPtInside.set(o,s,r.z).applyMatrix4(e).z<0}calculateLodLevel(t,e,r,n,o){var s;if(!e){o.mesh_lod=-1,o.texture_lod=-1;return}if(!t){o.mesh_lod=-1,o.texture_lod=-1;return}let a=10+1;if(W&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const i=O.getMeshLODInformation(e.geometry),u=i?.lods,l=u&&u.length>0,g=O.getMaterialMinMaxLODsCount(e.material),d=g?.min_count!=1/0&&g.min_count>0&&g.max_count>0;if(!l&&!d){o.mesh_lod=0,o.texture_lod=0;return}if(l||(a=0),!((s=this.cameraFrustrum)!=null&&s.intersectsObject(e))){o.mesh_lod=99,o.texture_lod=99;return}const f=e.geometry.boundingBox;if(f&&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 x=t.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(x)){o.mesh_lod=0,o.texture_lod=0;return}}if(this._tempBox.copy(f),this._tempBox.applyMatrix4(e.matrixWorld),T.isInside(this._tempBox,this.projectionScreenMatrix)){o.mesh_lod=0,o.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&w.fov>70){const x=this._tempBox.min,L=this._tempBox.max;let D=x.x,y=x.y,h=L.x,_=L.y;const A=2,C=1.5,k=(x.x+L.x)*.5,j=(x.y+L.y)*.5;D=(D-k)*A+k,y=(y-j)*A+j,h=(h-k)*A+k,_=(_-j)*A+j;const fe=D<0&&h>0?0:Math.min(Math.abs(x.x),Math.abs(L.x)),ge=y<0&&_>0?0:Math.min(Math.abs(x.y),Math.abs(L.y)),Z=Math.max(fe,ge);r.lastCentrality=(C-Z)*(C-Z)*(C-Z)}else r.lastCentrality=1;const m=this._tempBox.getSize(this._tempBoxSize);m.multiplyScalar(.5),screen.availHeight>0&&m.multiplyScalar(this.renderer.domElement.clientHeight/screen.availHeight),m.x*=w.aspect;const S=t.matrixWorldInverse,p=this._tempBox2;p.copy(f),p.applyMatrix4(e.matrixWorld),p.applyMatrix4(S);const b=p.getSize(this._tempBox2Size),N=Math.max(b.x,b.y);if(Math.max(m.x,m.y)!=0&&N!=0&&(m.z=b.z/Math.max(b.x,b.y)*Math.max(m.x,m.y)),r.lastScreenCoverage=Math.max(m.x,m.y,m.z),r.lastScreenspaceVolume.copy(m),r.lastScreenCoverage*=r.lastCentrality,W&&T.debugDrawLine){const x=this.tempMatrix.copy(this.projectionScreenMatrix);x.invert();const L=T.corner0,D=T.corner1,y=T.corner2,h=T.corner3;L.copy(this._tempBox.min),D.copy(this._tempBox.max),D.x=L.x,y.copy(this._tempBox.max),y.y=L.y,h.copy(this._tempBox.max);const _=(L.z+h.z)*.5;L.z=D.z=y.z=h.z=_,L.applyMatrix4(x),D.applyMatrix4(x),y.applyMatrix4(x),h.applyMatrix4(x),T.debugDrawLine(L,D,255),T.debugDrawLine(L,y,255),T.debugDrawLine(D,h,255),T.debugDrawLine(y,h,255)}let F=999;if(u&&r.lastScreenCoverage>0){for(let x=0;x<u.length;x++)if(u[x].density/r.lastScreenCoverage<n){F=x;break}}F<a&&(a=F)}if(o.mesh_lod=a,d)if(r.lastLodLevel_Texture<0){if(o.texture_lod=g.max_count-1,W){const w=g.lods[g.max_count-1];W&&console.log(`First Texture LOD ${o.texture_lod} (${w.max_height}px) - ${e.name}`)}}else{const w=r.lastScreenCoverage*1.5,m=this.renderer.domElement.clientHeight/window.devicePixelRatio*w;for(let S=g.lods.length-1;S>=0;S--){const p=g.lods[S];if(!(Te()&&p.max_height>4096)&&p.max_height>m){o.texture_lod=S,o.texture_lod<r.lastLodLevel_Texture&&W&&console.log(`Texture LOD changed ${r.lastLodLevel_Texture} \u2192 ${o.texture_lod} (${p.max_height}px: ${(100*r.lastScreenCoverage).toFixed(2)} % = ${m.toFixed(0)}px) - ${e.name}`);break}}}else o.texture_lod=0}};let I=T;c(I,"debugDrawLine"),c(I,"corner0",new B),c(I,"corner1",new B),c(I,"corner2",new B),c(I,"corner3",new B),c(I,"_tempPtInside",new B);class Be{constructor(){c(this,"frames",0),c(this,"lastLodLevel_Mesh",-1),c(this,"lastLodLevel_Texture",-1),c(this,"lastScreenCoverage",0),c(this,"lastScreenspaceVolume",new B),c(this,"lastCentrality",0)}}const de=Symbol("NEEDLE_mesh_lod"),Q=Symbol("NEEDLE_texture_lod");function he(t){if(!t)return null;let e=null,r=null;for(let n=t;n!=null;n=Object.getPrototypeOf(n)){const o=Object.getOwnPropertySymbols(n),s=o.find(i=>i.toString()=="Symbol(renderer)"),a=o.find(i=>i.toString()=="Symbol(scene)");!e&&s!=null&&(e=t[s].threeRenderer),!r&&a!=null&&(r=t[a])}if(e){console.log("Adding Needle LODs to modelviewer");const n=I.get(e);if(I.addPlugin(new Ce(t)),n.enable(),r){const o=r.camera||r.traverse(s=>s.type=="PerspectiveCamera")[0];o&&e.render(r,o)}return()=>{n.disable()}}return null}class Ce{constructor(e){c(this,"modelviewer"),c(this,"_didWarnAboutMissingUrl",!1),this.modelviewer=e}onBeforeUpdateLOD(e,r,n,o){this.tryParseMeshLOD(r,o),this.tryParseTextureLOD(r,o)}getUrl(){let e=this.modelviewer.getAttribute("src");return e||(e=this.modelviewer.src),e||(this._didWarnAboutMissingUrl||console.warn("No url found in modelviewer",this.modelviewer),this._didWarnAboutMissingUrl=!0),e}tryGetCurrentGLTF(e){return e._currentGLTF}tryParseTextureLOD(e,r){if(r[Q]==!0)return;r[Q]=!0;const n=this.tryGetCurrentGLTF(e),o=this.getUrl();if(o&&n&&r.material){let s=function(i){var u,l,g;if(i[Q]==!0)return;i[Q]=!0,i.userData&&(i.userData.LOD=-1);const d=Object.keys(i);for(let f=0;f<d.length;f++){const w=d[f],m=i[w];if(m?.isTexture===!0){const S=(l=(u=m.userData)==null?void 0:u.associations)==null?void 0:l.textures,p=n.parser.json.textures[S];if(!p){console.warn("Texture data not found for texture index "+S);continue}if((g=p?.extensions)!=null&&g[P]){const b=p.extensions[P];b&&o&&O.registerTexture(o,m,b.lods.length,S,b)}}}};const a=r.material;if(Array.isArray(a))for(const i of a)s(i);else s(a)}}tryParseMeshLOD(e,r){var n,o;if(r[de]==!0)return;r[de]=!0;const s=this.getUrl();if(!s)return;const a=(o=(n=r.userData)==null?void 0:n.gltfExtensions)==null?void 0:o[P];if(a&&s){const i=r.uuid;O.registerMesh(s,i,r,0,a.lods.length,a)}}}function Re(t,e,r,n){re(e),se(r),r.register(s=>new O(s,t));const o=I.get(e);return n?.enableLODsManager!==!1&&o.enable(),o}document.addEventListener("DOMContentLoaded",()=>{he(document.querySelector("model-viewer"))});export{P as EXTENSION_NAME,I as LODsManager,O as NEEDLE_progressive,se as addDracoAndKTX2Loaders,re as createLoaders,J as getRaycastMesh,he as patchModelViewer,we as setDracoDecoderLocation,be as setKTX2TranscoderLocation,le as setRaycastMesh,Re as useNeedleProgressive,Ee 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 _=M;c(_,"registerTexture",(t,e,r,n,o)=>{if(L&&console.log("> Progressive: register texture",n,e.name,e.uuid,e,o),!e){L&&console.error("gltf-progressive: Register texture without texture");return}e.source&&(e.source[oe]=o);const s=o.guid;M.assignLODInformation(t,e,s,r,n,void 0),M.lodInfos.set(s,o),M.lowresCache.set(s,e)}),c(_,"registerMesh",(t,e,r,n,o,s)=>{var a;L&&console.log("> Progressive: register mesh",o,r.name,s,r.uuid,r);const i=r.geometry;if(!i){L&&console.warn("gltf-progressive: Register mesh without geometry");return}i.userData||(i.userData={}),M.assignLODInformation(t,i,e,n,o,s.density),M.lodInfos.set(e,s);let u=M.lowresCache.get(e);u?u.push(r.geometry):u=[r.geometry],M.lowresCache.set(e,u),n>0&&!J(r)&&le(r,i);for(const l of R)(a=l.onRegisteredNewMesh)==null||a.call(l,r,s)}),c(_,"lodInfos",new Map),c(_,"previouslyLoaded",new Map),c(_,"lowresCache",new Map);class Pe{constructor(e,r,n,o,s){c(this,"url"),c(this,"key"),c(this,"level"),c(this,"index"),c(this,"density"),this.url=e,this.key=r,this.level=n,o!=null&&(this.index=o),s!=null&&(this.density=s)}}const W=H("debugprogressive"),Ie=H("noprogressive"),ce=Symbol("Needle:LODSManager"),E={mesh_lod:-1,texture_lod:-1},T=class{constructor(t){c(this,"renderer"),c(this,"projectionScreenMatrix",new ie),c(this,"cameraFrustrum",new Me),c(this,"targetTriangleDensity",2e5),c(this,"updateInterval",0),c(this,"pause",!1),c(this,"_frame",0),c(this,"_originalRender"),c(this,"_sphere",new Oe),c(this,"_tempBox",new ae),c(this,"_tempBox2",new ae),c(this,"tempMatrix",new ie),c(this,"_tempWorldPosition",new B),c(this,"_tempBoxSize",new B),c(this,"_tempBox2Size",new B),this.renderer=t}static getObjectLODState(t){var e;return(e=t.userData)==null?void 0:e.LOD_state}static addPlugin(t){R.push(t)}static removePlugin(t){const e=R.indexOf(t);e>=0&&R.splice(e,1)}static get(t){return t[ce]?t[ce]:new T(t)}get plugins(){return R}enable(){if(this._originalRender)return;let t=0;this._originalRender=this.renderer.render;const e=this;re(this.renderer),this.renderer.render=function(r,n){e.renderer.getRenderTarget()==null&&(t=0,e._frame+=1);const o=e._frame,s=t++;e.onBeforeRender(r,n,s,o),e._originalRender.call(this,r,n),e.onAfterRender(r,n,s,o)}}disable(){this._originalRender&&(this.renderer.render=this._originalRender,this._originalRender=void 0)}onBeforeRender(t,e,r,n){}onAfterRender(t,e,r,n){var o,s;if(this.pause)return;const a=this.renderer.renderLists.get(t,0),i=a.opaque;let u=!0;if(i.length===1){const l=i[0].material;(l.name==="EffectMaterial"||l.name==="CopyShader")&&(u=!1)}if(e.parent&&e.parent.type==="CubeCamera"&&(u=!1),u){if(Ie||this.updateInterval>0&&n%this.updateInterval!=0)return;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse),this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix,this.renderer.coordinateSystem);const l=this.targetTriangleDensity;for(const d of i){if(d.material&&(((o=d.geometry)==null?void 0:o.type)==="BoxGeometry"||((s=d.geometry)==null?void 0:s.type)==="BufferGeometry")&&(d.material.name==="SphericalGaussianBlur"||d.material.name=="BackgroundCubeMaterial"||d.material.name==="CubemapFromEquirect"||d.material.name==="EquirectangularToCubeUV")){W&&(d.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(d.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",d,d.material.name,d.material.type)));continue}switch(d.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}const f=d.object;(f instanceof G||f.isMesh)&&this.updateLODs(t,e,f,l,n)}const g=a.transparent;for(const d of g){const f=d.object;(f instanceof G||f.isMesh)&&this.updateLODs(t,e,f,l,n)}}}updateLODs(t,e,r,n,o){var s,a;r.userData||(r.userData={});let i=r.userData.LOD_state;if(i||(i=new Be,r.userData.LOD_state=i),i.frames++<2)return;for(const l of R)(s=l.onBeforeUpdateLOD)==null||s.call(l,this.renderer,t,e,r);this.calculateLodLevel(e,r,i,n,E),E.mesh_lod=Math.round(E.mesh_lod),E.texture_lod=Math.round(E.texture_lod),E.mesh_lod>=0&&this.loadProgressiveMeshes(r,E.mesh_lod);let u=E.texture_lod;if(r.material&&u>=0){const l=r["DEBUG:LOD"];l!=null&&(u=l),this.loadProgressiveTextures(r.material,u)}for(const l of R)(a=l.onAfterUpdatedLOD)==null||a.call(l,this.renderer,t,e,r,E);i.lastLodLevel_Mesh=E.mesh_lod,i.lastLodLevel_Texture=E.texture_lod}loadProgressiveTextures(t,e){if(!t)return;if(Array.isArray(t)){for(const o of t)this.loadProgressiveTextures(o,e);return}const r=t;let n=!1;(r.NEEDLE_LOD==null||e<r.NEEDLE_LOD)&&(n=!0),n&&(r.NEEDLE_LOD=e,_.assignTextureLOD(t,e))}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);if(t.userData||(t.userData={}),t.userData.LOD!==e){t.userData.LOD=e;const r=t.geometry;return _.assignMeshLOD(t,e).then(n=>(n&&t.userData.LOD==e&&r!=t.geometry,n))}return Promise.resolve(null)}static isInside(t,e){const r=t.min,n=t.max,o=(r.x+n.x)*.5,s=(r.y+n.y)*.5;return this._tempPtInside.set(o,s,r.z).applyMatrix4(e).z<0}calculateLodLevel(t,e,r,n,o){var s;if(!e){o.mesh_lod=-1,o.texture_lod=-1;return}if(!t){o.mesh_lod=-1,o.texture_lod=-1;return}let a=10+1;if(W&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const i=_.getMeshLODInformation(e.geometry),u=i?.lods,l=u&&u.length>0,g=_.getMaterialMinMaxLODsCount(e.material),d=g?.min_count!=1/0&&g.min_count>0&&g.max_count>0;if(!l&&!d){o.mesh_lod=0,o.texture_lod=0;return}if(l||(a=0),!((s=this.cameraFrustrum)!=null&&s.intersectsObject(e))){o.mesh_lod=99,o.texture_lod=99;return}const f=e.geometry.boundingBox;if(f&&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 x=t.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(x)){o.mesh_lod=0,o.texture_lod=0;return}}if(this._tempBox.copy(f),this._tempBox.applyMatrix4(e.matrixWorld),T.isInside(this._tempBox,this.projectionScreenMatrix)){o.mesh_lod=0,o.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&w.fov>70){const x=this._tempBox.min,v=this._tempBox.max;let D=x.x,y=x.y,h=v.x,O=v.y;const A=2,C=1.5,k=(x.x+v.x)*.5,j=(x.y+v.y)*.5;D=(D-k)*A+k,y=(y-j)*A+j,h=(h-k)*A+k,O=(O-j)*A+j;const fe=D<0&&h>0?0:Math.min(Math.abs(x.x),Math.abs(v.x)),ge=y<0&&O>0?0:Math.min(Math.abs(x.y),Math.abs(v.y)),Z=Math.max(fe,ge);r.lastCentrality=(C-Z)*(C-Z)*(C-Z)}else r.lastCentrality=1;const m=this._tempBox.getSize(this._tempBoxSize);m.multiplyScalar(.5),screen.availHeight>0&&m.multiplyScalar(this.renderer.domElement.clientHeight/screen.availHeight),m.x*=w.aspect;const S=t.matrixWorldInverse,p=this._tempBox2;p.copy(f),p.applyMatrix4(e.matrixWorld),p.applyMatrix4(S);const b=p.getSize(this._tempBox2Size),N=Math.max(b.x,b.y);if(Math.max(m.x,m.y)!=0&&N!=0&&(m.z=b.z/Math.max(b.x,b.y)*Math.max(m.x,m.y)),r.lastScreenCoverage=Math.max(m.x,m.y,m.z),r.lastScreenspaceVolume.copy(m),r.lastScreenCoverage*=r.lastCentrality,W&&T.debugDrawLine){const x=this.tempMatrix.copy(this.projectionScreenMatrix);x.invert();const v=T.corner0,D=T.corner1,y=T.corner2,h=T.corner3;v.copy(this._tempBox.min),D.copy(this._tempBox.max),D.x=v.x,y.copy(this._tempBox.max),y.y=v.y,h.copy(this._tempBox.max);const O=(v.z+h.z)*.5;v.z=D.z=y.z=h.z=O,v.applyMatrix4(x),D.applyMatrix4(x),y.applyMatrix4(x),h.applyMatrix4(x),T.debugDrawLine(v,D,255),T.debugDrawLine(v,y,255),T.debugDrawLine(D,h,255),T.debugDrawLine(y,h,255)}let F=999;if(u&&r.lastScreenCoverage>0){for(let x=0;x<u.length;x++)if(u[x].density/r.lastScreenCoverage<n){F=x;break}}F<a&&(a=F)}if(o.mesh_lod=a,d)if(r.lastLodLevel_Texture<0){if(o.texture_lod=g.max_count-1,W){const w=g.lods[g.max_count-1];W&&console.log(`First Texture LOD ${o.texture_lod} (${w.max_height}px) - ${e.name}`)}}else{const w=r.lastScreenCoverage*1.5,m=this.renderer.domElement.clientHeight/window.devicePixelRatio*w;for(let S=g.lods.length-1;S>=0;S--){const p=g.lods[S];if(!(Te()&&p.max_height>4096)&&p.max_height>m){o.texture_lod=S,o.texture_lod<r.lastLodLevel_Texture&&W&&console.log(`Texture LOD changed ${r.lastLodLevel_Texture} \u2192 ${o.texture_lod} (${p.max_height}px: ${(100*r.lastScreenCoverage).toFixed(2)} % = ${m.toFixed(0)}px) - ${e.name}`);break}}}else o.texture_lod=0}};let I=T;c(I,"debugDrawLine"),c(I,"corner0",new B),c(I,"corner1",new B),c(I,"corner2",new B),c(I,"corner3",new B),c(I,"_tempPtInside",new B);class Be{constructor(){c(this,"frames",0),c(this,"lastLodLevel_Mesh",-1),c(this,"lastLodLevel_Texture",-1),c(this,"lastScreenCoverage",0),c(this,"lastScreenspaceVolume",new B),c(this,"lastCentrality",0)}}const de=Symbol("NEEDLE_mesh_lod"),Q=Symbol("NEEDLE_texture_lod");function he(t){if(!t)return null;let e=null,r=null;for(let n=t;n!=null;n=Object.getPrototypeOf(n)){const o=Object.getOwnPropertySymbols(n),s=o.find(i=>i.toString()=="Symbol(renderer)"),a=o.find(i=>i.toString()=="Symbol(scene)");!e&&s!=null&&(e=t[s].threeRenderer),!r&&a!=null&&(r=t[a])}if(e){console.log("Adding Needle LODs to modelviewer");const n=I.get(e);if(I.addPlugin(new Ce(t)),n.enable(),r){const o=r.camera||r.traverse(s=>s.type=="PerspectiveCamera")[0];o&&e.render(r,o)}return()=>{n.disable()}}return null}class Ce{constructor(e){c(this,"modelviewer"),c(this,"_didWarnAboutMissingUrl",!1),this.modelviewer=e}onBeforeUpdateLOD(e,r,n,o){this.tryParseMeshLOD(r,o),this.tryParseTextureLOD(r,o)}getUrl(){let e=this.modelviewer.getAttribute("src");return e||(e=this.modelviewer.src),e||(this._didWarnAboutMissingUrl||console.warn("No url found in modelviewer",this.modelviewer),this._didWarnAboutMissingUrl=!0),e}tryGetCurrentGLTF(e){return e._currentGLTF}tryParseTextureLOD(e,r){if(r[Q]==!0)return;r[Q]=!0;const n=this.tryGetCurrentGLTF(e),o=this.getUrl();if(o&&n&&r.material){let s=function(i){var u,l,g;if(i[Q]==!0)return;i[Q]=!0,i.userData&&(i.userData.LOD=-1);const d=Object.keys(i);for(let f=0;f<d.length;f++){const w=d[f],m=i[w];if(m?.isTexture===!0){const S=(l=(u=m.userData)==null?void 0:u.associations)==null?void 0:l.textures,p=n.parser.json.textures[S];if(!p){console.warn("Texture data not found for texture index "+S);continue}if((g=p?.extensions)!=null&&g[P]){const b=p.extensions[P];b&&o&&_.registerTexture(o,m,b.lods.length,S,b)}}}};const a=r.material;if(Array.isArray(a))for(const i of a)s(i);else s(a)}}tryParseMeshLOD(e,r){var n,o;if(r[de]==!0)return;r[de]=!0;const s=this.getUrl();if(!s)return;const a=(o=(n=r.userData)==null?void 0:n.gltfExtensions)==null?void 0:o[P];if(a&&s){const i=r.uuid;_.registerMesh(s,i,r,0,a.lods.length,a)}}}function Re(t,e,r,n){re(e),se(r),r.register(s=>new _(s,t));const o=I.get(e);return n?.enableLODsManager!==!1&&o.enable(),o}document.addEventListener("DOMContentLoaded",()=>{he(document.querySelector("model-viewer"))});export{P as EXTENSION_NAME,I as LODsManager,_ as NEEDLE_progressive,se as addDracoAndKTX2Loaders,re as createLoaders,J as getRaycastMesh,he as patchModelViewer,we as setDracoDecoderLocation,be as setKTX2TranscoderLocation,le as setRaycastMesh,Re as useNeedleProgressive,Ee as useRaycastMeshes};
@@ -1,5 +1,5 @@
1
- "use strict";var ge=Object.defineProperty;var pe=(l,e,t)=>e in l?ge(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t;var c=(l,e,t)=>(pe(l,typeof e!="symbol"?e+"":e,t),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const ye=require("three/examples/jsm/libs/meshopt_decoder.module.js"),Le=require("three/examples/jsm/loaders/DRACOLoader.js"),xe=require("three/examples/jsm/loaders/KTX2Loader.js"),g=require("three"),me=require("three/examples/jsm/loaders/GLTFLoader.js");let H="https://www.gstatic.com/draco/versioned/decoders/1.4.1/",ie="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";fetch(H+"draco_decoder.js",{method:"head"}).catch(l=>{H="./include/draco/",ie="./include/ktx2/"});function De(l){H=l}function Me(l){ie=l}let W,re,V;function oe(l){W||(W=new Le.DRACOLoader,W.setDecoderPath(H),W.setDecoderConfig({type:"js"})),V||(V=new xe.KTX2Loader,V.setTranscoderPath(ie)),re||(re=ye.MeshoptDecoder),l?V.detectSupport(l):console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures will probably fail")}function ne(l){l.dracoLoader||l.setDRACOLoader(W),l.ktx2Loader||l.setKTX2Loader(V),l.meshoptDecoder||l.setMeshoptDecoder(re)}function J(l){const t=new URL(window.location.href).searchParams.get(l);return t==null||t==="0"||t==="false"?!1:t===""?!0:t}function _e(l,e){if(e===void 0||e.startsWith("./")||e.startsWith("http")||l===void 0)return e;const t=l.lastIndexOf("/");if(t>=0){const r=l.substring(0,t+1);for(;r.endsWith("/")&&e.startsWith("/");)e=e.substring(1);return r+e}return e}let $;function Oe(){return $!==void 0||($=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),J("debugprogressive")&&console.log("isMobileDevice",$)),$}function Q(l){var e;return((e=l==null?void 0:l.userData)==null?void 0:e["needle:raycast-mesh"])instanceof g.BufferGeometry?l.userData["needle:raycast-mesh"]:null}function ue(l,e){if((l.type==="Mesh"||l.type==="SkinnedMesh")&&!Q(l)){const r=ve(e);r.userData={isRaycastMesh:!0},l.userData||(l.userData={}),l.userData["needle:raycast-mesh"]=r}}function we(l=!0){if(l){if(U)return;const e=U=g.Mesh.prototype.raycast;g.Mesh.prototype.raycast=function(t,r){const s=this,o=Q(s);let i;o&&s.isMesh&&(i=s.geometry,s.geometry=o),e.call(this,t,r),i&&(s.geometry=i)}}else{if(!U)return;g.Mesh.prototype.raycast=U,U=null}}let U=null;function ve(l){const e=new g.BufferGeometry;for(const t in l.attributes)e.setAttribute(t,l.getAttribute(t));return e.setIndex(l.getIndex()),e}const I=new Array,C="NEEDLE_progressive",w=J("debugprogressive"),te=Symbol("needle-progressive-texture"),q=new Map,se=new Set;if(w){let l=function(){e+=1,console.log("Toggle LOD level",e,q),q.forEach((s,o)=>{for(const i of s.keys){const n=o[i];if(n.isBufferGeometry===!0){const a=S.getMeshLODInformation(n),h=a?Math.min(e,a.lods.length):0;o["DEBUG:LOD"]=e,S.assignMeshLOD(o,h),a&&(t=Math.max(t,a.lods.length-1))}else if(o.isMaterial===!0){o["DEBUG:LOD"]=e,S.assignTextureLOD(o,e);break}}}),e>=t&&(e=-1)},e=-1,t=2,r=!1;window.addEventListener("keyup",s=>{s.key==="p"&&l(),s.key==="w"&&(r=!r,se&&se.forEach(o=>{o.name!="BackgroundCubeMaterial"&&"wireframe"in o&&(o.wireframe=r)}))})}function ae(l,e,t){var s;if(!w)return;q.has(l)||q.set(l,{keys:[],sourceId:t});const r=q.get(l);((s=r==null?void 0:r.keys)==null?void 0:s.includes(e))==!1&&r.keys.push(e)}const v=class{constructor(e,t){c(this,"parser");c(this,"url");c(this,"_isLoadingMesh");c(this,"loadMesh",e=>{var r,s;if(this._isLoadingMesh)return null;const t=(s=(r=this.parser.json.meshes[e])==null?void 0:r.extensions)==null?void 0:s[C];return t?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",e).then(o=>(this._isLoadingMesh=!1,o&&v.registerMesh(this.url,t.guid,o,t.lods.length,void 0,t),o))):null});w&&console.log("Progressive extension registered for",t),this.parser=e,this.url=t}get name(){return C}static getMeshLODInformation(e){const t=this.getAssignedLODInformation(e);return t!=null&&t.key?this.lodInfos.get(t.key):null}static getMaterialMinMaxLODsCount(e,t){const r=this,s="LODS:minmax",o=e[s];if(o!=null)return o;if(t||(t={min_count:1/0,max_count:0,lods:[]}),Array.isArray(e)){for(const n of e)this.getMaterialMinMaxLODsCount(n,t);return e[s]=t,t}if(w==="verbose"&&console.log("getMaterialMinMaxLODsCount",e),e.type==="ShaderMaterial"||e.type==="RawShaderMaterial"){const n=e;for(const a of Object.keys(n.uniforms)){const h=n.uniforms[a].value;(h==null?void 0:h.isTexture)===!0&&i(h,t)}}else if(e.isMaterial)for(const n of Object.keys(e)){const a=e[n];(a==null?void 0:a.isTexture)===!0&&i(a,t)}return e[s]=t,t;function i(n,a){const h=r.getAssignedLODInformation(n);if(h){const d=r.lodInfos.get(h.key);if(d&&d.lods){a.min_count=Math.min(a.min_count,d.lods.length),a.max_count=Math.max(a.max_count,d.lods.length);for(let p=0;p<d.lods.length;p++){const f=d.lods[p];f.width&&(a.lods[p]=a.lods[p]||{min_height:1/0,max_height:0},a.lods[p].min_height=Math.min(a.lods[p].min_height,f.height),a.lods[p].max_height=Math.max(a.lods[p].max_height,f.height))}}}}}static hasLODLevelAvailable(e,t){var o;if(Array.isArray(e)){for(const i of e)if(this.hasLODLevelAvailable(i,t))return!0;return!1}if(e.isMaterial===!0){for(const i of Object.keys(e)){const n=e[i];if(n&&n.isTexture&&this.hasLODLevelAvailable(n,t))return!0}return!1}else if(e.isGroup===!0){for(const i of e.children)if(i.isMesh===!0&&this.hasLODLevelAvailable(i,t))return!0}let r,s;if(e.isMesh?r=e.geometry:(e.isBufferGeometry||e.isTexture)&&(r=e),r&&(o=r==null?void 0:r.userData)!=null&&o.LODS){const i=r.userData.LODS;if(s=this.lodInfos.get(i.key),t===void 0)return s!=null;if(s)return Array.isArray(s.lods)?t<s.lods.length:t===0}return!1}static assignMeshLOD(e,t){var r;if(!e)return Promise.resolve(null);if(e instanceof g.Mesh||e.isMesh===!0){const s=e.geometry,o=this.getAssignedLODInformation(s);if(!o)return Promise.resolve(null);for(const i of I)(r=i.onBeforeGetLODMesh)==null||r.call(i,e,t);return e["LOD:requested level"]=t,v.getOrLoadLOD(s,t).then(i=>{if(e["LOD:requested level"]===t){if(delete e["LOD:requested level"],Array.isArray(i)){const n=o.index||0;i=i[n]}i&&s!=i&&i instanceof g.BufferGeometry&&(e.geometry=i,w&&ae(e,"geometry",o.url))}return i}).catch(i=>(console.error("Error loading mesh LOD",e,i),null))}else w&&console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh",e);return Promise.resolve(null)}static assignTextureLOD(e,t=0){if(!e)return Promise.resolve(null);if(e instanceof g.Material||e.isMaterial===!0){const r=e,s=[],o=new Array;if(w&&se.add(r),r.uniforms&&r.isRawShaderMaterial||r.isShaderMaterial===!0){const i=r;for(const n of Object.keys(i.uniforms)){const a=i.uniforms[n].value;if((a==null?void 0:a.isTexture)===!0){const h=this.assignTextureLODForSlot(a,t,r,n);s.push(h),o.push(n)}}}else for(const i of Object.keys(r)){const n=r[i];if((n==null?void 0:n.isTexture)===!0){const a=this.assignTextureLODForSlot(n,t,r,i);s.push(a),o.push(i)}}return Promise.all(s).then(i=>{const n=new Array;for(let a=0;a<i.length;a++){const h=i[a],d=o[a];h&&h.isTexture===!0?n.push({material:r,slot:d,texture:h,level:t}):n.push({material:r,slot:d,texture:null,level:t})}return n})}if(e instanceof g.Texture||e.isTexture===!0){const r=e;return this.assignTextureLODForSlot(r,t,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(e,t,r,s){return(e==null?void 0:e.isTexture)!==!0?Promise.resolve(null):s==="glyphMap"?Promise.resolve(e):v.getOrLoadLOD(e,t).then(o=>{if(Array.isArray(o))return null;if((o==null?void 0:o.isTexture)===!0){if(o!=e){if(r&&s){const i=r[s];if(i){const n=this.getAssignedLODInformation(i);if(n&&(n==null?void 0:n.level)<t)return w==="verbose"&&console.warn("Assigned texture level is already higher: ",n.level,t,r,i,o),null}r[s]=o}if(w&&s&&r){const i=this.getAssignedLODInformation(e);i&&ae(r,s,i.url)}}return o}else w=="verbose"&&console.warn("No LOD found for",e,t);return null}).catch(o=>(console.error("Error loading LOD",e,o),null))}afterRoot(e){var t,r;return w&&console.log("AFTER",this.url,e),(t=this.parser.json.textures)==null||t.forEach((s,o)=>{if(s!=null&&s.extensions){const i=s==null?void 0:s.extensions[C];if(i){let n=!1;for(const a of this.parser.associations.keys())a.isTexture===!0&&this.parser.associations.get(a).textures===o&&(n=!0,v.registerTexture(this.url,a,i.lods.length,o,i));n||this.parser.getDependency("texture",o).then(a=>{a&&v.registerTexture(this.url,a,i.lods.length,o,i)})}}}),(r=this.parser.json.meshes)==null||r.forEach((s,o)=>{if(s!=null&&s.extensions){const i=s==null?void 0:s.extensions[C];if(i&&i.lods){for(const n of this.parser.associations.keys())if(n.isMesh){const a=this.parser.associations.get(n);a.meshes===o&&v.registerMesh(this.url,i.guid,n,i.lods.length,a.primitives,i)}}}}),null}static async getOrLoadLOD(e,t){var n,a,h,d;const r=w=="verbose",s=e.userData.LODS;if(!s)return null;const o=s==null?void 0:s.key;let i;if(e.isTexture===!0){const p=e;p.source&&p.source[te]&&(i=p.source[te])}if(i||(i=v.lodInfos.get(o)),i){if(t>0){let x=!1;const M=Array.isArray(i.lods);if(M&&t>=i.lods.length?x=!0:M||(x=!0),x)return this.lowresCache.get(o)}const p=Array.isArray(i.lods)?(n=i.lods[t])==null?void 0:n.path:i.lods;if(!p)return w&&!i["missing:uri"]&&(i["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+t,i)),null;const f=_e(s.url,p);if(f.endsWith(".glb")||f.endsWith(".gltf")){if(!i.guid)return console.warn("missing pointer for glb/gltf texture",i),null;const x=f+"_"+i.guid,M=this.previouslyLoaded.get(x);if(M!==void 0){r&&console.log(`LOD ${t} was already loading/loaded: ${x}`);let m=await M.catch(F=>(console.error(`Error loading LOD ${t} from ${f}
2
- `,F),null)),A=!1;if(m==null||(m instanceof g.Texture&&e instanceof g.Texture?(a=m.image)!=null&&a.data||(h=m.source)!=null&&h.data?m=this.copySettings(e,m):(A=!0,this.previouslyLoaded.delete(x)):m instanceof g.BufferGeometry&&e instanceof g.BufferGeometry&&((d=m.attributes.position)!=null&&d.array||(A=!0,this.previouslyLoaded.delete(x)))),!A)return m}const _=i,O=new Promise(async(m,A)=>{const F=new me.GLTFLoader;ne(F),w&&(await new Promise(y=>setTimeout(y,1e3)),r&&console.warn("Start loading (delayed) "+f,_.guid));let Z=f;if(_&&Array.isArray(_.lods)){const y=_.lods[t];y.hash&&(Z+="?v="+y.hash)}const R=await F.loadAsync(Z).catch(y=>(console.error(`Error loading LOD ${t} from ${f}
3
- `,y),null));if(!R)return null;const j=R.parser;r&&console.log("Loading finished "+f,_.guid);let L=0;if(R.parser.json.textures){let y=!1;for(const u of R.parser.json.textures){if(u!=null&&u.extensions){const D=u==null?void 0:u.extensions[C];if(D!=null&&D.guid&&D.guid===_.guid){y=!0;break}}L++}if(y){let u=await j.getDependency("texture",L);return u&&v.assignLODInformation(s.url,u,o,t,void 0,void 0),r&&console.log('change "'+e.name+'" → "'+u.name+'"',f,L,u,x),e instanceof g.Texture&&(u=this.copySettings(e,u)),u&&(u.guid=_.guid),m(u)}else w&&console.warn("Could not find texture with guid",_.guid)}if(L=0,R.parser.json.meshes){let y=!1;for(const u of R.parser.json.meshes){if(u!=null&&u.extensions){const D=u==null?void 0:u.extensions[C];if(D!=null&&D.guid&&D.guid===_.guid){y=!0;break}}L++}if(y){const u=await j.getDependency("mesh",L),D=_;if(r&&console.log(`Loaded Mesh "${u.name}"`,f,L,u,x),u.isMesh===!0){const T=u.geometry;return v.assignLODInformation(s.url,T,o,t,void 0,D.density),m(T)}else{const T=new Array;for(let B=0;B<u.children.length;B++){const G=u.children[B];if(G instanceof g.Mesh){const N=G.geometry;v.assignLODInformation(s.url,N,o,t,B,D.density),T.push(N)}}return m(T)}}}return m(null)});return this.previouslyLoaded.set(x,O),await O}else if(e instanceof g.Texture){r&&console.log("Load texture from uri: "+f);const M=await new g.TextureLoader().loadAsync(f);return M?(M.guid=i.guid,M.flipY=!1,M.needsUpdate=!0,M.colorSpace=e.colorSpace,r&&console.log(i,M)):w&&console.warn("failed loading",f),M}}else w&&console.warn(`Can not load LOD ${t}: no LOD info found for "${o}" ${e.name}`,e.type);return null}static assignLODInformation(e,t,r,s,o,i){if(!t)return;t.userData||(t.userData={});const n=new Se(e,r,s,o,i);t.userData.LODS=n,t.userData.LOD=s}static getAssignedLODInformation(e){var t;return((t=e==null?void 0:e.userData)==null?void 0:t.LODS)||null}static copySettings(e,t){return t=t.clone(),w&&console.warn(`Copying texture settings
1
+ "use strict";var ge=Object.defineProperty;var pe=(l,e,t)=>e in l?ge(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t;var c=(l,e,t)=>(pe(l,typeof e!="symbol"?e+"":e,t),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const ye=require("three/examples/jsm/libs/meshopt_decoder.module.js"),Le=require("three/examples/jsm/loaders/DRACOLoader.js"),xe=require("three/examples/jsm/loaders/KTX2Loader.js"),g=require("three"),me=require("three/examples/jsm/loaders/GLTFLoader.js");let H="https://www.gstatic.com/draco/versioned/decoders/1.4.1/",ie="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";fetch(H+"draco_decoder.js",{method:"head"}).catch(l=>{H="./include/draco/",ie="./include/ktx2/"});function De(l){H=l}function Me(l){ie=l}let W,re,V;function oe(l){W||(W=new Le.DRACOLoader,W.setDecoderPath(H),W.setDecoderConfig({type:"js"})),V||(V=new xe.KTX2Loader,V.setTranscoderPath(ie)),re||(re=ye.MeshoptDecoder),l?V.detectSupport(l):console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures will probably fail")}function ne(l){l.dracoLoader||l.setDRACOLoader(W),l.ktx2Loader||l.setKTX2Loader(V),l.meshoptDecoder||l.setMeshoptDecoder(re)}function J(l){const t=new URL(window.location.href).searchParams.get(l);return t==null||t==="0"||t==="false"?!1:t===""?!0:t}function _e(l,e){if(e===void 0||e.startsWith("./")||e.startsWith("http")||l===void 0)return e;const t=l.lastIndexOf("/");if(t>=0){const r=l.substring(0,t+1);for(;r.endsWith("/")&&e.startsWith("/");)e=e.substring(1);return r+e}return e}let $;function Oe(){return $!==void 0||($=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),J("debugprogressive")&&console.log("isMobileDevice",$)),$}function Q(l){var e;return((e=l==null?void 0:l.userData)==null?void 0:e["needle:raycast-mesh"])instanceof g.BufferGeometry?l.userData["needle:raycast-mesh"]:null}function ue(l,e){if((l.type==="Mesh"||l.type==="SkinnedMesh")&&!Q(l)){const r=ve(e);r.userData={isRaycastMesh:!0},l.userData||(l.userData={}),l.userData["needle:raycast-mesh"]=r}}function we(l=!0){if(l){if(U)return;const e=U=g.Mesh.prototype.raycast;g.Mesh.prototype.raycast=function(t,r){const i=this,o=Q(i);let s;o&&i.isMesh&&(s=i.geometry,i.geometry=o),e.call(this,t,r),s&&(i.geometry=s)}}else{if(!U)return;g.Mesh.prototype.raycast=U,U=null}}let U=null;function ve(l){const e=new g.BufferGeometry;for(const t in l.attributes)e.setAttribute(t,l.getAttribute(t));return e.setIndex(l.getIndex()),e}const I=new Array,C="NEEDLE_progressive",M=J("debugprogressive"),te=Symbol("needle-progressive-texture"),q=new Map,se=new Set;if(M){let l=function(){e+=1,console.log("Toggle LOD level",e,q),q.forEach((i,o)=>{for(const s of i.keys){const n=o[s];if(n.isBufferGeometry===!0){const a=S.getMeshLODInformation(n),h=a?Math.min(e,a.lods.length):0;o["DEBUG:LOD"]=e,S.assignMeshLOD(o,h),a&&(t=Math.max(t,a.lods.length-1))}else if(o.isMaterial===!0){o["DEBUG:LOD"]=e,S.assignTextureLOD(o,e);break}}}),e>=t&&(e=-1)},e=-1,t=2,r=!1;window.addEventListener("keyup",i=>{i.key==="p"&&l(),i.key==="w"&&(r=!r,se&&se.forEach(o=>{o.name!="BackgroundCubeMaterial"&&"wireframe"in o&&(o.wireframe=r)}))})}function ae(l,e,t){var i;if(!M)return;q.has(l)||q.set(l,{keys:[],sourceId:t});const r=q.get(l);((i=r==null?void 0:r.keys)==null?void 0:i.includes(e))==!1&&r.keys.push(e)}const v=class{constructor(e,t){c(this,"parser");c(this,"url");c(this,"_isLoadingMesh");c(this,"loadMesh",e=>{var r,i;if(this._isLoadingMesh)return null;const t=(i=(r=this.parser.json.meshes[e])==null?void 0:r.extensions)==null?void 0:i[C];return t?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",e).then(o=>(this._isLoadingMesh=!1,o&&v.registerMesh(this.url,t.guid,o,t.lods.length,void 0,t),o))):null});M&&console.log("Progressive extension registered for",t),this.parser=e,this.url=t}get name(){return C}static getMeshLODInformation(e){const t=this.getAssignedLODInformation(e);return t!=null&&t.key?this.lodInfos.get(t.key):null}static getMaterialMinMaxLODsCount(e,t){const r=this,i="LODS:minmax",o=e[i];if(o!=null)return o;if(t||(t={min_count:1/0,max_count:0,lods:[]}),Array.isArray(e)){for(const n of e)this.getMaterialMinMaxLODsCount(n,t);return e[i]=t,t}if(M==="verbose"&&console.log("getMaterialMinMaxLODsCount",e),e.type==="ShaderMaterial"||e.type==="RawShaderMaterial"){const n=e;for(const a of Object.keys(n.uniforms)){const h=n.uniforms[a].value;(h==null?void 0:h.isTexture)===!0&&s(h,t)}}else if(e.isMaterial)for(const n of Object.keys(e)){const a=e[n];(a==null?void 0:a.isTexture)===!0&&s(a,t)}return e[i]=t,t;function s(n,a){const h=r.getAssignedLODInformation(n);if(h){const d=r.lodInfos.get(h.key);if(d&&d.lods){a.min_count=Math.min(a.min_count,d.lods.length),a.max_count=Math.max(a.max_count,d.lods.length);for(let p=0;p<d.lods.length;p++){const f=d.lods[p];f.width&&(a.lods[p]=a.lods[p]||{min_height:1/0,max_height:0},a.lods[p].min_height=Math.min(a.lods[p].min_height,f.height),a.lods[p].max_height=Math.max(a.lods[p].max_height,f.height))}}}}}static hasLODLevelAvailable(e,t){var o;if(Array.isArray(e)){for(const s of e)if(this.hasLODLevelAvailable(s,t))return!0;return!1}if(e.isMaterial===!0){for(const s of Object.keys(e)){const n=e[s];if(n&&n.isTexture&&this.hasLODLevelAvailable(n,t))return!0}return!1}else if(e.isGroup===!0){for(const s of e.children)if(s.isMesh===!0&&this.hasLODLevelAvailable(s,t))return!0}let r,i;if(e.isMesh?r=e.geometry:(e.isBufferGeometry||e.isTexture)&&(r=e),r&&(o=r==null?void 0:r.userData)!=null&&o.LODS){const s=r.userData.LODS;if(i=this.lodInfos.get(s.key),t===void 0)return i!=null;if(i)return Array.isArray(i.lods)?t<i.lods.length:t===0}return!1}static assignMeshLOD(e,t){var r;if(!e)return Promise.resolve(null);if(e instanceof g.Mesh||e.isMesh===!0){const i=e.geometry,o=this.getAssignedLODInformation(i);if(!o)return Promise.resolve(null);for(const s of I)(r=s.onBeforeGetLODMesh)==null||r.call(s,e,t);return e["LOD:requested level"]=t,v.getOrLoadLOD(i,t).then(s=>{if(e["LOD:requested level"]===t){if(delete e["LOD:requested level"],Array.isArray(s)){const n=o.index||0;s=s[n]}s&&i!=s&&s instanceof g.BufferGeometry&&(e.geometry=s,M&&ae(e,"geometry",o.url))}return s}).catch(s=>(console.error("Error loading mesh LOD",e,s),null))}else M&&console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh",e);return Promise.resolve(null)}static assignTextureLOD(e,t=0){if(!e)return Promise.resolve(null);if(e instanceof g.Material||e.isMaterial===!0){const r=e,i=[],o=new Array;if(M&&se.add(r),r.uniforms&&r.isRawShaderMaterial||r.isShaderMaterial===!0){const s=r;for(const n of Object.keys(s.uniforms)){const a=s.uniforms[n].value;if((a==null?void 0:a.isTexture)===!0){const h=this.assignTextureLODForSlot(a,t,r,n);i.push(h),o.push(n)}}}else for(const s of Object.keys(r)){const n=r[s];if((n==null?void 0:n.isTexture)===!0){const a=this.assignTextureLODForSlot(n,t,r,s);i.push(a),o.push(s)}}return Promise.all(i).then(s=>{const n=new Array;for(let a=0;a<s.length;a++){const h=s[a],d=o[a];h&&h.isTexture===!0?n.push({material:r,slot:d,texture:h,level:t}):n.push({material:r,slot:d,texture:null,level:t})}return n})}if(e instanceof g.Texture||e.isTexture===!0){const r=e;return this.assignTextureLODForSlot(r,t,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(e,t,r,i){return(e==null?void 0:e.isTexture)!==!0?Promise.resolve(null):i==="glyphMap"?Promise.resolve(e):v.getOrLoadLOD(e,t).then(o=>{if(Array.isArray(o))return null;if((o==null?void 0:o.isTexture)===!0){if(o!=e){if(r&&i){const s=r[i];if(s){const n=this.getAssignedLODInformation(s);if(n&&(n==null?void 0:n.level)<t)return M==="verbose"&&console.warn("Assigned texture level is already higher: ",n.level,t,r,s,o),null}r[i]=o}if(M&&i&&r){const s=this.getAssignedLODInformation(e);s&&ae(r,i,s.url)}}return o}else M=="verbose"&&console.warn("No LOD found for",e,t);return null}).catch(o=>(console.error("Error loading LOD",e,o),null))}afterRoot(e){var t,r;return M&&console.log("AFTER",this.url,e),(t=this.parser.json.textures)==null||t.forEach((i,o)=>{if(i!=null&&i.extensions){const s=i==null?void 0:i.extensions[C];if(s){if(!s.lods){M&&console.warn("Texture has no LODs",s);return}let n=!1;for(const a of this.parser.associations.keys())a.isTexture===!0&&this.parser.associations.get(a).textures===o&&(n=!0,v.registerTexture(this.url,a,s.lods.length,o,s));n||this.parser.getDependency("texture",o).then(a=>{a&&v.registerTexture(this.url,a,s.lods.length,o,s)})}}}),(r=this.parser.json.meshes)==null||r.forEach((i,o)=>{if(i!=null&&i.extensions){const s=i==null?void 0:i.extensions[C];if(s&&s.lods){for(const n of this.parser.associations.keys())if(n.isMesh){const a=this.parser.associations.get(n);a.meshes===o&&v.registerMesh(this.url,s.guid,n,s.lods.length,a.primitives,s)}}}}),null}static async getOrLoadLOD(e,t){var n,a,h,d;const r=M=="verbose",i=e.userData.LODS;if(!i)return null;const o=i==null?void 0:i.key;let s;if(e.isTexture===!0){const p=e;p.source&&p.source[te]&&(s=p.source[te])}if(s||(s=v.lodInfos.get(o)),s){if(t>0){let x=!1;const _=Array.isArray(s.lods);if(_&&t>=s.lods.length?x=!0:_||(x=!0),x)return this.lowresCache.get(o)}const p=Array.isArray(s.lods)?(n=s.lods[t])==null?void 0:n.path:s.lods;if(!p)return M&&!s["missing:uri"]&&(s["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+t,s)),null;const f=_e(i.url,p);if(f.endsWith(".glb")||f.endsWith(".gltf")){if(!s.guid)return console.warn("missing pointer for glb/gltf texture",s),null;const x=f+"_"+s.guid,_=this.previouslyLoaded.get(x);if(_!==void 0){r&&console.log(`LOD ${t} was already loading/loaded: ${x}`);let m=await _.catch(F=>(console.error(`Error loading LOD ${t} from ${f}
2
+ `,F),null)),A=!1;if(m==null||(m instanceof g.Texture&&e instanceof g.Texture?(a=m.image)!=null&&a.data||(h=m.source)!=null&&h.data?m=this.copySettings(e,m):(A=!0,this.previouslyLoaded.delete(x)):m instanceof g.BufferGeometry&&e instanceof g.BufferGeometry&&((d=m.attributes.position)!=null&&d.array||(A=!0,this.previouslyLoaded.delete(x)))),!A)return m}const O=s,w=new Promise(async(m,A)=>{const F=new me.GLTFLoader;ne(F),M&&(await new Promise(y=>setTimeout(y,1e3)),r&&console.warn("Start loading (delayed) "+f,O.guid));let Z=f;if(O&&Array.isArray(O.lods)){const y=O.lods[t];y.hash&&(Z+="?v="+y.hash)}const R=await F.loadAsync(Z).catch(y=>(console.error(`Error loading LOD ${t} from ${f}
3
+ `,y),null));if(!R)return null;const j=R.parser;r&&console.log("Loading finished "+f,O.guid);let L=0;if(R.parser.json.textures){let y=!1;for(const u of R.parser.json.textures){if(u!=null&&u.extensions){const D=u==null?void 0:u.extensions[C];if(D!=null&&D.guid&&D.guid===O.guid){y=!0;break}}L++}if(y){let u=await j.getDependency("texture",L);return u&&v.assignLODInformation(i.url,u,o,t,void 0,void 0),r&&console.log('change "'+e.name+'" → "'+u.name+'"',f,L,u,x),e instanceof g.Texture&&(u=this.copySettings(e,u)),u&&(u.guid=O.guid),m(u)}else M&&console.warn("Could not find texture with guid",O.guid)}if(L=0,R.parser.json.meshes){let y=!1;for(const u of R.parser.json.meshes){if(u!=null&&u.extensions){const D=u==null?void 0:u.extensions[C];if(D!=null&&D.guid&&D.guid===O.guid){y=!0;break}}L++}if(y){const u=await j.getDependency("mesh",L),D=O;if(r&&console.log(`Loaded Mesh "${u.name}"`,f,L,u,x),u.isMesh===!0){const T=u.geometry;return v.assignLODInformation(i.url,T,o,t,void 0,D.density),m(T)}else{const T=new Array;for(let B=0;B<u.children.length;B++){const G=u.children[B];if(G instanceof g.Mesh){const N=G.geometry;v.assignLODInformation(i.url,N,o,t,B,D.density),T.push(N)}}return m(T)}}}return m(null)});return this.previouslyLoaded.set(x,w),await w}else if(e instanceof g.Texture){r&&console.log("Load texture from uri: "+f);const _=await new g.TextureLoader().loadAsync(f);return _?(_.guid=s.guid,_.flipY=!1,_.needsUpdate=!0,_.colorSpace=e.colorSpace,r&&console.log(s,_)):M&&console.warn("failed loading",f),_}}else M&&console.warn(`Can not load LOD ${t}: no LOD info found for "${o}" ${e.name}`,e.type);return null}static assignLODInformation(e,t,r,i,o,s){if(!t)return;t.userData||(t.userData={});const n=new Se(e,r,i,o,s);t.userData.LODS=n,t.userData.LOD=i}static getAssignedLODInformation(e){var t;return((t=e==null?void 0:e.userData)==null?void 0:t.LODS)||null}static copySettings(e,t){return t=t.clone(),M&&console.warn(`Copying texture settings
4
4
  `,e.uuid,`
5
- `,t.uuid),t.offset=e.offset,t.repeat=e.repeat,t.colorSpace=e.colorSpace,t.magFilter=e.magFilter,t.minFilter=e.minFilter,t.wrapS=e.wrapS,t.wrapT=e.wrapT,t.flipY=e.flipY,t.anisotropy=e.anisotropy,t.mipmaps||(t.generateMipmaps=e.generateMipmaps),t}};let S=v;c(S,"registerTexture",(e,t,r,s,o)=>{if(w&&console.log("> Progressive: register texture",s,t.name,t.uuid,t,o),!t){w&&console.error("gltf-progressive: Register texture without texture");return}t.source&&(t.source[te]=o);const i=o.guid;v.assignLODInformation(e,t,i,r,s,void 0),v.lodInfos.set(i,o),v.lowresCache.set(i,t)}),c(S,"registerMesh",(e,t,r,s,o,i)=>{var h;w&&console.log("> Progressive: register mesh",o,r.name,i,r.uuid,r);const n=r.geometry;if(!n){w&&console.warn("gltf-progressive: Register mesh without geometry");return}n.userData||(n.userData={}),v.assignLODInformation(e,n,t,s,o,i.density),v.lodInfos.set(t,i);let a=v.lowresCache.get(t);a?a.push(r.geometry):a=[r.geometry],v.lowresCache.set(t,a),s>0&&!Q(r)&&ue(r,n);for(const d of I)(h=d.onRegisteredNewMesh)==null||h.call(d,r,i)}),c(S,"lodInfos",new Map),c(S,"previouslyLoaded",new Map),c(S,"lowresCache",new Map);class Se{constructor(e,t,r,s,o){c(this,"url");c(this,"key");c(this,"level");c(this,"index");c(this,"density");this.url=e,this.key=t,this.level=r,s!=null&&(this.index=s),o!=null&&(this.density=o)}}const z=J("debugprogressive"),Te=J("noprogressive"),le=Symbol("Needle:LODSManager"),E={mesh_lod:-1,texture_lod:-1},b=class{constructor(e){c(this,"renderer");c(this,"projectionScreenMatrix",new g.Matrix4);c(this,"cameraFrustrum",new g.Frustum);c(this,"targetTriangleDensity",2e5);c(this,"updateInterval",0);c(this,"pause",!1);c(this,"_frame",0);c(this,"_originalRender");c(this,"_sphere",new g.Sphere);c(this,"_tempBox",new g.Box3);c(this,"_tempBox2",new g.Box3);c(this,"tempMatrix",new g.Matrix4);c(this,"_tempWorldPosition",new g.Vector3);c(this,"_tempBoxSize",new g.Vector3);c(this,"_tempBox2Size",new g.Vector3);this.renderer=e}static getObjectLODState(e){var t;return(t=e.userData)==null?void 0:t.LOD_state}static addPlugin(e){I.push(e)}static removePlugin(e){const t=I.indexOf(e);t>=0&&I.splice(t,1)}static get(e){return e[le]?e[le]:new b(e)}get plugins(){return I}enable(){if(this._originalRender)return;let e=0;this._originalRender=this.renderer.render;const t=this;oe(this.renderer),this.renderer.render=function(r,s){t.renderer.getRenderTarget()==null&&(e=0,t._frame+=1);const i=t._frame,n=e++;t.onBeforeRender(r,s,n,i),t._originalRender.call(this,r,s),t.onAfterRender(r,s,n,i)}}disable(){this._originalRender&&(this.renderer.render=this._originalRender,this._originalRender=void 0)}onBeforeRender(e,t,r,s){}onAfterRender(e,t,r,s){var a,h;if(this.pause)return;const o=this.renderer.renderLists.get(e,0),i=o.opaque;let n=!0;if(i.length===1){const d=i[0].material;(d.name==="EffectMaterial"||d.name==="CopyShader")&&(n=!1)}if(t.parent&&t.parent.type==="CubeCamera"&&(n=!1),n){if(Te||this.updateInterval>0&&s%this.updateInterval!=0)return;this.projectionScreenMatrix.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse),this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix,this.renderer.coordinateSystem);const d=this.targetTriangleDensity;for(const f of i){if(f.material&&(((a=f.geometry)==null?void 0:a.type)==="BoxGeometry"||((h=f.geometry)==null?void 0:h.type)==="BufferGeometry")&&(f.material.name==="SphericalGaussianBlur"||f.material.name=="BackgroundCubeMaterial"||f.material.name==="CubemapFromEquirect"||f.material.name==="EquirectangularToCubeUV")){z&&(f.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(f.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",f,f.material.name,f.material.type)));continue}switch(f.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}const x=f.object;(x instanceof g.Mesh||x.isMesh)&&this.updateLODs(e,t,x,d,s)}const p=o.transparent;for(const f of p){const x=f.object;(x instanceof g.Mesh||x.isMesh)&&this.updateLODs(e,t,x,d,s)}}}updateLODs(e,t,r,s,o){var a,h;r.userData||(r.userData={});let i=r.userData.LOD_state;if(i||(i=new Ae,r.userData.LOD_state=i),i.frames++<2)return;for(const d of I)(a=d.onBeforeUpdateLOD)==null||a.call(d,this.renderer,e,t,r);this.calculateLodLevel(t,r,i,s,E),E.mesh_lod=Math.round(E.mesh_lod),E.texture_lod=Math.round(E.texture_lod),E.mesh_lod>=0&&this.loadProgressiveMeshes(r,E.mesh_lod);let n=E.texture_lod;if(r.material&&n>=0){const d=r["DEBUG:LOD"];d!=null&&(n=d),this.loadProgressiveTextures(r.material,n)}for(const d of I)(h=d.onAfterUpdatedLOD)==null||h.call(d,this.renderer,e,t,r,E);i.lastLodLevel_Mesh=E.mesh_lod,i.lastLodLevel_Texture=E.texture_lod}loadProgressiveTextures(e,t){if(!e)return;if(Array.isArray(e)){for(const o of e)this.loadProgressiveTextures(o,t);return}const r=e;let s=!1;(r.NEEDLE_LOD==null||t<r.NEEDLE_LOD)&&(s=!0),s&&(r.NEEDLE_LOD=t,S.assignTextureLOD(e,t))}loadProgressiveMeshes(e,t){if(!e)return Promise.resolve(null);if(e.userData||(e.userData={}),e.userData.LOD!==t){e.userData.LOD=t;const r=e.geometry;return S.assignMeshLOD(e,t).then(s=>(s&&e.userData.LOD==t&&r!=e.geometry,s))}return Promise.resolve(null)}static isInside(e,t){const r=e.min,s=e.max,o=(r.x+s.x)*.5,i=(r.y+s.y)*.5;return this._tempPtInside.set(o,i,r.z).applyMatrix4(t).z<0}calculateLodLevel(e,t,r,s,o){var M;if(!t){o.mesh_lod=-1,o.texture_lod=-1;return}if(!e){o.mesh_lod=-1,o.texture_lod=-1;return}let n=10+1;if(z&&t["DEBUG:LOD"]!=null)return t["DEBUG:LOD"];const a=S.getMeshLODInformation(t.geometry),h=a==null?void 0:a.lods,d=h&&h.length>0,p=S.getMaterialMinMaxLODsCount(t.material),f=(p==null?void 0:p.min_count)!=1/0&&p.min_count>0&&p.max_count>0;if(!d&&!f){o.mesh_lod=0,o.texture_lod=0;return}if(d||(n=0),!((M=this.cameraFrustrum)!=null&&M.intersectsObject(t))){o.mesh_lod=99,o.texture_lod=99;return}const x=t.geometry.boundingBox;if(x&&e.isPerspectiveCamera){const _=e;if(t.geometry.attributes.color&&t.geometry.attributes.color.count<100&&t.geometry.boundingSphere){this._sphere.copy(t.geometry.boundingSphere),this._sphere.applyMatrix4(t.matrixWorld);const L=e.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(L)){o.mesh_lod=0,o.texture_lod=0;return}}if(this._tempBox.copy(x),this._tempBox.applyMatrix4(t.matrixWorld),b.isInside(this._tempBox,this.projectionScreenMatrix)){o.mesh_lod=0,o.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&_.fov>70){const L=this._tempBox.min,y=this._tempBox.max;let u=L.x,D=L.y,T=y.x,B=y.y;const G=2,N=1.5,K=(L.x+y.x)*.5,X=(L.y+y.y)*.5;u=(u-K)*G+K,D=(D-X)*G+X,T=(T-K)*G+K,B=(B-X)*G+X;const de=u<0&&T>0?0:Math.min(Math.abs(L.x),Math.abs(y.x)),he=D<0&&B>0?0:Math.min(Math.abs(L.y),Math.abs(y.y)),ee=Math.max(de,he);r.lastCentrality=(N-ee)*(N-ee)*(N-ee)}else r.lastCentrality=1;const O=this._tempBox.getSize(this._tempBoxSize);O.multiplyScalar(.5),screen.availHeight>0&&O.multiplyScalar(this.renderer.domElement.clientHeight/screen.availHeight),O.x*=_.aspect;const k=e.matrixWorldInverse,m=this._tempBox2;m.copy(x),m.applyMatrix4(t.matrixWorld),m.applyMatrix4(k);const A=m.getSize(this._tempBox2Size),F=Math.max(A.x,A.y);if(Math.max(O.x,O.y)!=0&&F!=0&&(O.z=A.z/Math.max(A.x,A.y)*Math.max(O.x,O.y)),r.lastScreenCoverage=Math.max(O.x,O.y,O.z),r.lastScreenspaceVolume.copy(O),r.lastScreenCoverage*=r.lastCentrality,z&&b.debugDrawLine){const L=this.tempMatrix.copy(this.projectionScreenMatrix);L.invert();const y=b.corner0,u=b.corner1,D=b.corner2,T=b.corner3;y.copy(this._tempBox.min),u.copy(this._tempBox.max),u.x=y.x,D.copy(this._tempBox.max),D.y=y.y,T.copy(this._tempBox.max);const B=(y.z+T.z)*.5;y.z=u.z=D.z=T.z=B,y.applyMatrix4(L),u.applyMatrix4(L),D.applyMatrix4(L),T.applyMatrix4(L),b.debugDrawLine(y,u,255),b.debugDrawLine(y,D,255),b.debugDrawLine(u,T,255),b.debugDrawLine(D,T,255)}let R=999;if(h&&r.lastScreenCoverage>0){for(let L=0;L<h.length;L++)if(h[L].density/r.lastScreenCoverage<s){R=L;break}}R<n&&(n=R)}if(o.mesh_lod=n,f)if(r.lastLodLevel_Texture<0){if(o.texture_lod=p.max_count-1,z){const _=p.lods[p.max_count-1];z&&console.log(`First Texture LOD ${o.texture_lod} (${_.max_height}px) - ${t.name}`)}}else{const _=r.lastScreenCoverage*1.5,k=this.renderer.domElement.clientHeight/window.devicePixelRatio*_;for(let m=p.lods.length-1;m>=0;m--){const A=p.lods[m];if(!(Oe()&&A.max_height>4096)&&A.max_height>k){o.texture_lod=m,o.texture_lod<r.lastLodLevel_Texture&&z&&console.log(`Texture LOD changed ${r.lastLodLevel_Texture} → ${o.texture_lod} (${A.max_height}px: ${(100*r.lastScreenCoverage).toFixed(2)} % = ${k.toFixed(0)}px) - ${t.name}`);break}}}else o.texture_lod=0}};let P=b;c(P,"debugDrawLine"),c(P,"corner0",new g.Vector3),c(P,"corner1",new g.Vector3),c(P,"corner2",new g.Vector3),c(P,"corner3",new g.Vector3),c(P,"_tempPtInside",new g.Vector3);class Ae{constructor(){c(this,"frames",0);c(this,"lastLodLevel_Mesh",-1);c(this,"lastLodLevel_Texture",-1);c(this,"lastScreenCoverage",0);c(this,"lastScreenspaceVolume",new g.Vector3);c(this,"lastCentrality",0)}}const ce=Symbol("NEEDLE_mesh_lod"),Y=Symbol("NEEDLE_texture_lod");function fe(l){if(!l)return null;let e=null,t=null;for(let r=l;r!=null;r=Object.getPrototypeOf(r)){const s=Object.getOwnPropertySymbols(r),o=s.find(n=>n.toString()=="Symbol(renderer)"),i=s.find(n=>n.toString()=="Symbol(scene)");!e&&o!=null&&(e=l[o].threeRenderer),!t&&i!=null&&(t=l[i])}if(e){console.log("Adding Needle LODs to modelviewer");const r=P.get(e);if(P.addPlugin(new be(l)),r.enable(),t){const s=t.camera||t.traverse(o=>o.type=="PerspectiveCamera")[0];s&&e.render(t,s)}return()=>{r.disable()}}return null}class be{constructor(e){c(this,"modelviewer");c(this,"_didWarnAboutMissingUrl",!1);this.modelviewer=e}onBeforeUpdateLOD(e,t,r,s){this.tryParseMeshLOD(t,s),this.tryParseTextureLOD(t,s)}getUrl(){let e=this.modelviewer.getAttribute("src");return e||(e=this.modelviewer.src),e||(this._didWarnAboutMissingUrl||console.warn("No url found in modelviewer",this.modelviewer),this._didWarnAboutMissingUrl=!0),e}tryGetCurrentGLTF(e){return e._currentGLTF}tryParseTextureLOD(e,t){if(t[Y]==!0)return;t[Y]=!0;const r=this.tryGetCurrentGLTF(e),s=this.getUrl();if(s&&r&&t.material){let o=function(n){var h,d,p;if(n[Y]==!0)return;n[Y]=!0,n.userData&&(n.userData.LOD=-1);const a=Object.keys(n);for(let f=0;f<a.length;f++){const x=a[f],M=n[x];if((M==null?void 0:M.isTexture)===!0){const _=(d=(h=M.userData)==null?void 0:h.associations)==null?void 0:d.textures,O=r.parser.json.textures[_];if(!O){console.warn("Texture data not found for texture index "+_);continue}if((p=O==null?void 0:O.extensions)!=null&&p[C]){const k=O.extensions[C];k&&s&&S.registerTexture(s,M,k.lods.length,_,k)}}}};const i=t.material;if(Array.isArray(i))for(const n of i)o(n);else o(i)}}tryParseMeshLOD(e,t){var o,i;if(t[ce]==!0)return;t[ce]=!0;const r=this.getUrl();if(!r)return;const s=(i=(o=t.userData)==null?void 0:o.gltfExtensions)==null?void 0:i[C];if(s&&r){const n=t.uuid;S.registerMesh(r,n,t,0,s.lods.length,s)}}}function Pe(l,e,t,r){oe(e),ne(t),t.register(o=>new S(o,l));const s=P.get(e);return(r==null?void 0:r.enableLODsManager)!==!1&&s.enable(),s}document.addEventListener("DOMContentLoaded",()=>{fe(document.querySelector("model-viewer"))});exports.EXTENSION_NAME=C;exports.LODsManager=P;exports.NEEDLE_progressive=S;exports.addDracoAndKTX2Loaders=ne;exports.createLoaders=oe;exports.getRaycastMesh=Q;exports.patchModelViewer=fe;exports.setDracoDecoderLocation=De;exports.setKTX2TranscoderLocation=Me;exports.setRaycastMesh=ue;exports.useNeedleProgressive=Pe;exports.useRaycastMeshes=we;
5
+ `,t.uuid),t.offset=e.offset,t.repeat=e.repeat,t.colorSpace=e.colorSpace,t.magFilter=e.magFilter,t.minFilter=e.minFilter,t.wrapS=e.wrapS,t.wrapT=e.wrapT,t.flipY=e.flipY,t.anisotropy=e.anisotropy,t.mipmaps||(t.generateMipmaps=e.generateMipmaps),t}};let S=v;c(S,"registerTexture",(e,t,r,i,o)=>{if(M&&console.log("> Progressive: register texture",i,t.name,t.uuid,t,o),!t){M&&console.error("gltf-progressive: Register texture without texture");return}t.source&&(t.source[te]=o);const s=o.guid;v.assignLODInformation(e,t,s,r,i,void 0),v.lodInfos.set(s,o),v.lowresCache.set(s,t)}),c(S,"registerMesh",(e,t,r,i,o,s)=>{var h;M&&console.log("> Progressive: register mesh",o,r.name,s,r.uuid,r);const n=r.geometry;if(!n){M&&console.warn("gltf-progressive: Register mesh without geometry");return}n.userData||(n.userData={}),v.assignLODInformation(e,n,t,i,o,s.density),v.lodInfos.set(t,s);let a=v.lowresCache.get(t);a?a.push(r.geometry):a=[r.geometry],v.lowresCache.set(t,a),i>0&&!Q(r)&&ue(r,n);for(const d of I)(h=d.onRegisteredNewMesh)==null||h.call(d,r,s)}),c(S,"lodInfos",new Map),c(S,"previouslyLoaded",new Map),c(S,"lowresCache",new Map);class Se{constructor(e,t,r,i,o){c(this,"url");c(this,"key");c(this,"level");c(this,"index");c(this,"density");this.url=e,this.key=t,this.level=r,i!=null&&(this.index=i),o!=null&&(this.density=o)}}const z=J("debugprogressive"),Te=J("noprogressive"),le=Symbol("Needle:LODSManager"),E={mesh_lod:-1,texture_lod:-1},b=class{constructor(e){c(this,"renderer");c(this,"projectionScreenMatrix",new g.Matrix4);c(this,"cameraFrustrum",new g.Frustum);c(this,"targetTriangleDensity",2e5);c(this,"updateInterval",0);c(this,"pause",!1);c(this,"_frame",0);c(this,"_originalRender");c(this,"_sphere",new g.Sphere);c(this,"_tempBox",new g.Box3);c(this,"_tempBox2",new g.Box3);c(this,"tempMatrix",new g.Matrix4);c(this,"_tempWorldPosition",new g.Vector3);c(this,"_tempBoxSize",new g.Vector3);c(this,"_tempBox2Size",new g.Vector3);this.renderer=e}static getObjectLODState(e){var t;return(t=e.userData)==null?void 0:t.LOD_state}static addPlugin(e){I.push(e)}static removePlugin(e){const t=I.indexOf(e);t>=0&&I.splice(t,1)}static get(e){return e[le]?e[le]:new b(e)}get plugins(){return I}enable(){if(this._originalRender)return;let e=0;this._originalRender=this.renderer.render;const t=this;oe(this.renderer),this.renderer.render=function(r,i){t.renderer.getRenderTarget()==null&&(e=0,t._frame+=1);const s=t._frame,n=e++;t.onBeforeRender(r,i,n,s),t._originalRender.call(this,r,i),t.onAfterRender(r,i,n,s)}}disable(){this._originalRender&&(this.renderer.render=this._originalRender,this._originalRender=void 0)}onBeforeRender(e,t,r,i){}onAfterRender(e,t,r,i){var a,h;if(this.pause)return;const o=this.renderer.renderLists.get(e,0),s=o.opaque;let n=!0;if(s.length===1){const d=s[0].material;(d.name==="EffectMaterial"||d.name==="CopyShader")&&(n=!1)}if(t.parent&&t.parent.type==="CubeCamera"&&(n=!1),n){if(Te||this.updateInterval>0&&i%this.updateInterval!=0)return;this.projectionScreenMatrix.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse),this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix,this.renderer.coordinateSystem);const d=this.targetTriangleDensity;for(const f of s){if(f.material&&(((a=f.geometry)==null?void 0:a.type)==="BoxGeometry"||((h=f.geometry)==null?void 0:h.type)==="BufferGeometry")&&(f.material.name==="SphericalGaussianBlur"||f.material.name=="BackgroundCubeMaterial"||f.material.name==="CubemapFromEquirect"||f.material.name==="EquirectangularToCubeUV")){z&&(f.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(f.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",f,f.material.name,f.material.type)));continue}switch(f.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}const x=f.object;(x instanceof g.Mesh||x.isMesh)&&this.updateLODs(e,t,x,d,i)}const p=o.transparent;for(const f of p){const x=f.object;(x instanceof g.Mesh||x.isMesh)&&this.updateLODs(e,t,x,d,i)}}}updateLODs(e,t,r,i,o){var a,h;r.userData||(r.userData={});let s=r.userData.LOD_state;if(s||(s=new Ae,r.userData.LOD_state=s),s.frames++<2)return;for(const d of I)(a=d.onBeforeUpdateLOD)==null||a.call(d,this.renderer,e,t,r);this.calculateLodLevel(t,r,s,i,E),E.mesh_lod=Math.round(E.mesh_lod),E.texture_lod=Math.round(E.texture_lod),E.mesh_lod>=0&&this.loadProgressiveMeshes(r,E.mesh_lod);let n=E.texture_lod;if(r.material&&n>=0){const d=r["DEBUG:LOD"];d!=null&&(n=d),this.loadProgressiveTextures(r.material,n)}for(const d of I)(h=d.onAfterUpdatedLOD)==null||h.call(d,this.renderer,e,t,r,E);s.lastLodLevel_Mesh=E.mesh_lod,s.lastLodLevel_Texture=E.texture_lod}loadProgressiveTextures(e,t){if(!e)return;if(Array.isArray(e)){for(const o of e)this.loadProgressiveTextures(o,t);return}const r=e;let i=!1;(r.NEEDLE_LOD==null||t<r.NEEDLE_LOD)&&(i=!0),i&&(r.NEEDLE_LOD=t,S.assignTextureLOD(e,t))}loadProgressiveMeshes(e,t){if(!e)return Promise.resolve(null);if(e.userData||(e.userData={}),e.userData.LOD!==t){e.userData.LOD=t;const r=e.geometry;return S.assignMeshLOD(e,t).then(i=>(i&&e.userData.LOD==t&&r!=e.geometry,i))}return Promise.resolve(null)}static isInside(e,t){const r=e.min,i=e.max,o=(r.x+i.x)*.5,s=(r.y+i.y)*.5;return this._tempPtInside.set(o,s,r.z).applyMatrix4(t).z<0}calculateLodLevel(e,t,r,i,o){var _;if(!t){o.mesh_lod=-1,o.texture_lod=-1;return}if(!e){o.mesh_lod=-1,o.texture_lod=-1;return}let n=10+1;if(z&&t["DEBUG:LOD"]!=null)return t["DEBUG:LOD"];const a=S.getMeshLODInformation(t.geometry),h=a==null?void 0:a.lods,d=h&&h.length>0,p=S.getMaterialMinMaxLODsCount(t.material),f=(p==null?void 0:p.min_count)!=1/0&&p.min_count>0&&p.max_count>0;if(!d&&!f){o.mesh_lod=0,o.texture_lod=0;return}if(d||(n=0),!((_=this.cameraFrustrum)!=null&&_.intersectsObject(t))){o.mesh_lod=99,o.texture_lod=99;return}const x=t.geometry.boundingBox;if(x&&e.isPerspectiveCamera){const O=e;if(t.geometry.attributes.color&&t.geometry.attributes.color.count<100&&t.geometry.boundingSphere){this._sphere.copy(t.geometry.boundingSphere),this._sphere.applyMatrix4(t.matrixWorld);const L=e.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(L)){o.mesh_lod=0,o.texture_lod=0;return}}if(this._tempBox.copy(x),this._tempBox.applyMatrix4(t.matrixWorld),b.isInside(this._tempBox,this.projectionScreenMatrix)){o.mesh_lod=0,o.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&O.fov>70){const L=this._tempBox.min,y=this._tempBox.max;let u=L.x,D=L.y,T=y.x,B=y.y;const G=2,N=1.5,K=(L.x+y.x)*.5,X=(L.y+y.y)*.5;u=(u-K)*G+K,D=(D-X)*G+X,T=(T-K)*G+K,B=(B-X)*G+X;const de=u<0&&T>0?0:Math.min(Math.abs(L.x),Math.abs(y.x)),he=D<0&&B>0?0:Math.min(Math.abs(L.y),Math.abs(y.y)),ee=Math.max(de,he);r.lastCentrality=(N-ee)*(N-ee)*(N-ee)}else r.lastCentrality=1;const w=this._tempBox.getSize(this._tempBoxSize);w.multiplyScalar(.5),screen.availHeight>0&&w.multiplyScalar(this.renderer.domElement.clientHeight/screen.availHeight),w.x*=O.aspect;const k=e.matrixWorldInverse,m=this._tempBox2;m.copy(x),m.applyMatrix4(t.matrixWorld),m.applyMatrix4(k);const A=m.getSize(this._tempBox2Size),F=Math.max(A.x,A.y);if(Math.max(w.x,w.y)!=0&&F!=0&&(w.z=A.z/Math.max(A.x,A.y)*Math.max(w.x,w.y)),r.lastScreenCoverage=Math.max(w.x,w.y,w.z),r.lastScreenspaceVolume.copy(w),r.lastScreenCoverage*=r.lastCentrality,z&&b.debugDrawLine){const L=this.tempMatrix.copy(this.projectionScreenMatrix);L.invert();const y=b.corner0,u=b.corner1,D=b.corner2,T=b.corner3;y.copy(this._tempBox.min),u.copy(this._tempBox.max),u.x=y.x,D.copy(this._tempBox.max),D.y=y.y,T.copy(this._tempBox.max);const B=(y.z+T.z)*.5;y.z=u.z=D.z=T.z=B,y.applyMatrix4(L),u.applyMatrix4(L),D.applyMatrix4(L),T.applyMatrix4(L),b.debugDrawLine(y,u,255),b.debugDrawLine(y,D,255),b.debugDrawLine(u,T,255),b.debugDrawLine(D,T,255)}let R=999;if(h&&r.lastScreenCoverage>0){for(let L=0;L<h.length;L++)if(h[L].density/r.lastScreenCoverage<i){R=L;break}}R<n&&(n=R)}if(o.mesh_lod=n,f)if(r.lastLodLevel_Texture<0){if(o.texture_lod=p.max_count-1,z){const O=p.lods[p.max_count-1];z&&console.log(`First Texture LOD ${o.texture_lod} (${O.max_height}px) - ${t.name}`)}}else{const O=r.lastScreenCoverage*1.5,k=this.renderer.domElement.clientHeight/window.devicePixelRatio*O;for(let m=p.lods.length-1;m>=0;m--){const A=p.lods[m];if(!(Oe()&&A.max_height>4096)&&A.max_height>k){o.texture_lod=m,o.texture_lod<r.lastLodLevel_Texture&&z&&console.log(`Texture LOD changed ${r.lastLodLevel_Texture} → ${o.texture_lod} (${A.max_height}px: ${(100*r.lastScreenCoverage).toFixed(2)} % = ${k.toFixed(0)}px) - ${t.name}`);break}}}else o.texture_lod=0}};let P=b;c(P,"debugDrawLine"),c(P,"corner0",new g.Vector3),c(P,"corner1",new g.Vector3),c(P,"corner2",new g.Vector3),c(P,"corner3",new g.Vector3),c(P,"_tempPtInside",new g.Vector3);class Ae{constructor(){c(this,"frames",0);c(this,"lastLodLevel_Mesh",-1);c(this,"lastLodLevel_Texture",-1);c(this,"lastScreenCoverage",0);c(this,"lastScreenspaceVolume",new g.Vector3);c(this,"lastCentrality",0)}}const ce=Symbol("NEEDLE_mesh_lod"),Y=Symbol("NEEDLE_texture_lod");function fe(l){if(!l)return null;let e=null,t=null;for(let r=l;r!=null;r=Object.getPrototypeOf(r)){const i=Object.getOwnPropertySymbols(r),o=i.find(n=>n.toString()=="Symbol(renderer)"),s=i.find(n=>n.toString()=="Symbol(scene)");!e&&o!=null&&(e=l[o].threeRenderer),!t&&s!=null&&(t=l[s])}if(e){console.log("Adding Needle LODs to modelviewer");const r=P.get(e);if(P.addPlugin(new be(l)),r.enable(),t){const i=t.camera||t.traverse(o=>o.type=="PerspectiveCamera")[0];i&&e.render(t,i)}return()=>{r.disable()}}return null}class be{constructor(e){c(this,"modelviewer");c(this,"_didWarnAboutMissingUrl",!1);this.modelviewer=e}onBeforeUpdateLOD(e,t,r,i){this.tryParseMeshLOD(t,i),this.tryParseTextureLOD(t,i)}getUrl(){let e=this.modelviewer.getAttribute("src");return e||(e=this.modelviewer.src),e||(this._didWarnAboutMissingUrl||console.warn("No url found in modelviewer",this.modelviewer),this._didWarnAboutMissingUrl=!0),e}tryGetCurrentGLTF(e){return e._currentGLTF}tryParseTextureLOD(e,t){if(t[Y]==!0)return;t[Y]=!0;const r=this.tryGetCurrentGLTF(e),i=this.getUrl();if(i&&r&&t.material){let o=function(n){var h,d,p;if(n[Y]==!0)return;n[Y]=!0,n.userData&&(n.userData.LOD=-1);const a=Object.keys(n);for(let f=0;f<a.length;f++){const x=a[f],_=n[x];if((_==null?void 0:_.isTexture)===!0){const O=(d=(h=_.userData)==null?void 0:h.associations)==null?void 0:d.textures,w=r.parser.json.textures[O];if(!w){console.warn("Texture data not found for texture index "+O);continue}if((p=w==null?void 0:w.extensions)!=null&&p[C]){const k=w.extensions[C];k&&i&&S.registerTexture(i,_,k.lods.length,O,k)}}}};const s=t.material;if(Array.isArray(s))for(const n of s)o(n);else o(s)}}tryParseMeshLOD(e,t){var o,s;if(t[ce]==!0)return;t[ce]=!0;const r=this.getUrl();if(!r)return;const i=(s=(o=t.userData)==null?void 0:o.gltfExtensions)==null?void 0:s[C];if(i&&r){const n=t.uuid;S.registerMesh(r,n,t,0,i.lods.length,i)}}}function Pe(l,e,t,r){oe(e),ne(t),t.register(o=>new S(o,l));const i=P.get(e);return(r==null?void 0:r.enableLODsManager)!==!1&&i.enable(),i}document.addEventListener("DOMContentLoaded",()=>{fe(document.querySelector("model-viewer"))});exports.EXTENSION_NAME=C;exports.LODsManager=P;exports.NEEDLE_progressive=S;exports.addDracoAndKTX2Loaders=ne;exports.createLoaders=oe;exports.getRaycastMesh=Q;exports.patchModelViewer=fe;exports.setDracoDecoderLocation=De;exports.setKTX2TranscoderLocation=Me;exports.setRaycastMesh=ue;exports.useNeedleProgressive=Pe;exports.useRaycastMeshes=we;
package/lib/extension.js CHANGED
@@ -418,6 +418,11 @@ export class NEEDLE_progressive {
418
418
  if (textureInfo?.extensions) {
419
419
  const ext = textureInfo?.extensions[EXTENSION_NAME];
420
420
  if (ext) {
421
+ if (!ext.lods) {
422
+ if (debug)
423
+ console.warn("Texture has no LODs", ext);
424
+ return;
425
+ }
421
426
  let found = false;
422
427
  for (const key of this.parser.associations.keys()) {
423
428
  if (key.isTexture === true) {
@@ -352,13 +352,6 @@ export class LODsManager {
352
352
  mesh_level = 0;
353
353
  }
354
354
  if (!this.cameraFrustrum?.intersectsObject(mesh)) {
355
- // console.log("Mesh not visible");
356
- // if (debugProgressiveLoading && mesh.geometry.boundingSphere) {
357
- // const bounds = mesh.geometry.boundingSphere;
358
- // this._sphere.copy(bounds);
359
- // this._sphere.applyMatrix4(mesh.matrixWorld);
360
- // Gizmos.DrawWireSphere(this._sphere.center, this._sphere.radius * 1.01, 0xff5555, .5);
361
- // }
362
355
  // the object is not visible by the camera
363
356
  result.mesh_lod = 99;
364
357
  result.texture_lod = 99;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@needle-tools/gltf-progressive",
3
- "version": "1.2.0-alpha.5",
3
+ "version": "1.2.0-alpha.6",
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": {