UNPKG

playcanvas

Version:

PlayCanvas WebGL game engine

545 lines (542 loc) 18.1 kB
import { LAYERID_WORLD, RENDERSTYLE_SOLID } from '../../../scene/constants.js'; import { BatchGroup } from '../../../scene/batching/batch-group.js'; import { MeshInstance } from '../../../scene/mesh-instance.js'; import { MorphInstance } from '../../../scene/morph-instance.js'; import { getShapePrimitive } from '../../graphics/primitive-cache.js'; import { GraphNode } from '../../../scene/graph-node.js'; import { SkinInstanceCache } from '../../../scene/skin-instance-cache.js'; import { Asset } from '../../asset/asset.js'; import { AssetReference } from '../../asset/asset-reference.js'; import { Component } from '../component.js'; class RenderComponent extends Component { set renderStyle(renderStyle) { if (this._renderStyle !== renderStyle) { this._renderStyle = renderStyle; MeshInstance._prepareRenderStyleForArray(this._meshInstances, renderStyle); } } get renderStyle() { return this._renderStyle; } set customAabb(value) { this._customAabb = value; var mi = this._meshInstances; if (mi) { for(var i = 0; i < mi.length; i++){ mi[i].setCustomAabb(this._customAabb); } } } get customAabb() { return this._customAabb; } set type(value) { if (this._type !== value) { this._area = null; this._type = value; this.destroyMeshInstances(); if (value !== 'asset') { var material = this._material; if (!material || material === this.system.defaultMaterial) { material = this._materialReferences[0] && this._materialReferences[0].asset && this._materialReferences[0].asset.resource; } var primData = getShapePrimitive(this.system.app.graphicsDevice, value); this._area = primData.area; this.meshInstances = [ new MeshInstance(primData.mesh, material || this.system.defaultMaterial, this.entity) ]; } } } get type() { return this._type; } set meshInstances(value) { this.destroyMeshInstances(); this._meshInstances = value; if (this._meshInstances) { var mi = this._meshInstances; for(var i = 0; i < mi.length; i++){ if (!mi[i].node) { mi[i].node = this.entity; } mi[i].castShadow = this._castShadows; mi[i].receiveShadow = this._receiveShadows; mi[i].renderStyle = this._renderStyle; mi[i].setLightmapped(this._lightmapped); mi[i].setCustomAabb(this._customAabb); } if (this.enabled && this.entity.enabled) { this.addToLayers(); } } } get meshInstances() { return this._meshInstances; } set lightmapped(value) { if (value !== this._lightmapped) { this._lightmapped = value; var mi = this._meshInstances; if (mi) { for(var i = 0; i < mi.length; i++){ mi[i].setLightmapped(value); } } } } get lightmapped() { return this._lightmapped; } set castShadows(value) { if (this._castShadows !== value) { var mi = this._meshInstances; if (mi) { var layers = this.layers; var scene = this.system.app.scene; if (this._castShadows && !value) { for(var i = 0; i < layers.length; i++){ var layer = scene.layers.getLayerById(this.layers[i]); if (layer) { layer.removeShadowCasters(mi); } } } for(var i1 = 0; i1 < mi.length; i1++){ mi[i1].castShadow = value; } if (!this._castShadows && value) { for(var i2 = 0; i2 < layers.length; i2++){ var layer1 = scene.layers.getLayerById(layers[i2]); if (layer1) { layer1.addShadowCasters(mi); } } } } this._castShadows = value; } } get castShadows() { return this._castShadows; } set receiveShadows(value) { if (this._receiveShadows !== value) { this._receiveShadows = value; var mi = this._meshInstances; if (mi) { for(var i = 0; i < mi.length; i++){ mi[i].receiveShadow = value; } } } } get receiveShadows() { return this._receiveShadows; } set castShadowsLightmap(value) { this._castShadowsLightmap = value; } get castShadowsLightmap() { return this._castShadowsLightmap; } set lightmapSizeMultiplier(value) { this._lightmapSizeMultiplier = value; } get lightmapSizeMultiplier() { return this._lightmapSizeMultiplier; } set layers(value) { var layers = this.system.app.scene.layers; var layer; if (this._meshInstances) { for(var i = 0; i < this._layers.length; i++){ layer = layers.getLayerById(this._layers[i]); if (layer) { layer.removeMeshInstances(this._meshInstances); } } } this._layers.length = 0; for(var i1 = 0; i1 < value.length; i1++){ this._layers[i1] = value[i1]; } if (!this.enabled || !this.entity.enabled || !this._meshInstances) return; for(var i2 = 0; i2 < this._layers.length; i2++){ layer = layers.getLayerById(this._layers[i2]); if (layer) { layer.addMeshInstances(this._meshInstances); } } } get layers() { return this._layers; } set batchGroupId(value) { if (this._batchGroupId !== value) { if (this.entity.enabled && this._batchGroupId >= 0) { var _this_system_app_batcher; (_this_system_app_batcher = this.system.app.batcher) == null ? void 0 : _this_system_app_batcher.remove(BatchGroup.RENDER, this.batchGroupId, this.entity); } if (this.entity.enabled && value >= 0) { var _this_system_app_batcher1; (_this_system_app_batcher1 = this.system.app.batcher) == null ? void 0 : _this_system_app_batcher1.insert(BatchGroup.RENDER, value, this.entity); } if (value < 0 && this._batchGroupId >= 0 && this.enabled && this.entity.enabled) { this.addToLayers(); } this._batchGroupId = value; } } get batchGroupId() { return this._batchGroupId; } set material(value) { if (this._material !== value) { this._material = value; if (this._meshInstances && this._type !== 'asset') { for(var i = 0; i < this._meshInstances.length; i++){ this._meshInstances[i].material = value; } } } } get material() { return this._material; } set materialAssets(value) { if (value === void 0) value = []; if (this._materialReferences.length > value.length) { for(var i = value.length; i < this._materialReferences.length; i++){ this._materialReferences[i].id = null; } this._materialReferences.length = value.length; } for(var i1 = 0; i1 < value.length; i1++){ if (!this._materialReferences[i1]) { this._materialReferences.push(new AssetReference(i1, this, this.system.app.assets, { add: this._onMaterialAdded, load: this._onMaterialLoad, remove: this._onMaterialRemove, unload: this._onMaterialUnload }, this)); } if (value[i1]) { var id = value[i1] instanceof Asset ? value[i1].id : value[i1]; if (this._materialReferences[i1].id !== id) { this._materialReferences[i1].id = id; } if (this._materialReferences[i1].asset) { this._onMaterialAdded(i1, this, this._materialReferences[i1].asset); } } else { this._materialReferences[i1].id = null; if (this._meshInstances[i1]) { this._meshInstances[i1].material = this.system.defaultMaterial; } } } } get materialAssets() { return this._materialReferences.map((ref)=>{ return ref.id; }); } set asset(value) { var id = value instanceof Asset ? value.id : value; if (this._assetReference.id === id) return; if (this._assetReference.asset && this._assetReference.asset.resource) { this._onRenderAssetRemove(); } this._assetReference.id = id; if (this._assetReference.asset) { this._onRenderAssetAdded(); } } get asset() { return this._assetReference.id; } assignAsset(asset) { var id = asset instanceof Asset ? asset.id : asset; this._assetReference.id = id; } set rootBone(value) { if (this._rootBone !== value) { var isString = typeof value === 'string'; if (this._rootBone && isString && this._rootBone.getGuid() === value) { return; } if (this._rootBone) { this._clearSkinInstances(); } if (value instanceof GraphNode) { this._rootBone = value; } else if (isString) { this._rootBone = this.system.app.getEntityFromIndex(value) || null; if (!this._rootBone) ; } else { this._rootBone = null; } if (this._rootBone) { this._cloneSkinInstances(); } } } get rootBone() { return this._rootBone; } destroyMeshInstances() { var meshInstances = this._meshInstances; if (meshInstances) { this.removeFromLayers(); this._clearSkinInstances(); for(var i = 0; i < meshInstances.length; i++){ meshInstances[i].destroy(); } this._meshInstances.length = 0; } } addToLayers() { var layers = this.system.app.scene.layers; for(var i = 0; i < this._layers.length; i++){ var layer = layers.getLayerById(this._layers[i]); if (layer) { layer.addMeshInstances(this._meshInstances); } } } removeFromLayers() { if (this._meshInstances && this._meshInstances.length) { var layers = this.system.app.scene.layers; for(var i = 0; i < this._layers.length; i++){ var layer = layers.getLayerById(this._layers[i]); if (layer) { layer.removeMeshInstances(this._meshInstances); } } } } onRemoveChild() { this.removeFromLayers(); } onInsertChild() { if (this._meshInstances && this.enabled && this.entity.enabled) { this.addToLayers(); } } onRemove() { this.destroyMeshInstances(); this.asset = null; this.materialAsset = null; this._assetReference.id = null; for(var i = 0; i < this._materialReferences.length; i++){ this._materialReferences[i].id = null; } this.entity.off('remove', this.onRemoveChild, this); this.entity.off('insert', this.onInsertChild, this); } onLayersChanged(oldComp, newComp) { this.addToLayers(); oldComp.off('add', this.onLayerAdded, this); oldComp.off('remove', this.onLayerRemoved, this); newComp.on('add', this.onLayerAdded, this); newComp.on('remove', this.onLayerRemoved, this); } onLayerAdded(layer) { var index = this.layers.indexOf(layer.id); if (index < 0) return; layer.addMeshInstances(this._meshInstances); } onLayerRemoved(layer) { var index = this.layers.indexOf(layer.id); if (index < 0) return; layer.removeMeshInstances(this._meshInstances); } onEnable() { var app = this.system.app; var scene = app.scene; var layers = scene.layers; if (this._rootBone) { this._cloneSkinInstances(); } this._evtLayersChanged = scene.on('set:layers', this.onLayersChanged, this); if (layers) { this._evtLayerAdded = layers.on('add', this.onLayerAdded, this); this._evtLayerRemoved = layers.on('remove', this.onLayerRemoved, this); } var isAsset = this._type === 'asset'; if (this._meshInstances && this._meshInstances.length) { this.addToLayers(); } else if (isAsset && this.asset) { this._onRenderAssetAdded(); } for(var i = 0; i < this._materialReferences.length; i++){ if (this._materialReferences[i].asset) { this.system.app.assets.load(this._materialReferences[i].asset); } } if (this._batchGroupId >= 0) { var _app_batcher; (_app_batcher = app.batcher) == null ? void 0 : _app_batcher.insert(BatchGroup.RENDER, this.batchGroupId, this.entity); } } onDisable() { var _this__evtLayersChanged; var app = this.system.app; var scene = app.scene; var layers = scene.layers; (_this__evtLayersChanged = this._evtLayersChanged) == null ? void 0 : _this__evtLayersChanged.off(); this._evtLayersChanged = null; if (this._rootBone) { this._clearSkinInstances(); } if (layers) { var _this__evtLayerAdded, _this__evtLayerRemoved; (_this__evtLayerAdded = this._evtLayerAdded) == null ? void 0 : _this__evtLayerAdded.off(); this._evtLayerAdded = null; (_this__evtLayerRemoved = this._evtLayerRemoved) == null ? void 0 : _this__evtLayerRemoved.off(); this._evtLayerRemoved = null; } if (this._batchGroupId >= 0) { var _app_batcher; (_app_batcher = app.batcher) == null ? void 0 : _app_batcher.remove(BatchGroup.RENDER, this.batchGroupId, this.entity); } this.removeFromLayers(); } hide() { if (this._meshInstances) { for(var i = 0; i < this._meshInstances.length; i++){ this._meshInstances[i].visible = false; } } } show() { if (this._meshInstances) { for(var i = 0; i < this._meshInstances.length; i++){ this._meshInstances[i].visible = true; } } } _onRenderAssetAdded() { if (!this._assetReference.asset) return; if (this._assetReference.asset.resource) { this._onRenderAssetLoad(); } else if (this.enabled && this.entity.enabled) { this.system.app.assets.load(this._assetReference.asset); } } _onRenderAssetLoad() { this.destroyMeshInstances(); if (this._assetReference.asset) { var _this__evtSetMeshes; var render = this._assetReference.asset.resource; (_this__evtSetMeshes = this._evtSetMeshes) == null ? void 0 : _this__evtSetMeshes.off(); this._evtSetMeshes = render.on('set:meshes', this._onSetMeshes, this); if (render.meshes) { this._onSetMeshes(render.meshes); } } } _onSetMeshes(meshes) { this._cloneMeshes(meshes); } _clearSkinInstances() { for(var i = 0; i < this._meshInstances.length; i++){ var meshInstance = this._meshInstances[i]; SkinInstanceCache.removeCachedSkinInstance(meshInstance.skinInstance); meshInstance.skinInstance = null; } } _cloneSkinInstances() { if (this._meshInstances.length && this._rootBone instanceof GraphNode) { for(var i = 0; i < this._meshInstances.length; i++){ var meshInstance = this._meshInstances[i]; var mesh = meshInstance.mesh; if (mesh.skin && !meshInstance.skinInstance) { meshInstance.skinInstance = SkinInstanceCache.createCachedSkinInstance(mesh.skin, this._rootBone, this.entity); } } } } _cloneMeshes(meshes) { if (meshes && meshes.length) { var meshInstances = []; for(var i = 0; i < meshes.length; i++){ var mesh = meshes[i]; var material = this._materialReferences[i] && this._materialReferences[i].asset && this._materialReferences[i].asset.resource; var meshInst = new MeshInstance(mesh, material || this.system.defaultMaterial, this.entity); meshInstances.push(meshInst); if (mesh.morph) { meshInst.morphInstance = new MorphInstance(mesh.morph); } } this.meshInstances = meshInstances; this._cloneSkinInstances(); } } _onRenderAssetUnload() { if (this._type === 'asset') { this.destroyMeshInstances(); } } _onRenderAssetRemove() { var _this__evtSetMeshes; (_this__evtSetMeshes = this._evtSetMeshes) == null ? void 0 : _this__evtSetMeshes.off(); this._evtSetMeshes = null; this._onRenderAssetUnload(); } _onMaterialAdded(index, component, asset) { if (asset.resource) { this._onMaterialLoad(index, component, asset); } else { if (this.enabled && this.entity.enabled) { this.system.app.assets.load(asset); } } } _updateMainMaterial(index, material) { if (index === 0) { this.material = material; } } _onMaterialLoad(index, component, asset) { if (this._meshInstances[index]) { this._meshInstances[index].material = asset.resource; } this._updateMainMaterial(index, asset.resource); } _onMaterialRemove(index, component, asset) { if (this._meshInstances[index]) { this._meshInstances[index].material = this.system.defaultMaterial; } this._updateMainMaterial(index, this.system.defaultMaterial); } _onMaterialUnload(index, component, asset) { if (this._meshInstances[index]) { this._meshInstances[index].material = this.system.defaultMaterial; } this._updateMainMaterial(index, this.system.defaultMaterial); } resolveDuplicatedEntityReferenceProperties(oldRender, duplicatedIdsMap) { if (oldRender.rootBone) { this.rootBone = duplicatedIdsMap[oldRender.rootBone.getGuid()]; } } constructor(system, entity){ super(system, entity), this._type = 'asset', this._castShadows = true, this._receiveShadows = true, this._castShadowsLightmap = true, this._lightmapped = false, this._lightmapSizeMultiplier = 1, this.isStatic = false, this._batchGroupId = -1, this._layers = [ LAYERID_WORLD ], this._renderStyle = RENDERSTYLE_SOLID, this._meshInstances = [], this._customAabb = null, this._area = null, this._materialReferences = [], this._rootBone = null, this._evtLayersChanged = null, this._evtLayerAdded = null, this._evtLayerRemoved = null, this._evtSetMeshes = null; this._assetReference = new AssetReference('asset', this, system.app.assets, { add: this._onRenderAssetAdded, load: this._onRenderAssetLoad, remove: this._onRenderAssetRemove, unload: this._onRenderAssetUnload }, this); this._material = system.defaultMaterial; entity.on('remove', this.onRemoveChild, this); entity.on('removehierarchy', this.onRemoveChild, this); entity.on('insert', this.onInsertChild, this); entity.on('inserthierarchy', this.onInsertChild, this); } } export { RenderComponent };