Skip to content

@aosengine/animation

Classes

MovementComponent

Navmesh path following for one character.

Constructors

Constructor
ts
new MovementComponent(options?): MovementComponent;

Build a component.

Parameters
ParameterTypeDescription
optionsMovementOptionsSee MovementOptions.
Returns

MovementComponent

Properties

config
ts
readonly config: MovementConfig;

Tuning.

path
ts
path: Vec3[] = [];

The path being followed.

speed
ts
speed: number = 0;

Current speed in metres per second.

status
ts
status: MovementStatus = 'idle';

Current status.

targetIndex
ts
targetIndex: number = 0;

Index of the waypoint currently being steered toward.

Methods

abort()
ts
abort(): void;

Unreal's StopMovement — halt and clear the path.

Returns

void

configure()
ts
configure(patch): void;

Patch the tuning.

Parameters
ParameterTypeDescription
patchPartial<MovementConfig>Fields to change.
Returns

void

moveToActor()
ts
moveToActor(target, acceptanceRadius?): boolean;

Unreal's MoveToActor: follows a possibly-moving target.

Parameters
ParameterTypeDescription
targetMovementTargetThe target.
acceptanceRadius?numberOverride for this move, in metres.
Returns

boolean

Whether a path was found.

moveToLocation()
ts
moveToLocation(point, acceptanceRadius?): boolean;

Unreal's MoveToLocation.

Parameters
ParameterTypeDescription
pointVec3The destination.
acceptanceRadius?numberOverride for this move, in metres.
Returns

boolean

Whether a path was found.

moveToRandomPoint()
ts
moveToRandomPoint(
   center, 
   radius, 
   rng?
): boolean;

Unreal's MoveToRandomPoint.

Parameters
ParameterTypeDescription
centerVec3Search centre.
radiusnumberSearch radius in metres.
rng?() => numberUniform [0, 1) source.
Returns

boolean

Whether a path was found.

reset()
ts
reset(): void;

Clear the path and go idle.

Returns

void

setEventSink()
ts
setEventSink(fn): void;

Set the event sink.

Parameters
ParameterTypeDescription
fnMovementEventSink | nullThe sink, or null.
Returns

void

setGroup()
ts
setGroup(g): void;

Set the transform to drive.

Parameters
ParameterTypeDescription
gMovementGroupLike | nullThe transform, or null.
Returns

void

setNavMesh()
ts
setNavMesh(nm): void;

Set the navmesh.

Parameters
ParameterTypeDescription
nmNavMeshLike | nullThe navmesh, or null.
Returns

void

tick()
ts
tick(dt): void;

Advance one frame.

Parameters
ParameterTypeDescription
dtnumberSeconds since the last tick.
Returns

void

Interfaces

AddClipOptions

How a clip behaves once registered.

Properties

additive?
ts
optional additive?: boolean;

Register the clip on the additive/gesture layer instead of the base layer. Additive actions are never stopped by the base layer's weight pass.

loop?
ts
optional loop?: boolean;

Whether the clip loops; defaults to true.


AdditiveBakeContext

What bakeAdditive needs besides the clip itself.

Properties

boneParents?
ts
optional boneParents?: ReadonlyMap<string, string>;

Child node name to parent node name, required by mesh-space baking.

clipsByName
ts
clipsByName: ReadonlyMap<string, AnimationClip>;

Every loaded clip by name, for the anim_frame and anim_scaled modes.

fps?
ts
optional fps?: number;

Sample rate the Ref Frame Index is interpreted against; defaults to 30.

restPose?
ts
optional restPose?: RestPose;

Rest pose, required by ref_pose and by mesh-space baking.


AdditiveSettings

The additive settings as authored, all optional.

Properties

additiveType?
ts
optional additiveType?: AdditiveType;

Unreal's Additive Anim Type.

basePoseClipName?
ts
optional basePoseClipName?: string | null;

Clip name the base pose is taken from, for anim_frame and anim_scaled.

basePoseType?
ts
optional basePoseType?: BasePoseType;

Unreal's Base Pose Type.

refFrameIndex?
ts
optional refFrameIndex?: number;

Unreal's Ref Frame Index.


Animator

The layered animator.

Properties

ts
readonly blink: BlinkRuntime | null;

The blink channel, or null when blink is disabled.

bodyPose
ts
readonly bodyPose: BodyPose;

The final skeleton pose, including the procedural overrides. Reused per frame.

boneNames
ts
readonly boneNames: readonly string[];

Bone names, in the order BodyPose.bones uses.

expression
ts
readonly expression: Float32Array;

The expression vector in the bundle's space. Reused per frame.

face
ts
readonly face: FaceClipPlayer;

The face-clip blender.

gaze
ts
readonly gaze: Float32Array;

Eye gaze as [pitchL, yawL, pitchR, yawR] in radians. Reused per frame.

gesture
ts
readonly gesture: GestureChannel;

The additive gesture layer.

jointOverrides
ts
readonly jointOverrides: ReadonlyMap<string, Float32Array<ArrayBufferLike>>;

Procedural joint rotations, by bone name.

Each entry is a PARENT-LOCAL delta rotation (xyzw) that PRE-multiplies the bone's animated local rotation. Animator.bodyPose already has them applied; this map is for rig backends that take joint overrides separately and must not have them applied twice.

variables
ts
readonly variables: Map<string, unknown>;

Blueprint variables the body graph reads.

Methods

addClip()
ts
addClip(
   name, 
   clip, 
   options?
): void;

Register a body clip.

Parameters
ParameterTypeDescription
namestringRuntime name; how state.clips and the graph address it.
clipAnimationClipThe clip, already bound to this rig's bone names.
options?AddClipOptionsSee AddClipOptions.
Returns

void

addFaceClip()
ts
addFaceClip(name, clip): void;

Register a face clip.

Parameters
ParameterTypeDescription
namestringRuntime name.
clipFaceClipDataARKit-52 frames; see FaceClipData.
Returns

void

dispose()
ts
dispose(): void;

Release the mixer, the actions and the clip caches.

Returns

void

setGraph()
ts
setGraph(graph): void;

Set (or clear) the body graph.

Parameters
ParameterTypeDescription
graphBodyGraph | nullThe graph, or null to fall back to state.clips / locomotion.
Returns

void

setLocomotion()
ts
setLocomotion(index): void;

Set the locomotion index used by the velocity fallback.

Parameters
ParameterTypeDescription
indexLocomotionIndex | nullThe index, or null to disable the fallback.
Returns

void

setState()
ts
setState(state): void;

Set the character state for the coming frames.

Parameters
ParameterTypeDescription
stateCharacterStateThe state; validate untrusted input with validateCharacterState.
Returns

void

update()
ts
update(dt, context?): void;

Advance every layer by dt.

Parameters
ParameterTypeDescription
dtnumberSeconds since the last update.
context?AnimatorUpdateContextSee AnimatorUpdateContext.
Returns

void


AnimatorOptions

Options for createAnimator.

Properties

ts
optional blink?: false | Partial<BlinkConfig>;

Blink tuning overrides, or false to disable the blink layer.

clock?
ts
optional clock?: Clock;

Millisecond clock; defaults to defaultClock.

expressionSpace
ts
expressionSpace: ExpressionSpace;

The bundle's expression space.

