Example USD Structure
Overview
Since a BVH animation file only contains skeletal animation data, the plug-in will translate a BVH file into a hierarchy of the following prims from the usdSkel schema:
A
SkelRoot
prim containing:A
Skeleton
prim that holds the bone heirarchy of the BVH fileA
SkelAnimation
prim that holds the skeletal animation data from the BVH file
Timing information is encoded into the metadata of the root layer, and relationships are set up to ensure the animation data drives the skeleton by default.
A Note About Timing Metadata
The plug-in uses the timing information in the BVH file to set the timeCodesPerSecond
metadata on the root layer.
The plug-in deliberately does not set framesPerSecond
on the root layer, as it is the responsibility of the consumer
of animation content to specify the desired playback frame rate, and not the responsibility of the content itself
to dictate this.
A Note About Extents
As recommended, extents for the BVH animation data are computed by the plug-in so that the resultant
skelRoot
contains extents that are valid at the time of authoring.
However, if later on in the pipeline, you plan on composing BVH animation data into a larger scene, and in particular, if you plan on either:
Composing skinned meshes into the
skelRoot
and binding them to animation dataComposing the BVH data into an existing
skelRoot
then, these extents should be re-authored so that they reflect every prim that ends up parented to the skelRoot
.
Example
To illustrate the prims produced by the plug-in, the following example is a direct result of running
usdcat --flattenLayerStack data\test_bvh.bvh
:
#usda 1.0
(
defaultPrim = "Root"
endTimeCode = 21
startTimeCode = 1
timeCodesPerSecond = 23.999808001535985
)
def SkelRoot "Root" (
prepend apiSchemas = ["SkelBindingAPI"]
)
{
float3[] extent.timeSamples = {
1: [(0, 0, 0), (0, 0, 1)],
2: [(0, -0.004576359, 0), (0, 0.008019, 0.99992067)],
...
}
prepend rel skel:skeleton = </Root/Skeleton>
def Skeleton "Skeleton" (
prepend apiSchemas = ["SkelBindingAPI"]
)
{
uniform matrix4d[] bindTransforms = [( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) ), ( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 1, 1) )]
uniform token[] joints = ["Root", "Root/Foo"]
uniform matrix4d[] restTransforms = [( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) ), ( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 1, 1) )]
prepend rel skel:animationSource = </Root/Animation>
}
def SkelAnimation "Animation"
{
uniform token[] joints = ["Root", "Root/Foo"]
quatf[] rotations.timeSamples = {
1: [(1, 0, 0, 0), (1, 0, 0, 0)],
2: [(0.99998015, 0.0062978044, 0, 0), (0.99998015, 0, 0.0062978044, 0)],
...
}
half3[] scales.timeSamples = {
1: [(1, 1, 1), (1, 1, 1)],
}
float3[] translations.timeSamples = {
1: [(0, 0, 0), (0, 0, 1)],
2: [(0, 0.008019, 0), (0, 0, 1)],
...
}
}
}