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 9aa29cb288..c0dc2c63b6 100644 --- a/Gems/WhiteBox/Code/Source/Rendering/Atom/WhiteBoxAtomRenderMesh.cpp +++ b/Gems/WhiteBox/Code/Source/Rendering/Atom/WhiteBoxAtomRenderMesh.cpp @@ -120,9 +120,7 @@ namespace WhiteBox modelLodCreator.SetMeshAabb(meshData.GetAabb()); // set the default material - auto materialAsset = - AZ::RPI::AssetUtils::LoadAssetByProductPath(TexturedMaterialPath.data()); - if (materialAsset) + if (auto materialAsset = AZ::RPI::AssetUtils::LoadAssetByProductPath(TexturedMaterialPath.data())) { modelLodCreator.SetMeshMaterialAsset(materialAsset); }