headAim?
ts
optional headAim?: Partial<HeadAimConfig>;

Head-aim tuning overrides.

locomotion?
ts
optional locomotion?: LocomotionIndex;

Locomotion clips, for the velocity-driven fallback.

random?
ts
optional random?: () => number;

Uniform [0, 1) source for blink scheduling and graph randoms.

Returns

number

root
ts
root: Object3D;

The skinned rig root. Its skeleton defines the bone order of BodyPose.


AnimatorUpdateContext

What update needs from the rest of the frame.

Properties

camera?
ts
optional camera?: Object3D<Object3DEventMap> | null;

Camera to look at when the state names no explicit lookAt.

lookAt?
ts
optional lookAt?: readonly [number, number, number] | null;

World point to look at; overrides both the state's lookAt and the camera.


BlinkConfig

Blink scheduler and envelope shape.

Properties

closeMs
ts
closeMs: number;

Lid close ramp, in milliseconds.

holdMs
ts
holdMs: number;

Fully-closed hold, in milliseconds.

maxInterval
ts
maxInterval: number;

Longest gap between blinks, in seconds.

minInterval
ts
minInterval: number;

Shortest gap between blinks, in seconds.

openMs
ts
openMs: number;

Lid open ramp, in milliseconds.


BlinkRuntime

A live procedural-blink channel.

Properties

config
ts
readonly config: Readonly<BlinkConfig>;

The timings currently in force.

Methods

applyToArkit()
ts
applyToArkit(out, gate?): number;

Advance the scheduler and add the blink onto an ARKit-52 weight vector.

Parameters
ParameterTypeDescription
outFloat32ArrayARKit-52 weight vector, written in place and clamped to 1.
gate?numberSentinel weight from the caller; 0 disables the channel.
Returns

number

The blink weight that was applied.

currentWeight()
ts
currentWeight(gate?): number;

The current blink weight, advancing the scheduler.

Call at most once per frame — it advances blink timing.

Parameters
ParameterTypeDescription
gate?numberSentinel weight from the caller; 0 disables the channel.
Returns

number

The envelope value times gate, in [0, 1].

reset()
ts
reset(): void;

Clear the in-flight blink and reschedule; used when a character is swapped.

Returns

void

setConfig()
ts
setConfig(patch): void;

Replace the timings.

Last-writer-wins, and a PARTIAL patch falls back to the defaults for the fields it omits rather than to the previous write — the graph node that drives this re-sends its whole node data every frame, so "keep the previous value" would make a field that was cleared in the editor stick forever.

Parameters
ParameterTypeDescription
patchPartial<BlinkConfig>Fields to set; omitted fields revert to BLINK_DEFAULTS.
Returns

void


BlinkRuntimeOptions

Options for createBlinkRuntime.

Properties

config?
ts
optional config?: Partial<BlinkConfig>;

Initial timings; omitted fields take their BLINK_DEFAULTS value.

now?
ts
optional now?: Clock;

Millisecond clock; defaults to defaultClock.

random?
ts
optional random?: () => number;

Uniform [0, 1) source for the inter-blink delay; defaults to Math.random.

Returns

number


BodyGraph

A body graph: the finalPose node plus everything feeding it.

Properties

edges
ts
edges: readonly GraphEdge[];

Edges, in no particular order.

nodes
ts
nodes: readonly GraphNode[];

Nodes, in no particular order.


BodyMotionTracks

A generated motion payload: per-frame bone quaternions plus a world root track.

Properties

bones
ts
bones: Readonly<Record<string, ArrayLike<number>>>;

Bone name to a flat xyzw stream, four floats per frame.

fps?
ts
optional fps?: number;

Sample rate; defaults to 30.

frames?
ts
optional frames?: number;

Frame count; inferred from the first bone track when omitted.

root?
ts
optional root?: ArrayLike<number>;

Flat world-metre xyz root stream, three floats per frame.


BodyPose

The final skeleton pose for this frame.

Properties

bones
ts
bones: Float32Array;

Per-bone local rotations, xyzw, in skeleton order.

rootPos
ts
rootPos: Float32Array;

The root bone's local position.


BuildBodyMotionClipOptions

Options for buildBodyMotionClip.

Properties

name?
ts
optional name?: string;

Clip name; defaults to generated_motion.

onMissingBone?
ts
optional onMissingBone?: (boneName) => void;

Called once per bone name that is absent from the rig, instead of the POC's console.warn. Omit to ignore missing bones silently.

Parameters
ParameterType
boneNamestring
Returns

void

root
ts
root: Object3D;

The rig root the clip binds to. Replaces the POC's window.__AVATAR_SCENE__.

rootMode?
ts
optional rootMode?: RootMode;

See RootMode; defaults to travel.


CharacterClipRequest

A clip the guest is driving explicitly, bypassing the locomotion blend.

Properties

name
ts
name: string;

Clip name as registered with addClip or addFaceClip.

time?
ts
optional time?: number;

Seek to this time in seconds before the next update; omit to let it run.

weight
ts
weight: number;

Blend weight in [0, 1].


CharacterState

Everything the guest says about a character for one frame.

Properties

clips?
ts
optional clips?: readonly CharacterClipRequest[];

Explicit clip drives. When present, the locomotion blend is bypassed. Names that match a face clip drive the face layer; the rest drive the body.

expression?
ts
optional expression?: Float32Array<ArrayBufferLike>;

An expression vector. 52 long means ARKit-52 and is composed with blink; expressionSpace.dim long means it is already in the bundle's space and is used as-is.

grounded
ts
grounded: boolean;

Whether the character is on the ground.

lookAt?
ts
optional lookAt?: readonly [number, number, number] | null;

World-space point to look at, or null to release the head.

velocity
ts
velocity: readonly [number, number, number];

World-space velocity in metres per second.


ClipTiming

How far through a clip the mixer currently is; the input rules read.

Properties

duration
ts
duration: number;

Clip length in seconds.

ratio
ts
ratio: number;

time / duration, in [0, 1).

remaining
ts
remaining: number;

Seconds left before the clip ends.

time
ts
time: number;

Current time in seconds.


EvalAccumulator

The accumulators an evaluation writes into.

Properties

loop
ts
loop: Map<string, boolean>;

Clip name to loop flag; first writer wins.

speed
ts
speed: Map<string, number>;

Clip name to time scale; first writer wins.

weights
ts
weights: Map<string, number>;

Clip name to summed weight.


ExpressionSpace

Which space the bundle's expression vector is in.

Face clips are always authored in ARKit-52. A bundle whose head model is GNM wants 383 (or the reduced 68) coefficients instead, so the mapping is a BUNDLE field, not a code constant — two characters in one scene can be in different spaces.

Properties

dim
ts
dim: number;

Number of channels in Animator.expression.

kind
ts
kind: "arkit52" | "gnm" | "gnm68";

The space.

map?
ts
optional map?: (arkit, out) => void;

Convert ARKit-52 weights into this space.

Required unless kind is arkit52. Must not allocate: it runs per frame.

Parameters
ParameterTypeDescription
arkitFloat32Array52 ARKit weights.
outFloat32Arraydim channels, written in place.
Returns

void


FaceClipData

A face clip as authored: { fps, frames }.

Properties

fps?
ts
optional fps?: number;

