@babylonjs/viewer
Version:
The Babylon Viewer aims to simplify a specific but common Babylon.js use case: loading, viewing, and interacting with a 3D model.
3 lines (2 loc) • 6.2 kB
JavaScript
import{O as e,bv as s,bo as t,bp as i}from"./index-BPURObVq.esm.min.js";import{b as r,A as a}from"./glTFLoader.pure-Bdyl6AcK.esm.min.js";import"./morphTargetManager-CdEb1BHc.esm.min.js";import"./bone.pure-BcPT5kCP.esm.min.js";import"./skeleton-DinTjF3y.esm.min.js";import"./assetContainer-CAncviZo.esm.min.js";import"./objectModelMapping-ClgDmo5Q.esm.min.js";import"./spotLight.pure-5s2DDDIt.esm.min.js";const o="MSFT_lod";class n{constructor(s){this.name=o,this.order=100,this.maxLODsToLoad=10,this.onNodeLODsLoadedObservable=new e,this.onMaterialLODsLoadedObservable=new e,this._bufferLODs=new Array,this._nodeIndexLOD=null,this._nodeSignalLODs=new Array,this._nodePromiseLODs=new Array,this._nodeBufferLODs=new Array,this._materialIndexLOD=null,this._materialSignalLODs=new Array,this._materialPromiseLODs=new Array,this._materialBufferLODs=new Array,this._loader=s,this.maxLODsToLoad=this._loader.parent.extensionOptions[o]?.maxLODsToLoad??this.maxLODsToLoad,this.enabled=this._loader.isExtensionUsed(o)}dispose(){this._loader=null,this._nodeIndexLOD=null,this._nodeSignalLODs.length=0,this._nodePromiseLODs.length=0,this._nodeBufferLODs.length=0,this._materialIndexLOD=null,this._materialSignalLODs.length=0,this._materialPromiseLODs.length=0,this._materialBufferLODs.length=0,this.onMaterialLODsLoadedObservable.clear(),this.onNodeLODsLoadedObservable.clear()}onReady(){for(let e=0;e<this._nodePromiseLODs.length;e++){const s=Promise.all(this._nodePromiseLODs[e]).then(()=>{0!==e&&(this._loader.endPerformanceCounter(`Node LOD ${e}`),this._loader.log(`Loaded node LOD ${e}`)),this.onNodeLODsLoadedObservable.notifyObservers(e),e!==this._nodePromiseLODs.length-1&&(this._loader.startPerformanceCounter(`Node LOD ${e+1}`),this._loadBufferLOD(this._nodeBufferLODs,e+1),this._nodeSignalLODs[e]&&this._nodeSignalLODs[e].resolve())});this._loader._completePromises.push(s)}for(let e=0;e<this._materialPromiseLODs.length;e++){const s=Promise.all(this._materialPromiseLODs[e]).then(()=>{0!==e&&(this._loader.endPerformanceCounter(`Material LOD ${e}`),this._loader.log(`Loaded material LOD ${e}`)),this.onMaterialLODsLoadedObservable.notifyObservers(e),e!==this._materialPromiseLODs.length-1&&(this._loader.startPerformanceCounter(`Material LOD ${e+1}`),this._loadBufferLOD(this._materialBufferLODs,e+1),this._materialSignalLODs[e]&&this._materialSignalLODs[e].resolve())});this._loader._completePromises.push(s)}}loadSceneAsync(e,s){const t=this._loader.loadSceneAsync(e,s);return this._loadBufferLOD(this._bufferLODs,0),t}loadNodeAsync(e,t,i){return r.LoadExtensionAsync(e,t,this.name,async(e,r)=>{let a;const o=this._getLODs(e,t,this._loader.gltf.nodes,r.ids);this._loader.logOpen(`${e}`);for(let e=0;e<o.length;e++){const t=o[e];0!==e&&(this._nodeIndexLOD=e,this._nodeSignalLODs[e]=this._nodeSignalLODs[e]||new s);const r=e=>{i(e),e.setEnabled(!1)},n=this._loader.loadNodeAsync(`/nodes/${t.index}`,t,r).then(s=>{if(0!==e){const s=o[e-1];s._babylonTransformNode&&(this._disposeTransformNode(s._babylonTransformNode),delete s._babylonTransformNode)}return s.setEnabled(!0),s});this._nodePromiseLODs[e]=this._nodePromiseLODs[e]||[],0===e?a=n:(this._nodeIndexLOD=null,this._nodePromiseLODs[e].push(n))}return this._loader.logClose(),await a})}_loadMaterialAsync(e,s,t,i,a){return this._nodeIndexLOD?null:r.LoadExtensionAsync(e,s,this.name,async(e,r)=>{let o;const n=this._getLODs(e,s,this._loader.gltf.materials,r.ids);this._loader.logOpen(`${e}`);for(let e=0;e<n.length;e++){const s=n[e];0!==e&&(this._materialIndexLOD=e);const r=this._loader._loadMaterialAsync(`/materials/${s.index}`,s,t,i,s=>{0===e&&a(s)}).then(s=>{if(0!==e){a(s);const t=n[e-1]._data;t[i]&&(this._disposeMaterials([t[i].babylonMaterial]),delete t[i])}return s});this._materialPromiseLODs[e]=this._materialPromiseLODs[e]||[],0===e?o=r:(this._materialIndexLOD=null,this._materialPromiseLODs[e].push(r))}return this._loader.logClose(),await o})}_loadUriAsync(e,t,i){if(null!==this._nodeIndexLOD){this._loader.log("deferred");const r=this._nodeIndexLOD-1;return this._nodeSignalLODs[r]=this._nodeSignalLODs[r]||new s,this._nodeSignalLODs[this._nodeIndexLOD-1].promise.then(async()=>await this._loader.loadUriAsync(e,t,i))}if(null!==this._materialIndexLOD){this._loader.log("deferred");const r=this._materialIndexLOD-1;return this._materialSignalLODs[r]=this._materialSignalLODs[r]||new s,this._materialSignalLODs[r].promise.then(async()=>await this._loader.loadUriAsync(e,t,i))}return null}loadBufferAsync(e,t,i,r){if(this._loader.parent.useRangeRequests&&!t.uri){if(!this._loader.bin)throw new Error(`${e}: Uri is missing or the binary glTF is missing its binary chunk`);const t=async(e,t)=>{const a=i,o=a+r-1;let n=e[t];return n?(n.start=Math.min(n.start,a),n.end=Math.max(n.end,o)):(n={start:a,end:o,loaded:new s},e[t]=n),await n.loaded.promise.then(e=>new Uint8Array(e.buffer,e.byteOffset+i-n.start,r))};return this._loader.log("deferred"),null!==this._nodeIndexLOD?t(this._nodeBufferLODs,this._nodeIndexLOD):null!==this._materialIndexLOD?t(this._materialBufferLODs,this._materialIndexLOD):t(this._bufferLODs,0)}return null}_loadBufferLOD(e,s){const t=e[s];t&&(this._loader.log(`Loading buffer range [${t.start}-${t.end}]`),this._loader.bin.readAsync(t.start,t.end-t.start+1).then(e=>{t.loaded.resolve(e)},e=>{t.loaded.reject(e)}))}_getLODs(e,s,t,i){if(this.maxLODsToLoad<=0)throw new Error("maxLODsToLoad must be greater than zero");const r=[];for(let s=i.length-1;s>=0;s--)if(r.push(a.Get(`${e}/ids/${i[s]}`,t,i[s])),r.length===this.maxLODsToLoad)return r;return r.push(s),r}_disposeTransformNode(e){const s=[],t=e.material;t&&s.push(t);for(const t of e.getChildMeshes())t.material&&s.push(t.material);e.dispose();const i=s.filter(e=>this._loader.babylonScene.meshes.every(s=>s.material!=e));this._disposeMaterials(i)}_disposeMaterials(e){const s={};for(const t of e){for(const e of t.getActiveTextures())s[e.uniqueId]=e;t.dispose()}for(const e in s)for(const t of this._loader.babylonScene.materials)t.hasTexture(s[e])&&delete s[e];for(const e in s)s[e].dispose()}}let l=!1;function d(){l||(l=!0,t(o),i(o,!0,e=>new n(e)))}d();export{n as MSFT_lod,d as RegisterMSFT_lod};
//# sourceMappingURL=MSFT_lod-CjiuxLSj.esm.min.js.map