Share

Rigging

Walking centipede example available in the Bifrost Browser

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.

The matrices contained in a transform

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.

Transform components output in the scene

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

Was this information helpful?