Sample rate, used only to synthesise timeCode when frames omit it.

frames
ts
frames: readonly FaceClipFrame[];

Frames in time order.


FaceClipFrame

One authored frame of a face clip.

Properties

blendshapeWeights
ts
blendshapeWeights: ArrayLike<number>;

ARKit-52 weights for this frame; shorter arrays are zero-padded.

timeCode?
ts
optional timeCode?: number;

Seconds from the clip start. Defaults to index / fps when omitted.


FaceClipPlayer

A live face-clip blender.

Methods

addFaceClip()
ts
addFaceClip(name, clip): void;

Register a face clip.

Parameters
ParameterTypeDescription
namestringRuntime key the drive weights address it by.
clipFaceClipDataThe clip data; see FaceClipData.
Returns

void

aliasClip()
ts
aliasClip(alias, sourceName): boolean;

Point a second key at an already-registered clip — no copy.

Frame data is SHARED, unlike a body-clip alias, which has to clone because three caches one action per clip object. Face clips are read-only weight tables with no per-clip playback state on them (that lives per key), so two keys over one table is correct here and costs nothing.

Parameters
ParameterTypeDescription
aliasstringThe new key.
sourceNamestringThe key that already resolves.
Returns

boolean

Whether alias now resolves.

getBlendedWeights()
ts
getBlendedWeights(weights): Float32Array<ArrayBufferLike> | null;

Blend every driven clip into one ARKit-52 vector.

Parameters
ParameterTypeDescription
weightsReadonlyMap<string, number> | nullDrive weights by clip name; null or empty means nothing plays.
Returns

Float32Array<ArrayBufferLike> | null

A reused 52-element buffer, or null when nothing is driven. Do not retain it across frames — it is overwritten in place.

hasClip()
ts
hasClip(name): boolean;
Parameters
ParameterTypeDescription
namestringRuntime key.
Returns

boolean

Whether a clip is registered under name.

play()
ts
play(name): void;

Start a clip's playback clock if it is not already running.

Parameters
ParameterTypeDescription
namestringRuntime key.
Returns

void

reset()
ts
reset(): void;

Drop every clip and every playback cursor.

Returns

void

stop()
ts
stop(name): void;

Stop a clip, so it restarts from frame 0 next time it is driven.

Parameters
ParameterTypeDescription
namestringRuntime key.
Returns

void


FaceClipPlayerOptions

Options for createFaceClipPlayer.

Properties

now?
ts
optional now?: Clock;

Millisecond clock; defaults to defaultClock.


GeneratedMotionMarker

The aosGeneratedMotion extras a generated clip carries.

Present with keepRootMotion !== true → the clip opted out of root motion, so its pelvis .position is stripped too (play in place). Present with keepRootMotion === true → the authored relative-travel track is kept. Absent → pelvis .position is kept, the behaviour stock and arbitrary custom uploads have always had.

Properties

keepRootMotion?
ts
optional keepRootMotion?: boolean;

Whether the authored pelvis travel track survives the prune.


GestureActionLike

The subset of three's AnimationAction the gesture channel drives.

Properties

blendMode
ts
blendMode: number;

Blend mode; set to ADDITIVE_BLEND_MODE while a gesture plays.

clampWhenFinished
ts
clampWhenFinished: boolean;

Whether the action holds its last frame when it finishes.

loop?
ts
optional loop?: number;

Current loop style, if the implementation exposes one.

Methods

isRunning()
ts
isRunning(): boolean;
Returns

boolean

Whether the action is currently scheduled on the mixer.

play()
ts
play(): void;

Schedule the action on the mixer.

Returns

void

reset()
ts
reset(): unknown;

Rewind the action to its start.

Returns

unknown

setEffectiveWeight()
ts
setEffectiveWeight(weight): void;

Set the effective blend weight.

Parameters
ParameterTypeDescription
weightnumberWeight in [0, 1].
Returns

void

setLoop()
ts
setLoop(mode, count): void;

Set the loop style.

Parameters
ParameterTypeDescription
modenumberLoop style, e.g. LOOP_ONCE.
countnumberRepetition count.
Returns

void

stop()
ts
stop(): void;

Remove the action from the mixer.

Returns

void


GestureChannel

A one-slot additive gesture layer.

Methods

activeClip()
ts
activeClip(): string | null;
Returns

string | null

The clip name of the in-flight gesture, or null.

apply()
ts
apply(actions): void;

Advance the envelope and write the gesture weight onto its action.

Parameters
ParameterTypeDescription
actionsReadonlyMap<string, GestureActionLike>Registered actions by clip name.
Returns

void

isActive()
ts
isActive(): boolean;
Returns

boolean

Whether a gesture envelope is in flight.

play()
ts
play(clipName, options?): boolean;

Start a gesture, replacing whatever was in flight.

Parameters
ParameterTypeDescription
clipNamestringName the clip was registered under.
options?GestureOptionsEnvelope overrides; see GestureOptions.
Returns

boolean

Whether the gesture started; false when it was suppressed.

setExclusiveOverride()
ts
setExclusiveOverride(active): void;

Declare that an exclusive body override owns the skeleton.

A conversational override — generated locomotion, or a performance-classified generated clip — already owns the skeleton exclusively. The base layer zeroes any additive gesture weight while it is active anyway, but STARTING a new envelope under one would leave it primed to pop back in for the tail of its fade-out once the override releases. So play() is suppressed while this is set. Dev/test one-shots (a prefab Test button, a clip preview) must NOT set it, which is why this is an explicit opt-in rather than "any clip is playing".

Parameters
ParameterTypeDescription
activebooleanWhether an exclusive override currently owns the skeleton.
Returns

void

stop()
ts
stop(): void;

Clear the channel without touching the action.

Returns

void


GestureChannelOptions

Options for createGestureChannel.

Properties

now?
ts
optional now?: Clock;

Millisecond clock; defaults to defaultClock.


GestureOptions

Envelope overrides for a single gesture.

Properties

durationMs?
ts
optional durationMs?: number;

Total envelope length, in milliseconds.

fadeInMs?
ts
optional fadeInMs?: number;

Fade-in, in milliseconds.

fadeOutMs?
ts
optional fadeOutMs?: number;

Fade-out, in milliseconds.

peakWeight?
ts
optional peakWeight?: number;

Weight held between the fades.


GraphEdge

One edge of a body or rule graph.

Properties

data?
ts
optional data?: Readonly<Record<string, unknown>>;

Authored payload; a transition edge carries its ruleGraph here.

id?
ts
optional id?: string;

Optional identity; unused by the evaluator.

source
ts
source: string;

Source node id.

target
ts
target: string;

Target node id.

targetHandle?
ts
optional targetHandle?: string;

Which input of the target this edge feeds, e.g. a, b, alpha-in.


GraphNode

One node of a body or rule graph.

Properties

data?
ts
optional data?: Readonly<Record<string, unknown>>;

Authored payload.

id
ts
id: string;

Unique within its (sub)graph.

type
ts
type: string;

Node type, e.g. playClip, blend, stateMachine, ruleCompare.


GraphRuntime

Everything the graph evaluator needs from the outside world.

The POC read all of this from module singletons (animVariables, smRuntime, debugState) and from Date.now(). Injecting it is what makes the evaluator testable, lets two characters share one graph, and keeps the clock consistent with the rest of the package.

