Files
test2/intern/cycles/hydra/instancer.cpp
2024-06-26 21:06:40 +02:00

155 lines
4.3 KiB
C++

/* SPDX-FileCopyrightText: 2022 NVIDIA Corporation
* SPDX-FileCopyrightText: 2022 Blender Foundation
*
* SPDX-License-Identifier: Apache-2.0 */
#include "hydra/instancer.h"
#include <pxr/base/gf/quatd.h>
#include <pxr/imaging/hd/sceneDelegate.h>
HDCYCLES_NAMESPACE_OPEN_SCOPE
HdCyclesInstancer::HdCyclesInstancer(HdSceneDelegate *delegate,
const SdfPath &instancerId
#if PXR_VERSION <= 2011
,
const SdfPath &parentId
#endif
)
: HdInstancer(delegate,
instancerId
#if PXR_VERSION <= 2011
,
parentId
#endif
)
{
}
HdCyclesInstancer::~HdCyclesInstancer() {}
#if PXR_VERSION > 2011
void HdCyclesInstancer::Sync(HdSceneDelegate *sceneDelegate,
HdRenderParam * /*renderParam*/,
HdDirtyBits *dirtyBits)
{
_UpdateInstancer(sceneDelegate, dirtyBits);
if (HdChangeTracker::IsAnyPrimvarDirty(*dirtyBits, GetId())) {
SyncPrimvars();
}
}
#endif
void HdCyclesInstancer::SyncPrimvars()
{
HdSceneDelegate *const sceneDelegate = GetDelegate();
const HdDirtyBits dirtyBits =
sceneDelegate->GetRenderIndex().GetChangeTracker().GetInstancerDirtyBits(GetId());
for (const HdPrimvarDescriptor &desc :
sceneDelegate->GetPrimvarDescriptors(GetId(), HdInterpolationInstance))
{
if (!HdChangeTracker::IsPrimvarDirty(dirtyBits, GetId(), desc.name)) {
continue;
}
const VtValue value = sceneDelegate->Get(GetId(), desc.name);
if (value.IsEmpty()) {
continue;
}
#if PXR_VERSION < 2311
if (desc.name == HdInstancerTokens->translate) {
_translate = value.Get<VtVec3fArray>();
}
else if (desc.name == HdInstancerTokens->rotate) {
_rotate = value.Get<VtVec4fArray>();
}
else if (desc.name == HdInstancerTokens->scale) {
_scale = value.Get<VtVec3fArray>();
}
else if (desc.name == HdInstancerTokens->instanceTransform) {
_instanceTransform = value.Get<VtMatrix4dArray>();
}
#else
if (desc.name == HdInstancerTokens->instanceTranslations) {
_translate = value.Get<VtVec3fArray>();
}
else if (desc.name == HdInstancerTokens->instanceRotations) {
_rotate = value.Get<VtVec4fArray>();
}
else if (desc.name == HdInstancerTokens->instanceScales) {
_scale = value.Get<VtVec3fArray>();
}
else if (desc.name == HdInstancerTokens->instanceTransforms) {
_instanceTransform = value.Get<VtMatrix4dArray>();
}
#endif
}
sceneDelegate->GetRenderIndex().GetChangeTracker().MarkInstancerClean(GetId());
}
VtMatrix4dArray HdCyclesInstancer::ComputeInstanceTransforms(const SdfPath &prototypeId)
{
#if PXR_VERSION <= 2011
SyncPrimvars();
#endif
const VtIntArray instanceIndices = GetDelegate()->GetInstanceIndices(GetId(), prototypeId);
const GfMatrix4d instanceTransform = GetDelegate()->GetInstancerTransform(GetId());
VtMatrix4dArray transforms;
transforms.reserve(instanceIndices.size());
for (int index : instanceIndices) {
GfMatrix4d transform = instanceTransform;
if (index < _translate.size()) {
GfMatrix4d translateMat(1);
translateMat.SetTranslate(_translate[index]);
transform *= translateMat;
}
if (index < _rotate.size()) {
GfMatrix4d rotateMat(1);
const GfVec4f &quat = _rotate[index];
rotateMat.SetRotate(GfQuatd(quat[0], quat[1], quat[2], quat[3]));
transform *= rotateMat;
}
if (index < _scale.size()) {
GfMatrix4d scaleMat(1);
scaleMat.SetScale(_scale[index]);
transform *= scaleMat;
}
if (index < _instanceTransform.size()) {
transform *= _instanceTransform[index];
}
transforms.push_back(transform);
}
VtMatrix4dArray resultTransforms;
if (const auto instancer = static_cast<HdCyclesInstancer *>(
GetDelegate()->GetRenderIndex().GetInstancer(GetParentId())))
{
for (const GfMatrix4d &parentTransform : instancer->ComputeInstanceTransforms(GetId())) {
for (const GfMatrix4d &localTransform : transforms) {
resultTransforms.push_back(parentTransform * localTransform);
}
}
}
else {
resultTransforms = std::move(transforms);
}
return resultTransforms;
}
HDCYCLES_NAMESPACE_CLOSE_SCOPE