@needle-tools/gltf-progressive 1.0.0-alpha.18 → 1.0.0-alpha.19

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.0.0-alpha.19] - 2023-05-31
8
+ - add `LODsManager.plugins` getter
9
+
7
10
  ## [1.0.0-alpha.18] - 2023-05-30
8
11
  - update README
9
12
 
@@ -46,7 +46,7 @@ function xe(a) {
46
46
  function we(a, e) {
47
47
  (a.type === "Mesh" || a.type === "SkinnedMesh") && (a.userData || (a.userData = {}), a.userData["needle:raycast-mesh"] = e);
48
48
  }
49
- const G = new Array(), E = "NEEDLE_progressive", v = ee("debugprogressive"), H = Symbol("needle-progressive-texture"), N = /* @__PURE__ */ new Map(), Z = /* @__PURE__ */ new Set();
49
+ const E = new Array(), I = "NEEDLE_progressive", v = ee("debugprogressive"), H = Symbol("needle-progressive-texture"), N = /* @__PURE__ */ new Map(), Z = /* @__PURE__ */ new Set();
50
50
  if (v) {
51
51
  let a = function() {
52
52
  e += 1, console.log("Toggle LOD level", e, N), N.forEach((i, n) => {
@@ -84,7 +84,7 @@ const O = class {
84
84
  }
85
85
  /** The name of the extension */
86
86
  get name() {
87
- return E;
87
+ return I;
88
88
  }
89
89
  static getMeshLODInformation(e) {
90
90
  const t = this.getAssignedLODInformation(e);
@@ -141,7 +141,7 @@ const O = class {
141
141
  const i = e.geometry, n = this.getAssignedLODInformation(i);
142
142
  if (!n)
143
143
  return Promise.resolve(null);
144
- for (const s of G)
144
+ for (const s of E)
145
145
  (r = s.onBeforeGetLODMesh) == null || r.call(s, e, t);
146
146
  return e["LOD:requested level"] = t, O.getOrLoadLOD(i, t).then((s) => {
147
147
  if (e["LOD:requested level"] === t) {
@@ -220,7 +220,7 @@ const O = class {
220
220
  var t, r;
221
221
  return v && console.log("AFTER", this.url, e), (t = this.parser.json.textures) == null || t.forEach((i, n) => {
222
222
  if (i != null && i.extensions) {
223
- const s = i == null ? void 0 : i.extensions[E];
223
+ const s = i == null ? void 0 : i.extensions[I];
224
224
  if (s) {
225
225
  let o = !1;
226
226
  for (const l of this.parser.associations.keys())
@@ -232,7 +232,7 @@ const O = class {
232
232
  }
233
233
  }), (r = this.parser.json.meshes) == null || r.forEach((i, n) => {
234
234
  if (i != null && i.extensions) {
235
- const s = i == null ? void 0 : i.extensions[E];
235
+ const s = i == null ? void 0 : i.extensions[I];
236
236
  if (s && s.lods) {
237
237
  for (const o of this.parser.associations.keys())
238
238
  if (o.isMesh) {
@@ -295,7 +295,7 @@ const O = class {
295
295
  let m = !1;
296
296
  for (const d of y.parser.json.textures) {
297
297
  if (d != null && d.extensions) {
298
- const M = d == null ? void 0 : d.extensions[E];
298
+ const M = d == null ? void 0 : d.extensions[I];
299
299
  if (M != null && M.guid && M.guid === L.guid) {
300
300
  m = !0;
301
301
  break;
@@ -313,7 +313,7 @@ const O = class {
313
313
  let m = !1;
314
314
  for (const d of y.parser.json.meshes) {
315
315
  if (d != null && d.extensions) {
316
- const M = d == null ? void 0 : d.extensions[E];
316
+ const M = d == null ? void 0 : d.extensions[I];
317
317
  if (M != null && M.guid && M.guid === L.guid) {
318
318
  m = !0;
319
319
  break;
@@ -329,9 +329,9 @@ const O = class {
329
329
  } else {
330
330
  const _ = new Array();
331
331
  for (let B = 0; B < d.children.length; B++) {
332
- const I = d.children[B];
333
- if (I instanceof X) {
334
- const $ = I.geometry;
332
+ const G = d.children[B];
333
+ if (G instanceof X) {
334
+ const $ = G.geometry;
335
335
  O.assignLODInformation(i.url, $, n, t, B, M.density), _.push($);
336
336
  }
337
337
  }
@@ -385,7 +385,7 @@ u(S, "registerMesh", (e, t, r, i, n, s) => {
385
385
  o.userData || (o.userData = {}), O.assignLODInformation(e, o, t, i, n, s.density), O.lodInfos.set(t, s);
386
386
  let l = O.lowresCache.get(t);
387
387
  l ? l.push(r.geometry) : l = [r.geometry], O.lowresCache.set(t, l), i > 0 && !xe(r) && we(r, o);
388
- for (const f of G)
388
+ for (const f of E)
389
389
  (g = f.onRegisteredNewMesh) == null || g.call(f, r, s);
390
390
  }), /** A map of key = asset uuid and value = LOD information */
391
391
  u(S, "lodInfos", /* @__PURE__ */ new Map()), /** cache of already loaded mesh lods */
@@ -441,11 +441,11 @@ const J = ee("debugprogressive"), Me = ee("noprogressive"), ie = Symbol("Needle:
441
441
  return (t = e.userData) == null ? void 0 : t.LOD_state;
442
442
  }
443
443
  static addPlugin(e) {
444
- G.push(e);
444
+ E.push(e);
445
445
  }
446
446
  static removePlugin(e) {
447
- const t = G.indexOf(e);
448
- t >= 0 && G.splice(t, 1);
447
+ const t = E.indexOf(e);
448
+ t >= 0 && E.splice(t, 1);
449
449
  }
450
450
  /**
451
451
  * Gets the LODsManager for the given renderer. If the LODsManager does not exist yet, it will be created.
@@ -455,6 +455,10 @@ const J = ee("debugprogressive"), Me = ee("noprogressive"), ie = Symbol("Needle:
455
455
  static get(e) {
456
456
  return e[ie] ? e[ie] : new P(e);
457
457
  }
458
+ /** @deprecated use static `LODsManager.addPlugin()` method. This getter will be removed in later versions */
459
+ get plugins() {
460
+ return E;
461
+ }
458
462
  /**
459
463
  * Enable the LODsManager. This will replace the render method of the renderer with a method that updates the LODs.
460
464
  */
@@ -517,7 +521,7 @@ const J = ee("debugprogressive"), Me = ee("noprogressive"), ie = Symbol("Needle:
517
521
  /** Update the LOD levels for the renderer. */
518
522
  updateLODs(e, t, r, i) {
519
523
  var l, g;
520
- for (const f of G)
524
+ for (const f of E)
521
525
  (l = f.onBeforeUpdateLOD) == null || l.call(f, this.renderer, e, t, r);
522
526
  let n = r.userData.LOD_state;
523
527
  n || (n = new ve(), r.userData.LOD_state = n);
@@ -532,7 +536,7 @@ const J = ee("debugprogressive"), Me = ee("noprogressive"), ie = Symbol("Needle:
532
536
  else
533
537
  this.loadProgressiveTextures(r.material, o);
534
538
  }
535
- for (const f of G)
539
+ for (const f of E)
536
540
  (g = f.onAfterUpdatedLOD) == null || g.call(f, this.renderer, e, t, r, s);
537
541
  n.lastLodLevel = s;
538
542
  }
@@ -591,8 +595,8 @@ const J = ee("debugprogressive"), Me = ee("noprogressive"), ie = Symbol("Needle:
591
595
  if (this._tempBox.applyMatrix4(this.projectionScreenMatrix), this.renderer.xr.enabled && p.fov > 70) {
592
596
  const D = this._tempBox.min, y = this._tempBox.max;
593
597
  let T = D.x, w = D.y, m = y.x, d = y.y;
594
- const M = 2, _ = 1.5, B = (D.x + y.x) * 0.5, I = (D.y + y.y) * 0.5;
595
- T = (T - B) * M + B, w = (w - I) * M + I, m = (m - B) * M + B, d = (d - I) * M + I;
598
+ const M = 2, _ = 1.5, B = (D.x + y.x) * 0.5, G = (D.y + y.y) * 0.5;
599
+ T = (T - B) * M + B, w = (w - G) * M + G, m = (m - B) * M + B, d = (d - G) * M + G;
596
600
  const $ = T < 0 && m > 0 ? 0 : Math.min(Math.abs(D.x), Math.abs(y.x)), le = w < 0 && d > 0 ? 0 : Math.min(Math.abs(D.y), Math.abs(y.y)), V = Math.max($, le);
597
601
  r.lastCentrality = (_ - V) * (_ - V) * (_ - V);
598
602
  } else
@@ -694,8 +698,8 @@ class Te {
694
698
  console.warn("Texture data not found for texture index " + A);
695
699
  continue;
696
700
  }
697
- if ((p = C == null ? void 0 : C.extensions) != null && p[E]) {
698
- const x = C.extensions[E];
701
+ if ((p = C == null ? void 0 : C.extensions) != null && p[I]) {
702
+ const x = C.extensions[I];
699
703
  x && i && S.registerTexture(i, L, x.lods.length, x);
700
704
  }
701
705
  }
@@ -717,7 +721,7 @@ class Te {
717
721
  const r = this.getUrl();
718
722
  if (!r)
719
723
  return;
720
- const i = (s = (n = t.userData) == null ? void 0 : n.gltfExtensions) == null ? void 0 : s[E];
724
+ const i = (s = (n = t.userData) == null ? void 0 : n.gltfExtensions) == null ? void 0 : s[I];
721
725
  if (i && r) {
722
726
  const o = t.uuid;
723
727
  S.registerMesh(r, o, t, 0, i.lods.length, i);
@@ -733,7 +737,7 @@ document.addEventListener("DOMContentLoaded", () => {
733
737
  Se(document.querySelector("model-viewer"));
734
738
  });
735
739
  export {
736
- E as EXTENSION_NAME,
740
+ I as EXTENSION_NAME,
737
741
  b as LODsManager,
738
742
  S as NEEDLE_progressive,
739
743
  ae as addDracoAndKTX2Loaders,
@@ -1,3 +1,3 @@
1
1
  var le=Object.defineProperty,ue=(t,e,r)=>e in t?le(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,c=(t,e,r)=>(ue(t,typeof e!="symbol"?e+"":e,r),r);import{MeshoptDecoder as ce}from"three/examples/jsm/libs/meshopt_decoder.module.js";import{DRACOLoader as de}from"three/examples/jsm/loaders/DRACOLoader.js";import{KTX2Loader as he}from"three/examples/jsm/loaders/KTX2Loader.js";import{BufferGeometry as z,Mesh as U,Material as fe,Texture as k,TextureLoader as ge,Matrix4 as ee,Frustum as me,Sphere as pe,Box3 as te,Vector3 as B}from"three";import{GLTFLoader as ye}from"three/examples/jsm/loaders/GLTFLoader.js";let $="https://www.gstatic.com/draco/versioned/decoders/1.4.1/",V="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";fetch($+"draco_decoder.js",{method:"head"}).catch(t=>{$="./include/draco/",V="./include/ktx2/"});function De(t){$=t}function xe(t){V=t}let G,X,N;function K(t){G||(G=new de,G.setDecoderPath($),G.setDecoderConfig({type:"js"})),N||(N=new he,N.setTranscoderPath(V)),X||(X=ce),t?N.detectSupport(t):console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures will probably fail")}function H(t){t.dracoLoader||t.setDRACOLoader(G),t.ktx2Loader||t.setKTX2Loader(N),t.meshoptDecoder||t.setMeshoptDecoder(X)}function Y(t){const e=new URL(window.location.href).searchParams.get(t);return e==null||e==="0"||e==="false"?!1:e===""?!0:e}function Le(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}function re(t){var e;return((e=t.userData)==null?void 0:e["needle:raycast-mesh"])instanceof z?t.userData["needle:raycast-mesh"]:null}function se(t,e){(t.type==="Mesh"||t.type==="SkinnedMesh")&&(t.userData||(t.userData={}),t.userData["needle:raycast-mesh"]=e)}const R=new Array,I="NEEDLE_progressive",v=Y("debugprogressive"),J=Symbol("needle-progressive-texture"),F=new Map,Q=new Set;if(v){let t=function(){e+=1,console.log("Toggle LOD level",e,F),F.forEach((o,s)=>{for(const a of o.keys){const i=s[a];if(i.isBufferGeometry===!0){const l=O.getMeshLODInformation(i),d=l?Math.min(e,l.lods.length):0;s["DEBUG:LOD"]=e,O.assignMeshLOD(s,d),l&&(r=Math.max(r,l.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,Q&&Q.forEach(s=>{s.name!="BackgroundCubeMaterial"&&"wireframe"in s&&(s.wireframe=n)}))})}function ne(t,e,r){var n;if(!v)return;F.has(t)||F.set(t,{keys:[],sourceId:r});const o=F.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"),v&&console.log("Progressive extension registered for",e),this.parser=t,this.url=e}get name(){return I}static getMeshLODInformation(t){const e=this.getAssignedLODInformation(t);return e!=null&&e.key?this.lodInfos.get(e.key):null}static hasLODLevelAvailable(t,e){var r;if(t.isMaterial===!0){for(const s of Object.keys(t)){const a=t[s];if(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 U||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 z&&(t.geometry=s,v&&ne(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 fe||t.isMaterial===!0){const r=t,n=[],o=new Array;if(v&&Q.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 l=this.assignTextureLODForSlot(i,e,r,a);n.push(l),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 l=s[i],d=o[i];l&&l.isTexture===!0?a.push({material:r,slot:d,texture:l,level:e}):a.push({material:r,slot:d,texture:null,level:e})}return a})}if(t instanceof k||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):M.getOrLoadLOD(t,e).then(o=>{if(Array.isArray(o))return null;if(o?.isTexture===!0){if(o!=t&&(r&&n&&(r[n]=o),v&&n&&r)){const s=this.getAssignedLODInformation(t);s&&ne(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[I];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,o,s));a||this.parser.getDependency("texture",o).then(i=>{i&&M.registerTexture(this.url,i,o,s)})}}}),(r=this.parser.json.meshes)==null||r.forEach((n,o)=>{if(n!=null&&n.extensions){const s=n?.extensions[I];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;const s=v=="verbose",a=t.userData.LODS;if(!a)return null;const i=a?.key;let l;if(t.isTexture===!0){const d=t;d.source&&d.source[J]&&(l=d.source[J])}if(l||(l=M.lodInfos.get(i)),l){if(e>0){let u=!1;const p=Array.isArray(l.lods);if(p&&e>=l.lods.length?u=!0:p||(u=!0),u)return this.lowresCache.get(i)}const d=Array.isArray(l.lods)?l.lods[e].path:l.lods;if(!d)return v&&!l["missing:uri"]&&(l["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+e,l)),null;const h=Le(a.url,d);if(h.endsWith(".glb")||h.endsWith(".gltf")){if(!l.guid)return console.warn("missing pointer for glb/gltf texture",l),null;const u=h+"_"+l.guid,p=this.previouslyLoaded.get(u);if(p!==void 0){s&&console.log(`LOD ${e} was already loading/loaded: ${u}`);let y=await p.catch(m=>(console.error(`Error loading LOD ${e} from ${h}
2
2
  `,m),null)),g=!1;if(y==null||(y instanceof k&&t instanceof k?(r=y.image)!=null&&r.data||(n=y.source)!=null&&n.data?y=this.copySettings(t,y):(g=!0,this.previouslyLoaded.delete(u)):y instanceof z&&t instanceof z&&((o=y.attributes.position)!=null&&o.array||(g=!0,this.previouslyLoaded.delete(u)))),!g)return y}const D=l,P=new Promise(async(y,g)=>{const m=new ye;H(m),v&&(await new Promise(L=>setTimeout(L,1e3)),s&&console.warn("Start loading (delayed) "+h,D.guid));let b=h;if(D&&Array.isArray(D.lods)){const L=D.lods[e];L.hash&&(b+="?v="+L.hash)}const x=await m.loadAsync(b).catch(L=>(console.error(`Error loading LOD ${e} from ${h}
3
- `,L),null));if(!x)return null;const S=x.parser;s&&console.log("Loading finished "+h,D.guid);let _=0;if(x.parser.json.textures){let L=!1;for(const f of x.parser.json.textures){if(f!=null&&f.extensions){const w=f?.extensions[I];if(w!=null&&w.guid&&w.guid===D.guid){L=!0;break}}_++}if(L){let f=await S.getDependency("texture",_);return f&&M.assignLODInformation(a.url,f,i,e,void 0,void 0),s&&console.log('change "'+t.name+'" \u2192 "'+f.name+'"',h,_,f,u),t instanceof k&&(f=this.copySettings(t,f)),f&&(f.guid=D.guid),y(f)}else v&&console.warn("Could not find texture with guid",D.guid)}if(_=0,x.parser.json.meshes){let L=!1;for(const f of x.parser.json.meshes){if(f!=null&&f.extensions){const w=f?.extensions[I];if(w!=null&&w.guid&&w.guid===D.guid){L=!0;break}}_++}if(L){const f=await S.getDependency("mesh",_),w=D;if(s&&console.log(`Loaded Mesh "${f.name}"`,h,_,f,u),f.isMesh===!0){const E=f.geometry;return M.assignLODInformation(a.url,E,i,e,void 0,w.density),y(E)}else{const E=new Array;for(let C=0;C<f.children.length;C++){const W=f.children[C];if(W instanceof U){const j=W.geometry;M.assignLODInformation(a.url,j,i,e,C,w.density),E.push(j)}}return y(E)}}}return y(null)});return this.previouslyLoaded.set(u,P),await P}else if(t instanceof k){s&&console.log("Load texture from uri: "+h);const u=await new ge().loadAsync(h);return u?(u.guid=l.guid,u.flipY=!1,u.needsUpdate=!0,u.colorSpace=t.colorSpace,s&&console.log(l,u)):v&&console.warn("failed loading",h),u}}else v&&console.warn(`Can not load LOD ${e}: no LOD info found for "${i}" ${t.name}`,t.type);return null}static assignLODInformation(t,e,r,n,o,s){if(!e)return;e.userData||(e.userData={});const a=new ve(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 this._copiedTextures.get(t)||(e=e.clone(),this._copiedTextures.set(t,e),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.generateMipmaps=t.generateMipmaps,e)}};let O=M;c(O,"registerTexture",(t,e,r,n)=>{v&&console.log("> Progressive: register texture",r,e.name,e.uuid,e,n),e.source&&(e.source[J]=n);const o=n.guid;M.assignLODInformation(t,e,o,0,0,void 0),M.lodInfos.set(o,n),M.lowresCache.set(o,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;i.userData||(i.userData={}),M.assignLODInformation(t,i,e,n,o,s.density),M.lodInfos.set(e,s);let l=M.lowresCache.get(e);l?l.push(r.geometry):l=[r.geometry],M.lowresCache.set(e,l),n>0&&!re(r)&&se(r,i);for(const d of R)(a=d.onRegisteredNewMesh)==null||a.call(d,r,s)}),c(O,"lodInfos",new Map),c(O,"previouslyLoaded",new Map),c(O,"lowresCache",new Map),c(O,"_copiedTextures",new Map);class ve{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 Z=Y("debugprogressive"),Me=Y("noprogressive"),oe=Symbol("Needle:LODSManager"),T=class{constructor(t){c(this,"renderer"),c(this,"projectionScreenMatrix",new ee),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 pe),c(this,"_tempBox",new te),c(this,"_tempBox2",new te),c(this,"tempMatrix",new ee),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[oe]?t[oe]:new T(t)}enable(){if(this._originalRender)return;let t=0;this._originalRender=this.renderer.render;const e=this;K(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 l=!0;if(i.length===1){const d=i[0].material;(d.name==="EffectMaterial"||d.name==="CopyShader")&&(l=!1)}if(l){if(Me||this.updateInterval>0&&n%this.updateInterval!=0)return;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse),this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix,this.renderer.coordinateSystem);const d=this.targetTriangleDensity;for(const u of i){if(u.material&&(((o=u.geometry)==null?void 0:o.type)==="BoxGeometry"||((s=u.geometry)==null?void 0:s.type)==="BufferGeometry")&&(u.material.name==="SphericalGaussianBlur"||u.material.name=="BackgroundCubeMaterial"||u.material.name==="CubemapFromEquirect"||u.material.name==="EquirectangularToCubeUV")){Z&&(u.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(u.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",u,u.material.name,u.material.type)));continue}switch(u.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}const p=u.object;(p instanceof U||p.isMesh)&&this.updateLODs(t,e,p,d)}const h=a.transparent;for(const u of h){const p=u.object;(p instanceof U||p.isMesh)&&this.updateLODs(t,e,p,d)}}}updateLODs(t,e,r,n){var o,s;for(const d of R)(o=d.onBeforeUpdateLOD)==null||o.call(d,this.renderer,t,e,r);let a=r.userData.LOD_state;a||(a=new Oe,r.userData.LOD_state=a);let i=this.calculateLodLevel(e,r,a,n);i=Math.round(i),i>=0&&this.loadProgressiveMeshes(r,i);let l=0;if(r.material){const d=r["DEBUG:LOD"];if(d!=null&&(l=d),Array.isArray(r.material))for(const h of r.material)this.loadProgressiveTextures(h,l);else this.loadProgressiveTextures(r.material,l)}for(const d of R)(s=d.onAfterUpdatedLOD)==null||s.call(d,this.renderer,t,e,r,i);a.lastLodLevel=i}loadProgressiveTextures(t,e){return t&&t.userData&&t.userData.LOD!==e?(t.userData.LOD=e,O.assignTextureLOD(t,e)):Promise.resolve(null)}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){var o;if(!e)return-1;let s=10+1;if(t){if(Z&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const a=O.getMeshLODInformation(e.geometry),i=a?.lods;if(!i||i.length<=0)return 0;if(!((o=this.cameraFrustrum)!=null&&o.intersectsObject(e)))return 99;const l=e.geometry.boundingBox;if(l&&t.isPerspectiveCamera){const d=t;if(e.geometry.attributes.color&&e.geometry.attributes.color.count<100&&e.geometry.boundingSphere){this._sphere.copy(e.geometry.boundingSphere),this._sphere.applyMatrix4(e.matrixWorld);const g=t.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(g))return 0}if(this._tempBox.copy(l),this._tempBox.applyMatrix4(e.matrixWorld),T.isInside(this._tempBox,this.projectionScreenMatrix))return 0;if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&d.fov>70){const g=this._tempBox.min,m=this._tempBox.max;let b=g.x,x=g.y,S=m.x,_=m.y;const L=2,f=1.5,w=(g.x+m.x)*.5,E=(g.y+m.y)*.5;b=(b-w)*L+w,x=(x-E)*L+E,S=(S-w)*L+w,_=(_-E)*L+E;const C=b<0&&S>0?0:Math.min(Math.abs(g.x),Math.abs(m.x)),W=x<0&&_>0?0:Math.min(Math.abs(g.y),Math.abs(m.y)),j=Math.max(C,W);r.lastCentrality=(f-j)*(f-j)*(f-j)}else r.lastCentrality=1;const h=this._tempBox.getSize(this._tempBoxSize);h.multiplyScalar(.5),screen.availHeight>0&&h.multiplyScalar(this.renderer.domElement.clientHeight/screen.availHeight),h.x*=d.aspect;const u=t.matrixWorldInverse,p=this._tempBox2;p.copy(l),p.applyMatrix4(e.matrixWorld),p.applyMatrix4(u);const D=p.getSize(this._tempBox2Size),P=Math.max(D.x,D.y);if(Math.max(h.x,h.y)!=0&&P!=0&&(h.z=D.z/Math.max(D.x,D.y)*Math.max(h.x,h.y)),r.lastScreenCoverage=Math.max(h.x,h.y,h.z),r.lastScreenspaceVolume.copy(h),r.lastScreenCoverage*=r.lastCentrality,Z&&T.debugDrawLine){const g=this.tempMatrix.copy(this.projectionScreenMatrix);g.invert();const m=T.corner0,b=T.corner1,x=T.corner2,S=T.corner3;m.copy(this._tempBox.min),b.copy(this._tempBox.max),b.x=m.x,x.copy(this._tempBox.max),x.y=m.y,S.copy(this._tempBox.max);const _=(m.z+S.z)*.5;m.z=b.z=x.z=S.z=_,m.applyMatrix4(g),b.applyMatrix4(g),x.applyMatrix4(g),S.applyMatrix4(g),T.debugDrawLine(m,b,255),T.debugDrawLine(m,x,255),T.debugDrawLine(b,S,255),T.debugDrawLine(x,S,255)}let y=999;if(i&&r.lastScreenCoverage>0){for(let g=0;g<i.length;g++)if(i[g].density/r.lastScreenCoverage<n){y=g;break}}y<s&&(s=y)}}return s}};let A=T;c(A,"debugDrawLine"),c(A,"corner0",new B),c(A,"corner1",new B),c(A,"corner2",new B),c(A,"corner3",new B),c(A,"_tempPtInside",new B);class Oe{constructor(){c(this,"lastLodLevel",0),c(this,"lastScreenCoverage",0),c(this,"lastScreenspaceVolume",new B),c(this,"lastCentrality",0)}}const ie=Symbol("NEEDLE_mesh_lod"),q=Symbol("NEEDLE_texture_lod");function ae(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=A.get(e);if(A.addPlugin(new we(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 we{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 l,d,h;if(i[q]==!0)return;i[q]=!0,i.userData&&(i.userData.LOD=-1);const u=Object.keys(i);for(let p=0;p<u.length;p++){const D=u[p],P=i[D];if(P?.isTexture===!0){const y=(d=(l=P.userData)==null?void 0:l.associations)==null?void 0:d.textures,g=n.parser.json.textures[y];if(!g){console.warn("Texture data not found for texture index "+y);continue}if((h=g?.extensions)!=null&&h[I]){const m=g.extensions[I];m&&o&&O.registerTexture(o,P,m.lods.length,m)}}}};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[ie]==!0)return;r[ie]=!0;const s=this.getUrl();if(!s)return;const a=(o=(n=r.userData)==null?void 0:n.gltfExtensions)==null?void 0:o[I];if(a&&s){const i=r.uuid;O.registerMesh(s,i,r,0,a.lods.length,a)}}}function be(t,e,r,n){K(e),H(r),r.register(s=>new O(s,t));const o=A.get(e);return n?.enableLODsManager!==!1&&o.enable(),o}document.addEventListener("DOMContentLoaded",()=>{ae(document.querySelector("model-viewer"))});export{I as EXTENSION_NAME,A as LODsManager,O as NEEDLE_progressive,H as addDracoAndKTX2Loaders,K as createLoaders,re as getRaycastMesh,ae as patchModelViewer,De as setDracoDecoderLocation,xe as setKTX2TranscoderLocation,se as setRaycastMesh,be as useNeedleProgressive};
3
+ `,L),null));if(!x)return null;const S=x.parser;s&&console.log("Loading finished "+h,D.guid);let _=0;if(x.parser.json.textures){let L=!1;for(const f of x.parser.json.textures){if(f!=null&&f.extensions){const w=f?.extensions[I];if(w!=null&&w.guid&&w.guid===D.guid){L=!0;break}}_++}if(L){let f=await S.getDependency("texture",_);return f&&M.assignLODInformation(a.url,f,i,e,void 0,void 0),s&&console.log('change "'+t.name+'" \u2192 "'+f.name+'"',h,_,f,u),t instanceof k&&(f=this.copySettings(t,f)),f&&(f.guid=D.guid),y(f)}else v&&console.warn("Could not find texture with guid",D.guid)}if(_=0,x.parser.json.meshes){let L=!1;for(const f of x.parser.json.meshes){if(f!=null&&f.extensions){const w=f?.extensions[I];if(w!=null&&w.guid&&w.guid===D.guid){L=!0;break}}_++}if(L){const f=await S.getDependency("mesh",_),w=D;if(s&&console.log(`Loaded Mesh "${f.name}"`,h,_,f,u),f.isMesh===!0){const E=f.geometry;return M.assignLODInformation(a.url,E,i,e,void 0,w.density),y(E)}else{const E=new Array;for(let C=0;C<f.children.length;C++){const W=f.children[C];if(W instanceof U){const j=W.geometry;M.assignLODInformation(a.url,j,i,e,C,w.density),E.push(j)}}return y(E)}}}return y(null)});return this.previouslyLoaded.set(u,P),await P}else if(t instanceof k){s&&console.log("Load texture from uri: "+h);const u=await new ge().loadAsync(h);return u?(u.guid=l.guid,u.flipY=!1,u.needsUpdate=!0,u.colorSpace=t.colorSpace,s&&console.log(l,u)):v&&console.warn("failed loading",h),u}}else v&&console.warn(`Can not load LOD ${e}: no LOD info found for "${i}" ${t.name}`,t.type);return null}static assignLODInformation(t,e,r,n,o,s){if(!e)return;e.userData||(e.userData={});const a=new ve(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 this._copiedTextures.get(t)||(e=e.clone(),this._copiedTextures.set(t,e),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.generateMipmaps=t.generateMipmaps,e)}};let O=M;c(O,"registerTexture",(t,e,r,n)=>{v&&console.log("> Progressive: register texture",r,e.name,e.uuid,e,n),e.source&&(e.source[J]=n);const o=n.guid;M.assignLODInformation(t,e,o,0,0,void 0),M.lodInfos.set(o,n),M.lowresCache.set(o,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;i.userData||(i.userData={}),M.assignLODInformation(t,i,e,n,o,s.density),M.lodInfos.set(e,s);let l=M.lowresCache.get(e);l?l.push(r.geometry):l=[r.geometry],M.lowresCache.set(e,l),n>0&&!re(r)&&se(r,i);for(const d of R)(a=d.onRegisteredNewMesh)==null||a.call(d,r,s)}),c(O,"lodInfos",new Map),c(O,"previouslyLoaded",new Map),c(O,"lowresCache",new Map),c(O,"_copiedTextures",new Map);class ve{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 Z=Y("debugprogressive"),Me=Y("noprogressive"),oe=Symbol("Needle:LODSManager"),T=class{constructor(t){c(this,"renderer"),c(this,"projectionScreenMatrix",new ee),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 pe),c(this,"_tempBox",new te),c(this,"_tempBox2",new te),c(this,"tempMatrix",new ee),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[oe]?t[oe]:new T(t)}get plugins(){return R}enable(){if(this._originalRender)return;let t=0;this._originalRender=this.renderer.render;const e=this;K(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 l=!0;if(i.length===1){const d=i[0].material;(d.name==="EffectMaterial"||d.name==="CopyShader")&&(l=!1)}if(l){if(Me||this.updateInterval>0&&n%this.updateInterval!=0)return;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse),this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix,this.renderer.coordinateSystem);const d=this.targetTriangleDensity;for(const u of i){if(u.material&&(((o=u.geometry)==null?void 0:o.type)==="BoxGeometry"||((s=u.geometry)==null?void 0:s.type)==="BufferGeometry")&&(u.material.name==="SphericalGaussianBlur"||u.material.name=="BackgroundCubeMaterial"||u.material.name==="CubemapFromEquirect"||u.material.name==="EquirectangularToCubeUV")){Z&&(u.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(u.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",u,u.material.name,u.material.type)));continue}switch(u.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}const p=u.object;(p instanceof U||p.isMesh)&&this.updateLODs(t,e,p,d)}const h=a.transparent;for(const u of h){const p=u.object;(p instanceof U||p.isMesh)&&this.updateLODs(t,e,p,d)}}}updateLODs(t,e,r,n){var o,s;for(const d of R)(o=d.onBeforeUpdateLOD)==null||o.call(d,this.renderer,t,e,r);let a=r.userData.LOD_state;a||(a=new Oe,r.userData.LOD_state=a);let i=this.calculateLodLevel(e,r,a,n);i=Math.round(i),i>=0&&this.loadProgressiveMeshes(r,i);let l=0;if(r.material){const d=r["DEBUG:LOD"];if(d!=null&&(l=d),Array.isArray(r.material))for(const h of r.material)this.loadProgressiveTextures(h,l);else this.loadProgressiveTextures(r.material,l)}for(const d of R)(s=d.onAfterUpdatedLOD)==null||s.call(d,this.renderer,t,e,r,i);a.lastLodLevel=i}loadProgressiveTextures(t,e){return t&&t.userData&&t.userData.LOD!==e?(t.userData.LOD=e,O.assignTextureLOD(t,e)):Promise.resolve(null)}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){var o;if(!e)return-1;let s=10+1;if(t){if(Z&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const a=O.getMeshLODInformation(e.geometry),i=a?.lods;if(!i||i.length<=0)return 0;if(!((o=this.cameraFrustrum)!=null&&o.intersectsObject(e)))return 99;const l=e.geometry.boundingBox;if(l&&t.isPerspectiveCamera){const d=t;if(e.geometry.attributes.color&&e.geometry.attributes.color.count<100&&e.geometry.boundingSphere){this._sphere.copy(e.geometry.boundingSphere),this._sphere.applyMatrix4(e.matrixWorld);const g=t.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(g))return 0}if(this._tempBox.copy(l),this._tempBox.applyMatrix4(e.matrixWorld),T.isInside(this._tempBox,this.projectionScreenMatrix))return 0;if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&d.fov>70){const g=this._tempBox.min,m=this._tempBox.max;let b=g.x,x=g.y,S=m.x,_=m.y;const L=2,f=1.5,w=(g.x+m.x)*.5,E=(g.y+m.y)*.5;b=(b-w)*L+w,x=(x-E)*L+E,S=(S-w)*L+w,_=(_-E)*L+E;const C=b<0&&S>0?0:Math.min(Math.abs(g.x),Math.abs(m.x)),W=x<0&&_>0?0:Math.min(Math.abs(g.y),Math.abs(m.y)),j=Math.max(C,W);r.lastCentrality=(f-j)*(f-j)*(f-j)}else r.lastCentrality=1;const h=this._tempBox.getSize(this._tempBoxSize);h.multiplyScalar(.5),screen.availHeight>0&&h.multiplyScalar(this.renderer.domElement.clientHeight/screen.availHeight),h.x*=d.aspect;const u=t.matrixWorldInverse,p=this._tempBox2;p.copy(l),p.applyMatrix4(e.matrixWorld),p.applyMatrix4(u);const D=p.getSize(this._tempBox2Size),P=Math.max(D.x,D.y);if(Math.max(h.x,h.y)!=0&&P!=0&&(h.z=D.z/Math.max(D.x,D.y)*Math.max(h.x,h.y)),r.lastScreenCoverage=Math.max(h.x,h.y,h.z),r.lastScreenspaceVolume.copy(h),r.lastScreenCoverage*=r.lastCentrality,Z&&T.debugDrawLine){const g=this.tempMatrix.copy(this.projectionScreenMatrix);g.invert();const m=T.corner0,b=T.corner1,x=T.corner2,S=T.corner3;m.copy(this._tempBox.min),b.copy(this._tempBox.max),b.x=m.x,x.copy(this._tempBox.max),x.y=m.y,S.copy(this._tempBox.max);const _=(m.z+S.z)*.5;m.z=b.z=x.z=S.z=_,m.applyMatrix4(g),b.applyMatrix4(g),x.applyMatrix4(g),S.applyMatrix4(g),T.debugDrawLine(m,b,255),T.debugDrawLine(m,x,255),T.debugDrawLine(b,S,255),T.debugDrawLine(x,S,255)}let y=999;if(i&&r.lastScreenCoverage>0){for(let g=0;g<i.length;g++)if(i[g].density/r.lastScreenCoverage<n){y=g;break}}y<s&&(s=y)}}return s}};let A=T;c(A,"debugDrawLine"),c(A,"corner0",new B),c(A,"corner1",new B),c(A,"corner2",new B),c(A,"corner3",new B),c(A,"_tempPtInside",new B);class Oe{constructor(){c(this,"lastLodLevel",0),c(this,"lastScreenCoverage",0),c(this,"lastScreenspaceVolume",new B),c(this,"lastCentrality",0)}}const ie=Symbol("NEEDLE_mesh_lod"),q=Symbol("NEEDLE_texture_lod");function ae(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=A.get(e);if(A.addPlugin(new we(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 we{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 l,d,h;if(i[q]==!0)return;i[q]=!0,i.userData&&(i.userData.LOD=-1);const u=Object.keys(i);for(let p=0;p<u.length;p++){const D=u[p],P=i[D];if(P?.isTexture===!0){const y=(d=(l=P.userData)==null?void 0:l.associations)==null?void 0:d.textures,g=n.parser.json.textures[y];if(!g){console.warn("Texture data not found for texture index "+y);continue}if((h=g?.extensions)!=null&&h[I]){const m=g.extensions[I];m&&o&&O.registerTexture(o,P,m.lods.length,m)}}}};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[ie]==!0)return;r[ie]=!0;const s=this.getUrl();if(!s)return;const a=(o=(n=r.userData)==null?void 0:n.gltfExtensions)==null?void 0:o[I];if(a&&s){const i=r.uuid;O.registerMesh(s,i,r,0,a.lods.length,a)}}}function be(t,e,r,n){K(e),H(r),r.register(s=>new O(s,t));const o=A.get(e);return n?.enableLODsManager!==!1&&o.enable(),o}document.addEventListener("DOMContentLoaded",()=>{ae(document.querySelector("model-viewer"))});export{I as EXTENSION_NAME,A as LODsManager,O as NEEDLE_progressive,H as addDracoAndKTX2Loaders,K as createLoaders,re as getRaycastMesh,ae as patchModelViewer,De as setDracoDecoderLocation,xe as setKTX2TranscoderLocation,se as setRaycastMesh,be as useNeedleProgressive};
@@ -1,3 +1,3 @@
1
- "use strict";var ae=Object.defineProperty;var le=(a,e,t)=>e in a?ae(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var u=(a,e,t)=>(le(a,typeof e!="symbol"?e+"":e,t),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const ce=require("three/examples/jsm/libs/meshopt_decoder.module.js"),ue=require("three/examples/jsm/loaders/DRACOLoader.js"),fe=require("three/examples/jsm/loaders/KTX2Loader.js"),g=require("three"),de=require("three/examples/jsm/loaders/GLTFLoader.js");let q="https://www.gstatic.com/draco/versioned/decoders/1.4.1/",J="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";fetch(q+"draco_decoder.js",{method:"head"}).catch(a=>{q="./include/draco/",J="./include/ktx2/"});function ge(a){q=a}function he(a){J=a}let N,Y,U;function Q(a){N||(N=new ue.DRACOLoader,N.setDecoderPath(q),N.setDecoderConfig({type:"js"})),U||(U=new fe.KTX2Loader,U.setTranscoderPath(J)),Y||(Y=ce.MeshoptDecoder),a?U.detectSupport(a):console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures will probably fail")}function Z(a){a.dracoLoader||a.setDRACOLoader(N),a.ktx2Loader||a.setKTX2Loader(U),a.meshoptDecoder||a.setMeshoptDecoder(Y)}function j(a){const t=new URL(window.location.href).searchParams.get(a);return t==null||t==="0"||t==="false"?!1:t===""?!0:t}function pe(a,e){if(e===void 0||e.startsWith("./")||e.startsWith("http")||a===void 0)return e;const t=a.lastIndexOf("/");if(t>=0){const r=a.substring(0,t+1);for(;r.endsWith("/")&&e.startsWith("/");)e=e.substring(1);return r+e}return e}function se(a){var e;return((e=a.userData)==null?void 0:e["needle:raycast-mesh"])instanceof g.BufferGeometry?a.userData["needle:raycast-mesh"]:null}function ie(a,e){(a.type==="Mesh"||a.type==="SkinnedMesh")&&(a.userData||(a.userData={}),a.userData["needle:raycast-mesh"]=e)}const I=new Array,R="NEEDLE_progressive",T=j("debugprogressive"),$=Symbol("needle-progressive-texture"),z=new Map,H=new Set;if(T){let a=function(){e+=1,console.log("Toggle LOD level",e,z),z.forEach((i,n)=>{for(const s of i.keys){const o=n[s];if(o.isBufferGeometry===!0){const l=v.getMeshLODInformation(o),h=l?Math.min(e,l.lods.length):0;n["DEBUG:LOD"]=e,v.assignMeshLOD(n,h),l&&(t=Math.max(t,l.lods.length-1))}else if(n.isMaterial===!0){n["DEBUG:LOD"]=e,v.assignTextureLOD(n,e);break}}}),e>=t&&(e=-1)},e=-1,t=2,r=!1;window.addEventListener("keyup",i=>{i.key==="p"&&a(),i.key==="w"&&(r=!r,H&&H.forEach(n=>{n.name!="BackgroundCubeMaterial"&&"wireframe"in n&&(n.wireframe=r)}))})}function ee(a,e,t){var i;if(!T)return;z.has(a)||z.set(a,{keys:[],sourceId:t});const r=z.get(a);((i=r==null?void 0:r.keys)==null?void 0:i.includes(e))==!1&&r.keys.push(e)}const O=class{constructor(e,t){u(this,"parser");u(this,"url");T&&console.log("Progressive extension registered for",t),this.parser=e,this.url=t}get name(){return R}static getMeshLODInformation(e){const t=this.getAssignedLODInformation(e);return t!=null&&t.key?this.lodInfos.get(t.key):null}static hasLODLevelAvailable(e,t){var n;if(e.isMaterial===!0){for(const s of Object.keys(e)){const o=e[s];if(o.isTexture&&this.hasLODLevelAvailable(o,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&&(n=r==null?void 0:r.userData)!=null&&n.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,n=this.getAssignedLODInformation(i);if(!n)return Promise.resolve(null);for(const s of I)(r=s.onBeforeGetLODMesh)==null||r.call(s,e,t);return e["LOD:requested level"]=t,O.getOrLoadLOD(i,t).then(s=>{if(e["LOD:requested level"]===t){if(delete e["LOD:requested level"],Array.isArray(s)){const o=n.index||0;s=s[o]}s&&i!=s&&s instanceof g.BufferGeometry&&(e.geometry=s,T&&ee(e,"geometry",n.url))}return s}).catch(s=>(console.error("Error loading mesh LOD",e,s),null))}else T&&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=[],n=new Array;if(T&&H.add(r),r.uniforms&&r.isRawShaderMaterial||r.isShaderMaterial===!0){const s=r;for(const o of Object.keys(s.uniforms)){const l=s.uniforms[o].value;if((l==null?void 0:l.isTexture)===!0){const h=this.assignTextureLODForSlot(l,t,r,o);i.push(h),n.push(o)}}}else for(const s of Object.keys(r)){const o=r[s];if((o==null?void 0:o.isTexture)===!0){const l=this.assignTextureLODForSlot(o,t,r,s);i.push(l),n.push(s)}}return Promise.all(i).then(s=>{const o=new Array;for(let l=0;l<s.length;l++){const h=s[l],f=n[l];h&&h.isTexture===!0?o.push({material:r,slot:f,texture:h,level:t}):o.push({material:r,slot:f,texture:null,level:t})}return o})}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):O.getOrLoadLOD(e,t).then(n=>{if(Array.isArray(n))return null;if((n==null?void 0:n.isTexture)===!0){if(n!=e&&(r&&i&&(r[i]=n),T&&i&&r)){const s=this.getAssignedLODInformation(e);s&&ee(r,i,s.url)}return n}else T=="verbose"&&console.warn("No LOD found for",e,t);return null}).catch(n=>(console.error("Error loading LOD",e,n),null))}afterRoot(e){var t,r;return T&&console.log("AFTER",this.url,e),(t=this.parser.json.textures)==null||t.forEach((i,n)=>{if(i!=null&&i.extensions){const s=i==null?void 0:i.extensions[R];if(s){let o=!1;for(const l of this.parser.associations.keys())l.isTexture===!0&&this.parser.associations.get(l).textures===n&&(o=!0,O.registerTexture(this.url,l,n,s));o||this.parser.getDependency("texture",n).then(l=>{l&&O.registerTexture(this.url,l,n,s)})}}}),(r=this.parser.json.meshes)==null||r.forEach((i,n)=>{if(i!=null&&i.extensions){const s=i==null?void 0:i.extensions[R];if(s&&s.lods){for(const o of this.parser.associations.keys())if(o.isMesh){const l=this.parser.associations.get(o);l.meshes===n&&O.registerMesh(this.url,s.guid,o,s.lods.length,l.primitives,s)}}}}),null}static async getOrLoadLOD(e,t){var o,l,h;const r=T=="verbose",i=e.userData.LODS;if(!i)return null;const n=i==null?void 0:i.key;let s;if(e.isTexture===!0){const f=e;f.source&&f.source[$]&&(s=f.source[$])}if(s||(s=O.lodInfos.get(n)),s){if(t>0){let c=!1;const p=Array.isArray(s.lods);if(p&&t>=s.lods.length?c=!0:p||(c=!0),c)return this.lowresCache.get(n)}const f=Array.isArray(s.lods)?s.lods[t].path:s.lods;if(!f)return T&&!s["missing:uri"]&&(s["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+t,s)),null;const y=pe(i.url,f);if(y.endsWith(".glb")||y.endsWith(".gltf")){if(!s.guid)return console.warn("missing pointer for glb/gltf texture",s),null;const c=y+"_"+s.guid,p=this.previouslyLoaded.get(c);if(p!==void 0){r&&console.log(`LOD ${t} was already loading/loaded: ${c}`);let M=await p.catch(F=>(console.error(`Error loading LOD ${t} from ${y}
1
+ "use strict";var ae=Object.defineProperty;var le=(a,e,t)=>e in a?ae(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var u=(a,e,t)=>(le(a,typeof e!="symbol"?e+"":e,t),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const ce=require("three/examples/jsm/libs/meshopt_decoder.module.js"),ue=require("three/examples/jsm/loaders/DRACOLoader.js"),fe=require("three/examples/jsm/loaders/KTX2Loader.js"),g=require("three"),de=require("three/examples/jsm/loaders/GLTFLoader.js");let q="https://www.gstatic.com/draco/versioned/decoders/1.4.1/",J="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";fetch(q+"draco_decoder.js",{method:"head"}).catch(a=>{q="./include/draco/",J="./include/ktx2/"});function ge(a){q=a}function he(a){J=a}let N,Y,U;function Q(a){N||(N=new ue.DRACOLoader,N.setDecoderPath(q),N.setDecoderConfig({type:"js"})),U||(U=new fe.KTX2Loader,U.setTranscoderPath(J)),Y||(Y=ce.MeshoptDecoder),a?U.detectSupport(a):console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures will probably fail")}function Z(a){a.dracoLoader||a.setDRACOLoader(N),a.ktx2Loader||a.setKTX2Loader(U),a.meshoptDecoder||a.setMeshoptDecoder(Y)}function j(a){const t=new URL(window.location.href).searchParams.get(a);return t==null||t==="0"||t==="false"?!1:t===""?!0:t}function pe(a,e){if(e===void 0||e.startsWith("./")||e.startsWith("http")||a===void 0)return e;const t=a.lastIndexOf("/");if(t>=0){const r=a.substring(0,t+1);for(;r.endsWith("/")&&e.startsWith("/");)e=e.substring(1);return r+e}return e}function se(a){var e;return((e=a.userData)==null?void 0:e["needle:raycast-mesh"])instanceof g.BufferGeometry?a.userData["needle:raycast-mesh"]:null}function ie(a,e){(a.type==="Mesh"||a.type==="SkinnedMesh")&&(a.userData||(a.userData={}),a.userData["needle:raycast-mesh"]=e)}const G=new Array,R="NEEDLE_progressive",T=j("debugprogressive"),$=Symbol("needle-progressive-texture"),z=new Map,H=new Set;if(T){let a=function(){e+=1,console.log("Toggle LOD level",e,z),z.forEach((i,n)=>{for(const s of i.keys){const o=n[s];if(o.isBufferGeometry===!0){const l=v.getMeshLODInformation(o),h=l?Math.min(e,l.lods.length):0;n["DEBUG:LOD"]=e,v.assignMeshLOD(n,h),l&&(t=Math.max(t,l.lods.length-1))}else if(n.isMaterial===!0){n["DEBUG:LOD"]=e,v.assignTextureLOD(n,e);break}}}),e>=t&&(e=-1)},e=-1,t=2,r=!1;window.addEventListener("keyup",i=>{i.key==="p"&&a(),i.key==="w"&&(r=!r,H&&H.forEach(n=>{n.name!="BackgroundCubeMaterial"&&"wireframe"in n&&(n.wireframe=r)}))})}function ee(a,e,t){var i;if(!T)return;z.has(a)||z.set(a,{keys:[],sourceId:t});const r=z.get(a);((i=r==null?void 0:r.keys)==null?void 0:i.includes(e))==!1&&r.keys.push(e)}const O=class{constructor(e,t){u(this,"parser");u(this,"url");T&&console.log("Progressive extension registered for",t),this.parser=e,this.url=t}get name(){return R}static getMeshLODInformation(e){const t=this.getAssignedLODInformation(e);return t!=null&&t.key?this.lodInfos.get(t.key):null}static hasLODLevelAvailable(e,t){var n;if(e.isMaterial===!0){for(const s of Object.keys(e)){const o=e[s];if(o.isTexture&&this.hasLODLevelAvailable(o,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&&(n=r==null?void 0:r.userData)!=null&&n.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,n=this.getAssignedLODInformation(i);if(!n)return Promise.resolve(null);for(const s of G)(r=s.onBeforeGetLODMesh)==null||r.call(s,e,t);return e["LOD:requested level"]=t,O.getOrLoadLOD(i,t).then(s=>{if(e["LOD:requested level"]===t){if(delete e["LOD:requested level"],Array.isArray(s)){const o=n.index||0;s=s[o]}s&&i!=s&&s instanceof g.BufferGeometry&&(e.geometry=s,T&&ee(e,"geometry",n.url))}return s}).catch(s=>(console.error("Error loading mesh LOD",e,s),null))}else T&&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=[],n=new Array;if(T&&H.add(r),r.uniforms&&r.isRawShaderMaterial||r.isShaderMaterial===!0){const s=r;for(const o of Object.keys(s.uniforms)){const l=s.uniforms[o].value;if((l==null?void 0:l.isTexture)===!0){const h=this.assignTextureLODForSlot(l,t,r,o);i.push(h),n.push(o)}}}else for(const s of Object.keys(r)){const o=r[s];if((o==null?void 0:o.isTexture)===!0){const l=this.assignTextureLODForSlot(o,t,r,s);i.push(l),n.push(s)}}return Promise.all(i).then(s=>{const o=new Array;for(let l=0;l<s.length;l++){const h=s[l],f=n[l];h&&h.isTexture===!0?o.push({material:r,slot:f,texture:h,level:t}):o.push({material:r,slot:f,texture:null,level:t})}return o})}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):O.getOrLoadLOD(e,t).then(n=>{if(Array.isArray(n))return null;if((n==null?void 0:n.isTexture)===!0){if(n!=e&&(r&&i&&(r[i]=n),T&&i&&r)){const s=this.getAssignedLODInformation(e);s&&ee(r,i,s.url)}return n}else T=="verbose"&&console.warn("No LOD found for",e,t);return null}).catch(n=>(console.error("Error loading LOD",e,n),null))}afterRoot(e){var t,r;return T&&console.log("AFTER",this.url,e),(t=this.parser.json.textures)==null||t.forEach((i,n)=>{if(i!=null&&i.extensions){const s=i==null?void 0:i.extensions[R];if(s){let o=!1;for(const l of this.parser.associations.keys())l.isTexture===!0&&this.parser.associations.get(l).textures===n&&(o=!0,O.registerTexture(this.url,l,n,s));o||this.parser.getDependency("texture",n).then(l=>{l&&O.registerTexture(this.url,l,n,s)})}}}),(r=this.parser.json.meshes)==null||r.forEach((i,n)=>{if(i!=null&&i.extensions){const s=i==null?void 0:i.extensions[R];if(s&&s.lods){for(const o of this.parser.associations.keys())if(o.isMesh){const l=this.parser.associations.get(o);l.meshes===n&&O.registerMesh(this.url,s.guid,o,s.lods.length,l.primitives,s)}}}}),null}static async getOrLoadLOD(e,t){var o,l,h;const r=T=="verbose",i=e.userData.LODS;if(!i)return null;const n=i==null?void 0:i.key;let s;if(e.isTexture===!0){const f=e;f.source&&f.source[$]&&(s=f.source[$])}if(s||(s=O.lodInfos.get(n)),s){if(t>0){let c=!1;const p=Array.isArray(s.lods);if(p&&t>=s.lods.length?c=!0:p||(c=!0),c)return this.lowresCache.get(n)}const f=Array.isArray(s.lods)?s.lods[t].path:s.lods;if(!f)return T&&!s["missing:uri"]&&(s["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+t,s)),null;const y=pe(i.url,f);if(y.endsWith(".glb")||y.endsWith(".gltf")){if(!s.guid)return console.warn("missing pointer for glb/gltf texture",s),null;const c=y+"_"+s.guid,p=this.previouslyLoaded.get(c);if(p!==void 0){r&&console.log(`LOD ${t} was already loading/loaded: ${c}`);let M=await p.catch(F=>(console.error(`Error loading LOD ${t} from ${y}
2
2
  `,F),null)),k=!1;if(M==null||(M instanceof g.Texture&&e instanceof g.Texture?(o=M.image)!=null&&o.data||(l=M.source)!=null&&l.data?M=this.copySettings(e,M):(k=!0,this.previouslyLoaded.delete(c)):M instanceof g.BufferGeometry&&e instanceof g.BufferGeometry&&((h=M.attributes.position)!=null&&h.array||(k=!0,this.previouslyLoaded.delete(c)))),!k)return M}const D=s,b=new Promise(async(M,k)=>{const F=new de.GLTFLoader;Z(F),T&&(await new Promise(L=>setTimeout(L,1e3)),r&&console.warn("Start loading (delayed) "+y,D.guid));let x=y;if(D&&Array.isArray(D.lods)){const L=D.lods[t];L.hash&&(x+="?v="+L.hash)}const m=await F.loadAsync(x).catch(L=>(console.error(`Error loading LOD ${t} from ${y}
3
- `,L),null));if(!m)return null;const P=m.parser;r&&console.log("Loading finished "+y,D.guid);let w=0;if(m.parser.json.textures){let L=!1;for(const d of m.parser.json.textures){if(d!=null&&d.extensions){const S=d==null?void 0:d.extensions[R];if(S!=null&&S.guid&&S.guid===D.guid){L=!0;break}}w++}if(L){let d=await P.getDependency("texture",w);return d&&O.assignLODInformation(i.url,d,n,t,void 0,void 0),r&&console.log('change "'+e.name+'" → "'+d.name+'"',y,w,d,c),e instanceof g.Texture&&(d=this.copySettings(e,d)),d&&(d.guid=D.guid),M(d)}else T&&console.warn("Could not find texture with guid",D.guid)}if(w=0,m.parser.json.meshes){let L=!1;for(const d of m.parser.json.meshes){if(d!=null&&d.extensions){const S=d==null?void 0:d.extensions[R];if(S!=null&&S.guid&&S.guid===D.guid){L=!0;break}}w++}if(L){const d=await P.getDependency("mesh",w),S=D;if(r&&console.log(`Loaded Mesh "${d.name}"`,y,w,d,c),d.isMesh===!0){const B=d.geometry;return O.assignLODInformation(i.url,B,n,t,void 0,S.density),M(B)}else{const B=new Array;for(let E=0;E<d.children.length;E++){const G=d.children[E];if(G instanceof g.Mesh){const W=G.geometry;O.assignLODInformation(i.url,W,n,t,E,S.density),B.push(W)}}return M(B)}}}return M(null)});return this.previouslyLoaded.set(c,b),await b}else if(e instanceof g.Texture){r&&console.log("Load texture from uri: "+y);const p=await new g.TextureLoader().loadAsync(y);return p?(p.guid=s.guid,p.flipY=!1,p.needsUpdate=!0,p.colorSpace=e.colorSpace,r&&console.log(s,p)):T&&console.warn("failed loading",y),p}}else T&&console.warn(`Can not load LOD ${t}: no LOD info found for "${n}" ${e.name}`,e.type);return null}static assignLODInformation(e,t,r,i,n,s){if(!t)return;t.userData||(t.userData={});const o=new ye(e,r,i,n,s);t.userData.LODS=o,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){const r=this._copiedTextures.get(e);return r||(t=t.clone(),this._copiedTextures.set(e,t),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.generateMipmaps=e.generateMipmaps,t)}};let v=O;u(v,"registerTexture",(e,t,r,i)=>{T&&console.log("> Progressive: register texture",r,t.name,t.uuid,t,i),t.source&&(t.source[$]=i);const n=i.guid;O.assignLODInformation(e,t,n,0,0,void 0),O.lodInfos.set(n,i),O.lowresCache.set(n,t)}),u(v,"registerMesh",(e,t,r,i,n,s)=>{var h;T&&console.log("> Progressive: register mesh",n,r.name,s,r.uuid,r);const o=r.geometry;o.userData||(o.userData={}),O.assignLODInformation(e,o,t,i,n,s.density),O.lodInfos.set(t,s);let l=O.lowresCache.get(t);l?l.push(r.geometry):l=[r.geometry],O.lowresCache.set(t,l),i>0&&!se(r)&&ie(r,o);for(const f of I)(h=f.onRegisteredNewMesh)==null||h.call(f,r,s)}),u(v,"lodInfos",new Map),u(v,"previouslyLoaded",new Map),u(v,"lowresCache",new Map),u(v,"_copiedTextures",new Map);class ye{constructor(e,t,r,i,n){u(this,"url");u(this,"key");u(this,"level");u(this,"index");u(this,"density");this.url=e,this.key=t,this.level=r,i!=null&&(this.index=i),n!=null&&(this.density=n)}}const K=j("debugprogressive"),me=j("noprogressive"),te=Symbol("Needle:LODSManager"),A=class{constructor(e){u(this,"renderer");u(this,"projectionScreenMatrix",new g.Matrix4);u(this,"cameraFrustrum",new g.Frustum);u(this,"targetTriangleDensity",2e5);u(this,"updateInterval",0);u(this,"pause",!1);u(this,"_frame",0);u(this,"_originalRender");u(this,"_sphere",new g.Sphere);u(this,"_tempBox",new g.Box3);u(this,"_tempBox2",new g.Box3);u(this,"tempMatrix",new g.Matrix4);u(this,"_tempWorldPosition",new g.Vector3);u(this,"_tempBoxSize",new g.Vector3);u(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[te]?e[te]:new A(e)}enable(){if(this._originalRender)return;let e=0;this._originalRender=this.renderer.render;const t=this;Q(this.renderer),this.renderer.render=function(r,i){t.renderer.getRenderTarget()==null&&(e=0,t._frame+=1);const s=t._frame,o=e++;t.onBeforeRender(r,i,o,s),t._originalRender.call(this,r,i),t.onAfterRender(r,i,o,s)}}disable(){this._originalRender&&(this.renderer.render=this._originalRender,this._originalRender=void 0)}onBeforeRender(e,t,r,i){}onAfterRender(e,t,r,i){var l,h;if(this.pause)return;const n=this.renderer.renderLists.get(e,0),s=n.opaque;let o=!0;if(s.length===1){const f=s[0].material;(f.name==="EffectMaterial"||f.name==="CopyShader")&&(o=!1)}if(o){if(me||this.updateInterval>0&&i%this.updateInterval!=0)return;this.projectionScreenMatrix.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse),this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix,this.renderer.coordinateSystem);const f=this.targetTriangleDensity;for(const c of s){if(c.material&&(((l=c.geometry)==null?void 0:l.type)==="BoxGeometry"||((h=c.geometry)==null?void 0:h.type)==="BufferGeometry")&&(c.material.name==="SphericalGaussianBlur"||c.material.name=="BackgroundCubeMaterial"||c.material.name==="CubemapFromEquirect"||c.material.name==="EquirectangularToCubeUV")){K&&(c.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(c.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",c,c.material.name,c.material.type)));continue}switch(c.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}const p=c.object;(p instanceof g.Mesh||p.isMesh)&&this.updateLODs(e,t,p,f)}const y=n.transparent;for(const c of y){const p=c.object;(p instanceof g.Mesh||p.isMesh)&&this.updateLODs(e,t,p,f)}}}updateLODs(e,t,r,i){var l,h;for(const f of I)(l=f.onBeforeUpdateLOD)==null||l.call(f,this.renderer,e,t,r);let n=r.userData.LOD_state;n||(n=new Le,r.userData.LOD_state=n);let s=this.calculateLodLevel(t,r,n,i);s=Math.round(s),s>=0&&this.loadProgressiveMeshes(r,s);let o=0;if(r.material){const f=r["DEBUG:LOD"];if(f!=null&&(o=f),Array.isArray(r.material))for(const y of r.material)this.loadProgressiveTextures(y,o);else this.loadProgressiveTextures(r.material,o)}for(const f of I)(h=f.onAfterUpdatedLOD)==null||h.call(f,this.renderer,e,t,r,s);n.lastLodLevel=s}loadProgressiveTextures(e,t){return e&&e.userData&&e.userData.LOD!==t?(e.userData.LOD=t,v.assignTextureLOD(e,t)):Promise.resolve(null)}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 v.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,n=(r.x+i.x)*.5,s=(r.y+i.y)*.5;return this._tempPtInside.set(n,s,r.z).applyMatrix4(t).z<0}calculateLodLevel(e,t,r,i){var o;if(!t)return-1;let s=10+1;if(e){if(K&&t["DEBUG:LOD"]!=null)return t["DEBUG:LOD"];const l=v.getMeshLODInformation(t.geometry),h=l==null?void 0:l.lods;if(!h||h.length<=0)return 0;if(!((o=this.cameraFrustrum)!=null&&o.intersectsObject(t)))return 99;const f=t.geometry.boundingBox;if(f&&e.isPerspectiveCamera){const y=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 x=e.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(x))return 0}if(this._tempBox.copy(f),this._tempBox.applyMatrix4(t.matrixWorld),A.isInside(this._tempBox,this.projectionScreenMatrix))return 0;if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&y.fov>70){const x=this._tempBox.min,m=this._tempBox.max;let P=x.x,w=x.y,L=m.x,d=m.y;const S=2,B=1.5,E=(x.x+m.x)*.5,G=(x.y+m.y)*.5;P=(P-E)*S+E,w=(w-G)*S+G,L=(L-E)*S+E,d=(d-G)*S+G;const W=P<0&&L>0?0:Math.min(Math.abs(x.x),Math.abs(m.x)),oe=w<0&&d>0?0:Math.min(Math.abs(x.y),Math.abs(m.y)),X=Math.max(W,oe);r.lastCentrality=(B-X)*(B-X)*(B-X)}else r.lastCentrality=1;const c=this._tempBox.getSize(this._tempBoxSize);c.multiplyScalar(.5),screen.availHeight>0&&c.multiplyScalar(this.renderer.domElement.clientHeight/screen.availHeight),c.x*=y.aspect;const p=e.matrixWorldInverse,D=this._tempBox2;D.copy(f),D.applyMatrix4(t.matrixWorld),D.applyMatrix4(p);const b=D.getSize(this._tempBox2Size),C=Math.max(b.x,b.y);if(Math.max(c.x,c.y)!=0&&C!=0&&(c.z=b.z/Math.max(b.x,b.y)*Math.max(c.x,c.y)),r.lastScreenCoverage=Math.max(c.x,c.y,c.z),r.lastScreenspaceVolume.copy(c),r.lastScreenCoverage*=r.lastCentrality,K&&A.debugDrawLine){const x=this.tempMatrix.copy(this.projectionScreenMatrix);x.invert();const m=A.corner0,P=A.corner1,w=A.corner2,L=A.corner3;m.copy(this._tempBox.min),P.copy(this._tempBox.max),P.x=m.x,w.copy(this._tempBox.max),w.y=m.y,L.copy(this._tempBox.max);const d=(m.z+L.z)*.5;m.z=P.z=w.z=L.z=d,m.applyMatrix4(x),P.applyMatrix4(x),w.applyMatrix4(x),L.applyMatrix4(x),A.debugDrawLine(m,P,255),A.debugDrawLine(m,w,255),A.debugDrawLine(P,L,255),A.debugDrawLine(w,L,255)}let k=999;if(h&&r.lastScreenCoverage>0){for(let x=0;x<h.length;x++)if(h[x].density/r.lastScreenCoverage<i){k=x;break}}k<s&&(s=k)}}return s}};let _=A;u(_,"debugDrawLine"),u(_,"corner0",new g.Vector3),u(_,"corner1",new g.Vector3),u(_,"corner2",new g.Vector3),u(_,"corner3",new g.Vector3),u(_,"_tempPtInside",new g.Vector3);class Le{constructor(){u(this,"lastLodLevel",0);u(this,"lastScreenCoverage",0);u(this,"lastScreenspaceVolume",new g.Vector3);u(this,"lastCentrality",0)}}const re=Symbol("NEEDLE_mesh_lod"),V=Symbol("NEEDLE_texture_lod");function ne(a){if(!a)return null;let e=null,t=null;for(let r=a;r!=null;r=Object.getPrototypeOf(r)){const i=Object.getOwnPropertySymbols(r),n=i.find(o=>o.toString()=="Symbol(renderer)"),s=i.find(o=>o.toString()=="Symbol(scene)");!e&&n!=null&&(e=a[n].threeRenderer),!t&&s!=null&&(t=a[s])}if(e){console.log("Adding Needle LODs to modelviewer");const r=_.get(e);if(_.addPlugin(new De(a)),r.enable(),t){const i=t.camera||t.traverse(n=>n.type=="PerspectiveCamera")[0];i&&e.render(t,i)}return()=>{r.disable()}}return null}class De{constructor(e){u(this,"modelviewer");u(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[V]==!0)return;t[V]=!0;const r=this.tryGetCurrentGLTF(e),i=this.getUrl();if(i&&r&&t.material){let n=function(o){var h,f,y;if(o[V]==!0)return;o[V]=!0,o.userData&&(o.userData.LOD=-1);const l=Object.keys(o);for(let c=0;c<l.length;c++){const p=l[c],D=o[p];if((D==null?void 0:D.isTexture)===!0){const b=(f=(h=D.userData)==null?void 0:h.associations)==null?void 0:f.textures,C=r.parser.json.textures[b];if(!C){console.warn("Texture data not found for texture index "+b);continue}if((y=C==null?void 0:C.extensions)!=null&&y[R]){const M=C.extensions[R];M&&i&&v.registerTexture(i,D,M.lods.length,M)}}}};const s=t.material;if(Array.isArray(s))for(const o of s)n(o);else n(s)}}tryParseMeshLOD(e,t){var n,s;if(t[re]==!0)return;t[re]=!0;const r=this.getUrl();if(!r)return;const i=(s=(n=t.userData)==null?void 0:n.gltfExtensions)==null?void 0:s[R];if(i&&r){const o=t.uuid;v.registerMesh(r,o,t,0,i.lods.length,i)}}}function xe(a,e,t,r){Q(e),Z(t),t.register(n=>new v(n,a));const i=_.get(e);return(r==null?void 0:r.enableLODsManager)!==!1&&i.enable(),i}document.addEventListener("DOMContentLoaded",()=>{ne(document.querySelector("model-viewer"))});exports.EXTENSION_NAME=R;exports.LODsManager=_;exports.NEEDLE_progressive=v;exports.addDracoAndKTX2Loaders=Z;exports.createLoaders=Q;exports.getRaycastMesh=se;exports.patchModelViewer=ne;exports.setDracoDecoderLocation=ge;exports.setKTX2TranscoderLocation=he;exports.setRaycastMesh=ie;exports.useNeedleProgressive=xe;
3
+ `,L),null));if(!m)return null;const P=m.parser;r&&console.log("Loading finished "+y,D.guid);let w=0;if(m.parser.json.textures){let L=!1;for(const d of m.parser.json.textures){if(d!=null&&d.extensions){const S=d==null?void 0:d.extensions[R];if(S!=null&&S.guid&&S.guid===D.guid){L=!0;break}}w++}if(L){let d=await P.getDependency("texture",w);return d&&O.assignLODInformation(i.url,d,n,t,void 0,void 0),r&&console.log('change "'+e.name+'" → "'+d.name+'"',y,w,d,c),e instanceof g.Texture&&(d=this.copySettings(e,d)),d&&(d.guid=D.guid),M(d)}else T&&console.warn("Could not find texture with guid",D.guid)}if(w=0,m.parser.json.meshes){let L=!1;for(const d of m.parser.json.meshes){if(d!=null&&d.extensions){const S=d==null?void 0:d.extensions[R];if(S!=null&&S.guid&&S.guid===D.guid){L=!0;break}}w++}if(L){const d=await P.getDependency("mesh",w),S=D;if(r&&console.log(`Loaded Mesh "${d.name}"`,y,w,d,c),d.isMesh===!0){const B=d.geometry;return O.assignLODInformation(i.url,B,n,t,void 0,S.density),M(B)}else{const B=new Array;for(let E=0;E<d.children.length;E++){const I=d.children[E];if(I instanceof g.Mesh){const W=I.geometry;O.assignLODInformation(i.url,W,n,t,E,S.density),B.push(W)}}return M(B)}}}return M(null)});return this.previouslyLoaded.set(c,b),await b}else if(e instanceof g.Texture){r&&console.log("Load texture from uri: "+y);const p=await new g.TextureLoader().loadAsync(y);return p?(p.guid=s.guid,p.flipY=!1,p.needsUpdate=!0,p.colorSpace=e.colorSpace,r&&console.log(s,p)):T&&console.warn("failed loading",y),p}}else T&&console.warn(`Can not load LOD ${t}: no LOD info found for "${n}" ${e.name}`,e.type);return null}static assignLODInformation(e,t,r,i,n,s){if(!t)return;t.userData||(t.userData={});const o=new ye(e,r,i,n,s);t.userData.LODS=o,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){const r=this._copiedTextures.get(e);return r||(t=t.clone(),this._copiedTextures.set(e,t),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.generateMipmaps=e.generateMipmaps,t)}};let v=O;u(v,"registerTexture",(e,t,r,i)=>{T&&console.log("> Progressive: register texture",r,t.name,t.uuid,t,i),t.source&&(t.source[$]=i);const n=i.guid;O.assignLODInformation(e,t,n,0,0,void 0),O.lodInfos.set(n,i),O.lowresCache.set(n,t)}),u(v,"registerMesh",(e,t,r,i,n,s)=>{var h;T&&console.log("> Progressive: register mesh",n,r.name,s,r.uuid,r);const o=r.geometry;o.userData||(o.userData={}),O.assignLODInformation(e,o,t,i,n,s.density),O.lodInfos.set(t,s);let l=O.lowresCache.get(t);l?l.push(r.geometry):l=[r.geometry],O.lowresCache.set(t,l),i>0&&!se(r)&&ie(r,o);for(const f of G)(h=f.onRegisteredNewMesh)==null||h.call(f,r,s)}),u(v,"lodInfos",new Map),u(v,"previouslyLoaded",new Map),u(v,"lowresCache",new Map),u(v,"_copiedTextures",new Map);class ye{constructor(e,t,r,i,n){u(this,"url");u(this,"key");u(this,"level");u(this,"index");u(this,"density");this.url=e,this.key=t,this.level=r,i!=null&&(this.index=i),n!=null&&(this.density=n)}}const K=j("debugprogressive"),me=j("noprogressive"),te=Symbol("Needle:LODSManager"),A=class{constructor(e){u(this,"renderer");u(this,"projectionScreenMatrix",new g.Matrix4);u(this,"cameraFrustrum",new g.Frustum);u(this,"targetTriangleDensity",2e5);u(this,"updateInterval",0);u(this,"pause",!1);u(this,"_frame",0);u(this,"_originalRender");u(this,"_sphere",new g.Sphere);u(this,"_tempBox",new g.Box3);u(this,"_tempBox2",new g.Box3);u(this,"tempMatrix",new g.Matrix4);u(this,"_tempWorldPosition",new g.Vector3);u(this,"_tempBoxSize",new g.Vector3);u(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){G.push(e)}static removePlugin(e){const t=G.indexOf(e);t>=0&&G.splice(t,1)}static get(e){return e[te]?e[te]:new A(e)}get plugins(){return G}enable(){if(this._originalRender)return;let e=0;this._originalRender=this.renderer.render;const t=this;Q(this.renderer),this.renderer.render=function(r,i){t.renderer.getRenderTarget()==null&&(e=0,t._frame+=1);const s=t._frame,o=e++;t.onBeforeRender(r,i,o,s),t._originalRender.call(this,r,i),t.onAfterRender(r,i,o,s)}}disable(){this._originalRender&&(this.renderer.render=this._originalRender,this._originalRender=void 0)}onBeforeRender(e,t,r,i){}onAfterRender(e,t,r,i){var l,h;if(this.pause)return;const n=this.renderer.renderLists.get(e,0),s=n.opaque;let o=!0;if(s.length===1){const f=s[0].material;(f.name==="EffectMaterial"||f.name==="CopyShader")&&(o=!1)}if(o){if(me||this.updateInterval>0&&i%this.updateInterval!=0)return;this.projectionScreenMatrix.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse),this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix,this.renderer.coordinateSystem);const f=this.targetTriangleDensity;for(const c of s){if(c.material&&(((l=c.geometry)==null?void 0:l.type)==="BoxGeometry"||((h=c.geometry)==null?void 0:h.type)==="BufferGeometry")&&(c.material.name==="SphericalGaussianBlur"||c.material.name=="BackgroundCubeMaterial"||c.material.name==="CubemapFromEquirect"||c.material.name==="EquirectangularToCubeUV")){K&&(c.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(c.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",c,c.material.name,c.material.type)));continue}switch(c.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}const p=c.object;(p instanceof g.Mesh||p.isMesh)&&this.updateLODs(e,t,p,f)}const y=n.transparent;for(const c of y){const p=c.object;(p instanceof g.Mesh||p.isMesh)&&this.updateLODs(e,t,p,f)}}}updateLODs(e,t,r,i){var l,h;for(const f of G)(l=f.onBeforeUpdateLOD)==null||l.call(f,this.renderer,e,t,r);let n=r.userData.LOD_state;n||(n=new Le,r.userData.LOD_state=n);let s=this.calculateLodLevel(t,r,n,i);s=Math.round(s),s>=0&&this.loadProgressiveMeshes(r,s);let o=0;if(r.material){const f=r["DEBUG:LOD"];if(f!=null&&(o=f),Array.isArray(r.material))for(const y of r.material)this.loadProgressiveTextures(y,o);else this.loadProgressiveTextures(r.material,o)}for(const f of G)(h=f.onAfterUpdatedLOD)==null||h.call(f,this.renderer,e,t,r,s);n.lastLodLevel=s}loadProgressiveTextures(e,t){return e&&e.userData&&e.userData.LOD!==t?(e.userData.LOD=t,v.assignTextureLOD(e,t)):Promise.resolve(null)}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 v.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,n=(r.x+i.x)*.5,s=(r.y+i.y)*.5;return this._tempPtInside.set(n,s,r.z).applyMatrix4(t).z<0}calculateLodLevel(e,t,r,i){var o;if(!t)return-1;let s=10+1;if(e){if(K&&t["DEBUG:LOD"]!=null)return t["DEBUG:LOD"];const l=v.getMeshLODInformation(t.geometry),h=l==null?void 0:l.lods;if(!h||h.length<=0)return 0;if(!((o=this.cameraFrustrum)!=null&&o.intersectsObject(t)))return 99;const f=t.geometry.boundingBox;if(f&&e.isPerspectiveCamera){const y=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 x=e.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(x))return 0}if(this._tempBox.copy(f),this._tempBox.applyMatrix4(t.matrixWorld),A.isInside(this._tempBox,this.projectionScreenMatrix))return 0;if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&y.fov>70){const x=this._tempBox.min,m=this._tempBox.max;let P=x.x,w=x.y,L=m.x,d=m.y;const S=2,B=1.5,E=(x.x+m.x)*.5,I=(x.y+m.y)*.5;P=(P-E)*S+E,w=(w-I)*S+I,L=(L-E)*S+E,d=(d-I)*S+I;const W=P<0&&L>0?0:Math.min(Math.abs(x.x),Math.abs(m.x)),oe=w<0&&d>0?0:Math.min(Math.abs(x.y),Math.abs(m.y)),X=Math.max(W,oe);r.lastCentrality=(B-X)*(B-X)*(B-X)}else r.lastCentrality=1;const c=this._tempBox.getSize(this._tempBoxSize);c.multiplyScalar(.5),screen.availHeight>0&&c.multiplyScalar(this.renderer.domElement.clientHeight/screen.availHeight),c.x*=y.aspect;const p=e.matrixWorldInverse,D=this._tempBox2;D.copy(f),D.applyMatrix4(t.matrixWorld),D.applyMatrix4(p);const b=D.getSize(this._tempBox2Size),C=Math.max(b.x,b.y);if(Math.max(c.x,c.y)!=0&&C!=0&&(c.z=b.z/Math.max(b.x,b.y)*Math.max(c.x,c.y)),r.lastScreenCoverage=Math.max(c.x,c.y,c.z),r.lastScreenspaceVolume.copy(c),r.lastScreenCoverage*=r.lastCentrality,K&&A.debugDrawLine){const x=this.tempMatrix.copy(this.projectionScreenMatrix);x.invert();const m=A.corner0,P=A.corner1,w=A.corner2,L=A.corner3;m.copy(this._tempBox.min),P.copy(this._tempBox.max),P.x=m.x,w.copy(this._tempBox.max),w.y=m.y,L.copy(this._tempBox.max);const d=(m.z+L.z)*.5;m.z=P.z=w.z=L.z=d,m.applyMatrix4(x),P.applyMatrix4(x),w.applyMatrix4(x),L.applyMatrix4(x),A.debugDrawLine(m,P,255),A.debugDrawLine(m,w,255),A.debugDrawLine(P,L,255),A.debugDrawLine(w,L,255)}let k=999;if(h&&r.lastScreenCoverage>0){for(let x=0;x<h.length;x++)if(h[x].density/r.lastScreenCoverage<i){k=x;break}}k<s&&(s=k)}}return s}};let _=A;u(_,"debugDrawLine"),u(_,"corner0",new g.Vector3),u(_,"corner1",new g.Vector3),u(_,"corner2",new g.Vector3),u(_,"corner3",new g.Vector3),u(_,"_tempPtInside",new g.Vector3);class Le{constructor(){u(this,"lastLodLevel",0);u(this,"lastScreenCoverage",0);u(this,"lastScreenspaceVolume",new g.Vector3);u(this,"lastCentrality",0)}}const re=Symbol("NEEDLE_mesh_lod"),V=Symbol("NEEDLE_texture_lod");function ne(a){if(!a)return null;let e=null,t=null;for(let r=a;r!=null;r=Object.getPrototypeOf(r)){const i=Object.getOwnPropertySymbols(r),n=i.find(o=>o.toString()=="Symbol(renderer)"),s=i.find(o=>o.toString()=="Symbol(scene)");!e&&n!=null&&(e=a[n].threeRenderer),!t&&s!=null&&(t=a[s])}if(e){console.log("Adding Needle LODs to modelviewer");const r=_.get(e);if(_.addPlugin(new De(a)),r.enable(),t){const i=t.camera||t.traverse(n=>n.type=="PerspectiveCamera")[0];i&&e.render(t,i)}return()=>{r.disable()}}return null}class De{constructor(e){u(this,"modelviewer");u(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[V]==!0)return;t[V]=!0;const r=this.tryGetCurrentGLTF(e),i=this.getUrl();if(i&&r&&t.material){let n=function(o){var h,f,y;if(o[V]==!0)return;o[V]=!0,o.userData&&(o.userData.LOD=-1);const l=Object.keys(o);for(let c=0;c<l.length;c++){const p=l[c],D=o[p];if((D==null?void 0:D.isTexture)===!0){const b=(f=(h=D.userData)==null?void 0:h.associations)==null?void 0:f.textures,C=r.parser.json.textures[b];if(!C){console.warn("Texture data not found for texture index "+b);continue}if((y=C==null?void 0:C.extensions)!=null&&y[R]){const M=C.extensions[R];M&&i&&v.registerTexture(i,D,M.lods.length,M)}}}};const s=t.material;if(Array.isArray(s))for(const o of s)n(o);else n(s)}}tryParseMeshLOD(e,t){var n,s;if(t[re]==!0)return;t[re]=!0;const r=this.getUrl();if(!r)return;const i=(s=(n=t.userData)==null?void 0:n.gltfExtensions)==null?void 0:s[R];if(i&&r){const o=t.uuid;v.registerMesh(r,o,t,0,i.lods.length,i)}}}function xe(a,e,t,r){Q(e),Z(t),t.register(n=>new v(n,a));const i=_.get(e);return(r==null?void 0:r.enableLODsManager)!==!1&&i.enable(),i}document.addEventListener("DOMContentLoaded",()=>{ne(document.querySelector("model-viewer"))});exports.EXTENSION_NAME=R;exports.LODsManager=_;exports.NEEDLE_progressive=v;exports.addDracoAndKTX2Loaders=Z;exports.createLoaders=Q;exports.getRaycastMesh=se;exports.patchModelViewer=ne;exports.setDracoDecoderLocation=ge;exports.setKTX2TranscoderLocation=he;exports.setRaycastMesh=ie;exports.useNeedleProgressive=xe;
@@ -46,6 +46,8 @@ export declare class LODsManager {
46
46
  readonly renderer: WebGLRenderer;
47
47
  readonly projectionScreenMatrix: Matrix4;
48
48
  readonly cameraFrustrum: Frustum;
49
+ /** @deprecated use static `LODsManager.addPlugin()` method. This getter will be removed in later versions */
50
+ get plugins(): NEEDLE_progressive_plugin[];
49
51
  /**
50
52
  * The target triangle density is the desired max amount of triangles on screen when the mesh is filling the screen.
51
53
  * @default 200_000
@@ -66,6 +66,8 @@ export class LODsManager {
66
66
  renderer;
67
67
  projectionScreenMatrix = new Matrix4();
68
68
  cameraFrustrum = new Frustum();
69
+ /** @deprecated use static `LODsManager.addPlugin()` method. This getter will be removed in later versions */
70
+ get plugins() { return plugins; }
69
71
  /**
70
72
  * The target triangle density is the desired max amount of triangles on screen when the mesh is filling the screen.
71
73
  * @default 200_000
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@needle-tools/gltf-progressive",
3
- "version": "1.0.0-alpha.18",
3
+ "version": "1.0.0-alpha.19",
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": {