From 9930cc8fd892ca4843556dee29662191824048bd Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Wed, 12 Jul 2023 11:47:28 -0400 Subject: [PATCH] Add support for tileset materials --- .../usd/plugins/CesiumUsdSchemas/__init__.pyi | 2 +- .../schemas/cesium_schemas.usda | 2 +- .../cesium/omniverse/FabricResourceManager.h | 5 ++- .../include/cesium/omniverse/OmniTileset.h | 1 + src/core/src/Context.cpp | 4 +- src/core/src/FabricPrepareRenderResources.cpp | 24 +++++++---- src/core/src/FabricResourceManager.cpp | 9 ++++- src/core/src/OmniTileset.cpp | 11 +++++ .../CesiumUsdSchemas/generatedSchema.usda.in | 40 +++++++++++++++++++ src/plugins/CesiumUsdSchemas/plugInfo.json.in | 2 +- .../src/CesiumUsdSchemas/tileset.cpp | 4 +- .../src/CesiumUsdSchemas/tileset.h | 8 ++-- .../src/CesiumUsdSchemas/wrapTileset.cpp | 2 +- 13 files changed, 93 insertions(+), 21 deletions(-) diff --git a/exts/cesium.usd.plugins/cesium/usd/plugins/CesiumUsdSchemas/__init__.pyi b/exts/cesium.usd.plugins/cesium/usd/plugins/CesiumUsdSchemas/__init__.pyi index 0ebd14b2b..9c5011c1b 100644 --- a/exts/cesium.usd.plugins/cesium/usd/plugins/CesiumUsdSchemas/__init__.pyi +++ b/exts/cesium.usd.plugins/cesium/usd/plugins/CesiumUsdSchemas/__init__.pyi @@ -146,7 +146,7 @@ class Session(pxr.Usd.Typed): @classmethod def __reduce__(cls) -> Any: ... -class Tileset(pxr.UsdGeom.Boundable): +class Tileset(pxr.UsdGeom.Gprim): __instance_size__: ClassVar[int] = ... @classmethod def __init__(cls, *args, **kwargs) -> None: ... diff --git a/exts/cesium.usd.plugins/schemas/cesium_schemas.usda b/exts/cesium.usd.plugins/schemas/cesium_schemas.usda index f21199ea4..1edf8e2f5 100644 --- a/exts/cesium.usd.plugins/schemas/cesium_schemas.usda +++ b/exts/cesium.usd.plugins/schemas/cesium_schemas.usda @@ -165,7 +165,7 @@ class CesiumGeoreferencePrim "CesiumGeoreferencePrim" ( class CesiumTilesetPrim "CesiumTilesetPrim" ( doc = """A prim representing a tileset.""" - inherits = + inherits = customData = { string className = "Tileset" diff --git a/src/core/include/cesium/omniverse/FabricResourceManager.h b/src/core/include/cesium/omniverse/FabricResourceManager.h index 639f4f0c9..3ab2f4e67 100644 --- a/src/core/include/cesium/omniverse/FabricResourceManager.h +++ b/src/core/include/cesium/omniverse/FabricResourceManager.h @@ -41,7 +41,10 @@ class FabricResourceManager { return instance; } - bool shouldAcquireMaterial(const CesiumGltf::MeshPrimitive& primitive, bool hasImagery) const; + bool shouldAcquireMaterial( + const CesiumGltf::MeshPrimitive& primitive, + bool hasImagery, + const pxr::SdfPath& materialPath) const; std::shared_ptr acquireGeometry(const CesiumGltf::Model& model, const CesiumGltf::MeshPrimitive& primitive, bool smoothNormals); diff --git a/src/core/include/cesium/omniverse/OmniTileset.h b/src/core/include/cesium/omniverse/OmniTileset.h index 61ab08d50..fc0af9ab9 100644 --- a/src/core/include/cesium/omniverse/OmniTileset.h +++ b/src/core/include/cesium/omniverse/OmniTileset.h @@ -65,6 +65,7 @@ class OmniTileset { [[nodiscard]] float getMainThreadLoadingTimeLimit() const; [[nodiscard]] bool getShowCreditsOnScreen() const; [[nodiscard]] pxr::CesiumGeoreference getGeoreference() const; + [[nodiscard]] pxr::SdfPath getMaterialPath() const; [[nodiscard]] int64_t getTilesetId() const; [[nodiscard]] TilesetStatistics getStatistics() const; diff --git a/src/core/src/Context.cpp b/src/core/src/Context.cpp index 28304e5fb..291fe78a8 100644 --- a/src/core/src/Context.cpp +++ b/src/core/src/Context.cpp @@ -11,6 +11,7 @@ #include "cesium/omniverse/OmniImagery.h" #include "cesium/omniverse/OmniTileset.h" #include "cesium/omniverse/TaskProcessor.h" +#include "cesium/omniverse/Tokens.h" #include "cesium/omniverse/UsdUtil.h" #ifdef CESIUM_OMNI_MSVC @@ -317,7 +318,8 @@ void Context::processCesiumTilesetChanged(const ChangedPrim& changedPrim) { name == pxr::CesiumTokens->cesiumCulledScreenSpaceError || name == pxr::CesiumTokens->cesiumSmoothNormals || name == pxr::CesiumTokens->cesiumMainThreadLoadingTimeLimit || - name == pxr::CesiumTokens->cesiumShowCreditsOnScreen) { + name == pxr::CesiumTokens->cesiumShowCreditsOnScreen || + name == UsdTokens::material_binding) { tileset.value()->reload(); } // clang-format on diff --git a/src/core/src/FabricPrepareRenderResources.cpp b/src/core/src/FabricPrepareRenderResources.cpp index 0bbfcf8c9..b37a58761 100644 --- a/src/core/src/FabricPrepareRenderResources.cpp +++ b/src/core/src/FabricPrepareRenderResources.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include namespace cesium::omniverse { @@ -93,8 +94,11 @@ gatherMeshes(const OmniTileset& tileset, const glm::dmat4& tileTransform, const return meshes; } -std::vector -acquireFabricMeshes(const CesiumGltf::Model& model, const std::vector& meshes, bool hasImagery) { +std::vector acquireFabricMeshes( + const CesiumGltf::Model& model, + const std::vector& meshes, + bool hasImagery, + const OmniTileset& tileset) { CESIUM_TRACE("FabricPrepareRenderResources::acquireFabricMeshes"); std::vector fabricMeshes; fabricMeshes.reserve(meshes.size()); @@ -108,8 +112,8 @@ acquireFabricMeshes(const CesiumGltf::Model& model, const std::vector& const auto fabricGeometry = fabricResourceManager.acquireGeometry(model, primitive, mesh.smoothNormals); fabricMesh.geometry = fabricGeometry; - const auto shouldAcquireMaterial = - FabricResourceManager::getInstance().shouldAcquireMaterial(primitive, hasImagery); + const auto shouldAcquireMaterial = FabricResourceManager::getInstance().shouldAcquireMaterial( + primitive, hasImagery, tileset.getMaterialPath()); if (shouldAcquireMaterial) { const auto materialInfo = GltfUtil::getMaterialInfo(model, primitive); @@ -151,11 +155,13 @@ void setFabricMeshes( const CesiumGltf::Model& model, const std::vector& meshes, std::vector& fabricMeshes, - bool hasImagery) { + bool hasImagery, + const OmniTileset& tileset) { CESIUM_TRACE("FabricPrepareRenderResources::setFabricMeshes"); for (size_t i = 0; i < meshes.size(); i++) { const auto& meshInfo = meshes[i]; const auto& primitive = model.meshes[meshInfo.meshId].primitives[meshInfo.primitiveId]; + const auto& materialPath = tileset.getMaterialPath(); auto& mesh = fabricMeshes[i]; auto& geometry = mesh.geometry; @@ -180,6 +186,8 @@ void setFabricMeshes( if (baseColorTexture != nullptr && materialInfo.baseColorTexture.has_value()) { material->setBaseColorTexture(baseColorTexture, materialInfo.baseColorTexture.value()); } + } else if (!materialPath.IsEmpty()) { + geometry->setMaterial(omni::fabric::Path(omni::fabric::asInt(materialPath))); } } } @@ -213,9 +221,9 @@ FabricPrepareRenderResources::prepareInLoadThread( return asyncSystem .runInMainThread( - [hasImagery, meshes = std::move(meshes), tileLoadResult = std::move(tileLoadResult)]() mutable { + [this, hasImagery, meshes = std::move(meshes), tileLoadResult = std::move(tileLoadResult)]() mutable { const auto pModel = std::get_if(&tileLoadResult.contentKind); - auto fabricMeshes = acquireFabricMeshes(*pModel, meshes, hasImagery); + auto fabricMeshes = acquireFabricMeshes(*pModel, meshes, hasImagery, _tileset); return IntermediateLoadThreadResult{ std::move(tileLoadResult), std::move(meshes), @@ -261,7 +269,7 @@ void* FabricPrepareRenderResources::prepareInMainThread(Cesium3DTilesSelection:: const auto& model = pRenderContent->getModel(); - setFabricMeshes(model, meshes, fabricMeshes, hasImagery); + setFabricMeshes(model, meshes, fabricMeshes, hasImagery, _tileset); return new TileRenderResources{ tileTransform, diff --git a/src/core/src/FabricResourceManager.cpp b/src/core/src/FabricResourceManager.cpp index eaf96c6e4..38e67a2ea 100644 --- a/src/core/src/FabricResourceManager.cpp +++ b/src/core/src/FabricResourceManager.cpp @@ -28,11 +28,18 @@ FabricResourceManager::FabricResourceManager() { FabricResourceManager::~FabricResourceManager() = default; -bool FabricResourceManager::shouldAcquireMaterial(const CesiumGltf::MeshPrimitive& primitive, bool hasImagery) const { +bool FabricResourceManager::shouldAcquireMaterial( + const CesiumGltf::MeshPrimitive& primitive, + bool hasImagery, + const pxr::SdfPath& materialPath) const { if (_disableMaterials) { return false; } + if (!materialPath.IsEmpty()) { + return false; + } + return hasImagery || GltfUtil::hasMaterial(primitive); } diff --git a/src/core/src/OmniTileset.cpp b/src/core/src/OmniTileset.cpp index 46d85b5ec..511eba8d4 100644 --- a/src/core/src/OmniTileset.cpp +++ b/src/core/src/OmniTileset.cpp @@ -27,6 +27,7 @@ #include #include #include +#include namespace cesium::omniverse { @@ -243,6 +244,16 @@ pxr::CesiumGeoreference OmniTileset::getGeoreference() const { return UsdUtil::getCesiumGeoreference(georeferencePath); } +pxr::SdfPath OmniTileset::getMaterialPath() const { + auto tileset = UsdUtil::getCesiumTileset(_tilesetPath); + + const auto materialBindingApi = pxr::UsdShadeMaterialBindingAPI(tileset); + const auto materialBinding = materialBindingApi.GetDirectBinding(); + const auto& materialPath = materialBinding.GetMaterialPath(); + + return materialPath; +} + int64_t OmniTileset::getTilesetId() const { return _tilesetId; } diff --git a/src/plugins/CesiumUsdSchemas/generatedSchema.usda.in b/src/plugins/CesiumUsdSchemas/generatedSchema.usda.in index be7693b89..9ec24b093 100644 --- a/src/plugins/CesiumUsdSchemas/generatedSchema.usda.in +++ b/src/plugins/CesiumUsdSchemas/generatedSchema.usda.in @@ -166,6 +166,25 @@ class CesiumTilesetPrim "CesiumTilesetPrim" ( displayName = "URL" doc = "The URL of this tileset's tileset.json file. Usually blank if this is an ion asset." ) + uniform bool doubleSided = 0 ( + doc = """Although some renderers treat all parametric or polygonal + surfaces as if they were effectively laminae with outward-facing + normals on both sides, some renderers derive significant optimizations + by considering these surfaces to have only a single outward side, + typically determined by control-point winding order and/or + orientation. By doing so they can perform \"backface culling\" to + avoid drawing the many polygons of most closed surfaces that face away + from the viewer. + + However, it is often advantageous to model thin objects such as paper + and cloth as single, open surfaces that must be viewable from both + sides, always. Setting a gprim's doubleSided attribute to + \\c true instructs all renderers to disable optimizations such as + backface culling for the gprim, and attempt (not all renderers are able + to do so, but the USD reference GL renderer always will) to provide + forward-facing normals on each side of the surface for lighting + calculations.""" + ) float3[] extent ( doc = """Extent is a three dimensional range measuring the geometric extent of the authored gprim in its own local space (i.e. its own @@ -184,6 +203,27 @@ class CesiumTilesetPrim "CesiumTilesetPrim" ( the extent of all children, as they will be pruned from BBox computation during traversal.""" ) + uniform token orientation = "rightHanded" ( + allowedTokens = ["rightHanded", "leftHanded"] + doc = """Orientation specifies whether the gprim's surface normal + should be computed using the right hand rule, or the left hand rule. + Please see for a deeper explanation and + generalization of orientation to composed scenes with transformation + hierarchies.""" + ) + color3f[] primvars:displayColor ( + doc = '''It is useful to have an "official" colorSet that can be used + as a display or modeling color, even in the absence of any specified + shader for a gprim. DisplayColor serves this role; because it is a + UsdGeomPrimvar, it can also be used as a gprim override for any shader + that consumes a displayColor parameter.''' + ) + float[] primvars:displayOpacity ( + doc = """Companion to displayColor that specifies opacity, broken + out as an independent attribute rather than an rgba color, both so that + each can be independently overridden, and because shaders rarely consume + rgba parameters.""" + ) rel proxyPrim ( doc = '''The proxyPrim relationship allows us to link a prim whose purpose is "render" to its (single target) diff --git a/src/plugins/CesiumUsdSchemas/plugInfo.json.in b/src/plugins/CesiumUsdSchemas/plugInfo.json.in index cb824e536..4f0df0d06 100644 --- a/src/plugins/CesiumUsdSchemas/plugInfo.json.in +++ b/src/plugins/CesiumUsdSchemas/plugInfo.json.in @@ -52,7 +52,7 @@ }, "autoGenerated": true, "bases": [ - "UsdGeomBoundable" + "UsdGeomGprim" ], "schemaKind": "concreteTyped" } diff --git a/src/plugins/CesiumUsdSchemas/src/CesiumUsdSchemas/tileset.cpp b/src/plugins/CesiumUsdSchemas/src/CesiumUsdSchemas/tileset.cpp index 18c3b6fb9..57718bcdc 100644 --- a/src/plugins/CesiumUsdSchemas/src/CesiumUsdSchemas/tileset.cpp +++ b/src/plugins/CesiumUsdSchemas/src/CesiumUsdSchemas/tileset.cpp @@ -11,7 +11,7 @@ PXR_NAMESPACE_OPEN_SCOPE TF_REGISTRY_FUNCTION(TfType) { TfType::Define >(); + TfType::Bases< UsdGeomGprim > >(); // Register the usd prim typename as an alias under UsdSchemaBase. This // enables one to call @@ -455,7 +455,7 @@ CesiumTileset::GetSchemaAttributeNames(bool includeInherited) }; static TfTokenVector allNames = _ConcatenateAttributeNames( - UsdGeomBoundable::GetSchemaAttributeNames(true), + UsdGeomGprim::GetSchemaAttributeNames(true), localNames); if (includeInherited) diff --git a/src/plugins/CesiumUsdSchemas/src/CesiumUsdSchemas/tileset.h b/src/plugins/CesiumUsdSchemas/src/CesiumUsdSchemas/tileset.h index d79e7f069..d4851bdee 100644 --- a/src/plugins/CesiumUsdSchemas/src/CesiumUsdSchemas/tileset.h +++ b/src/plugins/CesiumUsdSchemas/src/CesiumUsdSchemas/tileset.h @@ -5,7 +5,7 @@ #include "pxr/pxr.h" #include ".//api.h" -#include "pxr/usd/usdGeom/boundable.h" +#include "pxr/usd/usdGeom/gprim.h" #include "pxr/usd/usd/prim.h" #include "pxr/usd/usd/stage.h" #include ".//tokens.h" @@ -36,7 +36,7 @@ class SdfAssetPath; /// So to set an attribute to the value "rightHanded", use CesiumTokens->rightHanded /// as the value. /// -class CesiumTileset : public UsdGeomBoundable +class CesiumTileset : public UsdGeomGprim { public: /// Compile time constant representing what kind of schema this class is. @@ -49,7 +49,7 @@ class CesiumTileset : public UsdGeomBoundable /// for a \em valid \p prim, but will not immediately throw an error for /// an invalid \p prim explicit CesiumTileset(const UsdPrim& prim=UsdPrim()) - : UsdGeomBoundable(prim) + : UsdGeomGprim(prim) { } @@ -57,7 +57,7 @@ class CesiumTileset : public UsdGeomBoundable /// Should be preferred over CesiumTileset(schemaObj.GetPrim()), /// as it preserves SchemaBase state. explicit CesiumTileset(const UsdSchemaBase& schemaObj) - : UsdGeomBoundable(schemaObj) + : UsdGeomGprim(schemaObj) { } diff --git a/src/plugins/CesiumUsdSchemas/src/CesiumUsdSchemas/wrapTileset.cpp b/src/plugins/CesiumUsdSchemas/src/CesiumUsdSchemas/wrapTileset.cpp index b8c31fc9d..8ce680fd5 100644 --- a/src/plugins/CesiumUsdSchemas/src/CesiumUsdSchemas/wrapTileset.cpp +++ b/src/plugins/CesiumUsdSchemas/src/CesiumUsdSchemas/wrapTileset.cpp @@ -174,7 +174,7 @@ void wrapCesiumTileset() { typedef CesiumTileset This; - class_ > + class_ > cls("Tileset"); cls