Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve typing for Anim APIs #6179

Merged
merged 5 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 101 additions & 23 deletions src/framework/anim/controller/anim-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,81 @@ import {
* @ignore
*/
class AnimController {
/**
* @type {Object<string, AnimState>}
* @private
*/
_states = {};

/**
* @type {string[]}
* @private
*/
_stateNames = [];

/**
* @type {Object<string, AnimTransition[]>}
* @private
*/
_findTransitionsFromStateCache = {};

/**
* @type {Object<string, AnimTransition[]>}
* @private
*/
_findTransitionsBetweenStatesCache = {};

/**
* @type {string|null}
* @private
*/
_previousStateName = null;

/** @private */
_activeStateName = ANIM_STATE_START;

/** @private */
_activeStateDuration = 0;

/** @private */
_activeStateDurationDirty = true;

/** @private */
_playing = false;

/**
* @type {boolean}
* @private
*/
_activate;

/**
* @type {AnimTransition[]}
* @private
*/
_transitions;

/** @private */
_currTransitionTime = 1;

/** @private */
_totalTransitionTime = 1;

/** @private */
_isTransitioning = false;

/** @private */
_transitionInterruptionSource = ANIM_INTERRUPTION_NONE;

/** @private */
_transitionPreviousStates = [];

/** @private */
_timeInState = 0;

/** @private */
_timeInStateBefore = 0;

/**
* Create a new AnimController.
*
Expand All @@ -33,14 +108,13 @@ class AnimController {
* once all {@link AnimNodes} are assigned animations.
* @param {import('../../../core/event-handler.js').EventHandler} eventHandler - The event
* handler which should be notified with anim events.
* @param {Function} findParameter - Retrieves a parameter which is used to control the transition between states.
* @param {Function} consumeTrigger - Used to set triggers back to their default state after they
* have been consumed by a transition.
* @param {Function} findParameter - Retrieves a parameter which is used to control the
* transition between states.
* @param {Function} consumeTrigger - Used to set triggers back to their default state after
* they have been consumed by a transition.
*/
constructor(animEvaluator, states, transitions, activate, eventHandler, findParameter, consumeTrigger) {
this._animEvaluator = animEvaluator;
this._states = {};
this._stateNames = [];
this._eventHandler = eventHandler;
this._findParameter = findParameter;
this._consumeTrigger = consumeTrigger;
Expand All @@ -59,23 +133,7 @@ class AnimController {
...transition
});
});
this._findTransitionsFromStateCache = {};
this._findTransitionsBetweenStatesCache = {};
this._previousStateName = null;
this._activeStateName = ANIM_STATE_START;
this._activeStateDuration = 0.0;
this._activeStateDurationDirty = true;
this._playing = false;
this._activate = activate;

this._currTransitionTime = 1.0;
this._totalTransitionTime = 1.0;
this._isTransitioning = false;
this._transitionInterruptionSource = ANIM_INTERRUPTION_NONE;
this._transitionPreviousStates = [];

this._timeInState = 0;
this._timeInStateBefore = 0;
}

