-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsatellite_info_renderer.cpp
More file actions
97 lines (77 loc) · 3.41 KB
/
satellite_info_renderer.cpp
File metadata and controls
97 lines (77 loc) · 3.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include "satellite_info_renderer.h"
#include <QFontMetrics>
#include <QDebug>
#include <QApplication>
SatelliteInfoRenderer::SatelliteInfoRenderer()
{
}
SatelliteInfoRenderer::~SatelliteInfoRenderer()
{
}
QPoint SatelliteInfoRenderer::worldToScreen(const QVector3D& worldPos, const QMatrix4x4& mvp,
const QSize& viewportSize)
{
// Преобразование из мировых координат в экранные
QVector4D clipSpace = mvp * QVector4D(worldPos, 1.0f);
// Проверка на видимость точки (за камерой)
if (clipSpace.w() <= 0)
return QPoint(-1, -1);
clipSpace = clipSpace / clipSpace.w();
// Преобразование в координаты экрана
QPoint screenPos;
screenPos.setX(int((clipSpace.x() + 1.0f) * viewportSize.width() / 2.0f));
screenPos.setY(int((1.0f - clipSpace.y()) * viewportSize.height() / 2.0f));
return screenPos;
}
void SatelliteInfoRenderer::drawInfoBox(QPainter* painter, const QPoint& pos, const QString& info)
{
// Настройка шрифта
QFont font("Arial", 10);
painter->setFont(font);
QFontMetrics fm(font);
// Разбиваем текст на строки
QStringList lines = info.split('\n');
// Вычисляем размеры текстового блока
int maxWidth = 0;
int totalHeight = 0;
for (const QString& line : lines) {
QRect bounds = fm.boundingRect(line);
maxWidth = qMax(maxWidth, bounds.width());
totalHeight += bounds.height();
}
// Добавляем минимальные отступы
const int padding = 4;
maxWidth += padding * 2;
totalHeight += padding * 2 + (lines.count() - 1) * 2;
// Позиционируем блок справа от спутника
int boxX = pos.x() + 5; // Небольшой отступ вправо от точки спутника
int boxY = pos.y() - totalHeight / 2; // Центрируем по вертикали относительно спутника
// Создаем прямоугольник для фона
QRect backgroundRect(boxX, boxY, maxWidth, totalHeight);
// Рисуем фон
painter->setPen(Qt::NoPen);
painter->setBrush(QColor(0, 0, 0, 180));
painter->drawRoundedRect(backgroundRect, 3, 3);
// Рисуем текст
painter->setPen(Qt::white);
int y = backgroundRect.top() + padding;
for (const QString& line : lines) {
painter->drawText(boxX + padding, y + fm.ascent(), line);
y += fm.height() + 2;
}
}
void SatelliteInfoRenderer::render(QPainter* painter, const QMatrix4x4& projection,
const QMatrix4x4& view, const QMatrix4x4& model,
const Satellite& satellite, const QSize& viewportSize)
{
QMatrix4x4 mvp = projection * view * model;
QPoint screenPos = worldToScreen(satellite.position, mvp, viewportSize);
if (screenPos.x() < 0 || screenPos.y() < 0 ||
screenPos.x() > viewportSize.width() || screenPos.y() > viewportSize.height())
return;
// Компактный формат информации
QString info = QString("%1\n%2").arg(satellite.id).arg(satellite.info);
painter->setRenderHint(QPainter::Antialiasing);
painter->setRenderHint(QPainter::TextAntialiasing);
drawInfoBox(painter, screenPos, info);
}