-
Notifications
You must be signed in to change notification settings - Fork 1.4k
APPLE: Add Gaussian Splats API schema #3716
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from all commits
9f1d4d2
3326483
8e994e0
e898be2
95bb224
d36eb08
92e75bf
44cd9db
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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) |
| 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 | ||
| 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} | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
There was a problem hiding this comment.
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.