@needle-tools/engine
Version:
Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.
9 lines (8 loc) • 29.8 kB
JavaScript
"use strict";var Xe=Object.defineProperty;var Ee=i=>{throw TypeError(i)};var qe=(i,t,e)=>t in i?Xe(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e;var d=(i,t,e)=>qe(i,typeof t!="symbol"?t+"":t,e),Ce=(i,t,e)=>t.has(i)||Ee("Cannot "+e);var L=(i,t,e)=>(Ce(i,t,"read from private field"),e?e.call(i):t.get(i)),j=(i,t,e)=>t.has(i)?Ee("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(i):t.set(i,e),z=(i,t,e,r)=>(Ce(i,t,"write to private field"),r?r.call(i,e):t.set(i,e),e);const p=require("./three-DMrv-4ar.umd.cjs"),ee=require("./three-examples-C7ryg8vN.umd.cjs"),Ke="";globalThis.GLTF_PROGRESSIVE_VERSION=Ke;console.debug("[gltf-progressive] version -");let W="https://www.gstatic.com/draco/versioned/decoders/1.5.7/",te="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";const Ye=W,He=te,Ge=new URL(W+"draco_decoder.js");Ge.searchParams.append("range","true");fetch(Ge,{method:"GET",headers:{Range:"bytes=0-1"}}).catch(i=>{console.debug(`Failed to fetch remote Draco decoder from ${W} (offline: ${typeof navigator<"u"?navigator.onLine:"unknown"})`),W===Ye&&ke("./include/draco/"),te===He&&$e("./include/ktx2/")}).finally(()=>{Fe()});function ke(i){W=i,R&&R[_e]!=W?(console.debug("Updating Draco decoder path to "+i),R[_e]=W,R.setDecoderPath(W),R.preload()):console.debug("Setting Draco decoder path to "+i)}function $e(i){te=i,U&&U.transcoderPath!=te?(console.debug("Updating KTX2 transcoder path to "+i),U.setTranscoderPath(te),U.init()):console.debug("Setting KTX2 transcoder path to "+i)}const _e=Symbol("dracoDecoderPath");let R,ye,U;function Fe(){R||(R=new ee.DRACOLoader,R[_e]=W,R.setDecoderPath(W),R.setDecoderConfig({type:"js"}),R.preload()),U||(U=new ee.KTX2Loader,U.setTranscoderPath(te),U.init()),ye||(ye=ee.MeshoptDecoder)}function Te(i){return Fe(),i?U.detectSupport(i):i!==null&&console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"),{dracoLoader:R,ktx2Loader:U,meshoptDecoder:ye}}function Ae(i){i.dracoLoader||i.setDRACOLoader(R),i.ktx2Loader||i.setKTX2Loader(U),i.meshoptDecoder||i.setMeshoptDecoder(ye)}const be=new WeakMap;function Pe(i,t){let e=be.get(i);e?e=Object.assign(e,t):e=t,be.set(i,e)}const De=ee.GLTFLoader.prototype.load;function je(...i){const t=be.get(this);let e=i[0];const r=new URL(e,window.location.href);if(r.hostname.endsWith("needle.tools")){const o=(t==null?void 0:t.progressive)!==void 0?t.progressive:!0,s=t!=null&&t.usecase?t.usecase:"default";o?this.requestHeader.Accept=`*/*;progressive=allowed;usecase=${s}`:this.requestHeader.Accept=`*/*;usecase=${s}`,e=r.toString()}return i[0]=e,De==null?void 0:De.call(this,...i)}ee.GLTFLoader.prototype.load=je;ue("debugprogressive");function ue(i){if(typeof window>"u")return!1;const e=new URL(window.location.href).searchParams.get(i);return e==null||e==="0"||e==="false"?!1:e===""?!0:e}function Je(i,t){if(t===void 0||t.startsWith("./")||t.startsWith("http")||i===void 0)return t;const e=i.lastIndexOf("/");if(e>=0){const r=i.substring(0,e+1);for(;r.endsWith("/")&&t.startsWith("/");)t=t.substring(1);return r+t}return t}let ie;function Qe(){return ie!==void 0||(ie=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),ue("debugprogressive")&&console.log("[glTF Progressive]: isMobileDevice",ie)),ie}const Ze=typeof window>"u"&&typeof document>"u",Se=Symbol("needle:raycast-mesh");function oe(i){return(i==null?void 0:i[Se])instanceof p.BufferGeometry?i[Se]:null}function et(i,t){if((i.type==="Mesh"||i.type==="SkinnedMesh")&&!oe(i)){const r=rt(t);r.userData={isRaycastMesh:!0},i[Se]=r}}function tt(i=!0){if(i){if(ae)return;const t=ae=p.Mesh.prototype.raycast;p.Mesh.prototype.raycast=function(e,r){const n=this,o=oe(n);let s;o&&n.isMesh&&(s=n.geometry,n.geometry=o),t.call(this,e,r),s&&(n.geometry=s)}}else{if(!ae)return;p.Mesh.prototype.raycast=ae,ae=null}}let ae=null;function rt(i){const t=new p.BufferGeometry;for(const e in i.attributes)t.setAttribute(e,i.getAttribute(e));return t.setIndex(i.getIndex()),t}const Q=new Array,D=ue("debugprogressive");let pe,Z=-1;if(D){let i=function(){Z+=1,Z>=t&&(Z=-1),console.log(`Toggle LOD level [${Z}]`)},t=6;window.addEventListener("keyup",e=>{e.key==="p"&&i(),e.key==="w"&&(pe=!pe,console.log(`Toggle wireframe [${pe}]`));const r=parseInt(e.key);!isNaN(r)&&r>=0&&(Z=r,console.log(`Set LOD level to [${Z}]`))})}function Ue(i){if(D)if(Array.isArray(i))for(const t of i)Ue(t);else i&&"wireframe"in i&&(i.wireframe=pe===!0)}const K="NEEDLE_progressive",ve=Symbol("needle-progressive-texture"),M=class M{constructor(t,e){d(this,"parser");d(this,"url");d(this,"_isLoadingMesh");d(this,"loadMesh",t=>{var r,n;if(this._isLoadingMesh)return null;const e=(n=(r=this.parser.json.meshes[t])==null?void 0:r.extensions)==null?void 0:n[K];return e?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",t).then(o=>{var s;return this._isLoadingMesh=!1,o&&M.registerMesh(this.url,e.guid,o,(s=e.lods)==null?void 0:s.length,0,e),o})):null});D&&console.log("Progressive extension registered for",e),this.parser=t,this.url=e}get name(){return K}static getMeshLODExtension(t){const e=this.getAssignedLODInformation(t);return e!=null&&e.key?this.lodInfos.get(e.key):null}static getPrimitiveIndex(t){var r;const e=(r=this.getAssignedLODInformation(t))==null?void 0:r.index;return e??-1}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(D==="verbose"&&console.log("getMaterialMinMaxLODsCount",t),t.type==="ShaderMaterial"||t.type==="RawShaderMaterial"){const a=t;for(const l of Object.keys(a.uniforms)){const u=a.uniforms[l].value;(u==null?void 0:u.isTexture)===!0&&s(u,e)}}else if(t.isMaterial)for(const a of Object.keys(t)){const l=t[a];(l==null?void 0:l.isTexture)===!0&&s(l,e)}return t[n]=e,e;function s(a,l){const u=r.getAssignedLODInformation(a);if(u){const c=r.lodInfos.get(u.key);if(c&&c.lods){l.min_count=Math.min(l.min_count,c.lods.length),l.max_count=Math.max(l.max_count,c.lods.length);for(let h=0;h<c.lods.length;h++){const g=c.lods[h];g.width&&(l.lods[h]=l.lods[h]||{min_height:1/0,max_height:0},l.lods[h].min_height=Math.min(l.lods[h].min_height,g.height),l.lods[h].max_height=Math.max(l.lods[h].max_height,g.height))}}}}}static hasLODLevelAvailable(t,e){var o;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 r,n;if(t.isMesh?r=t.geometry:(t.isBufferGeometry||t.isTexture)&&(r=t),r&&(o=r==null?void 0:r.userData)!=null&&o.LODS){const s=r.userData.LODS;if(n=this.lodInfos.get(s.key),e===void 0)return n!=null;if(n)return Array.isArray(n.lods)?e<n.lods.length:e===0}return!1}static assignMeshLOD(t,e){var r;if(!t)return Promise.resolve(null);if(t instanceof p.Mesh||t.isMesh===!0){const n=t.geometry,o=this.getAssignedLODInformation(n);if(!o)return Promise.resolve(null);for(const s of Q)(r=s.onBeforeGetLODMesh)==null||r.call(s,t,e);return t["LOD:requested level"]=e,M.getOrLoadLOD(n,e).then(s=>{if(Array.isArray(s)){const a=o.index||0;s=s[a]}return t["LOD:requested level"]===e&&(delete t["LOD:requested level"],s&&n!=s&&((s==null?void 0:s.isBufferGeometry)?t.geometry=s:D&&console.error("Invalid LOD geometry",s))),s}).catch(s=>(console.error("Error loading mesh LOD",t,s),null))}else D&&console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh",t);return Promise.resolve(null)}static assignTextureLOD(t,e=0){if(!t)return Promise.resolve(null);if(t.isMesh===!0){const r=t;if(Array.isArray(r.material)){const n=new Array;for(const o of r.material){const s=this.assignTextureLOD(o,e);n.push(s)}return Promise.all(n).then(o=>{const s=new Array;for(const a of o)Array.isArray(a)&&s.push(...a);return s})}else return this.assignTextureLOD(r.material,e)}if(t.isMaterial===!0){const r=t,n=[],o=new Array;if(r.uniforms&&(r.isRawShaderMaterial||r.isShaderMaterial===!0)){const s=r;for(const a of Object.keys(s.uniforms)){const l=s.uniforms[a].value;if((l==null?void 0:l.isTexture)===!0){const u=this.assignTextureLODForSlot(l,e,r,a).then(c=>(c&&s.uniforms[a].value!=c&&(s.uniforms[a].value=c,s.uniformsNeedUpdate=!0),c));n.push(u),o.push(a)}}}else for(const s of Object.keys(r)){const a=r[s];if((a==null?void 0:a.isTexture)===!0){const l=this.assignTextureLODForSlot(a,e,r,s);n.push(l),o.push(s)}}return Promise.all(n).then(s=>{const a=new Array;for(let l=0;l<s.length;l++){const u=s[l],c=o[l];u&&u.isTexture===!0?a.push({material:r,slot:c,texture:u,level:e}):a.push({material:r,slot:c,texture:null,level:e})}return a})}if(t instanceof p.Texture||t.isTexture===!0){const r=t;return this.assignTextureLODForSlot(r,e,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(t,e,r,n){return(t==null?void 0: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==null?void 0:o.isTexture)===!0){if(o!=t&&r&&n){const s=r[n];if(s&&!D){const a=this.getAssignedLODInformation(s);if(a&&(a==null?void 0:a.level)<e)return D==="verbose"&&console.warn("Assigned texture level is already higher: ",a.level,e,r,s,o),null}r[n]=o}return o}else D=="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 D&&console.log("AFTER",this.url,t),(e=this.parser.json.textures)==null||e.forEach((n,o)=>{var s;if(n!=null&&n.extensions){const a=n==null?void 0:n.extensions[K];if(a){if(!a.lods){D&&console.warn("Texture has no LODs",a);return}let l=!1;for(const u of this.parser.associations.keys())if(u.isTexture===!0){const c=this.parser.associations.get(u);(c==null?void 0:c.textures)===o&&(l=!0,M.registerTexture(this.url,u,(s=a.lods)==null?void 0:s.length,o,a))}l||this.parser.getDependency("texture",o).then(u=>{var c;u&&M.registerTexture(this.url,u,(c=a.lods)==null?void 0:c.length,o,a)})}}}),(r=this.parser.json.meshes)==null||r.forEach((n,o)=>{if(n!=null&&n.extensions){const s=n==null?void 0:n.extensions[K];if(s&&s.lods){for(const a of this.parser.associations.keys())if(a.isMesh){const l=this.parser.associations.get(a);(l==null?void 0:l.meshes)===o&&M.registerMesh(this.url,s.guid,a,s.lods.length,l.primitives,s)}}}}),null}static async getOrLoadLOD(t,e){var a,l,u,c;const r=D=="verbose",n=t.userData.LODS;if(!n)return null;const o=n==null?void 0:n.key;let s;if(t.isTexture===!0){const h=t;h.source&&h.source[ve]&&(s=h.source[ve])}if(s||(s=M.lodInfos.get(o)),s){if(e>0){let w=!1;const S=Array.isArray(s.lods);if(S&&e>=s.lods.length?w=!0:S||(w=!0),w)return this.lowresCache.get(o)}const h=Array.isArray(s.lods)?(a=s.lods[e])==null?void 0:a.path:s.lods;if(!h)return D&&!s["missing:uri"]&&(s["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+e,s)),null;const g=Je(n.url,h);if(g.endsWith(".glb")||g.endsWith(".gltf")){if(!s.guid)return console.warn("missing pointer for glb/gltf texture",s),null;const w=g+"_"+s.guid,S=this.previouslyLoaded.get(w);if(S!==void 0){r&&console.log(`LOD ${e} was already loading/loaded: ${w}`);let O=await S.catch(y=>(console.error(`Error loading LOD ${e} from ${g}
`,y),null)),b=!1;if(O==null||(O instanceof p.Texture&&t instanceof p.Texture?(l=O.image)!=null&&l.data||(u=O.source)!=null&&u.data?O=this.copySettings(t,O):(b=!0,this.previouslyLoaded.delete(w)):O instanceof p.BufferGeometry&&t instanceof p.BufferGeometry&&((c=O.attributes.position)!=null&&c.array||(b=!0,this.previouslyLoaded.delete(w)))),!b)return O}const v=s,V=new Promise(async(O,b)=>{const y=new ee.GLTFLoader;Ae(y),D&&(await new Promise(T=>setTimeout(T,1e3)),r&&console.warn("Start loading (delayed) "+g,v.guid));let q=g;if(v&&Array.isArray(v.lods)){const T=v.lods[e];T.hash&&(q+="?v="+T.hash)}const P=await y.loadAsync(q).catch(T=>(console.error(`Error loading LOD ${e} from ${g}
`,T),null));if(!P)return null;const G=P.parser;r&&console.log("Loading finished "+g,v.guid);let I=0;if(P.parser.json.textures){let T=!1;for(const f of P.parser.json.textures){if(f!=null&&f.extensions){const A=f==null?void 0:f.extensions[K];if(A!=null&&A.guid&&A.guid===v.guid){T=!0;break}}I++}if(T){let f=await G.getDependency("texture",I);return f&&M.assignLODInformation(n.url,f,o,e,void 0),r&&console.log('change "'+t.name+'" → "'+f.name+'"',g,I,f,w),t instanceof p.Texture&&(f=this.copySettings(t,f)),f&&(f.guid=v.guid),O(f)}else D&&console.warn("Could not find texture with guid",v.guid,P.parser.json)}if(I=0,P.parser.json.meshes){let T=!1;for(const f of P.parser.json.meshes){if(f!=null&&f.extensions){const A=f==null?void 0:f.extensions[K];if(A!=null&&A.guid&&A.guid===v.guid){T=!0;break}}I++}if(T){const f=await G.getDependency("mesh",I);if(r&&console.log(`Loaded Mesh "${f.name}"`,g,I,f,w),f.isMesh===!0){const A=f.geometry;return M.assignLODInformation(n.url,A,o,e,0),O(A)}else{const A=new Array;for(let x=0;x<f.children.length;x++){const _=f.children[x];if(_.isMesh===!0){const E=_.geometry;M.assignLODInformation(n.url,E,o,e,x),A.push(E)}}return O(A)}}else D&&console.warn("Could not find mesh with guid",v.guid,P.parser.json)}return O(null)});return this.previouslyLoaded.set(w,V),await V}else if(t instanceof p.Texture){r&&console.log("Load texture from uri: "+g);const S=await new p.TextureLoader().loadAsync(g);return S?(S.guid=s.guid,S.flipY=!1,S.needsUpdate=!0,S.colorSpace=t.colorSpace,r&&console.log(s,S)):D&&console.warn("failed loading",g),S}}else D&&console.warn(`Can not load LOD ${e}: no LOD info found for "${o}" ${t.name}`,t.type);return null}static assignLODInformation(t,e,r,n,o){if(!e)return;e.userData||(e.userData={});const s=new st(t,r,n,o);e.userData.LODS=s}static getAssignedLODInformation(t){var e;return((e=t==null?void 0:t.userData)==null?void 0:e.LODS)||null}static copySettings(t,e){return e?(D&&console.warn(`Copy texture settings
`,t.uuid,`
`,e.uuid),e=e.clone(),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):t}};d(M,"registerTexture",(t,e,r,n,o)=>{if(D&&console.log("> Progressive: register texture",n,e.name,e.uuid,e,o),!e){D&&console.error("gltf-progressive: Register texture without texture");return}e.source&&(e.source[ve]=o);const s=o.guid;M.assignLODInformation(t,e,s,r,n),M.lodInfos.set(s,o),M.lowresCache.set(s,e)}),d(M,"registerMesh",(t,e,r,n,o,s)=>{var u;const a=r.geometry;if(!a){D&&console.warn("gltf-progressive: Register mesh without geometry");return}a.userData||(a.userData={}),D&&console.log("> Progressive: register mesh "+r.name,{index:o,uuid:r.uuid},s,r),M.assignLODInformation(t,a,e,n,o),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&&!oe(r)&&et(r,a);for(const c of Q)(u=c.onRegisteredNewMesh)==null||u.call(c,r,s)}),d(M,"lodInfos",new Map),d(M,"previouslyLoaded",new Map),d(M,"lowresCache",new Map);let F=M;class st{constructor(t,e,r,n){d(this,"url");d(this,"key");d(this,"level");d(this,"index");this.url=t,this.key=e,this.level=r,n!=null&&(this.index=n)}}const $=ue("debugprogressive"),ot=ue("noprogressive"),we=Symbol("Needle:LODSManager"),Oe=Symbol("Needle:LODState"),J=Symbol("Needle:CurrentLOD"),C={mesh_lod:-1,texture_lod:-1};var m,B,Y,Le,re,se,me,H;let ce=(m=class{constructor(t,e){d(this,"context");d(this,"renderer");d(this,"projectionScreenMatrix",new p.Matrix4);d(this,"targetTriangleDensity",2e5);d(this,"skinnedMeshAutoUpdateBoundsInterval",30);d(this,"updateInterval","auto");j(this,B,1);d(this,"pause",!1);d(this,"manual",!1);d(this,"_lodchangedlisteners",[]);j(this,Y);j(this,Le,new p.Clock);j(this,re,0);j(this,se,0);j(this,me,0);j(this,H,0);d(this,"_fpsBuffer",[60,60,60,60,60]);d(this,"_sphere",new p.Sphere);d(this,"_tempBox",new p.Box3);d(this,"_tempBox2",new p.Box3);d(this,"tempMatrix",new p.Matrix4);d(this,"_tempWorldPosition",new p.Vector3);d(this,"_tempBoxSize",new p.Vector3);d(this,"_tempBox2Size",new p.Vector3);this.renderer=t,this.context={...e}}static getObjectLODState(t){return t[Oe]}static addPlugin(t){Q.push(t)}static removePlugin(t){const e=Q.indexOf(t);e>=0&&Q.splice(e,1)}static get(t,e){if(t[we])return console.debug("[gltf-progressive] LODsManager already exists for this renderer"),t[we];const r=new m(t,{engine:"unknown",...e});return t[we]=r,r}get plugins(){return Q}addEventListener(t,e){t==="changed"&&this._lodchangedlisteners.push(e)}removeEventListener(t,e){if(t==="changed"){const r=this._lodchangedlisteners.indexOf(e);r>=0&&this._lodchangedlisteners.splice(r,1)}}enable(){if(L(this,Y))return;console.debug("[gltf-progressive] Enabling LODsManager for renderer");let t=0;z(this,Y,this.renderer.render);const e=this;Te(this.renderer),this.renderer.render=function(r,n){const o=e.renderer.getRenderTarget();(o==null||"isXRRenderTarget"in o&&o.isXRRenderTarget)&&(t=0,z(e,re,L(e,re)+1),z(e,se,L(e,Le).getDelta()),z(e,me,L(e,me)+L(e,se)),e._fpsBuffer.shift(),e._fpsBuffer.push(1/L(e,se)),z(e,H,e._fpsBuffer.reduce((a,l)=>a+l)/e._fpsBuffer.length),$&&L(e,re)%200===0&&console.log("FPS",Math.round(L(e,H)),"Interval:",L(e,B)));const s=t++;L(e,Y).call(this,r,n),e.onAfterRender(r,n,s)}}disable(){L(this,Y)&&(console.debug("[gltf-progressive] Disabling LODsManager for renderer"),this.renderer.render=L(this,Y),z(this,Y,void 0))}update(t,e){this.internalUpdate(t,e)}onAfterRender(t,e,r){if(this.pause)return;const o=this.renderer.renderLists.get(t,0).opaque;let s=!0;if(o.length===1){const a=o[0].material;(a.name==="EffectMaterial"||a.name==="CopyShader")&&(s=!1)}if((e.parent&&e.parent.type==="CubeCamera"||r>=1&&e.type==="OrthographicCamera")&&(s=!1),s){if(ot||(this.updateInterval==="auto"?L(this,H)<40&&L(this,B)<10?(z(this,B,L(this,B)+1),$&&console.warn("↓ Reducing LOD updates",L(this,B),L(this,H).toFixed(0))):L(this,H)>=60&&L(this,B)>1&&(z(this,B,L(this,B)-1),$&&console.warn("↑ Increasing LOD updates",L(this,B),L(this,H).toFixed(0))):z(this,B,this.updateInterval),L(this,B)>0&&L(this,re)%L(this,B)!=0))return;this.internalUpdate(t,e)}}internalUpdate(t,e){var l,u;const r=this.renderer.renderLists.get(t,0),n=r.opaque;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse);const o=this.targetTriangleDensity;for(const c of n){if(c.material&&(((l=c.geometry)==null?void 0:l.type)==="BoxGeometry"||((u=c.geometry)==null?void 0:u.type)==="BufferGeometry")&&(c.material.name==="SphericalGaussianBlur"||c.material.name=="BackgroundCubeMaterial"||c.material.name==="CubemapFromEquirect"||c.material.name==="EquirectangularToCubeUV")){$&&(c.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(c.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",c,c.material.name,c.material.type)));continue}switch(c.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}if($==="color"&&c.material&&!c.object.progressive_debug_color){c.object.progressive_debug_color=!0;const g=Math.random()*16777215,w=new p.MeshStandardMaterial({color:g});c.object.material=w}const h=c.object;(h instanceof p.Mesh||h.isMesh)&&this.updateLODs(t,e,h,o)}const s=r.transparent;for(const c of s){const h=c.object;(h instanceof p.Mesh||h.isMesh)&&this.updateLODs(t,e,h,o)}const a=r.transmissive;for(const c of a){const h=c.object;(h instanceof p.Mesh||h.isMesh)&&this.updateLODs(t,e,h,o)}}updateLODs(t,e,r,n){var a,l;r.userData||(r.userData={});let o=r[Oe];if(o||(o=new nt,r[Oe]=o),o.frames++<2)return;for(const u of Q)(a=u.onBeforeUpdateLOD)==null||a.call(u,this.renderer,t,e,r);const s=m.overrideGlobalLodLevel!==void 0?m.overrideGlobalLodLevel:Z;s>=0?(C.mesh_lod=s,C.texture_lod=s):(this.calculateLodLevel(e,r,o,n,C),C.mesh_lod=Math.round(C.mesh_lod),C.texture_lod=Math.round(C.texture_lod)),C.mesh_lod>=0&&this.loadProgressiveMeshes(r,C.mesh_lod),r.material&&C.texture_lod>=0&&this.loadProgressiveTextures(r.material,C.texture_lod),D&&r.material&&!r.isGizmo&&Ue(r.material);for(const u of Q)(l=u.onAfterUpdatedLOD)==null||l.call(u,this.renderer,t,e,r,C);o.lastLodLevel_Mesh=C.mesh_lod,o.lastLodLevel_Texture=C.texture_lod}loadProgressiveTextures(t,e){if(!t)return;if(Array.isArray(t)){for(const o of t)this.loadProgressiveTextures(o,e);return}let r=!1;(t[J]===void 0||e<t[J])&&(r=!0);const n=t["DEBUG:LOD"];n!=null&&(r=t[J]!=n,e=n),r&&(t[J]=e,F.assignTextureLOD(t,e).then(o=>{this._lodchangedlisteners.forEach(s=>s({type:"texture",level:e,object:t}))}))}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);let r=t[J]!==e;const n=t["DEBUG:LOD"];if(n!=null&&(r=t[J]!=n,e=n),r){t[J]=e;const o=t.geometry;return F.assignMeshLOD(t,e).then(s=>(s&&t[J]==e&&o!=t.geometry&&this._lodchangedlisteners.forEach(a=>a({type:"mesh",level:e,object:t})),s))}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 V,X,O;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,l=!1;if($&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const u=(V=F.getMeshLODExtension(e.geometry))==null?void 0:V.lods,c=F.getPrimitiveIndex(e.geometry),h=u&&u.length>0,g=F.getMaterialMinMaxLODsCount(e.material),w=(g==null?void 0:g.min_count)!=1/0&&g.min_count>0&&g.max_count>0;if(!h&&!w){o.mesh_lod=0,o.texture_lod=0;return}h||(l=!0,a=0);const S=this.renderer.domElement.clientHeight||this.renderer.domElement.height;let v=e.geometry.boundingBox;if(e.type==="SkinnedMesh"){const b=e;if(!b.boundingBox)b.computeBoundingBox();else if(this.skinnedMeshAutoUpdateBoundsInterval>0&&r.frames%this.skinnedMeshAutoUpdateBoundsInterval===0){const y=oe(b),q=b.geometry;y&&(b.geometry=y),b.computeBoundingBox(),b.geometry=q}v=b.boundingBox}if(v){const b=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(v),this._tempBox.applyMatrix4(e.matrixWorld),b.isPerspectiveCamera&&m.isInside(this._tempBox,this.projectionScreenMatrix)){o.mesh_lod=0,o.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&b.isPerspectiveCamera&&b.fov>70){const x=this._tempBox.min,_=this._tempBox.max;let E=x.x,k=x.y,N=_.x,ne=_.y;const de=2,xe=1.5,fe=(x.x+_.x)*.5,he=(x.y+_.y)*.5;E=(E-fe)*de+fe,k=(k-he)*de+he,N=(N-fe)*de+fe,ne=(ne-he)*de+he;const ze=E<0&&N>0?0:Math.min(Math.abs(x.x),Math.abs(_.x)),We=k<0&&ne>0?0:Math.min(Math.abs(x.y),Math.abs(_.y)),Me=Math.max(ze,We);r.lastCentrality=(xe-Me)*(xe-Me)*(xe-Me)}else r.lastCentrality=1;const y=this._tempBox.getSize(this._tempBoxSize);y.multiplyScalar(.5),screen.availHeight>0&&S>0&&y.multiplyScalar(S/screen.availHeight),t.isPerspectiveCamera?y.x*=t.aspect:t.isOrthographicCamera;const q=t.matrixWorldInverse,P=this._tempBox2;P.copy(v),P.applyMatrix4(e.matrixWorld),P.applyMatrix4(q);const G=P.getSize(this._tempBox2Size),I=Math.max(G.x,G.y);if(Math.max(y.x,y.y)!=0&&I!=0&&(y.z=G.z/Math.max(G.x,G.y)*Math.max(y.x,y.y)),r.lastScreenCoverage=Math.max(y.x,y.y,y.z),r.lastScreenspaceVolume.copy(y),r.lastScreenCoverage*=r.lastCentrality,$&&m.debugDrawLine){const x=this.tempMatrix.copy(this.projectionScreenMatrix);x.invert();const _=m.corner0,E=m.corner1,k=m.corner2,N=m.corner3;_.copy(this._tempBox.min),E.copy(this._tempBox.max),E.x=_.x,k.copy(this._tempBox.max),k.y=_.y,N.copy(this._tempBox.max);const ne=(_.z+N.z)*.5;_.z=E.z=k.z=N.z=ne,_.applyMatrix4(x),E.applyMatrix4(x),k.applyMatrix4(x),N.applyMatrix4(x),m.debugDrawLine(_,E,255),m.debugDrawLine(_,k,255),m.debugDrawLine(E,N,255),m.debugDrawLine(k,N,255)}let f=999;if(u&&r.lastScreenCoverage>0)for(let x=0;x<u.length;x++){const _=u[x];if((((X=_.densities)==null?void 0:X[c])||_.density||1e-5)/r.lastScreenCoverage<n){f=x;break}}f<a&&(a=f,l=!0)}if(l?o.mesh_lod=a:o.mesh_lod=r.lastLodLevel_Mesh,$&&o.mesh_lod!=r.lastLodLevel_Mesh){const y=u==null?void 0:u[o.mesh_lod];y&&console.log(`Mesh LOD changed: ${r.lastLodLevel_Mesh} → ${o.mesh_lod} (${y.density.toFixed(0)}) - ${e.name}`)}if(w){const b="saveData"in globalThis.navigator&&globalThis.navigator.saveData===!0;if(r.lastLodLevel_Texture<0){if(o.texture_lod=g.max_count-1,$){const y=g.lods[g.max_count-1];$&&console.log(`First Texture LOD ${o.texture_lod} (${y.max_height}px) - ${e.name}`)}}else{const y=r.lastScreenspaceVolume.x+r.lastScreenspaceVolume.y+r.lastScreenspaceVolume.z;let q=r.lastScreenCoverage*4;((O=this.context)==null?void 0:O.engine)==="model-viewer"&&(q*=1.5);const G=S/window.devicePixelRatio*q;let I=!1;for(let T=g.lods.length-1;T>=0;T--){const f=g.lods[T];if(!(b&&f.max_height>=2048)&&!(Qe()&&f.max_height>4096)&&(f.max_height>G||!I&&T===0)){if(I=!0,o.texture_lod=T,o.texture_lod<r.lastLodLevel_Texture){const A=f.max_height;$&&console.log(`Texture LOD changed: ${r.lastLodLevel_Texture} → ${o.texture_lod} = ${A}px
Screensize: ${G.toFixed(0)}px, Coverage: ${(100*r.lastScreenCoverage).toFixed(2)}%, Volume ${y.toFixed(1)}
${e.name}`)}break}}}}else o.texture_lod=0}},B=new WeakMap,Y=new WeakMap,Le=new WeakMap,re=new WeakMap,se=new WeakMap,me=new WeakMap,H=new WeakMap,d(m,"debugDrawLine"),d(m,"overrideGlobalLodLevel"),d(m,"corner0",new p.Vector3),d(m,"corner1",new p.Vector3),d(m,"corner2",new p.Vector3),d(m,"corner3",new p.Vector3),d(m,"_tempPtInside",new p.Vector3),m);class nt{constructor(){d(this,"frames",0);d(this,"lastLodLevel_Mesh",-1);d(this,"lastLodLevel_Texture",-1);d(this,"lastScreenCoverage",0);d(this,"lastScreenspaceVolume",new p.Vector3);d(this,"lastCentrality",0)}}const Be=Symbol("NEEDLE_mesh_lod"),ge=Symbol("NEEDLE_texture_lod");let le=null;function Ve(){const i=it();i&&(i.mapURLs(function(t){return Re(),t}),Re(),le==null||le.disconnect(),le=new MutationObserver(t=>{t.forEach(e=>{e.addedNodes.forEach(r=>{r instanceof HTMLElement&&r.tagName.toLowerCase()==="model-viewer"&&Ne(r)})})}),le.observe(document,{childList:!0,subtree:!0}))}function it(){if(typeof customElements>"u")return null;const i=customElements.get("model-viewer");return i||(customElements.whenDefined("model-viewer").then(()=>{console.debug("[gltf-progressive] model-viewer defined"),Ve()}),null)}function Re(){if(typeof document>"u")return;document.querySelectorAll("model-viewer").forEach(t=>{Ne(t)})}const Ie=new WeakSet;let at=0;function Ne(i){if(!i||Ie.has(i))return null;Ie.add(i),console.debug("[gltf-progressive] found new model-viewer..."+ ++at+`
`,i.getAttribute("src"));let t=null,e=null,r=null;for(let n=i;n!=null;n=Object.getPrototypeOf(n)){const o=Object.getOwnPropertySymbols(n),s=o.find(u=>u.toString()=="Symbol(renderer)"),a=o.find(u=>u.toString()=="Symbol(scene)"),l=o.find(u=>u.toString()=="Symbol(needsRender)");!t&&s!=null&&(t=i[s].threeRenderer),!e&&a!=null&&(e=i[a]),!r&&l!=null&&(r=i[l])}if(t&&e){let n=function(){if(r){let s=0,a=setInterval(()=>{if(s++>5){clearInterval(a);return}r==null||r.call(i)},300)}};console.debug("[gltf-progressive] setup model-viewer");const o=ce.get(t,{engine:"model-viewer"});return ce.addPlugin(new lt),o.enable(),o.addEventListener("changed",()=>{r==null||r.call(i)}),i.addEventListener("model-visibility",s=>{s.detail.visible&&(r==null||r.call(i))}),i.addEventListener("load",()=>{n()}),()=>{o.disable()}}return null}class lt{constructor(){d(this,"_didWarnAboutMissingUrl",!1)}onBeforeUpdateLOD(t,e,r,n){this.tryParseMeshLOD(e,n),this.tryParseTextureLOD(e,n)}getUrl(t){if(!t)return null;let e=t.getAttribute("src");return e||(e=t.src),e||(this._didWarnAboutMissingUrl||console.warn("No url found in modelviewer",t),this._didWarnAboutMissingUrl=!0),e}tryGetCurrentGLTF(t){return t._currentGLTF}tryGetCurrentModelViewer(t){return t.element}tryParseTextureLOD(t,e){if(e[ge]==!0)return;e[ge]=!0;const r=this.tryGetCurrentGLTF(t),n=this.tryGetCurrentModelViewer(t),o=this.getUrl(n);if(o&&r&&e.material){let s=function(l){var c,h,g;if(l[ge]==!0)return;l[ge]=!0,l.userData&&(l.userData.LOD=-1);const u=Object.keys(l);for(let w=0;w<u.length;w++){const S=u[w],v=l[S];if((v==null?void 0:v.isTexture)===!0){const V=(h=(c=v.userData)==null?void 0:c.associations)==null?void 0:h.textures;if(V==null)continue;const X=r.parser.json.textures[V];if(!X){console.warn("Texture data not found for texture index "+V);continue}if((g=X==null?void 0:X.extensions)!=null&&g[K]){const O=X.extensions[K];O&&o&&F.registerTexture(o,v,O.lods.length,V,O)}}}};const a=e.material;if(Array.isArray(a))for(const l of a)s(l);else s(a)}}tryParseMeshLOD(t,e){var s,a;if(e[Be]==!0)return;e[Be]=!0;const r=this.tryGetCurrentModelViewer(t),n=this.getUrl(r);if(!n)return;const o=(a=(s=e.userData)==null?void 0:s.gltfExtensions)==null?void 0:a[K];if(o&&n){const l=e.uuid;F.registerMesh(n,l,e,0,o.lods.length,o)}}}function ct(i,t,e,r){Te(t),Ae(e),Pe(e,{progressive:!0,...r==null?void 0:r.hints}),e.register(o=>new F(o,i));const n=ce.get(t);return(r==null?void 0:r.enableLODsManager)!==!1&&n.enable(),n}Ve();if(!Ze){const i={gltfProgressive:{useNeedleProgressive:ct,LODsManager:ce,configureLoader:Pe,getRaycastMesh:oe,useRaycastMeshes:tt}};if(!globalThis.Needle)globalThis.Needle=i;else for(const t in i)globalThis.Needle[t]=i[t]}exports.LODsManager=ce;exports.NEEDLE_progressive=F;exports.addDracoAndKTX2Loaders=Ae;exports.configureLoader=Pe;exports.createLoaders=Te;exports.getRaycastMesh=oe;exports.setDracoDecoderLocation=ke;exports.setKTX2TranscoderLocation=$e;