Mon, 19 Jul 2021 19:28:16 +0300
Add connections
47 | 1 | #include <QMouseEvent> |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
2 | #include <QPainter> |
47 | 3 | #include "canvas.h" |
4 | ||
5 | Canvas::Canvas( | |
6 | Model* model, | |
7 | DocumentManager* documents, | |
8 | const ldraw::ColorTable& colorTable, | |
9 | QWidget* parent) : | |
70 | 10 | PartRenderer{model, documents, colorTable, parent} |
47 | 11 | { |
12 | this->setMouseTracking(true); | |
13 | } | |
14 | ||
73
97df974b5ed5
ldraw::Id is now templated for extra type safety
Teemu Piippo <teemu@hecknology.net>
parents:
71
diff
changeset
|
15 | void Canvas::handleSelectionChange(const QSet<ldraw::id_t>& selectedIds, const QSet<ldraw::id_t>& deselectedIds) |
51 | 16 | { |
52
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
17 | Q_ASSERT(not selectedIds.contains(ldraw::NULL_ID)); |
51 | 18 | this->selection.subtract(deselectedIds); |
19 | this->selection.unite(selectedIds); | |
20 | this->compiler->setSelectedObjects(this->selection); | |
21 | this->update(); | |
22 | } | |
23 | ||
47 | 24 | void Canvas::mouseMoveEvent(QMouseEvent* event) |
25 | { | |
73
97df974b5ed5
ldraw::Id is now templated for extra type safety
Teemu Piippo <teemu@hecknology.net>
parents:
71
diff
changeset
|
26 | const ldraw::id_t id = this->pick(event->pos()); |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
27 | this->highlighted = id; |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
28 | this->totalMouseMove += (event->pos() - this->lastMousePosition).manhattanLength(); |
64
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
29 | this->worldPosition = this->screenToModelCoordinates(event->pos(), this->gridPlane); |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
30 | if (this->worldPosition.has_value()) |
55 | 31 | { |
65
87c906545fc3
document the grid snapping transformations
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
32 | /* |
87c906545fc3
document the grid snapping transformations
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
33 | * Snap the position to grid. This procedure is basically the "change of basis" and almost follows the |
87c906545fc3
document the grid snapping transformations
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
34 | * Aโปยน ร M ร A formula which is used to perform a transformation in some other coordinate system, except |
87c906545fc3
document the grid snapping transformations
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
35 | * we actually use the inverted matrix first and the regular one last to perform the transformation of |
87c906545fc3
document the grid snapping transformations
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
36 | * grid coordinates in our XY coordinate system. Also, we're rounding the coordinates which is obviously |
87c906545fc3
document the grid snapping transformations
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
37 | * not a linear transformation, but fits the pattern anyway. |
87c906545fc3
document the grid snapping transformations
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
38 | */ |
87c906545fc3
document the grid snapping transformations
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
39 | // First transform the coordinates to the XY plane... |
64
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
40 | this->worldPosition = glm::inverse(this->gridMatrix) * glm::vec4{*this->worldPosition, 1}; |
65
87c906545fc3
document the grid snapping transformations
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
41 | // Then round the coordinates to integer precision... |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
42 | this->worldPosition = glm::round(*this->worldPosition); |
65
87c906545fc3
document the grid snapping transformations
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
43 | // And finally transform it back to grid coordinates by transforming it with the |
87c906545fc3
document the grid snapping transformations
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
44 | // grid matrix. |
64
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
45 | this->worldPosition = this->gridMatrix * glm::vec4{*this->worldPosition, 1}; |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
46 | } |
66
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
47 | /* |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
48 | if (this->worldPosition.has_value()) |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
49 | { |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
50 | this->newStatusText("Position: (%1, %2, %3)"_q |
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
51 | .arg(toDouble(this->worldPosition->x)) |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
52 | .arg(toDouble(this->worldPosition->y)) |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
53 | .arg(toDouble(this->worldPosition->z))); |
55 | 54 | } |
55 | else | |
56 | { | |
57 | this->newStatusText("Position: <none>"_q); | |
58 | } | |
66
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
59 | */ |
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
60 | // use a relatively high threshold so that we know when the grid is somewhat perpendicular so we can |
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
61 | // automatically change it properly |
67 | 62 | if (isGridPerpendicularToScreen(0.03f)) |
63 | { | |
64 | const glm::vec3 cameraDirection = this->cameraVector(); | |
65 | const glm::vec3 vector_x = glm::normalize(this->gridMatrix * glm::vec4{1, 0, 0, 1}); | |
66 | const glm::vec3 vector_y = glm::normalize(this->gridMatrix * glm::vec4{0, 1, 0, 1}); | |
67 | const float angle_x = std::abs(glm::dot(vector_x, cameraDirection)); | |
68 | const float angle_y = std::abs(glm::dot(vector_y, cameraDirection)); | |
69 | if (angle_x < angle_y) | |
70 | { | |
96 | 71 | this->gridMatrix = glm::rotate(this->gridMatrix, PI<float> / 2, glm::vec3{1, 0, 0}); |
67 | 72 | } |
73 | else | |
74 | { | |
96 | 75 | this->gridMatrix = glm::rotate(this->gridMatrix, PI<float> / 2, glm::vec3{0, 1, 0}); |
67 | 76 | } |
77 | this->updateGridMatrix(); | |
78 | this->update(); | |
79 | } | |
47 | 80 | PartRenderer::mouseMoveEvent(event); |
81 | } | |
51 | 82 | |
83 | void Canvas::mousePressEvent(QMouseEvent* event) | |
84 | { | |
85 | this->totalMouseMove = 0; | |
86 | this->lastMousePosition = event->pos(); | |
87 | PartRenderer::mousePressEvent(event); | |
88 | } | |
89 | ||
90 | void Canvas::mouseReleaseEvent(QMouseEvent* event) | |
91 | { | |
104 | 92 | MouseClickInfo info; |
93 | info.click = this->totalMouseMove < (2.0 / sqrt(2)) * 5.0; | |
94 | emit mouseClick(info); | |
51 | 95 | if (this->totalMouseMove < (2.0 / sqrt(2)) * 5.0) |
96 | { | |
52
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
97 | if (this->highlighted == ldraw::NULL_ID) |
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
98 | { |
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
99 | this->selection = {}; |
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
100 | } |
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
101 | else |
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
102 | { |
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
103 | this->selection = {this->highlighted}; |
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
104 | } |
51 | 105 | this->compiler->setSelectedObjects(this->selection); |
106 | emit selectionChanged(this->selection); | |
107 | this->update(); | |
108 | } | |
109 | PartRenderer::mouseReleaseEvent(event); | |
110 | } | |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
111 | |
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
112 | void Canvas::initializeGL() |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
113 | { |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
114 | // We first create the grid program and connect everything and only then call the part renderer's initialization |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
115 | // functions so that when initialization sets up, the signals also set up the matrices on our side. |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
116 | this->gridProgram.emplace(this); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
117 | this->gridProgram->initialize(); |
70 | 118 | this->axesProgram.emplace(this); |
119 | this->axesProgram->initialize(); | |
120 | for (AbstractBasicShaderProgram* program : { | |
121 | static_cast<AbstractBasicShaderProgram*>(&*this->gridProgram), | |
122 | static_cast<AbstractBasicShaderProgram*>(&*this->axesProgram), | |
123 | }) | |
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
124 | { |
70 | 125 | connect(this, &PartRenderer::projectionMatrixChanged, |
126 | program, &AbstractBasicShaderProgram::setProjectionMatrix); | |
127 | connect(this, &PartRenderer::modelMatrixChanged, | |
128 | program, &AbstractBasicShaderProgram::setModelMatrix); | |
129 | connect(this, &PartRenderer::viewMatrixChanged, | |
130 | program, &AbstractBasicShaderProgram::setViewMatrix); | |
131 | } | |
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
132 | connect(this, &PartRenderer::renderPreferencesChanged, [&]() |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
133 | { |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
134 | if (this->gridProgram.has_value()) |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
135 | { |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
136 | const bool isDark = luma(this->renderPreferences.backgroundColor) < 0.25; |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
137 | this->gridProgram->setGridColor(isDark ? Qt::white : Qt::black); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
138 | } |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
139 | }); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
140 | PartRenderer::initializeGL(); |
70 | 141 | // Set up XZ grid matrix |
68 | 142 | this->gridMatrix = glm::mat4{ |
143 | {1, 0, 0, 0}, | |
144 | {0, 0, 1, 0}, | |
145 | {0, 1, 0, 0}, | |
146 | {0, 0, 0, 1} | |
147 | }; | |
64
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
148 | this->updateGridMatrix(); |
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
149 | } |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
150 | |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
151 | void Canvas::paintGL() |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
152 | { |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
153 | PartRenderer::paintGL(); |
79
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
154 | if (this->renderPreferences.style != gl::RenderStyle::PickScene) |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
155 | { |
79
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
156 | // Render axes |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
157 | { |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
158 | glLineWidth(5); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
159 | glEnable(GL_LINE_SMOOTH); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
160 | glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
161 | this->axesProgram->draw(); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
162 | glDisable(GL_LINE_SMOOTH); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
163 | } |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
164 | // Render grid |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
165 | { |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
166 | glEnable(GL_BLEND); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
167 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
168 | this->gridProgram->draw(); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
169 | glDisable(GL_BLEND); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
170 | } |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
171 | if (this->worldPosition.has_value()) |
71
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
172 | { |
79
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
173 | QPainter painter{this}; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
174 | painter.setRenderHint(QPainter::Antialiasing); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
175 | painter.setPen(Qt::black); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
176 | painter.setBrush(Qt::green); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
177 | const QPointF pos = this->modelToScreenCoordinates(*this->worldPosition); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
178 | painter.drawEllipse(pos, 5, 5); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
179 | painter.setPen(Qt::white); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
180 | painter.drawText(pos + QPointF{5, 5}, vectorToString(*this->worldPosition)); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
181 | } |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
182 | { |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
183 | QPainter painter{this}; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
184 | QFont font; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
185 | //font.setStyle(QFont::StyleItalic); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
186 | painter.setFont(font); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
187 | QFontMetrics fontMetrics{font}; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
188 | const auto renderText = [&](const QString& text, const geom::PointOnRectagle& intersection) |
71
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
189 | { |
79
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
190 | QPointF position = toQPointF(intersection.position); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
191 | const geom::RectangleSide side = intersection.side; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
192 | switch (side) |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
193 | { |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
194 | case geom::RectangleSide::Top: |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
195 | position += QPointF{0, static_cast<qreal>(fontMetrics.ascent())}; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
196 | break; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
197 | case geom::RectangleSide::Left: |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
198 | break; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
199 | case geom::RectangleSide::Bottom: |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
200 | position += QPointF{0, static_cast<qreal>(-fontMetrics.descent())}; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
201 | break; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
202 | case geom::RectangleSide::Right: |
100 | 203 | position += QPointF{static_cast<qreal>(-fontMetrics.horizontalAdvance(text)), 0}; |
79
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
204 | break; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
205 | } |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
206 | painter.drawText(position, text); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
207 | }; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
208 | const QRectF box { |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
209 | QPointF{0, 0}, |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
210 | QPointF{static_cast<qreal>(this->width()), static_cast<qreal>(this->height())} |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
211 | }; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
212 | const QPointF p1 = this->modelToScreenCoordinates(glm::vec3{0, 0, 0}); |
71
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
213 | |
79
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
214 | static const struct |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
215 | { |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
216 | QString text; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
217 | glm::vec3 direction; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
218 | } directions[] = |
71
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
219 | { |
79
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
220 | {"+๐ฅ", {1, 0, 0}}, |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
221 | {"-๐ฅ", {-1, 0, 0}}, |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
222 | {"+๐ฆ", {0, 1, 0}}, |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
223 | {"-๐ฆ", {0, -1, 0}}, |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
224 | {"+๐ง", {0, 0, 1}}, |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
225 | {"-๐ง", {0, 0, -1}}, |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
226 | }; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
227 | for (const auto& axis : directions) |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
228 | { |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
229 | const QPointF x_p = this->modelToScreenCoordinates(axis.direction); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
230 | const auto intersection = geom::rayRectangleIntersection(geom::rayFromPoints(toVec2(p1), toVec2(x_p)), box); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
231 | if (intersection.has_value()) |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
232 | { |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
233 | renderText(axis.text, *intersection); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
234 | } |
71
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
235 | } |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
236 | } |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
237 | } |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
238 | } |
64
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
239 | |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
240 | void Canvas::updateGridMatrix() |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
241 | { |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
242 | const geom::Triangle triangle { |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
243 | this->gridMatrix * glm::vec4{0, 0, 0, 1}, |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
244 | this->gridMatrix * glm::vec4{1, 0, 0, 1}, |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
245 | this->gridMatrix * glm::vec4{0, 1, 0, 1}, |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
246 | }; |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
247 | this->gridPlane = geom::planeFromTriangle(triangle); |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
248 | this->gridProgram->setGridMatrix(this->gridMatrix); |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
249 | } |
66
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
250 | |
67 | 251 | glm::vec3 Canvas::cameraVector() const |
252 | { | |
253 | // Find out where the grid is projected on the screen | |
254 | const QPoint gridOrigin2d = pointFToPoint(this->modelToScreenCoordinates(this->gridPlane.anchor)); | |
255 | // Find out which direction the camera is looking at the grid origin in 3d | |
256 | return glm::normalize(this->cameraLine(gridOrigin2d).direction); | |
257 | } | |
258 | ||
66
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
259 | /** |
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
260 | * @brief Calculates if the screen is perpendicular to the current grid |
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
261 | * @return yes no |
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
262 | */ |
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
263 | bool Canvas::isGridPerpendicularToScreen(float threshold) const |
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
264 | { |
67 | 265 | const glm::vec3 cameraDirection = this->cameraVector(); |
66
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
266 | // Compute the dot product. The parameters given are: |
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
267 | // - the normal of the grid plane, which is the vector from the grid origin perpendicular to the grid |
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
268 | // - the direction of the camera looking at the grid, which is the inverse of the vector from the grid |
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
269 | // origin towards the camera |
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
270 | // If the dot product between these two vectors is 0, the grid normal is perpendicular to the camera vector |
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
271 | // and the grid is perpendicular to the screen. |
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
272 | const float dot = glm::dot(glm::normalize(this->gridPlane.normal), glm::normalize(cameraDirection)); |
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
273 | return std::abs(dot) < threshold; |
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
274 | } |