Properties

clipTimings
ts
clipTimings: Map<string, ClipTiming>;

Clip timings by clip name, for the anim-time rule nodes.

now
ts
now: Clock;

Millisecond clock.

rand?
ts
optional rand?: () => number;

Uniform [0, 1) source. Absent means a deterministic 0.5, so tests are reproducible.

Returns

number

sm
ts
sm: Map<string, SMState>;

State-machine state by node id.

sticky
ts
sticky: Map<string, StickyRandom>;

Sticky random draws by node id.

valueCache
ts
valueCache: Map<string, number>;

Per-frame value cache; cleared at the start of every evaluation.

variables
ts
variables: Map<string, unknown>;

Blueprint variables read by getVariable and varGet.


GraphRuntimeOptions

Options for createGraphRuntime.

Properties

now
ts
now: () => number;

Millisecond clock.

Returns

number

rand?
ts
optional rand?: () => number;

Uniform [0, 1) source; omit for the deterministic 0.5 stand-in.

Returns

number

variables?
ts
optional variables?: Iterable<readonly [string, unknown], any, any>;

Initial blueprint variables.


HeadAimConfig

Head-aim tuning. All angles are radians.

Properties

joints
ts
joints: readonly readonly [string, number][];

Bone names that share the aim, and the fraction each takes.

maxEyePitch
ts
maxEyePitch: number;

Max additional eye pitch.

maxEyeYaw
ts
maxEyeYaw: number;

Max additional eye yaw, on top of the head's.

maxPitch
ts
maxPitch: number;

Max head pitch.

maxYaw
ts
maxYaw: number;

Max head yaw away from the torso.

rate
ts
rate: number;

Follow rate in 1/seconds.


LocomotionBlend

The result of a 1D blend, reused across frames so the hot path allocates nothing.

Properties

a
ts
a: string | null;

Lower-speed clip name, or null when the index is empty.

alpha
ts
alpha: number;

Mix from a to b, in [0, 1].

b
ts
b: string | null;

Higher-speed clip name; equals a outside the bracketed range.

timeScale
ts
timeScale: number;

Playback rate for both clips, so the stride matches the ground speed.


LocomotionClipMeta

One retargeted locomotion clip, as locomotion.json records it.

Properties

file
ts
file: string;

GLB file name, relative to the index.

loop
ts
loop: boolean;

Whether the clip loops.

name
ts
name: string;

Runtime clip name.

speed
ts
speed: number;

Authored ground speed in metres per second; 0 for idle.


LocomotionIndex

The locomotion.json index a retarget run emits.

Properties

clips
ts
clips: readonly LocomotionClipMeta[];

The clips, in any order; sortLocomotionClips orders them.


LoopConstants

three's loop constants, overridable so this module needs no three import.

Properties

loopOnce?
ts
optional loopOnce?: number;

three's LoopOnce.

loopRepeat?
ts
optional loopRepeat?: number;

three's LoopRepeat.


MoveCompletedEvent

The payload of an onMoveCompleted event.

Properties

reason?
ts
optional reason?: string;

Why it failed, when it did.

result
ts
result: "failed" | "success" | "aborted";

How the move ended.


MovementConfig

Movement tuning.

Properties

accel
ts
accel: number;

Metres per second squared.

acceptanceRadius
ts
acceptanceRadius: number;

Metres; the move completes inside this radius of the goal.

facingOffset
ts
facingOffset: number;

Added to the computed yaw, for models whose forward is not +Z.

maxSpeed
ts
maxSpeed: number;

Metres per second; ~1.4 is a human walk.

replanThreshold
ts
replanThreshold: number;

Metres a followed target may drift before moveToActor re-paths.

turnRate
ts
turnRate: number;

Radians per second.


MovementGroupLike

The transform the component drives: XZ position and yaw.

Properties

position
ts
position: object;

World position. Y is owned by the floor, not by this component.

x
ts
x: number;
y
ts
y: number;
z
ts
z: number;
rotation
ts
rotation: object;

World rotation; only y is written.

y
ts
y: number;

MovementOptions

Options for createMovementComponent.

Properties

config?
ts
optional config?: Partial<MovementConfig>;

Tuning overrides.


The navmesh queries the component needs.

Properties

floorY
ts
floorY: number;

Ground height the component falls back to when it has no group.

Methods

findPath()
ts
findPath(from, to): Vec3[] | null;

Find a path between two points.

Parameters
ParameterTypeDescription
fromVec3Start point.
toVec3Goal point.
Returns

Vec3[] | null

Waypoints including the goal, or null when unreachable.

getRandomReachablePoint()?
ts
optional getRandomReachablePoint(
   center, 
   radius, 
   rng?
): Vec3 | null;

Pick a random reachable point.

Parameters
ParameterTypeDescription
centerVec3Search centre.
radiusnumberSearch radius in metres.
rng?() => numberUniform [0, 1) source.
Returns

Vec3 | null

A point, or null when nothing is reachable.


NodeHandlers

Node-type overrides by node type.

Properties

stateMachine?
ts
optional stateMachine?: NodeHandler;

Handles stateMachine nodes.


PrunableClip

The minimum shape a clip needs for the prune decision.

Properties

tracks
ts
tracks: PrunableTrack[];

Tracks, replaced in place with the kept subset.


PrunableTrack

The minimum shape a track needs for the prune decision.

Properties

name
ts
name: string;

"<nodePath>.<property>", e.g. "Armature/pelvis.position".

times?
ts
optional times?: ArrayLike<number>;

Keyframe times; only the length is read, to classify active vs static.


PruneOptions

Options for pruneBodyClipTracks.

Properties

generatedMarker?
ts
optional generatedMarker?: GeneratedMotionMarker | null;

The clip's aosGeneratedMotion extras, or null for a non-generated clip.


PruneReport

What a prune did, for logging and for tests.

Properties

active
ts
active: number;

Bound tracks with more than ACTIVE_KEY_THRESHOLD keys.

bound
ts
bound: number;

Tracks kept, i.e. bound to a node present on the rig.

samples
ts
samples: string[];

Up to five node paths from the unbound set, for a readable warning.

tracks
ts
tracks: number;

Track count before the prune.

unbound
ts
unbound: number;

Tracks dropped because their node is absent from the rig.


ResolvedAdditiveSettings

The additive settings with every default filled in.

Properties

additiveType
ts
additiveType: "local" | "mesh";

Never none.

basePoseClipName
ts
basePoseClipName: string | null;

Clip name the base pose is taken from, or null.

basePoseType
ts
basePoseType: "ref_pose" | "anim_scaled" | "anim_frame" | "local_frame";

Never none.

refFrameIndex
ts
refFrameIndex: number;

Ref Frame Index, defaulting to 0.


RestFrames

One bone's rest orientation in both skeletons, in MODEL space.

Properties

dstParentRest
ts
dstParentRest: Quat;

Target bone's PARENT rest rotation, model space.

dstRest
ts
dstRest: Quat;

Target bone rest rotation, model space.

srcParentRest
ts
srcParentRest: Quat;

Source bone's PARENT rest rotation, model space.

srcRest
ts
srcRest: Quat;

Source bone rest rotation, model space.


RestPoseEntry

One bone's rest (bind) transform.

Properties

