UNPKG

playcanvas

Version:

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

140 lines (139 loc) 4.17 kB
import { AnimTrack } from "../evaluator/anim-track.js"; import { ANIM_BLEND_1D, ANIM_BLEND_2D_CARTESIAN, ANIM_BLEND_2D_DIRECTIONAL, ANIM_BLEND_DIRECT, 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 { _animations = {}; _animationList = []; constructor(controller, name, speed = 1, loop = true, blendTree) { 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, blendTree.parameter ? [blendTree.parameter] : blendTree.parameters, blendTree.children, blendTree.syncAnimations, this._createTree, this._controller.findParameter ); } else { this._blendTree = new AnimNode(this, null, name, 1, 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 void 0; } _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 };