@aosengine/animation
Classes
MovementComponent
Navmesh path following for one character.
Constructors
Constructor
ts
new MovementComponent(options?): MovementComponent;Build a component.
Parameters
| Parameter | Type | Description |
|---|---|---|
options | MovementOptions | See MovementOptions. |
Returns
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
| Parameter | Type | Description |
|---|---|---|
patch | Partial<MovementConfig> | Fields to change. |
Returns
void
moveToActor()
ts
moveToActor(target, acceptanceRadius?): boolean;Unreal's MoveToActor: follows a possibly-moving target.
Parameters
| Parameter | Type | Description |
|---|---|---|
target | MovementTarget | The target. |
acceptanceRadius? | number | Override for this move, in metres. |
Returns
boolean
Whether a path was found.
moveToLocation()
ts
moveToLocation(point, acceptanceRadius?): boolean;Unreal's MoveToLocation.
Parameters
| Parameter | Type | Description |
|---|---|---|
point | Vec3 | The destination. |
acceptanceRadius? | number | Override for this move, in metres. |
Returns
boolean
Whether a path was found.
moveToRandomPoint()
ts
moveToRandomPoint(
center,
radius,
rng?
): boolean;Unreal's MoveToRandomPoint.
Parameters
| Parameter | Type | Description |
|---|---|---|
center | Vec3 | Search centre. |
radius | number | Search radius in metres. |
rng? | () => number | Uniform [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
| Parameter | Type | Description |
|---|---|---|
fn | MovementEventSink | null | The sink, or null. |
Returns
void
setGroup()
ts
setGroup(g): void;Set the transform to drive.
Parameters
| Parameter | Type | Description |
|---|---|---|
g | MovementGroupLike | null | The transform, or null. |
Returns
void
setNavMesh()
ts
setNavMesh(nm): void;Set the navmesh.
Parameters
| Parameter | Type | Description |
|---|---|---|
nm | NavMeshLike | null | The navmesh, or null. |
Returns
void
tick()
ts
tick(dt): void;Advance one frame.
Parameters
| Parameter | Type | Description |
|---|---|---|
dt | number | Seconds 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
blink
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
| Parameter | Type | Description |
|---|---|---|
name | string | Runtime name; how state.clips and the graph address it. |
clip | AnimationClip | The clip, already bound to this rig's bone names. |
options? | AddClipOptions | See AddClipOptions. |
Returns
void
addFaceClip()
ts
addFaceClip(name, clip): void;Register a face clip.
Parameters
| Parameter | Type | Description |
|---|---|---|
name | string | Runtime name. |
clip | FaceClipData | ARKit-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
| Parameter | Type | Description |
|---|---|---|
graph | BodyGraph | null | The 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
| Parameter | Type | Description |
|---|---|---|
index | LocomotionIndex | null | The index, or null to disable the fallback. |
Returns
void
setState()
ts
setState(state): void;Set the character state for the coming frames.
Parameters
| Parameter | Type | Description |
|---|---|---|
state | CharacterState | The state; validate untrusted input with validateCharacterState. |
Returns
void
update()
ts
update(dt, context?): void;Advance every layer by dt.
Parameters
| Parameter | Type | Description |
|---|---|---|
dt | number | Seconds since the last update. |
context? | AnimatorUpdateContext | See AnimatorUpdateContext. |
Returns
void
AnimatorOptions
Options for createAnimator.
Properties
blink?
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
| Parameter | Type | Description |
|---|---|---|
out | Float32Array | ARKit-52 weight vector, written in place and clamped to 1. |
gate? | number | Sentinel 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
| Parameter | Type | Description |
|---|---|---|
gate? | number | Sentinel 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
| Parameter | Type | Description |
|---|---|---|
patch | Partial<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
| Parameter | Type |
|---|---|
boneName | string |
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
| Parameter | Type | Description |
|---|---|---|
arkit | Float32Array | 52 ARKit weights. |
out | Float32Array | dim 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
| Parameter | Type | Description |
|---|---|---|
name | string | Runtime key the drive weights address it by. |
clip | FaceClipData | The 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
| Parameter | Type | Description |
|---|---|---|
alias | string | The new key. |
sourceName | string | The 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
| Parameter | Type | Description |
|---|---|---|
weights | ReadonlyMap<string, number> | null | Drive 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
| Parameter | Type | Description |
|---|---|---|
name | string | Runtime 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
| Parameter | Type | Description |
|---|---|---|
name | string | Runtime 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
| Parameter | Type | Description |
|---|---|---|
name | string | Runtime 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
| Parameter | Type | Description |
|---|---|---|
weight | number | Weight in [0, 1]. |
Returns
void
setLoop()
ts
setLoop(mode, count): void;Set the loop style.
Parameters
| Parameter | Type | Description |
|---|---|---|
mode | number | Loop style, e.g. LOOP_ONCE. |
count | number | Repetition 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
| Parameter | Type | Description |
|---|---|---|
actions | ReadonlyMap<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
| Parameter | Type | Description |
|---|---|---|
clipName | string | Name the clip was registered under. |
options? | GestureOptions | Envelope 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
| Parameter | Type | Description |
|---|---|---|
active | boolean | Whether 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.
NavMeshLike
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
| Parameter | Type | Description |
|---|---|---|
from | Vec3 | Start point. |
to | Vec3 | Goal 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
| Parameter | Type | Description |
|---|---|---|
center | Vec3 | Search centre. |
radius | number | Search radius in metres. |
rng? | () => number | Uniform [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
| Parameter | Type | Description |
|---|---|---|
weight | number | Weight in [0, 1]. |
Returns
void
setLoop()
ts
setLoop(mode, count): void;Set the loop style.
Parameters
| Parameter | Type | Description |
|---|---|---|
mode | number | Loop style. |
count | number | Repetition 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
| Parameter | Type | Description |
|---|---|---|
type | string | Event name; only onMoveCompleted is emitted today. |
data | MoveCompletedEvent | Event 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.
ARKIT_EYE_BLINK_LEFT
ts
const ARKIT_EYE_BLINK_LEFT: 0 = 0;Index of EyeBlinkLeft, the left half of the procedural blink overlay.
ARKIT_EYE_BLINK_RIGHT
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.
BLINK_DEFAULTS
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
| Parameter | Type | Description |
|---|---|---|
weights | ReadonlyMap<string, number> | null | Clip name to weight, or null to stop everything. |
loop | ReadonlyMap<string, boolean> | null | Clip name to loop flag; a missing entry means "loop". |
speed | ReadonlyMap<string, number> | null | Clip name to time scale; a missing entry means 1. |
actions | ReadonlyMap<string, WeightedActionLike> | Registered actions by clip name. |
constants | LoopConstants | three'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
| Parameter | Type | Description |
|---|---|---|
current | number | Current angle in radians. |
target | number | Target angle in radians. |
rate | number | Follow rate in 1/seconds; larger is snappier. |
dt | number | Delta 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
| Parameter | Type | Description |
|---|---|---|
name | string | Channel 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
| Parameter | Type | Description |
|---|---|---|
clip | AnimationClip | The clip, mutated in place. |
settings | AdditiveSettings | null | The authored additive settings, or null for the historical local-space / own-frame-0 default. |
ctx | AdditiveBakeContext | What 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
| Parameter | Type | Description |
|---|---|---|
sorted | readonly LocomotionClipMeta[] | Clips ordered by ascending speed, from sortLocomotionClips. |
speed | number | Planar ground speed in metres per second. |
out | LocomotionBlend | Result written in place, from createLocomotionBlend. |
Returns
out.
boneMapFromJson()
ts
function boneMapFromJson(table): BoneNameMap;Turn a JSON { source: target } table into a BoneNameMap.
Parameters
| Parameter | Type | Description |
|---|---|---|
table | unknown | Parsed mixamo_to_mh.json. |
Returns
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
| Parameter | Type | Description |
|---|---|---|
tracks | BodyMotionTracks | The payload; see BodyMotionTracks. |
options | BuildBodyMotionClipOptions | See 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
| Parameter | Type | Description |
|---|---|---|
root | Object3D | The 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
| Parameter | Type | Description |
|---|---|---|
root | Object3D | The rig root, freshly loaded and not yet posed. |
Returns
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
| Parameter | Type | Description |
|---|---|---|
rawPitch | number | Desired look pitch in radians; positive looks up. |
maxPitch | number | Max 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
| Parameter | Type | Description |
|---|---|---|
rawYaw | number | Desired look yaw in world space (radians; 0 = +Z). |
bodyYaw | number | Body forward yaw in world space (radians). |
maxYaw | number | Max 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
| Parameter | Type | Description |
|---|---|---|
tracks? | | Pick<BodyMotionTracks, "root" | "frames"> | null | A 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
| Parameter | Type | Description |
|---|---|---|
options | AnimatorOptions | See AnimatorOptions. |
Returns
The Animator.
createBlinkRuntime()
ts
function createBlinkRuntime(options?): BlinkRuntime;Create a procedural blink channel.
Parameters
| Parameter | Type | Description |
|---|---|---|
options | BlinkRuntimeOptions | See BlinkRuntimeOptions. |
Returns
A BlinkRuntime owning its own phase and scheduler.
createEvalAccumulator()
ts
function createEvalAccumulator(): EvalAccumulator;Create the accumulators an evaluation writes into.
Returns
Empty accumulators, ready to be reused every frame.
createFaceClipPlayer()
ts
function createFaceClipPlayer(options?): FaceClipPlayer;Create a face-clip blender.
Parameters
| Parameter | Type | Description |
|---|---|---|
options | FaceClipPlayerOptions | See FaceClipPlayerOptions. |
Returns
createGestureChannel()
ts
function createGestureChannel(options?): GestureChannel;Create a one-slot additive gesture channel.
Parameters
| Parameter | Type | Description |
|---|---|---|
options | GestureChannelOptions | See GestureChannelOptions. |
Returns
createGraphRuntime()
ts
function createGraphRuntime(options): GraphRuntime;Create the runtime context the evaluator reads and mutates.
Parameters
| Parameter | Type | Description |
|---|---|---|
options | GraphRuntimeOptions | See GraphRuntimeOptions. |
Returns
A fresh GraphRuntime.
createLocomotionBlend()
ts
function createLocomotionBlend(): LocomotionBlend;Create an empty blend result to reuse every frame.
Returns
A zeroed LocomotionBlend.
createMovementComponent()
ts
function createMovementComponent(options?): MovementComponent;Create a movement component.
Parameters
| Parameter | Type | Description |
|---|---|---|
options | MovementOptions | See MovementOptions. |
Returns
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
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
| Parameter | Type | Description |
|---|---|---|
data | Readonly<Record<string, unknown>> | undefined | Authored payload, possibly undefined. |
key | string | Field 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
| Parameter | Type | Default value | Description |
|---|---|---|---|
graph | BodyGraph | undefined | The graph. Its finalPose node is the root; the first edge into it is the pose that is evaluated. |
rt | GraphRuntime | undefined | Runtime context; valueCache is cleared here, because one call is one logical frame and stale cache entries would freeze a wired alpha. |
out | EvalAccumulator | ... | Accumulators to fill. Cleared first. Omit to allocate fresh ones. |
handlers | NodeHandlers | DEFAULT_HANDLERS | Node-type overrides; defaults to the built-in state machine. |
Returns
out, or the freshly allocated accumulators.
evaluateRule()
ts
function evaluateRule(graph, ctx?): boolean;Evaluate a rule graph to a boolean.
Parameters
| Parameter | Type | Description |
|---|---|---|
graph | RuleGraph | The rule graph. |
ctx | RuleContext | What 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
| Parameter | Type | Description |
|---|---|---|
srcHipHeight | number | Source pelvis height above the floor, in metres. |
dstHipHeight | number | Target 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
| Parameter | Type | Description |
|---|---|---|
data | Readonly<Record<string, unknown>> | undefined | Authored payload, possibly undefined. |
key | string | Field 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
| Parameter | Type | Description |
|---|---|---|
trackName | string | Source track name, e.g. mixamorig:LeftArm.quaternion. |
boneMap | BoneNameMap | Source 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
| Parameter | Type | Description |
|---|---|---|
data | Readonly<Record<string, unknown>> | undefined | Authored payload, possibly undefined. |
key | string | Field 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
| Parameter | Type | Description |
|---|---|---|
angle | number | Angle 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
| Parameter | Type | Description |
|---|---|---|
data | Readonly<Record<string, unknown>> | undefined | Authored payload, possibly undefined. |
key | string | Field name. |
fallback | number | Value 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
| Parameter | Type | Description |
|---|---|---|
dx | number | World-space X offset from the head to the look target. |
dy | number | World-space Y offset from the head to the look target. |
dz | number | World-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
| Parameter | Type | Description |
|---|---|---|
state | CharacterState | The 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
| Parameter | Type | Description |
|---|---|---|
clip | PrunableClip | Clip whose tracks array is replaced in place with the kept subset. |
sceneNodes | ReadonlySet<string> | Leaf node names present on the rig. |
options | PruneOptions | Prune options; see PruneOptions. |
Returns
A PruneReport describing what was kept and dropped.
quatInvert()
ts
function quatInvert(q): Quat;Conjugate of a unit quaternion, i.e. its inverse.
Parameters
| Parameter | Type | Description |
|---|---|---|
q | Quat | The quaternion; assumed normalised, as every rest rotation is. |
Returns
A new quaternion.
quatMultiply()
ts
function quatMultiply(
a,
b,
out
): number[];Hamilton product a * b.
Parameters
| Parameter | Type | Description |
|---|---|---|
a | Quat | Left quaternion. |
b | Quat | Right quaternion. |
out | number[] | 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_dstwhere 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
| Parameter | Type | Description |
|---|---|---|
qSource | Quat | Local rotation from the source clip. |
frames | RestFrames | Rest orientations of the bone in both skeletons. |
out | number[] | 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
| Parameter | Type | Description |
|---|---|---|
values | Float32Array<ArrayBufferLike> | number[] | Flat xyzw stream, four floats per key; rewritten in place. |
frames | RestFrames | Rest 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
| Parameter | Type | Description |
|---|---|---|
settings? | AdditiveSettings | null | The authored settings, or null. |
Returns
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
| Parameter | Type | Description |
|---|---|---|
values | Float32Array<ArrayBufferLike> | number[] | Flat xyz stream, three floats per key; rewritten in place. |
ratio | number | dstHipHeight / srcHipHeight. |
Returns
Float32Array<ArrayBufferLike> | number[]
values, for chaining.
sortLocomotionClips()
ts
function sortLocomotionClips(index): LocomotionClipMeta[];Order an index by authored speed, ascending.
Parameters
| Parameter | Type | Description |
|---|---|---|
index | LocomotionIndex | The index. |
Returns
A new array, sorted. Sort once at load; never per frame.
strField()
ts
function strField(data, key): string | null;Read a string field.
Parameters
| Parameter | Type | Description |
|---|---|---|
data | Readonly<Record<string, unknown>> | undefined | Authored payload, possibly undefined. |
key | string | Field 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
| Parameter | Type | Description |
|---|---|---|
data | Readonly<Record<string, unknown>> | undefined | Authored payload, possibly undefined. |
key | string | Field 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
| Parameter | Type | Description |
|---|---|---|
speed | number | Actual ground speed. |
clipSpeed | number | The 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
| Parameter | Type | Description |
|---|---|---|
value | unknown | The candidate, typically decoded from the guest's frame output. |
Returns
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
| Parameter | Type | Description |
|---|---|---|
value | unknown | Parsed JSON. |
Returns
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
| Parameter | Type | Description |
|---|---|---|
blend | LocomotionBlend | A result from blendLocomotion. |
weights | Map<string, number> | Cleared and filled with clip name to weight. |
speeds | Map<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
| Parameter | Type | Description |
|---|---|---|
dx | number | World-space X offset from the head to the look target. |
dz | number | World-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.