ImGuiHistogramQueue.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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. #include <Utils/ImGuiHistogramQueue.h>
  9. #include <AzCore/std/string/string.h>
  10. #include <imgui/imgui.h>
  11. namespace AtomSampleViewer
  12. {
  13. ImGuiHistogramQueue::ImGuiHistogramQueue(
  14. AZStd::size_t maxSamples,
  15. AZStd::size_t runningAverageSamples,
  16. float numericDisplayUpdateDelay)
  17. : m_maxSamples(maxSamples)
  18. , m_runningAverageSamples(runningAverageSamples)
  19. , m_numericDisplayDelay(numericDisplayUpdateDelay)
  20. {
  21. AZ_Assert(m_maxSamples >= m_runningAverageSamples, "maxSamples must be larger");
  22. m_valueLog.reserve(m_maxSamples);
  23. m_averageLog.reserve(m_maxSamples);
  24. }
  25. float ImGuiHistogramQueue::UpdateDisplayedValues(AZStd::size_t maxSampleCount, float& minValue, float& maxValue)
  26. {
  27. size_t sampleCount = AZStd::min<size_t>(maxSampleCount, m_valueLog.size());
  28. float average = 0.f;
  29. if (sampleCount > 0)
  30. {
  31. average = m_valueLog.at(0);
  32. minValue = maxValue = average;
  33. for (size_t i = 1; i < sampleCount; ++i)
  34. {
  35. float curValue = m_valueLog.at(i);
  36. average += curValue;
  37. minValue = minValue > curValue ? curValue : minValue;
  38. maxValue = maxValue < curValue ? curValue : maxValue;
  39. }
  40. average /= sampleCount;
  41. }
  42. return average;
  43. }
  44. void ImGuiHistogramQueue::PushValue(float value)
  45. {
  46. m_samplesSinceLastDisplayUpdate++;
  47. // Update the log of all values
  48. if (m_valueLog.size() == m_maxSamples)
  49. {
  50. m_valueLog.pop_back();
  51. }
  52. m_valueLog.insert(m_valueLog.begin(), value);
  53. // Calculate running average for line graph
  54. if (m_averageLog.size() == m_maxSamples)
  55. {
  56. m_averageLog.pop_back();
  57. }
  58. [[maybe_unused]] float minValue, maxValue; // unused required call parameters
  59. m_averageLog.insert(m_averageLog.begin(), UpdateDisplayedValues(m_runningAverageSamples, minValue, maxValue));
  60. // Calculate average for numeric display
  61. if (m_timeSinceLastDisplayUpdate >= m_numericDisplayDelay || m_samplesSinceLastDisplayUpdate >= m_maxSamples)
  62. {
  63. m_displayedAverage = UpdateDisplayedValues(m_samplesSinceLastDisplayUpdate, m_displayedMinimum, m_displayedMaximum);
  64. m_timeSinceLastDisplayUpdate = 0.0f;
  65. m_samplesSinceLastDisplayUpdate = 0;
  66. }
  67. }
  68. void ImGuiHistogramQueue::Tick(float deltaTime, WidgetSettings settings)
  69. {
  70. if (m_averageLog.empty() || m_valueLog.empty())
  71. {
  72. return;
  73. }
  74. m_timeSinceLastDisplayUpdate += deltaTime;
  75. ImVec2 pos = ImGui::GetCursorPos();
  76. AZStd::string valueString;
  77. if (settings.m_reportInverse)
  78. {
  79. valueString = AZStd::string::format("%4.2f %s", 1.0 / m_displayedAverage, settings.m_units);
  80. }
  81. else
  82. {
  83. valueString = AZStd::string::format("avg:%4.2f %s | min:%4.2f %s | max:%4.2f %s ", m_displayedAverage, settings.m_units, m_displayedMinimum, settings.m_units, m_displayedMaximum, settings.m_units);
  84. }
  85. // Draw moving average of values first
  86. ImGui::PushStyleColor(ImGuiCol_PlotLines, ImVec4(0.6, 0.8, 0.9, 1.0));
  87. ImGui::PlotLines("##Average", &m_averageLog[0], int32_t(m_averageLog.size()), 0, nullptr, 0.0f, m_displayedAverage * 2.0f, ImVec2(400, 50));
  88. ImGui::PopStyleColor();
  89. // Draw individual value bars on top of it (with no background).
  90. ImGui::SetCursorPos(pos);
  91. ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0, 0, 0, 0));
  92. ImGui::PlotHistogram("##Value", &m_valueLog[0], int32_t(m_valueLog.size()), 0, valueString.c_str(), 0.0f, m_displayedAverage * 2.0f, ImVec2(400, 50));
  93. ImGui::PopStyleColor();
  94. }
  95. } // namespace AtomSampleViewer