UNPKG

playcanvas

Version:

PlayCanvas WebGL game engine

125 lines (122 loc) 4.36 kB
import { AnimTrack } from '../evaluator/anim-track.js'; import { ANIM_BLEND_DIRECT, ANIM_BLEND_2D_DIRECTIONAL, ANIM_BLEND_2D_CARTESIAN, ANIM_BLEND_1D, ANIM_CONTROL_STATES } from './constants.js'; import { AnimBlendTree1D } from './anim-blend-tree-1d.js'; import { AnimBlendTreeCartesian2D } from './anim-blend-tree-2d-cartesian.js'; import { AnimBlendTreeDirectional2D } from './anim-blend-tree-2d-directional.js'; import { AnimBlendTreeDirect } from './anim-blend-tree-direct.js'; import { AnimNode } from './anim-node.js'; class AnimState { constructor(controller, name, speed = 1, loop = true, blendTree){ this._animations = {}; this._animationList = []; this._controller = controller; this._name = name; this._speed = speed; this._loop = loop; this._hasAnimations = false; if (blendTree) { this._blendTree = this._createTree(blendTree.type, this, null, name, 1.0, blendTree.parameter ? [ blendTree.parameter ] : blendTree.parameters, blendTree.children, blendTree.syncAnimations, this._createTree, this._controller.findParameter); } else { this._blendTree = new AnimNode(this, null, name, 1.0, speed); } } _createTree(type, state, parent, name, point, parameters, children, syncAnimations, createTree, findParameter) { switch(type){ case ANIM_BLEND_1D: return new AnimBlendTree1D(state, parent, name, point, parameters, children, syncAnimations, createTree, findParameter); case ANIM_BLEND_2D_CARTESIAN: return new AnimBlendTreeCartesian2D(state, parent, name, point, parameters, children, syncAnimations, createTree, findParameter); case ANIM_BLEND_2D_DIRECTIONAL: return new AnimBlendTreeDirectional2D(state, parent, name, point, parameters, children, syncAnimations, createTree, findParameter); case ANIM_BLEND_DIRECT: return new AnimBlendTreeDirect(state, parent, name, point, parameters, children, syncAnimations, createTree, findParameter); } return undefined; } _getNodeFromPath(path) { let currNode = this._blendTree; for(let i = 1; i < path.length; i++){ currNode = currNode.getChild(path[i]); } return currNode; } addAnimation(path, animTrack) { const pathString = path.join('.'); const indexOfAnimation = this._animationList.findIndex((animation)=>{ return animation.path === pathString; }); if (indexOfAnimation >= 0) { this._animationList[indexOfAnimation].animTrack = animTrack; } else { const node = this._getNodeFromPath(path); node.animTrack = animTrack; this._animationList.push(node); } this._updateHasAnimations(); } _updateHasAnimations() { this._hasAnimations = this._animationList.length > 0 && this._animationList.every((animation)=>animation.animTrack && animation.animTrack !== AnimTrack.EMPTY); } get name() { return this._name; } set animations(value) { this._animationList = value; this._updateHasAnimations(); } get animations() { return this._animationList; } get hasAnimations() { return this._hasAnimations; } set speed(value) { this._speed = value; } get speed() { return this._speed; } set loop(value) { this._loop = value; } get loop() { return this._loop; } get nodeCount() { if (!this._blendTree || this._blendTree.constructor === AnimNode) return 1; return this._blendTree.getNodeCount(); } get playable() { return ANIM_CONTROL_STATES.indexOf(this.name) !== -1 || this.animations.length === this.nodeCount; } get looping() { if (this.animations.length > 0) { const trackClipName = `${this.name}.${this.animations[0].animTrack.name}`; const trackClip = this._controller.animEvaluator.findClip(trackClipName); if (trackClip) { return trackClip.loop; } } return false; } get totalWeight() { let sum = 0; for(let i = 0; i < this.animations.length; i++){ sum += this.animations[i].weight; } return sum; } get timelineDuration() { let duration = 0; for(let i = 0; i < this.animations.length; i++){ const animation = this.animations[i]; if (animation.animTrack.duration > duration) { duration = animation.animTrack.duration; } } return duration; } } export { AnimState };