diff --git a/src/core/include/cesium/omniverse/FabricGeometry.h b/src/core/include/cesium/omniverse/FabricGeometry.h index 4722b244c..cd3ea2eac 100644 --- a/src/core/include/cesium/omniverse/FabricGeometry.h +++ b/src/core/include/cesium/omniverse/FabricGeometry.h @@ -39,7 +39,7 @@ class FabricGeometry { [[nodiscard]] omni::fabric::Path getPathFabric() const; [[nodiscard]] const FabricGeometryDefinition& getGeometryDefinition() const; - void setMaterial(const std::shared_ptr& material); + void setMaterial(const omni::fabric::Path& materialPath); private: void initialize(); diff --git a/src/core/include/cesium/omniverse/FabricGeometryDefinition.h b/src/core/include/cesium/omniverse/FabricGeometryDefinition.h index d788614c9..26bd43eac 100644 --- a/src/core/include/cesium/omniverse/FabricGeometryDefinition.h +++ b/src/core/include/cesium/omniverse/FabricGeometryDefinition.h @@ -14,11 +14,8 @@ class FabricGeometryDefinition { FabricGeometryDefinition( const CesiumGltf::Model& model, const CesiumGltf::MeshPrimitive& primitive, - bool smoothNormals, - bool hasImagery, - bool disableMaterials); + bool smoothNormals); - [[nodiscard]] bool hasMaterial() const; [[nodiscard]] bool hasTexcoords() const; [[nodiscard]] bool hasNormals() const; [[nodiscard]] bool hasVertexColors() const; @@ -27,7 +24,6 @@ class FabricGeometryDefinition { bool operator==(const FabricGeometryDefinition& other) const; private: - bool _hasMaterial{false}; bool _hasTexcoords{false}; bool _hasNormals{false}; bool _hasVertexColors{false}; diff --git a/src/core/include/cesium/omniverse/FabricResourceManager.h b/src/core/include/cesium/omniverse/FabricResourceManager.h index ec5c5f265..3ab2f4e67 100644 --- a/src/core/include/cesium/omniverse/FabricResourceManager.h +++ b/src/core/include/cesium/omniverse/FabricResourceManager.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -40,11 +41,13 @@ class FabricResourceManager { return instance; } - std::shared_ptr acquireGeometry( - const CesiumGltf::Model& model, + bool shouldAcquireMaterial( const CesiumGltf::MeshPrimitive& primitive, - bool smoothNormals, - bool hasImagery); + bool hasImagery, + const pxr::SdfPath& materialPath) const; + + std::shared_ptr + acquireGeometry(const CesiumGltf::Model& model, const CesiumGltf::MeshPrimitive& primitive, bool smoothNormals); std::shared_ptr acquireMaterial(const MaterialInfo& materialInfo, bool hasImagery); 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 eaa657ce9..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 @@ -203,16 +204,16 @@ void Context::clearStage() { void Context::reloadStage() { clearStage(); - auto& FabricResourceManager = FabricResourceManager::getInstance(); - FabricResourceManager.setDisableMaterials(getDebugDisableMaterials()); - FabricResourceManager.setDisableTextures(getDebugDisableTextures()); - FabricResourceManager.setDisableGeometryPool(getDebugDisableGeometryPool()); - FabricResourceManager.setDisableMaterialPool(getDebugDisableMaterialPool()); - FabricResourceManager.setDisableTexturePool(getDebugDisableTexturePool()); - FabricResourceManager.setGeometryPoolInitialCapacity(getDebugGeometryPoolInitialCapacity()); - FabricResourceManager.setMaterialPoolInitialCapacity(getDebugMaterialPoolInitialCapacity()); - FabricResourceManager.setTexturePoolInitialCapacity(getDebugTexturePoolInitialCapacity()); - FabricResourceManager.setDebugRandomColors(getDebugRandomColors()); + auto& fabricResourceManager = FabricResourceManager::getInstance(); + fabricResourceManager.setDisableMaterials(getDebugDisableMaterials()); + fabricResourceManager.setDisableTextures(getDebugDisableTextures()); + fabricResourceManager.setDisableGeometryPool(getDebugDisableGeometryPool()); + fabricResourceManager.setDisableMaterialPool(getDebugDisableMaterialPool()); + fabricResourceManager.setDisableTexturePool(getDebugDisableTexturePool()); + fabricResourceManager.setGeometryPoolInitialCapacity(getDebugGeometryPoolInitialCapacity()); + fabricResourceManager.setMaterialPoolInitialCapacity(getDebugMaterialPoolInitialCapacity()); + fabricResourceManager.setTexturePoolInitialCapacity(getDebugTexturePoolInitialCapacity()); + fabricResourceManager.setDebugRandomColors(getDebugRandomColors()); // Repopulate the asset registry. We need to do this manually because USD doesn't notify us about // resynced paths when the stage is loaded. @@ -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/FabricGeometry.cpp b/src/core/src/FabricGeometry.cpp index 102954939..39a864eea 100644 --- a/src/core/src/FabricGeometry.cpp +++ b/src/core/src/FabricGeometry.cpp @@ -67,11 +67,11 @@ const FabricGeometryDefinition& FabricGeometry::getGeometryDefinition() const { return _geometryDefinition; } -void FabricGeometry::setMaterial(const std::shared_ptr& material) { +void FabricGeometry::setMaterial(const omni::fabric::Path& materialPath) { auto srw = UsdUtil::getFabricStageReaderWriter(); srw.setArrayAttributeSize(_pathFabric, FabricTokens::material_binding, 1); auto materialBindingFabric = srw.getArrayAttributeWr(_pathFabric, FabricTokens::material_binding); - materialBindingFabric[0] = omni::fabric::PathC(material->getPathFabric()).path; + materialBindingFabric[0] = omni::fabric::PathC(materialPath).path; } void FabricGeometry::initialize() { diff --git a/src/core/src/FabricGeometryDefinition.cpp b/src/core/src/FabricGeometryDefinition.cpp index 9ff81def5..998ff0683 100644 --- a/src/core/src/FabricGeometryDefinition.cpp +++ b/src/core/src/FabricGeometryDefinition.cpp @@ -14,27 +14,19 @@ namespace cesium::omniverse { FabricGeometryDefinition::FabricGeometryDefinition( const CesiumGltf::Model& model, const CesiumGltf::MeshPrimitive& primitive, - bool smoothNormals, - bool hasImagery, - bool disableMaterials) { + bool smoothNormals) { - const auto hasMaterial = GltfUtil::hasMaterial(primitive); const auto hasPrimitiveSt = GltfUtil::hasTexcoords(model, primitive, 0); const auto hasImagerySt = GltfUtil::hasImageryTexcoords(model, primitive, 0); const auto materialInfo = GltfUtil::getMaterialInfo(model, primitive); - _hasMaterial = (hasMaterial || hasImagery) && !disableMaterials; _hasTexcoords = hasPrimitiveSt || hasImagerySt; _hasNormals = GltfUtil::hasNormals(model, primitive, smoothNormals); _hasVertexColors = GltfUtil::hasVertexColors(model, primitive, 0); _doubleSided = materialInfo.doubleSided; } -bool FabricGeometryDefinition::hasMaterial() const { - return _hasMaterial; -} - bool FabricGeometryDefinition::hasTexcoords() const { return _hasTexcoords; } @@ -52,10 +44,6 @@ bool FabricGeometryDefinition::getDoubleSided() const { } bool FabricGeometryDefinition::operator==(const FabricGeometryDefinition& other) const { - if (_hasMaterial != other._hasMaterial) { - return false; - } - if (_hasTexcoords != other._hasTexcoords) { return false; } diff --git a/src/core/src/FabricPrepareRenderResources.cpp b/src/core/src/FabricPrepareRenderResources.cpp index 428659119..aeac579a2 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,33 +94,38 @@ 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()); - auto& FabricResourceManager = FabricResourceManager::getInstance(); + auto& fabricResourceManager = FabricResourceManager::getInstance(); for (const auto& mesh : meshes) { auto& fabricMesh = fabricMeshes.emplace_back(); const auto& primitive = model.meshes[mesh.meshId].primitives[mesh.primitiveId]; - const auto fabricGeometry = - FabricResourceManager.acquireGeometry(model, primitive, mesh.smoothNormals, hasImagery); + const auto smoothNormals = mesh.smoothNormals; + const auto fabricGeometry = fabricResourceManager.acquireGeometry(model, primitive, smoothNormals); fabricMesh.geometry = fabricGeometry; - if (fabricGeometry->getGeometryDefinition().hasMaterial()) { + const auto shouldAcquireMaterial = FabricResourceManager::getInstance().shouldAcquireMaterial( + primitive, hasImagery, tileset.getMaterialPath()); + + if (shouldAcquireMaterial) { const auto materialInfo = GltfUtil::getMaterialInfo(model, primitive); - const auto fabricMaterial = FabricResourceManager.acquireMaterial(materialInfo, hasImagery); + const auto fabricMaterial = fabricResourceManager.acquireMaterial(materialInfo, hasImagery); fabricMesh.material = fabricMaterial; fabricMesh.materialInfo = materialInfo; - if (fabricMaterial->getMaterialDefinition().hasBaseColorTexture() && - materialInfo.baseColorTexture.has_value()) { - const auto fabricTexture = FabricResourceManager.acquireTexture(); + if (fabricMaterial->getMaterialDefinition().hasBaseColorTexture()) { + const auto fabricTexture = fabricResourceManager.acquireTexture(); fabricMesh.baseColorTexture = fabricTexture; } } @@ -150,11 +156,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; @@ -174,11 +182,13 @@ void setFabricMeshes( if (material != nullptr) { material->setMaterial(meshInfo.tilesetId, materialInfo); - geometry->setMaterial(material); + geometry->setMaterial(material->getPathFabric()); 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))); } } } @@ -212,9 +222,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), @@ -260,7 +270,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, @@ -279,7 +289,7 @@ void FabricPrepareRenderResources::free( if (pMainThreadResult) { const auto pTileRenderResources = reinterpret_cast(pMainThreadResult); - auto& FabricResourceManager = FabricResourceManager::getInstance(); + auto& fabricResourceManager = FabricResourceManager::getInstance(); for (const auto& mesh : pTileRenderResources->fabricMeshes) { auto& geometry = mesh.geometry; @@ -288,14 +298,14 @@ void FabricPrepareRenderResources::free( assert(geometry != nullptr); - FabricResourceManager.releaseGeometry(geometry); + fabricResourceManager.releaseGeometry(geometry); if (material != nullptr) { - FabricResourceManager.releaseMaterial(material); + fabricResourceManager.releaseMaterial(material); } if (baseColorTexture != nullptr) { - FabricResourceManager.releaseTexture(baseColorTexture); + fabricResourceManager.releaseTexture(baseColorTexture); } } diff --git a/src/core/src/FabricResourceManager.cpp b/src/core/src/FabricResourceManager.cpp index 9503eadee..38e67a2ea 100644 --- a/src/core/src/FabricResourceManager.cpp +++ b/src/core/src/FabricResourceManager.cpp @@ -28,13 +28,27 @@ FabricResourceManager::FabricResourceManager() { FabricResourceManager::~FabricResourceManager() = default; +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); +} + std::shared_ptr FabricResourceManager::acquireGeometry( const CesiumGltf::Model& model, const CesiumGltf::MeshPrimitive& primitive, - bool smoothNormals, - bool hasImagery) { + bool smoothNormals) { - FabricGeometryDefinition geometryDefinition(model, primitive, smoothNormals, hasImagery, _disableMaterials); + FabricGeometryDefinition geometryDefinition(model, primitive, smoothNormals); if (_disableGeometryPool) { const auto path = pxr::SdfPath(fmt::format("/fabric_geometry_{}", getNextGeometryId())); 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; }