Physics Simulation & Visualization Tool 0.1
A C++ physics simulation engine with real-time 3D visualization
Loading...
Searching...
No Matches
FrameGraphPanel.cpp
Go to the documentation of this file.
1#include <algorithm>
2#include <QVBoxLayout>
3#include <QResizeEvent>
4#include <array>
5
6#include "FrameGraphPanel.h"
7#include "FrameGraphWidget.h"
8#include "Metric.h"
9
10namespace {
11 constexpr int kMinimumCardWidth = 180;
12 constexpr int kLayoutMargin = 0;
13 constexpr int kGridMargin = 8;
14 constexpr int kGridSpacing = 8;
15 constexpr float kAxisPadding = 0.5f;
16}
17
18FrameGraphPanel::FrameGraphPanel(QWidget* parent) : QWidget(parent) {
19 auto* layout = new QVBoxLayout(this);
20 layout->setContentsMargins(kLayoutMargin, kLayoutMargin, kLayoutMargin, kLayoutMargin);
21 scrollArea = new QScrollArea(this);
22 scrollArea->setWidgetResizable(true);
23 auto* container = new QWidget(scrollArea);
24 gridLayout = new QGridLayout(container);
25 gridLayout->setContentsMargins(kGridMargin, kGridMargin, kGridMargin, kGridMargin);
26 gridLayout->setSpacing(kGridSpacing);
27 gridLayout->setAlignment(Qt::AlignTop);
28
29 int cntMetric = static_cast<int>(Metric::Count);
30 frameGraphs.reserve(cntMetric);
31 for (int i = 0; i < cntMetric; ++i) {
32 Metric metric = static_cast<Metric>(i);
33 auto* graph = new FrameGraphWidget(container);
34 graph->setMetric(metric);
35 graph->setSelectorVisible(false);
36 frameGraphs.push_back(graph);
37 }
38 scrollArea->setWidget(container);
39 layout->addWidget(scrollArea);
40}
41
42void FrameGraphPanel::recomputeTimeAndValueRanges() {
43 if (!m_snapshots || m_snapshots->empty()) {
44 m_tMin = m_tMax = 0.0f;
45 m_valueMinMaxPerMetric = {};
46 return;
47 }
48 const auto& snapshots = *m_snapshots;
49 m_tMin = m_tMax = snapshots.front().time;
50 for (int m = 0; m < static_cast<int>(kPlottableMetricCount); ++m) {
51 const float v = objectSnapshotValue(static_cast<Metric>(m), snapshots.front());
52 m_valueMinMaxPerMetric[static_cast<size_t>(m)] = {v, v};
53 }
54 for (const auto& s : snapshots) {
55 m_tMin = std::min(m_tMin, s.time);
56 m_tMax = std::max(m_tMax, s.time);
57 for (int m = 0; m < static_cast<int>(kPlottableMetricCount); ++m) {
58 const float v = objectSnapshotValue(static_cast<Metric>(m), s);
59 auto& pr = m_valueMinMaxPerMetric[static_cast<size_t>(m)];
60 pr.first = std::min(pr.first, v);
61 pr.second = std::max(pr.second, v);
62 }
63 }
64 if (m_tMin == m_tMax) {
65 m_tMin -= kAxisPadding;
66 m_tMax += kAxisPadding;
67 }
68 for (auto& pr : m_valueMinMaxPerMetric) {
69 if (pr.first == pr.second) {
70 pr.first -= kAxisPadding;
71 pr.second += kAxisPadding;
72 }
73 }
74}
75
76void FrameGraphPanel::loadSnapshots(const std::vector<ObjectSnapshot>& snapshots) {
77 m_snapshots = std::make_shared<std::vector<ObjectSnapshot>>(snapshots);
78 recomputeTimeAndValueRanges();
79 if (!m_snapshots || m_snapshots->empty()) {
80 for (auto* graph : frameGraphs) {
81 graph->clear();
82 }
83 return;
84 }
85 for (auto* graph : frameGraphs) {
86 graph->setSharedData(m_snapshots, m_valueMinMaxPerMetric, m_tMin, m_tMax);
87 }
88}
89
91 m_snapshots.reset();
92 m_tMin = m_tMax = 0.0f;
93 m_valueMinMaxPerMetric = {};
94 for (auto* graph : frameGraphs) {
95 graph->clear();
96 }
97}
98
99void FrameGraphPanel::resizeEvent(QResizeEvent* event) {
100 QWidget::resizeEvent(event);
101 relayoutGraphs();
102}
103
104void FrameGraphPanel::relayoutGraphs() {
105 if (!gridLayout) return;
106 const int availableWidth = scrollArea->viewport()->width() - gridLayout->contentsMargins().left() - gridLayout->contentsMargins().right();
107 const int spacing = gridLayout->horizontalSpacing();
108 const int columns = std::max(1, (availableWidth + spacing) / (kMinimumCardWidth + spacing));
109 if (columns == currentColumns && gridLayout->count() == static_cast<int>(frameGraphs.size())) {
110 return;
111 }
112 currentColumns = columns;
113 for (auto* graph : frameGraphs) {
114 gridLayout->removeWidget(graph);
115 }
116 const int maxTracks = static_cast<int>(frameGraphs.size());
117 for (int index = 0; index < maxTracks; ++index) {
118 gridLayout->setColumnStretch(index, 0);
119 gridLayout->setColumnMinimumWidth(index, 0);
120 gridLayout->setRowStretch(index, 0);
121 gridLayout->setRowMinimumHeight(index, 0);
122 }
123 for (int i = 0; i < maxTracks; ++i) {
124 const int row = i / columns;
125 const int column = i % columns;
126 gridLayout->addWidget(frameGraphs[i], row, column);
127 }
128 for (int column = 0; column < columns; ++column) {
129 gridLayout->setColumnStretch(column, 1);
130 }
131 gridLayout->invalidate();
132 scrollArea->widget()->updateGeometry();
133}
constexpr std::size_t kPlottableMetricCount
Definition Metric.h:21
Metric
Definition Metric.h:9
float objectSnapshotValue(Metric metric, const ObjectSnapshot &s)
Definition Metric.h:37
void loadSnapshots(const std::vector< ObjectSnapshot > &snapshots)
FrameGraphPanel(QWidget *parent=nullptr)
void resizeEvent(QResizeEvent *event) override