Skip to content

Commit

Permalink
USD Viewer: improved stage extent computation
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Dec 3, 2023
1 parent ababb4b commit 310f330
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 35 deletions.
1 change: 1 addition & 0 deletions Samples/USDViewer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,6 @@ PRIVATE
Diligent-Hydrogent
DiligentFX
usd_usdGeom
usd_work
)
set_target_properties(USDViewer PROPERTIES CXX_STANDARD 17)
52 changes: 17 additions & 35 deletions Samples/USDViewer/src/USDViewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,38 +118,18 @@ void USDViewer::Initialize(const SampleInitInfo& InitInfo)
LoadStage();
}

static BoundBox ComputeSceneBounds(pxr::HdSceneDelegate& SceneDelegate, const pxr::UsdPrim& Prim)
static pxr::GfRange3d ComputeStageAABB(const pxr::UsdStage& Stage)
{
BoundBox BB{float3{+FLT_MAX}, float3{-FLT_MAX}};
pxr::TfTokenVector Purposes{{pxr::UsdGeomTokens->default_}};

pxr::UsdGeomBoundable Boundable{Prim};
if (Boundable)
{
pxr::GfRange3d Extent = SceneDelegate.GetExtent(Prim.GetPath());
if (Extent.IsEmpty())
return BB;

BB.Min = float3::MakeVector(Extent.GetMin().data());
BB.Max = float3::MakeVector(Extent.GetMax().data());

pxr::UsdGeomXformable XFormable{Prim};
if (XFormable)
{
// Scene delegate returns global transform
const pxr::GfMatrix4d GlobalTransform = SceneDelegate.GetTransform(Prim.GetPath());

BB = BB.Transform(USD::ToFloat4x4(GlobalTransform));
}

return BB;
}

for (auto Child : Prim.GetAllChildren())
{
BB = BB.Combine(ComputeSceneBounds(SceneDelegate, Child));
}
// Extent hints are sometimes authored as an optimization to avoid
// computing bounds, they are particularly useful for some tests where
// there is no bound on the first frame.
constexpr bool UseExtentHints = true;
pxr::UsdGeomBBoxCache BBoxCache(pxr::UsdTimeCode::Default(), Purposes, UseExtentHints);

return BB;
const pxr::GfBBox3d BBox = BBoxCache.ComputeWorldBound(Stage.GetPseudoRoot());
return BBox.ComputeAlignedRange();
}

static float4x4 GetUpAxisTransform(const pxr::TfToken UpAxis)
Expand Down Expand Up @@ -266,24 +246,26 @@ void USDViewer::LoadStage()
m_Stage.RootTransform = GetUpAxisTransform(UpAxis);
m_Stage.ImagingDelegate->SetRootTransform(USD::ToGfMatrix4d(m_Stage.RootTransform));

float SceneExtent = 100;
if (BoundBox SceneBB = ComputeSceneBounds(*m_Stage.ImagingDelegate, m_Stage.Stage->GetPseudoRoot()))
float SceneExtent = 100;
const pxr::GfRange3d SceneAABB = ComputeStageAABB(*m_Stage.Stage);
if (!SceneAABB.IsEmpty())
{
SceneExtent = 0;
for (size_t i = 0; i < 8; ++i)
{
float3 BBCorner = {
(i & 0x1) ? SceneBB.Max.x : SceneBB.Min.x,
(i & 0x2) ? SceneBB.Max.y : SceneBB.Min.y,
(i & 0x4) ? SceneBB.Max.z : SceneBB.Min.z,
static_cast<float>((i & 0x1) ? SceneAABB.GetMax()[0] : SceneAABB.GetMin()[0]),
static_cast<float>((i & 0x2) ? SceneAABB.GetMax()[1] : SceneAABB.GetMin()[1]),
static_cast<float>((i & 0x4) ? SceneAABB.GetMax()[2] : SceneAABB.GetMin()[2]),
};
SceneExtent = std::max(SceneExtent, length(BBCorner));
}
m_Camera.SetDist(SceneExtent * 2.f);
m_Camera.SetDistRange(0.1f, SceneExtent * 10.f);
m_Camera.SetDistRange(SceneExtent * 0.01f, SceneExtent * 10.f);
}
else
{
m_Camera.SetDist(300.f);
m_Camera.SetDistRange(0.1f, 10000.f);
}

Expand Down

0 comments on commit 310f330

Please sign in to comment.