UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

211 lines (162 loc) 4.54 kB
import { BlendStateMatrix } from "../blending/BlendStateMatrix.js"; import { AnimationStateType } from "./AnimationStateType.js"; export class AnimationState { constructor() { /** * * @type {AnimationStateDefinition} */ this.def = null; /** * Incoming transitions * @type {AnimationTransition[]} */ this.inEdges = []; /** * Outgoing transitions * @type {AnimationTransition[]} */ this.outEdges = []; /** * * @type {AnimationGraph} */ this.graph = null; /** * * @type {BlendStateMatrix} */ this.blendState = null; /** * * @type {number} */ this.time = 0; /** * * @type {number} */ this.timeScale = 1; } /** * * @param {AnimationState} other * @returns {boolean} */ equals(other) { if (this === other) { return true; } return this.def.equals(other.def); } /** * * @return {number} */ hash() { return this.def.hash(); } initialize() { const graphDefinition = this.graph.def; const n = graphDefinition.clipIndex.length; const matrix = graphDefinition.createBlendState(); for (let i = 0; i < n; i++) { matrix.weights[i] = 0; matrix.timeScales[i] = 1; } this.blendState = matrix; } updateBlendState() { const graphDefinition = this.graph.def; const stateDefinition = this.def; const matrix = this.blendState; if (stateDefinition.type === AnimationStateType.Clip) { /** * * @type {AnimationClip} */ const clip = stateDefinition.motion; /** * * @type {AnimationClipDefinition} */ const clipDefinition = clip.def; const clipIndex = graphDefinition.getClipIndex(clipDefinition); matrix.weights[clipIndex] = clip.weight; matrix.timeScales[clipIndex] = clip.timeScale * this.timeScale; } } /** * * @param {number} timeDelta in seconds */ tick(timeDelta) { const timeBefore = this.time; /** * * @type {AnimationStateDefinition} */ const stateDefinition = this.def; /** * * @type {AnimationGraph} */ const graph = this.graph; /** * * @type {EntityComponentDataset} */ const dataset = graph.__dataset; /** * * @type {number} */ const entity = graph.__entity; if (stateDefinition.type === AnimationStateType.Clip) { /** * * @type {AnimationClip} */ const clip = stateDefinition.motion; const realTimeDelta = timeDelta * clip.timeScale * this.timeScale; const timeAfter = timeBefore + realTimeDelta; clip.dispatchNotifications(entity, dataset, timeBefore, timeAfter); this.time = timeAfter; } } /** * Executed when state becomes active * @param {number} entity * @param {EntityComponentDataset} ecd */ activate(entity, ecd) { this.time = 0; /** * * @type {AnimationTransition[]} */ const outEdges = this.outEdges; const outEdgeCount = outEdges.length; for (let i = 0; i < outEdgeCount; i++) { const outEdge = outEdges[i]; outEdge.link(entity, ecd); } } /** * Executed when state becomes inactive * @param {number} entity * @param {EntityComponentDataset} ecd */ deactivate(entity, ecd) { /** * * @type {AnimationTransition[]} */ const outEdges = this.outEdges; const outEdgeCount = outEdges.length; for (let i = 0; i < outEdgeCount; i++) { const outEdge = outEdges[i]; outEdge.unlink(entity, ecd); } } }