UNPKG

playcanvas

Version:

PlayCanvas WebGL game engine

93 lines (90 loc) 4.1 kB
import { AnimNode } from './anim-node.js'; /** * @import { AnimState } from './anim-state.js' * @import { Vec2 } from '../../../core/math/vec2.js' */ /** * AnimBlendTrees are used to store and blend multiple {@link AnimNode}s together. BlendTrees can * be the child of other AnimBlendTrees, in order to create a hierarchy of AnimNodes. It takes a * blend type as an argument which defines which function should be used to determine the weights * of each of its children, based on the current parameter value. * * @category Animation */ class AnimBlendTree extends AnimNode { /** * Create a new AnimBlendTree instance. * * @param {AnimState} state - The AnimState that this AnimBlendTree belongs to. * @param {AnimBlendTree|null} parent - The parent of the AnimBlendTree. If not null, the * AnimNode is stored as part of a {@link AnimBlendTree} hierarchy. * @param {string} name - The name of the BlendTree. Used when assigning an {@link AnimTrack} * to its children. * @param {number|Vec2} point - The coordinate/vector that's used to determine the weight of * this node when it's part of an {@link AnimBlendTree}. * @param {string[]} parameters - The anim component parameters which are used to calculate the * current weights of the blend trees children. * @param {object[]} children - The child nodes that this blend tree should create. Can either * be of type {@link AnimNode} or {@link AnimBlendTree}. * @param {boolean} syncAnimations - If true, the speed of each blended animation will be * synchronized. * @param {Function} createTree - Used to create child blend trees of varying types. * @param {Function} findParameter - Used at runtime to get the current parameter values. */ constructor(state, parent, name, point, parameters, children, syncAnimations, createTree, findParameter){ super(state, parent, name, point); this._parameters = parameters; this._parameterValues = new Array(parameters.length); this._children = []; this._findParameter = findParameter; this._syncAnimations = syncAnimations !== false; this._pointCache = {}; for(let i = 0; i < children.length; i++){ const child = children[i]; if (child.children) { this._children.push(createTree(child.type, state, this, child.name, 1.0, child.parameter ? [ child.parameter ] : child.parameters, child.children, child.syncAnimations, createTree, findParameter)); } else { this._children.push(new AnimNode(state, this, child.name, child.point, child.speed)); } } } get weight() { this.calculateWeights(); return this._parent ? this._parent.weight * this._weight : this._weight; } get syncAnimations() { return this._syncAnimations; } getChild(name) { for(let i = 0; i < this._children.length; i++){ if (this._children[i].name === name) return this._children[i]; } return null; } updateParameterValues() { let paramsEqual = true; for(let i = 0; i < this._parameterValues.length; i++){ const updatedParameter = this._findParameter(this._parameters[i]).value; if (this._parameterValues[i] !== updatedParameter) { this._parameterValues[i] = updatedParameter; paramsEqual = false; } } return paramsEqual; } getNodeWeightedDuration(i) { return this._children[i].animTrack.duration / this._children[i].speedMultiplier * this._children[i].weight; } getNodeCount() { let count = 0; for(let i = 0; i < this._children.length; i++){ const child = this._children[i]; if (child.constructor === AnimBlendTree) { count += this._children[i].getNodeCount(); } else { count++; } } return count; } } export { AnimBlendTree };