position
ts
position: [number, number, number];

Local position.

quaternion
ts
quaternion: [number, number, number, number];

Local rotation, xyzw.

scale
ts
scale: [number, number, number];

Local scale.


RuleContext

What a rule graph is allowed to read.

Properties

clipTimings?
ts
optional clipTimings?: ReadonlyMap<string, ClipTiming>;

Clip timings by clip name.

currentClipName?
ts
optional currentClipName?: string | null;

The clip the current state is playing, which the anim-time nodes read.

variables?
ts
optional variables?: ReadonlyMap<string, unknown>;

Blueprint variables.


RuleGraph

A rule graph: a ruleResult node plus everything feeding it.

Properties

edges?
ts
optional edges?: readonly GraphEdge[];

Edges, in no particular order.

nodes
ts
nodes: readonly GraphNode[];

Nodes, in no particular order.


SMState

Per-state-machine runtime state, keyed by the state-machine node's id.

Properties

currentState
ts
currentState: string | null;

Current state node id, or null before the entry transition runs.

pickedClip
ts
pickedClip: string | null;

The clip drawn for the current state, for legacy states with no subgraph.

stateEnteredAt
ts
stateEnteredAt: number;

Clock reading when the current state was entered.

transition
ts
transition: SMTransition | null;

The in-flight crossfade, or null.


SMTransition

An in-flight crossfade between two states.

Properties

duration
ts
duration: number;

Crossfade length in milliseconds.

from
ts
from: string;

State being left.

fromPickedClip
ts
fromPickedClip: string | null;

The clip the from state had drawn, so the fade-out keeps playing it.

startTime
ts
startTime: number;

Clock reading when the crossfade started.

to
ts
to: string;

State being entered.


StickyRandom

A sticky random draw, held until its bounds change or its state is re-entered.

Properties

max
ts
max: number;

Upper bound the draw was made against.

min
ts
min: number;

Lower bound the draw was made against.

randomType
ts
randomType: string;

float or int.

value
ts
value: number;

The drawn value.


WeightedActionLike

The subset of three's AnimationAction the base layer drives.

Properties

clampWhenFinished
ts
clampWhenFinished: boolean;

Whether the action holds its last frame when it finishes.

loop?
ts
optional loop?: number;

Current loop style, if the implementation exposes one.

timeScale
ts
timeScale: number;

Playback rate.

Methods

isRunning()
ts
isRunning(): boolean;
Returns

boolean

Whether the action is currently scheduled on the mixer.

play()
ts
play(): void;

Schedule the action on the mixer.

Returns

void

setEffectiveWeight()
ts
setEffectiveWeight(weight): void;

Set the effective blend weight.

Parameters
ParameterTypeDescription
weightnumberWeight in [0, 1].
Returns

void

setLoop()
ts
setLoop(mode, count): void;

Set the loop style.

Parameters
ParameterTypeDescription
modenumberLoop style.
countnumberRepetition count.
Returns

void

stop()
ts
stop(): void;

Remove the action from the mixer.

Returns

void

Type Aliases

AdditiveType

ts
type AdditiveType = "none" | "local" | "mesh";

How the additive delta is computed.


BasePoseType

ts
type BasePoseType = "none" | "ref_pose" | "anim_scaled" | "anim_frame" | "local_frame";

What pose counts as "zero" for the delta.


BoneNameMap

ts
type BoneNameMap = ReadonlyMap<string, string>;

Source bone name to target bone name.


Clock

ts
type Clock = () => number;

A monotonic clock reading, in milliseconds.

Implementations must be monotonic and must not be mixed within one runtime: an envelope started against one clock is always expired against the same one.

Returns

number


GraphNodeData

ts
type GraphNodeData = Readonly<Record<string, unknown>>;

A node's authored payload: arbitrary JSON.


MovementEventSink

ts
type MovementEventSink = (type, data) => void;

Event sink.

Parameters

ParameterTypeDescription
typestringEvent name; only onMoveCompleted is emitted today.
dataMoveCompletedEventEvent payload.

Returns

void


MovementStatus

ts
type MovementStatus = "idle" | "moving" | "arrived" | "failed";

What a move ended as.


MovementTarget

ts
type MovementTarget = 
  | Vec3
  | {
  position: {
     x: number;
     y: number;
     z: number;
  };
}
  | {
  getWorldPosition: {
     x: number;
     y: number;
     z: number;
  };
};

Anything moveToActor can follow.


Quat

ts
type Quat = readonly number[];

A quaternion as four numbers in xyzw order, matching three's memory layout.

Typed as a read-only number array rather than a 4-tuple so a scratch number[] can be fed straight back in without a cast; every function here reads exactly four components.


RestPose

ts
type RestPose = Map<string, RestPoseEntry>;

Rest transforms by node name.


RootMode

ts
type RootMode = "travel" | "lock";

How the pelvis translation is handled.

travel builds the pelvis position track so the clip locomotes — walk and jump leave the ground. lock skips it so the motion plays IN PLACE, which is the shape a gesture wants: the pelvis stays at rest and the clip can layer additively over the base pose without dragging the body across the floor. Bone rotations are identical either way.


Vec3

ts
type Vec3 = readonly [number, number, number];

A world-space point.

Variables

ACTIVE_KEY_THRESHOLD

ts
const ACTIVE_KEY_THRESHOLD: 10 = 10;

Above this many keys a bound track counts as animated rather than a static pose.


ADDITIVE_BLEND_MODE

ts
const ADDITIVE_BLEND_MODE: 2501 = 2501;

three's AdditiveAnimationBlendMode, as a number.

Kept numeric rather than imported so this module stays three-free and can be unit-tested against fake actions. The value is pinned by three's public enum.


ARKIT_COUNT

ts
const ARKIT_COUNT: 52 = 52;

How many ARKit channels there are; the width of every ARKit weight vector.


ts
const ARKIT_EYE_BLINK_LEFT: 0 = 0;

Index of EyeBlinkLeft, the left half of the procedural blink overlay.


ts
const ARKIT_EYE_BLINK_RIGHT: 7 = 7;

Index of EyeBlinkRight, the right half of the procedural blink overlay.


ARKIT_NAMES

ts
const ARKIT_NAMES: readonly ["EyeBlinkLeft", "EyeLookDownLeft", "EyeLookInLeft", "EyeLookOutLeft", "EyeLookUpLeft", "EyeSquintLeft", "EyeWideLeft", "EyeBlinkRight", "EyeLookDownRight", "EyeLookInRight", "EyeLookOutRight", "EyeLookUpRight", "EyeSquintRight", "EyeWideRight", "JawForward", "JawLeft", "JawRight", "JawOpen", "MouthClose", "MouthFunnel", "MouthPucker", "MouthLeft", "MouthRight", "MouthSmileLeft", "MouthSmileRight", "MouthFrownLeft", "MouthFrownRight", "MouthDimpleLeft", "MouthDimpleRight", "MouthStretchLeft", "MouthStretchRight", "MouthRollLower", "MouthRollUpper", "MouthShrugLower", "MouthShrugUpper", "MouthPressLeft", "MouthPressRight", "MouthLowerDownLeft", "MouthLowerDownRight", "MouthUpperUpLeft", "MouthUpperUpRight", "BrowDownLeft", "BrowDownRight", "BrowInnerUp", "BrowOuterUpLeft", "BrowOuterUpRight", "CheekPuff", "CheekSquintLeft", "CheekSquintRight", "NoseSneerLeft", "NoseSneerRight", "TongueOut"];

