From 274669a1b43ec2ff79479db729161ae62518cded Mon Sep 17 00:00:00 2001 From: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> Date: Wed, 7 Jul 2021 16:05:38 -0500 Subject: [PATCH] Fixed Vegetation Debugger to work with Atom rendering and AZ::Console. (#1924) The previous implementation used Cry rendering and CVars and had been left in a commented-out state. These changes restore it back to full functionality. Signed-off-by: mbalfour --- .../Code/Source/Debugger/DebugComponent.cpp | 211 +++++++++++------- .../Code/Source/Debugger/DebugComponent.h | 12 +- 2 files changed, 137 insertions(+), 86 deletions(-) diff --git a/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp b/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp index c24c380d6f..5fa2d6fd88 100644 --- a/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp +++ b/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp @@ -10,7 +10,10 @@ #include "AreaSystemComponent.h" #include "InstanceSystemComponent.h" +#include +#include #include +#include #include #include #include @@ -22,11 +25,6 @@ #include #include -#include -#include -#include -#include - #include namespace Vegetation @@ -112,18 +110,16 @@ void DebugComponent::Activate() DebugRequestBus::Handler::BusConnect(); DebugNotificationBus::Handler::BusConnect(); DebugNotificationBus::AllowFunctionQueuing(true); - AzFramework::DebugDisplayEventBus::Handler::BusConnect(); + AzFramework::EntityDebugDisplayEventBus::Handler::BusConnect(GetEntityId()); SystemConfigurationRequestBus::Handler::BusConnect(); - AddConsoleVariables(); VEG_PROFILE_METHOD(DebugSystemDataBus::BroadcastResult(m_debugData, &DebugSystemDataBus::Events::GetDebugData)); } void DebugComponent::Deactivate() { - RemoveConsoleVariables(); SystemConfigurationRequestBus::Handler::BusDisconnect(); - AzFramework::DebugDisplayEventBus::Handler::BusDisconnect(); + AzFramework::EntityDebugDisplayEventBus::Handler::BusDisconnect(); DebugRequestBus::Handler::BusDisconnect(); DebugNotificationBus::Handler::BusDisconnect(); @@ -153,7 +149,7 @@ bool DebugComponent::WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const return false; } -void DebugComponent::DrawGlobalDebugInfo() +void DebugComponent::DisplayEntityViewport(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) { // time to collect the report? if (AZStd::chrono::microseconds(AZStd::chrono::system_clock::now() - m_lastCollectionTime).count() > m_configuration.m_collectionFrequencyUs) @@ -173,23 +169,25 @@ void DebugComponent::DrawGlobalDebugInfo() m_exportCurrentReport = false; } + if (m_configuration.m_showVisualization) + { + DrawSectorTimingData(viewportInfo, debugDisplay); + } + if (m_configuration.m_showDebugStats) { - DrawDebugStats(); + DrawDebugStats(debugDisplay); } if (m_configuration.m_showInstanceVisualization) { - DrawInstanceDebug(); + DrawInstanceDebug(debugDisplay); } } -void DebugComponent::DrawInstanceDebug() +void DebugComponent::DrawInstanceDebug(AzFramework::DebugDisplayRequests& debugDisplay) { #if defined(VEG_PROFILE_ENABLED) - // ToDo: Re-implement with Atom. LYN-3681 - /*renderAuxGeom->SetRenderFlags(e_Mode3D | e_FillModeSolid | e_CullModeBack | e_DepthWriteOff | e_DepthTestOn); - AZStd::unordered_map areaDebugDisplayDataMap; for (const auto& instance : m_activeInstances) @@ -213,16 +211,87 @@ void DebugComponent::DrawInstanceDebug() { continue; } - - Vec3 pos(AZVec3ToLYVec3(instanceData.m_position)); - Vec3 radius(areaDebugDisplayData.m_instanceSize * 0.5f); - AABB bounds(pos - radius, pos + radius); - renderAuxGeom->DrawAABB(bounds, true, ColorB(areaDebugDisplayData.m_instanceColor.ToU32()), eBBD_Faceted); - }*/ + AZ::Vector3 radius(areaDebugDisplayData.m_instanceSize * 0.5f); + debugDisplay.SetColor(areaDebugDisplayData.m_instanceColor); + debugDisplay.DrawSolidBox(instanceData.m_position - radius, instanceData.m_position + radius); + } #endif } +void DebugComponent::DrawSectorTimingData(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) +{ + static const AZ::Color s_green = AZ::Color(0.3f, 0.9f, 0.3f, .05f); + static const AZ::Color s_yellow = AZ::Color(1.0f, 1.0f, 0.0f, .05f); + static const AZ::Color s_red = AZ::Color(1.0f, 0.0f, 0.0f, .05f); + static const float boxHeightAboveTerrain = 3.0f; + + + AreaSystemConfig areaConfig; + SystemConfigurationRequestBus::Broadcast(&SystemConfigurationRequestBus::Events::GetSystemConfig, &areaConfig); + const auto sectorSizeInMeters = areaConfig.m_sectorSizeInMeters; + const AZ::u32 maxTextDisplayDistance = m_configuration.m_maxLabelDisplayDistance; + const int maxDisplayCount = m_configuration.m_maxDatapointDisplayCount; + + AZ::Vector3 cameraPos(0.0f); + if (auto viewportContextRequests = AZ::RPI::ViewportContextRequests::Get(); viewportContextRequests) + { + AZ::RPI::ViewportContextPtr viewportContext = viewportContextRequests->GetViewportContextById(viewportInfo.m_viewportId); + cameraPos = viewportContext->GetCameraTransform().GetTranslation(); + } + AZ::Vector2 cameraPos2d(cameraPos.GetX(), cameraPos.GetY()); + + for (int i = 0; i < maxDisplayCount && i < m_currentSortedTimingList.size(); ++i) + { + const auto& sectorTiming = m_currentSortedTimingList[i]; + + AZ::Vector3 topCorner{ float(sectorTiming.m_id.first), float(sectorTiming.m_id.second), 0.0f }; + topCorner *= float(sectorSizeInMeters); + + AZ::Vector3 bottomCorner = topCorner + + AZ::Vector3(float(sectorSizeInMeters), float(sectorSizeInMeters), sectorTiming.m_worldPosition.GetZ() + boxHeightAboveTerrain); + + auto aabb = AZ::Aabb::CreateFromMinMax(topCorner, bottomCorner); + const AZ::Color* color = &s_yellow; + + if (sectorTiming.m_averageTimeUs >= m_configuration.m_maxThresholdUs) + { + color = &s_red; + } + else if (sectorTiming.m_averageTimeUs < m_configuration.m_minThresholdUs) + { + color = &s_green; + } + + AZ::Color outlineColor(color->GetR(), color->GetG(), color->GetB(), 1.0f); + + // Box around the entire sector + debugDisplay.SetColor(*color); + debugDisplay.DrawSolidBox(aabb.GetMin(), aabb.GetMax()); + debugDisplay.SetColor(outlineColor); + debugDisplay.DrawWireBox(aabb.GetMin(), aabb.GetMax()); + + // Smaller box inside the sector + const AZ::Vector3 innerBoxRadius(0.5f); + debugDisplay.SetColor(outlineColor); + debugDisplay.DrawSolidBox(sectorTiming.m_worldPosition - innerBoxRadius, sectorTiming.m_worldPosition + innerBoxRadius); + + AZ::Vector2 sectorPos2d(sectorTiming.m_worldPosition.GetX(), sectorTiming.m_worldPosition.GetY()); + float distanceToCamera = cameraPos2d.GetDistance(sectorPos2d); + + if (distanceToCamera <= maxTextDisplayDistance) + { + AZStd::string displayString = AZStd::string::format("Sector %d, %d\nTime: %dus\nUpdate Count: %d", sectorTiming.m_id.first, + sectorTiming.m_id.second, static_cast(sectorTiming.m_averageTimeUs), sectorTiming.m_updateCount); + + constexpr bool centerText = true; + constexpr float fontSize = 1.5f; + debugDisplay.SetColor(AZ::Color(1.0f)); + debugDisplay.DrawTextLabel(sectorTiming.m_worldPosition, fontSize, displayString.c_str(), centerText); + } + } +} + void DebugComponent::CopyReportToSortedList() { m_currentSortedTimingList.clear(); @@ -885,23 +954,9 @@ void DebugComponent::PrepareNextReport() }); } -void DebugComponent::RemoveConsoleVariables() +void DebugComponent::DrawDebugStats(AzFramework::DebugDisplayRequests& debugDisplay) { - ISystem* crySystem = GetISystem(); - if (crySystem && crySystem->GetIConsole()) - { - IConsole* console = crySystem->GetIConsole(); - console->RemoveCommand("veg_debugToggleVisualization"); - console->RemoveCommand("veg_debugDumpReport"); - console->RemoveCommand("veg_debugRefreshAllAreas"); - console->RemoveCommand("veg_debugClearAllAreas"); - } -} - -void DebugComponent::DrawDebugStats() -{ - // ToDo: Re-implement with Atom. LYN-3681 - /*if (!m_debugData) + if (!m_debugData) { return; } @@ -915,52 +970,48 @@ void DebugComponent::DrawDebugStats() AZ::u32 destroyTaskCount = 0; InstanceSystemStatsRequestBus::BroadcastResult(destroyTaskCount, &InstanceSystemStatsRequestBus::Events::GetDestroyTaskCount); - renderAuxGeom->Draw2dLabel(4, 16, 1.5f, ColorF(1, 1, 1), false, - AZStd::string::format("VegetationSystemStats:\nActive Instances Count: %d\nInstance Register Queue: %d\nInstance Unregister Queue: %d\nThread Queue Count: %d\nThread Processing Count: %d", - instanceCount, - createTaskCount, - destroyTaskCount, - m_debugData->m_areaTaskQueueCount.load(AZStd::memory_order_relaxed), - m_debugData->m_areaTaskActiveCount.load(AZStd::memory_order_relaxed) - ).c_str());*/ -} - -void DebugComponent::AddConsoleVariables() -{ - ISystem* crySystem = GetISystem(); - if (crySystem && crySystem->GetIConsole()) - { - IConsole* console = crySystem->GetIConsole(); - - static auto fnCmdToggleDebugger = []([[maybe_unused]] IConsoleCmdArgs* args) - { - DebugNotificationBus::Broadcast(&DebugNotificationBus::Events::ToggleVisualization); - }; - console->AddCommand("veg_debugToggleVisualization", fnCmdToggleDebugger, VF_NULL, "Toggles visualization of sector timings"); - - static auto fnCmdDumpReport = []([[maybe_unused]] IConsoleCmdArgs* args) - { - DebugNotificationBus::Broadcast(&DebugNotificationBus::Events::ExportCurrentReport); - }; - console->AddCommand("veg_debugDumpReport", fnCmdDumpReport, VF_NULL, "Writes out a vegetation sector report"); - - static auto fnRefreshAllAreas = []([[maybe_unused]] IConsoleCmdArgs* args) - { - AreaSystemRequestBus::Broadcast(&AreaSystemRequestBus::Events::RefreshAllAreas); - }; - console->AddCommand("veg_debugRefreshAllAreas", fnRefreshAllAreas, VF_NULL, "Refresh all vegetation areas in the current view"); - - static auto fnClearAllAreas = []([[maybe_unused]] IConsoleCmdArgs* args) - { - AreaSystemRequestBus::Broadcast(&AreaSystemRequestBus::Events::ClearAllAreas); - AreaSystemRequestBus::Broadcast(&AreaSystemRequestBus::Events::RefreshAllAreas); - }; - console->AddCommand("veg_debugClearAllAreas", fnClearAllAreas, VF_NULL, "Clear and refresh all vegetation areas in the current view"); - } + debugDisplay.SetColor(AZ::Color(1.0f)); + debugDisplay.Draw2dTextLabel( + 4.0f, 16.0f, 1.5f, + AZStd::string::format( + "VegetationSystemStats:\nActive Instances Count: %d\nInstance Register Queue: %d\nInstance Unregister Queue: %d\nThread " + "Queue Count: %d\nThread Processing Count: %d", + instanceCount, createTaskCount, destroyTaskCount, m_debugData->m_areaTaskQueueCount.load(AZStd::memory_order_relaxed), + m_debugData->m_areaTaskActiveCount.load(AZStd::memory_order_relaxed)) + .c_str(), + false); } namespace { + static void veg_debugToggleVisualization([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments) + { + DebugNotificationBus::Broadcast(&DebugNotificationBus::Events::ToggleVisualization); + } + AZ_CONSOLEFREEFUNC(veg_debugToggleVisualization, AZ::ConsoleFunctorFlags::DontReplicate, "Toggles visualization of sector timings"); + + static void veg_debugDumpReport([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments) + { + DebugNotificationBus::Broadcast(&DebugNotificationBus::Events::ExportCurrentReport); + } + AZ_CONSOLEFREEFUNC(veg_debugDumpReport, AZ::ConsoleFunctorFlags::DontReplicate, "Writes out a vegetation sector report"); + + static void veg_debugRefreshAllAreas([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments) + { + AreaSystemRequestBus::Broadcast(&AreaSystemRequestBus::Events::RefreshAllAreas); + } + AZ_CONSOLEFREEFUNC( + veg_debugRefreshAllAreas, AZ::ConsoleFunctorFlags::DontReplicate, "Refresh all vegetation areas in the current view"); + + static void veg_debugClearAllAreas([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments) + { + AreaSystemRequestBus::Broadcast(&AreaSystemRequestBus::Events::ClearAllAreas); + AreaSystemRequestBus::Broadcast(&AreaSystemRequestBus::Events::RefreshAllAreas); + } + AZ_CONSOLEFREEFUNC( + veg_debugClearAllAreas, AZ::ConsoleFunctorFlags::DontReplicate, "Clear and refresh all vegetation areas in the current view"); + + const char* GetSortTypeString(DebugRequests::SortType sortType) { switch (sortType) diff --git a/Gems/Vegetation/Code/Source/Debugger/DebugComponent.h b/Gems/Vegetation/Code/Source/Debugger/DebugComponent.h index 6362d98371..224ad5ded5 100644 --- a/Gems/Vegetation/Code/Source/Debugger/DebugComponent.h +++ b/Gems/Vegetation/Code/Source/Debugger/DebugComponent.h @@ -54,7 +54,7 @@ namespace Vegetation class DebugComponent : public AZ::Component - , private AzFramework::DebugDisplayEventBus::Handler + , private AzFramework::EntityDebugDisplayEventBus::Handler , private DebugRequestBus::Handler , private DebugNotificationBus::Handler , private SystemConfigurationRequestBus::Handler @@ -79,7 +79,8 @@ namespace Vegetation ////////////////////////////////////////////////////////////////////////// // EntityDebugDisplayEventBus - void DrawGlobalDebugInfo() override; + void DisplayEntityViewport( + const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override; ////////////////////////////////////////////////////////////////////////// // DebugNotifications @@ -112,10 +113,9 @@ namespace Vegetation protected: void PrepareNextReport(); void CopyReportToSortedList(); - void AddConsoleVariables(); - void RemoveConsoleVariables(); - void DrawDebugStats(); - void DrawInstanceDebug(); + void DrawSectorTimingData(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay); + void DrawDebugStats(AzFramework::DebugDisplayRequests& debugDisplay); + void DrawInstanceDebug(AzFramework::DebugDisplayRequests& debugDisplay); private: AZStd::atomic_bool m_exportCurrentReport{ false };