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