The 52 ARKit blendshape channel names, in wire order.


ts
const BLINK_DEFAULTS: Readonly<BlinkConfig>;

The Unreal DynamicBlinkSM timings the POC shipped with.


defaultClock

ts
const defaultClock: Clock;

The default clock: performance.now(), monotonic and sub-millisecond.

Returns

Milliseconds since the time origin.


HEAD_AIM_DEFAULTS

ts
const HEAD_AIM_DEFAULTS: Readonly<HeadAimConfig>;

The default head-aim tuning: 45 degrees of yaw over neck_01, neck_02 and head.


IDENTITY_QUAT

ts
const IDENTITY_QUAT: Quat;

The identity rotation.


IDLE_CHARACTER_STATE

ts
const IDLE_CHARACTER_STATE: CharacterState;

A state with nothing driven: standing still, on the ground, looking nowhere.


LOOP_ONCE

ts
const LOOP_ONCE: 2200 = 2200;

three's LoopOnce, as a number, for the same reason.


PACKAGE

ts
const PACKAGE: "@aosengine/animation";

Package identity marker for @aosengine/animation.

Example

ts
import { PACKAGE } from '@aosengine/animation';

console.log(PACKAGE); // '@aosengine/animation'

SM_TRANSITION_MS

ts
const SM_TRANSITION_MS: 300 = 300;

The crossfade length the POC hard-coded in smRuntime, in milliseconds.

Functions

applyWeights()

ts
function applyWeights(
   weights, 
   loop, 
   speed, 
   actions, 
   constants?
): void;

Apply evaluated weights to a set of mixer actions.

Every action absent from weights, or at weight <= 0, is stopped (or zeroed if it was not running). Present actions get their loop style, clamp flag and time scale written ONLY when they change — the steady-state optimisation the POC's GraphEvaluator carried, because setLoop on a running action resets its loop counter and a per-frame write made long non-looping clips restart.

Parameters

ParameterTypeDescription
weightsReadonlyMap<string, number> | nullClip name to weight, or null to stop everything.
loopReadonlyMap<string, boolean> | nullClip name to loop flag; a missing entry means "loop".
speedReadonlyMap<string, number> | nullClip name to time scale; a missing entry means 1.
actionsReadonlyMap<string, WeightedActionLike>Registered actions by clip name.
constantsLoopConstantsthree's loop constants; defaults match three r186.

Returns

void


approachAngle()

ts
function approachAngle(
   current, 
   target, 
   rate, 
   dt
): number;

Move current toward target along the shortest arc, framerate-corrected.

Exponential follow rather than a naive lerp: e^(-rate·2dt) is exactly (e^(-rate·dt))², so one 1/30 s step and two 1/60 s steps land in the same place. A dt-naive lerp drifts with the frame rate, which showed up as the head tracking visibly faster on a fast machine.

Parameters

ParameterTypeDescription
currentnumberCurrent angle in radians.
targetnumberTarget angle in radians.
ratenumberFollow rate in 1/seconds; larger is snappier.
dtnumberDelta time in seconds.

Returns

number

The new angle, wrapped into (-π, π].


arkitIndex()

ts
function arkitIndex(name): number;

Index of an ARKit channel by name, or -1 when the name is not an ARKit one.

Parameters

ParameterTypeDescription
namestringChannel name, case-sensitive, as it appears in ARKIT_NAMES.

Returns

number

The channel index in [0, 52), or -1.


bakeAdditive()

ts
function bakeAdditive(
   clip, 
   settings, 
   ctx
): void;

Bake clip into an additive delta IN PLACE, per the resolved settings.

Parameters

ParameterTypeDescription
clipAnimationClipThe clip, mutated in place.
settingsAdditiveSettings | nullThe authored additive settings, or null for the historical local-space / own-frame-0 default.
ctxAdditiveBakeContextWhat the bake may read; see AdditiveBakeContext.

Returns

void


blendLocomotion()

ts
function blendLocomotion(
   sorted, 
   speed, 
   out
): LocomotionBlend;

Pick and mix the two clips bracketing speed.

Below the slowest clip and above the fastest one the blend clamps to that clip — an idle at speed 0 and a run at 4 m/s bound the space — and only the time scale keeps changing.

Parameters

ParameterTypeDescription
sortedreadonly LocomotionClipMeta[]Clips ordered by ascending speed, from sortLocomotionClips.
speednumberPlanar ground speed in metres per second.
outLocomotionBlendResult written in place, from createLocomotionBlend.

Returns

LocomotionBlend

out.


boneMapFromJson()

ts
function boneMapFromJson(table): BoneNameMap;

Turn a JSON { source: target } table into a BoneNameMap.

Parameters

ParameterTypeDescription
tableunknownParsed mixamo_to_mh.json.

Returns

BoneNameMap

The map.

Throws

When an entry is not a string-to-string pair.


buildBodyMotionClip()

ts
function buildBodyMotionClip(tracks, options): AnimationClip;

Build an AnimationClip bound to a live rig from a generated tracks payload.

Parameters

ParameterTypeDescription
tracksBodyMotionTracksThe payload; see BodyMotionTracks.
optionsBuildBodyMotionClipOptionsSee BuildBodyMotionClipOptions.

Returns

AnimationClip

The clip, ready for mixer.clipAction.

Throws

When the payload is empty or no bone in it exists on the rig.


buildBoneParents()

ts
function buildBoneParents(root): Map<string, string>;

Build a child -> parent node-name map from the rig hierarchy.

Parameters

ParameterTypeDescription
rootObject3DThe rig root.

Returns

Map<string, string>

Child node name to parent node name.


buildRestPose()

ts
function buildRestPose(root): RestPose;

Read the rig's rest (bind) pose straight off the loaded rig root.

At load time — before the mixer plays anything — every bone sits at its rest local transform, which is exactly Unreal's "Skeleton Reference Pose".

Parameters

ParameterTypeDescription
rootObject3DThe rig root, freshly loaded and not yet posed.

Returns

RestPose

Rest transforms by node name.


clampPitch()

ts
function clampPitch(rawPitch, maxPitch): number;

Clamp a pitch to [-maxPitch, maxPitch] after wrapping it.

Pitch has no body-relative frame to fight over — the torso does not pitch in locomotion — so this is the plain symmetric clamp the yaw path cannot use.

Parameters

ParameterTypeDescription
rawPitchnumberDesired look pitch in radians; positive looks up.
maxPitchnumberMax head pitch (radians, >= 0).

Returns

number

The clamped pitch.


clampYawToBody()

ts
function clampYawToBody(
   rawYaw, 
   bodyYaw, 
   maxYaw
): number;

Clamp the desired world yaw to within ±maxYaw of the body's forward yaw, and return the result RELATIVE to the body (so the caller can smooth it and then re-add bodyYaw to get the world-space look direction).

Parameters

ParameterTypeDescription
rawYawnumberDesired look yaw in world space (radians; 0 = +Z).
bodyYawnumberBody forward yaw in world space (radians).
maxYawnumberMax head deviation from the body (radians, >= 0).

Returns

