Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions extras/imaging/examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
set(PXR_PREFIX examples)
set(PXR_INSTALL_SUBDIR share/usd/examples)

add_subdirectory(hdParticleField)
add_subdirectory(hdTiny)
3 changes: 3 additions & 0 deletions extras/imaging/examples/hdParticleField/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

add_subdirectory(hdParticleField)
add_subdirectory(libGSRenderer)
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
SET(CPPFILES
debugCodes.cpp
tokens.cpp
imaging/dataSourceParticleField.cpp
imaging/particleFieldAdapter.cpp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Convention is to have a CMakeLists.txt for each directory... My inclination would be to promote the USD adapters to pxr/usdImaging/usdLightFieldImaging directly? And then put the whole hydra implementation just directly in pxr/extras/imaging/examples/hdParticleField.

renderDelegate/hd3DGaussianSplat.cpp
renderDelegate/renderBuffer.cpp
renderDelegate/renderDelegate.cpp
renderDelegate/renderer.cpp
renderDelegate/rendererPlugin.cpp
renderDelegate/renderPass.cpp
)

set(PXR_PACKAGE hdParticleField)

pxr_plugin(hdParticleField

CPPFILES
${CPPFILES}

LIBRARIES
arch
js
plug
tf
sdf
vt
gf
hd
hf
usdGeom
usdLightField
usdImaging

GSRenderer

RESOURCE_FILES
plugInfo.json
)

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

#include "debugCodes.h"

PXR_NAMESPACE_OPEN_SCOPE

TF_REGISTRY_FUNCTION(TfDebug) {
TF_DEBUG_ENVIRONMENT_SYMBOL(HDPARTICLEFIELD_GENERAL, "HdParticleField general debug logging.");
}

PXR_NAMESPACE_CLOSE_SCOPE
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

#ifndef HDPARTICLEFIELD_DEBUGCODES_H
#define HDPARTICLEFIELD_DEBUGCODES_H

#include <pxr/base/tf/debug.h>
#include <pxr/pxr.h>

PXR_NAMESPACE_OPEN_SCOPE

TF_DEBUG_CODES(HDPARTICLEFIELD_GENERAL);

PXR_NAMESPACE_CLOSE_SCOPE

#endif // HDPARTICLEFIELD_DEBUGCODES_H
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//
// Copyright 2022 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://openusd.org/license.
//
#include "dataSourceParticleField.h"

#include <pxr/usdImaging/usdImaging/dataSourcePrimvars.h>

#include <pxr/usd/usdLightField/particleField_3DGaussianSplat.h>

#include <pxr/imaging/hd/overlayContainerDataSource.h>
#include <pxr/imaging/hd/primvarsSchema.h>
#include <pxr/imaging/hd/tokens.h>

PXR_NAMESPACE_OPEN_SCOPE

UsdImagingDataSource_3DGaussianSplatPrim::UsdImagingDataSource_3DGaussianSplatPrim(
const SdfPath& sceneIndexPath, UsdPrim usdPrim, const UsdImagingDataSourceStageGlobals& stageGlobals)
: UsdImagingDataSourceGprim(sceneIndexPath, usdPrim, stageGlobals) {}

static const UsdImagingDataSourceCustomPrimvars::Mappings& _GetCustomPrimvarMappings(const UsdPrim& usdPrim) {
static const UsdImagingDataSourceCustomPrimvars::Mappings mappings = {
{UsdLightFieldTokens->positions, UsdLightFieldTokens->positions}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more note I forgot :). We're switched over to datasources in UsdImaging now, and this only maps "positions" and won't correctly fetch the other parameters you need e.g. "orientations", "scales", "opacities", "SH coefficients". Should just be a matter of adding them to this mapping list though?

};

return mappings;
}

