@animech-public/playcanvas
Version:
PlayCanvas WebGL game engine
2 lines (1 loc) • 12.5 kB
JavaScript
import{LAYERID_WORLD as t}from"../../../scene/constants.js";import{BatchGroup as s}from"../../../scene/batching/batch-group.js";import{GraphNode as e}from"../../../scene/graph-node.js";import{MeshInstance as i}from"../../../scene/mesh-instance.js";import{Model as a}from"../../../scene/model.js";import{getShapePrimitive as h}from"../../graphics/primitive-cache.js";import{Asset as n}from"../../asset/asset.js";import{Component as l}from"../component.js";class o extends l{constructor(s,e){super(s,e),this._type="asset",this._asset=null,this._model=null,this._mapping={},this._castShadows=!0,this._receiveShadows=!0,this._materialAsset=null,this._material=void 0,this._castShadowsLightmap=!0,this._lightmapped=!1,this._lightmapSizeMultiplier=1,this.isStatic=!1,this._layers=[t],this._batchGroupId=-1,this._customAabb=null,this._area=null,this._materialEvents=null,this._clonedModel=!1,this._evtLayersChanged=null,this._evtLayerAdded=null,this._evtLayerRemoved=null,this._material=s.defaultMaterial,e.on("remove",this.onRemoveChild,this),e.on("removehierarchy",this.onRemoveChild,this),e.on("insert",this.onInsertChild,this),e.on("inserthierarchy",this.onInsertChild,this)}set meshInstances(t){this._model&&(this._model.meshInstances=t)}get meshInstances(){return this._model?this._model.meshInstances:null}set customAabb(t){if(this._customAabb=t,this._model){const t=this._model.meshInstances;if(t)for(let s=0;s<t.length;s++)t[s].setCustomAabb(this._customAabb)}}get customAabb(){return this._customAabb}set type(t){if(this._type!==t)if(this._area=null,this._type=t,"asset"===t)null!==this._asset?this._bindModelAsset(this._asset):this.model=null;else{const s=h(this.system.app.graphicsDevice,t);this._area=s.area;const n=s.mesh,l=new e,o=new a;o.graph=l,o.meshInstances=[new i(n,this._material,l)],this.model=o,this._asset=null}}get type(){return this._type}set asset(t){const s=this.system.app.assets;let e=t;if(t instanceof n&&(e=t.id),this._asset!==e){if(this._asset){s.off(`add:${this._asset}`,this._onModelAssetAdded,this);const t=s.get(this._asset);t&&this._unbindModelAsset(t)}if(this._asset=e,this._asset){const t=s.get(this._asset);t?this._bindModelAsset(t):(this.model=null,s.on(`add:${this._asset}`,this._onModelAssetAdded,this))}else this.model=null}}get asset(){return this._asset}set model(t){if(this._model!==t&&(!t||!t._immutable)&&(this._model&&(this._model._immutable=!1,this.removeModelFromLayers(),this._model.getGraph().destroy(),delete this._model._entity,this._clonedModel&&(this._model.destroy(),this._clonedModel=!1)),this._model=t,this._model)){this._model._immutable=!0;const t=this._model.meshInstances;for(let s=0;s<t.length;s++)t[s].castShadow=this._castShadows,t[s].receiveShadow=this._receiveShadows,t[s].setCustomAabb(this._customAabb);this.lightmapped=this._lightmapped,this.entity.addChild(this._model.graph),this.enabled&&this.entity.enabled&&this.addModelToLayers(),this._model._entity=this.entity,this.entity.animation&&this.entity.animation.setModel(this._model),this.entity.anim&&this.entity.anim.rebind(),"asset"===this.type?this.mapping=this._mapping:this._unsetMaterialEvents()}}get model(){return this._model}set lightmapped(t){if(t!==this._lightmapped&&(this._lightmapped=t,this._model)){const s=this._model.meshInstances;for(let e=0;e<s.length;e++)s[e].setLightmapped(t)}}get lightmapped(){return this._lightmapped}set castShadows(t){if(this._castShadows===t)return;const s=this._model;if(s){const e=this.layers,i=this.system.app.scene;if(this._castShadows&&!t)for(let t=0;t<e.length;t++){const e=this.system.app.scene.layers.getLayerById(this.layers[t]);e&&e.removeShadowCasters(s.meshInstances)}const a=s.meshInstances;for(let s=0;s<a.length;s++)a[s].castShadow=t;if(!this._castShadows&&t)for(let t=0;t<e.length;t++){const a=i.layers.getLayerById(e[t]);a&&a.addShadowCasters(s.meshInstances)}}this._castShadows=t}get castShadows(){return this._castShadows}set receiveShadows(t){if(this._receiveShadows!==t&&(this._receiveShadows=t,this._model)){const s=this._model.meshInstances;for(let e=0,i=s.length;e<i;e++)s[e].receiveShadow=t}}get receiveShadows(){return this._receiveShadows}set castShadowsLightmap(t){this._castShadowsLightmap=t}get castShadowsLightmap(){return this._castShadowsLightmap}set lightmapSizeMultiplier(t){this._lightmapSizeMultiplier=t}get lightmapSizeMultiplier(){return this._lightmapSizeMultiplier}set layers(t){const s=this.system.app.scene.layers;if(this.meshInstances)for(let t=0;t<this._layers.length;t++){const e=s.getLayerById(this._layers[t]);e&&e.removeMeshInstances(this.meshInstances)}this._layers.length=0;for(let s=0;s<t.length;s++)this._layers[s]=t[s];if(this.enabled&&this.entity.enabled&&this.meshInstances)for(let t=0;t<this._layers.length;t++){const e=s.getLayerById(this._layers[t]);e&&e.addMeshInstances(this.meshInstances)}}get layers(){return this._layers}set batchGroupId(t){if(this._batchGroupId!==t){var e,i;if(this.entity.enabled&&this._batchGroupId>=0)null==(e=this.system.app.batcher)||e.remove(s.MODEL,this.batchGroupId,this.entity);if(this.entity.enabled&&t>=0)null==(i=this.system.app.batcher)||i.insert(s.MODEL,t,this.entity);t<0&&this._batchGroupId>=0&&this.enabled&&this.entity.enabled&&this.addModelToLayers(),this._batchGroupId=t}}get batchGroupId(){return this._batchGroupId}set materialAsset(t){let s=t;t instanceof n&&(s=t.id);const e=this.system.app.assets;if(s!==this._materialAsset){if(this._materialAsset){e.off(`add:${this._materialAsset}`,this._onMaterialAssetAdd,this);const t=e.get(this._materialAsset);t&&this._unbindMaterialAsset(t)}if(this._materialAsset=s,this._materialAsset){const t=e.get(this._materialAsset);t?this._bindMaterialAsset(t):(this._setMaterial(this.system.defaultMaterial),e.on(`add:${this._materialAsset}`,this._onMaterialAssetAdd,this))}else this._setMaterial(this.system.defaultMaterial)}}get materialAsset(){return this._materialAsset}set material(t){this._material!==t&&(this.materialAsset=null,this._setMaterial(t))}get material(){return this._material}set mapping(t){if("asset"!==this._type)return;if(this._unsetMaterialEvents(),t||(t={}),this._mapping=t,!this._model)return;const s=this._model.meshInstances,e=this.asset?this.system.app.assets.get(this.asset):null,i=e?e.data.mapping:null;let a=null;for(let e=0,h=s.length;e<h;e++)if(void 0!==t[e])t[e]?(a=this.system.app.assets.get(t[e]),this._loadAndSetMeshInstanceMaterial(a,s[e],e)):s[e].material=this.system.defaultMaterial;else if(i)if(i[e]&&(i[e].material||i[e].path)){if(void 0!==i[e].material)a=this.system.app.assets.get(i[e].material);else if(void 0!==i[e].path){const t=this._getMaterialAssetUrl(i[e].path);t&&(a=this.system.app.assets.getByUrl(t))}this._loadAndSetMeshInstanceMaterial(a,s[e],e)}else s[e].material=this.system.defaultMaterial}get mapping(){return this._mapping}addModelToLayers(){const t=this.system.app.scene.layers;for(let s=0;s<this._layers.length;s++){const e=t.getLayerById(this._layers[s]);e&&e.addMeshInstances(this.meshInstances)}}removeModelFromLayers(){const t=this.system.app.scene.layers;for(let s=0;s<this._layers.length;s++){const e=t.getLayerById(this._layers[s]);e&&e.removeMeshInstances(this.meshInstances)}}onRemoveChild(){this._model&&this.removeModelFromLayers()}onInsertChild(){this._model&&this.enabled&&this.entity.enabled&&this.addModelToLayers()}onRemove(){this.asset=null,this.model=null,this.materialAsset=null,this._unsetMaterialEvents(),this.entity.off("remove",this.onRemoveChild,this),this.entity.off("insert",this.onInsertChild,this)}onLayersChanged(t,s){this.addModelToLayers(),t.off("add",this.onLayerAdded,this),t.off("remove",this.onLayerRemoved,this),s.on("add",this.onLayerAdded,this),s.on("remove",this.onLayerRemoved,this)}onLayerAdded(t){this.layers.indexOf(t.id)<0||t.addMeshInstances(this.meshInstances)}onLayerRemoved(t){this.layers.indexOf(t.id)<0||t.removeMeshInstances(this.meshInstances)}_setMaterialEvent(t,s,e,i){const a=`${s}:${e}`;this.system.app.assets.on(a,i,this),this._materialEvents||(this._materialEvents=[]),this._materialEvents[t]||(this._materialEvents[t]={}),this._materialEvents[t][a]={id:e,handler:i}}_unsetMaterialEvents(){const t=this.system.app.assets,s=this._materialEvents;if(s){for(let e=0,i=s.length;e<i;e++){if(!s[e])continue;const i=s[e];for(const s in i)t.off(s,i[s].handler,this)}this._materialEvents=null}}_getAssetByIdOrPath(t){let s=null;if(isNaN(parseInt(t,10))){if(this.asset){const e=this._getMaterialAssetUrl(t);e&&(s=this.system.app.assets.getByUrl(e))}}else s=this.system.app.assets.get(t);return s}_getMaterialAssetUrl(t){if(!this.asset)return null;const s=this.system.app.assets.get(this.asset);return s?s.getAbsoluteUrl(t):null}_loadAndSetMeshInstanceMaterial(t,s,e){const i=this.system.app.assets;t&&(t.resource?(s.material=t.resource,this._setMaterialEvent(e,"remove",t.id,(function(){s.material=this.system.defaultMaterial}))):(this._setMaterialEvent(e,"load",t.id,(function(i){s.material=i.resource,this._setMaterialEvent(e,"remove",t.id,(function(){s.material=this.system.defaultMaterial}))})),this.enabled&&this.entity.enabled&&i.load(t)))}onEnable(){const t=this.system.app,e=t.scene,i=null==e?void 0:e.layers;this._evtLayersChanged=e.on("set:layers",this.onLayersChanged,this),i&&(this._evtLayerAdded=i.on("add",this.onLayerAdded,this),this._evtLayerRemoved=i.on("remove",this.onLayerRemoved,this));const a="asset"===this._type;let h;if(this._model?this.addModelToLayers():a&&this._asset&&(h=t.assets.get(this._asset),h&&h.resource!==this._model&&this._bindModelAsset(h)),this._materialAsset&&(h=t.assets.get(this._materialAsset),h&&h.resource!==this._material&&this._bindMaterialAsset(h)),a&&this._mapping)for(const s in this._mapping)this._mapping[s]&&(h=this._getAssetByIdOrPath(this._mapping[s]),h&&!h.resource&&t.assets.load(h));var n;this._batchGroupId>=0&&(null==(n=t.batcher)||n.insert(s.MODEL,this.batchGroupId,this.entity))}onDisable(){var t;const e=this.system.app,i=e.scene.layers;var a,h,n;(null==(t=this._evtLayersChanged)||t.off(),this._evtLayersChanged=null,i)&&(null==(a=this._evtLayerAdded)||a.off(),this._evtLayerAdded=null,null==(h=this._evtLayerRemoved)||h.off(),this._evtLayerRemoved=null);this._batchGroupId>=0&&(null==(n=e.batcher)||n.remove(s.MODEL,this.batchGroupId,this.entity));this._model&&this.removeModelFromLayers()}hide(){if(this._model){const t=this._model.meshInstances;for(let s=0,e=t.length;s<e;s++)t[s].visible=!1}}show(){if(this._model){const t=this._model.meshInstances;for(let s=0,e=t.length;s<e;s++)t[s].visible=!0}}_bindMaterialAsset(t){if(t.on("load",this._onMaterialAssetLoad,this),t.on("unload",this._onMaterialAssetUnload,this),t.on("remove",this._onMaterialAssetRemove,this),t.on("change",this._onMaterialAssetChange,this),t.resource)this._onMaterialAssetLoad(t);else{if(!this.enabled||!this.entity.enabled)return;this.system.app.assets.load(t)}}_unbindMaterialAsset(t){t.off("load",this._onMaterialAssetLoad,this),t.off("unload",this._onMaterialAssetUnload,this),t.off("remove",this._onMaterialAssetRemove,this),t.off("change",this._onMaterialAssetChange,this)}_onMaterialAssetAdd(t){this.system.app.assets.off(`add:${t.id}`,this._onMaterialAssetAdd,this),this._materialAsset===t.id&&this._bindMaterialAsset(t)}_onMaterialAssetLoad(t){this._setMaterial(t.resource)}_onMaterialAssetUnload(t){this._setMaterial(this.system.defaultMaterial)}_onMaterialAssetRemove(t){this._onMaterialAssetUnload(t)}_onMaterialAssetChange(t){}_bindModelAsset(t){if(this._unbindModelAsset(t),t.on("load",this._onModelAssetLoad,this),t.on("unload",this._onModelAssetUnload,this),t.on("change",this._onModelAssetChange,this),t.on("remove",this._onModelAssetRemove,this),t.resource)this._onModelAssetLoad(t);else{if(!this.enabled||!this.entity.enabled)return;this.system.app.assets.load(t)}}_unbindModelAsset(t){t.off("load",this._onModelAssetLoad,this),t.off("unload",this._onModelAssetUnload,this),t.off("change",this._onModelAssetChange,this),t.off("remove",this._onModelAssetRemove,this)}_onModelAssetAdded(t){this.system.app.assets.off(`add:${t.id}`,this._onModelAssetAdded,this),t.id===this._asset&&this._bindModelAsset(t)}_onModelAssetLoad(t){this.model=t.resource.clone(),this._clonedModel=!0}_onModelAssetUnload(t){this.model=null}_onModelAssetChange(t,s,e,i){"data"===s&&(this.mapping=this._mapping)}_onModelAssetRemove(t){this.model=null}_setMaterial(t){if(this._material===t)return;this._material=t;const s=this._model;if(s&&"asset"!==this._type){const e=s.meshInstances;for(let s=0,i=e.length;s<i;s++)e[s].material=t}}}export{o as ModelComponent};