@needle-tools/engine 4.7.4 → 4.8.0-alpha.1
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/dist/gltf-progressive-CBWvONCe.js +1385 -0
- package/dist/gltf-progressive-DvKoBHYV.min.js +8 -0
- package/dist/gltf-progressive-Dz8fohdH.umd.cjs +8 -0
- package/dist/loader.worker-D5fjeWJO.js +27 -0
- package/dist/needle-engine.bundle-Bhmfsu91.umd.cjs +1607 -0
- package/dist/needle-engine.bundle-CGLKqtPw.min.js +1607 -0
- package/dist/needle-engine.bundle-DSifkT49.js +42600 -0
- package/dist/needle-engine.d.ts +15 -15
- package/dist/needle-engine.js +591 -592
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/dist/{postprocessing-BzY0H7ry.min.js → postprocessing-ChsrvDkI.min.js} +54 -54
- package/dist/{postprocessing-vKBVFpSz.js → postprocessing-DElbMQgB.js} +479 -483
- package/dist/{postprocessing-Dw2OCMp4.umd.cjs → postprocessing-DtxaELce.umd.cjs} +66 -66
- package/dist/{three-examples-DUcCNw9s.umd.cjs → three-examples-BhQvv1B9.umd.cjs} +11 -11
- package/dist/{three-examples-tvuhV8Ne.js → three-examples-CM6Iip03.js} +23 -27
- package/dist/{three-examples-BMOhDaYR.min.js → three-examples-D2zemuAM.min.js} +12 -12
- package/dist/{three-mesh-ui-CxuWt7m-.js → three-mesh-ui-D6Mz5Yl7.js} +799 -810
- package/dist/three-mesh-ui-DWcMuyQ_.min.js +406 -0
- package/dist/three-mesh-ui-tt0buEDC.umd.cjs +406 -0
- package/dist/{vendor-BmYIgaS1.js → vendor-ClB-U1Hn.js} +10 -10
- package/dist/{vendor-Cavtu3CP.umd.cjs → vendor-bOWOWClg.umd.cjs} +1 -1
- package/lib/engine/engine_serialization_builtin_serializer.js +1 -1
- package/lib/engine/engine_serialization_builtin_serializer.js.map +1 -1
- package/lib/engine/extensions/extensions.js +1 -1
- package/lib/engine/extensions/extensions.js.map +1 -1
- package/lib/engine-components/export/usdz/extensions/behavior/Behaviour.d.ts +1 -1
- package/lib/engine-components/postprocessing/PostProcessingHandler.d.ts +1 -0
- package/lib/engine-components/postprocessing/PostProcessingHandler.js +8 -0
- package/lib/engine-components/postprocessing/PostProcessingHandler.js.map +1 -1
- package/package.json +4 -4
- package/plugins/vite/dependencies.js +28 -19
- package/plugins/vite/dependency-watcher.js +6 -1
- package/src/engine/engine_serialization_builtin_serializer.ts +1 -1
- package/src/engine/extensions/extensions.ts +1 -1
- package/src/engine-components/postprocessing/PostProcessingHandler.ts +14 -0
- package/dist/gltf-progressive-Bgh1c4Fd.js +0 -1224
- package/dist/gltf-progressive-D6f5talj.min.js +0 -8
- package/dist/gltf-progressive-otA_hxSA.umd.cjs +0 -8
- package/dist/needle-engine.bundle-Bb6xVcZE.min.js +0 -1607
- package/dist/needle-engine.bundle-BldBPoPh.js +0 -43846
- package/dist/needle-engine.bundle-ByrSH-zp.umd.cjs +0 -1607
- package/dist/three-mesh-ui-B3p3gyUz.min.js +0 -406
- package/dist/three-mesh-ui-CQiIQIlA.umd.cjs +0 -406
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
var He=Object.defineProperty,Ae=s=>{throw TypeError(s)},Qe=(s,e,t)=>e in s?He(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t,d=(s,e,t)=>Qe(s,typeof e!="symbol"?e+"":e,t),Ie=(s,e,t)=>e.has(s)||Ae("Cannot "+t),_=(s,e,t)=>(Ie(s,e,"read from private field"),t?t.call(s):e.get(s)),Z=(s,e,t)=>e.has(s)?Ae("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(s):e.set(s,t),F=(s,e,t,n)=>(Ie(s,e,"write to private field"),n?n.call(s,t):e.set(s,t),t);import{BufferGeometry as de,Mesh as J,Texture as re,TextureLoader as Ye,Matrix4 as Ce,Clock as Ze,MeshStandardMaterial as Je,Sphere as et,Box3 as ke,Vector3 as U}from"./three-DuDKwKB8.min.js";import{DRACOLoader as tt,KTX2Loader as st,MeshoptDecoder as rt,GLTFLoader as we}from"./three-examples-BMOhDaYR.min.js";const nt="";globalThis.GLTF_PROGRESSIVE_VERSION=nt,console.debug("[gltf-progressive] version -");let N="https://www.gstatic.com/draco/versioned/decoders/1.5.7/",te="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";const ot=N,it=te,Be=new URL(N+"draco_decoder.js");Be.searchParams.append("range","true"),fetch(Be,{method:"GET",headers:{Range:"bytes=0-1"}}).catch(s=>{console.debug(`Failed to fetch remote Draco decoder from ${N} (offline: ${typeof navigator<"u"?navigator.onLine:"unknown"})`),N===ot&&$e("./include/draco/"),te===it&&Ge("./include/ktx2/")}).finally(()=>{je()});function $e(s){N=s,C&&C[Le]!=N?(console.debug("Updating Draco decoder path to "+s),C[Le]=N,C.setDecoderPath(N),C.preload()):console.debug("Setting Draco decoder path to "+s)}function Ge(s){te=s,G&&G.transcoderPath!=te?(console.debug("Updating KTX2 transcoder path to "+s),G.setTranscoderPath(te),G.init()):console.debug("Setting KTX2 transcoder path to "+s)}const Le=Symbol("dracoDecoderPath");let C,ce,G;function je(){C||(C=new tt,C[Le]=N,C.setDecoderPath(N),C.setDecoderConfig({type:"js"}),C.preload()),G||(G=new st,G.setTranscoderPath(te),G.init()),ce||(ce=rt)}function _e(s){return je(),s?G.detectSupport(s):s!==null&&console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"),{dracoLoader:C,ktx2Loader:G,meshoptDecoder:ce}}function De(s){s.dracoLoader||s.setDRACOLoader(C),s.ktx2Loader||s.setKTX2Loader(G),s.meshoptDecoder||s.setMeshoptDecoder(ce)}const Me=new WeakMap;function be(s,e){let t=Me.get(s);t?t=Object.assign(t,e):t=e,Me.set(s,t)}const Re=we.prototype.load;function at(...s){const e=Me.get(this);let t=s[0];const n=new URL(t,window.location.href);if(n.hostname.endsWith("needle.tools")){const r=e?.progressive!==void 0?e.progressive:!0,i=e!=null&&e.usecase?e.usecase:"default";r?this.requestHeader.Accept=`*/*;progressive=allowed;usecase=${i}`:this.requestHeader.Accept=`*/*;usecase=${i}`,t=n.toString()}return s[0]=t,Re?.call(this,...s)}we.prototype.load=at,ne("debugprogressive");function ne(s){if(typeof window>"u")return!1;const e=new URL(window.location.href).searchParams.get(s);return e==null||e==="0"||e==="false"?!1:e===""?!0:e}function lt(s,e){if(e===void 0||e.startsWith("./")||e.startsWith("http")||s===void 0)return e;const t=s.lastIndexOf("/");if(t>=0){const n=s.substring(0,t+1);for(;n.endsWith("/")&&e.startsWith("/");)e=e.substring(1);return n+e}return e}let he;function ut(){return he!==void 0||(he=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),ne("debugprogressive")&&console.log("[glTF Progressive]: isMobileDevice",he)),he}function Ne(){if(typeof window>"u")return!1;const s=new URL(window.location.href),e=s.hostname==="localhost"||/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(s.hostname);return s.hostname==="127.0.0.1"||e}class dt{constructor(e=100,t={}){d(this,"_running",new Map),d(this,"_queue",[]),d(this,"debug",!1),d(this,"tick",()=>{this.internalUpdate(),setTimeout(this.tick,10)}),this.maxConcurrent=e,this.debug=t.debug??!1,window.requestAnimationFrame(this.tick)}slot(e){return this.debug&&console.debug(`[PromiseQueue]: Requesting slot for key ${e}, running: ${this._running.size}, waiting: ${this._queue.length}`),new Promise(t=>{this._queue.push({key:e,resolve:t})})}add(e,t){this._running.has(e)||(this._running.set(e,t),t.finally(()=>{this._running.delete(e),this.debug&&console.debug(`[PromiseQueue]: Promise finished now running: ${this._running.size}, waiting: ${this._queue.length}. (finished ${e})`)}),this.debug&&console.debug(`[PromiseQueue]: Added new promise, now running: ${this._running.size}, waiting: ${this._queue.length}. (added ${e})`))}internalUpdate(){const e=this.maxConcurrent-this._running.size;for(let t=0;t<e&&this._queue.length>0;t++){this.debug&&console.debug(`[PromiseQueue]: Running ${this._running.size} promises, waiting for ${this._queue.length} more.`);const{key:n,resolve:r}=this._queue.shift();r({use:i=>this.add(n,i)})}}}const ct=typeof window>"u"&&typeof document>"u",Oe=Symbol("needle:raycast-mesh");function se(s){return s?.[Oe]instanceof de?s[Oe]:null}function ht(s,e){if((s.type==="Mesh"||s.type==="SkinnedMesh")&&!se(s)){const t=ft(e);t.userData={isRaycastMesh:!0},s[Oe]=t}}function gt(s=!0){if(s){if(oe)return;const e=oe=J.prototype.raycast;J.prototype.raycast=function(t,n){const r=this,i=se(r);let o;i&&r.isMesh&&(o=r.geometry,r.geometry=i),e.call(this,t,n),o&&(r.geometry=o)}}else{if(!oe)return;J.prototype.raycast=oe,oe=null}}let oe=null;function ft(s){const e=new de;for(const t in s.attributes)e.setAttribute(t,s.getAttribute(t));return e.setIndex(s.getIndex()),e}const V=new Array,y=ne("debugprogressive");let ge,ee=-1;if(y){let s=function(){ee+=1,ee>=e&&(ee=-1),console.log(`Toggle LOD level [${ee}]`)},e=6;window.addEventListener("keyup",t=>{t.key==="p"&&s(),t.key==="w"&&(ge=!ge,console.log(`Toggle wireframe [${ge}]`));const n=parseInt(t.key);!isNaN(n)&&n>=0&&(ee=n,console.log(`Set LOD level to [${ee}]`))})}function Fe(s){if(y)if(Array.isArray(s))for(const e of s)Fe(e);else s&&"wireframe"in s&&(s.wireframe=ge===!0)}const W="NEEDLE_progressive",Se=Symbol("needle-progressive-texture"),T=class R{constructor(e,t){d(this,"parser"),d(this,"url"),d(this,"_isLoadingMesh"),d(this,"loadMesh",n=>{var r,i;if(this._isLoadingMesh)return null;const o=(i=(r=this.parser.json.meshes[n])==null?void 0:r.extensions)==null?void 0:i[W];return o?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",n).then(a=>{var l;return this._isLoadingMesh=!1,a&&R.registerMesh(this.url,o.guid,a,(l=o.lods)==null?void 0:l.length,0,o),a})):null}),y&&console.log("Progressive extension registered for",t),this.parser=e,this.url=t}get name(){return W}static getMeshLODExtension(e){const t=this.getAssignedLODInformation(e);return t!=null&&t.key?this.lodInfos.get(t.key):null}static getPrimitiveIndex(e){var t;return((t=this.getAssignedLODInformation(e))==null?void 0:t.index)??-1}static getMaterialMinMaxLODsCount(e,t){const n=this,r="LODS:minmax",i=e[r];if(i!=null)return i;if(t||(t={min_count:1/0,max_count:0,lods:[]}),Array.isArray(e)){for(const a of e)this.getMaterialMinMaxLODsCount(a,t);return e[r]=t,t}if(y==="verbose"&&console.log("getMaterialMinMaxLODsCount",e),e.type==="ShaderMaterial"||e.type==="RawShaderMaterial"){const a=e;for(const l of Object.keys(a.uniforms)){const u=a.uniforms[l].value;u?.isTexture===!0&&o(u,t)}}else if(e.isMaterial)for(const a of Object.keys(e)){const l=e[a];l?.isTexture===!0&&o(l,t)}return e[r]=t,t;function o(a,l){const u=n.getAssignedLODInformation(a);if(u){const c=n.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 L=0;L<c.lods.length;L++){const p=c.lods[L];p.width&&(l.lods[L]=l.lods[L]||{min_height:1/0,max_height:0},l.lods[L].min_height=Math.min(l.lods[L].min_height,p.height),l.lods[L].max_height=Math.max(l.lods[L].max_height,p.height))}}}}}static hasLODLevelAvailable(e,t){var n;if(Array.isArray(e)){for(const o of e)if(this.hasLODLevelAvailable(o,t))return!0;return!1}if(e.isMaterial===!0){for(const o of Object.keys(e)){const a=e[o];if(a&&a.isTexture&&this.hasLODLevelAvailable(a,t))return!0}return!1}else if(e.isGroup===!0){for(const o of e.children)if(o.isMesh===!0&&this.hasLODLevelAvailable(o,t))return!0}let r,i;if(e.isMesh?r=e.geometry:(e.isBufferGeometry||e.isTexture)&&(r=e),r&&(n=r?.userData)!=null&&n.LODS){const o=r.userData.LODS;if(i=this.lodInfos.get(o.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 n;if(!e)return Promise.resolve(null);if(e instanceof J||e.isMesh===!0){const r=e.geometry,i=this.getAssignedLODInformation(r);if(!i)return Promise.resolve(null);for(const o of V)(n=o.onBeforeGetLODMesh)==null||n.call(o,e,t);return e["LOD:requested level"]=t,R.getOrLoadLOD(r,t).then(o=>{if(Array.isArray(o)){const a=i.index||0;o=o[a]}return e["LOD:requested level"]===t&&(delete e["LOD:requested level"],o&&r!=o&&(o?.isBufferGeometry?e.geometry=o:y&&console.error("Invalid LOD geometry",o))),o}).catch(o=>(console.error("Error loading mesh LOD",e,o),null))}else y&&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.isMesh===!0){const n=e;if(Array.isArray(n.material)){const r=new Array;for(const i of n.material){const o=this.assignTextureLOD(i,t);r.push(o)}return Promise.all(r).then(i=>{const o=new Array;for(const a of i)Array.isArray(a)&&o.push(...a);return o})}else return this.assignTextureLOD(n.material,t)}if(e.isMaterial===!0){const n=e,r=[],i=new Array;if(n.uniforms&&(n.isRawShaderMaterial||n.isShaderMaterial===!0)){const o=n;for(const a of Object.keys(o.uniforms)){const l=o.uniforms[a].value;if(l?.isTexture===!0){const u=this.assignTextureLODForSlot(l,t,n,a).then(c=>(c&&o.uniforms[a].value!=c&&(o.uniforms[a].value=c,o.uniformsNeedUpdate=!0),c));r.push(u),i.push(a)}}}else for(const o of Object.keys(n)){const a=n[o];if(a?.isTexture===!0){const l=this.assignTextureLODForSlot(a,t,n,o);r.push(l),i.push(o)}}return Promise.all(r).then(o=>{const a=new Array;for(let l=0;l<o.length;l++){const u=o[l],c=i[l];u&&u.isTexture===!0?a.push({material:n,slot:c,texture:u,level:t}):a.push({material:n,slot:c,texture:null,level:t})}return a})}if(e instanceof re||e.isTexture===!0){const n=e;return this.assignTextureLODForSlot(n,t,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(e,t,n,r){return e?.isTexture!==!0?Promise.resolve(null):r==="glyphMap"?Promise.resolve(e):R.getOrLoadLOD(e,t).then(i=>{if(Array.isArray(i))return console.warn("Progressive: Got an array of textures for a texture slot, this should not happen",i),null;if(i?.isTexture===!0){if(i!=e&&n&&r){const o=n[r];if(o&&!y){const a=this.getAssignedLODInformation(o);if(a&&a?.level<t)return y==="verbose"&&console.warn("Assigned texture level is already higher: ",a.level,t,n,o,i),null}n[r]=i}return i}else y=="verbose"&&console.warn("No LOD found for",e,t);return null}).catch(i=>(console.error("Error loading LOD",e,i),null))}afterRoot(e){var t,n;return y&&console.log("AFTER",this.url,e),(t=this.parser.json.textures)==null||t.forEach((r,i)=>{var o;if(r!=null&&r.extensions){const a=r?.extensions[W];if(a){if(!a.lods){y&&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?.textures===i&&(l=!0,R.registerTexture(this.url,u,(o=a.lods)==null?void 0:o.length,i,a))}l||this.parser.getDependency("texture",i).then(u=>{var c;u&&R.registerTexture(this.url,u,(c=a.lods)==null?void 0:c.length,i,a)})}}}),(n=this.parser.json.meshes)==null||n.forEach((r,i)=>{if(r!=null&&r.extensions){const o=r?.extensions[W];if(o&&o.lods){for(const a of this.parser.associations.keys())if(a.isMesh){const l=this.parser.associations.get(a);l?.meshes===i&&R.registerMesh(this.url,o.guid,a,o.lods.length,l.primitives,o)}}}}),null}static async getOrLoadLOD(e,t){var n,r,i,o;const a=y=="verbose",l=this.getAssignedLODInformation(e);if(!l)return y&&console.warn(`[gltf-progressive] No LOD information found: ${e.name}, uuid: ${e.uuid}, type: ${e.type}`,e),null;const u=l?.key;let c;if(e.isTexture===!0){const L=e;L.source&&L.source[Se]&&(c=L.source[Se])}if(c||(c=R.lodInfos.get(u)),c){if(t>0){let f=!1;const k=Array.isArray(c.lods);if(k&&t>=c.lods.length?f=!0:k||(f=!0),f)return this.lowresCache.get(u)}const L=Array.isArray(c.lods)?(n=c.lods[t])==null?void 0:n.path:c.lods;if(!L)return y&&!c["missing:uri"]&&(c["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+t,c)),null;const p=lt(l.url,L);if(p.endsWith(".glb")||p.endsWith(".gltf")){if(!c.guid)return console.warn("missing pointer for glb/gltf texture",c),null;const f=p+"_"+c.guid,k=this.previouslyLoaded.get(f);if(k!==void 0){a&&console.log(`LOD ${t} was already loading/loaded: ${f}`);let h=await k.catch(P=>(console.error(`Error loading LOD ${t} from ${p}
|
|
2
|
-
`,P),null)),S=!1;if(h==null||(h instanceof re&&e instanceof re?(r=h.image)!=null&&r.data||(i=h.source)!=null&&i.data?h=this.copySettings(e,h):(S=!0,this.previouslyLoaded.delete(f)):h instanceof de&&e instanceof de&&((o=h.attributes.position)!=null&&o.array||(S=!0,this.previouslyLoaded.delete(f)))),!S)return h}const I=await this.queue.slot(p);if(!I.use)return y&&console.log(`LOD ${t} was aborted: ${p}`),null;const M=c,v=new Promise(async(h,S)=>{const P=new we;De(P),y&&(await new Promise(m=>setTimeout(m,1e3)),a&&console.warn("Start loading (delayed) "+p,M.guid));let B=p;if(M&&Array.isArray(M.lods)){const m=M.lods[t];m.hash&&(B+="?v="+m.hash)}const b=await P.loadAsync(B).catch(m=>(console.error(`Error loading LOD ${t} from ${p}
|
|
3
|
-
`,m),h(null)));if(!b)return h(null);const $=b.parser;a&&console.log("Loading finished "+p,M.guid);let x=0;if(b.parser.json.textures){let m=!1;for(const g of b.parser.json.textures){if(g!=null&&g.extensions){const D=g?.extensions[W];if(D!=null&&D.guid&&D.guid===M.guid){m=!0;break}}x++}if(m){let g=await $.getDependency("texture",x);return g&&R.assignLODInformation(l.url,g,u,t,void 0),a&&console.log('change "'+e.name+'" \u2192 "'+g.name+'"',p,x,g,f),e instanceof re&&(g=this.copySettings(e,g)),g&&(g.guid=M.guid),h(g)}else y&&console.warn("Could not find texture with guid",M.guid,b.parser.json)}if(x=0,b.parser.json.meshes){let m=!1;for(const g of b.parser.json.meshes){if(g!=null&&g.extensions){const D=g?.extensions[W];if(D!=null&&D.guid&&D.guid===M.guid){m=!0;break}}x++}if(m){const g=await $.getDependency("mesh",x);if(a&&console.log(`Loaded Mesh "${g.name}"`,p,x,g,f),g.isMesh===!0){const D=g.geometry;return R.assignLODInformation(l.url,D,u,t,0),h(D)}else{const D=new Array;for(let O=0;O<g.children.length;O++){const q=g.children[O];if(q.isMesh===!0){const Y=q.geometry;R.assignLODInformation(l.url,Y,u,t,O),D.push(Y)}}return h(D)}}else y&&console.warn("Could not find mesh with guid",M.guid,b.parser.json)}return h(null)});return this.previouslyLoaded.set(f,v),I.use(v),await v}else if(e instanceof re){a&&console.log("Load texture from uri: "+p);const f=await new Ye().loadAsync(p);return f?(f.guid=c.guid,f.flipY=!1,f.needsUpdate=!0,f.colorSpace=e.colorSpace,a&&console.log(c,f)):y&&console.warn("failed loading",p),f}}else y&&console.warn(`Can not load LOD ${t}: no LOD info found for "${u}" ${e.name}`,e.type);return null}static assignLODInformation(e,t,n,r,i){if(!t)return;t.userData||(t.userData={});const o=new mt(e,n,r,i);t.userData.LODS=o,"source"in t&&typeof t.source=="object"&&(t.source.LODS=o)}static getAssignedLODInformation(e){var t,n;return e?(t=e.userData)!=null&&t.LODS?e.userData.LODS:"source"in e&&(n=e.source)!=null&&n.LODS?e.source.LODS:null:null}static copySettings(e,t){return t?(y&&console.warn(`Copy texture settings
|
|
4
|
-
`,e.uuid,`
|
|
5
|
-
`,t.uuid),t=t.clone(),t.offset=e.offset,t.repeat=e.repeat,t.colorSpace=e.colorSpace,t.magFilter=e.magFilter,t.minFilter=e.minFilter,t.wrapS=e.wrapS,t.wrapT=e.wrapT,t.flipY=e.flipY,t.anisotropy=e.anisotropy,t.mipmaps||(t.generateMipmaps=e.generateMipmaps),t):e}};d(T,"registerTexture",(s,e,t,n,r)=>{var i,o,a,l,u,c,L,p;if(!e){y&&console.error("gltf-progressive: Called register texture without texture");return}if(y){const k=((i=e.image)==null?void 0:i.width)||((a=(o=e.source)==null?void 0:o.data)==null?void 0:a.width)||0,I=((l=e.image)==null?void 0:l.height)||((c=(u=e.source)==null?void 0:u.data)==null?void 0:c.height)||0;console.log(`> Progressive: register texture[${n}] "${e.name||e.uuid}", Current: ${k}x${I}, Max: ${(L=r.lods[0])==null?void 0:L.width}x${(p=r.lods[0])==null?void 0:p.height}, uuid: ${e.uuid}`,r,e)}e.source&&(e.source[Se]=r);const f=r.guid;T.assignLODInformation(s,e,f,t,n),T.lodInfos.set(f,r),T.lowresCache.set(f,e)}),d(T,"registerMesh",(s,e,t,n,r,i)=>{var o;const a=t.geometry;if(!a){y&&console.warn("gltf-progressive: Register mesh without geometry");return}a.userData||(a.userData={}),y&&console.log("> Progressive: register mesh "+t.name,{index:r,uuid:t.uuid},i,t),T.assignLODInformation(s,a,e,n,r),T.lodInfos.set(e,i);let l=T.lowresCache.get(e);l?l.push(t.geometry):l=[t.geometry],T.lowresCache.set(e,l),n>0&&!se(t)&&ht(t,a);for(const u of V)(o=u.onRegisteredNewMesh)==null||o.call(u,t,i)}),d(T,"lodInfos",new Map),d(T,"previouslyLoaded",new Map),d(T,"lowresCache",new Map),d(T,"queue",new dt(100,{debug:y!=!1}));let z=T;class mt{constructor(e,t,n,r){d(this,"url"),d(this,"key"),d(this,"level"),d(this,"index"),this.url=e,this.key=t,this.level=n,r!=null&&(this.index=r)}}class fe{constructor(e,t){d(this,"frame_start"),d(this,"frame_capture_end"),d(this,"ready"),d(this,"_resolve"),d(this,"_signal"),d(this,"_resolved",!1),d(this,"_addedCount",0),d(this,"_resolvedCount",0),d(this,"_awaiting",[]),d(this,"_maxPromisesPerObject",1),d(this,"_currentFrame",0),d(this,"_seen",new WeakMap);var n;const r=Math.max(t.frames??2,2);this.frame_start=e,this.frame_capture_end=e+r,this.ready=new Promise(i=>{this._resolve=i}),this.ready.finally(()=>{this._resolved=!0,this._awaiting.length=0}),this._signal=t.signal,(n=this._signal)==null||n.addEventListener("abort",()=>{this.resolveNow()}),this._maxPromisesPerObject=Math.max(1,t.maxPromisesPerObject??1)}get awaitedCount(){return this._addedCount}get resolvedCount(){return this._resolvedCount}get currentlyAwaiting(){return this._awaiting.length}update(e){var t;this._currentFrame=e,((t=this._signal)!=null&&t.aborted||this._currentFrame>this.frame_capture_end&&this._awaiting.length===0)&&this.resolveNow()}add(e,t,n){if(this._resolved){y&&console.warn("PromiseGroup: Trying to add a promise to a resolved group, ignoring.");return}if(!(this._currentFrame>this.frame_capture_end)){if(this._maxPromisesPerObject>=1)if(this._seen.has(t)){let r=this._seen.get(t);if(r>=this._maxPromisesPerObject){y&&console.warn("PromiseGroup: Already awaiting object ignoring new promise for it.");return}this._seen.set(t,r+1)}else this._seen.set(t,1);this._awaiting.push(n),this._addedCount++,n.finally(()=>{this._resolvedCount++,this._awaiting.splice(this._awaiting.indexOf(n),1)})}}resolveNow(){var e,t;this._resolved||(t=this._resolve)==null||t.call(this,{awaited_count:this._addedCount,resolved_count:this._resolvedCount,cancelled:((e=this._signal)==null?void 0:e.aborted)??!1})}}d(fe,"addPromise",(s,e,t,n)=>{n.forEach(r=>{r.add(s,e,t)})});const j=ne("debugprogressive"),pt=ne("noprogressive"),Pe=Symbol("Needle:LODSManager"),Te=Symbol("Needle:LODState"),X=Symbol("Needle:CurrentLOD"),E={mesh_lod:-1,texture_lod:-1};var w,A,K,Ee,H,ie,me,Q;let ae=(w=class{constructor(s,e){d(this,"renderer"),d(this,"context"),d(this,"projectionScreenMatrix",new Ce),d(this,"targetTriangleDensity",2e5),d(this,"skinnedMeshAutoUpdateBoundsInterval",30),d(this,"updateInterval","auto"),Z(this,A,1),d(this,"pause",!1),d(this,"manual",!1),d(this,"_newPromiseGroups",[]),d(this,"_promiseGroupIds",0),d(this,"_lodchangedlisteners",[]),Z(this,K),Z(this,Ee,new Ze),Z(this,H,0),Z(this,ie,0),Z(this,me,0),Z(this,Q,0),d(this,"_fpsBuffer",[60,60,60,60,60]),d(this,"_sphere",new et),d(this,"_tempBox",new ke),d(this,"_tempBox2",new ke),d(this,"tempMatrix",new Ce),d(this,"_tempWorldPosition",new U),d(this,"_tempBoxSize",new U),d(this,"_tempBox2Size",new U),this.renderer=s,this.context={...e}}static getObjectLODState(s){return s[Te]}static addPlugin(s){V.push(s)}static removePlugin(s){const e=V.indexOf(s);e>=0&&V.splice(e,1)}static get(s,e){if(s[Pe])return console.debug("[gltf-progressive] LODsManager already exists for this renderer"),s[Pe];const t=new w(s,{engine:"unknown",...e});return s[Pe]=t,t}get plugins(){return V}awaitLoading(s){const e=this._promiseGroupIds++,t=new fe(_(this,H),{...s});this._newPromiseGroups.push(t);const n=performance.now();return t.ready.finally(()=>{const r=this._newPromiseGroups.indexOf(t);r>=0&&(this._newPromiseGroups.splice(r,1),Ne()&&performance.measure("LODsManager:awaitLoading",{start:n,detail:{id:e,name:s?.name,awaited:t.awaitedCount,resolved:t.resolvedCount}}))}),t.ready}_postprocessPromiseGroups(){if(this._newPromiseGroups.length!==0)for(let s=this._newPromiseGroups.length-1;s>=0;s--)this._newPromiseGroups[s].update(_(this,H))}addEventListener(s,e){s==="changed"&&this._lodchangedlisteners.push(e)}removeEventListener(s,e){if(s==="changed"){const t=this._lodchangedlisteners.indexOf(e);t>=0&&this._lodchangedlisteners.splice(t,1)}}enable(){if(_(this,K))return;console.debug("[gltf-progressive] Enabling LODsManager for renderer");let s=0;F(this,K,this.renderer.render);const e=this;_e(this.renderer),this.renderer.render=function(t,n){const r=e.renderer.getRenderTarget();(r==null||"isXRRenderTarget"in r&&r.isXRRenderTarget)&&(s=0,F(e,H,_(e,H)+1),F(e,ie,_(e,Ee).getDelta()),F(e,me,_(e,me)+_(e,ie)),e._fpsBuffer.shift(),e._fpsBuffer.push(1/_(e,ie)),F(e,Q,e._fpsBuffer.reduce((o,a)=>o+a)/e._fpsBuffer.length),j&&_(e,H)%200===0&&console.log("FPS",Math.round(_(e,Q)),"Interval:",_(e,A)));const i=s++;_(e,K).call(this,t,n),e.onAfterRender(t,n,i)}}disable(){_(this,K)&&(console.debug("[gltf-progressive] Disabling LODsManager for renderer"),this.renderer.render=_(this,K),F(this,K,void 0))}update(s,e){this.internalUpdate(s,e)}onAfterRender(s,e,t){if(this.pause)return;const n=this.renderer.renderLists.get(s,0).opaque;let r=!0;if(n.length===1){const i=n[0].material;(i.name==="EffectMaterial"||i.name==="CopyShader")&&(r=!1)}if((e.parent&&e.parent.type==="CubeCamera"||t>=1&&e.type==="OrthographicCamera")&&(r=!1),r){if(pt||(this.updateInterval==="auto"?_(this,Q)<40&&_(this,A)<10?(F(this,A,_(this,A)+1),j&&console.warn("\u2193 Reducing LOD updates",_(this,A),_(this,Q).toFixed(0))):_(this,Q)>=60&&_(this,A)>1&&(F(this,A,_(this,A)-1),j&&console.warn("\u2191 Increasing LOD updates",_(this,A),_(this,Q).toFixed(0))):F(this,A,this.updateInterval),_(this,A)>0&&_(this,H)%_(this,A)!=0))return;this.internalUpdate(s,e),this._postprocessPromiseGroups()}}internalUpdate(s,e){var t,n;const r=this.renderer.renderLists.get(s,0),i=r.opaque;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse);const o=this.targetTriangleDensity;for(const u of i){if(u.material&&(((t=u.geometry)==null?void 0:t.type)==="BoxGeometry"||((n=u.geometry)==null?void 0:n.type)==="BufferGeometry")&&(u.material.name==="SphericalGaussianBlur"||u.material.name=="BackgroundCubeMaterial"||u.material.name==="CubemapFromEquirect"||u.material.name==="EquirectangularToCubeUV")){j&&(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}if(j==="color"&&u.material&&!u.object.progressive_debug_color){u.object.progressive_debug_color=!0;const L=Math.random()*16777215,p=new Je({color:L});u.object.material=p}const c=u.object;(c instanceof J||c.isMesh)&&this.updateLODs(s,e,c,o)}const a=r.transparent;for(const u of a){const c=u.object;(c instanceof J||c.isMesh)&&this.updateLODs(s,e,c,o)}const l=r.transmissive;for(const u of l){const c=u.object;(c instanceof J||c.isMesh)&&this.updateLODs(s,e,c,o)}}updateLODs(s,e,t,n){var r,i;t.userData||(t.userData={});let o=t[Te];if(o||(o=new vt,t[Te]=o),o.frames++<2)return;for(const l of V)(r=l.onBeforeUpdateLOD)==null||r.call(l,this.renderer,s,e,t);const a=w.overrideGlobalLodLevel!==void 0?w.overrideGlobalLodLevel:ee;a>=0?(E.mesh_lod=a,E.texture_lod=a):(this.calculateLodLevel(e,t,o,n,E),E.mesh_lod=Math.round(E.mesh_lod),E.texture_lod=Math.round(E.texture_lod)),E.mesh_lod>=0&&this.loadProgressiveMeshes(t,E.mesh_lod),t.material&&E.texture_lod>=0&&this.loadProgressiveTextures(t.material,E.texture_lod),y&&t.material&&!t.isGizmo&&Fe(t.material);for(const l of V)(i=l.onAfterUpdatedLOD)==null||i.call(l,this.renderer,s,e,t,E);o.lastLodLevel_Mesh=E.mesh_lod,o.lastLodLevel_Texture=E.texture_lod}loadProgressiveTextures(s,e){if(!s)return;if(Array.isArray(s)){for(const r of s)this.loadProgressiveTextures(r,e);return}let t=!1;(s[X]===void 0||e<s[X])&&(t=!0);const n=s["DEBUG:LOD"];if(n!=null&&(t=s[X]!=n,e=n),t){s[X]=e;const r=z.assignTextureLOD(s,e).then(i=>{this._lodchangedlisteners.forEach(o=>o({type:"texture",level:e,object:s}))});fe.addPromise("texture",s,r,this._newPromiseGroups)}}loadProgressiveMeshes(s,e){if(!s)return Promise.resolve(null);let t=s[X]!==e;const n=s["DEBUG:LOD"];if(n!=null&&(t=s[X]!=n,e=n),t){s[X]=e;const r=s.geometry,i=z.assignMeshLOD(s,e).then(o=>(o&&s[X]==e&&r!=s.geometry&&this._lodchangedlisteners.forEach(a=>a({type:"mesh",level:e,object:s})),o));return fe.addPromise("mesh",s,i,this._newPromiseGroups),i}return Promise.resolve(null)}static isInside(s,e){const t=s.min,n=s.max,r=(t.x+n.x)*.5,i=(t.y+n.y)*.5;return this._tempPtInside.set(r,i,t.z).applyMatrix4(e).z<0}calculateLodLevel(s,e,t,n,r){var i,o,a;if(!e){r.mesh_lod=-1,r.texture_lod=-1;return}if(!s){r.mesh_lod=-1,r.texture_lod=-1;return}let l=10+1,u=!1;if(j&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const c=(i=z.getMeshLODExtension(e.geometry))==null?void 0:i.lods,L=z.getPrimitiveIndex(e.geometry),p=c&&c.length>0,f=z.getMaterialMinMaxLODsCount(e.material),k=f?.min_count!=1/0&&f.min_count>0&&f.max_count>0;if(!p&&!k){r.mesh_lod=0,r.texture_lod=0;return}p||(u=!0,l=0);const I=this.renderer.domElement.clientHeight||this.renderer.domElement.height;let M=e.geometry.boundingBox;if(e.type==="SkinnedMesh"){const v=e;if(!v.boundingBox)v.computeBoundingBox();else if(this.skinnedMeshAutoUpdateBoundsInterval>0){if(!v[w.$skinnedMeshBoundsOffset]){const S=w.skinnedMeshBoundsFrameOffsetCounter++;v[w.$skinnedMeshBoundsOffset]=S}const h=v[w.$skinnedMeshBoundsOffset];if((t.frames+h)%this.skinnedMeshAutoUpdateBoundsInterval===0){const S=se(v),P=v.geometry;S&&(v.geometry=S),v.computeBoundingBox(),v.geometry=P}}M=v.boundingBox}if(M){const v=s;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=s.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(x)){r.mesh_lod=0,r.texture_lod=0;return}}if(this._tempBox.copy(M),this._tempBox.applyMatrix4(e.matrixWorld),v.isPerspectiveCamera&&w.isInside(this._tempBox,this.projectionScreenMatrix)){r.mesh_lod=0,r.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&v.isPerspectiveCamera&&v.fov>70){const x=this._tempBox.min,m=this._tempBox.max;let g=x.x,D=x.y,O=m.x,q=m.y;const Y=2,xe=1.5,le=(x.x+m.x)*.5,ue=(x.y+m.y)*.5;g=(g-le)*Y+le,D=(D-ue)*Y+ue,O=(O-le)*Y+le,q=(q-ue)*Y+ue;const Xe=g<0&&O>0?0:Math.min(Math.abs(x.x),Math.abs(m.x)),Ke=D<0&&q>0?0:Math.min(Math.abs(x.y),Math.abs(m.y)),ye=Math.max(Xe,Ke);t.lastCentrality=(xe-ye)*(xe-ye)*(xe-ye)}else t.lastCentrality=1;const h=this._tempBox.getSize(this._tempBoxSize);h.multiplyScalar(.5),screen.availHeight>0&&I>0&&h.multiplyScalar(I/screen.availHeight),s.isPerspectiveCamera?h.x*=s.aspect:s.isOrthographicCamera;const S=s.matrixWorldInverse,P=this._tempBox2;P.copy(M),P.applyMatrix4(e.matrixWorld),P.applyMatrix4(S);const B=P.getSize(this._tempBox2Size),b=Math.max(B.x,B.y);if(Math.max(h.x,h.y)!=0&&b!=0&&(h.z=B.z/Math.max(B.x,B.y)*Math.max(h.x,h.y)),t.lastScreenCoverage=Math.max(h.x,h.y,h.z),t.lastScreenspaceVolume.copy(h),t.lastScreenCoverage*=t.lastCentrality,j&&w.debugDrawLine){const x=this.tempMatrix.copy(this.projectionScreenMatrix);x.invert();const m=w.corner0,g=w.corner1,D=w.corner2,O=w.corner3;m.copy(this._tempBox.min),g.copy(this._tempBox.max),g.x=m.x,D.copy(this._tempBox.max),D.y=m.y,O.copy(this._tempBox.max);const q=(m.z+O.z)*.5;m.z=g.z=D.z=O.z=q,m.applyMatrix4(x),g.applyMatrix4(x),D.applyMatrix4(x),O.applyMatrix4(x),w.debugDrawLine(m,g,255),w.debugDrawLine(m,D,255),w.debugDrawLine(g,O,255),w.debugDrawLine(D,O,255)}let $=999;if(c&&t.lastScreenCoverage>0)for(let x=0;x<c.length;x++){const m=c[x],g=(((o=m.densities)==null?void 0:o[L])||m.density||1e-5)/t.lastScreenCoverage;if(L>0&&Ne()&&!m.densities&&!globalThis["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"]&&(window["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"]=!0,console.warn("[Needle Progressive] Detected usage of mesh without primitive densities. This might cause incorrect LOD level selection: Consider re-optimizing your model by updating your Needle Integration, Needle glTF Pipeline or running optimization again on Needle Cloud.")),g<n){$=x;break}}$<l&&(l=$,u=!0)}if(u?r.mesh_lod=l:r.mesh_lod=t.lastLodLevel_Mesh,j&&r.mesh_lod!=t.lastLodLevel_Mesh){const v=c?.[r.mesh_lod];v&&console.log(`Mesh LOD changed: ${t.lastLodLevel_Mesh} \u2192 ${r.mesh_lod} (${v.density.toFixed(0)}) - ${e.name}`)}if(k){const v="saveData"in globalThis.navigator&&globalThis.navigator.saveData===!0;if(t.lastLodLevel_Texture<0){if(r.texture_lod=f.max_count-1,j){const h=f.lods[f.max_count-1];j&&console.log(`First Texture LOD ${r.texture_lod} (${h.max_height}px) - ${e.name}`)}}else{const h=t.lastScreenspaceVolume.x+t.lastScreenspaceVolume.y+t.lastScreenspaceVolume.z;let S=t.lastScreenCoverage*4;((a=this.context)==null?void 0:a.engine)==="model-viewer"&&(S*=1.5);const P=I/window.devicePixelRatio*S;let B=!1;for(let b=f.lods.length-1;b>=0;b--){const $=f.lods[b];if(!(v&&$.max_height>=2048)&&!(ut()&&$.max_height>4096)&&($.max_height>P||!B&&b===0)){if(B=!0,r.texture_lod=b,r.texture_lod<t.lastLodLevel_Texture){const x=$.max_height;j&&console.log(`Texture LOD changed: ${t.lastLodLevel_Texture} \u2192 ${r.texture_lod} = ${x}px
|
|
6
|
-
Screensize: ${P.toFixed(0)}px, Coverage: ${(100*t.lastScreenCoverage).toFixed(2)}%, Volume ${h.toFixed(1)}
|
|
7
|
-
${e.name}`)}break}}}}else r.texture_lod=0}},A=new WeakMap,K=new WeakMap,Ee=new WeakMap,H=new WeakMap,ie=new WeakMap,me=new WeakMap,Q=new WeakMap,d(w,"debugDrawLine"),d(w,"overrideGlobalLodLevel"),d(w,"corner0",new U),d(w,"corner1",new U),d(w,"corner2",new U),d(w,"corner3",new U),d(w,"_tempPtInside",new U),d(w,"skinnedMeshBoundsFrameOffsetCounter",0),d(w,"$skinnedMeshBoundsOffset",Symbol("gltf-progressive-skinnedMeshBoundsOffset")),w);class vt{constructor(){d(this,"frames",0),d(this,"lastLodLevel_Mesh",-1),d(this,"lastLodLevel_Texture",-1),d(this,"lastScreenCoverage",0),d(this,"lastScreenspaceVolume",new U),d(this,"lastCentrality",0)}}const Ue=Symbol("NEEDLE_mesh_lod"),pe=Symbol("NEEDLE_texture_lod");let ve=null;function We(){const s=xt();s&&(s.mapURLs(function(e){return ze(),e}),ze(),ve?.disconnect(),ve=new MutationObserver(e=>{e.forEach(t=>{t.addedNodes.forEach(n=>{n instanceof HTMLElement&&n.tagName.toLowerCase()==="model-viewer"&&Ve(n)})})}),ve.observe(document,{childList:!0,subtree:!0}))}function xt(){return typeof customElements>"u"?null:customElements.get("model-viewer")||(customElements.whenDefined("model-viewer").then(()=>{console.debug("[gltf-progressive] model-viewer defined"),We()}),null)}function ze(){typeof document>"u"||document.querySelectorAll("model-viewer").forEach(s=>{Ve(s)})}const qe=new WeakSet;let yt=0;function Ve(s){if(!s||qe.has(s))return null;qe.add(s),console.debug("[gltf-progressive] found new model-viewer..."+ ++yt+`
|
|
8
|
-
`,s.getAttribute("src"));let e=null,t=null,n=null;for(let r=s;r!=null;r=Object.getPrototypeOf(r)){const i=Object.getOwnPropertySymbols(r),o=i.find(u=>u.toString()=="Symbol(renderer)"),a=i.find(u=>u.toString()=="Symbol(scene)"),l=i.find(u=>u.toString()=="Symbol(needsRender)");!e&&o!=null&&(e=s[o].threeRenderer),!t&&a!=null&&(t=s[a]),!n&&l!=null&&(n=s[l])}if(e&&t){let r=function(){if(n){let o=0,a=setInterval(()=>{if(o++>5){clearInterval(a);return}n?.call(s)},300)}};console.debug("[gltf-progressive] setup model-viewer");const i=ae.get(e,{engine:"model-viewer"});return ae.addPlugin(new wt),i.enable(),i.addEventListener("changed",()=>{n?.call(s)}),s.addEventListener("model-visibility",o=>{o.detail.visible&&n?.call(s)}),s.addEventListener("load",()=>{r()}),()=>{i.disable()}}return null}class wt{constructor(){d(this,"_didWarnAboutMissingUrl",!1)}onBeforeUpdateLOD(e,t,n,r){this.tryParseMeshLOD(t,r),this.tryParseTextureLOD(t,r)}getUrl(e){if(!e)return null;let t=e.getAttribute("src");return t||(t=e.src),t||(this._didWarnAboutMissingUrl||console.warn("No url found in modelviewer",e),this._didWarnAboutMissingUrl=!0),t}tryGetCurrentGLTF(e){return e._currentGLTF}tryGetCurrentModelViewer(e){return e.element}tryParseTextureLOD(e,t){if(t[pe]==!0)return;t[pe]=!0;const n=this.tryGetCurrentGLTF(e),r=this.tryGetCurrentModelViewer(e),i=this.getUrl(r);if(i&&n&&t.material){let o=function(l){var u,c,L;if(l[pe]==!0)return;l[pe]=!0,l.userData&&(l.userData.LOD=-1);const p=Object.keys(l);for(let f=0;f<p.length;f++){const k=p[f],I=l[k];if(I?.isTexture===!0){const M=(c=(u=I.userData)==null?void 0:u.associations)==null?void 0:c.textures;if(M==null)continue;const v=n.parser.json.textures[M];if(!v){console.warn("Texture data not found for texture index "+M);continue}if((L=v?.extensions)!=null&&L[W]){const h=v.extensions[W];h&&i&&z.registerTexture(i,I,h.lods.length,M,h)}}}};const a=t.material;if(Array.isArray(a))for(const l of a)o(l);else o(a)}}tryParseMeshLOD(e,t){var n,r;if(t[Ue]==!0)return;t[Ue]=!0;const i=this.tryGetCurrentModelViewer(e),o=this.getUrl(i);if(!o)return;const a=(r=(n=t.userData)==null?void 0:n.gltfExtensions)==null?void 0:r[W];if(a&&o){const l=t.uuid;z.registerMesh(o,l,t,0,a.lods.length,a)}}}function Lt(s,e,t,n){_e(e),De(t),be(t,{progressive:!0,...n?.hints}),t.register(i=>new z(i,s));const r=ae.get(e);return n?.enableLODsManager!==!1&&r.enable(),r}if(We(),!ct){const s={gltfProgressive:{useNeedleProgressive:Lt,LODsManager:ae,configureLoader:be,getRaycastMesh:se,useRaycastMeshes:gt}};if(!globalThis.Needle)globalThis.Needle=s;else for(const e in s)globalThis.Needle[e]=s[e]}export{ae as LODsManager,z as NEEDLE_progressive,De as addDracoAndKTX2Loaders,be as configureLoader,_e as createLoaders,se as getRaycastMesh,$e as setDracoDecoderLocation,Ge as setKTX2TranscoderLocation};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
"use strict";var Ke=Object.defineProperty;var Ee=o=>{throw TypeError(o)};var Ye=(o,t,e)=>t in o?Ke(o,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):o[t]=e;var u=(o,t,e)=>Ye(o,typeof t!="symbol"?t+"":t,e),$e=(o,t,e)=>t.has(o)||Ee("Cannot "+e);var w=(o,t,e)=>($e(o,t,"read from private field"),e?e.call(o):t.get(o)),Y=(o,t,e)=>t.has(o)?Ee("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(o):t.set(o,e),z=(o,t,e,s)=>($e(o,t,"write to private field"),s?s.call(o,e):t.set(o,e),e);const y=require("./three-B_hneGZr.umd.cjs"),te=require("./three-examples-DUcCNw9s.umd.cjs"),He="";globalThis.GLTF_PROGRESSIVE_VERSION=He;console.debug("[gltf-progressive] version -");let q="https://www.gstatic.com/draco/versioned/decoders/1.5.7/",se="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";const Qe=q,je=se,Re=new URL(q+"draco_decoder.js");Re.searchParams.append("range","true");fetch(Re,{method:"GET",headers:{Range:"bytes=0-1"}}).catch(o=>{console.debug(`Failed to fetch remote Draco decoder from ${q} (offline: ${typeof navigator<"u"?navigator.onLine:"unknown"})`),q===Qe&&Fe("./include/draco/"),se===je&&Ne("./include/ktx2/")}).finally(()=>{Ue()});function Fe(o){q=o,B&&B[be]!=q?(console.debug("Updating Draco decoder path to "+o),B[be]=q,B.setDecoderPath(q),B.preload()):console.debug("Setting Draco decoder path to "+o)}function Ne(o){se=o,N&&N.transcoderPath!=se?(console.debug("Updating KTX2 transcoder path to "+o),N.setTranscoderPath(se),N.init()):console.debug("Setting KTX2 transcoder path to "+o)}const be=Symbol("dracoDecoderPath");let B,ye,N;function Ue(){B||(B=new te.DRACOLoader,B[be]=q,B.setDecoderPath(q),B.setDecoderConfig({type:"js"}),B.preload()),N||(N=new te.KTX2Loader,N.setTranscoderPath(se),N.init()),ye||(ye=te.MeshoptDecoder)}function Te(o){return Ue(),o?N.detectSupport(o):o!==null&&console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"),{dracoLoader:B,ktx2Loader:N,meshoptDecoder:ye}}function Ae(o){o.dracoLoader||o.setDRACOLoader(B),o.ktx2Loader||o.setKTX2Loader(N),o.meshoptDecoder||o.setMeshoptDecoder(ye)}const Se=new WeakMap;function Ce(o,t){let e=Se.get(o);e?e=Object.assign(e,t):e=t,Se.set(o,e)}const Me=te.GLTFLoader.prototype.load;function Je(...o){const t=Se.get(this);let e=o[0];const s=new URL(e,window.location.href);if(s.hostname.endsWith("needle.tools")){const r=(t==null?void 0:t.progressive)!==void 0?t.progressive:!0,i=t!=null&&t.usecase?t.usecase:"default";r?this.requestHeader.Accept=`*/*;progressive=allowed;usecase=${i}`:this.requestHeader.Accept=`*/*;usecase=${i}`,e=s.toString()}return o[0]=e,Me==null?void 0:Me.call(this,...o)}te.GLTFLoader.prototype.load=Je;de("debugprogressive");function de(o){if(typeof window>"u")return!1;const e=new URL(window.location.href).searchParams.get(o);return e==null||e==="0"||e==="false"?!1:e===""?!0:e}function Ze(o,t){if(t===void 0||t.startsWith("./")||t.startsWith("http")||o===void 0)return t;const e=o.lastIndexOf("/");if(e>=0){const s=o.substring(0,e+1);for(;s.endsWith("/")&&t.startsWith("/");)t=t.substring(1);return s+t}return t}let oe;function et(){return oe!==void 0||(oe=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),de("debugprogressive")&&console.log("[glTF Progressive]: isMobileDevice",oe)),oe}function Ie(){if(typeof window>"u")return!1;const o=new URL(window.location.href),t=o.hostname==="localhost"||/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(o.hostname);return o.hostname==="127.0.0.1"||t}class tt{constructor(t=100,e={}){u(this,"_running",new Map);u(this,"_queue",[]);u(this,"debug",!1);u(this,"tick",()=>{this.internalUpdate(),setTimeout(this.tick,10)});this.maxConcurrent=t,this.debug=e.debug??!1,window.requestAnimationFrame(this.tick)}slot(t){return this.debug&&console.debug(`[PromiseQueue]: Requesting slot for key ${t}, running: ${this._running.size}, waiting: ${this._queue.length}`),new Promise(e=>{this._queue.push({key:t,resolve:e})})}add(t,e){this._running.has(t)||(this._running.set(t,e),e.finally(()=>{this._running.delete(t),this.debug&&console.debug(`[PromiseQueue]: Promise finished now running: ${this._running.size}, waiting: ${this._queue.length}. (finished ${t})`)}),this.debug&&console.debug(`[PromiseQueue]: Added new promise, now running: ${this._running.size}, waiting: ${this._queue.length}. (added ${t})`))}internalUpdate(){const t=this.maxConcurrent-this._running.size;for(let e=0;e<t&&this._queue.length>0;e++){this.debug&&console.debug(`[PromiseQueue]: Running ${this._running.size} promises, waiting for ${this._queue.length} more.`);const{key:s,resolve:n}=this._queue.shift();n({use:r=>this.add(s,r)})}}}const st=typeof window>"u"&&typeof document>"u",Pe=Symbol("needle:raycast-mesh");function ie(o){return(o==null?void 0:o[Pe])instanceof y.BufferGeometry?o[Pe]:null}function rt(o,t){if((o.type==="Mesh"||o.type==="SkinnedMesh")&&!ie(o)){const s=nt(t);s.userData={isRaycastMesh:!0},o[Pe]=s}}function it(o=!0){if(o){if(ae)return;const t=ae=y.Mesh.prototype.raycast;y.Mesh.prototype.raycast=function(e,s){const n=this,r=ie(n);let i;r&&n.isMesh&&(i=n.geometry,n.geometry=r),t.call(this,e,s),i&&(n.geometry=i)}}else{if(!ae)return;y.Mesh.prototype.raycast=ae,ae=null}}let ae=null;function nt(o){const t=new y.BufferGeometry;for(const e in o.attributes)t.setAttribute(e,o.getAttribute(e));return t.setIndex(o.getIndex()),t}const Q=new Array,x=de("debugprogressive");let pe,ee=-1;if(x){let o=function(){ee+=1,ee>=t&&(ee=-1),console.log(`Toggle LOD level [${ee}]`)},t=6;window.addEventListener("keyup",e=>{e.key==="p"&&o(),e.key==="w"&&(pe=!pe,console.log(`Toggle wireframe [${pe}]`));const s=parseInt(e.key);!isNaN(s)&&s>=0&&(ee=s,console.log(`Set LOD level to [${ee}]`))})}function Ve(o){if(x)if(Array.isArray(o))for(const t of o)Ve(t);else o&&"wireframe"in o&&(o.wireframe=pe===!0)}const W="NEEDLE_progressive",De=Symbol("needle-progressive-texture"),M=class M{constructor(t,e){u(this,"parser");u(this,"url");u(this,"_isLoadingMesh");u(this,"loadMesh",t=>{var s,n;if(this._isLoadingMesh)return null;const e=(n=(s=this.parser.json.meshes[t])==null?void 0:s.extensions)==null?void 0:n[W];return e?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",t).then(r=>{var i;return this._isLoadingMesh=!1,r&&M.registerMesh(this.url,e.guid,r,(i=e.lods)==null?void 0:i.length,0,e),r})):null});x&&console.log("Progressive extension registered for",e),this.parser=t,this.url=e}get name(){return W}static getMeshLODExtension(t){const e=this.getAssignedLODInformation(t);return e!=null&&e.key?this.lodInfos.get(e.key):null}static getPrimitiveIndex(t){var s;const e=(s=this.getAssignedLODInformation(t))==null?void 0:s.index;return e??-1}static getMaterialMinMaxLODsCount(t,e){const s=this,n="LODS:minmax",r=t[n];if(r!=null)return r;if(e||(e={min_count:1/0,max_count:0,lods:[]}),Array.isArray(t)){for(const a of t)this.getMaterialMinMaxLODsCount(a,e);return t[n]=e,e}if(x==="verbose"&&console.log("getMaterialMinMaxLODsCount",t),t.type==="ShaderMaterial"||t.type==="RawShaderMaterial"){const a=t;for(const l of Object.keys(a.uniforms)){const c=a.uniforms[l].value;(c==null?void 0:c.isTexture)===!0&&i(c,e)}}else if(t.isMaterial)for(const a of Object.keys(t)){const l=t[a];(l==null?void 0:l.isTexture)===!0&&i(l,e)}return t[n]=e,e;function i(a,l){const c=s.getAssignedLODInformation(a);if(c){const d=s.lodInfos.get(c.key);if(d&&d.lods){l.min_count=Math.min(l.min_count,d.lods.length),l.max_count=Math.max(l.max_count,d.lods.length);for(let h=0;h<d.lods.length;h++){const f=d.lods[h];f.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,f.height),l.lods[h].max_height=Math.max(l.lods[h].max_height,f.height))}}}}}static hasLODLevelAvailable(t,e){var r;if(Array.isArray(t)){for(const i of t)if(this.hasLODLevelAvailable(i,e))return!0;return!1}if(t.isMaterial===!0){for(const i of Object.keys(t)){const a=t[i];if(a&&a.isTexture&&this.hasLODLevelAvailable(a,e))return!0}return!1}else if(t.isGroup===!0){for(const i of t.children)if(i.isMesh===!0&&this.hasLODLevelAvailable(i,e))return!0}let s,n;if(t.isMesh?s=t.geometry:(t.isBufferGeometry||t.isTexture)&&(s=t),s&&(r=s==null?void 0:s.userData)!=null&&r.LODS){const i=s.userData.LODS;if(n=this.lodInfos.get(i.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 s;if(!t)return Promise.resolve(null);if(t instanceof y.Mesh||t.isMesh===!0){const n=t.geometry,r=this.getAssignedLODInformation(n);if(!r)return Promise.resolve(null);for(const i of Q)(s=i.onBeforeGetLODMesh)==null||s.call(i,t,e);return t["LOD:requested level"]=e,M.getOrLoadLOD(n,e).then(i=>{if(Array.isArray(i)){const a=r.index||0;i=i[a]}return t["LOD:requested level"]===e&&(delete t["LOD:requested level"],i&&n!=i&&((i==null?void 0:i.isBufferGeometry)?t.geometry=i:x&&console.error("Invalid LOD geometry",i))),i}).catch(i=>(console.error("Error loading mesh LOD",t,i),null))}else x&&console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh",t);return Promise.resolve(null)}static assignTextureLOD(t,e=0){if(!t)return Promise.resolve(null);if(t.isMesh===!0){const s=t;if(Array.isArray(s.material)){const n=new Array;for(const r of s.material){const i=this.assignTextureLOD(r,e);n.push(i)}return Promise.all(n).then(r=>{const i=new Array;for(const a of r)Array.isArray(a)&&i.push(...a);return i})}else return this.assignTextureLOD(s.material,e)}if(t.isMaterial===!0){const s=t,n=[],r=new Array;if(s.uniforms&&(s.isRawShaderMaterial||s.isShaderMaterial===!0)){const i=s;for(const a of Object.keys(i.uniforms)){const l=i.uniforms[a].value;if((l==null?void 0:l.isTexture)===!0){const c=this.assignTextureLODForSlot(l,e,s,a).then(d=>(d&&i.uniforms[a].value!=d&&(i.uniforms[a].value=d,i.uniformsNeedUpdate=!0),d));n.push(c),r.push(a)}}}else for(const i of Object.keys(s)){const a=s[i];if((a==null?void 0:a.isTexture)===!0){const l=this.assignTextureLODForSlot(a,e,s,i);n.push(l),r.push(i)}}return Promise.all(n).then(i=>{const a=new Array;for(let l=0;l<i.length;l++){const c=i[l],d=r[l];c&&c.isTexture===!0?a.push({material:s,slot:d,texture:c,level:e}):a.push({material:s,slot:d,texture:null,level:e})}return a})}if(t instanceof y.Texture||t.isTexture===!0){const s=t;return this.assignTextureLODForSlot(s,e,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(t,e,s,n){return(t==null?void 0:t.isTexture)!==!0?Promise.resolve(null):n==="glyphMap"?Promise.resolve(t):M.getOrLoadLOD(t,e).then(r=>{if(Array.isArray(r))return console.warn("Progressive: Got an array of textures for a texture slot, this should not happen",r),null;if((r==null?void 0:r.isTexture)===!0){if(r!=t&&s&&n){const i=s[n];if(i&&!x){const a=this.getAssignedLODInformation(i);if(a&&(a==null?void 0:a.level)<e)return x==="verbose"&&console.warn("Assigned texture level is already higher: ",a.level,e,s,i,r),null}s[n]=r}return r}else x=="verbose"&&console.warn("No LOD found for",t,e);return null}).catch(r=>(console.error("Error loading LOD",t,r),null))}afterRoot(t){var e,s;return x&&console.log("AFTER",this.url,t),(e=this.parser.json.textures)==null||e.forEach((n,r)=>{var i;if(n!=null&&n.extensions){const a=n==null?void 0:n.extensions[W];if(a){if(!a.lods){x&&console.warn("Texture has no LODs",a);return}let l=!1;for(const c of this.parser.associations.keys())if(c.isTexture===!0){const d=this.parser.associations.get(c);(d==null?void 0:d.textures)===r&&(l=!0,M.registerTexture(this.url,c,(i=a.lods)==null?void 0:i.length,r,a))}l||this.parser.getDependency("texture",r).then(c=>{var d;c&&M.registerTexture(this.url,c,(d=a.lods)==null?void 0:d.length,r,a)})}}}),(s=this.parser.json.meshes)==null||s.forEach((n,r)=>{if(n!=null&&n.extensions){const i=n==null?void 0:n.extensions[W];if(i&&i.lods){for(const a of this.parser.associations.keys())if(a.isMesh){const l=this.parser.associations.get(a);(l==null?void 0:l.meshes)===r&&M.registerMesh(this.url,i.guid,a,i.lods.length,l.primitives,i)}}}}),null}static async getOrLoadLOD(t,e){var a,l,c,d;const s=x=="verbose",n=this.getAssignedLODInformation(t);if(!n)return x&&console.warn(`[gltf-progressive] No LOD information found: ${t.name}, uuid: ${t.uuid}, type: ${t.type}`,t),null;const r=n==null?void 0:n.key;let i;if(t.isTexture===!0){const h=t;h.source&&h.source[De]&&(i=h.source[De])}if(i||(i=M.lodInfos.get(r)),i){if(e>0){let D=!1;const O=Array.isArray(i.lods);if(O&&e>=i.lods.length?D=!0:O||(D=!0),D)return this.lowresCache.get(r)}const h=Array.isArray(i.lods)?(a=i.lods[e])==null?void 0:a.path:i.lods;if(!h)return x&&!i["missing:uri"]&&(i["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+e,i)),null;const f=Ze(n.url,h);if(f.endsWith(".glb")||f.endsWith(".gltf")){if(!i.guid)return console.warn("missing pointer for glb/gltf texture",i),null;const D=f+"_"+i.guid,O=this.previouslyLoaded.get(D);if(O!==void 0){s&&console.log(`LOD ${e} was already loading/loaded: ${D}`);let g=await O.catch(C=>(console.error(`Error loading LOD ${e} from ${f}
|
|
2
|
-
`,C),null)),_=!1;if(g==null||(g instanceof y.Texture&&t instanceof y.Texture?(l=g.image)!=null&&l.data||(c=g.source)!=null&&c.data?g=this.copySettings(t,g):(_=!0,this.previouslyLoaded.delete(D)):g instanceof y.BufferGeometry&&t instanceof y.BufferGeometry&&((d=g.attributes.position)!=null&&d.array||(_=!0,this.previouslyLoaded.delete(D)))),!_)return g}const T=await this.queue.slot(f);if(!T.use)return x&&console.log(`LOD ${e} was aborted: ${f}`),null;const S=i,k=new Promise(async(g,_)=>{const C=new te.GLTFLoader;Ae(C),x&&(await new Promise(b=>setTimeout(b,1e3)),s&&console.warn("Start loading (delayed) "+f,S.guid));let U=f;if(S&&Array.isArray(S.lods)){const b=S.lods[e];b.hash&&(U+="?v="+b.hash)}const P=await C.loadAsync(U).catch(b=>(console.error(`Error loading LOD ${e} from ${f}
|
|
3
|
-
`,b),g(null)));if(!P)return g(null);const Z=P.parser;s&&console.log("Loading finished "+f,S.guid);let E=0;if(P.parser.json.textures){let b=!1;for(const m of P.parser.json.textures){if(m!=null&&m.extensions){const p=m==null?void 0:m.extensions[W];if(p!=null&&p.guid&&p.guid===S.guid){b=!0;break}}E++}if(b){let m=await Z.getDependency("texture",E);return m&&M.assignLODInformation(n.url,m,r,e,void 0),s&&console.log('change "'+t.name+'" → "'+m.name+'"',f,E,m,D),t instanceof y.Texture&&(m=this.copySettings(t,m)),m&&(m.guid=S.guid),g(m)}else x&&console.warn("Could not find texture with guid",S.guid,P.parser.json)}if(E=0,P.parser.json.meshes){let b=!1;for(const m of P.parser.json.meshes){if(m!=null&&m.extensions){const p=m==null?void 0:m.extensions[W];if(p!=null&&p.guid&&p.guid===S.guid){b=!0;break}}E++}if(b){const m=await Z.getDependency("mesh",E);if(s&&console.log(`Loaded Mesh "${m.name}"`,f,E,m,D),m.isMesh===!0){const p=m.geometry;return M.assignLODInformation(n.url,p,r,e,0),g(p)}else{const p=new Array;for(let v=0;v<m.children.length;v++){const $=m.children[v];if($.isMesh===!0){const A=$.geometry;M.assignLODInformation(n.url,A,r,e,v),p.push(A)}}return g(p)}}else x&&console.warn("Could not find mesh with guid",S.guid,P.parser.json)}return g(null)});return this.previouslyLoaded.set(D,k),T.use(k),await k}else if(t instanceof y.Texture){s&&console.log("Load texture from uri: "+f);const O=await new y.TextureLoader().loadAsync(f);return O?(O.guid=i.guid,O.flipY=!1,O.needsUpdate=!0,O.colorSpace=t.colorSpace,s&&console.log(i,O)):x&&console.warn("failed loading",f),O}}else x&&console.warn(`Can not load LOD ${e}: no LOD info found for "${r}" ${t.name}`,t.type);return null}static assignLODInformation(t,e,s,n,r){if(!e)return;e.userData||(e.userData={});const i=new ot(t,s,n,r);e.userData.LODS=i,"source"in e&&typeof e.source=="object"&&(e.source.LODS=i)}static getAssignedLODInformation(t){var e,s;return t?(e=t.userData)!=null&&e.LODS?t.userData.LODS:"source"in t&&((s=t.source)!=null&&s.LODS)?t.source.LODS:null:null}static copySettings(t,e){return e?(x&&console.warn(`Copy texture settings
|
|
4
|
-
`,t.uuid,`
|
|
5
|
-
`,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}};u(M,"registerTexture",(t,e,s,n,r)=>{var a,l,c,d,h,f,D,O;if(!e){x&&console.error("gltf-progressive: Called register texture without texture");return}if(x){const T=((a=e.image)==null?void 0:a.width)||((c=(l=e.source)==null?void 0:l.data)==null?void 0:c.width)||0,S=((d=e.image)==null?void 0:d.height)||((f=(h=e.source)==null?void 0:h.data)==null?void 0:f.height)||0;console.log(`> Progressive: register texture[${n}] "${e.name||e.uuid}", Current: ${T}x${S}, Max: ${(D=r.lods[0])==null?void 0:D.width}x${(O=r.lods[0])==null?void 0:O.height}, uuid: ${e.uuid}`,r,e)}e.source&&(e.source[De]=r);const i=r.guid;M.assignLODInformation(t,e,i,s,n),M.lodInfos.set(i,r),M.lowresCache.set(i,e)}),u(M,"registerMesh",(t,e,s,n,r,i)=>{var c;const a=s.geometry;if(!a){x&&console.warn("gltf-progressive: Register mesh without geometry");return}a.userData||(a.userData={}),x&&console.log("> Progressive: register mesh "+s.name,{index:r,uuid:s.uuid},i,s),M.assignLODInformation(t,a,e,n,r),M.lodInfos.set(e,i);let l=M.lowresCache.get(e);l?l.push(s.geometry):l=[s.geometry],M.lowresCache.set(e,l),n>0&&!ie(s)&&rt(s,a);for(const d of Q)(c=d.onRegisteredNewMesh)==null||c.call(d,s,i)}),u(M,"lodInfos",new Map),u(M,"previouslyLoaded",new Map),u(M,"lowresCache",new Map),u(M,"queue",new tt(100,{debug:x!=!1}));let F=M;class ot{constructor(t,e,s,n){u(this,"url");u(this,"key");u(this,"level");u(this,"index");this.url=t,this.key=e,this.level=s,n!=null&&(this.index=n)}}class me{constructor(t,e){u(this,"frame_start");u(this,"frame_capture_end");u(this,"ready");u(this,"_resolve");u(this,"_signal");u(this,"_resolved",!1);u(this,"_addedCount",0);u(this,"_resolvedCount",0);u(this,"_awaiting",[]);u(this,"_maxPromisesPerObject",1);u(this,"_currentFrame",0);u(this,"_seen",new WeakMap);var r;const n=Math.max(e.frames??2,2);this.frame_start=t,this.frame_capture_end=t+n,this.ready=new Promise(i=>{this._resolve=i}),this.ready.finally(()=>{this._resolved=!0,this._awaiting.length=0}),this._signal=e.signal,(r=this._signal)==null||r.addEventListener("abort",()=>{this.resolveNow()}),this._maxPromisesPerObject=Math.max(1,e.maxPromisesPerObject??1)}get awaitedCount(){return this._addedCount}get resolvedCount(){return this._resolvedCount}get currentlyAwaiting(){return this._awaiting.length}update(t){var e;this._currentFrame=t,((e=this._signal)!=null&&e.aborted||this._currentFrame>this.frame_capture_end&&this._awaiting.length===0)&&this.resolveNow()}add(t,e,s){if(this._resolved){x&&console.warn("PromiseGroup: Trying to add a promise to a resolved group, ignoring.");return}if(!(this._currentFrame>this.frame_capture_end)){if(this._maxPromisesPerObject>=1)if(this._seen.has(e)){let n=this._seen.get(e);if(n>=this._maxPromisesPerObject){x&&console.warn("PromiseGroup: Already awaiting object ignoring new promise for it.");return}this._seen.set(e,n+1)}else this._seen.set(e,1);this._awaiting.push(s),this._addedCount++,s.finally(()=>{this._resolvedCount++,this._awaiting.splice(this._awaiting.indexOf(s),1)})}}resolveNow(){var t,e;this._resolved||(e=this._resolve)==null||e.call(this,{awaited_count:this._addedCount,resolved_count:this._resolvedCount,cancelled:((t=this._signal)==null?void 0:t.aborted)??!1})}}u(me,"addPromise",(t,e,s,n)=>{n.forEach(r=>{r.add(t,e,s)})});const R=de("debugprogressive"),at=de("noprogressive"),ve=Symbol("Needle:LODSManager"),Oe=Symbol("Needle:LODState"),H=Symbol("Needle:CurrentLOD"),I={mesh_lod:-1,texture_lod:-1};var L,G,X,Le,j,re,xe,K;let ue=(L=class{constructor(t,e){u(this,"renderer");u(this,"context");u(this,"projectionScreenMatrix",new y.Matrix4);u(this,"targetTriangleDensity",2e5);u(this,"skinnedMeshAutoUpdateBoundsInterval",30);u(this,"updateInterval","auto");Y(this,G,1);u(this,"pause",!1);u(this,"manual",!1);u(this,"_newPromiseGroups",[]);u(this,"_promiseGroupIds",0);u(this,"_lodchangedlisteners",[]);Y(this,X);Y(this,Le,new y.Clock);Y(this,j,0);Y(this,re,0);Y(this,xe,0);Y(this,K,0);u(this,"_fpsBuffer",[60,60,60,60,60]);u(this,"_sphere",new y.Sphere);u(this,"_tempBox",new y.Box3);u(this,"_tempBox2",new y.Box3);u(this,"tempMatrix",new y.Matrix4);u(this,"_tempWorldPosition",new y.Vector3);u(this,"_tempBoxSize",new y.Vector3);u(this,"_tempBox2Size",new y.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[ve])return console.debug("[gltf-progressive] LODsManager already exists for this renderer"),t[ve];const s=new L(t,{engine:"unknown",...e});return t[ve]=s,s}get plugins(){return Q}awaitLoading(t){const e=this._promiseGroupIds++,s=new me(w(this,j),{...t});this._newPromiseGroups.push(s);const n=performance.now();return s.ready.finally(()=>{const r=this._newPromiseGroups.indexOf(s);r>=0&&(this._newPromiseGroups.splice(r,1),Ie()&&performance.measure("LODsManager:awaitLoading",{start:n,detail:{id:e,name:t==null?void 0:t.name,awaited:s.awaitedCount,resolved:s.resolvedCount}}))}),s.ready}_postprocessPromiseGroups(){if(this._newPromiseGroups.length!==0)for(let t=this._newPromiseGroups.length-1;t>=0;t--)this._newPromiseGroups[t].update(w(this,j))}addEventListener(t,e){t==="changed"&&this._lodchangedlisteners.push(e)}removeEventListener(t,e){if(t==="changed"){const s=this._lodchangedlisteners.indexOf(e);s>=0&&this._lodchangedlisteners.splice(s,1)}}enable(){if(w(this,X))return;console.debug("[gltf-progressive] Enabling LODsManager for renderer");let t=0;z(this,X,this.renderer.render);const e=this;Te(this.renderer),this.renderer.render=function(s,n){const r=e.renderer.getRenderTarget();(r==null||"isXRRenderTarget"in r&&r.isXRRenderTarget)&&(t=0,z(e,j,w(e,j)+1),z(e,re,w(e,Le).getDelta()),z(e,xe,w(e,xe)+w(e,re)),e._fpsBuffer.shift(),e._fpsBuffer.push(1/w(e,re)),z(e,K,e._fpsBuffer.reduce((a,l)=>a+l)/e._fpsBuffer.length),R&&w(e,j)%200===0&&console.log("FPS",Math.round(w(e,K)),"Interval:",w(e,G)));const i=t++;w(e,X).call(this,s,n),e.onAfterRender(s,n,i)}}disable(){w(this,X)&&(console.debug("[gltf-progressive] Disabling LODsManager for renderer"),this.renderer.render=w(this,X),z(this,X,void 0))}update(t,e){this.internalUpdate(t,e)}onAfterRender(t,e,s){if(this.pause)return;const r=this.renderer.renderLists.get(t,0).opaque;let i=!0;if(r.length===1){const a=r[0].material;(a.name==="EffectMaterial"||a.name==="CopyShader")&&(i=!1)}if((e.parent&&e.parent.type==="CubeCamera"||s>=1&&e.type==="OrthographicCamera")&&(i=!1),i){if(at||(this.updateInterval==="auto"?w(this,K)<40&&w(this,G)<10?(z(this,G,w(this,G)+1),R&&console.warn("↓ Reducing LOD updates",w(this,G),w(this,K).toFixed(0))):w(this,K)>=60&&w(this,G)>1&&(z(this,G,w(this,G)-1),R&&console.warn("↑ Increasing LOD updates",w(this,G),w(this,K).toFixed(0))):z(this,G,this.updateInterval),w(this,G)>0&&w(this,j)%w(this,G)!=0))return;this.internalUpdate(t,e),this._postprocessPromiseGroups()}}internalUpdate(t,e){var l,c;const s=this.renderer.renderLists.get(t,0),n=s.opaque;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse);const r=this.targetTriangleDensity;for(const d of n){if(d.material&&(((l=d.geometry)==null?void 0:l.type)==="BoxGeometry"||((c=d.geometry)==null?void 0:c.type)==="BufferGeometry")&&(d.material.name==="SphericalGaussianBlur"||d.material.name=="BackgroundCubeMaterial"||d.material.name==="CubemapFromEquirect"||d.material.name==="EquirectangularToCubeUV")){R&&(d.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(d.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",d,d.material.name,d.material.type)));continue}switch(d.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}if(R==="color"&&d.material&&!d.object.progressive_debug_color){d.object.progressive_debug_color=!0;const f=Math.random()*16777215,D=new y.MeshStandardMaterial({color:f});d.object.material=D}const h=d.object;(h instanceof y.Mesh||h.isMesh)&&this.updateLODs(t,e,h,r)}const i=s.transparent;for(const d of i){const h=d.object;(h instanceof y.Mesh||h.isMesh)&&this.updateLODs(t,e,h,r)}const a=s.transmissive;for(const d of a){const h=d.object;(h instanceof y.Mesh||h.isMesh)&&this.updateLODs(t,e,h,r)}}updateLODs(t,e,s,n){var a,l;s.userData||(s.userData={});let r=s[Oe];if(r||(r=new lt,s[Oe]=r),r.frames++<2)return;for(const c of Q)(a=c.onBeforeUpdateLOD)==null||a.call(c,this.renderer,t,e,s);const i=L.overrideGlobalLodLevel!==void 0?L.overrideGlobalLodLevel:ee;i>=0?(I.mesh_lod=i,I.texture_lod=i):(this.calculateLodLevel(e,s,r,n,I),I.mesh_lod=Math.round(I.mesh_lod),I.texture_lod=Math.round(I.texture_lod)),I.mesh_lod>=0&&this.loadProgressiveMeshes(s,I.mesh_lod),s.material&&I.texture_lod>=0&&this.loadProgressiveTextures(s.material,I.texture_lod),x&&s.material&&!s.isGizmo&&Ve(s.material);for(const c of Q)(l=c.onAfterUpdatedLOD)==null||l.call(c,this.renderer,t,e,s,I);r.lastLodLevel_Mesh=I.mesh_lod,r.lastLodLevel_Texture=I.texture_lod}loadProgressiveTextures(t,e){if(!t)return;if(Array.isArray(t)){for(const r of t)this.loadProgressiveTextures(r,e);return}let s=!1;(t[H]===void 0||e<t[H])&&(s=!0);const n=t["DEBUG:LOD"];if(n!=null&&(s=t[H]!=n,e=n),s){t[H]=e;const r=F.assignTextureLOD(t,e).then(i=>{this._lodchangedlisteners.forEach(a=>a({type:"texture",level:e,object:t}))});me.addPromise("texture",t,r,this._newPromiseGroups)}}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);let s=t[H]!==e;const n=t["DEBUG:LOD"];if(n!=null&&(s=t[H]!=n,e=n),s){t[H]=e;const r=t.geometry,i=F.assignMeshLOD(t,e).then(a=>(a&&t[H]==e&&r!=t.geometry&&this._lodchangedlisteners.forEach(l=>l({type:"mesh",level:e,object:t})),a));return me.addPromise("mesh",t,i,this._newPromiseGroups),i}return Promise.resolve(null)}static isInside(t,e){const s=t.min,n=t.max,r=(s.x+n.x)*.5,i=(s.y+n.y)*.5;return this._tempPtInside.set(r,i,s.z).applyMatrix4(e).z<0}calculateLodLevel(t,e,s,n,r){var S,k,J;if(!e){r.mesh_lod=-1,r.texture_lod=-1;return}if(!t){r.mesh_lod=-1,r.texture_lod=-1;return}let a=10+1,l=!1;if(R&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const c=(S=F.getMeshLODExtension(e.geometry))==null?void 0:S.lods,d=F.getPrimitiveIndex(e.geometry),h=c&&c.length>0,f=F.getMaterialMinMaxLODsCount(e.material),D=(f==null?void 0:f.min_count)!=1/0&&f.min_count>0&&f.max_count>0;if(!h&&!D){r.mesh_lod=0,r.texture_lod=0;return}h||(l=!0,a=0);const O=this.renderer.domElement.clientHeight||this.renderer.domElement.height;let T=e.geometry.boundingBox;if(e.type==="SkinnedMesh"){const g=e;if(!g.boundingBox)g.computeBoundingBox();else if(this.skinnedMeshAutoUpdateBoundsInterval>0){if(!g[L.$skinnedMeshBoundsOffset]){const C=L.skinnedMeshBoundsFrameOffsetCounter++;g[L.$skinnedMeshBoundsOffset]=C}const _=g[L.$skinnedMeshBoundsOffset];if((s.frames+_)%this.skinnedMeshAutoUpdateBoundsInterval===0){const C=ie(g),U=g.geometry;C&&(g.geometry=C),g.computeBoundingBox(),g.geometry=U}}T=g.boundingBox}if(T){const g=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 p=t.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(p)){r.mesh_lod=0,r.texture_lod=0;return}}if(this._tempBox.copy(T),this._tempBox.applyMatrix4(e.matrixWorld),g.isPerspectiveCamera&&L.isInside(this._tempBox,this.projectionScreenMatrix)){r.mesh_lod=0,r.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&g.isPerspectiveCamera&&g.fov>70){const p=this._tempBox.min,v=this._tempBox.max;let $=p.x,A=p.y,V=v.x,ne=v.y;const ce=2,we=1.5,fe=(p.x+v.x)*.5,he=(p.y+v.y)*.5;$=($-fe)*ce+fe,A=(A-he)*ce+he,V=(V-fe)*ce+fe,ne=(ne-he)*ce+he;const We=$<0&&V>0?0:Math.min(Math.abs(p.x),Math.abs(v.x)),Xe=A<0&&ne>0?0:Math.min(Math.abs(p.y),Math.abs(v.y)),_e=Math.max(We,Xe);s.lastCentrality=(we-_e)*(we-_e)*(we-_e)}else s.lastCentrality=1;const _=this._tempBox.getSize(this._tempBoxSize);_.multiplyScalar(.5),screen.availHeight>0&&O>0&&_.multiplyScalar(O/screen.availHeight),t.isPerspectiveCamera?_.x*=t.aspect:t.isOrthographicCamera;const C=t.matrixWorldInverse,U=this._tempBox2;U.copy(T),U.applyMatrix4(e.matrixWorld),U.applyMatrix4(C);const P=U.getSize(this._tempBox2Size),Z=Math.max(P.x,P.y);if(Math.max(_.x,_.y)!=0&&Z!=0&&(_.z=P.z/Math.max(P.x,P.y)*Math.max(_.x,_.y)),s.lastScreenCoverage=Math.max(_.x,_.y,_.z),s.lastScreenspaceVolume.copy(_),s.lastScreenCoverage*=s.lastCentrality,R&&L.debugDrawLine){const p=this.tempMatrix.copy(this.projectionScreenMatrix);p.invert();const v=L.corner0,$=L.corner1,A=L.corner2,V=L.corner3;v.copy(this._tempBox.min),$.copy(this._tempBox.max),$.x=v.x,A.copy(this._tempBox.max),A.y=v.y,V.copy(this._tempBox.max);const ne=(v.z+V.z)*.5;v.z=$.z=A.z=V.z=ne,v.applyMatrix4(p),$.applyMatrix4(p),A.applyMatrix4(p),V.applyMatrix4(p),L.debugDrawLine(v,$,255),L.debugDrawLine(v,A,255),L.debugDrawLine($,V,255),L.debugDrawLine(A,V,255)}let b=999;if(c&&s.lastScreenCoverage>0)for(let p=0;p<c.length;p++){const v=c[p],A=(((k=v.densities)==null?void 0:k[d])||v.density||1e-5)/s.lastScreenCoverage;if(d>0&&Ie()&&!v.densities&&!globalThis["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"]&&(window["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"]=!0,console.warn("[Needle Progressive] Detected usage of mesh without primitive densities. This might cause incorrect LOD level selection: Consider re-optimizing your model by updating your Needle Integration, Needle glTF Pipeline or running optimization again on Needle Cloud.")),A<n){b=p;break}}b<a&&(a=b,l=!0)}if(l?r.mesh_lod=a:r.mesh_lod=s.lastLodLevel_Mesh,R&&r.mesh_lod!=s.lastLodLevel_Mesh){const _=c==null?void 0:c[r.mesh_lod];_&&console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} → ${r.mesh_lod} (${_.density.toFixed(0)}) - ${e.name}`)}if(D){const g="saveData"in globalThis.navigator&&globalThis.navigator.saveData===!0;if(s.lastLodLevel_Texture<0){if(r.texture_lod=f.max_count-1,R){const _=f.lods[f.max_count-1];R&&console.log(`First Texture LOD ${r.texture_lod} (${_.max_height}px) - ${e.name}`)}}else{const _=s.lastScreenspaceVolume.x+s.lastScreenspaceVolume.y+s.lastScreenspaceVolume.z;let C=s.lastScreenCoverage*4;((J=this.context)==null?void 0:J.engine)==="model-viewer"&&(C*=1.5);const P=O/window.devicePixelRatio*C;let Z=!1;for(let E=f.lods.length-1;E>=0;E--){const b=f.lods[E];if(!(g&&b.max_height>=2048)&&!(et()&&b.max_height>4096)&&(b.max_height>P||!Z&&E===0)){if(Z=!0,r.texture_lod=E,r.texture_lod<s.lastLodLevel_Texture){const m=b.max_height;R&&console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${r.texture_lod} = ${m}px
|
|
6
|
-
Screensize: ${P.toFixed(0)}px, Coverage: ${(100*s.lastScreenCoverage).toFixed(2)}%, Volume ${_.toFixed(1)}
|
|
7
|
-
${e.name}`)}break}}}}else r.texture_lod=0}},G=new WeakMap,X=new WeakMap,Le=new WeakMap,j=new WeakMap,re=new WeakMap,xe=new WeakMap,K=new WeakMap,u(L,"debugDrawLine"),u(L,"overrideGlobalLodLevel"),u(L,"corner0",new y.Vector3),u(L,"corner1",new y.Vector3),u(L,"corner2",new y.Vector3),u(L,"corner3",new y.Vector3),u(L,"_tempPtInside",new y.Vector3),u(L,"skinnedMeshBoundsFrameOffsetCounter",0),u(L,"$skinnedMeshBoundsOffset",Symbol("gltf-progressive-skinnedMeshBoundsOffset")),L);class lt{constructor(){u(this,"frames",0);u(this,"lastLodLevel_Mesh",-1);u(this,"lastLodLevel_Texture",-1);u(this,"lastScreenCoverage",0);u(this,"lastScreenspaceVolume",new y.Vector3);u(this,"lastCentrality",0)}}const Ge=Symbol("NEEDLE_mesh_lod"),ge=Symbol("NEEDLE_texture_lod");let le=null;function ze(){const o=ut();o&&(o.mapURLs(function(t){return Be(),t}),Be(),le==null||le.disconnect(),le=new MutationObserver(t=>{t.forEach(e=>{e.addedNodes.forEach(s=>{s instanceof HTMLElement&&s.tagName.toLowerCase()==="model-viewer"&&qe(s)})})}),le.observe(document,{childList:!0,subtree:!0}))}function ut(){if(typeof customElements>"u")return null;const o=customElements.get("model-viewer");return o||(customElements.whenDefined("model-viewer").then(()=>{console.debug("[gltf-progressive] model-viewer defined"),ze()}),null)}function Be(){if(typeof document>"u")return;document.querySelectorAll("model-viewer").forEach(t=>{qe(t)})}const ke=new WeakSet;let dt=0;function qe(o){if(!o||ke.has(o))return null;ke.add(o),console.debug("[gltf-progressive] found new model-viewer..."+ ++dt+`
|
|
8
|
-
`,o.getAttribute("src"));let t=null,e=null,s=null;for(let n=o;n!=null;n=Object.getPrototypeOf(n)){const r=Object.getOwnPropertySymbols(n),i=r.find(c=>c.toString()=="Symbol(renderer)"),a=r.find(c=>c.toString()=="Symbol(scene)"),l=r.find(c=>c.toString()=="Symbol(needsRender)");!t&&i!=null&&(t=o[i].threeRenderer),!e&&a!=null&&(e=o[a]),!s&&l!=null&&(s=o[l])}if(t&&e){let n=function(){if(s){let i=0,a=setInterval(()=>{if(i++>5){clearInterval(a);return}s==null||s.call(o)},300)}};console.debug("[gltf-progressive] setup model-viewer");const r=ue.get(t,{engine:"model-viewer"});return ue.addPlugin(new ct),r.enable(),r.addEventListener("changed",()=>{s==null||s.call(o)}),o.addEventListener("model-visibility",i=>{i.detail.visible&&(s==null||s.call(o))}),o.addEventListener("load",()=>{n()}),()=>{r.disable()}}return null}class ct{constructor(){u(this,"_didWarnAboutMissingUrl",!1)}onBeforeUpdateLOD(t,e,s,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 s=this.tryGetCurrentGLTF(t),n=this.tryGetCurrentModelViewer(t),r=this.getUrl(n);if(r&&s&&e.material){let i=function(l){var d,h,f;if(l[ge]==!0)return;l[ge]=!0,l.userData&&(l.userData.LOD=-1);const c=Object.keys(l);for(let D=0;D<c.length;D++){const O=c[D],T=l[O];if((T==null?void 0:T.isTexture)===!0){const S=(h=(d=T.userData)==null?void 0:d.associations)==null?void 0:h.textures;if(S==null)continue;const k=s.parser.json.textures[S];if(!k){console.warn("Texture data not found for texture index "+S);continue}if((f=k==null?void 0:k.extensions)!=null&&f[W]){const J=k.extensions[W];J&&r&&F.registerTexture(r,T,J.lods.length,S,J)}}}};const a=e.material;if(Array.isArray(a))for(const l of a)i(l);else i(a)}}tryParseMeshLOD(t,e){var i,a;if(e[Ge]==!0)return;e[Ge]=!0;const s=this.tryGetCurrentModelViewer(t),n=this.getUrl(s);if(!n)return;const r=(a=(i=e.userData)==null?void 0:i.gltfExtensions)==null?void 0:a[W];if(r&&n){const l=e.uuid;F.registerMesh(n,l,e,0,r.lods.length,r)}}}function ft(o,t,e,s){Te(t),Ae(e),Ce(e,{progressive:!0,...s==null?void 0:s.hints}),e.register(r=>new F(r,o));const n=ue.get(t);return(s==null?void 0:s.enableLODsManager)!==!1&&n.enable(),n}ze();if(!st){const o={gltfProgressive:{useNeedleProgressive:ft,LODsManager:ue,configureLoader:Ce,getRaycastMesh:ie,useRaycastMeshes:it}};if(!globalThis.Needle)globalThis.Needle=o;else for(const t in o)globalThis.Needle[t]=o[t]}exports.LODsManager=ue;exports.NEEDLE_progressive=F;exports.addDracoAndKTX2Loaders=Ae;exports.configureLoader=Ce;exports.createLoaders=Te;exports.getRaycastMesh=ie;exports.setDracoDecoderLocation=Fe;exports.setKTX2TranscoderLocation=Ne;
|