This document is for a version of USD that is under development. See this page for the current release.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
HdInstancer Class Reference

This class exists to facilitate point cloud style instancing. More...

#include <instancer.h>

+ Inheritance diagram for HdInstancer:

Public Member Functions

HD_API HdInstancer (HdSceneDelegate *delegate, SdfPath const &id)
 Constructor.
 
SdfPath const & GetId () const
 Returns the identifier.
 
SdfPath const & GetParentId () const
 Returns the parent instancer identifier.
 
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 const & GetBuiltinPrimvarNames ()
 
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"]; 
               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 108 of file instancer.h.

Constructor & Destructor Documentation

◆ HdInstancer()

HD_API HdInstancer ( HdSceneDelegate delegate,
SdfPath const &  id 
)

Constructor.

Member Function Documentation

◆ GetDelegate()

HdSceneDelegate * GetDelegate ( ) const
inline

Definition at line 123 of file instancer.h.

◆ GetId()

SdfPath const & GetId ( ) const
inline

Returns the identifier.

Definition at line 118 of file instancer.h.

◆ GetParentId()

SdfPath const & GetParentId ( ) const
inline

Returns the parent instancer identifier.

Definition at line 121 of file instancer.h.

◆ Sync()

virtual HD_API void Sync ( HdSceneDelegate sceneDelegate,
HdRenderParam renderParam,
HdDirtyBits *  dirtyBits 
)
virtual

Reimplemented in HdEmbreeInstancer.


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