UNPKG

playcanvas

Version:

Open-source WebGL/WebGPU 3D engine for the web

107 lines (106 loc) 3.45 kB
import { extend } from "../../../core/core.js"; import { Vec3 } from "../../../core/math/vec3.js"; import { BoundingBox } from "../../../core/shape/bounding-box.js"; import { getDefaultMaterial } from "../../../scene/materials/default-material.js"; import { Asset } from "../../asset/asset.js"; import { ComponentSystem } from "../system.js"; import { ModelComponent } from "./component.js"; const _properties = [ "material", "materialAsset", "asset", "castShadows", "receiveShadows", "castShadowsLightmap", "lightmapped", "lightmapSizeMultiplier", "type", "mapping", "layers", "isStatic", "batchGroupId" ]; class ModelComponentSystem extends ComponentSystem { constructor(app) { super(app); this.id = "model"; this.ComponentType = ModelComponent; this.extraDataProperties = ["aabbCenter", "aabbHalfExtents"]; this.defaultMaterial = getDefaultMaterial(app.graphicsDevice); this.on("beforeremove", this.onBeforeRemove, this); } initializeComponentData(component, _data) { if (_data.batchGroupId === null || _data.batchGroupId === void 0) { _data.batchGroupId = -1; } if (_data.layers && _data.layers.length) { _data.layers = _data.layers.slice(0); } for (let i = 0; i < _properties.length; i++) { if (_data.hasOwnProperty(_properties[i])) { component[_properties[i]] = _data[_properties[i]]; } } if (_data.aabbCenter && _data.aabbHalfExtents) { component.customAabb = new BoundingBox(new Vec3(_data.aabbCenter), new Vec3(_data.aabbHalfExtents)); } super.initializeComponentData(component, _data); } cloneComponent(entity, clone) { const data = { enabled: entity.model.enabled }; for (let i = 0; i < _properties.length; i++) { const property = _properties[i]; switch (property) { // material and materialAsset are handled below, after the // appropriate one to clone has been determined case "material": case "materialAsset": break; case "mapping": data.mapping = extend({}, entity.model.mapping); break; default: data[property] = entity.model[property]; break; } } let materialAsset = entity.model.materialAsset; if (!(materialAsset instanceof Asset) && materialAsset != null) { materialAsset = this.app.assets.get(materialAsset); } const material = entity.model.material; if (!material || material === this.defaultMaterial || !materialAsset || material === materialAsset.resource) { data.materialAsset = materialAsset; } const component = this.addComponent(clone, data); if (entity.model.model && entity.model.type === "asset" && !entity.model.asset) { component.model = entity.model.model.clone(); component._clonedModel = true; } if (!data.materialAsset) { component.material = material; } if (entity.model.model) { const meshInstances = entity.model.model.meshInstances; const meshInstancesClone = component.model.meshInstances; for (let i = 0; i < meshInstances.length; i++) { meshInstancesClone[i].mask = meshInstances[i].mask; meshInstancesClone[i].material = meshInstances[i].material; meshInstancesClone[i].layer = meshInstances[i].layer; meshInstancesClone[i].receiveShadow = meshInstances[i].receiveShadow; } } if (entity.model.customAabb) { component.customAabb = entity.model.customAabb.clone(); } return component; } onBeforeRemove(entity, component) { component.onBeforeRemove(); } } export { ModelComponentSystem };