number

Clamped yaw relative to the body forward, in [-maxYaw, maxYaw].


computeRootDelta()

ts
function computeRootDelta(tracks?): [number, number] | null;

Compute the [dx, dz] world-metre XZ root travel — frame-last minus frame-0 — from a generated tracks payload's root stream.

This is the root-motion commit: when a travelling clip finishes, the character must be MOVED by this delta so the resuming base pose continues from the destination instead of snapping back to where the clip started. Y is dropped because the floor owns it.

Parameters

ParameterTypeDescription
tracks?| Pick<BodyMotionTracks, "root" | "frames"> | nullA payload, or any object carrying root and frames.

Returns

[number, number] | null

[dx, dz], or null with fewer than two frames (nothing to commit).


createAnimator()

ts
function createAnimator(options): Animator;

Create a layered animator.

Parameters

ParameterTypeDescription
optionsAnimatorOptionsSee AnimatorOptions.

Returns

Animator

The Animator.


createBlinkRuntime()

ts
function createBlinkRuntime(options?): BlinkRuntime;

Create a procedural blink channel.

Parameters

ParameterTypeDescription
optionsBlinkRuntimeOptionsSee BlinkRuntimeOptions.

Returns

BlinkRuntime

A BlinkRuntime owning its own phase and scheduler.


createEvalAccumulator()

ts
function createEvalAccumulator(): EvalAccumulator;

Create the accumulators an evaluation writes into.

Returns

EvalAccumulator

Empty accumulators, ready to be reused every frame.


createFaceClipPlayer()

ts
function createFaceClipPlayer(options?): FaceClipPlayer;

Create a face-clip blender.

Parameters

ParameterTypeDescription
optionsFaceClipPlayerOptionsSee FaceClipPlayerOptions.

Returns

FaceClipPlayer

A FaceClipPlayer.


createGestureChannel()

ts
function createGestureChannel(options?): GestureChannel;

Create a one-slot additive gesture channel.

Parameters

ParameterTypeDescription
optionsGestureChannelOptionsSee GestureChannelOptions.

Returns

GestureChannel

A GestureChannel.


createGraphRuntime()

ts
function createGraphRuntime(options): GraphRuntime;

Create the runtime context the evaluator reads and mutates.

Parameters

ParameterTypeDescription
optionsGraphRuntimeOptionsSee GraphRuntimeOptions.

Returns

GraphRuntime

A fresh GraphRuntime.


createLocomotionBlend()

ts
function createLocomotionBlend(): LocomotionBlend;

Create an empty blend result to reuse every frame.

Returns

LocomotionBlend

A zeroed LocomotionBlend.


createMovementComponent()

ts
function createMovementComponent(options?): MovementComponent;

Create a movement component.

Parameters

ParameterTypeDescription
optionsMovementOptionsSee MovementOptions.

Returns

MovementComponent

A fresh MovementComponent; there is no shared singleton.


createSMHandler()

ts
function createSMHandler(): NodeHandler;

The stateMachine node handler, for injection into the dispatcher.

Returns

NodeHandler

A handler that drives transitions then evaluates the current state, in that order — the same frame order the POC's updateSMTransitions before evaluateGraph produced.


createSMState()

ts
function createSMState(): SMState;

Create a fresh per-state-machine state object.

Returns

SMState

State stored in rt.sm and mutated in place each frame.


edgeList()

ts
function edgeList(data, key): readonly GraphEdge[];

Read a nested edge list, e.g. a state machine's innerEdges.

Parameters

ParameterTypeDescription
dataReadonly<Record<string, unknown>> | undefinedAuthored payload, possibly undefined.
keystringField name.

Returns

readonly GraphEdge[]

The edges, or an empty array when the field is absent or malformed.


evaluateBody()

ts
function evaluateBody(
   graph, 
   rt, 
   out?, 
   handlers?
): EvalAccumulator;

Evaluate a body graph for one frame.

Parameters

ParameterTypeDefault valueDescription
graphBodyGraphundefinedThe graph. Its finalPose node is the root; the first edge into it is the pose that is evaluated.
rtGraphRuntimeundefinedRuntime context; valueCache is cleared here, because one call is one logical frame and stale cache entries would freeze a wired alpha.
outEvalAccumulator...Accumulators to fill. Cleared first. Omit to allocate fresh ones.
handlersNodeHandlersDEFAULT_HANDLERSNode-type overrides; defaults to the built-in state machine.

Returns

EvalAccumulator

out, or the freshly allocated accumulators.


evaluateRule()

ts
function evaluateRule(graph, ctx?): boolean;

Evaluate a rule graph to a boolean.

Parameters

ParameterTypeDescription
graphRuleGraphThe rule graph.
ctxRuleContextWhat the graph may read; see RuleContext.

Returns

boolean

Whether the rule fired.


hipHeightRatio()

ts
function hipHeightRatio(srcHipHeight, dstHipHeight): number;

Hip-height ratio between two rigs.

Parameters

ParameterTypeDescription
srcHipHeightnumberSource pelvis height above the floor, in metres.
dstHipHeightnumberTarget pelvis height above the floor, in metres.

Returns

number

The ratio, or 1 when either height is missing or zero.


isTrue()

ts
function isTrue(data, key): boolean;

Read a boolean field with strict === true semantics.

Parameters

ParameterTypeDescription
dataReadonly<Record<string, unknown>> | undefinedAuthored payload, possibly undefined.
keystringField name.

Returns

boolean

Whether the field is exactly true.


mapTrackName()

ts
function mapTrackName(trackName, boneMap): string | null;

Map a track name from the source naming convention to the target's.

A track name is "<node>.<property>"; only the node half is mapped.

Parameters

ParameterTypeDescription
trackNamestringSource track name, e.g. mixamorig:LeftArm.quaternion.
boneMapBoneNameMapSource bone name to target bone name.

Returns

string | null

The mapped track name, or null when the bone has no target.


nodeList()

ts
function nodeList(data, key): readonly GraphNode[];

Read a nested node list, e.g. a state machine's innerNodes.

Parameters

ParameterTypeDescription
dataReadonly<Record<string, unknown>> | undefinedAuthored payload, possibly undefined.
keystringField name.

Returns

readonly GraphNode[]

The nodes, or an empty array when the field is absent or malformed.


normalizeAngle()

ts
function normalizeAngle(angle): number;

Wrap an angle into (-π, π].

Parameters

ParameterTypeDescription
anglenumberAngle in radians.

Returns

number

The equivalent angle in (-π, π].


numField()

ts
function numField(
   data, 
   key, 
   fallback
): number;

Read a numeric field, falling back when it is absent or not finite.

Parameters

ParameterTypeDescription
dataReadonly<Record<string, unknown>> | undefinedAuthored payload, possibly undefined.
keystringField name.
fallbacknumberValue used when the field is missing or not a finite number.

Returns

number

The field as a number.


pitchTo()

ts
function pitchTo(
   dx, 
   dy, 
   dz
): number;

World-space pitch of the direction (dx, dy, dz); positive looks up.

Parameters

ParameterTypeDescription
dxnumberWorld-space X offset from the head to the look target.
dynumberWorld-space Y offset from the head to the look target.
dznumberWorld-space Z offset from the head to the look target.

Returns

number

The pitch in radians.