get animEvaluator() {
Expand Down Expand Up @@ -178,6 +236,11 @@ class AnimController {
return this._animEvaluator.assignMask(mask);
}

/**
* @param {string} stateName - The name of the state to find.
* @returns {AnimState} The state with the given name.
* @private
*/
_findState(stateName) {
return this._states[stateName];
}
Expand All @@ -194,7 +257,14 @@ class AnimController {
return null;
}

// return all the transitions that have the given stateName as their source state
/**
* Return all the transitions that have the given stateName as their source state.
*
* @param {string} stateName - The name of the state to find transitions from.
* @returns {AnimTransition[]} The transitions that have the given stateName as their source
* state.
* @private
*/
_findTransitionsFromState(stateName) {
let transitions = this._findTransitionsFromStateCache[stateName];
if (!transitions) {
Expand All @@ -210,7 +280,15 @@ class AnimController {
return transitions;
}

// return all the transitions that contain the given source and destination states
/**
* Return all the transitions that contain the given source and destination states.
*
* @param {string} sourceStateName - The name of the source state to find transitions from.
* @param {string} destinationStateName - The name of the destination state to find transitions
* to.
* @returns {AnimTransition[]} The transitions that have the given source and destination states.
* @private
*/
_findTransitionsBetweenStates(sourceStateName, destinationStateName) {
let transitions = this._findTransitionsBetweenStatesCache[sourceStateName + '->' + destinationStateName];
if (!transitions) {
Expand Down
18 changes: 9 additions & 9 deletions src/framework/anim/controller/anim-transition.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@ class AnimTransition {
* @param {object} options - Options.
* @param {string} options.from - The state that this transition will exit from.
* @param {string} options.to - The state that this transition will transition to.
* @param {number} options.time - The duration of the transition in seconds. Defaults to 0.
* @param {number} options.priority - Used to sort all matching transitions in ascending order.
* The first transition in the list will be selected. Defaults to 0.
* @param {object[]} options.conditions - A list of conditions which must pass for this
* @param {number} [options.time] - The duration of the transition in seconds. Defaults to 0.
* @param {number} [options.priority] - Used to sort all matching transitions in ascending
* order. The first transition in the list will be selected. Defaults to 0.
* @param {object[]} [options.conditions] - A list of conditions which must pass for this
* transition to be used. Defaults to [].
* @param {number} options.exitTime - If provided, this transition will only be active for the
* exact frame during which the source states progress passes the time specified. Given as a
* normalized value of the source states duration. Values less than 1 will be checked every
* @param {number} [options.exitTime] - If provided, this transition will only be active for
* the exact frame during which the source states progress passes the time specified. Given as
* a normalized value of the source states duration. Values less than 1 will be checked every
* animation loop. Defaults to null.
* @param {number} options.transitionOffset - If provided, the destination state will begin
* @param {number} [options.transitionOffset] - If provided, the destination state will begin
* playing its animation at this time. Given in normalized time, based on the state's duration
* and must be between 0 and 1. Defaults to null.
* @param {string} options.interruptionSource - Defines whether another transition can
* @param {string} [options.interruptionSource] - Defines whether another transition can
* interrupt this one and which of the current or previous states transitions can do so. One of
* pc.ANIM_INTERRUPTION_*. Defaults to pc.ANIM_INTERRUPTION_NONE.
*/
Expand Down
69 changes: 54 additions & 15 deletions src/framework/components/anim/component-layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,69 @@ import { ANIM_LAYER_OVERWRITE } from '../../anim/controller/constants.js';
* @category Animation
*/
class AnimComponentLayer {
/**
* @type {string}
* @private
*/
_name;

/**
* @type {import('../../anim/controller/anim-controller.js').AnimController}
* @private
*/
_controller;

/**
* @type {import('./component.js').AnimComponent}
* @private
*/
_component;

/**
* @type {number}
* @private
*/
_weight;

/**
* @type {string}
* @private
*/
_blendType;

/** @private */
_mask = null;

/** @private */
_blendTime = 0;

/** @private */
_blendTimeElapsed = 0;

/** @private */
_startingWeight = 0;

/** @private */
_targetWeight = 0;

/**
* Create a new AnimComponentLayer instance.
*
* @param {string} name - The name of the layer.
* @param {object} controller - The controller to manage this layers animations.
* @param {import('../../anim/controller/anim-controller.js').AnimController} controller - The
* controller to manage this layers animations.
* @param {import('./component.js').AnimComponent} component - The component that this layer is
* a member of.
* @param {number} [weight] - The weight of this layer. Defaults to 1.
* @param {string} [blendType] - The blend type of this layer. Defaults to {@link ANIM_LAYER_OVERWRITE}.
* @param {boolean} [normalizedWeight] - Whether the weight of this layer should be normalized
* using the total weight of all layers.
* @ignore
*/
constructor(name, controller, component, weight = 1, blendType = ANIM_LAYER_OVERWRITE, normalizedWeight = true) {
constructor(name, controller, component, weight = 1, blendType = ANIM_LAYER_OVERWRITE) {
this._name = name;
this._controller = controller;
this._component = component;
this._weight = weight;
this._blendType = blendType;
this._normalizedWeight = normalizedWeight;
this._mask = null;
this._blendTime = 0;
this._blendTimeElapsed = 0;
this._startingWeight = 0;
this._targetWeight = 0;
}

/**
Expand All @@ -49,7 +88,7 @@ class AnimComponentLayer {
/**
* Whether this layer is currently playing.
*
* @type {string}
* @type {boolean}
*/
set playing(value) {
this._controller.playing = value;
Expand All @@ -63,7 +102,7 @@ class AnimComponentLayer {
* Returns true if a state graph has been loaded and all states in the graph have been assigned
* animation tracks.
*
* @type {string}
* @type {boolean}
*/
get playable() {
return this._controller.playable;
Expand All @@ -81,14 +120,14 @@ class AnimComponentLayer {
/**
* Returns the previously active state name.
*
* @type {string}
* @type {string|null}
*/
get previousState() {
return this._controller.previousStateName;
}

/**
* Returns the currently active states progress as a value normalized by the states animation
* Returns the currently active state's progress as a value normalized by the state's animation
* duration. Looped animations will return values greater than 1.
*
* @type {number}
Expand Down Expand Up @@ -307,7 +346,7 @@ class AnimComponentLayer {
* animation should be associated with. Each section of a blend tree path is split using a
* period (`.`) therefore state names should not include this character (e.g "MyStateName" or
* "MyStateName.BlendTreeNode").
* @param {object} animTrack - The animation track that will be assigned to this state and
* @param {AnimTrack} animTrack - The animation track that will be assigned to this state and
* played whenever this state is active.
* @param {number} [speed] - Update the speed of the state you are assigning an animation to.
* Defaults to 1.
Expand Down