Blender  V3.3
instancer.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2022 NVIDIA Corporation
3  * Copyright 2022 Blender Foundation */
4 
5 #include "hydra/instancer.h"
6 
7 #include <pxr/base/gf/quatd.h>
8 #include <pxr/imaging/hd/sceneDelegate.h>
9 
11 
12 HdCyclesInstancer::HdCyclesInstancer(HdSceneDelegate *delegate,
13  const SdfPath &instancerId
14 #if PXR_VERSION <= 2011
15  ,
16  const SdfPath &parentId
17 #endif
18  )
19  : HdInstancer(delegate,
20  instancerId
21 #if PXR_VERSION <= 2011
22  ,
23  parentId
24 #endif
25  )
26 {
27 }
28 
30 {
31 }
32 
33 #if PXR_VERSION > 2011
34 void HdCyclesInstancer::Sync(HdSceneDelegate *sceneDelegate,
35  HdRenderParam *renderParam,
36  HdDirtyBits *dirtyBits)
37 {
38  _UpdateInstancer(sceneDelegate, dirtyBits);
39 
40  if (HdChangeTracker::IsAnyPrimvarDirty(*dirtyBits, GetId())) {
41  SyncPrimvars();
42  }
43 }
44 #endif
45 
46 void HdCyclesInstancer::SyncPrimvars()
47 {
48  HdSceneDelegate *const sceneDelegate = GetDelegate();
49  const HdDirtyBits dirtyBits =
50  sceneDelegate->GetRenderIndex().GetChangeTracker().GetInstancerDirtyBits(GetId());
51 
52  for (const HdPrimvarDescriptor &desc :
53  sceneDelegate->GetPrimvarDescriptors(GetId(), HdInterpolationInstance)) {
54  if (!HdChangeTracker::IsPrimvarDirty(dirtyBits, GetId(), desc.name)) {
55  continue;
56  }
57 
58  const VtValue value = sceneDelegate->Get(GetId(), desc.name);
59  if (value.IsEmpty()) {
60  continue;
61  }
62 
63  if (desc.name == HdInstancerTokens->translate) {
64  _translate = value.Get<VtVec3fArray>();
65  }
66  else if (desc.name == HdInstancerTokens->rotate) {
67  _rotate = value.Get<VtVec4fArray>();
68  }
69  else if (desc.name == HdInstancerTokens->scale) {
70  _scale = value.Get<VtVec3fArray>();
71  }
72  else if (desc.name == HdInstancerTokens->instanceTransform) {
73  _instanceTransform = value.Get<VtMatrix4dArray>();
74  }
75  }
76 
77  sceneDelegate->GetRenderIndex().GetChangeTracker().MarkInstancerClean(GetId());
78 }
79 
80 VtMatrix4dArray HdCyclesInstancer::ComputeInstanceTransforms(const SdfPath &prototypeId)
81 {
82 #if PXR_VERSION <= 2011
83  SyncPrimvars();
84 #endif
85 
86  const VtIntArray instanceIndices = GetDelegate()->GetInstanceIndices(GetId(), prototypeId);
87  const GfMatrix4d instanceTransform = GetDelegate()->GetInstancerTransform(GetId());
88 
89  VtMatrix4dArray transforms;
90  transforms.reserve(instanceIndices.size());
91 
92  for (int index : instanceIndices) {
93  GfMatrix4d transform = instanceTransform;
94 
95  if (index < _translate.size()) {
96  GfMatrix4d translateMat(1);
97  translateMat.SetTranslate(_translate[index]);
98  transform *= translateMat;
99  }
100 
101  if (index < _rotate.size()) {
102  GfMatrix4d rotateMat(1);
103  const GfVec4f &quat = _rotate[index];
104  rotateMat.SetRotate(GfQuatd(quat[0], quat[1], quat[2], quat[3]));
105  transform *= rotateMat;
106  }
107 
108  if (index < _scale.size()) {
109  GfMatrix4d scaleMat(1);
110  scaleMat.SetScale(_scale[index]);
111  transform *= scaleMat;
112  }
113 
114  if (index < _instanceTransform.size()) {
115  transform *= _instanceTransform[index];
116  }
117 
118  transforms.push_back(transform);
119  }
120 
121  VtMatrix4dArray resultTransforms;
122 
123  if (const auto instancer = static_cast<HdCyclesInstancer *>(
124  GetDelegate()->GetRenderIndex().GetInstancer(GetParentId()))) {
125  for (const GfMatrix4d &parentTransform : instancer->ComputeInstanceTransforms(GetId())) {
126  for (const GfMatrix4d &localTransform : transforms) {
127  resultTransforms.push_back(parentTransform * localTransform);
128  }
129  }
130  }
131  else {
132  resultTransforms = std::move(transforms);
133  }
134 
135  return resultTransforms;
136 }
137 
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
HdCyclesInstancer(PXR_NS::HdSceneDelegate *delegate, const PXR_NS::SdfPath &instancerId, const PXR_NS::SdfPath &parentId)
Definition: instancer.cpp:12
PXR_NS::VtMatrix4dArray ComputeInstanceTransforms(const PXR_NS::SdfPath &prototypeId)
Definition: instancer.cpp:80
~HdCyclesInstancer() override
Definition: instancer.cpp:29
#define HDCYCLES_NAMESPACE_CLOSE_SCOPE
Definition: hydra/config.h:17