- Track Needle/MenuScene/dist and Needle/SampleScene/dist for container deploys - Dockerfile copies pre-built dist (no npm in image); rebuild with npm run build before commit - Fix Needle .gitignore: /assets/ so dist/assets is not ignored - Git LFS: track *.wasm; relax .dockerignore so dist is sent as build context Made-with: Cursor
5 lines
39 KiB
JavaScript
5 lines
39 KiB
JavaScript
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./three@0.169.19.js","./rolldown-runtime.CYVBeYYp.js"])))=>i.map(i=>d[i]);
|
|
import{d as e}from"./materialx.CnHmG--Y.js";import{Ar as t,F as n,S as r,St as i,Xt as a,Yt as o,Zt as s,_ as c,_r as l,gr as u,in as d,k as f,lr as p,x as m,xt as h}from"./three@0.169.19.js";import{S as g,b as _,x as v,y as ee}from"./three-examples@0.169.19.js";var te=`3.4.0-beta.3`;globalThis.GLTF_PROGRESSIVE_VERSION=te,console.debug(`[gltf-progressive] version ${te}`);var y=`https://www.gstatic.com/draco/versioned/decoders/1.5.7/`,b=`https://cdn.needle.tools/static/three/0.179.1/basis2/`,ne=y,re=b,ie=new URL(y+`draco_decoder.js`);ie.searchParams.append(`range`,`true`),fetch(ie,{method:`GET`,headers:{Range:`bytes=0-1`}}).catch(e=>{console.debug(`Failed to fetch remote Draco decoder from ${y} (offline: ${typeof navigator<`u`?navigator.onLine:`unknown`})`),y===ne&&oe(`./include/draco/`),b===re&&se(`./include/ktx2/`)}).finally(()=>{ce()});var ae=()=>({dracoDecoderPath:y,ktx2TranscoderPath:b});function oe(e){y=e,w&&w[C]!=y?(console.debug(`Updating Draco decoder path to `+e),w[C]=y,w.setDecoderPath(y),w.preload()):console.debug(`Setting Draco decoder path to `+e)}function se(e){b=e,E&&E.transcoderPath!=b?(console.debug(`Updating KTX2 transcoder path to `+e),E.setTranscoderPath(b),E.init()):console.debug(`Setting KTX2 transcoder path to `+e)}function x(e){return ce(),e?E.detectSupport(e):e!==null&&console.warn(`No renderer provided to detect ktx2 support - loading KTX2 textures might fail`),{dracoLoader:w,ktx2Loader:E,meshoptDecoder:T}}function S(e){e.dracoLoader||e.setDRACOLoader(w),e.ktx2Loader||e.setKTX2Loader(E),e.meshoptDecoder||e.setMeshoptDecoder(T)}var C=Symbol(`dracoDecoderPath`),w,T,E;function ce(){w||(w=new _,w[C]=y,w.setDecoderPath(y),w.setDecoderConfig({type:`js`}),w.preload()),E||(E=new ee,E.setTranscoderPath(b),E.init()),T||=v}var D=new WeakMap;function O(e,t){let n=D.get(e);n=n?Object.assign(n,t):t,D.set(e,n)}var le=g.prototype.load;function ue(...e){let t=D.get(this),n=e[0],r=new URL(n,window.location.href);if(r.hostname.endsWith(`needle.tools`)){let e=t?.progressive===void 0?!0:t.progressive,i=t?.usecase?t.usecase:`default`;e?this.requestHeader.Accept=`*/*;progressive=allowed;usecase=${i}`:this.requestHeader.Accept=`*/*;usecase=${i}`,n=r.toString()}return e[0]=n,le?.call(this,...e)}g.prototype.load=ue,k(`debugprogressive`);function k(e){if(typeof window>`u`)return!1;let t=new URL(window.location.href).searchParams.get(e);return t==null||t===`0`||t===`false`?!1:t===``?!0:t}function de(e,t){if(t===void 0||e===void 0||t.startsWith(`./`)||t.startsWith(`http`)||t.startsWith(`data:`)||t.startsWith(`blob:`))return t;let n=e.lastIndexOf(`/`);if(n>=0){let r=e.substring(0,n+1);for(;r.endsWith(`/`)&&t.startsWith(`/`);)t=t.substring(1);return r+t}return t}function A(){return j===void 0?(j=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),k(`debugprogressive`)&&console.log(`[glTF Progressive]: isMobileDevice`,j),j):j}var j;function fe(){if(typeof window>`u`)return!1;let e=new URL(window.location.href),t=e.hostname===`localhost`||/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(e.hostname);return e.hostname===`127.0.0.1`||t}var pe=class{maxConcurrent;_running=new Map;_queue=[];debug=!1;constructor(e,t={}){this.maxConcurrent=e,this.debug=t.debug??!1,window.requestAnimationFrame(this.tick)}tick=()=>{this.internalUpdate(),setTimeout(this.tick,10)};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(){let 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.`);let{key:e,resolve:t}=this._queue.shift();t({use:t=>this.add(e,t)})}}};function me(e){let t=e.image?.width??0,n=e.image?.height??0,r=e.image?.depth??1,i=Math.floor(Math.log2(Math.max(t,n,r)))+1,a=he(e);return t*n*r*a*(1-.25**i)/.75}function he(e){let t=4,n=e.format;n===1024||n===1025?t=1:n===1026||n===1027?t=2:n===1022||n===1029?t=3:(n===1023||n===1033)&&(t=4);let r=1,i=e.type;return i===1009||i===1010?r=1:i===1011||i===1012?r=2:i===1013||i===1014||i===1015?r=4:i===1016&&(r=2),t*r}var ge=typeof window>`u`&&typeof document>`u`,M=Symbol(`needle:raycast-mesh`);function N(e){return e?.[M]instanceof r?e[M]:null}function _e(e,t){if((e.type===`Mesh`||e.type===`SkinnedMesh`)&&!N(e)){let n=ye(t);n.userData={isRaycastMesh:!0},e[M]=n}}function ve(e=!0){if(e){if(P)return;let e=P=s.prototype.raycast;s.prototype.raycast=function(t,n){let r=this,i=N(r),a;i&&r.isMesh&&(a=r.geometry,r.geometry=i),e.call(this,t,n),a&&(r.geometry=a)}}else{if(!P)return;s.prototype.raycast=P,P=null}}var P=null;function ye(e){let t=new r;for(let n in e.attributes)t.setAttribute(n,e.getAttribute(n));return t.setIndex(e.getIndex()),t}var F=[],I=k(`debugprogressive`),L=void 0,R=-1;if(I){function e(){R+=1,R>=6&&(R=-1),console.log(`Toggle LOD level [${R}]`)}window.addEventListener(`keyup`,t=>{t.key===`p`&&e(),t.key===`w`&&(L=!L,console.log(`Toggle wireframe [${L}]`));let n=parseInt(t.key);!isNaN(n)&&n>=0&&(R=n,console.log(`Set LOD level to [${R}]`))})}function be(e){if(I&&L!==void 0)if(Array.isArray(e))for(let t of e)be(t);else e&&`wireframe`in e&&(e.wireframe=L===!0)}var z=[],xe=0,Se=A()?2:10;function Ce(e){if(z.length<Se){let t=z.length;I&&console.warn(`[Worker] Creating new worker #${t}`);let n=we.createWorker(e||{});return z.push(n),n}return z[xe++%z.length]}var we=class t{worker;static async createWorker(e){return new t(new Worker(new URL(``+new URL(`gltf-progressive.worker-DbINgLUC.js`,import.meta.url).href,``+import.meta.url),{type:`module`}),e)}_running=[];_webglRenderer=null;async load(t,n){let r=ae(),i=n?.renderer;i||=(this._webglRenderer??=(async()=>{let{WebGLRenderer:t}=await e(async()=>{let{WebGLRenderer:e}=await import(`./three@0.169.19.js`).then(e=>e.Rr);return{WebGLRenderer:e}},__vite__mapDeps([0,1]),import.meta.url);return new t})(),await this._webglRenderer);let a=x(i).ktx2Loader.workerConfig;t instanceof URL?t=t.toString():t.startsWith(`file:`)?t=URL.createObjectURL(new Blob([t])):!t.startsWith(`blob:`)&&!t.startsWith(`http:`)&&!t.startsWith(`https:`)&&(t=new URL(t,window.location.href).toString());let o={type:`load`,url:t,dracoDecoderPath:r.dracoDecoderPath,ktx2TranscoderPath:r.ktx2TranscoderPath,ktx2LoaderConfig:a};return this._debug&&console.debug(`[Worker] Sending load request`,o),this.worker.postMessage(o),new Promise(e=>{this._running.push({url:t.toString(),resolve:e})})}_debug=!1;constructor(e,t){this.worker=e,this._debug=t.debug??!1,e.onmessage=e=>{let t=e.data;switch(this._debug&&console.log(`[Worker] EVENT`,t),t.type){case`loaded-gltf`:for(let e of this._running)if(e.url===t.result.url){Te(t.result),e.resolve(t.result);let n=e.url;n.startsWith(`blob:`)&&URL.revokeObjectURL(n)}}},e.onerror=e=>{console.error(`[Worker] Error in gltf-progressive worker:`,e)},e.postMessage({type:`init`})}};function Te(e){for(let n of e.geometries){let e=n.geometry,i=new r;if(i.name=e.name||``,e.index){let t=e.index;i.setIndex(B(t))}for(let t in e.attributes){let n=e.attributes[t],r=B(n);i.setAttribute(t,r)}if(e.morphAttributes)for(let t in e.morphAttributes){let n=e.morphAttributes[t].map(e=>B(e));i.morphAttributes[t]=n}if(i.morphTargetsRelative=e.morphTargetsRelative??!1,i.boundingBox=new c,i.boundingBox.min=new t(e.boundingBox?.min.x,e.boundingBox?.min.y,e.boundingBox?.min.z),i.boundingBox.max=new t(e.boundingBox?.max.x,e.boundingBox?.max.y,e.boundingBox?.max.z),i.boundingSphere=new p(new t(e.boundingSphere?.center.x,e.boundingSphere?.center.y,e.boundingSphere?.center.z),e.boundingSphere?.radius),e.groups)for(let t of e.groups)i.addGroup(t.start,t.count,t.materialIndex);e.userData&&(i.userData=e.userData),n.geometry=i}for(let t of e.textures){let e=t.texture,r=null;if(e.isCompressedTexture){let t=e.mipmaps;r=new n(t,e.image?.width||e.source?.data?.width||-1,e.image?.height||e.source?.data?.height||-1,e.format,e.type,e.mapping,e.wrapS,e.wrapT,e.magFilter,e.minFilter,e.anisotropy,e.colorSpace)}else r=new u(e.image,e.mapping,e.wrapS,e.wrapT,e.magFilter,e.minFilter,e.format,e.type,e.anisotropy,e.colorSpace),r.mipmaps=e.mipmaps,r.channel=e.channel,r.source.data=e.source.data,r.flipY=e.flipY,r.premultiplyAlpha=e.premultiplyAlpha,r.unpackAlignment=e.unpackAlignment,r.matrix=new o(...e.matrix.elements);if(!r){console.error(`[Worker] Failed to create new texture from received data. Texture is not a CompressedTexture or Texture.`);continue}t.texture=r}return e}function B(e){let t=e;if(`isInterleavedBufferAttribute`in e&&e.isInterleavedBufferAttribute){let n=e.data,r=n.array;t=new i(new h(r,n.stride),e.itemSize,r.byteOffset,e.normalized),t.offset=e.offset}else `isBufferAttribute`in e&&e.isBufferAttribute&&(t=new m(e.array,e.itemSize,e.normalized),t.usage=e.usage,t.gpuType=e.gpuType,t.updateRanges=e.updateRanges);return t}var Ee=k(`gltf-progressive-worker`);k(`gltf-progressive-reduce-mipmaps`);var V=k(`gltf-progressive-gc`),H=Symbol(`needle-progressive-texture`),U=`NEEDLE_progressive`,W=class e{get name(){return U}static getMeshLODExtension(e){let t=this.getAssignedLODInformation(e);return t?.key?this.lodInfos.get(t.key):null}static getPrimitiveIndex(e){return this.getAssignedLODInformation(e)?.index??-1}static getMaterialMinMaxLODsCount(e,t){let n=this,r=`LODS:minmax`,i=e[r];if(i!=null)return i;if(t||={min_count:1/0,max_count:0,lods:[]},Array.isArray(e)){for(let n of e)this.getMaterialMinMaxLODsCount(n,t);return e[r]=t,t}if(I===`verbose`&&console.log(`getMaterialMinMaxLODsCount`,e),e.type===`ShaderMaterial`||e.type===`RawShaderMaterial`){let n=e;for(let e of Object.keys(n.uniforms)){let r=n.uniforms[e].value;r?.isTexture===!0&&a(r,t)}}else if(e.isMaterial)for(let n of Object.keys(e)){let r=e[n];r?.isTexture===!0&&a(r,t)}else I&&console.warn(`[getMaterialMinMaxLODsCount] Unsupported material type: ${e.type}`);return e[r]=t,t;function a(e,t){let r=n.getAssignedLODInformation(e);if(r){let e=n.lodInfos.get(r.key);if(e&&e.lods){t.min_count=Math.min(t.min_count,e.lods.length),t.max_count=Math.max(t.max_count,e.lods.length);for(let n=0;n<e.lods.length;n++){let r=e.lods[n];r.width&&(t.lods[n]=t.lods[n]||{min_height:1/0,max_height:0},t.lods[n].min_height=Math.min(t.lods[n].min_height,r.height),t.lods[n].max_height=Math.max(t.lods[n].max_height,r.height))}}}}}static hasLODLevelAvailable(e,t){if(Array.isArray(e)){for(let n of e)if(this.hasLODLevelAvailable(n,t))return!0;return!1}if(e.isMaterial===!0){for(let n of Object.keys(e)){let r=e[n];if(r&&r.isTexture&&this.hasLODLevelAvailable(r,t))return!0}return!1}else if(e.isGroup===!0){for(let n of e.children)if(n.isMesh===!0&&this.hasLODLevelAvailable(n,t))return!0}let n,r;if(e.isMesh?n=e.geometry:(e.isBufferGeometry||e.isTexture)&&(n=e),n&&n?.userData?.LODS){let e=n.userData.LODS;if(r=this.lodInfos.get(e.key),t===void 0)return r!=null;if(r)return Array.isArray(r.lods)?t<r.lods.length:t===0}return!1}static assignMeshLOD(t,n){if(!t)return Promise.resolve(null);if(t instanceof s||t.isMesh===!0){let r=t.geometry,i=this.getAssignedLODInformation(r);if(!i)return Promise.resolve(null);for(let e of F)e.onBeforeGetLODMesh?.(t,n);return t[`LOD:requested level`]=n,e.getOrLoadLOD(r,n).then(e=>{if(Array.isArray(e)){let t=i.index||0;e=e[t]}return t[`LOD:requested level`]===n&&(delete t[`LOD:requested level`],e&&r!=e&&(e?.isBufferGeometry?t.geometry=e:I&&console.error(`Invalid LOD geometry`,e))),e}).catch(e=>(console.error(`Error loading mesh LOD`,t,e),null))}else I&&console.error(`Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh`,t);return Promise.resolve(null)}static assignTextureLOD(e,t=0){if(!e)return Promise.resolve(null);if(e.isMesh===!0){let n=e;if(Array.isArray(n.material)){let e=[];for(let r of n.material){let n=this.assignTextureLOD(r,t);e.push(n)}return Promise.all(e).then(e=>{let t=[];for(let n of e)Array.isArray(n)&&t.push(...n);return t})}else return this.assignTextureLOD(n.material,t)}if(e.isMaterial===!0){let n=e,r=[],i=[];if(n.uniforms&&(n.isRawShaderMaterial||n.isShaderMaterial===!0)){let e=n;for(let a of Object.keys(e.uniforms)){let o=e.uniforms[a].value;if(o?.isTexture===!0){let s=this.assignTextureLODForSlot(o,t,n,a).then(t=>(t&&e.uniforms[a].value!=t&&(e.uniforms[a].value=t,e.uniformsNeedUpdate=!0),t));r.push(s),i.push(a)}}}else for(let e of Object.keys(n)){let a=n[e];if(a?.isTexture===!0){let o=this.assignTextureLODForSlot(a,t,n,e);r.push(o),i.push(e)}}return Promise.all(r).then(e=>{let r=[];for(let a=0;a<e.length;a++){let o=e[a],s=i[a];o&&o.isTexture===!0?r.push({material:n,slot:s,texture:o,level:t}):r.push({material:n,slot:s,texture:null,level:t})}return r})}if(e instanceof u||e.isTexture===!0){let n=e;return this.assignTextureLODForSlot(n,t,null,null)}return Promise.resolve(null)}static set maxConcurrentLoadingTasks(t){e.queue.maxConcurrent=t}static get maxConcurrentLoadingTasks(){return e.queue.maxConcurrent}static assignTextureLODForSlot(t,n,r,i){return t?.isTexture===!0?i===`glyphMap`?Promise.resolve(t):e.getOrLoadLOD(t,n).then(e=>{if(Array.isArray(e))return console.warn(`Progressive: Got an array of textures for a texture slot, this should not happen...`),null;if(e?.isTexture===!0){if(e!=t&&r&&i){let t=r[i];if(t&&!I){let i=this.getAssignedLODInformation(t);if(i&&i?.level<n)return I===`verbose`&&console.warn(`Assigned texture level is already higher: `,i.level,n,r,t,e),e&&e!==t&&((I||V)&&console.log(`[gltf-progressive] Disposing rejected lower-quality texture LOD ${n} (assigned is ${i.level})`,e.uuid),e.dispose()),null}if(this.trackTextureUsage(e),t&&t!==e&&this.untrackTextureUsage(t)&&(I||V)){let e=this.getAssignedLODInformation(t);console.log(`[gltf-progressive] Disposed old texture LOD ${e?.level??`?`} → ${n} for ${r.name||r.type}.${i}`,t.uuid)}r[i]=e}return e}else I==`verbose`&&console.warn(`No LOD found for`,t,n);return null}).catch(e=>(console.error(`Error loading LOD`,t,e),null)):Promise.resolve(null)}parser;url;constructor(e){let t=e.options.path;I&&console.log(`Progressive extension registered for`,t),this.parser=e,this.url=t}_isLoadingMesh;loadMesh=t=>{if(this._isLoadingMesh)return null;let n=this.parser.json.meshes[t]?.extensions?.[U];return n?(this._isLoadingMesh=!0,this.parser.getDependency(`mesh`,t).then(t=>(this._isLoadingMesh=!1,t&&e.registerMesh(this.url,n.guid,t,n.lods?.length,0,n),t))):null};afterRoot(t){return I&&console.log(`AFTER`,this.url,t),this.parser.json.textures?.forEach((t,n)=>{if(t?.extensions){let r=t?.extensions[U];if(r){if(!r.lods){I&&console.warn(`Texture has no LODs`,r);return}let t=!1;for(let i of this.parser.associations.keys())i.isTexture===!0&&this.parser.associations.get(i)?.textures===n&&(t=!0,e.registerTexture(this.url,i,r.lods?.length,n,r));t||this.parser.getDependency(`texture`,n).then(t=>{t&&e.registerTexture(this.url,t,r.lods?.length,n,r)})}}}),this.parser.json.meshes?.forEach((t,n)=>{if(t?.extensions){let r=t?.extensions[U];if(r&&r.lods){for(let t of this.parser.associations.keys())if(t.isMesh){let i=this.parser.associations.get(t);i?.meshes===n&&e.registerMesh(this.url,r.guid,t,r.lods.length,i.primitives,r)}}}}),null}static registerTexture=(t,n,r,i,a)=>{if(!n){I&&console.error(`!! gltf-progressive: Called register texture without texture`);return}if(I){let e=n.image?.width||n.source?.data?.width||0,t=n.image?.height||n.source?.data?.height||0;console.log(`> gltf-progressive: register texture[${i}] "${n.name||n.uuid}", Current: ${e}x${t}, Max: ${a.lods[0]?.width}x${a.lods[0]?.height}, uuid: ${n.uuid}`,a,n)}n.source&&(n.source[H]=a);let o=a.guid;e.assignLODInformation(t,n,o,r,i),e.lodInfos.set(o,a),e.lowresCache.set(o,new WeakRef(n))};static registerMesh=(t,n,r,i,a,o)=>{let s=r.geometry;if(!s){I&&console.warn(`gltf-progressive: Register mesh without geometry`);return}s.userData||={},I&&console.log(`> Progressive: register mesh `+r.name,{index:a,uuid:r.uuid},o,r),e.assignLODInformation(t,s,n,i,a),e.lodInfos.set(n,o);let c=e.lowresCache.get(n)?.deref();c?c.push(r.geometry):c=[r.geometry],e.lowresCache.set(n,new WeakRef(c)),i>0&&!N(r)&&_e(r,s);for(let e of F)e.onRegisteredNewMesh?.(r,o)};static dispose(e){if(e){this.lodInfos.delete(e);let t=this.lowresCache.get(e);if(t){let n=t.deref();if(n){if(n.isTexture){let e=n;this.textureRefCounts.delete(e.uuid),e.dispose()}else if(Array.isArray(n))for(let e of n)e.dispose()}this.lowresCache.delete(e)}for(let[t,n]of this.cache)t.includes(e)&&(this._disposeCacheEntry(n),this.cache.delete(t))}else{this.lodInfos.clear();for(let[,e]of this.lowresCache){let t=e.deref();if(t){if(t.isTexture){let e=t;this.textureRefCounts.delete(e.uuid),e.dispose()}else if(Array.isArray(t))for(let e of t)e.dispose()}}this.lowresCache.clear();for(let[,e]of this.cache)this._disposeCacheEntry(e);this.cache.clear(),this.textureRefCounts.clear()}}static _disposeCacheEntry(e){if(e instanceof WeakRef){let t=e.deref();t&&(t.isTexture&&this.textureRefCounts.delete(t.uuid),t.dispose())}else e.then(e=>{if(e)if(Array.isArray(e))for(let t of e)t.dispose();else e.isTexture&&this.textureRefCounts.delete(e.uuid),e.dispose()}).catch(()=>{})}static lodInfos=new Map;static cache=new Map;static lowresCache=new Map;static textureRefCounts=new Map;static _resourceRegistry=new FinalizationRegistry(t=>{let n=e.cache.get(t);(I||V)&&console.debug(`[gltf-progressive] Memory: Resource GC'd\n${t}`),n instanceof WeakRef&&(n.deref()||(e.cache.delete(t),(I||V)&&console.log(`[gltf-progressive] ↪ Cache entry deleted (GC)`)))});static trackTextureUsage(e){let t=e.uuid,n=this.textureRefCounts.get(t)||0;this.textureRefCounts.set(t,n+1),I===`verbose`&&console.log(`[gltf-progressive] Track texture ${t}, refCount: ${n} → ${n+1}`)}static untrackTextureUsage(e){let t=e.uuid,n=this.textureRefCounts.get(t);if(!n)return(I===`verbose`||V)&&i(`[gltf-progressive] Memory: Untrack untracked texture (dispose immediately)`,0),e.dispose(),!0;let r=n-1;if(r<=0)return this.textureRefCounts.delete(t),(I||V)&&i(`[gltf-progressive] Memory: Dispose texture`,r),e.dispose(),!0;return this.textureRefCounts.set(t,r),I===`verbose`&&i(`[gltf-progressive] Memory: Untrack texture`,r),!1;function i(r,i){let a=e.image?.width||e.source?.data?.width||0,o=e.image?.height||e.source?.data?.height||0,s=a&&o?`${a}x${o}`:`N/A`,c=`N/A`;a&&o&&(c=`~${(me(e)/(1024*1024)).toFixed(2)} MB`),console.log(`${r} — ${e.name} ${s} (${c}), refCount: ${n} → ${i}\n${t}`)}}static workers=[];static _workersIndex=0;static async getOrLoadLOD(t,n){let i=I==`verbose`,a=this.getAssignedLODInformation(t);if(!a)return I&&console.warn(`[gltf-progressive] No LOD information found: ${t.name}, uuid: ${t.uuid}, type: ${t.type}`,t),null;let o=a?.key,s;if(t.isTexture===!0){let e=t;e.source&&e.source[H]&&(s=e.source[H])}if(s||=e.lodInfos.get(o),!s)I&&console.warn(`Can not load LOD ${n}: no LOD info found for \"${o}\" ${t.name}`,t.type,e.lodInfos);else{if(n>0){let e=!1,t=Array.isArray(s.lods);if(t&&n>=s.lods.length?e=!0:t||(e=!0),e){let e=this.lowresCache.get(o);if(e){let t=e.deref();if(t)return t;this.lowresCache.delete(o),I&&console.log(`[gltf-progressive] Lowres cache entry was GC'd: ${o}`)}return null}}let c=Array.isArray(s.lods)?s.lods[n]?.path:s.lods;if(!c)return I&&!s[`missing:uri`]&&(s[`missing:uri`]=!0,console.warn(`Missing uri for progressive asset for LOD `+n,s)),null;let d=de(a.url,c);if(d.endsWith(`.glb`)||d.endsWith(`.gltf`)){if(!s.guid)return console.warn(`missing pointer for glb/gltf texture`,s),null;let c=d+`_`+s.guid,l=await this.queue.slot(d),f=this.cache.get(c);if(f!==void 0)if(i&&console.log(`LOD ${n} was already loading/loaded: ${c}`),f instanceof WeakRef){let e=f.deref();if(e){let n=e,i=!1;if(n instanceof u&&t instanceof u?n.image?.data||n.source?.data?n=this.copySettings(t,n):i=!0:n instanceof r&&t instanceof r&&(n.attributes.position?.array||(i=!0)),!i)return n}this.cache.delete(c),I&&console.log(`[gltf-progressive] Re-loading GC'd/disposed resource: ${c}`)}else{let e=await f.catch(e=>(console.error(`Error loading LOD ${n} from ${d}\n`,e),null)),i=!1;if(e==null||(e instanceof u&&t instanceof u?e.image?.data||e.source?.data?e=this.copySettings(t,e):(i=!0,this.cache.delete(c)):e instanceof r&&t instanceof r&&(e.attributes.position?.array||(i=!0,this.cache.delete(c)))),!i)return e}if(!l.use)return I&&console.log(`LOD ${n} was aborted: ${d}`),null;let p=s,m=new Promise(async(r,s)=>{if(Ee){let i=await(await Ce({})).load(d);if(i.textures.length>0)for(let s of i.textures){let i=s.texture;return e.assignLODInformation(a.url,i,o,n,void 0),t instanceof u&&(i=this.copySettings(t,i)),i&&(i.guid=p.guid),r(i)}if(i.geometries.length>0){let t=[];for(let r of i.geometries){let i=r.geometry;e.assignLODInformation(a.url,i,o,n,r.primitiveIndex),t.push(i)}return r(t)}return r(null)}let l=new g;S(l),I&&(await new Promise(e=>setTimeout(e,1e3)),i&&console.warn(`Start loading (delayed) `+d,p.guid));let f=d;if(p&&Array.isArray(p.lods)){let e=p.lods[n];e.hash&&(f+=`?v=`+e.hash)}let m=await l.loadAsync(f).catch(e=>(console.error(`Error loading LOD ${n} from ${d}\n`,e),r(null)));if(!m)return r(null);let h=m.parser;i&&console.log(`Loading finished `+d,p.guid);let _=0;if(m.parser.json.textures){let s=!1;for(let e of m.parser.json.textures){if(e?.extensions){let t=e?.extensions[U];if(t?.guid&&t.guid===p.guid){s=!0;break}}_++}if(s){let s=await h.getDependency(`texture`,_);return s&&e.assignLODInformation(a.url,s,o,n,void 0),i&&console.log(`change "`+t.name+`" → "`+s.name+`"`,d,_,s,c),t instanceof u&&(s=this.copySettings(t,s)),s&&(s.guid=p.guid),r(s)}else I&&console.warn(`Could not find texture with guid`,p.guid,m.parser.json)}if(_=0,m.parser.json.meshes){let t=!1;for(let e of m.parser.json.meshes){if(e?.extensions){let n=e?.extensions[U];if(n?.guid&&n.guid===p.guid){t=!0;break}}_++}if(t){let t=await h.getDependency(`mesh`,_);if(i&&console.log(`Loaded Mesh \"${t.name}\"`,d,_,t,c),t.isMesh===!0){let i=t.geometry;return e.assignLODInformation(a.url,i,o,n,0),r(i)}else{let i=[];for(let r=0;r<t.children.length;r++){let s=t.children[r];if(s.isMesh===!0){let t=s.geometry;e.assignLODInformation(a.url,t,o,n,r),i.push(t)}}return r(i)}}else I&&console.warn(`Could not find mesh with guid`,p.guid,m.parser.json)}return r(null)});this.cache.set(c,m),l.use(m);let h=await m;return h==null?this.cache.set(c,Promise.resolve(null)):h instanceof u?(this.cache.set(c,new WeakRef(h)),e._resourceRegistry.register(h,c)):this.cache.set(c,Promise.resolve(h)),h}else if(t instanceof u){i&&console.log(`Load texture from uri: `+d);let e=await new l().loadAsync(d);return e?(e.guid=s.guid,e.flipY=!1,e.needsUpdate=!0,e.colorSpace=t.colorSpace,i&&console.log(s,e)):I&&console.warn(`failed loading`,d),e}}return null}static queue=new pe(A()?20:50,{debug:I!=0});static assignLODInformation(e,t,n,r,i){if(!t)return;t.userData||={};let a=new De(e,n,r,i);t.userData.LODS=a,`source`in t&&typeof t.source==`object`&&(t.source.LODS=a)}static getAssignedLODInformation(e){return e?e.userData?.LODS?e.userData.LODS:`source`in e&&e.source?.LODS?e.source.LODS:null:null}static copySettings(e,t){return t?(I===`verbose`&&console.debug(`Copy texture settings
|
|
`,e.uuid,`
|
|
`,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}},De=class{url;key;level;index;constructor(e,t,n,r){this.url=e,this.key=t,this.level=n,r!=null&&(this.index=r)}},G=class{static addPromise=(e,t,n,r)=>{r.forEach(r=>{r.add(e,t,n)})};ready;get awaitedCount(){return this._addedCount}get resolvedCount(){return this._resolvedCount}get currentlyAwaiting(){return this._awaiting.length}_resolve;_signal;_frame_start;_frames_to_capture;_resolved=!1;_addedCount=0;_resolvedCount=0;_awaiting=[];_maxPromisesPerObject=1;constructor(e,t){let n=Math.max(t.frames??2,2);this._frame_start=t.waitForFirstCapture?void 0:e,this._frames_to_capture=n,this.ready=new Promise(e=>{this._resolve=e}),this.ready.finally(()=>{this._resolved=!0,this._awaiting.length=0}),this._signal=t.signal,this._signal?.addEventListener(`abort`,()=>{this.resolveNow()}),this._maxPromisesPerObject=Math.max(1,t.maxPromisesPerObject??1)}_currentFrame=0;update(e){this._currentFrame=e,this._frame_start===void 0&&this._addedCount>0&&(this._frame_start=e),(this._signal?.aborted||this._awaiting.length===0&&this._frame_start!==void 0&&e>this._frame_start+this._frames_to_capture)&&this.resolveNow()}_seen=new WeakMap;add(e,t,n){if(this._resolved){I&&console.warn(`PromiseGroup: Trying to add a promise to a resolved group, ignoring.`);return}if(!(this._frame_start!==void 0&&this._currentFrame>this._frame_start+this._frames_to_capture)){if(this._maxPromisesPerObject>=1)if(this._seen.has(t)){let e=this._seen.get(t);if(e>=this._maxPromisesPerObject){I&&console.warn(`PromiseGroup: Already awaiting object ignoring new promise for it.`);return}this._seen.set(t,e+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(){this._resolved||this._resolve?.({awaited_count:this._addedCount,resolved_count:this._resolvedCount,cancelled:this._signal?.aborted??!1})}},K=k(`debugprogressive`),Oe=k(`noprogressive`),q=Symbol(`Needle:LODSManager`),J=Symbol(`Needle:LODState`),Y=Symbol(`Needle:CurrentLOD`),X={mesh_lod:-1,texture_lod:-1},Z=class e{static debugDrawLine;static getObjectLODState(e){return e[J]}static addPlugin(e){F.push(e)}static removePlugin(e){let t=F.indexOf(e);t>=0&&F.splice(t,1)}static get(t,n){if(t[q])return console.debug(`[gltf-progressive] LODsManager already exists for this renderer`),t[q];let r=new e(t,{engine:`unknown`,...n});return t[q]=r,r}renderer;context;projectionScreenMatrix=new a;get plugins(){return F}overrideLodLevel=void 0;targetTriangleDensity=2e5;skinnedMeshAutoUpdateBoundsInterval=30;updateInterval=`auto`;#e=1;pause=!1;manual=!1;_newPromiseGroups=[];_promiseGroupIds=0;awaitLoading(e){let t=this._promiseGroupIds++,n=new G(this.#r,{...e});this._newPromiseGroups.push(n);let r=performance.now();return n.ready.finally(()=>{let i=this._newPromiseGroups.indexOf(n);i>=0&&(this._newPromiseGroups.splice(i,1),fe()&&performance.measure(`LODsManager:awaitLoading`,{start:r,detail:{id:t,name:e?.name,awaited:n.awaitedCount,resolved:n.resolvedCount}}))}),n.ready}_postprocessPromiseGroups(){if(this._newPromiseGroups.length!==0)for(let e=this._newPromiseGroups.length-1;e>=0;e--)this._newPromiseGroups[e].update(this.#r)}_lodchangedlisteners=[];addEventListener(e,t){e===`changed`&&this._lodchangedlisteners.push(t)}removeEventListener(e,t){if(e===`changed`){let e=this._lodchangedlisteners.indexOf(t);e>=0&&this._lodchangedlisteners.splice(e,1)}}constructor(e,t){this.renderer=e,this.context={...t}}#t;#n=new f;#r=0;#i=0;#a=0;#o=0;_fpsBuffer=[60,60,60,60,60];enable(){if(this.#t)return;console.debug(`[gltf-progressive] Enabling LODsManager for renderer`);let e=0;this.#t=this.renderer.render;let t=this;x(this.renderer),this.renderer.render=function(n,r){let i=t.renderer.getRenderTarget();(i==null||`isXRRenderTarget`in i&&i.isXRRenderTarget)&&(e=0,t.#r+=1,t.#i=t.#n.getDelta(),t.#a+=t.#i,t._fpsBuffer.shift(),t._fpsBuffer.push(1/t.#i),t.#o=t._fpsBuffer.reduce((e,t)=>e+t)/t._fpsBuffer.length,K&&t.#r%200==0&&console.log(`FPS`,Math.round(t.#o),`Interval:`,t.#e));let a=e++;t.#t.call(this,n,r),t.onAfterRender(n,r,a)}}disable(){this.#t&&=(console.debug(`[gltf-progressive] Disabling LODsManager for renderer`),this.renderer.render=this.#t,void 0)}update(e,t){this.internalUpdate(e,t)}onAfterRender(e,t,n){if(this.pause)return;let r=this.renderer.renderLists.get(e,0).opaque,i=!0;if(r.length===1){let e=r[0].material;(e.name===`EffectMaterial`||e.name===`CopyShader`)&&(i=!1)}if((t.parent&&t.parent.type===`CubeCamera`||n>=1&&t.type===`OrthographicCamera`)&&(i=!1),i){if(Oe||(this.updateInterval===`auto`?this.#o<40&&this.#e<10?(this.#e+=1,K&&console.warn(`↓ Reducing LOD updates`,this.#e,this.#o.toFixed(0))):this.#o>=60&&this.#e>1&&(--this.#e,K&&console.warn(`↑ Increasing LOD updates`,this.#e,this.#o.toFixed(0))):this.#e=this.updateInterval,this.#e>0&&this.#r%this.#e!=0))return;this.internalUpdate(e,t),this._postprocessPromiseGroups()}}internalUpdate(e,t){let n=this.renderer.renderLists.get(e,0),r=n.opaque;this.projectionScreenMatrix.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse);let i=this.targetTriangleDensity;for(let n of r){if(n.material&&(n.geometry?.type===`BoxGeometry`||n.geometry?.type===`BufferGeometry`)&&(n.material.name===`SphericalGaussianBlur`||n.material.name==`BackgroundCubeMaterial`||n.material.name===`CubemapFromEquirect`||n.material.name===`EquirectangularToCubeUV`)){K&&(n.material[`NEEDLE_PROGRESSIVE:IGNORE-WARNING`]||(n.material[`NEEDLE_PROGRESSIVE:IGNORE-WARNING`]=!0,console.warn(`Ignoring skybox or BLIT object`,n,n.material.name,n.material.type)));continue}switch(n.material.type){case`LineBasicMaterial`:case`LineDashedMaterial`:case`PointsMaterial`:case`ShadowMaterial`:case`MeshDistanceMaterial`:case`MeshDepthMaterial`:continue}if(K===`color`&&n.material&&!n.object.progressive_debug_color){n.object.progressive_debug_color=!0;let e=new d({color:Math.random()*16777215});n.object.material=e}let r=n.object;(r instanceof s||r.isMesh)&&this.updateLODs(e,t,r,i)}let a=n.transparent;for(let n of a){let r=n.object;(r instanceof s||r.isMesh)&&this.updateLODs(e,t,r,i)}let o=n.transmissive;for(let n of o){let r=n.object;(r instanceof s||r.isMesh)&&this.updateLODs(e,t,r,i)}}updateLODs(e,t,n,r){n.userData||={};let i=n[J];if(i||(i=new ke,n[J]=i),i.frames++<2)return;for(let r of F)r.onBeforeUpdateLOD?.(this.renderer,e,t,n);let a=this.overrideLodLevel===void 0?R:this.overrideLodLevel;a>=0?(X.mesh_lod=a,X.texture_lod=a):(this.calculateLodLevel(t,n,i,r,X),X.mesh_lod=Math.round(X.mesh_lod),X.texture_lod=Math.round(X.texture_lod)),X.mesh_lod>=0&&this.loadProgressiveMeshes(n,X.mesh_lod),n.material&&X.texture_lod>=0&&this.loadProgressiveTextures(n.material,X.texture_lod,a),I&&n.material&&!n.isGizmo&&be(n.material);for(let r of F)r.onAfterUpdatedLOD?.(this.renderer,e,t,n,X);i.lastLodLevel_Mesh=X.mesh_lod,i.lastLodLevel_Texture=X.texture_lod}loadProgressiveTextures(e,t,n){if(!e)return;if(Array.isArray(e)){for(let n of e)this.loadProgressiveTextures(n,t);return}let r=!1;if((e[Y]===void 0||t<e[Y])&&(r=!0),n!==void 0&&n>=0&&(r=e[Y]!=n,t=n),r){e[Y]=t;let n=W.assignTextureLOD(e,t).then(n=>{this._lodchangedlisteners.forEach(n=>n({type:`texture`,level:t,object:e}))});G.addPromise(`texture`,e,n,this._newPromiseGroups)}}loadProgressiveMeshes(e,t){if(!e)return Promise.resolve(null);let n=e[Y]!==t,r=e[`DEBUG:LOD`];if(r!=null&&(n=e[Y]!=r,t=r),n){e[Y]=t;let n=e.geometry,r=W.assignMeshLOD(e,t).then(r=>(r&&e[Y]==t&&n!=e.geometry&&this._lodchangedlisteners.forEach(n=>n({type:`mesh`,level:t,object:e})),r));return G.addPromise(`mesh`,e,r,this._newPromiseGroups),r}return Promise.resolve(null)}_sphere=new p;_tempBox=new c;_tempBox2=new c;tempMatrix=new a;_tempWorldPosition=new t;_tempBoxSize=new t;_tempBox2Size=new t;static corner0=new t;static corner1=new t;static corner2=new t;static corner3=new t;static _tempPtInside=new t;static isInside(e,t){let n=e.min,r=e.max,i=(n.x+r.x)*.5,a=(n.y+r.y)*.5;return this._tempPtInside.set(i,a,n.z).applyMatrix4(t).z<0}static skinnedMeshBoundsFrameOffsetCounter=0;static $skinnedMeshBoundsOffset=Symbol(`gltf-progressive-skinnedMeshBoundsOffset`);calculateLodLevel(t,n,r,i,a){if(!n){a.mesh_lod=-1,a.texture_lod=-1;return}if(!t){a.mesh_lod=-1,a.texture_lod=-1;return}let o=11,s=!1;if(K&&n[`DEBUG:LOD`]!=null)return n[`DEBUG:LOD`];let c=W.getMeshLODExtension(n.geometry)?.lods,l=W.getPrimitiveIndex(n.geometry),u=c&&c.length>0,d=W.getMaterialMinMaxLODsCount(n.material),f=d.min_count!==1/0&&d.min_count>=0&&d.max_count>=0;if(!u&&!f){a.mesh_lod=0,a.texture_lod=0;return}u||(s=!0,o=0);let p=this.renderer.domElement.clientHeight||this.renderer.domElement.height,m=n.geometry.boundingBox;if(n.type===`SkinnedMesh`){let t=n;if(!t.boundingBox)t.computeBoundingBox();else if(this.skinnedMeshAutoUpdateBoundsInterval>0){if(!t[e.$skinnedMeshBoundsOffset]){let n=e.skinnedMeshBoundsFrameOffsetCounter++;t[e.$skinnedMeshBoundsOffset]=n}let n=t[e.$skinnedMeshBoundsOffset];if((r.frames+n)%this.skinnedMeshAutoUpdateBoundsInterval===0){let e=N(t),n=t.geometry;e&&(t.geometry=e),t.computeBoundingBox(),t.geometry=n}}m=t.boundingBox}if(m){let u=t;if(n.geometry.attributes.color&&n.geometry.attributes.color.count<100&&n.geometry.boundingSphere){this._sphere.copy(n.geometry.boundingSphere),this._sphere.applyMatrix4(n.matrixWorld);let e=t.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(e)){a.mesh_lod=0,a.texture_lod=0;return}}if(this._tempBox.copy(m),this._tempBox.applyMatrix4(n.matrixWorld),u.isPerspectiveCamera&&e.isInside(this._tempBox,this.projectionScreenMatrix)){a.mesh_lod=0,a.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&u.isPerspectiveCamera&&u.fov>70){let e=this._tempBox.min,t=this._tempBox.max,n=e.x,i=e.y,a=t.x,o=t.y,s=1.5,c=(e.x+t.x)*.5,l=(e.y+t.y)*.5;n=(n-c)*2+c,i=(i-l)*2+l,a=(a-c)*2+c,o=(o-l)*2+l;let u=n<0&&a>0?0:Math.min(Math.abs(e.x),Math.abs(t.x)),d=i<0&&o>0?0:Math.min(Math.abs(e.y),Math.abs(t.y)),f=Math.max(u,d);r.lastCentrality=(s-f)*(s-f)*(s-f)}else r.lastCentrality=1;let d=this._tempBox.getSize(this._tempBoxSize);d.multiplyScalar(.5),screen.availHeight>0&&p>0&&d.multiplyScalar(p/screen.availHeight),t.isPerspectiveCamera?d.x*=t.aspect:t.isOrthographicCamera;let f=t.matrixWorldInverse,h=this._tempBox2;h.copy(m),h.applyMatrix4(n.matrixWorld),h.applyMatrix4(f);let g=h.getSize(this._tempBox2Size),_=Math.max(g.x,g.y);if(Math.max(d.x,d.y)!=0&&_!=0&&(d.z=g.z/Math.max(g.x,g.y)*Math.max(d.x,d.y)),r.lastScreenCoverage=Math.max(d.x,d.y,d.z),r.lastScreenspaceVolume.copy(d),r.lastScreenCoverage*=r.lastCentrality,K&&e.debugDrawLine){let t=this.tempMatrix.copy(this.projectionScreenMatrix);t.invert();let n=e.corner0,r=e.corner1,i=e.corner2,a=e.corner3;n.copy(this._tempBox.min),r.copy(this._tempBox.max),r.x=n.x,i.copy(this._tempBox.max),i.y=n.y,a.copy(this._tempBox.max),n.z=r.z=i.z=a.z=(n.z+a.z)*.5,n.applyMatrix4(t),r.applyMatrix4(t),i.applyMatrix4(t),a.applyMatrix4(t),e.debugDrawLine(n,r,255),e.debugDrawLine(n,i,255),e.debugDrawLine(r,a,255),e.debugDrawLine(i,a,255)}let v=999;if(c&&r.lastScreenCoverage>0)for(let e=0;e<c.length;e++){let t=c[e],n=(t.densities?.[l]||t.density||1e-5)/r.lastScreenCoverage;if(l>0&&fe()&&!t.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.`)),n<i){v=e;break}}v<o&&(o=v,s=!0)}if(s?a.mesh_lod=o:a.mesh_lod=r.lastLodLevel_Mesh,K&&a.mesh_lod!=r.lastLodLevel_Mesh){let e=c?.[a.mesh_lod];e&&console.log(`Mesh LOD changed: ${r.lastLodLevel_Mesh} → ${a.mesh_lod} (density: ${e.densities?.[l].toFixed(0)}) | ${n.name}`)}if(f){let e=`saveData`in globalThis.navigator&&globalThis.navigator.saveData===!0;if(r.lastLodLevel_Texture<0){if(a.texture_lod=d.max_count-1,K){let e=d.lods[d.max_count-1];K&&console.log(`First Texture LOD ${a.texture_lod} (${e.max_height}px) - ${n.name}`)}}else{let t=r.lastScreenspaceVolume.x+r.lastScreenspaceVolume.y+r.lastScreenspaceVolume.z,i=r.lastScreenCoverage*4;this.context?.engine===`model-viewer`&&(i*=1.5);let o=p/window.devicePixelRatio*i,s=!1;for(let i=d.lods.length-1;i>=0;i--){let c=d.lods[i];if(!(e&&c.max_height>=2048)&&!(A()&&c.max_height>4096)&&(c.max_height>o||!s&&i===0)){if(s=!0,a.texture_lod=i,K&&a.texture_lod<r.lastLodLevel_Texture){let e=c.max_height;console.log(`Texture LOD changed: ${r.lastLodLevel_Texture} → ${a.texture_lod} = ${e}px \nScreensize: ${o.toFixed(0)}px, Coverage: ${(100*r.lastScreenCoverage).toFixed(2)}%, Volume ${t.toFixed(1)} \n${n.name}`)}break}}}}else a.texture_lod=0}},ke=class{frames=0;lastLodLevel_Mesh=-1;lastLodLevel_Texture=-1;lastScreenCoverage=0;lastScreenspaceVolume=new t;lastCentrality=0},Ae=Symbol(`NEEDLE_mesh_lod`),Q=Symbol(`NEEDLE_texture_lod`),$=null;function je(){let e=Me();e&&(e.mapURLs(function(e){return Ne(),e}),Ne(),$?.disconnect(),$=new MutationObserver(e=>{e.forEach(e=>{e.addedNodes.forEach(e=>{e instanceof HTMLElement&&e.tagName.toLowerCase()===`model-viewer`&&Ie(e)})})}),$.observe(document,{childList:!0,subtree:!0}))}function Me(){return typeof customElements>`u`?null:customElements.get(`model-viewer`)||(customElements.whenDefined(`model-viewer`).then(()=>{console.debug(`[gltf-progressive] model-viewer defined`),je()}),null)}function Ne(){typeof document>`u`||document.querySelectorAll(`model-viewer`).forEach(e=>{Ie(e)})}var Pe=new WeakSet,Fe=0;function Ie(e){if(!e||Pe.has(e))return null;Pe.add(e),console.debug(`[gltf-progressive] found new model-viewer...`+ ++Fe+`
|
|
`,e.getAttribute(`src`));let t=null,n=null,r=null;for(let i=e;i!=null;i=Object.getPrototypeOf(i)){let a=Object.getOwnPropertySymbols(i),o=a.find(e=>e.toString()==`Symbol(renderer)`),s=a.find(e=>e.toString()==`Symbol(scene)`),c=a.find(e=>e.toString()==`Symbol(needsRender)`);!t&&o!=null&&(t=e[o].threeRenderer),!n&&s!=null&&(n=e[s]),!r&&c!=null&&(r=e[c])}if(t&&n){console.debug(`[gltf-progressive] setup model-viewer`);let n=Z.get(t,{engine:`model-viewer`});Z.addPlugin(new Le),n.enable(),n.addEventListener(`changed`,()=>{r?.call(e)}),e.addEventListener(`model-visibility`,t=>{t.detail.visible&&r?.call(e)}),e.addEventListener(`load`,()=>{i()});function i(){if(r){let t=0,n=setInterval(()=>{if(t++>5){clearInterval(n);return}r?.call(e)},300)}}return()=>{n.disable()}}return null}var Le=class{_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||=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[Q]==1)return;t[Q]=!0;let n=this.tryGetCurrentGLTF(e),r=this.tryGetCurrentModelViewer(e),i=this.getUrl(r);if(i&&n&&t.material){let e=t.material;if(Array.isArray(e))for(let t of e)r(t);else r(e);function r(e){if(e[Q]==1)return;e[Q]=!0,e.userData&&(e.userData.LOD=-1);let t=Object.keys(e);for(let r=0;r<t.length;r++){let a=e[t[r]];if(a?.isTexture===!0){let e=a.userData?.associations?.textures;if(e==null)continue;let t=n.parser.json.textures[e];if(!t){console.warn(`Texture data not found for texture index `+e);continue}if(t?.extensions?.NEEDLE_progressive){let n=t.extensions[U];n&&i&&W.registerTexture(i,a,n.lods.length,e,n)}}}}}}tryParseMeshLOD(e,t){if(t[Ae]==1)return;t[Ae]=!0;let n=this.tryGetCurrentModelViewer(e),r=this.getUrl(n);if(!r)return;let i=t.userData?.gltfExtensions?.[U];if(i&&r){let e=t.uuid;W.registerMesh(r,e,t,0,i.lods.length,i)}}};function Re(...e){let t,n,r,i;switch(e.length){case 2:[r,n]=e,i={};break;case 3:[r,n,i]=e;break;case 4:[t,n,r,i]=e;break;default:throw Error(`Invalid arguments`)}x(n),S(r),O(r,{progressive:!0,...i?.hints}),r.register(e=>new W(e));let a=Z.get(n);return i?.enableLODsManager!==!1&&a.enable(),a}if(je(),!ge){let e={gltfProgressive:{useNeedleProgressive:Re,LODsManager:Z,configureLoader:O,getRaycastMesh:N,useRaycastMeshes:ve}};if(!globalThis.Needle)globalThis.Needle=e;else for(let t in e)globalThis.Needle[t]=e[t]}export{O as a,se as c,S as i,W as n,x as o,N as r,oe as s,Z as t}; |