UNPKG

@animech-public/playcanvas

Version:
2 lines (1 loc) 4.47 kB
import{GraphNode as t}from"../../scene/graph-node.js";import{MeshInstance as e}from"../../scene/mesh-instance.js";import{Model as s}from"../../scene/model.js";import{MorphInstance as n}from"../../scene/morph-instance.js";import{SkinInstance as a}from"../../scene/skin-instance.js";import{SkinInstanceCache as r}from"../../scene/skin-instance-cache.js";import{Entity as i}from"../entity.js";import{Asset as o}from"../asset/asset.js";class l{constructor(t,e,s,n){const a=function(t,n,a){const r=l.createAsset(e.name,t,n,a);return s.add(r),r},r=[];for(let e=0;e<t.renders.length;++e)r.push(a("render",t.renders[e],e));const i=[];for(let e=0;e<t.materials.length;++e)i.push(a("material",t.materials[e],e));const o=[];for(let e=0;e<t.animations.length;++e)o.push(a("animation",t.animations[e],e));this.data=t,this._model=null,this._assetName=e.name,this._assets=s,this._defaultMaterial=n,this.renders=r,this.materials=i,this.textures=t.textures,this.animations=o}get model(){if(!this._model){const t=l.createModel(this.data,this._defaultMaterial),e=l.createAsset(this._assetName,"model",t,0);this._assets.add(e),this._model=e}return this._model}static createAsset(t,e,s,n){const a=new o(`${t}/${e}/${n}`,e,{url:""});return a.resource=s,a.loaded=!0,a}instantiateModelEntity(t){const e=new i;return e.addComponent("model",Object.assign({type:"asset",asset:this.model},t)),e}instantiateRenderEntity(t){const s=this._defaultMaterial,a=[],o=function(t,r,i,o,l,h,c){const m=l[i.id],d=void 0===m?s:o[m],u=new e(i,d);return i.morph&&(u.morphInstance=new n(i.morph)),c.hasOwnProperty("skin")&&a.push({meshInstance:u,rootBone:t,entity:r}),u},h=(e,s,n)=>{const a=new i;s._cloneInternal(a),e||(e=a);let r=null,l=null;for(let t=0;t<n.nodes.length;t++){if(n.nodes[t]===s){const s=n.gltf.nodes[t];if(s.hasOwnProperty("mesh")){const t=n.renders[s.mesh].meshes;l=this.renders[s.mesh];for(let i=0;i<t.length;i++){const l=t[i];if(l){const t=o(e,a,l,n.materials,n.meshDefaultMaterials,n.skins,s);r||(r=[]),r.push(t)}}}if(n.lights){const t=n.lights.get(s);t&&a.addChild(t.clone())}if(n.cameras){const t=n.cameras.get(s);t&&t.camera.system.cloneComponent(t,a)}}}r&&(a.addComponent("render",Object.assign({type:"asset",meshInstances:r},t)),a.render.assignAsset(l));const c=s.children;for(let t=0;t<c.length;t++){const s=h(e,c[t],n);a.addChild(s)}return a},c=[];for(const t of this.data.scenes)c.push(h(null,t,this.data));return a.forEach((t=>{t.meshInstance.skinInstance=r.createCachedSkinInstance(t.meshInstance.mesh.skin,t.rootBone,t.entity),t.meshInstance.node.render.rootBone=t.rootBone})),l.createSceneHierarchy(c,i)}getMaterialVariants(){return this.data.variants?Object.keys(this.data.variants):[]}applyMaterialVariant(t,e){const s=e?this.data.variants[e]:null;if(void 0===s)return;const n=t.findComponents("render");for(let t=0;t<n.length;t++){const e=n[t];this._applyMaterialVariant(s,e.meshInstances)}}applyMaterialVariantInstances(t,e){const s=e?this.data.variants[e]:null;void 0!==s&&this._applyMaterialVariant(s,t)}_applyMaterialVariant(t,e){e.forEach((e=>{if(null===t)e.material=this._defaultMaterial;else{const s=this.data.meshVariants[e.mesh.id];s&&(e.material=this.data.materials[s[t]])}}))}static createSceneHierarchy(t,e){let s=null;if(1===t.length)s=t[0];else{s=new e("SceneGroup");for(const e of t)s.addChild(e)}return s}static createModel(r,i){const o=function(t,s,a,o,l,h,c){const m=r.meshDefaultMaterials[s.id],d=void 0===m?i:l[m],u=new e(s,d,h);if(s.morph){const e=new n(s.morph);u.morphInstance=e,t.morphInstances.push(e)}if(c.hasOwnProperty("skin")){const e=c.skin,n=a[e];s.skin=n;const r=o[e];u.skinInstance=r,t.skinInstances.push(r)}t.meshInstances.push(u)},h=new s,c=[];for(const t of r.skins){const e=new a(t);e.bones=t.bones,c.push(e)}h.graph=l.createSceneHierarchy(r.scenes,t);for(let t=0;t<r.nodes.length;t++){const e=r.nodes[t];if(e.root===h.graph){const s=r.gltf.nodes[t];if(s.hasOwnProperty("mesh")){const t=r.renders[s.mesh].meshes;for(let n=0;n<t.length;n++){const a=t[n];a&&o(h,a,r.skins,c,r.materials,e,s)}}}}return h}destroy(){const t=this._assets,e=function(e){t.remove(e),e.unload()},s=function(t){t.forEach((t=>{e(t)}))};this.animations&&(s(this.animations),this.animations=null),this.textures&&(s(this.textures),this.textures=null),this.materials&&(s(this.materials),this.materials=null),this.renders&&(s(this.renders),this.renders=null),this._model&&(e(this._model),this._model=null),this.data=null,this.assets=null}}export{l as GlbContainerResource};