| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include <Utils/ImGuiHistogramQueue.h>
- #include <AzCore/std/string/string.h>
- #include <imgui/imgui.h>
- namespace AtomSampleViewer
- {
- ImGuiHistogramQueue::ImGuiHistogramQueue(
- AZStd::size_t maxSamples,
- AZStd::size_t runningAverageSamples,
- float numericDisplayUpdateDelay)
- : m_maxSamples(maxSamples)
- , m_runningAverageSamples(runningAverageSamples)
- , m_numericDisplayDelay(numericDisplayUpdateDelay)
- {
- AZ_Assert(m_maxSamples >= m_runningAverageSamples, "maxSamples must be larger");
- m_valueLog.reserve(m_maxSamples);
- m_averageLog.reserve(m_maxSamples);
- }
- float ImGuiHistogramQueue::UpdateDisplayedValues(AZStd::size_t maxSampleCount, float& minValue, float& maxValue)
- {
- size_t sampleCount = AZStd::min<size_t>(maxSampleCount, m_valueLog.size());
- float average = 0.f;
- if (sampleCount > 0)
- {
- average = m_valueLog.at(0);
- minValue = maxValue = average;
- for (size_t i = 1; i < sampleCount; ++i)
- {
- float curValue = m_valueLog.at(i);
- average += curValue;
- minValue = minValue > curValue ? curValue : minValue;
- maxValue = maxValue < curValue ? curValue : maxValue;
- }
- average /= sampleCount;
- }
- return average;
- }
- void ImGuiHistogramQueue::PushValue(float value)
- {
- m_samplesSinceLastDisplayUpdate++;
- // Update the log of all values
- if (m_valueLog.size() == m_maxSamples)
- {
- m_valueLog.pop_back();
- }
- m_valueLog.insert(m_valueLog.begin(), value);
- // Calculate running average for line graph
- if (m_averageLog.size() == m_maxSamples)
- {
- m_averageLog.pop_back();
- }
- [[maybe_unused]] float minValue, maxValue; // unused required call parameters
- m_averageLog.insert(m_averageLog.begin(), UpdateDisplayedValues(m_runningAverageSamples, minValue, maxValue));
- // Calculate average for numeric display
- if (m_timeSinceLastDisplayUpdate >= m_numericDisplayDelay || m_samplesSinceLastDisplayUpdate >= m_maxSamples)
- {
- m_displayedAverage = UpdateDisplayedValues(m_samplesSinceLastDisplayUpdate, m_displayedMinimum, m_displayedMaximum);
- m_timeSinceLastDisplayUpdate = 0.0f;
- m_samplesSinceLastDisplayUpdate = 0;
- }
- }
- void ImGuiHistogramQueue::Tick(float deltaTime, WidgetSettings settings)
- {
- if (m_averageLog.empty() || m_valueLog.empty())
- {
- return;
- }
- m_timeSinceLastDisplayUpdate += deltaTime;
- ImVec2 pos = ImGui::GetCursorPos();
- AZStd::string valueString;
- if (settings.m_reportInverse)
- {
- valueString = AZStd::string::format("%4.2f %s", 1.0 / m_displayedAverage, settings.m_units);
- }
- else
- {
- 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);
- }
- // Draw moving average of values first
- ImGui::PushStyleColor(ImGuiCol_PlotLines, ImVec4(0.6, 0.8, 0.9, 1.0));
- ImGui::PlotLines("##Average", &m_averageLog[0], int32_t(m_averageLog.size()), 0, nullptr, 0.0f, m_displayedAverage * 2.0f, ImVec2(400, 50));
- ImGui::PopStyleColor();
- // Draw individual value bars on top of it (with no background).
- ImGui::SetCursorPos(pos);
- ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0, 0, 0, 0));
- ImGui::PlotHistogram("##Value", &m_valueLog[0], int32_t(m_valueLog.size()), 0, valueString.c_str(), 0.0f, m_displayedAverage * 2.0f, ImVec2(400, 50));
- ImGui::PopStyleColor();
- }
- } // namespace AtomSampleViewer
|