Skip to content

Commit

Permalink
Adding velocity and acceleration based interpolation to points and re…
Browse files Browse the repository at this point in the history
…moving USD_HAS_UPDATED_TIME_SAMPLE_ARRAY from hdarnold.h. (#673) (#833)

Fixes #832
  • Loading branch information
sirpalee authored Jul 13, 2021
1 parent e194701 commit b174428
Show file tree
Hide file tree
Showing 16 changed files with 295 additions and 134 deletions.
2 changes: 1 addition & 1 deletion render_delegate/basis_curves.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ void HdArnoldBasisCurves::Sync(
(*dirtyBits & HdChangeTracker::DirtyPrimvar);
if (_primvars.count(HdTokens->points) == 0 && HdChangeTracker::IsPrimvarDirty(*dirtyBits, id, HdTokens->points)) {
param.Interrupt();
HdArnoldSetPositionFromPrimvar(GetArnoldNode(), id, sceneDelegate, str::points);
HdArnoldSetPositionFromPrimvar(GetArnoldNode(), id, sceneDelegate, str::points, param());
}

if (HdChangeTracker::IsTopologyDirty(*dirtyBits, id)) {
Expand Down
7 changes: 0 additions & 7 deletions render_delegate/hdarnold.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,6 @@

#include "../arnold_usd.h"

#if PXR_VERSION >= 1911
/// Hydra has the new renderer plugin base class
#define USD_HAS_UPDATED_TIME_SAMPLE_ARRAY
/// Hydra has the updated render buffer class.
#define USD_HAS_UPDATED_RENDER_BUFFER
#endif

#if PXR_VERSION >= 2002
/// Depth range in Hydra was changed from -1 .. 1 to 0 .. 1.
#define USD_HAS_ZERO_TO_ONE_DEPTH
Expand Down
16 changes: 3 additions & 13 deletions render_delegate/mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,7 @@ template <typename UsdType, unsigned ArnoldType>
struct _ConvertValueToArnoldParameter<UsdType, ArnoldType, HdArnoldSampledPrimvarType> {
inline static unsigned int f(AtNode* node, const HdArnoldSampledPrimvarType& samples, const AtString& arnoldName)
{
if (samples.count == 0 ||
#ifdef USD_HAS_UPDATED_TIME_SAMPLE_ARRAY
samples.values.empty() ||
#endif
!samples.values[0].IsHolding<VtArray<UsdType>>()) {
if (samples.count == 0 || samples.values.empty() || !samples.values[0].IsHolding<VtArray<UsdType>>()) {
return 0;
}
const auto& v0 = samples.values[0].UncheckedGet<VtArray<UsdType>>();
Expand All @@ -95,13 +91,7 @@ struct _ConvertValueToArnoldParameter<UsdType, ArnoldType, HdArnoldSampledPrimva
auto* valueList = AiArrayAllocate(static_cast<unsigned int>(v0.size()), numKeys, ArnoldType);
AiArraySetKey(valueList, 0, v0.data());
for (auto index = decltype(numKeys){1}; index < numKeys; index += 1) {
if (
#ifdef USD_HAS_UPDATED_TIME_SAMPLE_ARRAY
samples.values.size()
#else
samples.count
#endif
> index) {
if (samples.values.size() > index) {
const auto& vti = samples.values[index];
if (ARCH_LIKELY(vti.IsHolding<VtArray<UsdType>>())) {
const auto& vi = vti.UncheckedGet<VtArray<UsdType>>();
Expand Down Expand Up @@ -175,7 +165,7 @@ void HdArnoldMesh::Sync(
_numberOfPositionKeys = 1;
} else if (HdChangeTracker::IsPrimvarDirty(*dirtyBits, id, HdTokens->points)) {
param.Interrupt();
_numberOfPositionKeys = HdArnoldSetPositionFromPrimvar(GetArnoldNode(), id, sceneDelegate, str::vlist);
_numberOfPositionKeys = HdArnoldSetPositionFromPrimvar(GetArnoldNode(), id, sceneDelegate, str::vlist, param());
}

const auto dirtyTopology = HdChangeTracker::IsTopologyDirty(*dirtyBits, id);
Expand Down
1 change: 0 additions & 1 deletion render_delegate/native_rprim.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ class HdArnoldNativeRprim : public HdArnoldRprim<HdRprim> {
const TfTokenVector& GetBuiltinPrimvarNames() const;
#endif


private:
/// List of parameters to query from the Hydra Primitive.
const HdArnoldRenderDelegate::NativeRprimParamList* _paramList = nullptr;
Expand Down
57 changes: 32 additions & 25 deletions render_delegate/points.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "points.h"

#include <constant_strings.h>

#include "material.h"
#include "utils.h"

Expand Down Expand Up @@ -43,10 +44,6 @@ void HdArnoldPoints::Sync(
{
HdArnoldRenderParamInterrupt param(renderParam);
const auto& id = GetId();
if (HdChangeTracker::IsPrimvarDirty(*dirtyBits, id, HdTokens->points)) {
param.Interrupt();
HdArnoldSetPositionFromPrimvar(GetArnoldNode(), id, sceneDelegate, str::points);
}

auto transformDirtied = false;
if (HdChangeTracker::IsTransformDirty(*dirtyBits, id)) {
Expand Down Expand Up @@ -75,38 +72,48 @@ void HdArnoldPoints::Sync(
}
}

auto extrapolatePoints = false;
if (*dirtyBits & HdChangeTracker::DirtyPrimvar) {
HdArnoldGetPrimvars(sceneDelegate, id, *dirtyBits, false, _primvars);
_visibilityFlags.ClearPrimvarFlags();
_sidednessFlags.ClearPrimvarFlags();
param.Interrupt();
for (const auto& primvar : sceneDelegate->GetPrimvarDescriptors(id, HdInterpolation::HdInterpolationConstant)) {
HdArnoldSetConstantPrimvar(
GetArnoldNode(), id, sceneDelegate, primvar, &_visibilityFlags, &_sidednessFlags, nullptr);
}

auto convertToUniformPrimvar = [&](const HdPrimvarDescriptor& primvar) {
if (primvar.name != HdTokens->points && primvar.name != HdTokens->widths) {
HdArnoldSetUniformPrimvar(GetArnoldNode(), id, sceneDelegate, primvar);
for (auto& primvar : _primvars) {
auto& desc = primvar.second;
// We can use this information to reset built-in values to their default values.
if (!desc.NeedsUpdate()) {
continue;
}
};

for (const auto& primvar : sceneDelegate->GetPrimvarDescriptors(id, HdInterpolation::HdInterpolationUniform)) {
convertToUniformPrimvar(primvar);
}

for (const auto& primvar : sceneDelegate->GetPrimvarDescriptors(id, HdInterpolation::HdInterpolationVertex)) {
// Per vertex attributes are uniform on points.
convertToUniformPrimvar(primvar);
}

for (const auto& primvar : sceneDelegate->GetPrimvarDescriptors(id, HdInterpolation::HdInterpolationVarying)) {
// Per vertex attributes are uniform on points.
convertToUniformPrimvar(primvar);
if (desc.interpolation == HdInterpolationConstant) {
if (primvar.first == str::deformKeys) {
if (desc.value.IsHolding<int>()) {
extrapolatePoints = SetDeformKeys(desc.value.UncheckedGet<int>());
}
} else {
HdArnoldSetConstantPrimvar(
GetArnoldNode(), primvar.first, desc.role, desc.value, &_visibilityFlags, &_sidednessFlags,
nullptr);
}
// Anything that's not per instance interpolation needs to be converted to uniform data.
} else if (desc.interpolation != HdInterpolationInstance) {
// Even though we are using velocity and acceleration for optional interpolation, we are still
// converting the values to user data.
if (primvar.first != HdTokens->points && primvar.first != HdTokens->widths) {
HdArnoldSetUniformPrimvar(GetArnoldNode(), primvar.first, desc.role, desc.value);
}
}
}

UpdateVisibilityAndSidedness();
}

if (extrapolatePoints || HdChangeTracker::IsPrimvarDirty(*dirtyBits, id, HdTokens->points)) {
param.Interrupt();
HdArnoldSetPositionFromPrimvar(
GetArnoldNode(), id, sceneDelegate, str::points, param(), GetDeformKeys(), &_primvars);
}

SyncShape(*dirtyBits, sceneDelegate, param, transformDirtied);

*dirtyBits = HdChangeTracker::Clean;
Expand Down
5 changes: 4 additions & 1 deletion render_delegate/points.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,16 @@ class HdArnoldPoints : public HdArnoldRprim<HdPoints> {
/// Syncs the Hydra Points to the Arnold Points.
///
/// @param sceneDelegate Pointer to the Scene Delegate.
/// @param renderPaaram Pointer to a HdArnoldRenderParam instance.
/// @param renderParam Pointer to a HdArnoldRenderParam instance.
/// @param dirtyBits Dirty Bits to sync.
/// @param reprToken Token describing the representation of the points.
HDARNOLD_API
void Sync(
HdSceneDelegate* sceneDelegate, HdRenderParam* renderParam, HdDirtyBits* dirtyBits,
const TfToken& reprToken) override;

private:
HdArnoldPrimvarMap _primvars; ///< Precomputed list of primvars.
};

PXR_NAMESPACE_CLOSE_SCOPE
4 changes: 0 additions & 4 deletions render_delegate/render_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,7 @@ bool HdArnoldRenderBuffer::Allocate(const GfVec3i& dimensions, HdFormat format,
return true;
}

#ifdef USD_HAS_UPDATED_RENDER_BUFFER
void* HdArnoldRenderBuffer::Map()
#else
uint8_t* HdArnoldRenderBuffer::Map()
#endif
{
_mutex.lock();
if (_buffer.empty()) {
Expand Down
4 changes: 0 additions & 4 deletions render_delegate/render_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,7 @@ class HdArnoldRenderBuffer : public HdRenderBuffer {
/// Map the buffer for reading.
/// @return The render buffer mapped to memory.
HDARNOLD_API
#ifdef USD_HAS_UPDATED_RENDER_BUFFER
void* Map() override;
#else
uint8_t* Map() override;
#endif
/// Unmap the buffer. It is no longer safe to read from the buffer.
HDARNOLD_API
void Unmap() override;
Expand Down
41 changes: 30 additions & 11 deletions render_delegate/render_delegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,18 @@ void _CheckForIntValue(const VtValue& value, F&& f)
}
}

template <typename F>
void _CheckForFloatValue(const VtValue& value, F&& f)
{
if (value.IsHolding<float>()) {
f(value.UncheckedGet<float>());
} else if (value.IsHolding<double>()) {
f(static_cast<float>(value.UncheckedGet<double>()));
} else if (value.IsHolding<GfHalf>()) {
f(value.UncheckedGet<GfHalf>());
}
}

void _RemoveArnoldGlobalPrefix(const TfToken& key, TfToken& key_new)
{
key_new =
Expand Down Expand Up @@ -393,6 +405,13 @@ HdArnoldRenderDelegate::HdArnoldRenderDelegate(HdArnoldRenderContext context) :
#else
_universe = nullptr;
#endif
#ifdef ARNOLD_MULTIPLE_RENDER_SESSIONS
_renderParam.reset(new HdArnoldRenderParam(this));
#else
_renderParam.reset(new HdArnoldRenderParam());
#endif
// To set the default value.
_fps = _renderParam->GetFPS();
_options = AiUniverseGetOptions(_universe);
for (const auto& o : _GetSupportedRenderSettings()) {
_SetRenderSetting(o.first, o.second.defaultValue);
Expand Down Expand Up @@ -420,12 +439,6 @@ HdArnoldRenderDelegate::HdArnoldRenderDelegate(HdArnoldRenderContext context) :
AiNodeSetStr(
_fallbackVolumeShader, str::name, AtString(TfStringPrintf("fallbackVolume_%p", _fallbackVolumeShader).c_str()));

#ifdef ARNOLD_MULTIPLE_RENDER_SESSIONS
_renderParam.reset(new HdArnoldRenderParam(this));
#else
_renderParam.reset(new HdArnoldRenderParam());
#endif

// We need access to both beauty and P at the same time.
if (_context == HdArnoldRenderContext::Husk) {
#ifdef ARNOLD_MULTIPLE_RENDER_SESSIONS
Expand Down Expand Up @@ -556,6 +569,8 @@ void HdArnoldRenderDelegate::_SetRenderSetting(const TfToken& _key, const VtValu
}
} else if (key == _tokens->instantaneousShutter) {
_CheckForBoolValue(value, [&](const bool b) { AiNodeSetBool(_options, str::ignore_motion_blur, b); });
} else if (key == str::t_houdiniFps) {
_CheckForFloatValue(value, [&](const float f) { _fps = f; });
} else {
auto* optionsEntry = AiNodeGetNodeEntry(_options);
// Sometimes the Render Delegate receives parameters that don't exist
Expand Down Expand Up @@ -1102,7 +1117,7 @@ void HdArnoldRenderDelegate::ApplyLightLinking(AtNode* shape, const VtArray<TfTo
}
}

bool HdArnoldRenderDelegate::ShouldSkipIteration(HdRenderIndex* renderIndex, float shutterOpen, float shutterClose)
bool HdArnoldRenderDelegate::ShouldSkipIteration(HdRenderIndex* renderIndex, const GfVec2f& shutter)
{
HdDirtyBits bits = HdChangeTracker::Clean;
// If Light Linking have changed, we have to dirty the categories on all rprims to force updating the
Expand All @@ -1112,10 +1127,14 @@ bool HdArnoldRenderDelegate::ShouldSkipIteration(HdRenderIndex* renderIndex, flo
}
// When shutter open and shutter close significantly changes, we might not have enough samples for transformation
// and deformation, so we need to force re-syncing all the prims.
if (_shutterOpen != shutterOpen || _shutterClose != shutterClose) {
_shutterOpen = shutterOpen;
_shutterClose = shutterClose;
bits |= HdChangeTracker::DirtyPoints | HdChangeTracker::DirtyTransform | HdChangeTracker::DirtyInstancer;
if (_renderParam->UpdateShutter(shutter)) {
bits |= HdChangeTracker::DirtyPoints | HdChangeTracker::DirtyTransform | HdChangeTracker::DirtyInstancer |
HdChangeTracker::DirtyPrimvar;
}
/// TODO(pal): Investigate if this is needed.
/// When FPS changes we have to dirty points and primvars.
if (_renderParam->UpdateFPS(_fps)) {
bits |= HdChangeTracker::DirtyPoints | HdChangeTracker::DirtyPrimvar;
}
auto skip = false;
if (bits != HdChangeTracker::Clean) {
Expand Down
6 changes: 3 additions & 3 deletions render_delegate/render_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ class HdArnoldRenderDelegate final : public HdRenderDelegate {
/// @param shutterClose Shutter Close value of the active camera.
/// @return True if the iteration should be skipped.
HDARNOLD_API
bool ShouldSkipIteration(HdRenderIndex* renderIndex, float shutterOpen, float shutterClose);
bool ShouldSkipIteration(HdRenderIndex* renderIndex, const GfVec2f& shutter);

using DelegateRenderProducts = std::vector<HdArnoldDelegateRenderProduct>;
/// Returns the list of available Delegate Render Products.
Expand Down Expand Up @@ -468,11 +468,11 @@ class HdArnoldRenderDelegate final : public HdRenderDelegate {
AtNode* _fallbackShader; ///< Pointer to the fallback Arnold Shader.
AtNode* _fallbackVolumeShader; ///< Pointer to the fallback Arnold Volume Shader.
std::string _logFile;
/// FPS value from render settings.
float _fps;
/// Top level render context using Hydra. Ie. Hydra, Solaris, Husk.
HdArnoldRenderContext _context = HdArnoldRenderContext::Hydra;
int _verbosityLogFlags = AI_LOG_WARNINGS | AI_LOG_ERRORS;
float _shutterOpen = 0.0f; ///< Saved Shutter Open value of the active camera.
float _shutterClose = 0.0f; ///< Saved Shutter Close value of the active camera.
bool _ignoreVerbosityLogFlags = false;
};

Expand Down
18 changes: 18 additions & 0 deletions render_delegate/render_param.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,22 @@ void HdArnoldRenderParam::Restart()
_needsRestart.store(true, std::memory_order_release);
}

bool HdArnoldRenderParam::UpdateShutter(const GfVec2f& shutter)
{
if (!GfIsClose(_shutter[0], shutter[0], AI_EPSILON) || !GfIsClose(_shutter[1], shutter[1], AI_EPSILON)) {
_shutter = shutter;
return true;
}
return false;
}

bool HdArnoldRenderParam::UpdateFPS(const float FPS)
{
if (!GfIsClose(_fps, FPS, AI_EPSILON)) {
_fps = FPS;
return true;
}
return false;
}

PXR_NAMESPACE_CLOSE_SCOPE
Loading

0 comments on commit b174428

Please sign in to comment.