HdDataSourceBaseHandle UsdImagingDataSource_3DGaussianSplatPrim::Get(const TfToken& name) {
HdDataSourceBaseHandle const result = UsdImagingDataSourceGprim::Get(name);

if (name == HdPrimvarsSchema::GetSchemaToken()) {
return HdOverlayContainerDataSource::New(
HdContainerDataSource::Cast(result),
UsdImagingDataSourceCustomPrimvars::New(_GetSceneIndexPath(), _GetUsdPrim(),
_GetCustomPrimvarMappings(_GetUsdPrim()), _GetStageGlobals()));
}

return result;
}

/*static*/
HdDataSourceLocatorSet
UsdImagingDataSource_3DGaussianSplatPrim::Invalidate(UsdPrim const& prim, const TfToken& subprim,
const TfTokenVector& properties,
const UsdImagingPropertyInvalidationType invalidationType) {
HdDataSourceLocatorSet result = UsdImagingDataSourceGprim::Invalidate(prim, subprim, properties, invalidationType);

if (subprim.IsEmpty()) {
result.insert(UsdImagingDataSourceCustomPrimvars::Invalidate(properties, _GetCustomPrimvarMappings(prim)));
}

return result;
}

PXR_NAMESPACE_CLOSE_SCOPE
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// Copyright 2022 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://openusd.org/license.
//

#ifndef HDPARTICLEFIELD_DATASOURCEPARTICLEFIELD_H
#define HDPARTICLEFIELD_DATASOURCEPARTICLEFIELD_H

#include <pxr/usdImaging/usdImaging/dataSourceGprim.h>
#include <pxr/usdImaging/usdImaging/dataSourceStageGlobals.h>

#include <pxr/imaging/hd/dataSource.h>

PXR_NAMESPACE_OPEN_SCOPE

class UsdImagingDataSource_3DGaussianSplatPrim : public UsdImagingDataSourceGprim {
public:
HD_DECLARE_DATASOURCE(UsdImagingDataSource_3DGaussianSplatPrim);

USDIMAGING_API
HdDataSourceBaseHandle Get(const TfToken& name) override;

USDIMAGING_API
static HdDataSourceLocatorSet Invalidate(UsdPrim const& prim, const TfToken& subprim,
const TfTokenVector& properties,
UsdImagingPropertyInvalidationType invalidationType);

private:
UsdImagingDataSource_3DGaussianSplatPrim(const SdfPath& sceneIndexPath, UsdPrim usdPrim,
const UsdImagingDataSourceStageGlobals& stageGlobals);
};

HD_DECLARE_DATASOURCE_HANDLES(UsdImagingDataSource_3DGaussianSplatPrim);

PXR_NAMESPACE_CLOSE_SCOPE

#endif // HDPARTICLEFIELD_DATASOURCEPARTICLEFIELD_H
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
//
// Copyright 2016 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://openusd.org/license.
//
#include "particleFieldAdapter.h"

#include "dataSourceParticleField.h"
#include <pxr/usdImaging/usdImaging/delegate.h>
#include <pxr/usdImaging/usdImaging/indexProxy.h>
#include <pxr/usdImaging/usdImaging/primvarUtils.h>
#include <pxr/usdImaging/usdImaging/tokens.h>

#include <pxr/imaging/hd/perfLog.h>
#include <pxr/imaging/hd/points.h>

#include <pxr/usd/usdGeom/points.h>
#include <pxr/usd/usdGeom/primvarsAPI.h>

#include <pxr/usd/usdLightField/particleField_3DGaussianSplat.h>

#include <pxr/base/tf/type.h>

#include "../tokens.h"

PXR_NAMESPACE_OPEN_SCOPE

TF_REGISTRY_FUNCTION(TfType) {
typedef UsdImaging_3DGaussianSplatAdapter Adapter;
TfType adapterType = TfType::Define<Adapter, TfType::Bases<Adapter::BaseAdapter>>();
adapterType.SetFactory<UsdImagingPrimAdapterFactory<Adapter>>();
}

UsdImaging_3DGaussianSplatAdapter::~UsdImaging_3DGaussianSplatAdapter() {}

TfTokenVector UsdImaging_3DGaussianSplatAdapter::GetImagingSubprims(UsdPrim const& prim) { return {TfToken()}; }

