Animation
Trial includes support for describing animations – meaning how properties aught to evolve over time. These systems can be used to animate individual properties of objects or full skeleton rigs. The constructs on offer for this are fairly standard, allowing import from model files, including skinning.
The relevant concepts for animation are as follows:
animation-track
An animation track is a sequence of keyframes and an interpolation method. Each keyframe is at a specific timecode, and has a value that the track should reach at that code. Timecodes between keyframes are interpolated between via theinterpolation
method. A track's value can besample
d for a desired time code.
Currently the values that a track can interpolate arereal
,vec2
,vec3
,vec4
, andquat
. Other value types, especially composite types, need to be composed out of multiple tracks.clip
A clip is a collection of tracks. Clips retain whether they shouldloop-p
or not, and can bename
d. When a clip issample
d, the target object passed should be a sequence, table, or object that can be indexed into by thename
of thetracks
in the clip.pose
A pose is a collection oftransform
s for a skeleton. It represents a particular state for certain bones in the skeleton to be in. It also allows convenient access to theglobal-transform
of a particular joint, and computing thematrix-palette
used to perform the skinning.skeleton
A skeleton contains all the information necessary for the skinning process, namely abind-pose
andinv-bind-pose
, arest-pose
, and a table for thejoint-names
.skinned-mesh
This is a helper class that contains the mesh data such as the extractedposition-normals
and packedvertex-data
. It can be used to performcpu-skin
ning if needed over the standard gpu-driven skinning method.layer-controller
This mixin class implements theupdate
method in such a way that extra animation poses can be layered onto the base pose. Layers can be added and removed viaadd-layer
andremove-layer
.fade-controller
This mixin class implements smooth playback of animation clips and the transitioning between them. As such implements a baseupdate
method to animate thepose
, and keeps track of possibly multiple fade targets, which can be added viafade-to
. A base clip can also be immediately started viaplay
.armature
A debug display to show poses and animation clips.animated-entity
A base class for skinned 3d models. Requires ananimation-asset
to be passed, but will take care of setting up everything else based on that asset. Is also afade-controller
andlayer-controller
so that animation clips can be easily used with the entity.
Note that it does not handle rendering of the mesh, only the vertex deformation needed to perform the skinning.
When loading stuff from a model file you will not have to worry about any of the underlying stuff. All you need is an animated-entity
and an asset to load the model with. From there you can just play
, fade-to
, and add-layer
/remove-layer
to manage your animations on the entities.
Animated-Assets
In order to use the animation pipeline from model files, the model format system needs to provide a subclass of the animation-asset
. Currently the only format that supports this is the trial-gltf
importer.
Using one should be as simple as this:
(define-asset (workbench model) model-file
#p"model.gltf")
(make-instance 'animated-entity :animation-asset (asset 'workbench 'model))
Once loaded the asset must contain a skeleton
, a hash table of clips
, and a hash table of meshes
. The animated-entity
will automatically extract and reference the properties as needed when you play
, fade-to
, etc.
Trial will also parse out the following extra animation properties from the model, if supported:
next
[string] The name of the clip to play after this.loop
[boolean] Whether to loop this clip or not. Defaults to true if unset. Ifnext
is set, this will be false.forward-kinematic
[boolean] Whether this clip is forward-kinematic or not. If it is, then the root motion will be turned into physical movement instead.velocity-scale
[float] The scale of the root motion when the clip is set to be forward-kinematic.
Defining Clips
Aside from the fully automated import of animations and skins from model files as used with the animated-entity
, you can also programmatically define animation clips to animate other properties and features.
To do so, use define-clip
which has the following general structure:
(define-clip sandstorm
(strength speed)
0.0 0.0 (vec 0.0 0.0)
1.0 0.8 (vec 0.2 0.0)
1.5 _ (vec 1.0 0.0)
2.0 1.0 _)
Wherein _
is used to omit a track from a keyframe. By default track interpolations are set to :linear
. If you specify :hermite
or :cubic
for a track, you must wrap each keyframe value in a list to pass the extra values needed for the interpolation handles.
Once a clip is defined, you can retrieve it by its name via clip
and use sample
to apply the track's effects to an object that contains the properties to be animated.
Note that in general sample
is modifying, meaning it updates the values in place to avoid producing garbage.
Animation clips are only meant for tweening properties. There is no support for evaluating functions at certain times or running other more complex code. If you need a system to put together sequences of actions and other such changes, please have a look at action-lists. They are trivial to integrate with Trial and are geared for that use.