From b708bc2c1070ee6fdb18e6ec0b2e62b07e1b3311 Mon Sep 17 00:00:00 2001 From: hultonha Date: Wed, 5 May 2021 16:08:38 +0100 Subject: [PATCH 1/2] potential fix for level loading hangs with White Box Component and Atom --- .../Rendering/Atom/WhiteBoxAtomRenderMesh.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Gems/WhiteBox/Code/Source/Rendering/Atom/WhiteBoxAtomRenderMesh.cpp b/Gems/WhiteBox/Code/Source/Rendering/Atom/WhiteBoxAtomRenderMesh.cpp index 9aa29cb288..8ceb95e3a7 100644 --- a/Gems/WhiteBox/Code/Source/Rendering/Atom/WhiteBoxAtomRenderMesh.cpp +++ b/Gems/WhiteBox/Code/Source/Rendering/Atom/WhiteBoxAtomRenderMesh.cpp @@ -119,9 +119,16 @@ namespace WhiteBox modelLodCreator.BeginMesh(); modelLodCreator.SetMeshAabb(meshData.GetAabb()); - // set the default material - auto materialAsset = - AZ::RPI::AssetUtils::LoadAssetByProductPath(TexturedMaterialPath.data()); + const AZ::Data::AssetId materialAssetId = + AZ::RPI::AssetUtils::GetAssetIdForProductPath(TexturedMaterialPath.data(), AZ::RPI::AssetUtils::TraceLevel::Warning); + + auto materialAsset = AZ::Data::AssetManager::Instance().FindAsset(materialAssetId, AZ::Data::AssetLoadBehavior::Default); + if (!materialAsset) + { + // set the default material + materialAsset = AZ::RPI::AssetUtils::LoadAssetById(materialAssetId); + } + if (materialAsset) { modelLodCreator.SetMeshMaterialAsset(materialAsset); From 1d900947f55bf3397621106328447bef8d9e7664 Mon Sep 17 00:00:00 2001 From: hultonha Date: Wed, 5 May 2021 16:55:48 +0100 Subject: [PATCH 2/2] defer rebuilding the white box mesh by a frame to prevent reentrancy causing issues --- .../Source/Asset/EditorWhiteBoxMeshAsset.cpp | 16 ++++++++++++++-- .../Code/Source/Asset/EditorWhiteBoxMeshAsset.h | 5 +++++ .../Rendering/Atom/WhiteBoxAtomRenderMesh.cpp | 13 ++----------- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/Gems/WhiteBox/Code/Source/Asset/EditorWhiteBoxMeshAsset.cpp b/Gems/WhiteBox/Code/Source/Asset/EditorWhiteBoxMeshAsset.cpp index cd308aef0f..010abedae9 100644 --- a/Gems/WhiteBox/Code/Source/Asset/EditorWhiteBoxMeshAsset.cpp +++ b/Gems/WhiteBox/Code/Source/Asset/EditorWhiteBoxMeshAsset.cpp @@ -181,6 +181,9 @@ namespace WhiteBox // disconnect from any previously connected asset id AZ::Data::AssetBus::Handler::BusDisconnect(); WhiteBoxMeshAssetNotificationBus::Handler::BusDisconnect(); + + // ensure we're disconnected from the tick bus + AZ::TickBus::Handler::BusDisconnect(); } void EditorWhiteBoxMeshAsset::Release() @@ -215,11 +218,20 @@ namespace WhiteBox if (asset == m_meshAsset) { m_meshAsset = asset; - EditorWhiteBoxComponentRequestBus::Event( - m_entityComponentIdPair, &EditorWhiteBoxComponentRequestBus::Events::RebuildWhiteBox); + + // defer rebuilding the mesh by a frame by connecting to the tick bus - this prevents issues + // with reentrancy when rebuilding the white box mesh + AZ::TickBus::Handler::BusConnect(); } } + void EditorWhiteBoxMeshAsset::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time) + { + // after rebuilding the white box mesh, immediately disconnect from the tick bus (we only use it for deferred rebuilding) + EditorWhiteBoxComponentRequestBus::Event(m_entityComponentIdPair, &EditorWhiteBoxComponentRequestBus::Events::RebuildWhiteBox); + AZ::TickBus::Handler::BusDisconnect(); + } + void EditorWhiteBoxMeshAsset::OnAssetReloaded(AZ::Data::Asset asset) { OnAssetReady(asset); diff --git a/Gems/WhiteBox/Code/Source/Asset/EditorWhiteBoxMeshAsset.h b/Gems/WhiteBox/Code/Source/Asset/EditorWhiteBoxMeshAsset.h index caa56dce1a..1365e00681 100644 --- a/Gems/WhiteBox/Code/Source/Asset/EditorWhiteBoxMeshAsset.h +++ b/Gems/WhiteBox/Code/Source/Asset/EditorWhiteBoxMeshAsset.h @@ -16,6 +16,7 @@ #include "Asset/WhiteBoxMeshAssetBus.h" #include +#include #include namespace WhiteBox @@ -26,6 +27,7 @@ namespace WhiteBox : private AZ::Data::AssetBus::Handler , private WhiteBoxMeshAssetNotificationBus::Handler , private IEditorNotifyListener + , private AZ::TickBus::Handler { public: AZ_CLASS_ALLOCATOR_DECL @@ -93,6 +95,9 @@ namespace WhiteBox //! Disconnect from buses/listeners before either releasing or destroying the asset. void Disconnect(); + // AZ::TickBus overrides ... + void OnTick(float deltaTime, AZ::ScriptTimePoint time) override; + // Listeners for legacy editor events when the level is saved. void RegisterForEditorEvents(); void UnregisterForEditorEvents(); diff --git a/Gems/WhiteBox/Code/Source/Rendering/Atom/WhiteBoxAtomRenderMesh.cpp b/Gems/WhiteBox/Code/Source/Rendering/Atom/WhiteBoxAtomRenderMesh.cpp index 8ceb95e3a7..c0dc2c63b6 100644 --- a/Gems/WhiteBox/Code/Source/Rendering/Atom/WhiteBoxAtomRenderMesh.cpp +++ b/Gems/WhiteBox/Code/Source/Rendering/Atom/WhiteBoxAtomRenderMesh.cpp @@ -119,17 +119,8 @@ namespace WhiteBox modelLodCreator.BeginMesh(); modelLodCreator.SetMeshAabb(meshData.GetAabb()); - const AZ::Data::AssetId materialAssetId = - AZ::RPI::AssetUtils::GetAssetIdForProductPath(TexturedMaterialPath.data(), AZ::RPI::AssetUtils::TraceLevel::Warning); - - auto materialAsset = AZ::Data::AssetManager::Instance().FindAsset(materialAssetId, AZ::Data::AssetLoadBehavior::Default); - if (!materialAsset) - { - // set the default material - materialAsset = AZ::RPI::AssetUtils::LoadAssetById(materialAssetId); - } - - if (materialAsset) + // set the default material + if (auto materialAsset = AZ::RPI::AssetUtils::LoadAssetByProductPath(TexturedMaterialPath.data())) { modelLodCreator.SetMeshMaterialAsset(materialAsset); }