animouse
Version:
lightweight animation state machine for three js
115 lines (114 loc) • 5.01 kB
TypeScript
import type { AnimationAction } from "three";
import { AnimationTree } from "./AnimationTree";
/**
* Configuration for a polar animation action in the blend tree.
* Associates an animation action with polar coordinates (radius, azimuth).
*
* @public
*/
export interface PolarAction {
/** The Three.js animation action to be played */
action: AnimationAction;
/** Radial distance from the origin. Must be finite and positive. */
radius: number;
/** Angular position in radians. Must be finite. Will be normalized to [0, 2π) range. */
azimuth: number;
}
/**
* Configuration options for polar blend tree behavior.
*
* @public
*/
export interface PolarBlendTreeOptions {
/** Animation action to play at the center (origin) of the polar space */
centerAction: AnimationAction;
/** Whether the blend tree should loop azimuthal blending at 2π */
isLooped: boolean;
}
/**
* Polar blend tree implementation for 2D animation blending in polar coordinates.
*
* Manages animation actions positioned in polar space (radius, azimuth), blending
* between adjacent animations using bilinear interpolation. Organizes actions into
* rays (constant azimuth) and rings (constant radius).
*
* @example
* ```typescript
* const blendTree = new PolarBlendTree([
* { action: walkForward, radius: 1, azimuth: 0 },
* { action: walkLeft, radius: 1, azimuth: Math.PI / 2 },
* { action: runForward, radius: 2, azimuth: 0 },
* { action: runLeft, radius: 2, azimuth: Math.PI / 2 }
* ], idleAction);
*
* blendTree.setBlend(Math.PI / 4, 1.5);
* ```
*/
export declare class PolarBlendTree extends AnimationTree {
private readonly tempAnchorMap;
private readonly trackableAnchors;
/** Optional center anchor at origin (0,0) for special blending behavior */
private readonly centerAnchor?;
/** Array of rays (constant azimuth lines) containing anchors, sorted by azimuth */
private readonly rays;
/** Array of rings (constant radius circles) containing anchors, sorted by radius */
private readonly rings;
/** Current radial position for blending calculations */
private currentRadius;
/** Current angular position for blending calculations, normalized to [0, 2π) */
private currentAzimuth;
/**
* Creates a new polar blend tree with the specified animation actions.
* Actions are organized into rays (by azimuth) and rings (by radius).
*
* @param polarActions - Array of polar actions defining the blend space.
* Must contain at least 2 actions with unique coordinates.
* @param centerAction - Optional center action at origin (0,0)
* @throws {Error} When fewer than 2 actions are provided
* @throws {Error} When any action has non-finite radius or azimuth values
* @throws {Error} When any action has non-positive radius
* @throws {Error} When multiple actions have the same polar coordinates
* @throws {Error} When fewer than 2 rays are created
* @throws {Error} When rays don't have consistent anchor counts
* @throws {Error} When any animation clip duration is not positive
*/
constructor(polarActions: PolarAction[], centerAction?: AnimationAction);
get blendValue(): {
azimuth: number;
radius: number;
};
/**
* Sets the blend position in polar coordinates to determine animation weights.
* Azimuth is normalized to [0, 2π) range and radius must be non-negative.
* Recalculates weights using bilinear interpolation between the closest anchors.
*
* @param azimuth - Target angular position in radians. Will be normalized to [0, 2π).
* @param radius - Target radial distance from origin.
* @throws {Error} When azimuth is not a finite number
* @throws {Error} When radius is not a finite non-negative number
*/
setBlend(azimuth: number, radius: number): void;
protected ["onEnterInternal"](): void;
/**
* Updates the influence for all active anchors in the polar blend tree.
* Called when the tree's influence changes but relative weights remain the same.
*/
protected updateAnchorsInfluence(): void;
/**
* Recalculates and updates animation weights based on current blend position.
* Finds the two adjacent rays containing the current azimuth and applies
* appropriate interpolation (linear for center, bilinear for grid).
*/
private updateAnchors;
/**
* Calculates bilinear interpolation weights for the four corner anchors in the polar grid.
* Performs interpolation between four points in a rectangular grid pattern.
*
* @param weights - Map to store calculated weights for each anchor
* @param lRayT - Weight for the left ray
* @param rRayT - Weight for the right ray
* @param lRayIndex - Index of the left ray in the rays array
* @param rRayIndex - Index of the right ray in the rays array
*/
private calculateBilinearWeights;
}