diff --git a/CHANGES.md b/CHANGES.md index 69432fa3..e9019add 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,7 @@ * Fixed zooming to tileset extents when tileset prims have non identity transformation. * Fixed crash when updating tilesets shader inputs. * Fixed crash when setting certain `/Cesium` debug options at runtime. +* Fixed crash when disabling and re-enabling the extension. ### v0.17.0 - 2024-02-01 diff --git a/src/core/include/cesium/omniverse/Context.h b/src/core/include/cesium/omniverse/Context.h index 23ac9bc5..4ade5328 100644 --- a/src/core/include/cesium/omniverse/Context.h +++ b/src/core/include/cesium/omniverse/Context.h @@ -71,6 +71,8 @@ class Context { [[nodiscard]] RenderStatistics getRenderStatistics() const; + [[nodiscard]] int64_t getContextId() const; + private: std::filesystem::path _cesiumExtensionLocation; std::filesystem::path _certificatePath; @@ -86,6 +88,8 @@ class Context { std::unique_ptr _pCesiumIonServerManager; std::unique_ptr _pUsdNotificationHandler; + int64_t _contextId; + pxr::UsdStageWeakPtr _pUsdStage; std::unique_ptr _pFabricStage; int64_t _usdStageId{0}; diff --git a/src/core/src/Context.cpp b/src/core/src/Context.cpp index 2375380d..88812132 100644 --- a/src/core/src/Context.cpp +++ b/src/core/src/Context.cpp @@ -27,12 +27,17 @@ #include #include -#if CESIUM_TRACING_ENABLED #include -#endif namespace cesium::omniverse { +namespace { +uint64_t getSecondsSinceEpoch() { + const auto timePoint = std::chrono::system_clock::now(); + return std::chrono::duration_cast(timePoint.time_since_epoch()).count(); +} +} // namespace + Context::Context(const std::filesystem::path& cesiumExtensionLocation) : _cesiumExtensionLocation(cesiumExtensionLocation.lexically_normal()) , _certificatePath(_cesiumExtensionLocation / "certs" / "cacert.pem") @@ -45,7 +50,8 @@ Context::Context(const std::filesystem::path& cesiumExtensionLocation) , _pAssetRegistry(std::make_unique(this)) , _pFabricResourceManager(std::make_unique(this)) , _pCesiumIonServerManager(std::make_unique(this)) - , _pUsdNotificationHandler(std::make_unique(this)) { + , _pUsdNotificationHandler(std::make_unique(this)) + , _contextId(static_cast(getSecondsSinceEpoch())) { Cesium3DTilesContent::registerAllTileContentTypes(); @@ -236,4 +242,10 @@ RenderStatistics Context::getRenderStatistics() const { return renderStatistics; } +int64_t Context::getContextId() const { + // Creating a Fabric prim with the same path as a previously destroyed prim causes a crash. + // The contextId is randomly generated and ensures that Fabric prim paths are unique even across extension reloads. + return _contextId; +} + } // namespace cesium::omniverse diff --git a/src/core/src/FabricGeometryPool.cpp b/src/core/src/FabricGeometryPool.cpp index 234d8997..2c58f9d1 100644 --- a/src/core/src/FabricGeometryPool.cpp +++ b/src/core/src/FabricGeometryPool.cpp @@ -1,5 +1,6 @@ #include "cesium/omniverse/FabricGeometryPool.h" +#include "cesium/omniverse/Context.h" #include "cesium/omniverse/FabricVertexAttributeDescriptor.h" #include "cesium/omniverse/GltfUtil.h" @@ -28,7 +29,8 @@ int64_t FabricGeometryPool::getPoolId() const { } std::shared_ptr FabricGeometryPool::createObject(uint64_t objectId) const { - const auto pathStr = fmt::format("/cesium_geometry_pool_{}_object_{}", _poolId, objectId); + const auto contextId = _pContext->getContextId(); + const auto pathStr = fmt::format("/cesium_geometry_pool_{}_object_{}_context_{}", _poolId, objectId, contextId); const auto path = omni::fabric::Path(pathStr.c_str()); return std::make_shared(_pContext, path, _geometryDescriptor, _poolId); } diff --git a/src/core/src/FabricMaterialPool.cpp b/src/core/src/FabricMaterialPool.cpp index 4e8547e2..efcc2573 100644 --- a/src/core/src/FabricMaterialPool.cpp +++ b/src/core/src/FabricMaterialPool.cpp @@ -42,7 +42,8 @@ void FabricMaterialPool::updateShaderInput(const pxr::SdfPath& shaderPath, const } std::shared_ptr FabricMaterialPool::createObject(uint64_t objectId) const { - const auto pathStr = fmt::format("/cesium_material_pool_{}_object_{}", _poolId, objectId); + const auto contextId = _pContext->getContextId(); + const auto pathStr = fmt::format("/cesium_material_pool_{}_object_{}_context_{}", _poolId, objectId, contextId); const auto path = omni::fabric::Path(pathStr.c_str()); return std::make_shared( _pContext, diff --git a/src/core/src/FabricResourceManager.cpp b/src/core/src/FabricResourceManager.cpp index 9f97d6b1..93b3b47c 100644 --- a/src/core/src/FabricResourceManager.cpp +++ b/src/core/src/FabricResourceManager.cpp @@ -23,8 +23,8 @@ namespace cesium::omniverse { namespace { -const std::string_view DEFAULT_WHITE_TEXTURE_NAME = "fabric_default_white_texture"; -const std::string_view DEFAULT_TRANSPARENT_TEXTURE_NAME = "fabric_default_transparent_texture"; +const std::string_view DEFAULT_WHITE_TEXTURE_NAME = "cesium_default_white_texture"; +const std::string_view DEFAULT_TRANSPARENT_TEXTURE_NAME = "cesium_default_transparent_texture"; std::unique_ptr createSinglePixelTexture(const std::string_view& name, const std::array& bytes) { @@ -86,7 +86,8 @@ std::shared_ptr FabricResourceManager::acquireGeometry( FabricGeometryDescriptor geometryDescriptor(model, primitive, featuresInfo, smoothNormals); if (_disableGeometryPool) { - const auto pathStr = fmt::format("/cesium_geometry_{}", getNextGeometryId()); + const auto contextId = _pContext->getContextId(); + const auto pathStr = fmt::format("/cesium_geometry_{}_context_{}", getNextGeometryId(), contextId); const auto path = omni::fabric::Path(pathStr.c_str()); return std::make_shared(_pContext, path, geometryDescriptor, -1); } @@ -122,7 +123,8 @@ std::shared_ptr FabricResourceManager::acquireMaterial( std::shared_ptr FabricResourceManager::acquireTexture() { if (_disableTexturePool) { - const auto name = fmt::format("/cesium_texture_{}", getNextTextureId()); + const auto contextId = _pContext->getContextId(); + const auto name = fmt::format("/cesium_texture_{}_context_{}", getNextTextureId(), contextId); return std::make_shared(_pContext, name, -1); } @@ -241,7 +243,8 @@ void FabricResourceManager::clear() { std::shared_ptr FabricResourceManager::createMaterial(const FabricMaterialDescriptor& materialDescriptor) { - const auto pathStr = fmt::format("/cesium_material_{}", getNextMaterialId()); + const auto contextId = _pContext->getContextId(); + const auto pathStr = fmt::format("/cesium_material_{}_context_{}", getNextMaterialId(), contextId); const auto path = omni::fabric::Path(pathStr.c_str()); return std::make_shared( _pContext, diff --git a/src/core/src/FabricTexturePool.cpp b/src/core/src/FabricTexturePool.cpp index 6fd082c5..655ad950 100644 --- a/src/core/src/FabricTexturePool.cpp +++ b/src/core/src/FabricTexturePool.cpp @@ -1,5 +1,7 @@ #include "cesium/omniverse/FabricTexturePool.h" +#include "cesium/omniverse/Context.h" + #include namespace cesium::omniverse { @@ -16,7 +18,8 @@ int64_t FabricTexturePool::getPoolId() const { } std::shared_ptr FabricTexturePool::createObject(uint64_t objectId) const { - const auto name = fmt::format("/cesium_texture_pool_{}_object_{}", _poolId, objectId); + const auto contextId = _pContext->getContextId(); + const auto name = fmt::format("/cesium_texture_pool_{}_object_{}_context_{}", _poolId, objectId, contextId); return std::make_shared(_pContext, name, _poolId); }