UNPKG

playcanvas

Version:

PlayCanvas WebGL game engine

132 lines (129 loc) 4.31 kB
import { AnimTrack } from '../../anim/evaluator/anim-track.js'; import { Component } from '../component.js'; import { ComponentSystem } from '../system.js'; import { AnimComponent } from './component.js'; import { AnimComponentData } from './data.js'; const _schema = [ 'enabled' ]; class AnimComponentSystem extends ComponentSystem { constructor(app){ super(app); this.id = 'anim'; this.ComponentType = AnimComponent; this.DataType = AnimComponentData; this.schema = _schema; this.on('beforeremove', this.onBeforeRemove, this); this.app.systems.on('animationUpdate', this.onAnimationUpdate, this); } initializeComponentData(component, data, properties) { super.initializeComponentData(component, data, _schema); const complexProperties = [ 'animationAssets', 'stateGraph', 'layers', 'masks' ]; Object.keys(data).forEach((key)=>{ if (complexProperties.includes(key)) return; component[key] = data[key]; }); if (data.stateGraph) { component.stateGraph = data.stateGraph; component.loadStateGraph(component.stateGraph); } if (data.layers) { data.layers.forEach((layer, i)=>{ layer._controller.states.forEach((stateKey)=>{ layer._controller._states[stateKey]._animationList.forEach((node)=>{ if (!node.animTrack || node.animTrack === AnimTrack.EMPTY) { const animationAsset = this.app.assets.get(layer._component._animationAssets[`${layer.name}:${node.name}`].asset); if (animationAsset && !animationAsset.loaded) { animationAsset.once('load', ()=>{ component.layers[i].assignAnimation(node.name, animationAsset.resource); }); } } else { component.layers[i].assignAnimation(node.name, node.animTrack); } }); }); }); } if (data.animationAssets) { component.animationAssets = Object.assign(component.animationAssets, data.animationAssets); } if (data.masks) { Object.keys(data.masks).forEach((key)=>{ if (component.layers[key]) { const maskData = data.masks[key].mask; const mask = {}; Object.keys(maskData).forEach((maskKey)=>{ mask[decodeURI(maskKey)] = maskData[maskKey]; }); component.layers[key].mask = mask; } }); } } onAnimationUpdate(dt) { const components = this.store; for(const id in components){ if (components.hasOwnProperty(id)) { const component = components[id].entity.anim; const componentData = component.data; if (componentData.enabled && component.entity.enabled && component.playing) { component.update(dt); } } } } cloneComponent(entity, clone) { let masks; if (!entity.anim.rootBone || entity.anim.rootBone === entity) { masks = {}; entity.anim.layers.forEach((layer, i)=>{ if (layer.mask) { const mask = {}; Object.keys(layer.mask).forEach((path)=>{ const pathArr = path.split('/'); pathArr.shift(); const clonePath = [ clone.name, ...pathArr ].join('/'); mask[clonePath] = layer.mask[path]; }); masks[i] = { mask }; } }); } const data = { enabled: entity.anim.enabled, stateGraphAsset: entity.anim.stateGraphAsset, animationAssets: entity.anim.animationAssets, speed: entity.anim.speed, activate: entity.anim.activate, playing: entity.anim.playing, rootBone: entity.anim.rootBone, stateGraph: entity.anim.stateGraph, layers: entity.anim.layers, layerIndices: entity.anim.layerIndices, parameters: entity.anim.parameters, normalizeWeights: entity.anim.normalizeWeights, masks }; return this.addComponent(clone, data); } onBeforeRemove(entity, component) { component.onBeforeRemove(); } destroy() { super.destroy(); this.app.systems.off('animationUpdate', this.onAnimationUpdate, this); } } Component._buildAccessors(AnimComponent.prototype, _schema); export { AnimComponentSystem };