TfToken UsdImaging_3DGaussianSplatAdapter::GetImagingSubprimType(UsdPrim const& prim, TfToken const& subprim) {
if (subprim.IsEmpty()) {
return HdParticleFieldTokens->ParticleField_3DGaussianSplat;
}
return TfToken();
}

HdContainerDataSourceHandle
UsdImaging_3DGaussianSplatAdapter::GetImagingSubprimData(UsdPrim const& prim, TfToken const& subprim,
const UsdImagingDataSourceStageGlobals& stageGlobals) {
if (subprim.IsEmpty()) {
return UsdImagingDataSource_3DGaussianSplatPrim::New(prim.GetPath(), prim, stageGlobals);
}
return nullptr;
}

HdDataSourceLocatorSet
UsdImaging_3DGaussianSplatAdapter::InvalidateImagingSubprim(UsdPrim const& prim, TfToken const& subprim,
TfTokenVector const& properties,
const UsdImagingPropertyInvalidationType invalidationType) {
if (subprim.IsEmpty()) {
return UsdImagingDataSource_3DGaussianSplatPrim::Invalidate(prim, subprim, properties, invalidationType);
}

return HdDataSourceLocatorSet();
}

bool UsdImaging_3DGaussianSplatAdapter::IsSupported(UsdImagingIndexProxy const* index) const {
return index->IsRprimTypeSupported(HdParticleFieldTokens->ParticleField_3DGaussianSplat);
}

SdfPath UsdImaging_3DGaussianSplatAdapter::Populate(UsdPrim const& prim, UsdImagingIndexProxy* index,
UsdImagingInstancerContext const* instancerContext) {
return _AddRprim(HdParticleFieldTokens->ParticleField_3DGaussianSplat, prim, index, GetMaterialUsdPath(prim),
instancerContext);
}

void UsdImaging_3DGaussianSplatAdapter::TrackVariability(UsdPrim const& prim, SdfPath const& cachePath,
HdDirtyBits* timeVaryingBits,
UsdImagingInstancerContext const* instancerContext) const {
BaseAdapter::TrackVariability(prim, cachePath, timeVaryingBits, instancerContext);
//
// // Discover time-varying points.
// _IsVarying(prim,
// UsdLightFieldTokens->positions,
// HdChangeTracker::DirtyPoints,
// UsdImagingTokens->usdVaryingPrimvar,
// timeVaryingBits,
// /*isInherited*/false);
// _IsVarying(prim,
// UsdLightFieldTokens->positionsh,
// HdChangeTracker::DirtyPoints,
// UsdImagingTokens->usdVaryingPrimvar,
// timeVaryingBits,
// /*isInherited*/false);
}

void UsdImaging_3DGaussianSplatAdapter::UpdateForTime(UsdPrim const& prim, SdfPath const& cachePath, UsdTimeCode time,
HdDirtyBits requestedBits,
UsdImagingInstancerContext const* instancerContext) const {
BaseAdapter::UpdateForTime(
prim, cachePath, time, requestedBits, instancerContext);
}

HdDirtyBits UsdImaging_3DGaussianSplatAdapter::ProcessPropertyChange(UsdPrim const& prim, SdfPath const& cachePath,
TfToken const& propertyName) {
// Allow base class to handle change processing.
return BaseAdapter::ProcessPropertyChange(prim, cachePath, propertyName);
}

/*virtual*/
VtValue UsdImaging_3DGaussianSplatAdapter::Get(UsdPrim const& prim, SdfPath const& cachePath, TfToken const& key,
UsdTimeCode time, VtIntArray* outIndices) const {
TRACE_FUNCTION();
HF_MALLOC_TAG_FUNCTION();

return BaseAdapter::Get(prim, cachePath, key, time, outIndices);
}

PXR_NAMESPACE_CLOSE_SCOPE
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//
// Copyright 2025 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://openusd.org/license.
//
#ifndef HDPARTICLEFIELD_PARTICLEFIELDADAPTER_H
#define HDPARTICLEFIELD_PARTICLEFIELDADAPTER_H

