Thu, 19 Mar 2020 21:06:06 +0200
PolygonObjectEditor can now modify the object properly
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 | { | |
71 | this->newStatusText("rotate by X axis"); | |
70 | 72 | this->gridMatrix = glm::rotate(this->gridMatrix, PIf / 2, glm::vec3{1, 0, 0}); |
67 | 73 | } |
74 | else | |
75 | { | |
76 | this->newStatusText("rotate by Y axis"); | |
70 | 77 | this->gridMatrix = glm::rotate(this->gridMatrix, PIf / 2, glm::vec3{0, 1, 0}); |
67 | 78 | } |
79 | this->updateGridMatrix(); | |
80 | this->update(); | |
81 | } | |
82 | else | |
83 | { | |
84 | this->newStatusText("don't rotate"); | |
85 | } | |
47 | 86 | PartRenderer::mouseMoveEvent(event); |
87 | } | |
51 | 88 | |
89 | void Canvas::mousePressEvent(QMouseEvent* event) | |
90 | { | |
91 | this->totalMouseMove = 0; | |
92 | this->lastMousePosition = event->pos(); | |
93 | PartRenderer::mousePressEvent(event); | |
94 | } | |
95 | ||
96 | void Canvas::mouseReleaseEvent(QMouseEvent* event) | |
97 | { | |
98 | if (this->totalMouseMove < (2.0 / sqrt(2)) * 5.0) | |
99 | { | |
52
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
100 | if (this->highlighted == ldraw::NULL_ID) |
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
101 | { |
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
102 | this->selection = {}; |
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
103 | } |
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
104 | else |
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
105 | { |
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
106 | this->selection = {this->highlighted}; |
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
107 | } |
51 | 108 | this->compiler->setSelectedObjects(this->selection); |
109 | emit selectionChanged(this->selection); | |
110 | this->update(); | |
111 | } | |
112 | PartRenderer::mouseReleaseEvent(event); | |
113 | } | |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
114 | |
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
115 | void Canvas::initializeGL() |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
116 | { |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
117 | // 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
|
118 | // 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
|
119 | this->gridProgram.emplace(this); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
120 | this->gridProgram->initialize(); |
70 | 121 | this->axesProgram.emplace(this); |
122 | this->axesProgram->initialize(); | |
123 | for (AbstractBasicShaderProgram* program : { | |
124 | static_cast<AbstractBasicShaderProgram*>(&*this->gridProgram), | |
125 | static_cast<AbstractBasicShaderProgram*>(&*this->axesProgram), | |
126 | }) | |
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
127 | { |
70 | 128 | connect(this, &PartRenderer::projectionMatrixChanged, |
129 | program, &AbstractBasicShaderProgram::setProjectionMatrix); | |
130 | connect(this, &PartRenderer::modelMatrixChanged, | |
131 | program, &AbstractBasicShaderProgram::setModelMatrix); | |
132 | connect(this, &PartRenderer::viewMatrixChanged, | |
133 | program, &AbstractBasicShaderProgram::setViewMatrix); | |
134 | } | |
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
135 | connect(this, &PartRenderer::renderPreferencesChanged, [&]() |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
136 | { |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
137 | if (this->gridProgram.has_value()) |
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 | const bool isDark = luma(this->renderPreferences.backgroundColor) < 0.25; |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
140 | this->gridProgram->setGridColor(isDark ? Qt::white : Qt::black); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
141 | } |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
142 | }); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
143 | PartRenderer::initializeGL(); |
70 | 144 | // Set up XZ grid matrix |
68 | 145 | this->gridMatrix = glm::mat4{ |
146 | {1, 0, 0, 0}, | |
147 | {0, 0, 1, 0}, | |
148 | {0, 1, 0, 0}, | |
149 | {0, 0, 0, 1} | |
150 | }; | |
64
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
151 | this->updateGridMatrix(); |
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
152 | } |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
153 | |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
154 | void Canvas::paintGL() |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
155 | { |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
156 | PartRenderer::paintGL(); |
79
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
157 | if (this->renderPreferences.style != gl::RenderStyle::PickScene) |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
158 | { |
79
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
159 | // Render axes |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
160 | { |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
161 | glLineWidth(5); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
162 | glEnable(GL_LINE_SMOOTH); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
163 | glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
164 | this->axesProgram->draw(); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
165 | glDisable(GL_LINE_SMOOTH); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
166 | } |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
167 | // Render grid |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
168 | { |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
169 | glEnable(GL_BLEND); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
170 | 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
|
171 | this->gridProgram->draw(); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
172 | glDisable(GL_BLEND); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
173 | } |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
174 | if (this->worldPosition.has_value()) |
71
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
175 | { |
79
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
176 | QPainter painter{this}; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
177 | painter.setRenderHint(QPainter::Antialiasing); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
178 | painter.setPen(Qt::black); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
179 | painter.setBrush(Qt::green); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
180 | const QPointF pos = this->modelToScreenCoordinates(*this->worldPosition); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
181 | painter.drawEllipse(pos, 5, 5); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
182 | painter.setPen(Qt::white); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
183 | 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
|
184 | } |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
185 | { |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
186 | QPainter painter{this}; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
187 | QFont font; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
188 | //font.setStyle(QFont::StyleItalic); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
189 | painter.setFont(font); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
190 | QFontMetrics fontMetrics{font}; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
191 | 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
|
192 | { |
79
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
193 | QPointF position = toQPointF(intersection.position); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
194 | const geom::RectangleSide side = intersection.side; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
195 | switch (side) |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
196 | { |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
197 | case geom::RectangleSide::Top: |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
198 | 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
|
199 | break; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
200 | case geom::RectangleSide::Left: |
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::Bottom: |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
203 | 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
|
204 | break; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
205 | case geom::RectangleSide::Right: |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
206 | position += QPointF{static_cast<qreal>(-fontMetrics.width(text)), 0}; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
207 | break; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
208 | } |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
209 | painter.drawText(position, text); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
210 | }; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
211 | const QRectF box { |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
212 | QPointF{0, 0}, |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
213 | 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
|
214 | }; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
215 | 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
|
216 | |
79
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
217 | static const struct |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
218 | { |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
219 | QString text; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
220 | glm::vec3 direction; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
221 | } directions[] = |
71
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
222 | { |
79
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
223 | {"+๐ฅ", {1, 0, 0}}, |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
224 | {"-๐ฅ", {-1, 0, 0}}, |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
225 | {"+๐ฆ", {0, 1, 0}}, |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
226 | {"-๐ฆ", {0, -1, 0}}, |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
227 | {"+๐ง", {0, 0, 1}}, |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
228 | {"-๐ง", {0, 0, -1}}, |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
229 | }; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
230 | for (const auto& axis : directions) |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
231 | { |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
232 | 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
|
233 | 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
|
234 | if (intersection.has_value()) |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
235 | { |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
236 | renderText(axis.text, *intersection); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
237 | } |
71
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
238 | } |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
239 | } |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
240 | } |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
241 | } |
64
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
242 | |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
243 | void Canvas::updateGridMatrix() |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
244 | { |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
245 | const geom::Triangle triangle { |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
246 | 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
|
247 | 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
|
248 | 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
|
249 | }; |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
250 | this->gridPlane = geom::planeFromTriangle(triangle); |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
251 | this->gridProgram->setGridMatrix(this->gridMatrix); |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
252 | } |
66
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
253 | |
67 | 254 | glm::vec3 Canvas::cameraVector() const |
255 | { | |
256 | // Find out where the grid is projected on the screen | |
257 | const QPoint gridOrigin2d = pointFToPoint(this->modelToScreenCoordinates(this->gridPlane.anchor)); | |
258 | // Find out which direction the camera is looking at the grid origin in 3d | |
259 | return glm::normalize(this->cameraLine(gridOrigin2d).direction); | |
260 | } | |
261 | ||
66
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 | * @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
|
264 | * @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
|
265 | */ |
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
266 | 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
|
267 | { |
67 | 268 | 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
|
269 | // 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
|
270 | // - 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
|
271 | // - 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
|
272 | // 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
|
273 | // 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
|
274 | // 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
|
275 | 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
|
276 | 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
|
277 | } |