@needle-tools/engine 4.13.1-next.6cb1b73 → 4.13.1-next.9fc3e64
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-CaUGGjVL.umd.cjs +10 -0
- package/dist/{gltf-progressive-CsyU_5lc.js → gltf-progressive-Dbi_Tfhb.js} +628 -577
- package/dist/gltf-progressive-DuAR0MQR.min.js +10 -0
- package/dist/{needle-engine.bundle-wB3o8RB6.js → needle-engine.bundle-BZRE5G6O.js} +3 -3
- package/dist/{needle-engine.bundle-qTjHpin6.umd.cjs → needle-engine.bundle-Dqrh7aWw.umd.cjs} +4 -4
- package/dist/{needle-engine.bundle-DRSn34Va.min.js → needle-engine.bundle-DwybonUg.min.js} +2 -2
- package/dist/needle-engine.js +3 -3
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/package.json +2 -2
- package/plugins/vite/build-pipeline.js +16 -2
- package/dist/gltf-progressive-BTd714P0.min.js +0 -9
- package/dist/gltf-progressive-CrHduHPm.umd.cjs +0 -9
- package/src/include/three/DragControls.js +0 -232
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import{BufferGeometry as W,Mesh as F,Box3 as ae,Vector3 as A,Sphere as Le,CompressedTexture as Be,Texture as $,Matrix3 as Ge,InterleavedBuffer as je,InterleavedBufferAttribute as Ne,BufferAttribute as Ue,TextureLoader as We,Matrix4 as _e,Clock as Fe,MeshStandardMaterial as ze}from"./three-I__hSXzr.min.js";import{DRACOLoader as qe,KTX2Loader as Ve,MeshoptDecoder as Xe,GLTFLoader as le}from"./three-examples-D8zAE_7t.min.js";const He="";globalThis.GLTF_PROGRESSIVE_VERSION=He,console.debug("[gltf-progressive] version -");let k="https://www.gstatic.com/draco/versioned/decoders/1.5.7/",z="https://cdn.needle.tools/static/three/0.179.1/basis2/";const Ke=k,Ye=z,be=new URL(k+"draco_decoder.js");be.searchParams.append("range","true"),fetch(be,{method:"GET",headers:{Range:"bytes=0-1"}}).catch(i=>{console.debug(`Failed to fetch remote Draco decoder from ${k} (offline: ${typeof navigator<"u"?navigator.onLine:"unknown"})`),k===Ke&&Me("./include/draco/"),z===Ye&&De("./include/ktx2/")}).finally(()=>{Oe()});const Qe=()=>({dracoDecoderPath:k,ktx2TranscoderPath:z});function Me(i){k=i,T&&T[ce]!=k?(console.debug("Updating Draco decoder path to "+i),T[ce]=k,T.setDecoderPath(k),T.preload()):console.debug("Setting Draco decoder path to "+i)}function De(i){z=i,I&&I.transcoderPath!=z?(console.debug("Updating KTX2 transcoder path to "+i),I.setTranscoderPath(z),I.init()):console.debug("Setting KTX2 transcoder path to "+i)}function te(i){return Oe(),i?I.detectSupport(i):i!==null&&console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"),{dracoLoader:T,ktx2Loader:I,meshoptDecoder:re}}function ue(i){i.dracoLoader||i.setDRACOLoader(T),i.ktx2Loader||i.setKTX2Loader(I),i.meshoptDecoder||i.setMeshoptDecoder(re)}const ce=Symbol("dracoDecoderPath");let T,re,I;function Oe(){T||(T=new qe,T[ce]=k,T.setDecoderPath(k),T.setDecoderConfig({type:"js"}),T.preload()),I||(I=new Ve,I.setTranscoderPath(z),I.init()),re||(re=Xe)}const de=new WeakMap;function he(i,t){let e=de.get(i);e?e=Object.assign(e,t):e=t,de.set(i,e)}const Je=le.prototype.load;function Ze(...i){const t=de.get(this);let e=i[0];const r=new URL(e,window.location.href);if(r.hostname.endsWith("needle.tools")){const n=t?.progressive!==void 0?t.progressive:!0,s=t?.usecase?t.usecase:"default";n?this.requestHeader.Accept=`*/*;progressive=allowed;usecase=${s}`:this.requestHeader.Accept=`*/*;usecase=${s}`,e=r.toString()}return i[0]=e,Je?.call(this,...i)}le.prototype.load=Ze,j("debugprogressive");function j(i){if(typeof window>"u")return!1;const t=new URL(window.location.href).searchParams.get(i);return t==null||t==="0"||t==="false"?!1:t===""?!0:t}function et(i,t){if(t===void 0||i===void 0||t.startsWith("./")||t.startsWith("http")||t.startsWith("data:")||t.startsWith("blob:"))return t;const e=i.lastIndexOf("/");if(e>=0){const r=i.substring(0,e+1);for(;r.endsWith("/")&&t.startsWith("/");)t=t.substring(1);return r+t}return t}function Se(){return se!==void 0||(se=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),j("debugprogressive")&&console.log("[glTF Progressive]: isMobileDevice",se)),se}let se;function Te(){if(typeof window>"u")return!1;const i=new URL(window.location.href),t=i.hostname==="localhost"||/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(i.hostname);return i.hostname==="127.0.0.1"||t}class tt{constructor(t=100,e={}){this.maxConcurrent=t,this.debug=e.debug??!1,window.requestAnimationFrame(this.tick)}_running=new Map;_queue=[];debug=!1;tick=()=>{this.internalUpdate(),setTimeout(this.tick,10)};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:r,resolve:n}=this._queue.shift();n({use:s=>this.add(r,s)})}}}function rt(i){const t=i.image?.width??0,e=i.image?.height??0,r=i.image?.depth??1,n=Math.floor(Math.log2(Math.max(t,e,r)))+1,s=st(i);return t*e*r*s*(1-Math.pow(.25,n))/(1-.25)}function st(i){let t=4;const e=i.format;e===1024||e===1025?t=1:e===1026||e===1027?t=2:e===1022||e===1029?t=3:(e===1023||e===1033)&&(t=4);let r=1;const n=i.type;return n===1009||n===1010?r=1:n===1011||n===1012?r=2:n===1013||n===1014||n===1015?r=4:n===1016&&(r=2),t*r}const nt=typeof window>"u"&&typeof document>"u",ge=Symbol("needle:raycast-mesh");function V(i){return i?.[ge]instanceof W?i[ge]:null}function ot(i,t){if((i.type==="Mesh"||i.type==="SkinnedMesh")&&!V(i)){const e=at(t);e.userData={isRaycastMesh:!0},i[ge]=e}}function it(i=!0){if(i){if(H)return;const t=H=F.prototype.raycast;F.prototype.raycast=function(e,r){const n=this,s=V(n);let o;s&&n.isMesh&&(o=n.geometry,n.geometry=s),t.call(this,e,r),o&&(n.geometry=o)}}else{if(!H)return;F.prototype.raycast=H,H=null}}let H=null;function at(i){const t=new W;for(const e in i.attributes)t.setAttribute(e,i.getAttribute(e));return t.setIndex(i.getIndex()),t}const N=new Array,h=j("debugprogressive");let K,q=-1;if(h){let i=function(){q+=1,q>=t&&(q=-1),console.log(`Toggle LOD level [${q}]`)},t=6;window.addEventListener("keyup",e=>{e.key==="p"&&i(),e.key==="w"&&(K=!K,console.log(`Toggle wireframe [${K}]`));const r=parseInt(e.key);!isNaN(r)&&r>=0&&(q=r,console.log(`Set LOD level to [${q}]`))})}function Pe(i){if(h&&K!==void 0)if(Array.isArray(i))for(const t of i)Pe(t);else i&&"wireframe"in i&&(i.wireframe=K===!0)}const Y=new Array;let lt=0;const ut=Se()?2:10;function ct(i){if(Y.length<ut){const e=Y.length;h&&console.warn(`[Worker] Creating new worker #${e}`);const r=ve.createWorker(i||{});return Y.push(r),r}const t=lt++%Y.length;return Y[t]}class ve{constructor(t,e){this.worker=t,this._debug=e.debug??!1,t.onmessage=r=>{const n=r.data;switch(this._debug&&console.log("[Worker] EVENT",n),n.type){case"loaded-gltf":for(const s of this._running)if(s.url===n.result.url){dt(n.result),s.resolve(n.result);const o=s.url;o.startsWith("blob:")&&URL.revokeObjectURL(o)}}},t.onerror=r=>{console.error("[Worker] Error in gltf-progressive worker:",r)},t.postMessage({type:"init"})}static async createWorker(t){const e=new Worker(URL.createObjectURL(new Blob([`import '${new URL("./loader.worker-C1GG9A7C.js",import.meta.url).toString()}';`],{type:"text/javascript"})),{type:"module"});return new ve(e,t)}_running=[];_webglRenderer=null;async load(t,e){const r=Qe();let n=e?.renderer;n||(this._webglRenderer??=(async()=>{const{WebGLRenderer:l}=await import("./three-I__hSXzr.min.js").then(a=>a.THREE);return new l})(),n=await this._webglRenderer);const s=te(n).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());const o={type:"load",url:t,dracoDecoderPath:r.dracoDecoderPath,ktx2TranscoderPath:r.ktx2TranscoderPath,ktx2LoaderConfig:s};return this._debug&&console.debug("[Worker] Sending load request",o),this.worker.postMessage(o),new Promise(l=>{this._running.push({url:t.toString(),resolve:l})})}_debug=!1}function dt(i){for(const t of i.geometries){const e=t.geometry,r=new W;if(r.name=e.name||"",e.index){const n=e.index;r.setIndex(fe(n))}for(const n in e.attributes){const s=e.attributes[n],o=fe(s);r.setAttribute(n,o)}if(e.morphAttributes)for(const n in e.morphAttributes){const s=e.morphAttributes[n].map(o=>fe(o));r.morphAttributes[n]=s}if(r.morphTargetsRelative=e.morphTargetsRelative??!1,r.boundingBox=new ae,r.boundingBox.min=new A(e.boundingBox?.min.x,e.boundingBox?.min.y,e.boundingBox?.min.z),r.boundingBox.max=new A(e.boundingBox?.max.x,e.boundingBox?.max.y,e.boundingBox?.max.z),r.boundingSphere=new Le(new A(e.boundingSphere?.center.x,e.boundingSphere?.center.y,e.boundingSphere?.center.z),e.boundingSphere?.radius),e.groups)for(const n of e.groups)r.addGroup(n.start,n.count,n.materialIndex);e.userData&&(r.userData=e.userData),t.geometry=r}for(const t of i.textures){const e=t.texture;let r=null;if(e.isCompressedTexture){const n=e.mipmaps,s=e.image?.width||e.source?.data?.width||-1,o=e.image?.height||e.source?.data?.height||-1;r=new Be(n,s,o,e.format,e.type,e.mapping,e.wrapS,e.wrapT,e.magFilter,e.minFilter,e.anisotropy,e.colorSpace)}else r=new $(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 Ge(...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 i}function fe(i){let t=i;if("isInterleavedBufferAttribute"in i&&i.isInterleavedBufferAttribute){const e=i.data,r=e.array,n=new je(r,e.stride);t=new Ne(n,i.itemSize,r.byteOffset,i.normalized),t.offset=i.offset}else"isBufferAttribute"in i&&i.isBufferAttribute&&(t=new Ue(i.array,i.itemSize,i.normalized),t.usage=i.usage,t.gpuType=i.gpuType,t.updateRanges=i.updateRanges);return t}const ht=j("gltf-progressive-worker");j("gltf-progressive-reduce-mipmaps");const X=j("gltf-progressive-gc"),me=Symbol("needle-progressive-texture"),B="NEEDLE_progressive";class m{get name(){return B}static getMeshLODExtension(t){const e=this.getAssignedLODInformation(t);return e?.key?this.lodInfos.get(e.key):null}static getPrimitiveIndex(t){return this.getAssignedLODInformation(t)?.index??-1}static getMaterialMinMaxLODsCount(t,e){const r=this,n="LODS:minmax",s=t[n];if(s!=null)return s;if(e||(e={min_count:1/0,max_count:0,lods:[]}),Array.isArray(t)){for(const l of t)this.getMaterialMinMaxLODsCount(l,e);return t[n]=e,e}if(h==="verbose"&&console.log("getMaterialMinMaxLODsCount",t),t.type==="ShaderMaterial"||t.type==="RawShaderMaterial"){const l=t;for(const a of Object.keys(l.uniforms)){const u=l.uniforms[a].value;u?.isTexture===!0&&o(u,e)}}else if(t.isMaterial)for(const l of Object.keys(t)){const a=t[l];a?.isTexture===!0&&o(a,e)}else h&&console.warn(`[getMaterialMinMaxLODsCount] Unsupported material type: ${t.type}`);return t[n]=e,e;function o(l,a){const u=r.getAssignedLODInformation(l);if(u){const w=r.lodInfos.get(u.key);if(w&&w.lods){a.min_count=Math.min(a.min_count,w.lods.length),a.max_count=Math.max(a.max_count,w.lods.length);for(let p=0;p<w.lods.length;p++){const y=w.lods[p];y.width&&(a.lods[p]=a.lods[p]||{min_height:1/0,max_height:0},a.lods[p].min_height=Math.min(a.lods[p].min_height,y.height),a.lods[p].max_height=Math.max(a.lods[p].max_height,y.height))}}}}}static hasLODLevelAvailable(t,e){if(Array.isArray(t)){for(const s of t)if(this.hasLODLevelAvailable(s,e))return!0;return!1}if(t.isMaterial===!0){for(const s of Object.keys(t)){const o=t[s];if(o&&o.isTexture&&this.hasLODLevelAvailable(o,e))return!0}return!1}else if(t.isGroup===!0){for(const s of t.children)if(s.isMesh===!0&&this.hasLODLevelAvailable(s,e))return!0}let r,n;if(t.isMesh?r=t.geometry:(t.isBufferGeometry||t.isTexture)&&(r=t),r&&r?.userData?.LODS){const s=r.userData.LODS;if(n=this.lodInfos.get(s.key),e===void 0)return n!=null;if(n)return Array.isArray(n.lods)?e<n.lods.length:e===0}return!1}static assignMeshLOD(t,e){if(!t)return Promise.resolve(null);if(t instanceof F||t.isMesh===!0){const r=t.geometry,n=this.getAssignedLODInformation(r);if(!n)return Promise.resolve(null);for(const s of N)s.onBeforeGetLODMesh?.(t,e);return t["LOD:requested level"]=e,m.getOrLoadLOD(r,e).then(s=>{if(Array.isArray(s)){const o=n.index||0;s=s[o]}return t["LOD:requested level"]===e&&(delete t["LOD:requested level"],s&&r!=s&&(s?.isBufferGeometry?t.geometry=s:h&&console.error("Invalid LOD geometry",s))),s}).catch(s=>(console.error("Error loading mesh LOD",t,s),null))}else h&&console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh",t);return Promise.resolve(null)}static assignTextureLOD(t,e=0){if(!t)return Promise.resolve(null);if(t.isMesh===!0){const r=t;if(Array.isArray(r.material)){const n=new Array;for(const s of r.material){const o=this.assignTextureLOD(s,e);n.push(o)}return Promise.all(n).then(s=>{const o=new Array;for(const l of s)Array.isArray(l)&&o.push(...l);return o})}else return this.assignTextureLOD(r.material,e)}if(t.isMaterial===!0){const r=t,n=[],s=new Array;if(r.uniforms&&(r.isRawShaderMaterial||r.isShaderMaterial===!0)){const o=r;for(const l of Object.keys(o.uniforms)){const a=o.uniforms[l].value;if(a?.isTexture===!0){const u=this.assignTextureLODForSlot(a,e,r,l).then(w=>(w&&o.uniforms[l].value!=w&&(o.uniforms[l].value=w,o.uniformsNeedUpdate=!0),w));n.push(u),s.push(l)}}}else for(const o of Object.keys(r)){const l=r[o];if(l?.isTexture===!0){const a=this.assignTextureLODForSlot(l,e,r,o);n.push(a),s.push(o)}}return Promise.all(n).then(o=>{const l=new Array;for(let a=0;a<o.length;a++){const u=o[a],w=s[a];u&&u.isTexture===!0?l.push({material:r,slot:w,texture:u,level:e}):l.push({material:r,slot:w,texture:null,level:e})}return l})}if(t instanceof $||t.isTexture===!0){const r=t;return this.assignTextureLODForSlot(r,e,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(t,e,r,n){return t?.isTexture!==!0?Promise.resolve(null):n==="glyphMap"?Promise.resolve(t):m.getOrLoadLOD(t,e).then(s=>{if(Array.isArray(s))return console.warn("Progressive: Got an array of textures for a texture slot, this should not happen..."),null;if(s?.isTexture===!0){if(s!=t&&r&&n){const o=r[n];if(o&&!h){const l=this.getAssignedLODInformation(o);if(l&&l?.level<e)return h==="verbose"&&console.warn("Assigned texture level is already higher: ",l.level,e,r,o,s),s&&s!==o&&((h||X)&&console.log(`[gltf-progressive] Disposing rejected lower-quality texture LOD ${e} (assigned is ${l.level})`,s.uuid),s.dispose()),null}if(this.trackTextureUsage(s),o&&o!==s&&this.untrackTextureUsage(o)&&(h||X)){const l=this.getAssignedLODInformation(o);console.log(`[gltf-progressive] Disposed old texture LOD ${l?.level??"?"} \u2192 ${e} for ${r.name||r.type}.${n}`,o.uuid)}r[n]=s}return s}else h=="verbose"&&console.warn("No LOD found for",t,e);return null}).catch(s=>(console.error("Error loading LOD",t,s),null))}parser;url;constructor(t){const e=t.options.path;h&&console.log("Progressive extension registered for",e),this.parser=t,this.url=e}_isLoadingMesh;loadMesh=t=>{if(this._isLoadingMesh)return null;const e=this.parser.json.meshes[t]?.extensions?.[B];return e?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",t).then(r=>(this._isLoadingMesh=!1,r&&m.registerMesh(this.url,e.guid,r,e.lods?.length,0,e),r))):null};afterRoot(t){return h&&console.log("AFTER",this.url,t),this.parser.json.textures?.forEach((e,r)=>{if(e?.extensions){const n=e?.extensions[B];if(n){if(!n.lods){h&&console.warn("Texture has no LODs",n);return}let s=!1;for(const o of this.parser.associations.keys())o.isTexture===!0&&this.parser.associations.get(o)?.textures===r&&(s=!0,m.registerTexture(this.url,o,n.lods?.length,r,n));s||this.parser.getDependency("texture",r).then(o=>{o&&m.registerTexture(this.url,o,n.lods?.length,r,n)})}}}),this.parser.json.meshes?.forEach((e,r)=>{if(e?.extensions){const n=e?.extensions[B];if(n&&n.lods){for(const s of this.parser.associations.keys())if(s.isMesh){const o=this.parser.associations.get(s);o?.meshes===r&&m.registerMesh(this.url,n.guid,s,n.lods.length,o.primitives,n)}}}}),null}static registerTexture=(t,e,r,n,s)=>{if(!e){h&&console.error("!! gltf-progressive: Called register texture without texture");return}if(h){const l=e.image?.width||e.source?.data?.width||0,a=e.image?.height||e.source?.data?.height||0;console.log(`> gltf-progressive: register texture[${n}] "${e.name||e.uuid}", Current: ${l}x${a}, Max: ${s.lods[0]?.width}x${s.lods[0]?.height}, uuid: ${e.uuid}`,s,e)}e.source&&(e.source[me]=s);const o=s.guid;m.assignLODInformation(t,e,o,r,n),m.lodInfos.set(o,s),m.lowresCache.set(o,new WeakRef(e))};static registerMesh=(t,e,r,n,s,o)=>{const l=r.geometry;if(!l){h&&console.warn("gltf-progressive: Register mesh without geometry");return}l.userData||(l.userData={}),h&&console.log("> Progressive: register mesh "+r.name,{index:s,uuid:r.uuid},o,r),m.assignLODInformation(t,l,e,n,s),m.lodInfos.set(e,o);let a=m.lowresCache.get(e)?.deref();a?a.push(r.geometry):a=[r.geometry],m.lowresCache.set(e,new WeakRef(a)),n>0&&!V(r)&&ot(r,l);for(const u of N)u.onRegisteredNewMesh?.(r,o)};static dispose(t){if(t){this.lodInfos.delete(t);const e=this.lowresCache.get(t);if(e){const r=e.deref();if(r){if(r.isTexture){const n=r;this.textureRefCounts.delete(n.uuid),n.dispose()}else if(Array.isArray(r))for(const n of r)n.dispose()}this.lowresCache.delete(t)}for(const[r,n]of this.cache)r.includes(t)&&(this._disposeCacheEntry(n),this.cache.delete(r))}else{this.lodInfos.clear();for(const[,e]of this.lowresCache){const r=e.deref();if(r){if(r.isTexture){const n=r;this.textureRefCounts.delete(n.uuid),n.dispose()}else if(Array.isArray(r))for(const n of r)n.dispose()}}this.lowresCache.clear();for(const[,e]of this.cache)this._disposeCacheEntry(e);this.cache.clear(),this.textureRefCounts.clear()}}static _disposeCacheEntry(t){if(t instanceof WeakRef){const e=t.deref();e&&(e.isTexture&&this.textureRefCounts.delete(e.uuid),e.dispose())}else t.then(e=>{if(e)if(Array.isArray(e))for(const r of e)r.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=>{const e=m.cache.get(t);(h||X)&&console.debug(`[gltf-progressive] Memory: Resource GC'd
|
|
2
|
+
${t}`),e instanceof WeakRef&&(e.deref()||(m.cache.delete(t),(h||X)&&console.log("[gltf-progressive] \u21AA Cache entry deleted (GC)")))});static trackTextureUsage(t){const e=t.uuid,r=this.textureRefCounts.get(e)||0;this.textureRefCounts.set(e,r+1),h==="verbose"&&console.log(`[gltf-progressive] Track texture ${e}, refCount: ${r} \u2192 ${r+1}`)}static untrackTextureUsage(t){const e=t.uuid,r=this.textureRefCounts.get(e);if(!r)return(h==="verbose"||X)&&s("[gltf-progressive] Memory: Untrack untracked texture (dispose immediately)",0),t.dispose(),!0;const n=r-1;if(n<=0)return this.textureRefCounts.delete(e),(h||X)&&s("[gltf-progressive] Memory: Dispose texture",n),t.dispose(),!0;return this.textureRefCounts.set(e,n),h==="verbose"&&s("[gltf-progressive] Memory: Untrack texture",n),!1;function s(o,l){let a=t.image?.width||t.source?.data?.width||0,u=t.image?.height||t.source?.data?.height||0;const w=a&&u?`${a}x${u}`:"N/A";let p="N/A";a&&u&&(p=`~${(rt(t)/(1024*1024)).toFixed(2)} MB`),console.log(`${o} \u2014 ${t.name} ${w} (${p}), refCount: ${r} \u2192 ${l}
|
|
3
|
+
${e}`)}}static workers=[];static _workersIndex=0;static async getOrLoadLOD(t,e){const r=h=="verbose",n=this.getAssignedLODInformation(t);if(!n)return h&&console.warn(`[gltf-progressive] No LOD information found: ${t.name}, uuid: ${t.uuid}, type: ${t.type}`,t),null;const s=n?.key;let o;if(t.isTexture===!0){const l=t;l.source&&l.source[me]&&(o=l.source[me])}if(o||(o=m.lodInfos.get(s)),!o)h&&console.warn(`Can not load LOD ${e}: no LOD info found for "${s}" ${t.name}`,t.type,m.lodInfos);else{if(e>0){let u=!1;const w=Array.isArray(o.lods);if(w&&e>=o.lods.length?u=!0:w||(u=!0),u){const p=this.lowresCache.get(s);if(p){const y=p.deref();if(y)return y;this.lowresCache.delete(s),h&&console.log(`[gltf-progressive] Lowres cache entry was GC'd: ${s}`)}return null}}const l=Array.isArray(o.lods)?o.lods[e]?.path:o.lods;if(!l)return h&&!o["missing:uri"]&&(o["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+e,o)),null;const a=et(n.url,l);if(a.endsWith(".glb")||a.endsWith(".gltf")){if(!o.guid)return console.warn("missing pointer for glb/gltf texture",o),null;const u=a+"_"+o.guid,w=await this.queue.slot(a),p=this.cache.get(u);if(p!==void 0)if(r&&console.log(`LOD ${e} was already loading/loaded: ${u}`),p instanceof WeakRef){const c=p.deref();if(c){let x=c,v=!1;if(x instanceof $&&t instanceof $?x.image?.data||x.source?.data?x=this.copySettings(t,x):v=!0:x instanceof W&&t instanceof W&&(x.attributes.position?.array||(v=!0)),!v)return x}this.cache.delete(u),h&&console.log(`[gltf-progressive] Re-loading GC'd/disposed resource: ${u}`)}else{let c=await p.catch(v=>(console.error(`Error loading LOD ${e} from ${a}
|
|
4
|
+
`,v),null)),x=!1;if(c==null||(c instanceof $&&t instanceof $?c.image?.data||c.source?.data?c=this.copySettings(t,c):(x=!0,this.cache.delete(u)):c instanceof W&&t instanceof W&&(c.attributes.position?.array||(x=!0,this.cache.delete(u)))),!x)return c}if(!w.use)return h&&console.log(`LOD ${e} was aborted: ${a}`),null;const y=o,P=new Promise(async(c,x)=>{if(ht){const g=await(await ct({})).load(a);if(g.textures.length>0)for(const d of g.textures){let f=d.texture;return m.assignLODInformation(n.url,f,s,e,void 0),t instanceof $&&(f=this.copySettings(t,f)),f&&(f.guid=y.guid),c(f)}if(g.geometries.length>0){const d=new Array;for(const f of g.geometries){const L=f.geometry;m.assignLODInformation(n.url,L,s,e,f.primitiveIndex),d.push(L)}return c(d)}return c(null)}const v=new le;ue(v),h&&(await new Promise(g=>setTimeout(g,1e3)),r&&console.warn("Start loading (delayed) "+a,y.guid));let C=a;if(y&&Array.isArray(y.lods)){const g=y.lods[e];g.hash&&(C+="?v="+g.hash)}const b=await v.loadAsync(C).catch(g=>(console.error(`Error loading LOD ${e} from ${a}
|
|
5
|
+
`,g),c(null)));if(!b)return c(null);const R=b.parser;r&&console.log("Loading finished "+a,y.guid);let M=0;if(b.parser.json.textures){let g=!1;for(const d of b.parser.json.textures){if(d?.extensions){const f=d?.extensions[B];if(f?.guid&&f.guid===y.guid){g=!0;break}}M++}if(g){let d=await R.getDependency("texture",M);return d&&m.assignLODInformation(n.url,d,s,e,void 0),r&&console.log('change "'+t.name+'" \u2192 "'+d.name+'"',a,M,d,u),t instanceof $&&(d=this.copySettings(t,d)),d&&(d.guid=y.guid),c(d)}else h&&console.warn("Could not find texture with guid",y.guid,b.parser.json)}if(M=0,b.parser.json.meshes){let g=!1;for(const d of b.parser.json.meshes){if(d?.extensions){const f=d?.extensions[B];if(f?.guid&&f.guid===y.guid){g=!0;break}}M++}if(g){const d=await R.getDependency("mesh",M);if(r&&console.log(`Loaded Mesh "${d.name}"`,a,M,d,u),d.isMesh===!0){const f=d.geometry;return m.assignLODInformation(n.url,f,s,e,0),c(f)}else{const f=new Array;for(let L=0;L<d.children.length;L++){const S=d.children[L];if(S.isMesh===!0){const G=S.geometry;m.assignLODInformation(n.url,G,s,e,L),f.push(G)}}return c(f)}}else h&&console.warn("Could not find mesh with guid",y.guid,b.parser.json)}return c(null)});this.cache.set(u,P),w.use(P);const _=await P;return _!=null?_ instanceof $?(this.cache.set(u,new WeakRef(_)),m._resourceRegistry.register(_,u)):Array.isArray(_)?this.cache.set(u,Promise.resolve(_)):this.cache.set(u,Promise.resolve(_)):this.cache.set(u,Promise.resolve(null)),_}else if(t instanceof $){r&&console.log("Load texture from uri: "+a);const u=await new We().loadAsync(a);return u?(u.guid=o.guid,u.flipY=!1,u.needsUpdate=!0,u.colorSpace=t.colorSpace,r&&console.log(o,u)):h&&console.warn("failed loading",a),u}}return null}static maxConcurrent=50;static queue=new tt(m.maxConcurrent,{debug:h!=!1});static assignLODInformation(t,e,r,n,s){if(!e)return;e.userData||(e.userData={});const o=new gt(t,r,n,s);e.userData.LODS=o,"source"in e&&typeof e.source=="object"&&(e.source.LODS=o)}static getAssignedLODInformation(t){return t?t.userData?.LODS?t.userData.LODS:"source"in t&&t.source?.LODS?t.source.LODS:null:null}static copySettings(t,e){return e?(h==="verbose"&&console.debug(`Copy texture settings
|
|
6
|
+
`,t.uuid,`
|
|
7
|
+
`,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}}class gt{url;key;level;index;constructor(t,e,r,n){this.url=t,this.key=e,this.level=r,n!=null&&(this.index=n)}}class pe{static addPromise=(t,e,r,n)=>{n.forEach(s=>{s.add(t,e,r)})};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(t,e){const r=Math.max(e.frames??2,2);this._frame_start=e.waitForFirstCapture?void 0:t,this._frames_to_capture=r,this.ready=new Promise(n=>{this._resolve=n}),this.ready.finally(()=>{this._resolved=!0,this._awaiting.length=0}),this._signal=e.signal,this._signal?.addEventListener("abort",()=>{this.resolveNow()}),this._maxPromisesPerObject=Math.max(1,e.maxPromisesPerObject??1)}_currentFrame=0;update(t){this._currentFrame=t,this._frame_start===void 0&&this._addedCount>0&&(this._frame_start=t),(this._signal?.aborted||this._awaiting.length===0&&this._frame_start!==void 0&&t>this._frame_start+this._frames_to_capture)&&this.resolveNow()}_seen=new WeakMap;add(t,e,r){if(this._resolved){h&&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(e)){let n=this._seen.get(e);if(n>=this._maxPromisesPerObject){h&&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(r),this._addedCount++,r.finally(()=>{this._resolvedCount++,this._awaiting.splice(this._awaiting.indexOf(r),1)})}}resolveNow(){this._resolved||this._resolve?.({awaited_count:this._addedCount,resolved_count:this._resolvedCount,cancelled:this._signal?.aborted??!1})}}const E=j("debugprogressive"),ft=j("noprogressive"),xe=Symbol("Needle:LODSManager"),we=Symbol("Needle:LODState"),U=Symbol("Needle:CurrentLOD"),O={mesh_lod:-1,texture_lod:-1};let Q=class D{static debugDrawLine;static getObjectLODState(t){return t[we]}static addPlugin(t){N.push(t)}static removePlugin(t){const e=N.indexOf(t);e>=0&&N.splice(e,1)}static get(t,e){if(t[xe])return console.debug("[gltf-progressive] LODsManager already exists for this renderer"),t[xe];const r=new D(t,{engine:"unknown",...e});return t[xe]=r,r}renderer;context;projectionScreenMatrix=new _e;get plugins(){return N}overrideLodLevel=void 0;targetTriangleDensity=2e5;skinnedMeshAutoUpdateBoundsInterval=30;updateInterval="auto";#e=1;pause=!1;manual=!1;_newPromiseGroups=[];_promiseGroupIds=0;awaitLoading(t){const e=this._promiseGroupIds++,r=new pe(this.#s,{...t});this._newPromiseGroups.push(r);const n=performance.now();return r.ready.finally(()=>{const s=this._newPromiseGroups.indexOf(r);s>=0&&(this._newPromiseGroups.splice(s,1),Te()&&performance.measure("LODsManager:awaitLoading",{start:n,detail:{id:e,name:t?.name,awaited:r.awaitedCount,resolved:r.resolvedCount}}))}),r.ready}_postprocessPromiseGroups(){if(this._newPromiseGroups.length!==0)for(let t=this._newPromiseGroups.length-1;t>=0;t--)this._newPromiseGroups[t].update(this.#s)}_lodchangedlisteners=[];addEventListener(t,e){t==="changed"&&this._lodchangedlisteners.push(e)}removeEventListener(t,e){if(t==="changed"){const r=this._lodchangedlisteners.indexOf(e);r>=0&&this._lodchangedlisteners.splice(r,1)}}constructor(t,e){this.renderer=t,this.context={...e}}#t;#o=new Fe;#s=0;#n=0;#i=0;#r=0;_fpsBuffer=[60,60,60,60,60];enable(){if(this.#t)return;console.debug("[gltf-progressive] Enabling LODsManager for renderer");let t=0;this.#t=this.renderer.render;const e=this;te(this.renderer),this.renderer.render=function(r,n){const s=e.renderer.getRenderTarget();(s==null||"isXRRenderTarget"in s&&s.isXRRenderTarget)&&(t=0,e.#s+=1,e.#n=e.#o.getDelta(),e.#i+=e.#n,e._fpsBuffer.shift(),e._fpsBuffer.push(1/e.#n),e.#r=e._fpsBuffer.reduce((l,a)=>l+a)/e._fpsBuffer.length,E&&e.#s%200===0&&console.log("FPS",Math.round(e.#r),"Interval:",e.#e));const o=t++;e.#t.call(this,r,n),e.onAfterRender(r,n,o)}}disable(){this.#t&&(console.debug("[gltf-progressive] Disabling LODsManager for renderer"),this.renderer.render=this.#t,this.#t=void 0)}update(t,e){this.internalUpdate(t,e)}onAfterRender(t,e,r){if(this.pause)return;const n=this.renderer.renderLists.get(t,0).opaque;let s=!0;if(n.length===1){const o=n[0].material;(o.name==="EffectMaterial"||o.name==="CopyShader")&&(s=!1)}if((e.parent&&e.parent.type==="CubeCamera"||r>=1&&e.type==="OrthographicCamera")&&(s=!1),s){if(ft||(this.updateInterval==="auto"?this.#r<40&&this.#e<10?(this.#e+=1,E&&console.warn("\u2193 Reducing LOD updates",this.#e,this.#r.toFixed(0))):this.#r>=60&&this.#e>1&&(this.#e-=1,E&&console.warn("\u2191 Increasing LOD updates",this.#e,this.#r.toFixed(0))):this.#e=this.updateInterval,this.#e>0&&this.#s%this.#e!=0))return;this.internalUpdate(t,e),this._postprocessPromiseGroups()}}internalUpdate(t,e){const r=this.renderer.renderLists.get(t,0),n=r.opaque;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse);const s=this.targetTriangleDensity;for(const a of n){if(a.material&&(a.geometry?.type==="BoxGeometry"||a.geometry?.type==="BufferGeometry")&&(a.material.name==="SphericalGaussianBlur"||a.material.name=="BackgroundCubeMaterial"||a.material.name==="CubemapFromEquirect"||a.material.name==="EquirectangularToCubeUV")){E&&(a.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(a.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",a,a.material.name,a.material.type)));continue}switch(a.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}if(E==="color"&&a.material&&!a.object.progressive_debug_color){a.object.progressive_debug_color=!0;const w=Math.random()*16777215,p=new ze({color:w});a.object.material=p}const u=a.object;(u instanceof F||u.isMesh)&&this.updateLODs(t,e,u,s)}const o=r.transparent;for(const a of o){const u=a.object;(u instanceof F||u.isMesh)&&this.updateLODs(t,e,u,s)}const l=r.transmissive;for(const a of l){const u=a.object;(u instanceof F||u.isMesh)&&this.updateLODs(t,e,u,s)}}updateLODs(t,e,r,n){r.userData||(r.userData={});let s=r[we];if(s||(s=new mt,r[we]=s),s.frames++<2)return;for(const l of N)l.onBeforeUpdateLOD?.(this.renderer,t,e,r);const o=this.overrideLodLevel!==void 0?this.overrideLodLevel:q;o>=0?(O.mesh_lod=o,O.texture_lod=o):(this.calculateLodLevel(e,r,s,n,O),O.mesh_lod=Math.round(O.mesh_lod),O.texture_lod=Math.round(O.texture_lod)),O.mesh_lod>=0&&this.loadProgressiveMeshes(r,O.mesh_lod),r.material&&O.texture_lod>=0&&this.loadProgressiveTextures(r.material,O.texture_lod,o),h&&r.material&&!r.isGizmo&&Pe(r.material);for(const l of N)l.onAfterUpdatedLOD?.(this.renderer,t,e,r,O);s.lastLodLevel_Mesh=O.mesh_lod,s.lastLodLevel_Texture=O.texture_lod}loadProgressiveTextures(t,e,r){if(!t)return;if(Array.isArray(t)){for(const s of t)this.loadProgressiveTextures(s,e);return}let n=!1;if((t[U]===void 0||e<t[U])&&(n=!0),r!==void 0&&r>=0&&(n=t[U]!=r,e=r),n){t[U]=e;const s=m.assignTextureLOD(t,e).then(o=>{this._lodchangedlisteners.forEach(l=>l({type:"texture",level:e,object:t}))});pe.addPromise("texture",t,s,this._newPromiseGroups)}}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);let r=t[U]!==e;const n=t["DEBUG:LOD"];if(n!=null&&(r=t[U]!=n,e=n),r){t[U]=e;const s=t.geometry,o=m.assignMeshLOD(t,e).then(l=>(l&&t[U]==e&&s!=t.geometry&&this._lodchangedlisteners.forEach(a=>a({type:"mesh",level:e,object:t})),l));return pe.addPromise("mesh",t,o,this._newPromiseGroups),o}return Promise.resolve(null)}_sphere=new Le;_tempBox=new ae;_tempBox2=new ae;tempMatrix=new _e;_tempWorldPosition=new A;_tempBoxSize=new A;_tempBox2Size=new A;static corner0=new A;static corner1=new A;static corner2=new A;static corner3=new A;static _tempPtInside=new A;static isInside(t,e){const r=t.min,n=t.max,s=(r.x+n.x)*.5,o=(r.y+n.y)*.5;return this._tempPtInside.set(s,o,r.z).applyMatrix4(e).z<0}static skinnedMeshBoundsFrameOffsetCounter=0;static $skinnedMeshBoundsOffset=Symbol("gltf-progressive-skinnedMeshBoundsOffset");calculateLodLevel(t,e,r,n,s){if(!e){s.mesh_lod=-1,s.texture_lod=-1;return}if(!t){s.mesh_lod=-1,s.texture_lod=-1;return}let o=10+1,l=!1;if(E&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const a=m.getMeshLODExtension(e.geometry)?.lods,u=m.getPrimitiveIndex(e.geometry),w=a&&a.length>0,p=m.getMaterialMinMaxLODsCount(e.material),y=p.min_count!==1/0&&p.min_count>=0&&p.max_count>=0;if(!w&&!y){s.mesh_lod=0,s.texture_lod=0;return}w||(l=!0,o=0);const P=this.renderer.domElement.clientHeight||this.renderer.domElement.height;let _=e.geometry.boundingBox;if(e.type==="SkinnedMesh"){const c=e;if(!c.boundingBox)c.computeBoundingBox();else if(this.skinnedMeshAutoUpdateBoundsInterval>0){if(!c[D.$skinnedMeshBoundsOffset]){const v=D.skinnedMeshBoundsFrameOffsetCounter++;c[D.$skinnedMeshBoundsOffset]=v}const x=c[D.$skinnedMeshBoundsOffset];if((r.frames+x)%this.skinnedMeshAutoUpdateBoundsInterval===0){const v=V(c),C=c.geometry;v&&(c.geometry=v),c.computeBoundingBox(),c.geometry=C}}_=c.boundingBox}if(_){const c=t;if(e.geometry.attributes.color&&e.geometry.attributes.color.count<100&&e.geometry.boundingSphere){this._sphere.copy(e.geometry.boundingSphere),this._sphere.applyMatrix4(e.matrixWorld);const g=t.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(g)){s.mesh_lod=0,s.texture_lod=0;return}}if(this._tempBox.copy(_),this._tempBox.applyMatrix4(e.matrixWorld),c.isPerspectiveCamera&&D.isInside(this._tempBox,this.projectionScreenMatrix)){s.mesh_lod=0,s.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&c.isPerspectiveCamera&&c.fov>70){const g=this._tempBox.min,d=this._tempBox.max;let f=g.x,L=g.y,S=d.x,G=d.y;const J=2,oe=1.5,Z=(g.x+d.x)*.5,ee=(g.y+d.y)*.5;f=(f-Z)*J+Z,L=(L-ee)*J+ee,S=(S-Z)*J+Z,G=(G-ee)*J+ee;const Re=f<0&&S>0?0:Math.min(Math.abs(g.x),Math.abs(d.x)),$e=L<0&&G>0?0:Math.min(Math.abs(g.y),Math.abs(d.y)),ie=Math.max(Re,$e);r.lastCentrality=(oe-ie)*(oe-ie)*(oe-ie)}else r.lastCentrality=1;const x=this._tempBox.getSize(this._tempBoxSize);x.multiplyScalar(.5),screen.availHeight>0&&P>0&&x.multiplyScalar(P/screen.availHeight),t.isPerspectiveCamera?x.x*=t.aspect:t.isOrthographicCamera;const v=t.matrixWorldInverse,C=this._tempBox2;C.copy(_),C.applyMatrix4(e.matrixWorld),C.applyMatrix4(v);const b=C.getSize(this._tempBox2Size),R=Math.max(b.x,b.y);if(Math.max(x.x,x.y)!=0&&R!=0&&(x.z=b.z/Math.max(b.x,b.y)*Math.max(x.x,x.y)),r.lastScreenCoverage=Math.max(x.x,x.y,x.z),r.lastScreenspaceVolume.copy(x),r.lastScreenCoverage*=r.lastCentrality,E&&D.debugDrawLine){const g=this.tempMatrix.copy(this.projectionScreenMatrix);g.invert();const d=D.corner0,f=D.corner1,L=D.corner2,S=D.corner3;d.copy(this._tempBox.min),f.copy(this._tempBox.max),f.x=d.x,L.copy(this._tempBox.max),L.y=d.y,S.copy(this._tempBox.max);const G=(d.z+S.z)*.5;d.z=f.z=L.z=S.z=G,d.applyMatrix4(g),f.applyMatrix4(g),L.applyMatrix4(g),S.applyMatrix4(g),D.debugDrawLine(d,f,255),D.debugDrawLine(d,L,255),D.debugDrawLine(f,S,255),D.debugDrawLine(L,S,255)}let M=999;if(a&&r.lastScreenCoverage>0)for(let g=0;g<a.length;g++){const d=a[g],f=(d.densities?.[u]||d.density||1e-5)/r.lastScreenCoverage;if(u>0&&Te()&&!d.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.")),f<n){M=g;break}}M<o&&(o=M,l=!0)}if(l?s.mesh_lod=o:s.mesh_lod=r.lastLodLevel_Mesh,E&&s.mesh_lod!=r.lastLodLevel_Mesh){const c=a?.[s.mesh_lod];c&&console.log(`Mesh LOD changed: ${r.lastLodLevel_Mesh} \u2192 ${s.mesh_lod} (density: ${c.densities?.[u].toFixed(0)}) | ${e.name}`)}if(y){const c="saveData"in globalThis.navigator&&globalThis.navigator.saveData===!0;if(r.lastLodLevel_Texture<0){if(s.texture_lod=p.max_count-1,E){const x=p.lods[p.max_count-1];E&&console.log(`First Texture LOD ${s.texture_lod} (${x.max_height}px) - ${e.name}`)}}else{const x=r.lastScreenspaceVolume.x+r.lastScreenspaceVolume.y+r.lastScreenspaceVolume.z;let v=r.lastScreenCoverage*4;this.context?.engine==="model-viewer"&&(v*=1.5);const C=P/window.devicePixelRatio*v;let b=!1;for(let R=p.lods.length-1;R>=0;R--){const M=p.lods[R];if(!(c&&M.max_height>=2048)&&!(Se()&&M.max_height>4096)&&(M.max_height>C||!b&&R===0)){if(b=!0,s.texture_lod=R,E&&s.texture_lod<r.lastLodLevel_Texture){const g=M.max_height;console.log(`Texture LOD changed: ${r.lastLodLevel_Texture} \u2192 ${s.texture_lod} = ${g}px
|
|
8
|
+
Screensize: ${C.toFixed(0)}px, Coverage: ${(100*r.lastScreenCoverage).toFixed(2)}%, Volume ${x.toFixed(1)}
|
|
9
|
+
${e.name}`)}break}}}}else s.texture_lod=0}};class mt{frames=0;lastLodLevel_Mesh=-1;lastLodLevel_Texture=-1;lastScreenCoverage=0;lastScreenspaceVolume=new A;lastCentrality=0}const Ce=Symbol("NEEDLE_mesh_lod"),ne=Symbol("NEEDLE_texture_lod");let ye=null;function Ae(){const i=pt();i&&(i.mapURLs(function(t){return ke(),t}),ke(),ye?.disconnect(),ye=new MutationObserver(t=>{t.forEach(e=>{e.addedNodes.forEach(r=>{r instanceof HTMLElement&&r.tagName.toLowerCase()==="model-viewer"&&Ee(r)})})}),ye.observe(document,{childList:!0,subtree:!0}))}function pt(){return typeof customElements>"u"?null:customElements.get("model-viewer")||(customElements.whenDefined("model-viewer").then(()=>{console.debug("[gltf-progressive] model-viewer defined"),Ae()}),null)}function ke(){typeof document>"u"||document.querySelectorAll("model-viewer").forEach(i=>{Ee(i)})}const Ie=new WeakSet;let xt=0;function Ee(i){if(!i||Ie.has(i))return null;Ie.add(i),console.debug("[gltf-progressive] found new model-viewer..."+ ++xt+`
|
|
10
|
+
`,i.getAttribute("src"));let t=null,e=null,r=null;for(let n=i;n!=null;n=Object.getPrototypeOf(n)){const s=Object.getOwnPropertySymbols(n),o=s.find(u=>u.toString()=="Symbol(renderer)"),l=s.find(u=>u.toString()=="Symbol(scene)"),a=s.find(u=>u.toString()=="Symbol(needsRender)");!t&&o!=null&&(t=i[o].threeRenderer),!e&&l!=null&&(e=i[l]),!r&&a!=null&&(r=i[a])}if(t&&e){let n=function(){if(r){let o=0,l=setInterval(()=>{if(o++>5){clearInterval(l);return}r?.call(i)},300)}};console.debug("[gltf-progressive] setup model-viewer");const s=Q.get(t,{engine:"model-viewer"});return Q.addPlugin(new wt),s.enable(),s.addEventListener("changed",()=>{r?.call(i)}),i.addEventListener("model-visibility",o=>{o.detail.visible&&r?.call(i)}),i.addEventListener("load",()=>{n()}),()=>{s.disable()}}return null}class wt{_didWarnAboutMissingUrl=!1;onBeforeUpdateLOD(t,e,r,n){this.tryParseMeshLOD(e,n),this.tryParseTextureLOD(e,n)}getUrl(t){if(!t)return null;let e=t.getAttribute("src");return e||(e=t.src),e||(this._didWarnAboutMissingUrl||console.warn("No url found in modelviewer",t),this._didWarnAboutMissingUrl=!0),e}tryGetCurrentGLTF(t){return t._currentGLTF}tryGetCurrentModelViewer(t){return t.element}tryParseTextureLOD(t,e){if(e[ne]==!0)return;e[ne]=!0;const r=this.tryGetCurrentGLTF(t),n=this.tryGetCurrentModelViewer(t),s=this.getUrl(n);if(s&&r&&e.material){let o=function(a){if(a[ne]==!0)return;a[ne]=!0,a.userData&&(a.userData.LOD=-1);const u=Object.keys(a);for(let w=0;w<u.length;w++){const p=u[w],y=a[p];if(y?.isTexture===!0){const P=y.userData?.associations?.textures;if(P==null)continue;const _=r.parser.json.textures[P];if(!_){console.warn("Texture data not found for texture index "+P);continue}if(_?.extensions?.[B]){const c=_.extensions[B];c&&s&&m.registerTexture(s,y,c.lods.length,P,c)}}}};const l=e.material;if(Array.isArray(l))for(const a of l)o(a);else o(l)}}tryParseMeshLOD(t,e){if(e[Ce]==!0)return;e[Ce]=!0;const r=this.tryGetCurrentModelViewer(t),n=this.getUrl(r);if(!n)return;const s=e.userData?.gltfExtensions?.[B];if(s&&n){const o=e.uuid;m.registerMesh(n,o,e,0,s.lods.length,s)}}}function yt(...i){let t,e,r,n;switch(i.length){case 2:[r,e]=i,n={};break;case 3:[r,e,n]=i;break;case 4:[t,e,r,n]=i;break;default:throw new Error("Invalid arguments")}te(e),ue(r),he(r,{progressive:!0,...n?.hints}),r.register(o=>new m(o));const s=Q.get(e);return n?.enableLODsManager!==!1&&s.enable(),s}if(Ae(),!nt){const i={gltfProgressive:{useNeedleProgressive:yt,LODsManager:Q,configureLoader:he,getRaycastMesh:V,useRaycastMeshes:it}};if(!globalThis.Needle)globalThis.Needle=i;else for(const t in i)globalThis.Needle[t]=i[t]}export{Q as LODsManager,m as NEEDLE_progressive,ue as addDracoAndKTX2Loaders,he as configureLoader,te as createLoaders,V as getRaycastMesh,Me as setDracoDecoderLocation,De as setKTX2TranscoderLocation};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Vector2 as ee, Vector3 as y, Vector4 as me, Quaternion as V, PlaneGeometry as Sn, WebGLRenderer as Lr, PerspectiveCamera as ce, OrthographicCamera as au, Scene as Mi, Mesh as H, Texture as Fe, Uniform$1 as Gi, Color as re, ShaderMaterial as Xn, Box3 as Pi, ShadowMaterial as i0, Euler as ct, MeshStandardMaterial as pt, Box3Helper as Xx, GridHelper as n0, Object3D as M, Material as be, Matrix3 as s0, Matrix4 as J, Layers as wo, Ray as Es, MathUtils as Ps, AxesHelper as Oi, MeshBasicMaterial as we, DoubleSide as Ri, BufferGeometry as _n, Group as Os, CylinderGeometry as o0, SphereGeometry as lu, BoxGeometry as La, SpriteMaterial as Qx, Sprite as Yx, Shape as Kx, ExtrudeGeometry as Zx, Fog as r0, DirectionalLight as Bp, PointLight as Vm, TextureLoader as Sr, EdgesGeometry as Jx, LineSegments as a0, LineBasicMaterial as Hm, Line as Da, BufferAttribute as mt, Raycaster as cu, Sphere as hu, ArrayCamera as eS, Plane as Cr, SkinnedMesh as mo, InterleavedBufferAttribute as l0, Skeleton as tS, Bone as iS, WebGLCubeRenderTarget as nS, CubeCamera as sS, AnimationClip as ki, FileLoader as Gm, PropertyBinding as ja, KeyframeTrack as oS, LinearSRGBColorSpace as Ts, ShaderChunk as Zt, UniformsLib as rS, DataTexture as qm, RGBAFormat as du, EquirectangularReflectionMapping as Hn, SRGBColorSpace as As, Clock as aS, NeutralToneMapping as Ba, AgXToneMapping as uu, ACESFilmicToneMapping as fu, NoToneMapping as Cd, PCFSoftShadowMap$1 as lS, BasicNodeLibrary as cS, WebGLRenderTarget as Qn, DepthTexture as c0, NearestFilter as Pd, LoopRepeat as hS, LoopOnce as Fp, AnimationMixer as Xm, CompressedTexture as dS, FrontSide as xo, Camera as uS, Frustum as Ly, AudioListener as fS, PositionalAudio as pS, AudioLoader as Up, EventDispatcher as Qm, BackSide as pu, MeshDepthMaterial as mS, CustomBlending as gS, MaxEquation as yS, AlwaysStencilFunc as _S, GreaterEqualStencilFunc as bS, NotEqualStencilFunc as vS, GreaterStencilFunc as wS, LessEqualStencilFunc as xS, EqualStencilFunc as SS, LessStencilFunc as CS, NeverStencilFunc as Dy, InvertStencilOp as PS, DecrementWrapStencilOp as OS, IncrementWrapStencilOp as kS, DecrementStencilOp as MS, IncrementStencilOp as RS, ReplaceStencilOp as ES, ZeroStencilOp as TS, KeepStencilOp as AS, CubeTexture as h0, AmbientLight as IS, HemisphereLight as LS, Loader as DS, RawShaderMaterial as d0, GLSL3 as jS, AlwaysDepth as BS, GreaterEqualDepth as FS, GreaterDepth as US, LessEqualDepth as zS, LessDepth as NS, NotEqualDepth as $S, EqualDepth as WS, BatchedMesh as jy, MeshPhysicalMaterial as zp, LinearFilter as Od, UnsignedByteType as VS, RingGeometry as HS, Line3 as GS, AdditiveBlending as u0, BoxHelper as qS, SpotLight as XS, DirectionalLightHelper as QS, CameraHelper as YS, LOD as KS, Triangle as ZS, NormalBlending as JS, ReinhardToneMapping as Ym, LinearToneMapping as Km, HalfFloatType as xf, VideoTexture as eC, CubeUVReflectionMapping as f0, CompressedCubeTexture as tC, EquirectangularRefractionMapping as iC, CatmullRomCurve3 as nC, VectorKeyframeTrack as sC, QuaternionKeyframeTrack as oC, Audio as rC, ShaderLib as kd, UniformsUtils as p0, MirroredRepeatWrapping as By, MeshNormalMaterial as aC, AudioContext as lC, PMREMGenerator$1 as cC } from "./three-VvRoMeIN.js";
|
|
2
|
-
import { createLoaders as Zm, getRaycastMesh as m0, LODsManager as Xo, NEEDLE_progressive as We, addDracoAndKTX2Loaders as hC, configureLoader as dC, setKTX2TranscoderLocation as uC, setDracoDecoderLocation as fC } from "./gltf-progressive-
|
|
2
|
+
import { createLoaders as Zm, getRaycastMesh as m0, LODsManager as Xo, NEEDLE_progressive as We, addDracoAndKTX2Loaders as hC, configureLoader as dC, setKTX2TranscoderLocation as uC, setDracoDecoderLocation as fC } from "./gltf-progressive-Dbi_Tfhb.js";
|
|
3
3
|
import { GroundedSkybox as Fa, Font as pC, TextGeometry as mC, FontLoader as gC, GLTFLoader as Is, TransformControlsGizmo as g0, EXRLoader as Jm, RGBELoader as y0, Stats as yC, nodeFrame as Fy, OrbitControls as _0, PositionalAudioHelper as _C, HorizontalBlurShader as bC, VerticalBlurShader as vC, GLTFExporter as b0, strToU8 as v0, zipSync as wC, XRControllerModelFactory as xC, XRHandMeshModel as SC, Line2 as CC, LineGeometry as PC, LineMaterial as OC, TransformControls as kC, InteractiveGroup as MC, HTMLMesh as RC, VertexNormalsHelper as EC, OBJLoader as eg, FBXLoader as w0, mergeVertices as TC } from "./three-examples-BhfOE7NG.js";
|
|
4
4
|
import { fetchProfile as AC, MotionController as IC, $70d766613f57b014$export$2e2bcd8739ae039 as Uy, ByteBuffer as LC, v5 as zy, md5 as Ny, SIZE_PREFIX_LENGTH as x0, Builder as tg, createNoise4D as DC, Matrix4 as Sf, BatchedParticleRenderer as jC, ParticleSystem as BC, RenderMode as gs, ConstantColor as FC, Vector4 as UC, ConstantValue as zC, TrailParticle as $y, WorkerBase as NC, MeshBVH as $C } from "./vendor-BiyIZ61v.js";
|
|
5
5
|
import { __webpack_exports__default as Ce, __webpack_exports__Text as S0, __webpack_exports__Block as C0, __webpack_exports__update as WC, SimpleStateBehavior as VC, __webpack_exports__Inline as Cf, __webpack_exports__FontLibrary as Wy, ThreeMeshUI as Vy } from "./three-mesh-ui-CcMp-FQm.js";
|
|
@@ -1965,9 +1965,9 @@ Oo('if(!globalThis["NEEDLE_PROJECT_BUILD_TIME"]) globalThis["NEEDLE_PROJECT_BUIL
|
|
|
1965
1965
|
Oo('if(!globalThis["NEEDLE_PUBLIC_KEY"]) globalThis["NEEDLE_PUBLIC_KEY"] = "unknown";');
|
|
1966
1966
|
Oo('globalThis["__NEEDLE_ENGINE_VERSION__"] = "4.13.1";');
|
|
1967
1967
|
Oo('globalThis["__NEEDLE_ENGINE_GENERATOR__"] = "undefined";');
|
|
1968
|
-
Oo('globalThis["__NEEDLE_PROJECT_BUILD_TIME__"] = "Mon Feb 16 2026
|
|
1968
|
+
Oo('globalThis["__NEEDLE_PROJECT_BUILD_TIME__"] = "Mon Feb 16 2026 14:46:26 GMT+0000 (Coordinated Universal Time)";');
|
|
1969
1969
|
Oo('globalThis["__NEEDLE_PUBLIC_KEY__"] = "' + NEEDLE_PUBLIC_KEY + '";');
|
|
1970
|
-
const Xi = "4.13.1", Rc = "undefined", Ad = "Mon Feb 16 2026
|
|
1970
|
+
const Xi = "4.13.1", Rc = "undefined", Ad = "Mon Feb 16 2026 14:46:26 GMT+0000 (Coordinated Universal Time)";
|
|
1971
1971
|
q0 && console.log(`Engine version: ${Xi} (generator: ${Rc})
|
|
1972
1972
|
Project built at ${Ad}`);
|
|
1973
1973
|
const ur = NEEDLE_PUBLIC_KEY, yo = "needle_isActiveInHierarchy", ca = "builtin_components", rd = "needle_editor_guid";
|