ImGuiLYCameraMonitor.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #ifdef IMGUI_ENABLED
  9. #include "ImGuiLYCameraMonitor.h"
  10. #include <AzCore/Component/ComponentApplicationBus.h>
  11. #include <AzCore/Component/ComponentBus.h>
  12. #include <AzCore/Component/TransformBus.h>
  13. #include <AzFramework/Components/CameraBus.h>
  14. #include "ImGuiColorDefines.h"
  15. namespace ImGui
  16. {
  17. ImGuiLYCameraMonitor::ImGuiLYCameraMonitor()
  18. : m_enabled(false)
  19. , m_recordCameraData(false)
  20. , m_camHistorySize(10)
  21. , m_currentCamera()
  22. , m_cameraHistory()
  23. {
  24. }
  25. void ImGuiLYCameraMonitor::Initialize()
  26. {
  27. // Connect to EBUSes
  28. AZ::TickBus::Handler::BusConnect();
  29. ImGuiCameraMonitorRequestBus::Handler::BusConnect();
  30. // Init Histogram Containers
  31. m_dofMinZHisto.Init( "DOF Min Z", 120, LYImGuiUtils::HistogramContainer::ViewType::Histogram, true, 0.0f, 0.0f);
  32. m_dofMinZBlendMultHisto.Init( "DOF Min Z Blend Mult", 120, LYImGuiUtils::HistogramContainer::ViewType::Histogram, true, 50.0f, 50.0f);
  33. m_dofMinZScaleHisto.Init( "DOF Min Z Scale", 120, LYImGuiUtils::HistogramContainer::ViewType::Histogram, true, 50.0f, 50.0f);
  34. m_globalActiveCamInfo.m_fovHisto.Init( "FOV", 120, LYImGuiUtils::HistogramContainer::ViewType::Lines, true, 50.0f, 50.0f);
  35. m_globalActiveCamInfo.m_facingVectorDeltaHisto.Init( "Facing Vec Frame Delta", 120, LYImGuiUtils::HistogramContainer::ViewType::Histogram, true, 0.0f, 0.0f);
  36. m_globalActiveCamInfo.m_positionDeltaHisto.Init( "Position Frame Delta", 120, LYImGuiUtils::HistogramContainer::ViewType::Histogram, true, 0.0f, 0.0f);
  37. }
  38. void ImGuiLYCameraMonitor::Shutdown()
  39. {
  40. AZ::TickBus::Handler::BusDisconnect();
  41. ImGuiCameraMonitorRequestBus::Handler::BusDisconnect();
  42. }
  43. void ImGuiLYCameraMonitor::ImGuiUpdate()
  44. {
  45. // Manage main window visibility
  46. if (m_enabled)
  47. {
  48. if (ImGui::Begin("Camera Monitor", &m_enabled, ImGuiWindowFlags_MenuBar|ImGuiWindowFlags_HorizontalScrollbar|ImGuiWindowFlags_NoSavedSettings))
  49. {
  50. // Draw the Entire Main Menu Window Area
  51. ImGuiUpdate_DrawMenu();
  52. //// Draw Menu Bar
  53. if (ImGui::BeginMenuBar())
  54. {
  55. if (ImGui::BeginMenu("Options##cameraMonitor"))
  56. {
  57. ImGuiUpdate_DrawOptions();
  58. ImGui::EndMenu();
  59. }
  60. ImGui::EndMenuBar();
  61. }
  62. }
  63. ImGui::End();
  64. }
  65. }
  66. void ImGuiLYCameraMonitor::ImGuiUpdate_DrawMenu()
  67. {
  68. ImGui::Checkbox("Record Camera Data", &m_recordCameraData);
  69. if (ImGui::CollapsingHeader("Current Camera Monitor", ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_Framed))
  70. {
  71. // Get Current Camera Name
  72. AZStd::string camName("*invalid_name*");
  73. AZ::ComponentApplicationBus::BroadcastResult(camName, &AZ::ComponentApplicationBus::Events::GetEntityName, m_currentCamera);
  74. ImGui::TextColored(ImGui::Colors::s_NiceLabelColor, " Active Cam: %s %s", m_currentCamera.ToString().c_str(), camName.c_str());
  75. ImGui::TextColored(ImGui::Colors::s_NiceLabelColor, " Active Cam frames/time: %d / %.02f", m_globalActiveCamInfo.m_activeFrames, m_globalActiveCamInfo.m_activeTime);
  76. ImGui::Columns(3);
  77. m_globalActiveCamInfo.m_fovHisto.Draw(ImGui::GetColumnWidth(), 140.0f);
  78. ImGui::NextColumn();
  79. m_globalActiveCamInfo.m_facingVectorDeltaHisto.Draw(ImGui::GetColumnWidth(), 140.0f);
  80. ImGui::NextColumn();
  81. m_globalActiveCamInfo.m_positionDeltaHisto.Draw(ImGui::GetColumnWidth(), 140.0f);
  82. ImGui::NextColumn();
  83. ImGui::Columns(1);
  84. }
  85. if (ImGui::CollapsingHeader("Camera History", ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_Framed))
  86. {
  87. for (int i = 0; i < m_cameraHistory.size(); ++i)
  88. {
  89. CameraInfo& camInfo = m_cameraHistory[i];
  90. ImGui::BeginChild(AZStd::string::format("cameraInfo%d", i).c_str(), ImVec2(0, 60.0f), true);
  91. ImGui::TextColored(ImGui::Colors::s_NiceLabelColor, "Previous Cam %d: %s %s", i, camInfo.m_camId.ToString().c_str(), camInfo.m_camName.c_str());
  92. ImGui::TextColored(ImGui::Colors::s_NiceLabelColor, " Active Cam frames/time: %d / %.02f", camInfo.m_activeFrames, camInfo.m_activeTime);
  93. if (ImGui::IsWindowHovered())
  94. {
  95. ImGui::BeginTooltip();
  96. ImGui::BeginChild(AZStd::string::format("cameraInfoTooltip%d", i).c_str(), ImVec2(500.0f, 140.0f), true);
  97. ImGui::Columns(3);
  98. camInfo.m_fovHisto.Draw(ImGui::GetColumnWidth(), 130.0f);
  99. ImGui::NextColumn();
  100. camInfo.m_facingVectorDeltaHisto.Draw(ImGui::GetColumnWidth(), 130.0f);
  101. ImGui::NextColumn();
  102. camInfo.m_positionDeltaHisto.Draw(ImGui::GetColumnWidth(), 130.0f);
  103. ImGui::Columns(1);
  104. ImGui::EndChild();
  105. ImGui::EndTooltip();
  106. }
  107. ImGui::EndChild();
  108. }
  109. }
  110. }
  111. void ImGuiLYCameraMonitor::ImGuiUpdate_DrawOptions()
  112. {
  113. ImGui::SliderInt("Camera History Size", &m_camHistorySize, 1, 100);
  114. // if we have lowered the camera history size, we should remove oldest here
  115. while (m_camHistorySize < m_cameraHistory.size())
  116. {
  117. m_cameraHistory.pop_back();
  118. }
  119. }
  120. void ImGuiLYCameraMonitor::OnTick(float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time)
  121. {
  122. if (m_recordCameraData)
  123. {
  124. OnTick_GatherCameraData(deltaTime);
  125. }
  126. }
  127. void ImGuiLYCameraMonitor::OnTick_GatherCameraData(float deltaTime)
  128. {
  129. // Get the Active Camera
  130. AZ::EntityId activeCam;
  131. Camera::CameraSystemRequestBus::BroadcastResult(activeCam, &Camera::CameraSystemRequests::GetActiveCamera);
  132. // if this is the first time we are seeing this camera, move the previous camera to the history and start recording this camera history
  133. if (activeCam != m_currentCamera)
  134. {
  135. OnTick_GatherCameraData_PushNewCameraToHistory(activeCam);
  136. }
  137. // Catch corner cases where no camera History has been added due to startup conditions ( Camera with Invalid Entity Id occurs during startup, which we don't add to the history )
  138. if (m_cameraHistory.empty())
  139. {
  140. return;
  141. }
  142. // Grab the current cameraInfo stuct ( may be the one that was just created above! Whatev! )
  143. CameraInfo& currentCam = m_cameraHistory.front();
  144. float fov;
  145. Camera::CameraRequestBus::EventResult(fov, currentCam.m_camId, &Camera::CameraComponentRequests::GetFovDegrees);
  146. currentCam.m_fovHisto.PushValue(fov);
  147. // Grab the current Transform to figure out Position and Orientation Drame Deltas, then push those into some Histogram Containers
  148. AZ::Transform camTransform;
  149. AZ::TransformBus::EventResult(camTransform, currentCam.m_camId, &AZ::TransformBus::Events::GetWorldTM);
  150. const AZ::Vector3& camFacing = camTransform.GetBasisY();
  151. const float positionFrameDelta = (camTransform.GetTranslation() - currentCam.m_lastWorldPos).GetLength();
  152. currentCam.m_lastWorldPos = camTransform.GetTranslation();
  153. currentCam.m_positionDeltaHisto.PushValue(positionFrameDelta);
  154. const float facingDirFrameDelta = GetAngleBetweenVectors(camFacing, currentCam.m_lastFacingVector);
  155. currentCam.m_lastFacingVector = camFacing;
  156. currentCam.m_facingVectorDeltaHisto.PushValue(facingDirFrameDelta);
  157. // increment frame count and timer
  158. ++currentCam.m_activeFrames;
  159. currentCam.m_activeTime += deltaTime;
  160. // Copy some of the info into the global Cam
  161. m_globalActiveCamInfo.m_lastWorldPos = currentCam.m_lastWorldPos;
  162. m_globalActiveCamInfo.m_lastFacingVector = currentCam.m_lastFacingVector;
  163. m_globalActiveCamInfo.m_fovHisto.PushValue(fov);
  164. m_globalActiveCamInfo.m_facingVectorDeltaHisto.PushValue(facingDirFrameDelta);
  165. m_globalActiveCamInfo.m_positionDeltaHisto.PushValue(positionFrameDelta);
  166. m_globalActiveCamInfo.m_activeFrames = currentCam.m_activeFrames;
  167. m_globalActiveCamInfo.m_activeTime = currentCam.m_activeTime;
  168. }
  169. float ImGuiLYCameraMonitor::GetAngleBetweenVectors(const AZ::Vector3& v1, const AZ::Vector3& v2)
  170. {
  171. float dot = v1.Dot(v2) / (v1.GetLength() * v2.GetLength());
  172. return !AZStd::isnan(dot) ? acosf(AZ::GetClamp(dot, -1.0f, 1.0f)) : 0.0f;
  173. }
  174. void ImGuiLYCameraMonitor::OnTick_GatherCameraData_PushNewCameraToHistory(AZ::EntityId newCamId)
  175. {
  176. // see if we are already at max history capacity, and if so, pop the back
  177. while (m_cameraHistory.size() >= m_camHistorySize - 1)
  178. {
  179. m_cameraHistory.pop_back();
  180. }
  181. // save this cam off as the current one
  182. m_currentCamera = newCamId;
  183. // create a new empty CameraInfo in the queue
  184. m_cameraHistory.push_front(CameraInfo());
  185. // init the new front of the queue
  186. CameraInfo& newCam = m_cameraHistory.front();
  187. newCam.m_camId = m_currentCamera;
  188. AZ::ComponentApplicationBus::BroadcastResult(newCam.m_camName, &AZ::ComponentApplicationBus::Events::GetEntityName, m_currentCamera);
  189. newCam.m_activeTime = 0.0f;
  190. newCam.m_activeFrames = 0;
  191. newCam.m_fovHisto.Init( "FOV", 120, LYImGuiUtils::HistogramContainer::ViewType::Lines, true, 50.0f, 50.0f);
  192. newCam.m_facingVectorDeltaHisto.Init( "Facing Vec Frame Delta", 120, LYImGuiUtils::HistogramContainer::ViewType::Histogram, true, 0.0f, 0.0f);
  193. newCam.m_positionDeltaHisto.Init( "Position Frame Delta", 120, LYImGuiUtils::HistogramContainer::ViewType::Histogram, true, 0.0f, 0.0f);
  194. // reset a few variables on the global camera info
  195. m_globalActiveCamInfo.m_camId = newCam.m_camId;
  196. m_globalActiveCamInfo.m_camName = newCam.m_camName;
  197. m_globalActiveCamInfo.m_activeFrames = 0;
  198. m_globalActiveCamInfo.m_activeTime = 0.0f;
  199. }
  200. } // namespace ImGui
  201. #endif // IMGUI_ENABLED