/*! \page UsdSkel_Intro UsdSkel Introduction \section UsdSkel_ScopeAndIntent Overview and Purpose UsdSkel provides an encoding of simple skeletons and blend shapes, with the goal of interchanging basic skeletons and skinned models, both for game studios as well for the performant, scalable interchange of large-scale crowds. This encoding supports both interchanging skinnable rigs, as well as the interchange of skeletal control rigs on their own. \subsection UsdSkel_Motivation Motivation & Trade-Offs UsdSkel was designed with the goal in mind of both being able to represent small numbers of characters, while also being efficient enough to be able to scale up to encoding crowds, consisting of hundreds of thousands of agents. Towards this end, some expressibility trade-offs have been made in the name of scalability: 1. In order to enable UsdSkel to efficiently encode very large numbers of characters, joint animations are stored using a compact, vectorized encoding on each Skeleton. This avoids both excess prim and property bloat, while also greatly improving both read and write performance. Although these factors are negligible on a small number of characters, this provides _substantial_ performance improvements when interchanging large numbers of characters. As a consequence of this, although UsdSkel allows a sparse skeletal animation to be defined, sparse *layering* of joint transforms is not supported. Sparse animation-layering capabilities may eventually be introduced as part of an encoding of animation blending. 2. UsdSkel leverages scene graph instancing to describe _rest state_ instancing, by which the rest state of characters may be shared across multiple instances of a character, each of which has been assigned a unique animation -- *without deinstancing*. This is a critical encoding feature for dealing with large numbers of characters. For the sake of enabling this feature, the encoding of a skeleton has been broken into two parts: The \ref UsdSkel_Skeleton "Skeleton" itself, and an \ref UsdSkel_SkelAnimation "Animation" associated with that skeleton. \subsection UsdSkel_IsNot What UsdSkel Is Not UsdSkel does *not* signal an intent to provide general rigging and execution behaviors as core USD features. We strongly believe that such features are beyond the scope of USD's core concerns. \section UsdSkel_Term Terminology Before discussing any concepts in detail, it's important to establish some common terminology: - \anchor UsdSkel_Term_Skeleton **Skeleton**: An encoding of an animated joint hierarchy. A Skeleton may additional hold other properties that affect deformations, such as weights for a set of blend shapes. - \anchor UsdSkel_Term_SkeletonTopology **Skeleton Topology**: The topology is the description of the parent<->child relationships of all joints in a joint hierarchy. - **Skel Animation**: An encoding of animation for a _Skeleton's_ joints and blendshapes. - **Binding**: An encoding of the binding of a _Skeleton_ to a geometry hierarchy, describing which geometric primitves the _Skeleton_ deforms (if any), and how. - \anchor UsdSkel_Term_JointInfluences **Joint Influences**: The set of joint weights and indices used by skinning algorithms to describe how each point is influenced by the change in joint transformations. \section UsdSkel_SkinnablePrims What Can Be Skinned? UsdSkel makes an attempt at encoding skinning information in a way that generalizes to many types of prims, rather than targetting a strict subset of known types. As a general rule, if a primitive's type inherits from UsdGeomBoundable, and if that primitive is not itself a _UsdSkelSkeleton_, then that primitive is considered by UsdSkel to be a valid *candidate* for skinning. The utility method \ref UsdSkelIsSkinnablePrim can be used to test this rule. When clients iterate over the set of skinnable primitives -- for example, when traversing the skinning targets of a UsdSkelBinding -- it is the client's responsibility to check prim types to determine whether or not they know how to skin each candidate primitive. \section UsdSkel_TransformSpaces Transforms and Transform Spaces There are a few special transform spaces and transforms that will frequently be referenced: - **Joint-Local Space**: The local transform space of each joint. - **Skeleton Space**: The object space of a _Skeleton_. This space does not contain the transformation that positions the root of the _Skeleton_ in the world, and therefore serves as the canonical space in which to apply joint animations. A _Skeleton_ is transformed into world space using the world space transform of the Skeleton primitive. - \anchor UsdSkel_Transforms_GeomBindTransform **Geom Bind Transform**: The transform that positions a skinned primitive in its binding state in _world space_. - **Skinning Transform**: The transform that describes a joint's change in transformation from its _world space_ bind pose, to its animated, _skeleton space_ pose. I.e., `inv(jointWorldSpaceBindTransform)*jointSkelSpaceTransform`. For the sake of planned animation blending capabilities, UsdSkel stores all joint transforms in _Joint Local Space_. To clarify the description of these spaces, a _Skeleton Space_ joint transform is computed from a _Joint Local_ transform as follows: \code jointSkelSpaceTransform = jointLocalSpaceTransform * parentJointSkelSpaceTransform \endcode Where the _parentJointSkelSpaceTransform_ is an identity matrix for root joints, or _jointSkelSpaceTransform_ of the parent joint otherwise. The _World Space_ transform of a joint is computed as: \code jointWorldSpaceTransform = jointLocalSpaceTransform * parentJointSkelSpaceTransform * skelLocalToWorldTransform \endcode Where _skelLocalToWorldTransform_ is the world space transform of the Skeleton primtiive. \section UsdSkel_PointSkinning Skinning a Point (Linear Blend Skinning) Using the terminology established above, in linear blend skinning, the _Skeleton Space_ position of a skinned point is computed as: \code skelSpacePoint = geomBindTransform.Transform(localSpacePoint) p = (0,0,0) for jointIndex,jointWeight in jointInfluencesForPoint: p += skinningTransforms[jointIndex].Transform(skelSpacePoint)*jointWeight \endcode Where _localSpacePoint_ is a point of a skinned primitive, given in the local space of that primitive. */