Animation · class

Skeleton

Explained in Animation.

class Skeleton
import { Skeleton } from '@driftengine/animation';

Constructor

new

constructor(joints: readonly Joint[], inverseBind: Float32Array)
ParameterTypeDescription
jointsreadonly Joint[]Sorted parents-first. Refused otherwise.
inverseBindFloat32ArraySixteen floats a joint, column-major, in the same order as joints.

Properties

NameTypeDescription
jointsreadonlyreadonly Joint[]
jointCountreadonlynumber
palettereadonlyFloat32ArraySixteen floats a joint, column-major, claimed once and written in place.
More

This is a skinning palette rather than a set of world matrices: each entry is the joint's world transform times its inverse bind, so it takes a vertex from model space to where the joint has moved it. At the bind pose every entry is identity, whatever the bind pose is, which is the property skeleton.test.ts pins — a reversed multiplication order does not shift a mesh slightly, it explodes it.

worldreadonlyFloat32ArrayEach joint's world matrix, sixteen floats a joint, resolved on the way to the palette.
More

Public because a palette entry is not a world transform. An entry is the world matrix times the joint's inverse bind, which is what a shader needs and is useless to anything asking where a joint is — attaching a sword to a hand, or an IK solver reading a chain. Those want this. Valid after applyPose and meaningless before it.

Methods

applyLocalMatrices

applyLocalMatrices(locals: Float32Array): void

Resolve the hierarchy from local matrices rather than from TRS.

ParameterTypeDescription
localsFloat32ArraySixteen floats a joint, column-major, in joint order. Each is the joint's transform relative to its parent, not its world transform.
More

For a rig whose poses are authored as matrices. applyPose is the right door for anything that interpolates — a clip, a blend tree, a state machine — because a quaternion is what you can blend and Euler angles are not. But a rig computed fresh every frame from gameplay state has no interpolation to do, and forcing it through TRS means decomposing matrices it just composed: a square root and a branch per joint, and a chance to get the rotation order wrong that no test of the engine can catch.

The two writers agree, and skeleton.test.ts pins that against applyPose rather than asserting it — a caller choosing between them on convenience must not be choosing between two answers.

What it costs is a second way in, which is a real cost: a reader now has to know both exist. What would make it wrong is a caller reaching for this to avoid learning quaternions and then wanting to blend — at which point they need applyPose and have built their rig in the one representation that cannot get there.

applyPose

applyPose(pose: Pose): void
ParameterTypeDescription
posePose