planarSpeed()

ts
function planarSpeed(state): number;

Planar (XZ) speed of a state's velocity.

Y is excluded on purpose: a character falling at 9 m/s is not running, and feeding the fall into the locomotion blend makes the legs sprint mid-air.

Parameters

ParameterTypeDescription
stateCharacterStateThe character state.

Returns

number

Ground speed in metres per second.


pruneBodyClipTracks()

ts
function pruneBodyClipTracks(
   clip, 
   sceneNodes, 
   options?
): PruneReport;

Drop every track of clip that cannot (or should not) bind to sceneNodes.

pelvis.scale is always stripped — it is the rig's metres/centimetres scale defence, and a stationary avatar never needs it. pelvis.position is kept by default; a generated motion that opted OUT of root motion strips it too so the clip plays in place.

Parameters

ParameterTypeDescription
clipPrunableClipClip whose tracks array is replaced in place with the kept subset.
sceneNodesReadonlySet<string>Leaf node names present on the rig.
optionsPruneOptionsPrune options; see PruneOptions.

Returns

PruneReport

A PruneReport describing what was kept and dropped.


quatInvert()

ts
function quatInvert(q): Quat;

Conjugate of a unit quaternion, i.e. its inverse.

Parameters

ParameterTypeDescription
qQuatThe quaternion; assumed normalised, as every rest rotation is.

Returns

Quat

A new quaternion.


quatMultiply()

ts
function quatMultiply(
   a, 
   b, 
   out
): number[];

Hamilton product a * b.

Parameters

ParameterTypeDescription
aQuatLeft quaternion.
bQuatRight quaternion.
outnumber[]Four-element output, written in place.

Returns

number[]

out.


rebindLocalRotation()

ts
function rebindLocalRotation(
   qSource, 
   frames, 
   out
): number[];

Rebind one local rotation from the source rest frame into the target's.

The formula, in model space:

text
q_target_local = inv(P_dst) * P_src * q_source_local * inv(R_src) * R_dst

where R is a bone's rest rotation and P its parent's, both in model space. It has the two properties that make a retarget correct:

  • identical skeletons are a no-op — inv(P)·P·q·inv(R)·R = q;
  • a source pose AT REST maps to the TARGET's rest pose, whatever the two rest poses are, so a retargeted clip starts from the target's own bind pose rather than injecting the source rig's A-pose/T-pose difference as a constant offset into every frame.

The second property is the whole point: skipping it is why naively renamed Mixamo clips leave a character with permanently drooping shoulders.

Parameters

ParameterTypeDescription
qSourceQuatLocal rotation from the source clip.
framesRestFramesRest orientations of the bone in both skeletons.
outnumber[]Four-element output, written in place.

Returns

number[]

out.


rebindQuaternionTrack()

ts
function rebindQuaternionTrack(values, frames): Float32Array<ArrayBufferLike> | number[];

Rebind a whole quaternion keyframe track in place.

Parameters

ParameterTypeDescription
valuesFloat32Array<ArrayBufferLike> | number[]Flat xyzw stream, four floats per key; rewritten in place.
framesRestFramesRest orientations of the bone in both skeletons.

Returns

Float32Array<ArrayBufferLike> | number[]

values, for chaining.


resolveAdditiveSettings()

ts
function resolveAdditiveSettings(settings?): ResolvedAdditiveSettings;

Resolve a possibly-missing or partial settings object into a concrete spec.

Clips that are additive but carry no explicit config fall back to the historical behaviour: local space, referenced against frame 0 of themselves, i.e. a bare makeClipAdditive(clip) call.

Parameters

ParameterTypeDescription
settings?AdditiveSettings | nullThe authored settings, or null.

Returns

ResolvedAdditiveSettings

The resolved spec.


scalePositionTrack()

ts
function scalePositionTrack(values, ratio): Float32Array<ArrayBufferLike> | number[];

Scale a position track by the hip-height ratio between the two rigs.

Root translation is the one track that does not survive a pure rotation rebind: a 1.9 m source actor's pelvis travels further per stride than a 1.6 m target's, so the target would skate. Scaling by dstHipHeight / srcHipHeight makes the stride proportional to the legs that take it.

Parameters

ParameterTypeDescription
valuesFloat32Array<ArrayBufferLike> | number[]Flat xyz stream, three floats per key; rewritten in place.
rationumberdstHipHeight / srcHipHeight.

Returns

Float32Array<ArrayBufferLike> | number[]

values, for chaining.


sortLocomotionClips()

ts
function sortLocomotionClips(index): LocomotionClipMeta[];

Order an index by authored speed, ascending.

Parameters

ParameterTypeDescription
indexLocomotionIndexThe index.

Returns

LocomotionClipMeta[]

A new array, sorted. Sort once at load; never per frame.


strField()

ts
function strField(data, key): string | null;

Read a string field.

Parameters

ParameterTypeDescription
dataReadonly<Record<string, unknown>> | undefinedAuthored payload, possibly undefined.
keystringField name.

Returns

string | null

The field, or null when it is missing or not a non-empty string.


strList()

ts
function strList(data, key): readonly string[];

Read a string array field, e.g. a state's clips.

Parameters

ParameterTypeDescription
dataReadonly<Record<string, unknown>> | undefinedAuthored payload, possibly undefined.
keystringField name.

Returns

readonly string[]

The strings, or an empty array.


timeScaleFor()

ts
function timeScaleFor(speed, clipSpeed): number;

The playback rate that matches a clip's stride to the ground speed.

Parameters

ParameterTypeDescription
speednumberActual ground speed.
clipSpeednumberThe clip's authored speed.

Returns

number

A rate in [0.5, 2], or 1 when the clip is an in-place idle.


validateCharacterState()

ts
function validateCharacterState(value): CharacterState;

Validate an unknown value as a CharacterState.

Parameters

ParameterTypeDescription
valueunknownThe candidate, typically decoded from the guest's frame output.

Returns

CharacterState

A validated state. Array fields are copied; the expressionFloat32Array is NOT copied, because it is the hot path and the guest owns a stable buffer for it.

Throws

Describing the first field that is wrong.


validateLocomotionIndex()

ts
function validateLocomotionIndex(value): LocomotionIndex;

Validate an unknown value as a LocomotionIndex.

locomotion.json is produced by an offline tool and shipped as an asset, so it is untrusted input by the time it reaches the runtime.

Parameters

ParameterTypeDescription
valueunknownParsed JSON.

Returns

LocomotionIndex

The validated index.

Throws

When the shape is wrong.


writeLocomotionWeights()

ts
function writeLocomotionWeights(
   blend, 
   weights, 
   speeds
): void;

Write a blend result into the weight / speed maps the base layer applies.

Parameters

ParameterTypeDescription
blendLocomotionBlendA result from blendLocomotion.
weightsMap<string, number>Cleared and filled with clip name to weight.
speedsMap<string, number>Cleared and filled with clip name to time scale.

Returns

void


yawTo()

ts
function yawTo(dx, dz): number;

World-space yaw of the direction (dx, dz), matching three's +Z forward.

Parameters

ParameterTypeDescription
dxnumberWorld-space X offset from the head to the look target.
dznumberWorld-space Z offset from the head to the look target.

Returns

number

The yaw in radians, 0 when the target is dead ahead on +Z.