This class exists to facilitate point cloud style instancing. Instancers, conceptually, are instructions to draw N objects; for each object, store which Rprim you're drawing and what instance-specific primvars you're binding.
"/InstancerA": prototypes = ["/sphere", "/cube", "/sphere"];
hydra:instanceTranslations = [<0,0,0>, <1,0,0>, <0,1,0>]
Hydra stores this in reverse: Rprims store which instancer is drawing them, and the instancer stores which indices in that array of N objects are the given Rprim.
"/sphere": instancerId = "/InstancerA"
"/cube": instancerId = "/InstancerA"
Instancer A: indices("/sphere") = [0, 2]
indices("/cube") = [1]
hydra:instanceTranslations = [<0,0,0>, <1,0,0>, <0,1,0>]
Instancing is implemented by the prototype drawing itself multiple times, and looking up per-instance data each time based on "indices": so "/sphere" would draw itself once with translate=<0,0,0> and once with translate=<0,1,0>.
To make things more exciting, instancers can be nested.
"/cube": instancerId = "/InstancerA"
"/InstancerA": instancerId = "/InstancerB"
indices("/cube") = [0, 1]
hydra:instanceTranslations = [<0,0,0>, <1,0,0>]
"/InstancerB": indices("/InstancerA") = [0, 1]
hydra:instanceTranslations = [<0,0,0>, <0,1,0>]
In this case, "/cube" draws itself four times, for each of the index tuples <0,0>, <0,1>, <1,0>, <1,1> where the first index is the index in instancerA, and the second index is in instancerB.
If the same primvar (e.g. "hydra:instanceTranslations") shows up at multiple levels of nesting, it's resolved as follows:
Transforms
Instance primvars "hydra:instanceTranslations", "hydra:instanceRotations", "hydra:instanceScales", and "hydra:instanceTransforms" are used to compute the final transform of an instance. "hydra:instanceTranslations" and "hydra:instanceScales" are interpreted as vec3: position, and axis-aligned scale respectively. "hydra:instanceRotations" is interpreted as a vec4 quaternion (<real, i, j k>), and "hydra:instanceTransforms" is a 4x4 matrix. In the transform computation, everything is converted to a 4x4 matrix.
There are additional transforms: "instancerTransform" comes from HdSceneDelegate::GetInstancerTransform(instancer, proto), and represents the constant transform between the instancer and the prototype. It varies with each level of nesting, but not across instances.
"transform" is the proto Rprim's local transform.
The final instance transform for instance "index" is computed as:
nested_transform(level) = instancerTransform(level) *
hydra:instanceTranslations(level, index) *
hydra:instanceRotations(level, index) *
hydra:instanceScales(level, index) *
hydra:instanceTransforms(level, index);
output_transform = product(i : nested-levels - 1 -> 0) {
nested_transform(i)
} * transform;
Any transforms not provided by the scene delegate are set to identity.
Class responsibilities
HdInstancer's primary role is to track the "indices" arrays for each proto used by an instancer, and any provided primvar arrays. The implementation is in the renderer-specific instancers, like HdStInstancer.
All data access (aside from local caches) is routed to the HdSceneDelegate.
Definition at line 125 of file instancer.h.