@needle-tools/gltf-progressive 3.0.0-alpha.1 → 3.0.0-alpha.2
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/gltf-progressive.js +1 -1
- package/gltf-progressive.min.js +1 -1
- package/gltf-progressive.umd.cjs +5 -5
- package/lib/lods.manager.d.ts +1 -1
- package/lib/lods.manager.js +1 -1
- package/lib/{lods.loading.js → lods.promise.js} +1 -1
- package/lib/version.js +1 -1
- package/package.json +1 -1
- /package/lib/{lods.loading.d.ts → lods.promise.d.ts} +0 -0
package/gltf-progressive.js
CHANGED
|
@@ -578,7 +578,7 @@ class ye {
|
|
|
578
578
|
d(this, "_awaiting", []);
|
|
579
579
|
d(this, "_currentFrame", 0);
|
|
580
580
|
var i;
|
|
581
|
-
const
|
|
581
|
+
const o = Math.max(e.frames ?? 2, 2);
|
|
582
582
|
this.frame_start = t, this.frame_capture_end = t + o, this.ready = new Promise((r) => {
|
|
583
583
|
this._resolve = r;
|
|
584
584
|
}), this.ready.finally(() => {
|
package/gltf-progressive.min.js
CHANGED
|
@@ -2,7 +2,7 @@ var Ye=Object.defineProperty,Je=(t,e,r)=>e in t?Ye(t,e,{enumerable:!0,configurab
|
|
|
2
2
|
`,f),null)),p=!1;if(x==null||(x instanceof re&&t instanceof re?(o=x.image)!=null&&o.data||(s=x.source)!=null&&s.data?x=this.copySettings(t,x):(p=!0,this.previouslyLoaded.delete(m)):x instanceof ue&&t instanceof ue&&((n=x.attributes.position)!=null&&n.array||(p=!0,this.previouslyLoaded.delete(m)))),!p)return x}const b=a,G=new Promise(async(x,p)=>{const f=new xe;_e(f),L&&(await new Promise(w=>setTimeout(w,1e3)),i&&console.warn("Start loading (delayed) "+y,b.guid));let F=y;if(b&&Array.isArray(b.lods)){const w=b.lods[e];w.hash&&(F+="?v="+w.hash)}const D=await f.loadAsync(F).catch(w=>(console.error(`Error loading LOD ${e} from ${y}
|
|
3
3
|
`,w),null));if(!D)return null;const R=D.parser;i&&console.log("Loading finished "+y,b.guid);let O=0;if(D.parser.json.textures){let w=!1;for(const c of D.parser.json.textures){if(c!=null&&c.extensions){const g=c?.extensions[W];if(g!=null&&g.guid&&g.guid===b.guid){w=!0;break}}O++}if(w){let c=await R.getDependency("texture",O);return c&&M.assignLODInformation(l.url,c,u,e,void 0),i&&console.log('change "'+t.name+'" \u2192 "'+c.name+'"',y,O,c,m),t instanceof re&&(c=this.copySettings(t,c)),c&&(c.guid=b.guid),x(c)}else L&&console.warn("Could not find texture with guid",b.guid,D.parser.json)}if(O=0,D.parser.json.meshes){let w=!1;for(const c of D.parser.json.meshes){if(c!=null&&c.extensions){const g=c?.extensions[W];if(g!=null&&g.guid&&g.guid===b.guid){w=!0;break}}O++}if(w){const c=await R.getDependency("mesh",O);if(i&&console.log(`Loaded Mesh "${c.name}"`,y,O,c,m),c.isMesh===!0){const g=c.geometry;return M.assignLODInformation(l.url,g,u,e,0),x(g)}else{const g=new Array;for(let S=0;S<c.children.length;S++){const C=c.children[S];if(C.isMesh===!0){const I=C.geometry;M.assignLODInformation(l.url,I,u,e,S),g.push(I)}}return x(g)}}else L&&console.warn("Could not find mesh with guid",b.guid,D.parser.json)}return x(null)});return this.previouslyLoaded.set(m,G),await G}else if(t instanceof re){i&&console.log("Load texture from uri: "+y);const m=await new Qe().loadAsync(y);return m?(m.guid=a.guid,m.flipY=!1,m.needsUpdate=!0,m.colorSpace=t.colorSpace,i&&console.log(a,m)):L&&console.warn("failed loading",y),m}}else L&&console.warn(`Can not load LOD ${e}: no LOD info found for "${u}" ${t.name}`,t.type);return null}static assignLODInformation(t,e,r,o,s){if(!e)return;e.userData||(e.userData={});const n=new gt(t,r,o,s);e.userData.LODS=n}static getAssignedLODInformation(t){var e;return((e=t?.userData)==null?void 0:e.LODS)||null}static copySettings(t,e){return e?(L&&console.warn(`Copy texture settings
|
|
4
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}};let T=M;d(T,"registerTexture",(t,e,r,o,s)=>{if(L&&console.log("> Progressive: register texture",o,e.name,e.uuid,e,s),!e){L&&console.error("gltf-progressive: Register texture without texture");return}e.source&&(e.source[Oe]=s);const n=s.guid;M.assignLODInformation(t,e,n,r,o),M.lodInfos.set(n,s),M.lowresCache.set(n,e)}),d(T,"registerMesh",(t,e,r,o,s,n)=>{var i;const l=r.geometry;if(!l){L&&console.warn("gltf-progressive: Register mesh without geometry");return}l.userData||(l.userData={}),L&&console.log("> Progressive: register mesh "+r.name,{index:s,uuid:r.uuid},n,r),M.assignLODInformation(t,l,e,o,s),M.lodInfos.set(e,n);let u=M.lowresCache.get(e);u?u.push(r.geometry):u=[r.geometry],M.lowresCache.set(e,u),o>0&&!ee(r)&&$e(r,l);for(const a of V)(i=a.onRegisteredNewMesh)==null||i.call(a,r,n)}),d(T,"lodInfos",new Map),d(T,"previouslyLoaded",new Map),d(T,"lowresCache",new Map);class gt{constructor(e,r,o,s){d(this,"url"),d(this,"key"),d(this,"level"),d(this,"index"),this.url=e,this.key=r,this.level=o,s!=null&&(this.index=s)}}class ge{constructor(e,r){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,"_currentFrame",0);var o;const s=e===0?2:1,n=Math.max(r.frames??s,s);this.frame_start=e,this.frame_capture_end=e+n,this.ready=new Promise(i=>{this._resolve=i}),this.ready.finally(()=>{this._resolved=!0,this._awaiting.length=0}),this._signal=r.signal,(o=this._signal)==null||o.addEventListener("abort",()=>{this.resolveNow()})}get awaitedCount(){return this._addedCount}get resolvedCount(){return this._resolvedCount}get currentlyAwaiting(){return this._awaiting.length}update(e){var r;this._currentFrame=e,((r=this._signal)!=null&&r.aborted||this._currentFrame>this.frame_capture_end&&this._awaiting.length===0)&&this.resolveNow()}add(e,r){if(this._resolved){console.warn("PromiseGroup: Trying to add a promise to a resolved group, ignoring.");return}this._currentFrame>this.frame_capture_end||(this._awaiting.push(r),this._addedCount++,r.finally(()=>{this._resolvedCount++,this._awaiting.splice(this._awaiting.indexOf(r),1)}))}resolveNow(){var e,r;this._resolved||(r=this._resolve)==null||r.call(this,{awaited_count:this._addedCount,resolved_count:this._resolvedCount,cancelled:((e=this._signal)==null?void 0:e.aborted)??!1})}}d(ge,"addPromise",(t,e,r)=>{r.forEach(o=>{o.add(t,e)})});const N=se("debugprogressive"),ft=se("noprogressive"),Se=Symbol("Needle:LODSManager"),Te=Symbol("Needle:LODState"),q=Symbol("Needle:CurrentLOD"),P={mesh_lod:-1,texture_lod:-1};var A,X,Pe,K,ne,fe,H;const E=class{constructor(t,e){d(this,"renderer"),d(this,"context"),d(this,"projectionScreenMatrix",new Ce),d(this,"targetTriangleDensity",2e5),d(this,"skinnedMeshAutoUpdateBoundsInterval",30),d(this,"updateInterval","auto"),Y(this,A,1),d(this,"pause",!1),d(this,"manual",!1),d(this,"_newPromiseGroups",[]),d(this,"_promiseGroupIds",0),d(this,"_lodchangedlisteners",[]),Y(this,X,void 0),Y(this,Pe,new Ze),Y(this,K,0),Y(this,ne,0),Y(this,fe,0),Y(this,H,0),d(this,"_fpsBuffer",[60,60,60,60,60]),d(this,"_sphere",new tt),d(this,"_tempBox",new Ie),d(this,"_tempBox2",new Ie),d(this,"tempMatrix",new Ce),d(this,"_tempWorldPosition",new z),d(this,"_tempBoxSize",new z),d(this,"_tempBox2Size",new z),this.renderer=t,this.context={...e}}static getObjectLODState(t){return t[Te]}static addPlugin(t){V.push(t)}static removePlugin(t){const e=V.indexOf(t);e>=0&&V.splice(e,1)}static get(t,e){if(t[Se])return console.debug("[gltf-progressive] LODsManager already exists for this renderer"),t[Se];const r=new E(t,{engine:"unknown",...e});return t[Se]=r,r}get plugins(){return V}awaitLoading(t){const e=this._promiseGroupIds++,r=new ge(v(this,K),{...t});this._newPromiseGroups.push(r);const o=performance.now();return r.ready.finally(()=>{const s=this._newPromiseGroups.indexOf(r);s>=0&&(this._newPromiseGroups.splice(s,1),dt()&&performance.measure("LODsManager:awaitLoading",{start:o,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(v(this,K))}addEventListener(t,e){t==="changed"&&this._lodchangedlisteners.push(e)}removeEventListener(t,e){if(t==="changed"){const r=this._lodchangedlisteners.indexOf(e);r>=0&&this._lodchangedlisteners.splice(r,1)}}enable(){if(v(this,X))return;console.debug("[gltf-progressive] Enabling LODsManager for renderer");let t=0;U(this,X,this.renderer.render);const e=this;we(this.renderer),this.renderer.render=function(r,o){const s=e.renderer.getRenderTarget();(s==null||"isXRRenderTarget"in s&&s.isXRRenderTarget)&&(t=0,U(e,K,v(e,K)+1),U(e,ne,v(e,Pe).getDelta()),U(e,fe,v(e,fe)+v(e,ne)),e._fpsBuffer.shift(),e._fpsBuffer.push(1/v(e,ne)),U(e,H,e._fpsBuffer.reduce((i,l)=>i+l)/e._fpsBuffer.length),N&&v(e,K)%200===0&&console.log("FPS",Math.round(v(e,H)),"Interval:",v(e,A)));const n=t++;v(e,X).call(this,r,o),e.onAfterRender(r,o,n)}}disable(){v(this,X)&&(console.debug("[gltf-progressive] Disabling LODsManager for renderer"),this.renderer.render=v(this,X),U(this,X,void 0))}update(t,e){this.internalUpdate(t,e)}onAfterRender(t,e,r){if(this.pause)return;const o=this.renderer.renderLists.get(t,0).opaque;let s=!0;if(o.length===1){const n=o[0].material;(n.name==="EffectMaterial"||n.name==="CopyShader")&&(s=!1)}if((e.parent&&e.parent.type==="CubeCamera"||r>=1&&e.type==="OrthographicCamera")&&(s=!1),s){if(ft||(this.updateInterval==="auto"?v(this,H)<40&&v(this,A)<10?(U(this,A,v(this,A)+1),N&&console.warn("\u2193 Reducing LOD updates",v(this,A),v(this,H).toFixed(0))):v(this,H)>=60&&v(this,A)>1&&(U(this,A,v(this,A)-1),N&&console.warn("\u2191 Increasing LOD updates",v(this,A),v(this,H).toFixed(0))):U(this,A,this.updateInterval),v(this,A)>0&&v(this,K)%v(this,A)!=0))return;this.internalUpdate(t,e),this._postprocessPromiseGroups()}}internalUpdate(t,e){var r,o;const s=this.renderer.renderLists.get(t,0),n=s.opaque;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse);const i=this.targetTriangleDensity;for(const a of n){if(a.material&&(((r=a.geometry)==null?void 0:r.type)==="BoxGeometry"||((o=a.geometry)==null?void 0:o.type)==="BufferGeometry")&&(a.material.name==="SphericalGaussianBlur"||a.material.name=="BackgroundCubeMaterial"||a.material.name==="CubemapFromEquirect"||a.material.name==="EquirectangularToCubeUV")){N&&(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(N==="color"&&a.material&&!a.object.progressive_debug_color){a.object.progressive_debug_color=!0;const y=Math.random()*16777215,m=new et({color:y});a.object.material=m}const h=a.object;(h instanceof J||h.isMesh)&&this.updateLODs(t,e,h,i)}const l=s.transparent;for(const a of l){const h=a.object;(h instanceof J||h.isMesh)&&this.updateLODs(t,e,h,i)}const u=s.transmissive;for(const a of u){const h=a.object;(h instanceof J||h.isMesh)&&this.updateLODs(t,e,h,i)}}updateLODs(t,e,r,o){var s,n;r.userData||(r.userData={});let i=r[Te];if(i||(i=new mt,r[Te]=i),i.frames++<2)return;for(const u of V)(s=u.onBeforeUpdateLOD)==null||s.call(u,this.renderer,t,e,r);const l=E.overrideGlobalLodLevel!==void 0?E.overrideGlobalLodLevel:Q;l>=0?(P.mesh_lod=l,P.texture_lod=l):(this.calculateLodLevel(e,r,i,o,P),P.mesh_lod=Math.round(P.mesh_lod),P.texture_lod=Math.round(P.texture_lod)),P.mesh_lod>=0&&this.loadProgressiveMeshes(r,P.mesh_lod),r.material&&P.texture_lod>=0&&this.loadProgressiveTextures(r.material,P.texture_lod),L&&r.material&&!r.isGizmo&&Fe(r.material);for(const u of V)(n=u.onAfterUpdatedLOD)==null||n.call(u,this.renderer,t,e,r,P);i.lastLodLevel_Mesh=P.mesh_lod,i.lastLodLevel_Texture=P.texture_lod}loadProgressiveTextures(t,e){if(!t)return;if(Array.isArray(t)){for(const s of t)this.loadProgressiveTextures(s,e);return}let r=!1;(t[q]===void 0||e<t[q])&&(r=!0);const o=t["DEBUG:LOD"];if(o!=null&&(r=t[q]!=o,e=o),r){t[q]=e;const s=T.assignTextureLOD(t,e).then(n=>{this._lodchangedlisteners.forEach(i=>i({type:"texture",level:e,object:t}))});ge.addPromise("texture",s,this._newPromiseGroups)}}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);let r=t[q]!==e;const o=t["DEBUG:LOD"];if(o!=null&&(r=t[q]!=o,e=o),r){t[q]=e;const s=t.geometry,n=T.assignMeshLOD(t,e).then(i=>(i&&t[q]==e&&s!=t.geometry&&this._lodchangedlisteners.forEach(l=>l({type:"mesh",level:e,object:t})),i));return ge.addPromise("mesh",n,this._newPromiseGroups),n}return Promise.resolve(null)}static isInside(t,e){const r=t.min,o=t.max,s=(r.x+o.x)*.5,n=(r.y+o.y)*.5;return this._tempPtInside.set(s,n,r.z).applyMatrix4(e).z<0}calculateLodLevel(t,e,r,o,s){var n,i,l;if(!e){s.mesh_lod=-1,s.texture_lod=-1;return}if(!t){s.mesh_lod=-1,s.texture_lod=-1;return}let u=10+1,a=!1;if(N&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const h=(n=T.getMeshLODExtension(e.geometry))==null?void 0:n.lods,y=T.getPrimitiveIndex(e.geometry),m=h&&h.length>0,_=T.getMaterialMinMaxLODsCount(e.material),b=_?.min_count!=1/0&&_.min_count>0&&_.max_count>0;if(!m&&!b){s.mesh_lod=0,s.texture_lod=0;return}m||(a=!0,u=0);const G=this.renderer.domElement.clientHeight||this.renderer.domElement.height;let x=e.geometry.boundingBox;if(e.type==="SkinnedMesh"){const p=e;if(!p.boundingBox)p.computeBoundingBox();else if(this.skinnedMeshAutoUpdateBoundsInterval>0&&r.frames%this.skinnedMeshAutoUpdateBoundsInterval===0){const f=ee(p),F=p.geometry;f&&(p.geometry=f),p.computeBoundingBox(),p.geometry=F}x=p.boundingBox}if(x){const p=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 c=t.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(c)){s.mesh_lod=0,s.texture_lod=0;return}}if(this._tempBox.copy(x),this._tempBox.applyMatrix4(e.matrixWorld),p.isPerspectiveCamera&&E.isInside(this._tempBox,this.projectionScreenMatrix)){s.mesh_lod=0,s.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&p.isPerspectiveCamera&&p.fov>70){const c=this._tempBox.min,g=this._tempBox.max;let S=c.x,C=c.y,I=g.x,te=g.y;const ie=2,ve=1.5,ae=(c.x+g.x)*.5,le=(c.y+g.y)*.5;S=(S-ae)*ie+ae,C=(C-le)*ie+le,I=(I-ae)*ie+ae,te=(te-le)*ie+le;const Ke=S<0&&I>0?0:Math.min(Math.abs(c.x),Math.abs(g.x)),He=C<0&&te>0?0:Math.min(Math.abs(c.y),Math.abs(g.y)),ye=Math.max(Ke,He);r.lastCentrality=(ve-ye)*(ve-ye)*(ve-ye)}else r.lastCentrality=1;const f=this._tempBox.getSize(this._tempBoxSize);f.multiplyScalar(.5),screen.availHeight>0&&G>0&&f.multiplyScalar(G/screen.availHeight),t.isPerspectiveCamera?f.x*=t.aspect:t.isOrthographicCamera;const F=t.matrixWorldInverse,D=this._tempBox2;D.copy(x),D.applyMatrix4(e.matrixWorld),D.applyMatrix4(F);const R=D.getSize(this._tempBox2Size),O=Math.max(R.x,R.y);if(Math.max(f.x,f.y)!=0&&O!=0&&(f.z=R.z/Math.max(R.x,R.y)*Math.max(f.x,f.y)),r.lastScreenCoverage=Math.max(f.x,f.y,f.z),r.lastScreenspaceVolume.copy(f),r.lastScreenCoverage*=r.lastCentrality,N&&E.debugDrawLine){const c=this.tempMatrix.copy(this.projectionScreenMatrix);c.invert();const g=E.corner0,S=E.corner1,C=E.corner2,I=E.corner3;g.copy(this._tempBox.min),S.copy(this._tempBox.max),S.x=g.x,C.copy(this._tempBox.max),C.y=g.y,I.copy(this._tempBox.max);const te=(g.z+I.z)*.5;g.z=S.z=C.z=I.z=te,g.applyMatrix4(c),S.applyMatrix4(c),C.applyMatrix4(c),I.applyMatrix4(c),E.debugDrawLine(g,S,255),E.debugDrawLine(g,C,255),E.debugDrawLine(S,I,255),E.debugDrawLine(C,I,255)}let w=999;if(h&&r.lastScreenCoverage>0)for(let c=0;c<h.length;c++){const g=h[c];if((((i=g.densities)==null?void 0:i[y])||g.density||1e-5)/r.lastScreenCoverage<o){w=c;break}}w<u&&(u=w,a=!0)}if(a?s.mesh_lod=u:s.mesh_lod=r.lastLodLevel_Mesh,N&&s.mesh_lod!=r.lastLodLevel_Mesh){const p=h?.[s.mesh_lod];p&&console.log(`Mesh LOD changed: ${r.lastLodLevel_Mesh} \u2192 ${s.mesh_lod} (${p.density.toFixed(0)}) - ${e.name}`)}if(b){const p="saveData"in globalThis.navigator&&globalThis.navigator.saveData===!0;if(r.lastLodLevel_Texture<0){if(s.texture_lod=_.max_count-1,N){const f=_.lods[_.max_count-1];N&&console.log(`First Texture LOD ${s.texture_lod} (${f.max_height}px) - ${e.name}`)}}else{const f=r.lastScreenspaceVolume.x+r.lastScreenspaceVolume.y+r.lastScreenspaceVolume.z;let F=r.lastScreenCoverage*4;((l=this.context)==null?void 0:l.engine)==="model-viewer"&&(F*=1.5);const D=G/window.devicePixelRatio*F;let R=!1;for(let O=_.lods.length-1;O>=0;O--){const w=_.lods[O];if(!(p&&w.max_height>=2048)&&!(ut()&&w.max_height>4096)&&(w.max_height>D||!R&&O===0)){if(R=!0,s.texture_lod=O,s.texture_lod<r.lastLodLevel_Texture){const c=w.max_height;N&&console.log(`Texture LOD changed: ${r.lastLodLevel_Texture} \u2192 ${s.texture_lod} = ${c}px
|
|
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}};let T=M;d(T,"registerTexture",(t,e,r,o,s)=>{if(L&&console.log("> Progressive: register texture",o,e.name,e.uuid,e,s),!e){L&&console.error("gltf-progressive: Register texture without texture");return}e.source&&(e.source[Oe]=s);const n=s.guid;M.assignLODInformation(t,e,n,r,o),M.lodInfos.set(n,s),M.lowresCache.set(n,e)}),d(T,"registerMesh",(t,e,r,o,s,n)=>{var i;const l=r.geometry;if(!l){L&&console.warn("gltf-progressive: Register mesh without geometry");return}l.userData||(l.userData={}),L&&console.log("> Progressive: register mesh "+r.name,{index:s,uuid:r.uuid},n,r),M.assignLODInformation(t,l,e,o,s),M.lodInfos.set(e,n);let u=M.lowresCache.get(e);u?u.push(r.geometry):u=[r.geometry],M.lowresCache.set(e,u),o>0&&!ee(r)&&$e(r,l);for(const a of V)(i=a.onRegisteredNewMesh)==null||i.call(a,r,n)}),d(T,"lodInfos",new Map),d(T,"previouslyLoaded",new Map),d(T,"lowresCache",new Map);class gt{constructor(e,r,o,s){d(this,"url"),d(this,"key"),d(this,"level"),d(this,"index"),this.url=e,this.key=r,this.level=o,s!=null&&(this.index=s)}}class ge{constructor(e,r){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,"_currentFrame",0);var o;const s=Math.max(r.frames??2,2);this.frame_start=e,this.frame_capture_end=e+s,this.ready=new Promise(n=>{this._resolve=n}),this.ready.finally(()=>{this._resolved=!0,this._awaiting.length=0}),this._signal=r.signal,(o=this._signal)==null||o.addEventListener("abort",()=>{this.resolveNow()})}get awaitedCount(){return this._addedCount}get resolvedCount(){return this._resolvedCount}get currentlyAwaiting(){return this._awaiting.length}update(e){var r;this._currentFrame=e,((r=this._signal)!=null&&r.aborted||this._currentFrame>this.frame_capture_end&&this._awaiting.length===0)&&this.resolveNow()}add(e,r){if(this._resolved){console.warn("PromiseGroup: Trying to add a promise to a resolved group, ignoring.");return}this._currentFrame>this.frame_capture_end||(this._awaiting.push(r),this._addedCount++,r.finally(()=>{this._resolvedCount++,this._awaiting.splice(this._awaiting.indexOf(r),1)}))}resolveNow(){var e,r;this._resolved||(r=this._resolve)==null||r.call(this,{awaited_count:this._addedCount,resolved_count:this._resolvedCount,cancelled:((e=this._signal)==null?void 0:e.aborted)??!1})}}d(ge,"addPromise",(t,e,r)=>{r.forEach(o=>{o.add(t,e)})});const N=se("debugprogressive"),ft=se("noprogressive"),Se=Symbol("Needle:LODSManager"),Te=Symbol("Needle:LODState"),q=Symbol("Needle:CurrentLOD"),P={mesh_lod:-1,texture_lod:-1};var A,X,Pe,K,ne,fe,H;const E=class{constructor(t,e){d(this,"renderer"),d(this,"context"),d(this,"projectionScreenMatrix",new Ce),d(this,"targetTriangleDensity",2e5),d(this,"skinnedMeshAutoUpdateBoundsInterval",30),d(this,"updateInterval","auto"),Y(this,A,1),d(this,"pause",!1),d(this,"manual",!1),d(this,"_newPromiseGroups",[]),d(this,"_promiseGroupIds",0),d(this,"_lodchangedlisteners",[]),Y(this,X,void 0),Y(this,Pe,new Ze),Y(this,K,0),Y(this,ne,0),Y(this,fe,0),Y(this,H,0),d(this,"_fpsBuffer",[60,60,60,60,60]),d(this,"_sphere",new tt),d(this,"_tempBox",new Ie),d(this,"_tempBox2",new Ie),d(this,"tempMatrix",new Ce),d(this,"_tempWorldPosition",new z),d(this,"_tempBoxSize",new z),d(this,"_tempBox2Size",new z),this.renderer=t,this.context={...e}}static getObjectLODState(t){return t[Te]}static addPlugin(t){V.push(t)}static removePlugin(t){const e=V.indexOf(t);e>=0&&V.splice(e,1)}static get(t,e){if(t[Se])return console.debug("[gltf-progressive] LODsManager already exists for this renderer"),t[Se];const r=new E(t,{engine:"unknown",...e});return t[Se]=r,r}get plugins(){return V}awaitLoading(t){const e=this._promiseGroupIds++,r=new ge(v(this,K),{...t});this._newPromiseGroups.push(r);const o=performance.now();return r.ready.finally(()=>{const s=this._newPromiseGroups.indexOf(r);s>=0&&(this._newPromiseGroups.splice(s,1),dt()&&performance.measure("LODsManager:awaitLoading",{start:o,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(v(this,K))}addEventListener(t,e){t==="changed"&&this._lodchangedlisteners.push(e)}removeEventListener(t,e){if(t==="changed"){const r=this._lodchangedlisteners.indexOf(e);r>=0&&this._lodchangedlisteners.splice(r,1)}}enable(){if(v(this,X))return;console.debug("[gltf-progressive] Enabling LODsManager for renderer");let t=0;U(this,X,this.renderer.render);const e=this;we(this.renderer),this.renderer.render=function(r,o){const s=e.renderer.getRenderTarget();(s==null||"isXRRenderTarget"in s&&s.isXRRenderTarget)&&(t=0,U(e,K,v(e,K)+1),U(e,ne,v(e,Pe).getDelta()),U(e,fe,v(e,fe)+v(e,ne)),e._fpsBuffer.shift(),e._fpsBuffer.push(1/v(e,ne)),U(e,H,e._fpsBuffer.reduce((i,l)=>i+l)/e._fpsBuffer.length),N&&v(e,K)%200===0&&console.log("FPS",Math.round(v(e,H)),"Interval:",v(e,A)));const n=t++;v(e,X).call(this,r,o),e.onAfterRender(r,o,n)}}disable(){v(this,X)&&(console.debug("[gltf-progressive] Disabling LODsManager for renderer"),this.renderer.render=v(this,X),U(this,X,void 0))}update(t,e){this.internalUpdate(t,e)}onAfterRender(t,e,r){if(this.pause)return;const o=this.renderer.renderLists.get(t,0).opaque;let s=!0;if(o.length===1){const n=o[0].material;(n.name==="EffectMaterial"||n.name==="CopyShader")&&(s=!1)}if((e.parent&&e.parent.type==="CubeCamera"||r>=1&&e.type==="OrthographicCamera")&&(s=!1),s){if(ft||(this.updateInterval==="auto"?v(this,H)<40&&v(this,A)<10?(U(this,A,v(this,A)+1),N&&console.warn("\u2193 Reducing LOD updates",v(this,A),v(this,H).toFixed(0))):v(this,H)>=60&&v(this,A)>1&&(U(this,A,v(this,A)-1),N&&console.warn("\u2191 Increasing LOD updates",v(this,A),v(this,H).toFixed(0))):U(this,A,this.updateInterval),v(this,A)>0&&v(this,K)%v(this,A)!=0))return;this.internalUpdate(t,e),this._postprocessPromiseGroups()}}internalUpdate(t,e){var r,o;const s=this.renderer.renderLists.get(t,0),n=s.opaque;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse);const i=this.targetTriangleDensity;for(const a of n){if(a.material&&(((r=a.geometry)==null?void 0:r.type)==="BoxGeometry"||((o=a.geometry)==null?void 0:o.type)==="BufferGeometry")&&(a.material.name==="SphericalGaussianBlur"||a.material.name=="BackgroundCubeMaterial"||a.material.name==="CubemapFromEquirect"||a.material.name==="EquirectangularToCubeUV")){N&&(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(N==="color"&&a.material&&!a.object.progressive_debug_color){a.object.progressive_debug_color=!0;const y=Math.random()*16777215,m=new et({color:y});a.object.material=m}const h=a.object;(h instanceof J||h.isMesh)&&this.updateLODs(t,e,h,i)}const l=s.transparent;for(const a of l){const h=a.object;(h instanceof J||h.isMesh)&&this.updateLODs(t,e,h,i)}const u=s.transmissive;for(const a of u){const h=a.object;(h instanceof J||h.isMesh)&&this.updateLODs(t,e,h,i)}}updateLODs(t,e,r,o){var s,n;r.userData||(r.userData={});let i=r[Te];if(i||(i=new mt,r[Te]=i),i.frames++<2)return;for(const u of V)(s=u.onBeforeUpdateLOD)==null||s.call(u,this.renderer,t,e,r);const l=E.overrideGlobalLodLevel!==void 0?E.overrideGlobalLodLevel:Q;l>=0?(P.mesh_lod=l,P.texture_lod=l):(this.calculateLodLevel(e,r,i,o,P),P.mesh_lod=Math.round(P.mesh_lod),P.texture_lod=Math.round(P.texture_lod)),P.mesh_lod>=0&&this.loadProgressiveMeshes(r,P.mesh_lod),r.material&&P.texture_lod>=0&&this.loadProgressiveTextures(r.material,P.texture_lod),L&&r.material&&!r.isGizmo&&Fe(r.material);for(const u of V)(n=u.onAfterUpdatedLOD)==null||n.call(u,this.renderer,t,e,r,P);i.lastLodLevel_Mesh=P.mesh_lod,i.lastLodLevel_Texture=P.texture_lod}loadProgressiveTextures(t,e){if(!t)return;if(Array.isArray(t)){for(const s of t)this.loadProgressiveTextures(s,e);return}let r=!1;(t[q]===void 0||e<t[q])&&(r=!0);const o=t["DEBUG:LOD"];if(o!=null&&(r=t[q]!=o,e=o),r){t[q]=e;const s=T.assignTextureLOD(t,e).then(n=>{this._lodchangedlisteners.forEach(i=>i({type:"texture",level:e,object:t}))});ge.addPromise("texture",s,this._newPromiseGroups)}}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);let r=t[q]!==e;const o=t["DEBUG:LOD"];if(o!=null&&(r=t[q]!=o,e=o),r){t[q]=e;const s=t.geometry,n=T.assignMeshLOD(t,e).then(i=>(i&&t[q]==e&&s!=t.geometry&&this._lodchangedlisteners.forEach(l=>l({type:"mesh",level:e,object:t})),i));return ge.addPromise("mesh",n,this._newPromiseGroups),n}return Promise.resolve(null)}static isInside(t,e){const r=t.min,o=t.max,s=(r.x+o.x)*.5,n=(r.y+o.y)*.5;return this._tempPtInside.set(s,n,r.z).applyMatrix4(e).z<0}calculateLodLevel(t,e,r,o,s){var n,i,l;if(!e){s.mesh_lod=-1,s.texture_lod=-1;return}if(!t){s.mesh_lod=-1,s.texture_lod=-1;return}let u=10+1,a=!1;if(N&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const h=(n=T.getMeshLODExtension(e.geometry))==null?void 0:n.lods,y=T.getPrimitiveIndex(e.geometry),m=h&&h.length>0,_=T.getMaterialMinMaxLODsCount(e.material),b=_?.min_count!=1/0&&_.min_count>0&&_.max_count>0;if(!m&&!b){s.mesh_lod=0,s.texture_lod=0;return}m||(a=!0,u=0);const G=this.renderer.domElement.clientHeight||this.renderer.domElement.height;let x=e.geometry.boundingBox;if(e.type==="SkinnedMesh"){const p=e;if(!p.boundingBox)p.computeBoundingBox();else if(this.skinnedMeshAutoUpdateBoundsInterval>0&&r.frames%this.skinnedMeshAutoUpdateBoundsInterval===0){const f=ee(p),F=p.geometry;f&&(p.geometry=f),p.computeBoundingBox(),p.geometry=F}x=p.boundingBox}if(x){const p=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 c=t.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(c)){s.mesh_lod=0,s.texture_lod=0;return}}if(this._tempBox.copy(x),this._tempBox.applyMatrix4(e.matrixWorld),p.isPerspectiveCamera&&E.isInside(this._tempBox,this.projectionScreenMatrix)){s.mesh_lod=0,s.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&p.isPerspectiveCamera&&p.fov>70){const c=this._tempBox.min,g=this._tempBox.max;let S=c.x,C=c.y,I=g.x,te=g.y;const ie=2,ve=1.5,ae=(c.x+g.x)*.5,le=(c.y+g.y)*.5;S=(S-ae)*ie+ae,C=(C-le)*ie+le,I=(I-ae)*ie+ae,te=(te-le)*ie+le;const Ke=S<0&&I>0?0:Math.min(Math.abs(c.x),Math.abs(g.x)),He=C<0&&te>0?0:Math.min(Math.abs(c.y),Math.abs(g.y)),ye=Math.max(Ke,He);r.lastCentrality=(ve-ye)*(ve-ye)*(ve-ye)}else r.lastCentrality=1;const f=this._tempBox.getSize(this._tempBoxSize);f.multiplyScalar(.5),screen.availHeight>0&&G>0&&f.multiplyScalar(G/screen.availHeight),t.isPerspectiveCamera?f.x*=t.aspect:t.isOrthographicCamera;const F=t.matrixWorldInverse,D=this._tempBox2;D.copy(x),D.applyMatrix4(e.matrixWorld),D.applyMatrix4(F);const R=D.getSize(this._tempBox2Size),O=Math.max(R.x,R.y);if(Math.max(f.x,f.y)!=0&&O!=0&&(f.z=R.z/Math.max(R.x,R.y)*Math.max(f.x,f.y)),r.lastScreenCoverage=Math.max(f.x,f.y,f.z),r.lastScreenspaceVolume.copy(f),r.lastScreenCoverage*=r.lastCentrality,N&&E.debugDrawLine){const c=this.tempMatrix.copy(this.projectionScreenMatrix);c.invert();const g=E.corner0,S=E.corner1,C=E.corner2,I=E.corner3;g.copy(this._tempBox.min),S.copy(this._tempBox.max),S.x=g.x,C.copy(this._tempBox.max),C.y=g.y,I.copy(this._tempBox.max);const te=(g.z+I.z)*.5;g.z=S.z=C.z=I.z=te,g.applyMatrix4(c),S.applyMatrix4(c),C.applyMatrix4(c),I.applyMatrix4(c),E.debugDrawLine(g,S,255),E.debugDrawLine(g,C,255),E.debugDrawLine(S,I,255),E.debugDrawLine(C,I,255)}let w=999;if(h&&r.lastScreenCoverage>0)for(let c=0;c<h.length;c++){const g=h[c];if((((i=g.densities)==null?void 0:i[y])||g.density||1e-5)/r.lastScreenCoverage<o){w=c;break}}w<u&&(u=w,a=!0)}if(a?s.mesh_lod=u:s.mesh_lod=r.lastLodLevel_Mesh,N&&s.mesh_lod!=r.lastLodLevel_Mesh){const p=h?.[s.mesh_lod];p&&console.log(`Mesh LOD changed: ${r.lastLodLevel_Mesh} \u2192 ${s.mesh_lod} (${p.density.toFixed(0)}) - ${e.name}`)}if(b){const p="saveData"in globalThis.navigator&&globalThis.navigator.saveData===!0;if(r.lastLodLevel_Texture<0){if(s.texture_lod=_.max_count-1,N){const f=_.lods[_.max_count-1];N&&console.log(`First Texture LOD ${s.texture_lod} (${f.max_height}px) - ${e.name}`)}}else{const f=r.lastScreenspaceVolume.x+r.lastScreenspaceVolume.y+r.lastScreenspaceVolume.z;let F=r.lastScreenCoverage*4;((l=this.context)==null?void 0:l.engine)==="model-viewer"&&(F*=1.5);const D=G/window.devicePixelRatio*F;let R=!1;for(let O=_.lods.length-1;O>=0;O--){const w=_.lods[O];if(!(p&&w.max_height>=2048)&&!(ut()&&w.max_height>4096)&&(w.max_height>D||!R&&O===0)){if(R=!0,s.texture_lod=O,s.texture_lod<r.lastLodLevel_Texture){const c=w.max_height;N&&console.log(`Texture LOD changed: ${r.lastLodLevel_Texture} \u2192 ${s.texture_lod} = ${c}px
|
|
6
6
|
Screensize: ${D.toFixed(0)}px, Coverage: ${(100*r.lastScreenCoverage).toFixed(2)}%, Volume ${f.toFixed(1)}
|
|
7
7
|
${e.name}`)}break}}}}else s.texture_lod=0}};let k=E;A=new WeakMap,X=new WeakMap,Pe=new WeakMap,K=new WeakMap,ne=new WeakMap,fe=new WeakMap,H=new WeakMap,d(k,"debugDrawLine"),d(k,"overrideGlobalLodLevel"),d(k,"corner0",new z),d(k,"corner1",new z),d(k,"corner2",new z),d(k,"corner3",new z),d(k,"_tempPtInside",new z);class mt{constructor(){d(this,"frames",0),d(this,"lastLodLevel_Mesh",-1),d(this,"lastLodLevel_Texture",-1),d(this,"lastScreenCoverage",0),d(this,"lastScreenspaceVolume",new z),d(this,"lastCentrality",0)}}const Ue=Symbol("NEEDLE_mesh_lod"),me=Symbol("NEEDLE_texture_lod");let pe=null;function Ae(){const t=pt();t&&(t.mapURLs(function(e){return ze(),e}),ze(),pe?.disconnect(),pe=new MutationObserver(e=>{e.forEach(r=>{r.addedNodes.forEach(o=>{o instanceof HTMLElement&&o.tagName.toLowerCase()==="model-viewer"&&qe(o)})})}),pe.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 ze(){typeof document>"u"||document.querySelectorAll("model-viewer").forEach(t=>{qe(t)})}const Ve=new WeakSet;let vt=0;function qe(t){if(!t||Ve.has(t))return null;Ve.add(t),console.debug("[gltf-progressive] found new model-viewer..."+ ++vt+`
|
|
8
8
|
`,t.getAttribute("src"));let e=null,r=null,o=null;for(let s=t;s!=null;s=Object.getPrototypeOf(s)){const n=Object.getOwnPropertySymbols(s),i=n.find(a=>a.toString()=="Symbol(renderer)"),l=n.find(a=>a.toString()=="Symbol(scene)"),u=n.find(a=>a.toString()=="Symbol(needsRender)");!e&&i!=null&&(e=t[i].threeRenderer),!r&&l!=null&&(r=t[l]),!o&&u!=null&&(o=t[u])}if(e&&r){let s=function(){if(o){let i=0,l=setInterval(()=>{if(i++>5){clearInterval(l);return}o?.call(t)},300)}};console.debug("[gltf-progressive] setup model-viewer");const n=k.get(e,{engine:"model-viewer"});return k.addPlugin(new yt),n.enable(),n.addEventListener("changed",()=>{o?.call(t)}),t.addEventListener("model-visibility",i=>{i.detail.visible&&o?.call(t)}),t.addEventListener("load",()=>{s()}),()=>{n.disable()}}return null}class yt{constructor(){d(this,"_didWarnAboutMissingUrl",!1)}onBeforeUpdateLOD(e,r,o,s){this.tryParseMeshLOD(r,s),this.tryParseTextureLOD(r,s)}getUrl(e){if(!e)return null;let r=e.getAttribute("src");return r||(r=e.src),r||(this._didWarnAboutMissingUrl||console.warn("No url found in modelviewer",e),this._didWarnAboutMissingUrl=!0),r}tryGetCurrentGLTF(e){return e._currentGLTF}tryGetCurrentModelViewer(e){return e.element}tryParseTextureLOD(e,r){if(r[me]==!0)return;r[me]=!0;const o=this.tryGetCurrentGLTF(e),s=this.tryGetCurrentModelViewer(e),n=this.getUrl(s);if(n&&o&&r.material){let i=function(u){var a,h,y;if(u[me]==!0)return;u[me]=!0,u.userData&&(u.userData.LOD=-1);const m=Object.keys(u);for(let _=0;_<m.length;_++){const b=m[_],G=u[b];if(G?.isTexture===!0){const x=(h=(a=G.userData)==null?void 0:a.associations)==null?void 0:h.textures;if(x==null)continue;const p=o.parser.json.textures[x];if(!p){console.warn("Texture data not found for texture index "+x);continue}if((y=p?.extensions)!=null&&y[W]){const f=p.extensions[W];f&&n&&T.registerTexture(n,G,f.lods.length,x,f)}}}};const l=r.material;if(Array.isArray(l))for(const u of l)i(u);else i(l)}}tryParseMeshLOD(e,r){var o,s;if(r[Ue]==!0)return;r[Ue]=!0;const n=this.tryGetCurrentModelViewer(e),i=this.getUrl(n);if(!i)return;const l=(s=(o=r.userData)==null?void 0:o.gltfExtensions)==null?void 0:s[W];if(l&&i){const u=r.uuid;T.registerMesh(i,u,r,0,l.lods.length,l)}}}function Xe(t,e,r,o){we(e),_e(r),De(r,{progressive:!0,...o?.hints}),r.register(n=>new T(n,t));const s=k.get(e);return o?.enableLODsManager!==!1&&s.enable(),s}if(Ae(),!ct){const t={gltfProgressive:{useNeedleProgressive:Xe,LODsManager:k,configureLoader:De,getRaycastMesh:ee,useRaycastMeshes:We}};if(!globalThis.Needle)globalThis.Needle=t;else for(const e in t)globalThis.Needle[e]=t[e]}export{W as EXTENSION_NAME,k as LODsManager,T as NEEDLE_progressive,Be as VERSION,_e as addDracoAndKTX2Loaders,De as configureLoader,we as createLoaders,ee as getRaycastMesh,Ae as patchModelViewer,$e as registerRaycastMesh,Ge as setDracoDecoderLocation,Re as setKTX2TranscoderLocation,Xe as useNeedleProgressive,We as useRaycastMeshes};
|
package/gltf-progressive.umd.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"use strict";var He=Object.defineProperty;var je=(n,t,e)=>t in n?He(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var d=(n,t,e)=>(je(n,typeof t!="symbol"?t+"":t,e),e),Ge=(n,t,e)=>{if(!t.has(n))throw TypeError("Cannot "+e)};var y=(n,t,e)=>(Ge(n,t,"read from private field"),e?e.call(n):t.get(n)),J=(n,t,e)=>{if(t.has(n))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(n):t.set(n,e)},W=(n,t,e,r)=>(Ge(n,t,"write to private field"),r?r.call(n,e):t.set(n,e),e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("three"),Te=require("three/examples/jsm/loaders/GLTFLoader.js"),Je=require("three/examples/jsm/libs/meshopt_decoder.module.js"),Qe=require("three/examples/jsm/loaders/DRACOLoader.js"),Ze=require("three/examples/jsm/loaders/KTX2Loader.js"),ke="";globalThis.GLTF_PROGRESSIVE_VERSION=ke;console.debug("[gltf-progressive] version -");let X="https://www.gstatic.com/draco/versioned/decoders/1.5.7/",re="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";const et=X,tt=re,$e=new URL(X+"draco_decoder.js");$e.searchParams.append("range","true");fetch($e,{method:"GET",headers:{Range:"bytes=0-1"}}).catch(n=>{console.debug(`Failed to fetch remote Draco decoder from ${X} (offline: ${typeof navigator<"u"?navigator.onLine:"unknown"})`),X===et&&Fe("./include/draco/"),re===tt&&Ne("./include/ktx2/")}).finally(()=>{Ue()});function Fe(n){X=n,I&&I[Oe]!=X?(console.debug("Updating Draco decoder path to "+n),I[Oe]=X,I.setDecoderPath(X),I.preload()):console.debug("Setting Draco decoder path to "+n)}function Ne(n){re=n,U&&U.transcoderPath!=re?(console.debug("Updating KTX2 transcoder path to "+n),U.setTranscoderPath(re),U.init()):console.debug("Setting KTX2 transcoder path to "+n)}const Oe=Symbol("dracoDecoderPath");let I,ye,U;function Ue(){I||(I=new Qe.DRACOLoader,I[Oe]=X,I.setDecoderPath(X),I.setDecoderConfig({type:"js"}),I.preload()),U||(U=new Ze.KTX2Loader,U.setTranscoderPath(re),U.init()),ye||(ye=Je.MeshoptDecoder)}function Pe(n){return Ue(),n?U.detectSupport(n):n!==null&&console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"),{dracoLoader:I,ktx2Loader:U,meshoptDecoder:ye}}function Ae(n){n.dracoLoader||n.setDRACOLoader(I),n.ktx2Loader||n.setKTX2Loader(U),n.meshoptDecoder||n.setMeshoptDecoder(ye)}const be=new WeakMap;function Ce(n,t){let e=be.get(n);e?e=Object.assign(e,t):e=t,be.set(n,e)}const we=Te.GLTFLoader.prototype.load;function rt(...n){const t=be.get(this);let e=n[0];const r=new URL(e,window.location.href);if(r.hostname.endsWith("needle.tools")){const o=(t==null?void 0:t.progressive)!==void 0?t.progressive:!0,s=t!=null&&t.usecase?t.usecase:"default";o?this.requestHeader.Accept=`*/*;progressive=allowed;usecase=${s}`:this.requestHeader.Accept=`*/*;usecase=${s}`,e=r.toString()}return n[0]=e,we==null?void 0:we.call(this,...n)}Te.GLTFLoader.prototype.load=rt;de("debugprogressive");function de(n){if(typeof window>"u")return!1;const e=new URL(window.location.href).searchParams.get(n);return e==null||e==="0"||e==="false"?!1:e===""?!0:e}function st(n,t){if(t===void 0||t.startsWith("./")||t.startsWith("http")||n===void 0)return t;const e=n.lastIndexOf("/");if(e>=0){const r=n.substring(0,e+1);for(;r.endsWith("/")&&t.startsWith("/");)t=t.substring(1);return r+t}return t}let ne;function ot(){return ne!==void 0||(ne=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),de("debugprogressive")&&console.log("[glTF Progressive]: isMobileDevice",ne)),ne}function it(){if(typeof window>"u")return!1;const n=new URL(window.location.href),t=n.hostname==="localhost"||/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(n.hostname);return n.hostname==="127.0.0.1"||t}const nt=typeof window>"u"&&typeof document>"u",Se=Symbol("needle:raycast-mesh");function oe(n){return(n==null?void 0:n[Se])instanceof p.BufferGeometry?n[Se]:null}function Ve(n,t){if((n.type==="Mesh"||n.type==="SkinnedMesh")&&!oe(n)){const r=at(t);r.userData={isRaycastMesh:!0},n[Se]=r}}function ze(n=!0){if(n){if(ae)return;const t=ae=p.Mesh.prototype.raycast;p.Mesh.prototype.raycast=function(e,r){const i=this,o=oe(i);let s;o&&i.isMesh&&(s=i.geometry,i.geometry=o),t.call(this,e,r),s&&(i.geometry=s)}}else{if(!ae)return;p.Mesh.prototype.raycast=ae,ae=null}}let ae=null;function at(n){const t=new p.BufferGeometry;for(const e in n.attributes)t.setAttribute(e,n.getAttribute(e));return t.setIndex(n.getIndex()),t}const Z=new Array,x=de("debugprogressive");let ge,te=-1;if(x){let n=function(){te+=1,te>=t&&(te=-1),console.log(`Toggle LOD level [${te}]`)},t=6;window.addEventListener("keyup",e=>{e.key==="p"&&n(),e.key==="w"&&(ge=!ge,console.log(`Toggle wireframe [${ge}]`));const r=parseInt(e.key);!isNaN(r)&&r>=0&&(te=r,console.log(`Set LOD level to [${te}]`))})}function We(n){if(x)if(Array.isArray(n))for(const t of n)We(t);else n&&"wireframe"in n&&(n.wireframe=ge===!0)}const q="NEEDLE_progressive",ve=Symbol("needle-progressive-texture"),S=class{constructor(t,e){d(this,"parser");d(this,"url");d(this,"_isLoadingMesh");d(this,"loadMesh",t=>{var r,i;if(this._isLoadingMesh)return null;const e=(i=(r=this.parser.json.meshes[t])==null?void 0:r.extensions)==null?void 0:i[q];return e?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",t).then(o=>{var s;return this._isLoadingMesh=!1,o&&S.registerMesh(this.url,e.guid,o,(s=e.lods)==null?void 0:s.length,0,e),o})):null});x&&console.log("Progressive extension registered for",e),this.parser=t,this.url=e}get name(){return q}static getMeshLODExtension(t){const e=this.getAssignedLODInformation(t);return e!=null&&e.key?this.lodInfos.get(e.key):null}static getPrimitiveIndex(t){var r;const e=(r=this.getAssignedLODInformation(t))==null?void 0:r.index;return e??-1}static getMaterialMinMaxLODsCount(t,e){const r=this,i="LODS:minmax",o=t[i];if(o!=null)return o;if(e||(e={min_count:1/0,max_count:0,lods:[]}),Array.isArray(t)){for(const a of t)this.getMaterialMinMaxLODsCount(a,e);return t[i]=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 u=a.uniforms[l].value;(u==null?void 0:u.isTexture)===!0&&s(u,e)}}else if(t.isMaterial)for(const a of Object.keys(t)){const l=t[a];(l==null?void 0:l.isTexture)===!0&&s(l,e)}return t[i]=e,e;function s(a,l){const u=r.getAssignedLODInformation(a);if(u){const c=r.lodInfos.get(u.key);if(c&&c.lods){l.min_count=Math.min(l.min_count,c.lods.length),l.max_count=Math.max(l.max_count,c.lods.length);for(let h=0;h<c.lods.length;h++){const g=c.lods[h];g.width&&(l.lods[h]=l.lods[h]||{min_height:1/0,max_height:0},l.lods[h].min_height=Math.min(l.lods[h].min_height,g.height),l.lods[h].max_height=Math.max(l.lods[h].max_height,g.height))}}}}}static hasLODLevelAvailable(t,e){var o;if(Array.isArray(t)){for(const s of t)if(this.hasLODLevelAvailable(s,e))return!0;return!1}if(t.isMaterial===!0){for(const s of Object.keys(t)){const a=t[s];if(a&&a.isTexture&&this.hasLODLevelAvailable(a,e))return!0}return!1}else if(t.isGroup===!0){for(const s of t.children)if(s.isMesh===!0&&this.hasLODLevelAvailable(s,e))return!0}let r,i;if(t.isMesh?r=t.geometry:(t.isBufferGeometry||t.isTexture)&&(r=t),r&&(o=r==null?void 0:r.userData)!=null&&o.LODS){const s=r.userData.LODS;if(i=this.lodInfos.get(s.key),e===void 0)return i!=null;if(i)return Array.isArray(i.lods)?e<i.lods.length:e===0}return!1}static assignMeshLOD(t,e){var r;if(!t)return Promise.resolve(null);if(t instanceof p.Mesh||t.isMesh===!0){const i=t.geometry,o=this.getAssignedLODInformation(i);if(!o)return Promise.resolve(null);for(const s of Z)(r=s.onBeforeGetLODMesh)==null||r.call(s,t,e);return t["LOD:requested level"]=e,S.getOrLoadLOD(i,e).then(s=>{if(Array.isArray(s)){const a=o.index||0;s=s[a]}return t["LOD:requested level"]===e&&(delete t["LOD:requested level"],s&&i!=s&&((s==null?void 0:s.isBufferGeometry)?t.geometry=s:x&&console.error("Invalid LOD geometry",s))),s}).catch(s=>(console.error("Error loading mesh LOD",t,s),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 r=t;if(Array.isArray(r.material)){const i=new Array;for(const o of r.material){const s=this.assignTextureLOD(o,e);i.push(s)}return Promise.all(i).then(o=>{const s=new Array;for(const a of o)Array.isArray(a)&&s.push(...a);return s})}else return this.assignTextureLOD(r.material,e)}if(t.isMaterial===!0){const r=t,i=[],o=new Array;if(r.uniforms&&(r.isRawShaderMaterial||r.isShaderMaterial===!0)){const s=r;for(const a of Object.keys(s.uniforms)){const l=s.uniforms[a].value;if((l==null?void 0:l.isTexture)===!0){const u=this.assignTextureLODForSlot(l,e,r,a).then(c=>(c&&s.uniforms[a].value!=c&&(s.uniforms[a].value=c,s.uniformsNeedUpdate=!0),c));i.push(u),o.push(a)}}}else for(const s of Object.keys(r)){const a=r[s];if((a==null?void 0:a.isTexture)===!0){const l=this.assignTextureLODForSlot(a,e,r,s);i.push(l),o.push(s)}}return Promise.all(i).then(s=>{const a=new Array;for(let l=0;l<s.length;l++){const u=s[l],c=o[l];u&&u.isTexture===!0?a.push({material:r,slot:c,texture:u,level:e}):a.push({material:r,slot:c,texture:null,level:e})}return a})}if(t instanceof p.Texture||t.isTexture===!0){const r=t;return this.assignTextureLODForSlot(r,e,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(t,e,r,i){return(t==null?void 0:t.isTexture)!==!0?Promise.resolve(null):i==="glyphMap"?Promise.resolve(t):S.getOrLoadLOD(t,e).then(o=>{if(Array.isArray(o))return null;if((o==null?void 0:o.isTexture)===!0){if(o!=t&&r&&i){const s=r[i];if(s&&!x){const a=this.getAssignedLODInformation(s);if(a&&(a==null?void 0:a.level)<e)return x==="verbose"&&console.warn("Assigned texture level is already higher: ",a.level,e,r,s,o),null}r[i]=o}return o}else x=="verbose"&&console.warn("No LOD found for",t,e);return null}).catch(o=>(console.error("Error loading LOD",t,o),null))}afterRoot(t){var e,r;return x&&console.log("AFTER",this.url,t),(e=this.parser.json.textures)==null||e.forEach((i,o)=>{var s;if(i!=null&&i.extensions){const a=i==null?void 0:i.extensions[q];if(a){if(!a.lods){x&&console.warn("Texture has no LODs",a);return}let l=!1;for(const u of this.parser.associations.keys())if(u.isTexture===!0){const c=this.parser.associations.get(u);(c==null?void 0:c.textures)===o&&(l=!0,S.registerTexture(this.url,u,(s=a.lods)==null?void 0:s.length,o,a))}l||this.parser.getDependency("texture",o).then(u=>{var c;u&&S.registerTexture(this.url,u,(c=a.lods)==null?void 0:c.length,o,a)})}}}),(r=this.parser.json.meshes)==null||r.forEach((i,o)=>{if(i!=null&&i.extensions){const s=i==null?void 0:i.extensions[q];if(s&&s.lods){for(const a of this.parser.associations.keys())if(a.isMesh){const l=this.parser.associations.get(a);(l==null?void 0:l.meshes)===o&&S.registerMesh(this.url,s.guid,a,s.lods.length,l.primitives,s)}}}}),null}static async getOrLoadLOD(t,e){var a,l,u,c;const r=x=="verbose",i=t.userData.LODS;if(!i)return null;const o=i==null?void 0:i.key;let s;if(t.isTexture===!0){const h=t;h.source&&h.source[ve]&&(s=h.source[ve])}if(s||(s=S.lodInfos.get(o)),s){if(e>0){let w=!1;const O=Array.isArray(s.lods);if(O&&e>=s.lods.length?w=!0:O||(w=!0),w)return this.lowresCache.get(o)}const h=Array.isArray(s.lods)?(a=s.lods[e])==null?void 0:a.path:s.lods;if(!h)return x&&!s["missing:uri"]&&(s["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+e,s)),null;const g=st(i.url,h);if(g.endsWith(".glb")||g.endsWith(".gltf")){if(!s.guid)return console.warn("missing pointer for glb/gltf texture",s),null;const w=g+"_"+s.guid,O=this.previouslyLoaded.get(w);if(O!==void 0){r&&console.log(`LOD ${e} was already loading/loaded: ${w}`);let v=await O.catch(m=>(console.error(`Error loading LOD ${e} from ${g}
|
|
1
|
+
"use strict";var He=Object.defineProperty;var je=(n,t,e)=>t in n?He(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var d=(n,t,e)=>(je(n,typeof t!="symbol"?t+"":t,e),e),Ge=(n,t,e)=>{if(!t.has(n))throw TypeError("Cannot "+e)};var y=(n,t,e)=>(Ge(n,t,"read from private field"),e?e.call(n):t.get(n)),J=(n,t,e)=>{if(t.has(n))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(n):t.set(n,e)},W=(n,t,e,r)=>(Ge(n,t,"write to private field"),r?r.call(n,e):t.set(n,e),e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("three"),Te=require("three/examples/jsm/loaders/GLTFLoader.js"),Je=require("three/examples/jsm/libs/meshopt_decoder.module.js"),Qe=require("three/examples/jsm/loaders/DRACOLoader.js"),Ze=require("three/examples/jsm/loaders/KTX2Loader.js"),ke="";globalThis.GLTF_PROGRESSIVE_VERSION=ke;console.debug("[gltf-progressive] version -");let X="https://www.gstatic.com/draco/versioned/decoders/1.5.7/",re="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";const et=X,tt=re,Fe=new URL(X+"draco_decoder.js");Fe.searchParams.append("range","true");fetch(Fe,{method:"GET",headers:{Range:"bytes=0-1"}}).catch(n=>{console.debug(`Failed to fetch remote Draco decoder from ${X} (offline: ${typeof navigator<"u"?navigator.onLine:"unknown"})`),X===et&&$e("./include/draco/"),re===tt&&Ne("./include/ktx2/")}).finally(()=>{Ue()});function $e(n){X=n,I&&I[Oe]!=X?(console.debug("Updating Draco decoder path to "+n),I[Oe]=X,I.setDecoderPath(X),I.preload()):console.debug("Setting Draco decoder path to "+n)}function Ne(n){re=n,U&&U.transcoderPath!=re?(console.debug("Updating KTX2 transcoder path to "+n),U.setTranscoderPath(re),U.init()):console.debug("Setting KTX2 transcoder path to "+n)}const Oe=Symbol("dracoDecoderPath");let I,ye,U;function Ue(){I||(I=new Qe.DRACOLoader,I[Oe]=X,I.setDecoderPath(X),I.setDecoderConfig({type:"js"}),I.preload()),U||(U=new Ze.KTX2Loader,U.setTranscoderPath(re),U.init()),ye||(ye=Je.MeshoptDecoder)}function Pe(n){return Ue(),n?U.detectSupport(n):n!==null&&console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"),{dracoLoader:I,ktx2Loader:U,meshoptDecoder:ye}}function Ae(n){n.dracoLoader||n.setDRACOLoader(I),n.ktx2Loader||n.setKTX2Loader(U),n.meshoptDecoder||n.setMeshoptDecoder(ye)}const be=new WeakMap;function Ce(n,t){let e=be.get(n);e?e=Object.assign(e,t):e=t,be.set(n,e)}const we=Te.GLTFLoader.prototype.load;function rt(...n){const t=be.get(this);let e=n[0];const r=new URL(e,window.location.href);if(r.hostname.endsWith("needle.tools")){const o=(t==null?void 0:t.progressive)!==void 0?t.progressive:!0,s=t!=null&&t.usecase?t.usecase:"default";o?this.requestHeader.Accept=`*/*;progressive=allowed;usecase=${s}`:this.requestHeader.Accept=`*/*;usecase=${s}`,e=r.toString()}return n[0]=e,we==null?void 0:we.call(this,...n)}Te.GLTFLoader.prototype.load=rt;de("debugprogressive");function de(n){if(typeof window>"u")return!1;const e=new URL(window.location.href).searchParams.get(n);return e==null||e==="0"||e==="false"?!1:e===""?!0:e}function st(n,t){if(t===void 0||t.startsWith("./")||t.startsWith("http")||n===void 0)return t;const e=n.lastIndexOf("/");if(e>=0){const r=n.substring(0,e+1);for(;r.endsWith("/")&&t.startsWith("/");)t=t.substring(1);return r+t}return t}let ne;function ot(){return ne!==void 0||(ne=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),de("debugprogressive")&&console.log("[glTF Progressive]: isMobileDevice",ne)),ne}function it(){if(typeof window>"u")return!1;const n=new URL(window.location.href),t=n.hostname==="localhost"||/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(n.hostname);return n.hostname==="127.0.0.1"||t}const nt=typeof window>"u"&&typeof document>"u",Se=Symbol("needle:raycast-mesh");function oe(n){return(n==null?void 0:n[Se])instanceof p.BufferGeometry?n[Se]:null}function Ve(n,t){if((n.type==="Mesh"||n.type==="SkinnedMesh")&&!oe(n)){const r=at(t);r.userData={isRaycastMesh:!0},n[Se]=r}}function ze(n=!0){if(n){if(ae)return;const t=ae=p.Mesh.prototype.raycast;p.Mesh.prototype.raycast=function(e,r){const i=this,o=oe(i);let s;o&&i.isMesh&&(s=i.geometry,i.geometry=o),t.call(this,e,r),s&&(i.geometry=s)}}else{if(!ae)return;p.Mesh.prototype.raycast=ae,ae=null}}let ae=null;function at(n){const t=new p.BufferGeometry;for(const e in n.attributes)t.setAttribute(e,n.getAttribute(e));return t.setIndex(n.getIndex()),t}const Z=new Array,x=de("debugprogressive");let ge,te=-1;if(x){let n=function(){te+=1,te>=t&&(te=-1),console.log(`Toggle LOD level [${te}]`)},t=6;window.addEventListener("keyup",e=>{e.key==="p"&&n(),e.key==="w"&&(ge=!ge,console.log(`Toggle wireframe [${ge}]`));const r=parseInt(e.key);!isNaN(r)&&r>=0&&(te=r,console.log(`Set LOD level to [${te}]`))})}function We(n){if(x)if(Array.isArray(n))for(const t of n)We(t);else n&&"wireframe"in n&&(n.wireframe=ge===!0)}const q="NEEDLE_progressive",ve=Symbol("needle-progressive-texture"),S=class{constructor(t,e){d(this,"parser");d(this,"url");d(this,"_isLoadingMesh");d(this,"loadMesh",t=>{var r,i;if(this._isLoadingMesh)return null;const e=(i=(r=this.parser.json.meshes[t])==null?void 0:r.extensions)==null?void 0:i[q];return e?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",t).then(o=>{var s;return this._isLoadingMesh=!1,o&&S.registerMesh(this.url,e.guid,o,(s=e.lods)==null?void 0:s.length,0,e),o})):null});x&&console.log("Progressive extension registered for",e),this.parser=t,this.url=e}get name(){return q}static getMeshLODExtension(t){const e=this.getAssignedLODInformation(t);return e!=null&&e.key?this.lodInfos.get(e.key):null}static getPrimitiveIndex(t){var r;const e=(r=this.getAssignedLODInformation(t))==null?void 0:r.index;return e??-1}static getMaterialMinMaxLODsCount(t,e){const r=this,i="LODS:minmax",o=t[i];if(o!=null)return o;if(e||(e={min_count:1/0,max_count:0,lods:[]}),Array.isArray(t)){for(const a of t)this.getMaterialMinMaxLODsCount(a,e);return t[i]=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 u=a.uniforms[l].value;(u==null?void 0:u.isTexture)===!0&&s(u,e)}}else if(t.isMaterial)for(const a of Object.keys(t)){const l=t[a];(l==null?void 0:l.isTexture)===!0&&s(l,e)}return t[i]=e,e;function s(a,l){const u=r.getAssignedLODInformation(a);if(u){const c=r.lodInfos.get(u.key);if(c&&c.lods){l.min_count=Math.min(l.min_count,c.lods.length),l.max_count=Math.max(l.max_count,c.lods.length);for(let h=0;h<c.lods.length;h++){const g=c.lods[h];g.width&&(l.lods[h]=l.lods[h]||{min_height:1/0,max_height:0},l.lods[h].min_height=Math.min(l.lods[h].min_height,g.height),l.lods[h].max_height=Math.max(l.lods[h].max_height,g.height))}}}}}static hasLODLevelAvailable(t,e){var o;if(Array.isArray(t)){for(const s of t)if(this.hasLODLevelAvailable(s,e))return!0;return!1}if(t.isMaterial===!0){for(const s of Object.keys(t)){const a=t[s];if(a&&a.isTexture&&this.hasLODLevelAvailable(a,e))return!0}return!1}else if(t.isGroup===!0){for(const s of t.children)if(s.isMesh===!0&&this.hasLODLevelAvailable(s,e))return!0}let r,i;if(t.isMesh?r=t.geometry:(t.isBufferGeometry||t.isTexture)&&(r=t),r&&(o=r==null?void 0:r.userData)!=null&&o.LODS){const s=r.userData.LODS;if(i=this.lodInfos.get(s.key),e===void 0)return i!=null;if(i)return Array.isArray(i.lods)?e<i.lods.length:e===0}return!1}static assignMeshLOD(t,e){var r;if(!t)return Promise.resolve(null);if(t instanceof p.Mesh||t.isMesh===!0){const i=t.geometry,o=this.getAssignedLODInformation(i);if(!o)return Promise.resolve(null);for(const s of Z)(r=s.onBeforeGetLODMesh)==null||r.call(s,t,e);return t["LOD:requested level"]=e,S.getOrLoadLOD(i,e).then(s=>{if(Array.isArray(s)){const a=o.index||0;s=s[a]}return t["LOD:requested level"]===e&&(delete t["LOD:requested level"],s&&i!=s&&((s==null?void 0:s.isBufferGeometry)?t.geometry=s:x&&console.error("Invalid LOD geometry",s))),s}).catch(s=>(console.error("Error loading mesh LOD",t,s),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 r=t;if(Array.isArray(r.material)){const i=new Array;for(const o of r.material){const s=this.assignTextureLOD(o,e);i.push(s)}return Promise.all(i).then(o=>{const s=new Array;for(const a of o)Array.isArray(a)&&s.push(...a);return s})}else return this.assignTextureLOD(r.material,e)}if(t.isMaterial===!0){const r=t,i=[],o=new Array;if(r.uniforms&&(r.isRawShaderMaterial||r.isShaderMaterial===!0)){const s=r;for(const a of Object.keys(s.uniforms)){const l=s.uniforms[a].value;if((l==null?void 0:l.isTexture)===!0){const u=this.assignTextureLODForSlot(l,e,r,a).then(c=>(c&&s.uniforms[a].value!=c&&(s.uniforms[a].value=c,s.uniformsNeedUpdate=!0),c));i.push(u),o.push(a)}}}else for(const s of Object.keys(r)){const a=r[s];if((a==null?void 0:a.isTexture)===!0){const l=this.assignTextureLODForSlot(a,e,r,s);i.push(l),o.push(s)}}return Promise.all(i).then(s=>{const a=new Array;for(let l=0;l<s.length;l++){const u=s[l],c=o[l];u&&u.isTexture===!0?a.push({material:r,slot:c,texture:u,level:e}):a.push({material:r,slot:c,texture:null,level:e})}return a})}if(t instanceof p.Texture||t.isTexture===!0){const r=t;return this.assignTextureLODForSlot(r,e,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(t,e,r,i){return(t==null?void 0:t.isTexture)!==!0?Promise.resolve(null):i==="glyphMap"?Promise.resolve(t):S.getOrLoadLOD(t,e).then(o=>{if(Array.isArray(o))return null;if((o==null?void 0:o.isTexture)===!0){if(o!=t&&r&&i){const s=r[i];if(s&&!x){const a=this.getAssignedLODInformation(s);if(a&&(a==null?void 0:a.level)<e)return x==="verbose"&&console.warn("Assigned texture level is already higher: ",a.level,e,r,s,o),null}r[i]=o}return o}else x=="verbose"&&console.warn("No LOD found for",t,e);return null}).catch(o=>(console.error("Error loading LOD",t,o),null))}afterRoot(t){var e,r;return x&&console.log("AFTER",this.url,t),(e=this.parser.json.textures)==null||e.forEach((i,o)=>{var s;if(i!=null&&i.extensions){const a=i==null?void 0:i.extensions[q];if(a){if(!a.lods){x&&console.warn("Texture has no LODs",a);return}let l=!1;for(const u of this.parser.associations.keys())if(u.isTexture===!0){const c=this.parser.associations.get(u);(c==null?void 0:c.textures)===o&&(l=!0,S.registerTexture(this.url,u,(s=a.lods)==null?void 0:s.length,o,a))}l||this.parser.getDependency("texture",o).then(u=>{var c;u&&S.registerTexture(this.url,u,(c=a.lods)==null?void 0:c.length,o,a)})}}}),(r=this.parser.json.meshes)==null||r.forEach((i,o)=>{if(i!=null&&i.extensions){const s=i==null?void 0:i.extensions[q];if(s&&s.lods){for(const a of this.parser.associations.keys())if(a.isMesh){const l=this.parser.associations.get(a);(l==null?void 0:l.meshes)===o&&S.registerMesh(this.url,s.guid,a,s.lods.length,l.primitives,s)}}}}),null}static async getOrLoadLOD(t,e){var a,l,u,c;const r=x=="verbose",i=t.userData.LODS;if(!i)return null;const o=i==null?void 0:i.key;let s;if(t.isTexture===!0){const h=t;h.source&&h.source[ve]&&(s=h.source[ve])}if(s||(s=S.lodInfos.get(o)),s){if(e>0){let w=!1;const O=Array.isArray(s.lods);if(O&&e>=s.lods.length?w=!0:O||(w=!0),w)return this.lowresCache.get(o)}const h=Array.isArray(s.lods)?(a=s.lods[e])==null?void 0:a.path:s.lods;if(!h)return x&&!s["missing:uri"]&&(s["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+e,s)),null;const g=st(i.url,h);if(g.endsWith(".glb")||g.endsWith(".gltf")){if(!s.guid)return console.warn("missing pointer for glb/gltf texture",s),null;const w=g+"_"+s.guid,O=this.previouslyLoaded.get(w);if(O!==void 0){r&&console.log(`LOD ${e} was already loading/loaded: ${w}`);let v=await O.catch(m=>(console.error(`Error loading LOD ${e} from ${g}
|
|
2
2
|
`,m),null)),D=!1;if(v==null||(v instanceof p.Texture&&t instanceof p.Texture?(l=v.image)!=null&&l.data||(u=v.source)!=null&&u.data?v=this.copySettings(t,v):(D=!0,this.previouslyLoaded.delete(w)):v instanceof p.BufferGeometry&&t instanceof p.BufferGeometry&&((c=v.attributes.position)!=null&&c.array||(D=!0,this.previouslyLoaded.delete(w)))),!D)return v}const _=s,V=new Promise(async(v,D)=>{const m=new Te.GLTFLoader;Ae(m),x&&(await new Promise(b=>setTimeout(b,1e3)),r&&console.warn("Start loading (delayed) "+g,_.guid));let Y=g;if(_&&Array.isArray(_.lods)){const b=_.lods[e];b.hash&&(Y+="?v="+b.hash)}const C=await m.loadAsync(Y).catch(b=>(console.error(`Error loading LOD ${e} from ${g}
|
|
3
|
-
`,b),null));if(!C)return null;const
|
|
3
|
+
`,b),null));if(!C)return null;const F=C.parser;r&&console.log("Loading finished "+g,_.guid);let k=0;if(C.parser.json.textures){let b=!1;for(const f of C.parser.json.textures){if(f!=null&&f.extensions){const T=f==null?void 0:f.extensions[q];if(T!=null&&T.guid&&T.guid===_.guid){b=!0;break}}k++}if(b){let f=await F.getDependency("texture",k);return f&&S.assignLODInformation(i.url,f,o,e,void 0),r&&console.log('change "'+t.name+'" → "'+f.name+'"',g,k,f,w),t instanceof p.Texture&&(f=this.copySettings(t,f)),f&&(f.guid=_.guid),v(f)}else x&&console.warn("Could not find texture with guid",_.guid,C.parser.json)}if(k=0,C.parser.json.meshes){let b=!1;for(const f of C.parser.json.meshes){if(f!=null&&f.extensions){const T=f==null?void 0:f.extensions[q];if(T!=null&&T.guid&&T.guid===_.guid){b=!0;break}}k++}if(b){const f=await F.getDependency("mesh",k);if(r&&console.log(`Loaded Mesh "${f.name}"`,g,k,f,w),f.isMesh===!0){const T=f.geometry;return S.assignLODInformation(i.url,T,o,e,0),v(T)}else{const T=new Array;for(let L=0;L<f.children.length;L++){const M=f.children[L];if(M.isMesh===!0){const E=M.geometry;S.assignLODInformation(i.url,E,o,e,L),T.push(E)}}return v(T)}}else x&&console.warn("Could not find mesh with guid",_.guid,C.parser.json)}return v(null)});return this.previouslyLoaded.set(w,V),await V}else if(t instanceof p.Texture){r&&console.log("Load texture from uri: "+g);const O=await new p.TextureLoader().loadAsync(g);return O?(O.guid=s.guid,O.flipY=!1,O.needsUpdate=!0,O.colorSpace=t.colorSpace,r&&console.log(s,O)):x&&console.warn("failed loading",g),O}}else x&&console.warn(`Can not load LOD ${e}: no LOD info found for "${o}" ${t.name}`,t.type);return null}static assignLODInformation(t,e,r,i,o){if(!e)return;e.userData||(e.userData={});const s=new lt(t,r,i,o);e.userData.LODS=s}static getAssignedLODInformation(t){var e;return((e=t==null?void 0:t.userData)==null?void 0:e.LODS)||null}static copySettings(t,e){return e?(x&&console.warn(`Copy texture settings
|
|
4
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}};let P=S;d(P,"registerTexture",(t,e,r,i,o)=>{if(x&&console.log("> Progressive: register texture",i,e.name,e.uuid,e,o),!e){x&&console.error("gltf-progressive: Register texture without texture");return}e.source&&(e.source[ve]=o);const s=o.guid;S.assignLODInformation(t,e,s,r,i),S.lodInfos.set(s,o),S.lowresCache.set(s,e)}),d(P,"registerMesh",(t,e,r,i,o,s)=>{var u;const a=r.geometry;if(!a){x&&console.warn("gltf-progressive: Register mesh without geometry");return}a.userData||(a.userData={}),x&&console.log("> Progressive: register mesh "+r.name,{index:o,uuid:r.uuid},s,r),S.assignLODInformation(t,a,e,i,o),S.lodInfos.set(e,s);let l=S.lowresCache.get(e);l?l.push(r.geometry):l=[r.geometry],S.lowresCache.set(e,l),i>0&&!oe(r)&&Ve(r,a);for(const c of Z)(u=c.onRegisteredNewMesh)==null||u.call(c,r,s)}),d(P,"lodInfos",new Map),d(P,"previouslyLoaded",new Map),d(P,"lowresCache",new Map);class lt{constructor(t,e,r,i){d(this,"url");d(this,"key");d(this,"level");d(this,"index");this.url=t,this.key=e,this.level=r,i!=null&&(this.index=i)}}class pe{constructor(t,e){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,"_currentFrame",0);var o;const r=t===0?2:1,i=Math.max(e.frames??r,r);this.frame_start=t,this.frame_capture_end=t+i,this.ready=new Promise(s=>{this._resolve=s}),this.ready.finally(()=>{this._resolved=!0,this._awaiting.length=0}),this._signal=e.signal,(o=this._signal)==null||o.addEventListener("abort",()=>{this.resolveNow()})}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){if(this._resolved){console.warn("PromiseGroup: Trying to add a promise to a resolved group, ignoring.");return}this._currentFrame>this.frame_capture_end||(this._awaiting.push(e),this._addedCount++,e.finally(()=>{this._resolvedCount++,this._awaiting.splice(this._awaiting.indexOf(e),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})}}d(pe,"addPromise",(t,e,r)=>{r.forEach(i=>{i.add(t,e)})});const N=de("debugprogressive"),dt=de("noprogressive"),Me=Symbol("Needle:LODSManager"),De=Symbol("Needle:LODState"),Q=Symbol("Needle:CurrentLOD"),G={mesh_lod:-1,texture_lod:-1};var R,H,me,ee,se,Le,j;const A=class{constructor(t,e){d(this,"renderer");d(this,"context");d(this,"projectionScreenMatrix",new p.Matrix4);d(this,"targetTriangleDensity",2e5);d(this,"skinnedMeshAutoUpdateBoundsInterval",30);d(this,"updateInterval","auto");J(this,R,1);d(this,"pause",!1);d(this,"manual",!1);d(this,"_newPromiseGroups",[]);d(this,"_promiseGroupIds",0);d(this,"_lodchangedlisteners",[]);J(this,H,void 0);J(this,me,new p.Clock);J(this,ee,0);J(this,se,0);J(this,Le,0);J(this,j,0);d(this,"_fpsBuffer",[60,60,60,60,60]);d(this,"_sphere",new p.Sphere);d(this,"_tempBox",new p.Box3);d(this,"_tempBox2",new p.Box3);d(this,"tempMatrix",new p.Matrix4);d(this,"_tempWorldPosition",new p.Vector3);d(this,"_tempBoxSize",new p.Vector3);d(this,"_tempBox2Size",new p.Vector3);this.renderer=t,this.context={...e}}static getObjectLODState(t){return t[De]}static addPlugin(t){Z.push(t)}static removePlugin(t){const e=Z.indexOf(t);e>=0&&Z.splice(e,1)}static get(t,e){if(t[Me])return console.debug("[gltf-progressive] LODsManager already exists for this renderer"),t[Me];const r=new A(t,{engine:"unknown",...e});return t[Me]=r,r}get plugins(){return Z}awaitLoading(t){const e=this._promiseGroupIds++,r=new pe(y(this,ee),{...t});this._newPromiseGroups.push(r);const i=performance.now();return r.ready.finally(()=>{const o=this._newPromiseGroups.indexOf(r);o>=0&&(this._newPromiseGroups.splice(o,1),it()&&performance.measure("LODsManager:awaitLoading",{start:i,detail:{id:e,name:t==null?void 0: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(y(this,ee))}addEventListener(t,e){t==="changed"&&this._lodchangedlisteners.push(e)}removeEventListener(t,e){if(t==="changed"){const r=this._lodchangedlisteners.indexOf(e);r>=0&&this._lodchangedlisteners.splice(r,1)}}enable(){if(y(this,H))return;console.debug("[gltf-progressive] Enabling LODsManager for renderer");let t=0;W(this,H,this.renderer.render);const e=this;Pe(this.renderer),this.renderer.render=function(r,i){const o=e.renderer.getRenderTarget();(o==null||"isXRRenderTarget"in o&&o.isXRRenderTarget)&&(t=0,W(e,ee,y(e,ee)+1),W(e,se,y(e,me).getDelta()),W(e,Le,y(e,Le)+y(e,se)),e._fpsBuffer.shift(),e._fpsBuffer.push(1/y(e,se)),W(e,j,e._fpsBuffer.reduce((a,l)=>a+l)/e._fpsBuffer.length),N&&y(e,ee)%200===0&&console.log("FPS",Math.round(y(e,j)),"Interval:",y(e,R)));const s=t++;y(e,H).call(this,r,i),e.onAfterRender(r,i,s)}}disable(){y(this,H)&&(console.debug("[gltf-progressive] Disabling LODsManager for renderer"),this.renderer.render=y(this,H),W(this,H,void 0))}update(t,e){this.internalUpdate(t,e)}onAfterRender(t,e,r){if(this.pause)return;const o=this.renderer.renderLists.get(t,0).opaque;let s=!0;if(o.length===1){const a=o[0].material;(a.name==="EffectMaterial"||a.name==="CopyShader")&&(s=!1)}if((e.parent&&e.parent.type==="CubeCamera"||r>=1&&e.type==="OrthographicCamera")&&(s=!1),s){if(dt||(this.updateInterval==="auto"?y(this,j)<40&&y(this,R)<10?(W(this,R,y(this,R)+1),N&&console.warn("↓ Reducing LOD updates",y(this,R),y(this,j).toFixed(0))):y(this,j)>=60&&y(this,R)>1&&(W(this,R,y(this,R)-1),N&&console.warn("↑ Increasing LOD updates",y(this,R),y(this,j).toFixed(0))):W(this,R,this.updateInterval),y(this,R)>0&&y(this,ee)%y(this,R)!=0))return;this.internalUpdate(t,e),this._postprocessPromiseGroups()}}internalUpdate(t,e){var l,u;const r=this.renderer.renderLists.get(t,0),i=r.opaque;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse);const o=this.targetTriangleDensity;for(const c of i){if(c.material&&(((l=c.geometry)==null?void 0:l.type)==="BoxGeometry"||((u=c.geometry)==null?void 0:u.type)==="BufferGeometry")&&(c.material.name==="SphericalGaussianBlur"||c.material.name=="BackgroundCubeMaterial"||c.material.name==="CubemapFromEquirect"||c.material.name==="EquirectangularToCubeUV")){N&&(c.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(c.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",c,c.material.name,c.material.type)));continue}switch(c.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}if(N==="color"&&c.material&&!c.object.progressive_debug_color){c.object.progressive_debug_color=!0;const g=Math.random()*16777215,w=new p.MeshStandardMaterial({color:g});c.object.material=w}const h=c.object;(h instanceof p.Mesh||h.isMesh)&&this.updateLODs(t,e,h,o)}const s=r.transparent;for(const c of s){const h=c.object;(h instanceof p.Mesh||h.isMesh)&&this.updateLODs(t,e,h,o)}const a=r.transmissive;for(const c of a){const h=c.object;(h instanceof p.Mesh||h.isMesh)&&this.updateLODs(t,e,h,o)}}updateLODs(t,e,r,i){var a,l;r.userData||(r.userData={});let o=r[De];if(o||(o=new ct,r[De]=o),o.frames++<2)return;for(const u of Z)(a=u.onBeforeUpdateLOD)==null||a.call(u,this.renderer,t,e,r);const s=A.overrideGlobalLodLevel!==void 0?A.overrideGlobalLodLevel:te;s>=0?(G.mesh_lod=s,G.texture_lod=s):(this.calculateLodLevel(e,r,o,i,G),G.mesh_lod=Math.round(G.mesh_lod),G.texture_lod=Math.round(G.texture_lod)),G.mesh_lod>=0&&this.loadProgressiveMeshes(r,G.mesh_lod),r.material&&G.texture_lod>=0&&this.loadProgressiveTextures(r.material,G.texture_lod),x&&r.material&&!r.isGizmo&&We(r.material);for(const u of Z)(l=u.onAfterUpdatedLOD)==null||l.call(u,this.renderer,t,e,r,G);o.lastLodLevel_Mesh=G.mesh_lod,o.lastLodLevel_Texture=G.texture_lod}loadProgressiveTextures(t,e){if(!t)return;if(Array.isArray(t)){for(const o of t)this.loadProgressiveTextures(o,e);return}let r=!1;(t[Q]===void 0||e<t[Q])&&(r=!0);const i=t["DEBUG:LOD"];if(i!=null&&(r=t[Q]!=i,e=i),r){t[Q]=e;const o=P.assignTextureLOD(t,e).then(s=>{this._lodchangedlisteners.forEach(a=>a({type:"texture",level:e,object:t}))});pe.addPromise("texture",o,this._newPromiseGroups)}}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);let r=t[Q]!==e;const i=t["DEBUG:LOD"];if(i!=null&&(r=t[Q]!=i,e=i),r){t[Q]=e;const o=t.geometry,s=P.assignMeshLOD(t,e).then(a=>(a&&t[Q]==e&&o!=t.geometry&&this._lodchangedlisteners.forEach(l=>l({type:"mesh",level:e,object:t})),a));return pe.addPromise("mesh",s,this._newPromiseGroups),s}return Promise.resolve(null)}static isInside(t,e){const r=t.min,i=t.max,o=(r.x+i.x)*.5,s=(r.y+i.y)*.5;return this._tempPtInside.set(o,s,r.z).applyMatrix4(e).z<0}calculateLodLevel(t,e,r,i,o){var V,K,v;if(!e){o.mesh_lod=-1,o.texture_lod=-1;return}if(!t){o.mesh_lod=-1,o.texture_lod=-1;return}let a=10+1,l=!1;if(N&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const u=(V=P.getMeshLODExtension(e.geometry))==null?void 0:V.lods,c=P.getPrimitiveIndex(e.geometry),h=u&&u.length>0,g=P.getMaterialMinMaxLODsCount(e.material),w=(g==null?void 0:g.min_count)!=1/0&&g.min_count>0&&g.max_count>0;if(!h&&!w){o.mesh_lod=0,o.texture_lod=0;return}h||(l=!0,a=0);const O=this.renderer.domElement.clientHeight||this.renderer.domElement.height;let _=e.geometry.boundingBox;if(e.type==="SkinnedMesh"){const D=e;if(!D.boundingBox)D.computeBoundingBox();else if(this.skinnedMeshAutoUpdateBoundsInterval>0&&r.frames%this.skinnedMeshAutoUpdateBoundsInterval===0){const m=oe(D),Y=D.geometry;m&&(D.geometry=m),D.computeBoundingBox(),D.geometry=Y}_=D.boundingBox}if(_){const D=t;if(e.geometry.attributes.color&&e.geometry.attributes.color.count<100&&e.geometry.boundingSphere){this._sphere.copy(e.geometry.boundingSphere),this._sphere.applyMatrix4(e.matrixWorld);const L=t.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(L)){o.mesh_lod=0,o.texture_lod=0;return}}if(this._tempBox.copy(_),this._tempBox.applyMatrix4(e.matrixWorld),D.isPerspectiveCamera&&A.isInside(this._tempBox,this.projectionScreenMatrix)){o.mesh_lod=0,o.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&D.isPerspectiveCamera&&D.fov>70){const L=this._tempBox.min,M=this._tempBox.max;let E=L.x,F=L.y,z=M.x,ie=M.y;const ce=2,xe=1.5,ue=(L.x+M.x)*.5,fe=(L.y+M.y)*.5;E=(E-ue)*ce+ue,F=(F-fe)*ce+fe,z=(z-ue)*ce+ue,ie=(ie-fe)*ce+fe;const Ke=E<0&&z>0?0:Math.min(Math.abs(L.x),Math.abs(M.x)),Ye=F<0&&ie>0?0:Math.min(Math.abs(L.y),Math.abs(M.y)),_e=Math.max(Ke,Ye);r.lastCentrality=(xe-_e)*(xe-_e)*(xe-_e)}else r.lastCentrality=1;const m=this._tempBox.getSize(this._tempBoxSize);m.multiplyScalar(.5),screen.availHeight>0&&O>0&&m.multiplyScalar(O/screen.availHeight),t.isPerspectiveCamera?m.x*=t.aspect:t.isOrthographicCamera;const Y=t.matrixWorldInverse,C=this._tempBox2;C.copy(_),C.applyMatrix4(e.matrixWorld),C.applyMatrix4(Y);const $=C.getSize(this._tempBox2Size),k=Math.max($.x,$.y);if(Math.max(m.x,m.y)!=0&&k!=0&&(m.z=$.z/Math.max($.x,$.y)*Math.max(m.x,m.y)),r.lastScreenCoverage=Math.max(m.x,m.y,m.z),r.lastScreenspaceVolume.copy(m),r.lastScreenCoverage*=r.lastCentrality,N&&A.debugDrawLine){const L=this.tempMatrix.copy(this.projectionScreenMatrix);L.invert();const M=A.corner0,E=A.corner1,F=A.corner2,z=A.corner3;M.copy(this._tempBox.min),E.copy(this._tempBox.max),E.x=M.x,F.copy(this._tempBox.max),F.y=M.y,z.copy(this._tempBox.max);const ie=(M.z+z.z)*.5;M.z=E.z=F.z=z.z=ie,M.applyMatrix4(L),E.applyMatrix4(L),F.applyMatrix4(L),z.applyMatrix4(L),A.debugDrawLine(M,E,255),A.debugDrawLine(M,F,255),A.debugDrawLine(E,z,255),A.debugDrawLine(F,z,255)}let f=999;if(u&&r.lastScreenCoverage>0)for(let L=0;L<u.length;L++){const M=u[L];if((((K=M.densities)==null?void 0:K[c])||M.density||1e-5)/r.lastScreenCoverage<i){f=L;break}}f<a&&(a=f,l=!0)}if(l?o.mesh_lod=a:o.mesh_lod=r.lastLodLevel_Mesh,N&&o.mesh_lod!=r.lastLodLevel_Mesh){const m=u==null?void 0:u[o.mesh_lod];m&&console.log(`Mesh LOD changed: ${r.lastLodLevel_Mesh} → ${o.mesh_lod} (${m.density.toFixed(0)}) - ${e.name}`)}if(w){const D="saveData"in globalThis.navigator&&globalThis.navigator.saveData===!0;if(r.lastLodLevel_Texture<0){if(o.texture_lod=g.max_count-1,N){const m=g.lods[g.max_count-1];N&&console.log(`First Texture LOD ${o.texture_lod} (${m.max_height}px) - ${e.name}`)}}else{const m=r.lastScreenspaceVolume.x+r.lastScreenspaceVolume.y+r.lastScreenspaceVolume.z;let Y=r.lastScreenCoverage*4;((v=this.context)==null?void 0:v.engine)==="model-viewer"&&(Y*=1.5);const $=O/window.devicePixelRatio*Y;let k=!1;for(let b=g.lods.length-1;b>=0;b--){const f=g.lods[b];if(!(D&&f.max_height>=2048)&&!(ot()&&f.max_height>4096)&&(f.max_height>$||!k&&b===0)){if(k=!0,o.texture_lod=b,o.texture_lod<r.lastLodLevel_Texture){const T=f.max_height;N&&console.log(`Texture LOD changed: ${r.lastLodLevel_Texture} → ${o.texture_lod} = ${T}px
|
|
6
|
-
Screensize: ${
|
|
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}};let P=S;d(P,"registerTexture",(t,e,r,i,o)=>{if(x&&console.log("> Progressive: register texture",i,e.name,e.uuid,e,o),!e){x&&console.error("gltf-progressive: Register texture without texture");return}e.source&&(e.source[ve]=o);const s=o.guid;S.assignLODInformation(t,e,s,r,i),S.lodInfos.set(s,o),S.lowresCache.set(s,e)}),d(P,"registerMesh",(t,e,r,i,o,s)=>{var u;const a=r.geometry;if(!a){x&&console.warn("gltf-progressive: Register mesh without geometry");return}a.userData||(a.userData={}),x&&console.log("> Progressive: register mesh "+r.name,{index:o,uuid:r.uuid},s,r),S.assignLODInformation(t,a,e,i,o),S.lodInfos.set(e,s);let l=S.lowresCache.get(e);l?l.push(r.geometry):l=[r.geometry],S.lowresCache.set(e,l),i>0&&!oe(r)&&Ve(r,a);for(const c of Z)(u=c.onRegisteredNewMesh)==null||u.call(c,r,s)}),d(P,"lodInfos",new Map),d(P,"previouslyLoaded",new Map),d(P,"lowresCache",new Map);class lt{constructor(t,e,r,i){d(this,"url");d(this,"key");d(this,"level");d(this,"index");this.url=t,this.key=e,this.level=r,i!=null&&(this.index=i)}}class pe{constructor(t,e){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,"_currentFrame",0);var o;const i=Math.max(e.frames??2,2);this.frame_start=t,this.frame_capture_end=t+i,this.ready=new Promise(s=>{this._resolve=s}),this.ready.finally(()=>{this._resolved=!0,this._awaiting.length=0}),this._signal=e.signal,(o=this._signal)==null||o.addEventListener("abort",()=>{this.resolveNow()})}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){if(this._resolved){console.warn("PromiseGroup: Trying to add a promise to a resolved group, ignoring.");return}this._currentFrame>this.frame_capture_end||(this._awaiting.push(e),this._addedCount++,e.finally(()=>{this._resolvedCount++,this._awaiting.splice(this._awaiting.indexOf(e),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})}}d(pe,"addPromise",(t,e,r)=>{r.forEach(i=>{i.add(t,e)})});const N=de("debugprogressive"),dt=de("noprogressive"),Me=Symbol("Needle:LODSManager"),De=Symbol("Needle:LODState"),Q=Symbol("Needle:CurrentLOD"),G={mesh_lod:-1,texture_lod:-1};var R,H,me,ee,se,Le,j;const A=class{constructor(t,e){d(this,"renderer");d(this,"context");d(this,"projectionScreenMatrix",new p.Matrix4);d(this,"targetTriangleDensity",2e5);d(this,"skinnedMeshAutoUpdateBoundsInterval",30);d(this,"updateInterval","auto");J(this,R,1);d(this,"pause",!1);d(this,"manual",!1);d(this,"_newPromiseGroups",[]);d(this,"_promiseGroupIds",0);d(this,"_lodchangedlisteners",[]);J(this,H,void 0);J(this,me,new p.Clock);J(this,ee,0);J(this,se,0);J(this,Le,0);J(this,j,0);d(this,"_fpsBuffer",[60,60,60,60,60]);d(this,"_sphere",new p.Sphere);d(this,"_tempBox",new p.Box3);d(this,"_tempBox2",new p.Box3);d(this,"tempMatrix",new p.Matrix4);d(this,"_tempWorldPosition",new p.Vector3);d(this,"_tempBoxSize",new p.Vector3);d(this,"_tempBox2Size",new p.Vector3);this.renderer=t,this.context={...e}}static getObjectLODState(t){return t[De]}static addPlugin(t){Z.push(t)}static removePlugin(t){const e=Z.indexOf(t);e>=0&&Z.splice(e,1)}static get(t,e){if(t[Me])return console.debug("[gltf-progressive] LODsManager already exists for this renderer"),t[Me];const r=new A(t,{engine:"unknown",...e});return t[Me]=r,r}get plugins(){return Z}awaitLoading(t){const e=this._promiseGroupIds++,r=new pe(y(this,ee),{...t});this._newPromiseGroups.push(r);const i=performance.now();return r.ready.finally(()=>{const o=this._newPromiseGroups.indexOf(r);o>=0&&(this._newPromiseGroups.splice(o,1),it()&&performance.measure("LODsManager:awaitLoading",{start:i,detail:{id:e,name:t==null?void 0: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(y(this,ee))}addEventListener(t,e){t==="changed"&&this._lodchangedlisteners.push(e)}removeEventListener(t,e){if(t==="changed"){const r=this._lodchangedlisteners.indexOf(e);r>=0&&this._lodchangedlisteners.splice(r,1)}}enable(){if(y(this,H))return;console.debug("[gltf-progressive] Enabling LODsManager for renderer");let t=0;W(this,H,this.renderer.render);const e=this;Pe(this.renderer),this.renderer.render=function(r,i){const o=e.renderer.getRenderTarget();(o==null||"isXRRenderTarget"in o&&o.isXRRenderTarget)&&(t=0,W(e,ee,y(e,ee)+1),W(e,se,y(e,me).getDelta()),W(e,Le,y(e,Le)+y(e,se)),e._fpsBuffer.shift(),e._fpsBuffer.push(1/y(e,se)),W(e,j,e._fpsBuffer.reduce((a,l)=>a+l)/e._fpsBuffer.length),N&&y(e,ee)%200===0&&console.log("FPS",Math.round(y(e,j)),"Interval:",y(e,R)));const s=t++;y(e,H).call(this,r,i),e.onAfterRender(r,i,s)}}disable(){y(this,H)&&(console.debug("[gltf-progressive] Disabling LODsManager for renderer"),this.renderer.render=y(this,H),W(this,H,void 0))}update(t,e){this.internalUpdate(t,e)}onAfterRender(t,e,r){if(this.pause)return;const o=this.renderer.renderLists.get(t,0).opaque;let s=!0;if(o.length===1){const a=o[0].material;(a.name==="EffectMaterial"||a.name==="CopyShader")&&(s=!1)}if((e.parent&&e.parent.type==="CubeCamera"||r>=1&&e.type==="OrthographicCamera")&&(s=!1),s){if(dt||(this.updateInterval==="auto"?y(this,j)<40&&y(this,R)<10?(W(this,R,y(this,R)+1),N&&console.warn("↓ Reducing LOD updates",y(this,R),y(this,j).toFixed(0))):y(this,j)>=60&&y(this,R)>1&&(W(this,R,y(this,R)-1),N&&console.warn("↑ Increasing LOD updates",y(this,R),y(this,j).toFixed(0))):W(this,R,this.updateInterval),y(this,R)>0&&y(this,ee)%y(this,R)!=0))return;this.internalUpdate(t,e),this._postprocessPromiseGroups()}}internalUpdate(t,e){var l,u;const r=this.renderer.renderLists.get(t,0),i=r.opaque;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse);const o=this.targetTriangleDensity;for(const c of i){if(c.material&&(((l=c.geometry)==null?void 0:l.type)==="BoxGeometry"||((u=c.geometry)==null?void 0:u.type)==="BufferGeometry")&&(c.material.name==="SphericalGaussianBlur"||c.material.name=="BackgroundCubeMaterial"||c.material.name==="CubemapFromEquirect"||c.material.name==="EquirectangularToCubeUV")){N&&(c.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(c.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",c,c.material.name,c.material.type)));continue}switch(c.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}if(N==="color"&&c.material&&!c.object.progressive_debug_color){c.object.progressive_debug_color=!0;const g=Math.random()*16777215,w=new p.MeshStandardMaterial({color:g});c.object.material=w}const h=c.object;(h instanceof p.Mesh||h.isMesh)&&this.updateLODs(t,e,h,o)}const s=r.transparent;for(const c of s){const h=c.object;(h instanceof p.Mesh||h.isMesh)&&this.updateLODs(t,e,h,o)}const a=r.transmissive;for(const c of a){const h=c.object;(h instanceof p.Mesh||h.isMesh)&&this.updateLODs(t,e,h,o)}}updateLODs(t,e,r,i){var a,l;r.userData||(r.userData={});let o=r[De];if(o||(o=new ct,r[De]=o),o.frames++<2)return;for(const u of Z)(a=u.onBeforeUpdateLOD)==null||a.call(u,this.renderer,t,e,r);const s=A.overrideGlobalLodLevel!==void 0?A.overrideGlobalLodLevel:te;s>=0?(G.mesh_lod=s,G.texture_lod=s):(this.calculateLodLevel(e,r,o,i,G),G.mesh_lod=Math.round(G.mesh_lod),G.texture_lod=Math.round(G.texture_lod)),G.mesh_lod>=0&&this.loadProgressiveMeshes(r,G.mesh_lod),r.material&&G.texture_lod>=0&&this.loadProgressiveTextures(r.material,G.texture_lod),x&&r.material&&!r.isGizmo&&We(r.material);for(const u of Z)(l=u.onAfterUpdatedLOD)==null||l.call(u,this.renderer,t,e,r,G);o.lastLodLevel_Mesh=G.mesh_lod,o.lastLodLevel_Texture=G.texture_lod}loadProgressiveTextures(t,e){if(!t)return;if(Array.isArray(t)){for(const o of t)this.loadProgressiveTextures(o,e);return}let r=!1;(t[Q]===void 0||e<t[Q])&&(r=!0);const i=t["DEBUG:LOD"];if(i!=null&&(r=t[Q]!=i,e=i),r){t[Q]=e;const o=P.assignTextureLOD(t,e).then(s=>{this._lodchangedlisteners.forEach(a=>a({type:"texture",level:e,object:t}))});pe.addPromise("texture",o,this._newPromiseGroups)}}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);let r=t[Q]!==e;const i=t["DEBUG:LOD"];if(i!=null&&(r=t[Q]!=i,e=i),r){t[Q]=e;const o=t.geometry,s=P.assignMeshLOD(t,e).then(a=>(a&&t[Q]==e&&o!=t.geometry&&this._lodchangedlisteners.forEach(l=>l({type:"mesh",level:e,object:t})),a));return pe.addPromise("mesh",s,this._newPromiseGroups),s}return Promise.resolve(null)}static isInside(t,e){const r=t.min,i=t.max,o=(r.x+i.x)*.5,s=(r.y+i.y)*.5;return this._tempPtInside.set(o,s,r.z).applyMatrix4(e).z<0}calculateLodLevel(t,e,r,i,o){var V,K,v;if(!e){o.mesh_lod=-1,o.texture_lod=-1;return}if(!t){o.mesh_lod=-1,o.texture_lod=-1;return}let a=10+1,l=!1;if(N&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const u=(V=P.getMeshLODExtension(e.geometry))==null?void 0:V.lods,c=P.getPrimitiveIndex(e.geometry),h=u&&u.length>0,g=P.getMaterialMinMaxLODsCount(e.material),w=(g==null?void 0:g.min_count)!=1/0&&g.min_count>0&&g.max_count>0;if(!h&&!w){o.mesh_lod=0,o.texture_lod=0;return}h||(l=!0,a=0);const O=this.renderer.domElement.clientHeight||this.renderer.domElement.height;let _=e.geometry.boundingBox;if(e.type==="SkinnedMesh"){const D=e;if(!D.boundingBox)D.computeBoundingBox();else if(this.skinnedMeshAutoUpdateBoundsInterval>0&&r.frames%this.skinnedMeshAutoUpdateBoundsInterval===0){const m=oe(D),Y=D.geometry;m&&(D.geometry=m),D.computeBoundingBox(),D.geometry=Y}_=D.boundingBox}if(_){const D=t;if(e.geometry.attributes.color&&e.geometry.attributes.color.count<100&&e.geometry.boundingSphere){this._sphere.copy(e.geometry.boundingSphere),this._sphere.applyMatrix4(e.matrixWorld);const L=t.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(L)){o.mesh_lod=0,o.texture_lod=0;return}}if(this._tempBox.copy(_),this._tempBox.applyMatrix4(e.matrixWorld),D.isPerspectiveCamera&&A.isInside(this._tempBox,this.projectionScreenMatrix)){o.mesh_lod=0,o.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&D.isPerspectiveCamera&&D.fov>70){const L=this._tempBox.min,M=this._tempBox.max;let E=L.x,$=L.y,z=M.x,ie=M.y;const ce=2,xe=1.5,ue=(L.x+M.x)*.5,fe=(L.y+M.y)*.5;E=(E-ue)*ce+ue,$=($-fe)*ce+fe,z=(z-ue)*ce+ue,ie=(ie-fe)*ce+fe;const Ke=E<0&&z>0?0:Math.min(Math.abs(L.x),Math.abs(M.x)),Ye=$<0&&ie>0?0:Math.min(Math.abs(L.y),Math.abs(M.y)),_e=Math.max(Ke,Ye);r.lastCentrality=(xe-_e)*(xe-_e)*(xe-_e)}else r.lastCentrality=1;const m=this._tempBox.getSize(this._tempBoxSize);m.multiplyScalar(.5),screen.availHeight>0&&O>0&&m.multiplyScalar(O/screen.availHeight),t.isPerspectiveCamera?m.x*=t.aspect:t.isOrthographicCamera;const Y=t.matrixWorldInverse,C=this._tempBox2;C.copy(_),C.applyMatrix4(e.matrixWorld),C.applyMatrix4(Y);const F=C.getSize(this._tempBox2Size),k=Math.max(F.x,F.y);if(Math.max(m.x,m.y)!=0&&k!=0&&(m.z=F.z/Math.max(F.x,F.y)*Math.max(m.x,m.y)),r.lastScreenCoverage=Math.max(m.x,m.y,m.z),r.lastScreenspaceVolume.copy(m),r.lastScreenCoverage*=r.lastCentrality,N&&A.debugDrawLine){const L=this.tempMatrix.copy(this.projectionScreenMatrix);L.invert();const M=A.corner0,E=A.corner1,$=A.corner2,z=A.corner3;M.copy(this._tempBox.min),E.copy(this._tempBox.max),E.x=M.x,$.copy(this._tempBox.max),$.y=M.y,z.copy(this._tempBox.max);const ie=(M.z+z.z)*.5;M.z=E.z=$.z=z.z=ie,M.applyMatrix4(L),E.applyMatrix4(L),$.applyMatrix4(L),z.applyMatrix4(L),A.debugDrawLine(M,E,255),A.debugDrawLine(M,$,255),A.debugDrawLine(E,z,255),A.debugDrawLine($,z,255)}let f=999;if(u&&r.lastScreenCoverage>0)for(let L=0;L<u.length;L++){const M=u[L];if((((K=M.densities)==null?void 0:K[c])||M.density||1e-5)/r.lastScreenCoverage<i){f=L;break}}f<a&&(a=f,l=!0)}if(l?o.mesh_lod=a:o.mesh_lod=r.lastLodLevel_Mesh,N&&o.mesh_lod!=r.lastLodLevel_Mesh){const m=u==null?void 0:u[o.mesh_lod];m&&console.log(`Mesh LOD changed: ${r.lastLodLevel_Mesh} → ${o.mesh_lod} (${m.density.toFixed(0)}) - ${e.name}`)}if(w){const D="saveData"in globalThis.navigator&&globalThis.navigator.saveData===!0;if(r.lastLodLevel_Texture<0){if(o.texture_lod=g.max_count-1,N){const m=g.lods[g.max_count-1];N&&console.log(`First Texture LOD ${o.texture_lod} (${m.max_height}px) - ${e.name}`)}}else{const m=r.lastScreenspaceVolume.x+r.lastScreenspaceVolume.y+r.lastScreenspaceVolume.z;let Y=r.lastScreenCoverage*4;((v=this.context)==null?void 0:v.engine)==="model-viewer"&&(Y*=1.5);const F=O/window.devicePixelRatio*Y;let k=!1;for(let b=g.lods.length-1;b>=0;b--){const f=g.lods[b];if(!(D&&f.max_height>=2048)&&!(ot()&&f.max_height>4096)&&(f.max_height>F||!k&&b===0)){if(k=!0,o.texture_lod=b,o.texture_lod<r.lastLodLevel_Texture){const T=f.max_height;N&&console.log(`Texture LOD changed: ${r.lastLodLevel_Texture} → ${o.texture_lod} = ${T}px
|
|
6
|
+
Screensize: ${F.toFixed(0)}px, Coverage: ${(100*r.lastScreenCoverage).toFixed(2)}%, Volume ${m.toFixed(1)}
|
|
7
7
|
${e.name}`)}break}}}}else o.texture_lod=0}};let B=A;R=new WeakMap,H=new WeakMap,me=new WeakMap,ee=new WeakMap,se=new WeakMap,Le=new WeakMap,j=new WeakMap,d(B,"debugDrawLine"),d(B,"overrideGlobalLodLevel"),d(B,"corner0",new p.Vector3),d(B,"corner1",new p.Vector3),d(B,"corner2",new p.Vector3),d(B,"corner3",new p.Vector3),d(B,"_tempPtInside",new p.Vector3);class ct{constructor(){d(this,"frames",0);d(this,"lastLodLevel_Mesh",-1);d(this,"lastLodLevel_Texture",-1);d(this,"lastScreenCoverage",0);d(this,"lastScreenspaceVolume",new p.Vector3);d(this,"lastCentrality",0)}}const Be=Symbol("NEEDLE_mesh_lod"),he=Symbol("NEEDLE_texture_lod");let le=null;function Ee(){const n=ut();n&&(n.mapURLs(function(t){return Re(),t}),Re(),le==null||le.disconnect(),le=new MutationObserver(t=>{t.forEach(e=>{e.addedNodes.forEach(r=>{r instanceof HTMLElement&&r.tagName.toLowerCase()==="model-viewer"&&qe(r)})})}),le.observe(document,{childList:!0,subtree:!0}))}function ut(){if(typeof customElements>"u")return null;const n=customElements.get("model-viewer");return n||(customElements.whenDefined("model-viewer").then(()=>{console.debug("[gltf-progressive] model-viewer defined"),Ee()}),null)}function Re(){if(typeof document>"u")return;document.querySelectorAll("model-viewer").forEach(t=>{qe(t)})}const Ie=new WeakSet;let ft=0;function qe(n){if(!n||Ie.has(n))return null;Ie.add(n),console.debug("[gltf-progressive] found new model-viewer..."+ ++ft+`
|
|
8
|
-
`,n.getAttribute("src"));let t=null,e=null,r=null;for(let i=n;i!=null;i=Object.getPrototypeOf(i)){const o=Object.getOwnPropertySymbols(i),s=o.find(u=>u.toString()=="Symbol(renderer)"),a=o.find(u=>u.toString()=="Symbol(scene)"),l=o.find(u=>u.toString()=="Symbol(needsRender)");!t&&s!=null&&(t=n[s].threeRenderer),!e&&a!=null&&(e=n[a]),!r&&l!=null&&(r=n[l])}if(t&&e){let i=function(){if(r){let s=0,a=setInterval(()=>{if(s++>5){clearInterval(a);return}r==null||r.call(n)},300)}};console.debug("[gltf-progressive] setup model-viewer");const o=B.get(t,{engine:"model-viewer"});return B.addPlugin(new ht),o.enable(),o.addEventListener("changed",()=>{r==null||r.call(n)}),n.addEventListener("model-visibility",s=>{s.detail.visible&&(r==null||r.call(n))}),n.addEventListener("load",()=>{i()}),()=>{o.disable()}}return null}class ht{constructor(){d(this,"_didWarnAboutMissingUrl",!1)}onBeforeUpdateLOD(t,e,r,i){this.tryParseMeshLOD(e,i),this.tryParseTextureLOD(e,i)}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[he]==!0)return;e[he]=!0;const r=this.tryGetCurrentGLTF(t),i=this.tryGetCurrentModelViewer(t),o=this.getUrl(i);if(o&&r&&e.material){let s=function(l){var c,h,g;if(l[he]==!0)return;l[he]=!0,l.userData&&(l.userData.LOD=-1);const u=Object.keys(l);for(let w=0;w<u.length;w++){const O=u[w],_=l[O];if((_==null?void 0:_.isTexture)===!0){const V=(h=(c=_.userData)==null?void 0:c.associations)==null?void 0:h.textures;if(V==null)continue;const K=r.parser.json.textures[V];if(!K){console.warn("Texture data not found for texture index "+V);continue}if((g=K==null?void 0:K.extensions)!=null&&g[q]){const v=K.extensions[q];v&&o&&P.registerTexture(o,_,v.lods.length,V,v)}}}};const a=e.material;if(Array.isArray(a))for(const l of a)s(l);else s(a)}}tryParseMeshLOD(t,e){var s,a;if(e[Be]==!0)return;e[Be]=!0;const r=this.tryGetCurrentModelViewer(t),i=this.getUrl(r);if(!i)return;const o=(a=(s=e.userData)==null?void 0:s.gltfExtensions)==null?void 0:a[q];if(o&&i){const l=e.uuid;P.registerMesh(i,l,e,0,o.lods.length,o)}}}function Xe(n,t,e,r){Pe(t),Ae(e),Ce(e,{progressive:!0,...r==null?void 0:r.hints}),e.register(o=>new P(o,n));const i=B.get(t);return(r==null?void 0:r.enableLODsManager)!==!1&&i.enable(),i}Ee();if(!nt){const n={gltfProgressive:{useNeedleProgressive:Xe,LODsManager:B,configureLoader:Ce,getRaycastMesh:oe,useRaycastMeshes:ze}};if(!globalThis.Needle)globalThis.Needle=n;else for(const t in n)globalThis.Needle[t]=n[t]}exports.EXTENSION_NAME=q;exports.LODsManager=B;exports.NEEDLE_progressive=P;exports.VERSION=ke;exports.addDracoAndKTX2Loaders=Ae;exports.configureLoader=Ce;exports.createLoaders=Pe;exports.getRaycastMesh=oe;exports.patchModelViewer=Ee;exports.registerRaycastMesh=Ve;exports.setDracoDecoderLocation
|
|
8
|
+
`,n.getAttribute("src"));let t=null,e=null,r=null;for(let i=n;i!=null;i=Object.getPrototypeOf(i)){const o=Object.getOwnPropertySymbols(i),s=o.find(u=>u.toString()=="Symbol(renderer)"),a=o.find(u=>u.toString()=="Symbol(scene)"),l=o.find(u=>u.toString()=="Symbol(needsRender)");!t&&s!=null&&(t=n[s].threeRenderer),!e&&a!=null&&(e=n[a]),!r&&l!=null&&(r=n[l])}if(t&&e){let i=function(){if(r){let s=0,a=setInterval(()=>{if(s++>5){clearInterval(a);return}r==null||r.call(n)},300)}};console.debug("[gltf-progressive] setup model-viewer");const o=B.get(t,{engine:"model-viewer"});return B.addPlugin(new ht),o.enable(),o.addEventListener("changed",()=>{r==null||r.call(n)}),n.addEventListener("model-visibility",s=>{s.detail.visible&&(r==null||r.call(n))}),n.addEventListener("load",()=>{i()}),()=>{o.disable()}}return null}class ht{constructor(){d(this,"_didWarnAboutMissingUrl",!1)}onBeforeUpdateLOD(t,e,r,i){this.tryParseMeshLOD(e,i),this.tryParseTextureLOD(e,i)}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[he]==!0)return;e[he]=!0;const r=this.tryGetCurrentGLTF(t),i=this.tryGetCurrentModelViewer(t),o=this.getUrl(i);if(o&&r&&e.material){let s=function(l){var c,h,g;if(l[he]==!0)return;l[he]=!0,l.userData&&(l.userData.LOD=-1);const u=Object.keys(l);for(let w=0;w<u.length;w++){const O=u[w],_=l[O];if((_==null?void 0:_.isTexture)===!0){const V=(h=(c=_.userData)==null?void 0:c.associations)==null?void 0:h.textures;if(V==null)continue;const K=r.parser.json.textures[V];if(!K){console.warn("Texture data not found for texture index "+V);continue}if((g=K==null?void 0:K.extensions)!=null&&g[q]){const v=K.extensions[q];v&&o&&P.registerTexture(o,_,v.lods.length,V,v)}}}};const a=e.material;if(Array.isArray(a))for(const l of a)s(l);else s(a)}}tryParseMeshLOD(t,e){var s,a;if(e[Be]==!0)return;e[Be]=!0;const r=this.tryGetCurrentModelViewer(t),i=this.getUrl(r);if(!i)return;const o=(a=(s=e.userData)==null?void 0:s.gltfExtensions)==null?void 0:a[q];if(o&&i){const l=e.uuid;P.registerMesh(i,l,e,0,o.lods.length,o)}}}function Xe(n,t,e,r){Pe(t),Ae(e),Ce(e,{progressive:!0,...r==null?void 0:r.hints}),e.register(o=>new P(o,n));const i=B.get(t);return(r==null?void 0:r.enableLODsManager)!==!1&&i.enable(),i}Ee();if(!nt){const n={gltfProgressive:{useNeedleProgressive:Xe,LODsManager:B,configureLoader:Ce,getRaycastMesh:oe,useRaycastMeshes:ze}};if(!globalThis.Needle)globalThis.Needle=n;else for(const t in n)globalThis.Needle[t]=n[t]}exports.EXTENSION_NAME=q;exports.LODsManager=B;exports.NEEDLE_progressive=P;exports.VERSION=ke;exports.addDracoAndKTX2Loaders=Ae;exports.configureLoader=Ce;exports.createLoaders=Pe;exports.getRaycastMesh=oe;exports.patchModelViewer=Ee;exports.registerRaycastMesh=Ve;exports.setDracoDecoderLocation=$e;exports.setKTX2TranscoderLocation=Ne;exports.useNeedleProgressive=Xe;exports.useRaycastMeshes=ze;
|
package/lib/lods.manager.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Camera, Material, Object3D, Scene, Texture, Vector3, WebGLRenderer } from "three";
|
|
2
2
|
import { NEEDLE_progressive_plugin } from "./plugins/plugin.js";
|
|
3
|
-
import { PromiseGroupOptions } from "./lods.
|
|
3
|
+
import { PromiseGroupOptions } from "./lods.promise.js";
|
|
4
4
|
export type LODManagerContext = {
|
|
5
5
|
engine: "three" | "needle-engine" | "model-viewer" | "react-three-fiber" | "unknown";
|
|
6
6
|
};
|
package/lib/lods.manager.js
CHANGED
|
@@ -5,7 +5,7 @@ import { getParam, isDevelopmentServer, isMobileDevice } from "./utils.internal.
|
|
|
5
5
|
import { plugins } from "./plugins/plugin.js";
|
|
6
6
|
import { getRaycastMesh } from "./utils.js";
|
|
7
7
|
import { applyDebugSettings, debug, debug_OverrideLodLevel } from "./lods.debug.js";
|
|
8
|
-
import { PromiseGroup } from "./lods.
|
|
8
|
+
import { PromiseGroup } from "./lods.promise.js";
|
|
9
9
|
const debugProgressiveLoading = getParam("debugprogressive");
|
|
10
10
|
const suppressProgressiveLoading = getParam("noprogressive");
|
|
11
11
|
const $lodsManager = Symbol("Needle:LODSManager");
|
|
@@ -31,7 +31,7 @@ export class PromiseGroup {
|
|
|
31
31
|
/** These promises are currently being awaited */
|
|
32
32
|
_awaiting = [];
|
|
33
33
|
constructor(frame, options) {
|
|
34
|
-
const minFrames =
|
|
34
|
+
const minFrames = 2; // wait at least 2 frames to capture promises
|
|
35
35
|
const framesToCapture = Math.max(options.frames ?? minFrames, minFrames); // default to 2 frames and make sure it's at least 2 frames
|
|
36
36
|
this.frame_start = frame;
|
|
37
37
|
this.frame_capture_end = frame + framesToCapture;
|
package/lib/version.js
CHANGED
package/package.json
CHANGED
|
File without changes
|