Rigging
Bifrost includes some basic tools to help with procedural rigging tasks. At the core of these are a minimalist transformation model, implemented by both the Core::Core::Transform
data type and its related nodes. To get a basic understanding of how these work, take a look at the Rigging example graphs in the Bifrost Browser.
The Transform
type
The Core::Core::Transform
type consists of a set of 4×4 double-precision matrices that can be updated together.
Matrix | Description | Formula |
---|---|---|
Pivot | The rest pose in the graph's world space. This is typically a static value. | P (input directly) |
Pivot Inverse | The inverse of the rest pose in world space. | P-1 |
Pivot Local | The rest pose in the local space of the transform's parent. | PL = PP-1 × P |
Operator | The accumulated changes to the scaling, rotation, and translation. This is typically an animated value. | O (input directly) |
Move Local | The operator applied in the space of the pivot. For example, if the pivot has a rotation of 90 degrees in X then an operator translation in Y results in a move translation in Z. | ML = P × O × P-1 |
Move World | The change in world space resulting from all the operators applied to their transforms in the hierarchy. | MW = MWP × ML |
Local | The animated pose in its parent's local space. | L = PL × O |
World | The animated pose in world space. | W = MW × P |
In addition to the pivot_matrix
and operator_matrix
inputs, the compute_transform
node requires the following two matrices which are extracted from the parent's transform. These matrices are not directly included in the transform's data.
Matrix | Description | Formula |
---|---|---|
Parent Pivot Inverse | The inverse of the parent's pivot. | PP-1 (input directly) |
Parent Move World | The parent transform's move world matrix. | MWP (input directly) |
You can use the update_transform
node to update all the matrices in a Transform
value. The update method that you select determines whether the input is interpreted as a new local, world, operator, or pivot matrix.
When you output a Transform
value to the scene, its member matrices are available directly for connection in the scene graph. You do not need to extract and output these matrices individually.
The Transform
type can also be automatically promoted to a double4x4
matrix. This means that you can plug a transform value directly into a port that accepts such a matrix, and the world-matrix value will be used.
Matrix and transform chains
A chain is an array of 4x4 matrices or transforms where each is treated as the parent of the next one in the array. You can easily create a transform chain from matching arrays of pivot and operator matrices using the compute_transform chain
node. The ik_fk_solver
node is an example of a solver that can perform inverse kinematics on a 2-bone chain. For some other examples of how chains can be used, see the resample_matrix_chain
and compute_transform_chain
graphs in the Rigging category of the Bifrost Browser.
Transform trees and skeletons
A transform tree is similar to a chain in that it is a flat array of transforms, but it requires an additional parent_indices
or joint_parent_index
array to define the tree topology. The parent index must refer to an earlier element in the array, or in the case of a root or isolated joint the parent index must be equal to the output of invalid_index
.
A skeleton is a geometry-like object consisting of a tree of joints. You can create a skeleton from an array of pivot matrices and corresponding array of parent indices using construct_skeleton
. Alternatively, you can construct a skeleton from an array of slash(/)-delimited strings using create_skeleton_from_paths
.
To get an idea of how skeletons can be used, look at the following graphs in the Rigging category of the Bifrost Browser:
dancing_skeleton
maya_skeleton_to_bifrost
usd_skeleton_animation
usd_skeleton_skinning
walking_centipede