All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HdInstancer Class Reference

#include <instancer.h>

+ Inheritance diagram for HdInstancer:

Public Member Functions

HD_API HdInstancer (HdSceneDelegate *delegate, SdfPath const &id)
 Constructor. More...
virtual HD_API ~HdInstancer ()
SdfPath constGetId () const
 Returns the identifier. More...
SdfPath constGetParentId () const
 Returns the parent instancer identifier. More...
HdSceneDelegateGetDelegate () const
virtual HD_API void Sync (HdSceneDelegate *sceneDelegate, HdRenderParam *renderParam, HdDirtyBits *dirtyBits)
virtual HD_API void Finalize (HdRenderParam *renderParam)
virtual HD_API HdDirtyBits GetInitialDirtyBitsMask () const

Static Public Member Functions

static HD_API int GetInstancerNumLevels (HdRenderIndex &index, HdRprim const &rprim)
static HD_API TfTokenVector constGetBuiltinPrimvarNames ()
static HD_API void _SyncInstancerAndParents (HdRenderIndex &renderIndex, SdfPath const &instancerId)

Protected Member Functions

HD_API void _UpdateInstancer (HdSceneDelegate *delegate, HdDirtyBits *dirtyBits)

Detailed Description

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"]; 
               translate  = [  <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]
             translate = [<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]
               translate = [<0,0,0>, <1,0,0>]
"/InstancerB": indices("/InstancerA") = [0, 1]
               translate = [<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. "translate") shows up at multiple levels of nesting, it's resolved as follows:


Instance primvars "translate", "rotate", "scale", and "instanceTransform" are used to compute the final transform of an instance. "translate" and "scale" are interpreted as vec3: position, and axis-aligned scale respectively. "rotate" is interpreted as a vec4 quaternion, and "instanceTransform" 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) *
                          translate(level, index) *
                          rotate(level, index) *
                          scale(level, index) *
                          instanceTransform(level, index);
output_transform = product(i : nested-levels - 1 -> 0) {
                   } * 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 124 of file instancer.h.

Constructor & Destructor Documentation

HD_API HdInstancer::HdInstancer ( HdSceneDelegate delegate,
SdfPath const id 


virtual HD_API HdInstancer::~HdInstancer ( )

Member Function Documentation

static HD_API void HdInstancer::_SyncInstancerAndParents ( HdRenderIndex renderIndex,
SdfPath const instancerId 
HD_API void HdInstancer::_UpdateInstancer ( HdSceneDelegate delegate,
HdDirtyBits dirtyBits 
virtual HD_API void HdInstancer::Finalize ( HdRenderParam renderParam)
static HD_API TfTokenVector const& HdInstancer::GetBuiltinPrimvarNames ( )
HdSceneDelegate* HdInstancer::GetDelegate ( ) const

Definition at line 139 of file instancer.h.

SdfPath const& HdInstancer::GetId ( ) const

Returns the identifier.

Definition at line 134 of file instancer.h.

virtual HD_API HdDirtyBits HdInstancer::GetInitialDirtyBitsMask ( ) const
static HD_API int HdInstancer::GetInstancerNumLevels ( HdRenderIndex index,
HdRprim const rprim 
SdfPath const& HdInstancer::GetParentId ( ) const

Returns the parent instancer identifier.

Definition at line 137 of file instancer.h.

virtual HD_API void HdInstancer::Sync ( HdSceneDelegate sceneDelegate,
HdRenderParam renderParam,
HdDirtyBits dirtyBits 

Reimplemented in HdStInstancer, and XUSD_HydraInstancer.

The documentation for this class was generated from the following file: