Object Model

Overview

In UsdSkel, skeletons are encoded as independent entities, which are 'bound' to the primitives that they affect – similar to material bindings.

For example:

def Skeleton "Skel" {
rel skel:animationSource = </Anim>
def SkelAnimation "Anim" {}
}
def SkelRoot "Character" {
rel skel:skeleton = </Skel>
def Mesh "Mesh" {
int[] primvars:skel:jointIndices = ...
float[] primvars:skel:jointWeights = ...
}

Above, there is a single skeleton at </Skel>, which is animated according to the animation at </Anim>. That skeleton is bound to </Character>, and so affects every skinnable primitive beneath </Character>, such as </Character/Mesh>.

UsdSkel provides various "query" objects, which provide convenient API to assist extraction of data related to the above components: For Skeleton primitives, a skeleton query can be created to extra resolved data for the skeleton. Similarly, a animation query provides can be created to extract data from an animation. Finally, a skinning query can be used to introspect bindings on skinnable primitives, or to compute the effect of skinning.

All of these query objects are created through a skel cache.

UsdSkelCache: Persistent Skeleton Cache

Bindings in UsdSkel are based on a set of inherited binding properties, set through the UsdSkelBindingAPI schema. The UsdSkelCache provides a cache with an explicit population step, which provides an efficient and simplified way for clients to reason about resolved properties.

UsdSkelSkeletonQuery: Skeleton Resolver

A UsdSkelSkeletonQuery provides a simplified API for querying resolved data related to a UsdSkelSKeleton.

A UsdSkelSkeletonQuery is created through a UsdSkelCache instance. Internally, constructing a query through a cache presents opportunities for sharing work across instanced skeletons. UsdSkelAnimQuery objects, which a UsdSkelSkeletonQuery references (when a valid animation source is bound) are also constructed through a UsdSkelCache. Internally, the UsdSkelCache will share both the UsdSkelAnimQuery objects across primitives that reference the same animation, as well as information about the definition of the skeleton, corresponding to a resolved UsdSkelSkeleton primitive. Both of these properties are shared across Usd_ScenegraphInstancing_Overview "instance primitives."

UsdSkelAnimQuery: Animation Resolver

A UsdSkelAnimQuery provides an interface to computing resolved animation for an animation source.

A UsdSkelAnimQuery is created through a UsdSkelCache instance. This is because we anticipate adding compound animation sources like animation blenders in the future, and expect that different instances of blenders may reference many of the same animations, so requiring a UsdSkelAnimQuery to be constructed through a UsdSkelCache presents an opportunity to share references to queries internally.

Data computed through a UsdSkelAnimQuery includes joint transformations, as well as blend shapes.

It is important to note that per-joint data computations, like joint transformations, provide animation data in the joint order of the animation source. This ordering may not match the order of data as defined on as skeleton, and must be mapped into skeleton-order by an anim mapper.

It is expected that clients should rarely need to interact with a UsdSkelAnimQuery. Instead, clients will typically work through a skeleton query when querying joint transforms.

UsdSkelSkinningQuery: Resolving Joint Influences and Skinning

At each skinnable primitive, a UsdSkelSkinningQuery is populated on a UsdSkelCache to facilitate querying of properties that define how that primitive is to be skinned. This includes joint influences and a geom bind transform.

UsdSkelAnimMapper: Remapping Data Between Different Orders

A helper for mapping vectorized data from one ordering to another.

Vectorized data in UsdSkel may be required to adhere to a variety of different orderings. For example, an animation source provides joint data in its own order, which may need to be remapped into the joint order defined for a skeleton. The skeleton order itself may also need to be remapped into an order declared at a binding site via a skel:joints binding relationship. Clients may also want to remap vectorized animation data into their own, externally-defined order.

A UsdSkelAnimMapper provides a mapping of vectorized data from one ordering to another to simplify these tasks. Based on two token orderings – as defined by two VtTokenArray constructor arguments – a mapper provides a reusable structure for remapping data between different orderings.

For joint orderings defined as part of the core schemas, clients should not generally need to manually construct UsdSkelAnimMapper objects. Rather, the mapper instances are populated on the skel cache, held by the different query objects, where needed. Those UsdSkelAnimMapper objects may be shared across different query objects, if possible.

An effort is made in mappers to provide additional information about a remapping task, to facilitate optimizations while remapping data. For instance, the result of UsdSkelAnimMapper::IsIdentity can be used to decide whether or not any remapping work is required – possibly allowing some array copies to be bypassed. Similarly, UsdSkelAnimMapper::IsNull indicates that no source values can be remapped (and so maybe we need not bother computing the source data to begin with).