We have a situation where we have asset_A and asset_B both using the same skeleton. Furthermore, B can reference in A (in fact, multiple assets of type A).
By itself, A and B would be valid assets with their own UsdSkel data. However, we’re looking for a solution for the case when B references in A, to have both A and B’s skeletons to be the same prim. Currently, it requires a simple Python code to repoint A’s skel:skeleton relationship to B’s. We’re hoping for a solution that does not require any additional configuration on the stage and leverages what USD can automatically determine.
Based on this thread, it looks like there’s no way for USD right now to automatically recalculate relationship paths that are “external”. Thus, we looked into using inherits instead.
We define a class containing the skeleton, and have both A and B inherit from the class to have the skeleton. We then reference A into B without any modification to the skel:skeleton relationship. We then apply any skeletal transformations (e.g. SkelAnimation) to the skeleton in the class prim so that both A and B can pick up the changes. This works fine.
My questions are 1) whether this is indeed the best way for what we’re doing, and 2) if so, what would be the performance implication for having multiple distinct Skeleton prims (e.g. one for A, and one for B) even though they’re inheriting from the same class?
Hi @waynewu , I think your use of inherits is the best USD can offer as a partial, automatic sharing solution. I have a question out to the Hydra folks about the “benefits of sharing skeleton prims” aspect, and whether using USD native instancing for the Skeleton prims might possibly recover any such benefits in your scenario. Native instancing will not produce any savings in the USD scenegraph since it is only a single prim.
Got some info from the Hydra team that there is low-level sharing of identical buffers in Storm, which you’d still benefit from in your setup with “unique but identical” skeletons; there are other opportunities for sharing that we’d like to pursue in the future, so there probably is some sharing/performance hit, though I’d imagine it is small (in the case of Skeletons, specifically) compared to other costs in that pipeline.
I just want to point out here for anyone that’s looking to try this workflow that even though the skeleton is somewhat “shared” through the inherit arc, most DCCs (e.g. Maya and Houdini) will still import them as distinct skeletons (which makes sense because they are indeed distinct primitives in the composed stage).
So in practice, it’s probably still best to just modify A to use B’s skeleton directly to get a shared skeleton across all DCCs. Perhaps in the future with OpenExec, we’ll have the ability to calculate relationship paths dynamically.