Skip to main content

Motion clips and rigs (.motion, .rig)

A .motion file is a keyframe animation: it moves, rotates and scales named parts over time. A .rig file is a hierarchy of joints and attachments (for example shoulder → hand → weapon) that a clip can animate. Studio's Model Animation editor and Timeline create both.

The engine doesn't play these files by itself. Your BT code loads them and applies the poses with the BT functions below. Register them in the asset registry under files.

There are two kinds of clip, told apart by the clip's file format version:

  • Rig clips (format 2.x, the current version) animate the nodes of a rig (or of a scene; see Scenes as rigs). A clip without a format section is a rig clip.
  • Model clips (format 1.x) animate the parts of a procedural model. They start with format: and version: 1.0.0 under it.

Clips saved by older versions of cTurtle say version: 1 (a model clip) or version: 2 (a rig clip) instead. They still load.

.motion example​

A model clip, animating a model part:

format:
version: 1.0.0
model: robot
duration: 1.0
loop: true
tracks:
- part: arm
property: rotation
interpolation: smooth
keys:
- time: 0.0
value: [0.0, 0.0, 0.0]
- time: 1.0
value: [0.0, 0.0, 1.570796]

A rig clip, animating a rig node:

binding: data/weapon-rig.rig
model: Weapon display
duration: 4
loop: true
tracks:
- part: hand
property: rotation
interpolation: bezier
curve: [0.25, 0.1, 0.25, 1.0]
keys:
- time: 0
value: [0, 0, 0]
- time: 4
value: [0, 0, 3.141593]

.motion fields​

FieldTypeDefaultDescription
formatmapnoneThe file format version: leave it out for a rig clip, write version: 1.0.0 under it for a model clip.
bindingstring—Rig clips only, required. Project-relative path of the .rig (or scene) the clip animates.
modelstring—Required. Model clip: the procedural model's name. Rig clip: the rig's name.
durationnumber—Required. Clip length in seconds, more than 0 and at most 3600.
loopbool—Required. true repeats the clip; false holds the last pose.
trackslist—Required. 1 to 128 tracks.

tracks[]​

Each track animates one property of one part. A part can't have two tracks for the same property.

FieldTypeDefaultDescription
partstring—Required. Model clip: model part name. Rig clip: rig node id.
propertystring—Required. position, rotation or scale.
interpolationstring—Required. How values move between keys: step (jump), linear, smooth (eases in and out) or bezier (uses curve).
curve[x1, y1, x2, y2][0.25, 0.1, 0.25, 1.0]Easing curve for bezier, like CSS cubic-bezier. Each value 0–1. Applies to every segment of the track.
keyslist—Required. 1 to 512 keyframes.

keys[]​

FieldTypeDescription
timenumberSeconds from the start, between 0 and duration. Must increase from key to key.
value[x, y, z]The part's position, rotation (radians) or scale at that time, relative to its parent. Scale must stay above 0. Values must be within ±1,000,000.

Playback​

  • Properties without a track stay at the rest pose. Before the first key and after the last, the part holds that key's value.
  • Model clip rotations blend each angle separately, so to spin a full turn you write the full angle (for example 6.283185).
  • Rig clip rotations take the shortest path between keys.

.rig example​

name: Weapon display
nodes:
- id: shoulder
name: Shoulder
kind: joint
position: [0, 1.4, 0]
- id: hand
kind: joint
parent: shoulder
position: [0.8, 0, 0]
- id: weapon
kind: attachment
parent: hand
model: gun

.rig fields​

FieldTypeDefaultDescription
formatmapnoneOptional file format version.
namestring—Required. Rig name; rig clips refer to it in model.
nodeslist—Required. 1 to 512 nodes.

nodes[]​

FieldTypeDefaultDescription
idstring—Required. Unique; can't contain / or :. Clip tracks name it in part.
kindstring—Required. joint, attachment or entity.
namestringidDisplay name.
parentstringnoneParent node's id. Children move with their parent.
modelstringnoneProcedural model drawn at this node, typically on an attachment.
position[x, y, z][0, 0, 0]Rest position, relative to the parent.
rotation[x, y, z][0, 0, 0]Rest rotation in radians, relative to the parent.
scale[x, y, z][1, 1, 1]Rest scale. Each value above 0.

Unknown fields are ignored, and Studio keeps them when editing.

Scenes as rigs​

A rig clip's binding can name a scene file instead of a .rig. The scene's entities with kind: entity become the nodes, using the same id, parent, position, rotation, scale and model fields as rig nodes. The rig name is the scene's top-level animation_name (default Scene).

Runtime API​

FunctionPurpose
ctMotionLoad(path) / ctMotionParse(text)Load a .motion file.
ctMotionTime(clip, elapsed)Turn elapsed seconds into clip time (wraps when looping, otherwise stops at the end).
ctMotionPose(clip, part, time, rest)Get one part's pose at a time.
ctAnimationBindingLoad(path) / ctAnimationBindingParse(text)Load a .rig or a scene used as a rig.
ctAnimationBind(binding, clip)Connect a rig clip to its rig.
ctMotionRigCreate(restParts, clip) / ctMotionRigSample(rig, clip, time, weight)Animate a whole hierarchy and get world poses.

Your game decides when clips play and whether animation or physics moves an object. Signatures are in cturtle/ui/btlib.

Errors​

Loading stops at the first problem.

MessageCause
.motion file uses format version X; this cTurtle reads format 1.x up to 1.0.0 and 2.x up to 2.0.0The clip was written for a newer cTurtle; see File format versions.
.motion file: `version: N` is not a clip versionAn old-style version other than 1 or 2.
Animation requires a binding assetRig clip without binding.
Animation needs a model and a duration in (0, 3600] secondsMissing model, or bad duration.
Animation needs 1 to 128 tracksNo tracks, or too many.
Track needs a part and position, rotation or scale propertyMissing part or bad property.
Interpolation must be step, linear, smooth or bezierBad interpolation.
Duplicate part/property animation trackTwo tracks for the same part and property.
Track needs 1 to 512 keyframesNo keys, or too many.
Key times must increase strictly within the clip durationKey times out of order or outside the clip.
Animated scale must stay positiveA scale key is 0 or negative.
Animation values must be finite and within +/-1000000Value too large.
Expected [x, y, z]A vector isn't a one-line list of three numbers.
Curve coordinates must be finite and between 0 and 1Bad curve.
.rig file: `version: 1` is no longer usedDelete the version line (an older file).
.rig file uses format version X; this cTurtle reads format …The rig was written for a newer cTurtle; see File format versions.
Binding needs 1 to 512 nodesNo nodes, or too many.
Node IDs must be nonempty and contain no slash or colonBad id.
Node kind must be joint, entity or attachmentBad kind.
Duplicate part name: …, Missing parent part: …, Part hierarchy contains a cycle, Part hierarchy exceeds 128 levelsProblems in the node hierarchy.
Animation part is missing: …A track names a part or node that doesn't exist.
Clip does not match its joint/scene bindingClip model doesn't equal the rig's name, or a model clip was bound to a rig.

Vectors (value, position, rotation, scale, curve) must be one-line lists like [1, 2, 3].

See also​