#include <pxr/pxr.h>
#include <pxr/usdImaging/usdImaging/api.h>
#include <pxr/usdImaging/usdImaging/gprimAdapter.h>
#include <pxr/usdImaging/usdImaging/primAdapter.h>

PXR_NAMESPACE_OPEN_SCOPE

/// \class UsdImagingPointsAdapter
///
/// Delegate support for UsdGeomPoints.
class UsdImaging_3DGaussianSplatAdapter : public UsdImagingGprimAdapter {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here & elsewhere in this directory: I think keeping with the "ParticleField" (i.e. base class) naming is preferable, and distinguishing between variations in hydra either via prim type (have a helper on the ParticleFieldAdapter that comes up with prim type based on prim.HasAPI() or whatever, as in UsdLuxLight); or by a token "kernelType" on the prim telling hydra which kernel to use (as in UsdGeomBasisCurves). All of this to minimize code duplication where we can.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To expand on that, the class itself is nicely parameterized in terms of telling you which data you're on the hook for pulling down, meaning it's possible to write a single particle field adapter that can ingest data for any specialization, saving a bunch of LOC (much like we do for e.g. lights, shaders, sample & display filters in Renderman, etc.). Since this is the only current specialization, this isn't an urgent note.

public:
using BaseAdapter = UsdImagingGprimAdapter;

// ---------------------------------------------------------------------- //
/// \name Initialization
// ---------------------------------------------------------------------- //

SdfPath Populate(const UsdPrim& usdPrim, UsdImagingIndexProxy* index,
const UsdImagingInstancerContext* instancerContext = nullptr) override;

bool IsSupported(const UsdImagingIndexProxy* index) const override;

// ---------------------------------------------------------------------- //
/// \name Parallel Setup and Resolve
// ---------------------------------------------------------------------- //

void TrackVariability(const UsdPrim& usdPrim, const SdfPath& cachePath, HdDirtyBits* timeVaryingBits,
const UsdImagingInstancerContext* i_instancerContext = nullptr) const override;

/// Thread Safe.
void UpdateForTime(UsdPrim const& prim, SdfPath const& cachePath, UsdTimeCode time, HdDirtyBits requestedBits,
UsdImagingInstancerContext const* instancerContext = nullptr) const override;

// ---------------------------------------------------------------------- //
/// \name Change processing
// ---------------------------------------------------------------------- //

HdDirtyBits ProcessPropertyChange(const UsdPrim& usdPrim, const SdfPath& cachePath,
const TfToken& propertyName) override;

// ---------------------------------------------------------------------- //
/// \name Data access
// ---------------------------------------------------------------------- //

VtValue Get(UsdPrim const& prim, SdfPath const& cachePath, TfToken const& key, UsdTimeCode time,
VtIntArray* outIndices) const override;

UsdImaging_3DGaussianSplatAdapter() : UsdImagingGprimAdapter() {}

~UsdImaging_3DGaussianSplatAdapter() override;

// ---------------------------------------------------------------------- //
/// \name Scene Index Support
// ---------------------------------------------------------------------- //

TfTokenVector GetImagingSubprims(UsdPrim const& prim) override;

TfToken GetImagingSubprimType(UsdPrim const& prim, TfToken const& subprim) override;

HdContainerDataSourceHandle GetImagingSubprimData(UsdPrim const& prim, TfToken const& subprim,
const UsdImagingDataSourceStageGlobals& stageGlobals) override;

USDIMAGING_API
HdDataSourceLocatorSet InvalidateImagingSubprim(UsdPrim const& prim, TfToken const& subprim,
TfTokenVector const& properties,
UsdImagingPropertyInvalidationType invalidationType) override;
};

PXR_NAMESPACE_CLOSE_SCOPE

#endif // HDPARTICLEFIELD_PARTICLEFIELD_ADAPTER_H
Loading
Loading