Wed, 25 May 2022 20:36:34 +0300
Fix pick() picking from weird places on the screen with high DPI scaling
glReadPixels reads data from the frame buffer, which contains data after
high DPI scaling, so any reads to that need to take this scaling into account
47 | 1 | #include <QMouseEvent> |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
2 | #include <QPainter> |
191
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
3 | #include "modeleditor.h" |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
4 | #include "document.h" |
47 | 5 | #include "canvas.h" |
6 | ||
7 | Canvas::Canvas( | |
8 | Model* model, | |
191
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
9 | Document *document, |
47 | 10 | DocumentManager* documents, |
11 | const ldraw::ColorTable& colorTable, | |
12 | QWidget* parent) : | |
191
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
13 | PartRenderer{model, documents, colorTable, parent}, |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
14 | document{document} |
47 | 15 | { |
16 | this->setMouseTracking(true); | |
17 | } | |
18 | ||
129 | 19 | /** |
20 | * @brief Handles a change of selection | |
21 | * @param selectedIds IDs of objects to select | |
22 | * @param deselectedIds IDs of objects to deselect. | |
23 | */ | |
73
97df974b5ed5
ldraw::Id is now templated for extra type safety
Teemu Piippo <teemu@hecknology.net>
parents:
71
diff
changeset
|
24 | void Canvas::handleSelectionChange(const QSet<ldraw::id_t>& selectedIds, const QSet<ldraw::id_t>& deselectedIds) |
51 | 25 | { |
52
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
26 | Q_ASSERT(not selectedIds.contains(ldraw::NULL_ID)); |
51 | 27 | this->selection.subtract(deselectedIds); |
28 | this->selection.unite(selectedIds); | |
189
815fbaae9cb2
cleanup, gl::Compiler changed to gl::ModelShaders
Teemu Piippo <teemu@hecknology.net>
parents:
188
diff
changeset
|
29 | gl::setModelShaderSelectedObjects(&this->shaders, this->selection); |
51 | 30 | this->update(); |
31 | } | |
32 | ||
129 | 33 | /** |
34 | * @brief Updates vertex rendering | |
35 | * @param document Document to get vertices from | |
36 | */ | |
118 | 37 | void Canvas::rebuildVertices(Document* document) |
38 | { | |
39 | if (this->vertexProgram.has_value()) | |
40 | { | |
41 | this->vertexProgram->build(document); | |
42 | this->update(); | |
43 | } | |
44 | } | |
45 | ||
47 | 46 | void Canvas::mouseMoveEvent(QMouseEvent* event) |
47 | { | |
73
97df974b5ed5
ldraw::Id is now templated for extra type safety
Teemu Piippo <teemu@hecknology.net>
parents:
71
diff
changeset
|
48 | 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
|
49 | this->highlighted = id; |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
50 | 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
|
51 | 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
|
52 | if (this->worldPosition.has_value()) |
55 | 53 | { |
65
87c906545fc3
document the grid snapping transformations
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
54 | /* |
87c906545fc3
document the grid snapping transformations
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
55 | * 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
|
56 | * 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
|
57 | * 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
|
58 | * 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
|
59 | * not a linear transformation, but fits the pattern anyway. |
87c906545fc3
document the grid snapping transformations
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
60 | */ |
87c906545fc3
document the grid snapping transformations
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
61 | // 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
|
62 | 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
|
63 | // Then round the coordinates to integer precision... |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
64 | this->worldPosition = glm::round(*this->worldPosition); |
65
87c906545fc3
document the grid snapping transformations
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
65 | // 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
|
66 | // grid matrix. |
64
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
67 | 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
|
68 | } |
197
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
69 | Q_EMIT this->mouseMove(event); |
47 | 70 | PartRenderer::mouseMoveEvent(event); |
121
000781318c36
added right click support for draw tool
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
71 | this->update(); |
47 | 72 | } |
51 | 73 | |
74 | void Canvas::mousePressEvent(QMouseEvent* event) | |
75 | { | |
76 | this->totalMouseMove = 0; | |
77 | this->lastMousePosition = event->pos(); | |
78 | PartRenderer::mousePressEvent(event); | |
79 | } | |
80 | ||
81 | void Canvas::mouseReleaseEvent(QMouseEvent* event) | |
82 | { | |
83 | if (this->totalMouseMove < (2.0 / sqrt(2)) * 5.0) | |
84 | { | |
197
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
85 | Q_EMIT this->mouseClick(event); |
51 | 86 | } |
87 | PartRenderer::mouseReleaseEvent(event); | |
121
000781318c36
added right click support for draw tool
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
88 | this->update(); |
51 | 89 | } |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
90 | |
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
91 | void Canvas::initializeGL() |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
92 | { |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
93 | // 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
|
94 | // 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
|
95 | this->gridProgram.emplace(this); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
96 | this->gridProgram->initialize(); |
70 | 97 | this->axesProgram.emplace(this); |
98 | this->axesProgram->initialize(); | |
118 | 99 | this->vertexProgram.emplace(this); |
100 | this->vertexProgram->initialize(); | |
70 | 101 | for (AbstractBasicShaderProgram* program : { |
102 | static_cast<AbstractBasicShaderProgram*>(&*this->gridProgram), | |
103 | static_cast<AbstractBasicShaderProgram*>(&*this->axesProgram), | |
118 | 104 | static_cast<AbstractBasicShaderProgram*>(&*this->vertexProgram), |
70 | 105 | }) |
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
106 | { |
70 | 107 | connect(this, &PartRenderer::projectionMatrixChanged, |
108 | program, &AbstractBasicShaderProgram::setProjectionMatrix); | |
109 | connect(this, &PartRenderer::modelMatrixChanged, | |
110 | program, &AbstractBasicShaderProgram::setModelMatrix); | |
111 | connect(this, &PartRenderer::viewMatrixChanged, | |
112 | program, &AbstractBasicShaderProgram::setViewMatrix); | |
113 | } | |
165
f6eab2bd46c2
fixed the grid not being black on startup if settings has bright background color
Teemu Piippo <teemu@hecknology.net>
parents:
164
diff
changeset
|
114 | connect(this, &PartRenderer::renderPreferencesChanged, this, &Canvas::updateCanvasRenderPreferences); |
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
115 | PartRenderer::initializeGL(); |
70 | 116 | // Set up XZ grid matrix |
129 | 117 | this->setGridMatrix({{1, 0, 0, 0}, {0, 0, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 1}}); |
165
f6eab2bd46c2
fixed the grid not being black on startup if settings has bright background color
Teemu Piippo <teemu@hecknology.net>
parents:
164
diff
changeset
|
118 | this->updateCanvasRenderPreferences(); |
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
119 | } |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
120 | |
191
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
121 | static const struct |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
122 | { |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
123 | const QBrush pointBrush = {Qt::white}; |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
124 | const QPen polygonPen = {QBrush{Qt::black}, 2.0, Qt::DashLine}; |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
125 | const QPen badPolygonPen = {QBrush{Qt::red}, 2.0, Qt::DashLine}; |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
126 | const QPen pointPen = {QBrush{Qt::black}, 2.0}; |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
127 | const QBrush greenPolygonBrush = {QColor{64, 255, 128, 192}}; |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
128 | const QBrush redPolygonBrush = {QColor{255, 96, 96, 192}}; |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
129 | } pens; |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
130 | |
197
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
131 | static void renderDrawState( |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
132 | QPainter* painter, |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
133 | Canvas* canvas, |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
134 | DrawState* drawState); |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
135 | |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
136 | void Canvas::paintGL() |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
137 | { |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
138 | PartRenderer::paintGL(); |
79
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
139 | if (this->renderPreferences.style != gl::RenderStyle::PickScene) |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
140 | { |
79
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
141 | // Render axes |
170
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
142 | if (this->renderPreferences.drawAxes) |
79
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
143 | { |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
144 | glLineWidth(5); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
145 | glEnable(GL_LINE_SMOOTH); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
146 | glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
147 | this->axesProgram->draw(); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
148 | glDisable(GL_LINE_SMOOTH); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
149 | } |
119 | 150 | // Render vertices |
151 | { | |
172
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
170
diff
changeset
|
152 | glCullFace(GL_FRONT); |
119 | 153 | this->vertexProgram->draw(); |
154 | } | |
79
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
155 | // Render grid |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
156 | { |
157 | 157 | glLineWidth(1); |
79
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
158 | glEnable(GL_BLEND); |
157 | 159 | glLineStipple(1, 0x8888); |
160 | glEnable(GL_LINE_STIPPLE); | |
79
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
161 | 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
|
162 | this->gridProgram->draw(); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
163 | glDisable(GL_BLEND); |
157 | 164 | glDisable(GL_LINE_STIPPLE); |
79
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 | if (this->worldPosition.has_value()) |
71
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
167 | { |
79
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
168 | QPainter painter{this}; |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
169 | painter.setRenderHint(QPainter::Antialiasing); |
166
8857351912d0
Fix rendering of cursor coordinates on bright background
Teemu Piippo <teemu@hecknology.net>
parents:
165
diff
changeset
|
170 | painter.setPen(this->isDark ? Qt::white : Qt::black); |
79
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
171 | painter.setBrush(Qt::green); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
172 | const QPointF pos = this->modelToScreenCoordinates(*this->worldPosition); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
173 | painter.drawEllipse(pos, 5, 5); |
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
174 | 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
|
175 | } |
191
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
176 | QPainter painter{this}; |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
177 | painter.setRenderHint(QPainter::Antialiasing); |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
178 | if (this->renderPreferences.drawAxes) |
79
5fe2dd4e161a
added a render style for pick scene
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
179 | { |
191
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
180 | this->renderAxesLabels(painter); |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
181 | } |
197
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
182 | if (this->drawState != nullptr) { |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
183 | renderDrawState(&painter, this, this->drawState); |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
184 | } |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
185 | } |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
186 | } |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
187 | |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
188 | static void renderDrawState( |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
189 | QPainter* painter, |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
190 | Canvas* canvas, |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
191 | DrawState* drawState) |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
192 | { |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
193 | switch(drawState->mode) |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
194 | { |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
195 | case SelectMode: |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
196 | break; |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
197 | case DrawMode: |
191
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
198 | { |
197
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
199 | painter->setPen(drawState->isconcave ? ::pens.badPolygonPen : ::pens.polygonPen); |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
200 | if (drawState->previewPolygon.size() > 2 and not drawState->isconcave) |
71
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
201 | { |
197
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
202 | if (canvas->worldPolygonWinding(drawState->previewPolygon) == Winding::Clockwise) |
191
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
203 | { |
197
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
204 | painter->setBrush(::pens.greenPolygonBrush); |
191
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
205 | } |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
206 | else |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
207 | { |
197
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
208 | painter->setBrush(::pens.redPolygonBrush); |
191
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
209 | } |
197
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
210 | canvas->drawWorldPolygon(painter, drawState->previewPolygon); |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
211 | } |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
212 | else |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
213 | { |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
214 | canvas->drawWorldPolyline(painter, drawState->previewPolygon); |
71
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
215 | } |
197
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
216 | painter->setBrush(::pens.pointBrush); |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
217 | painter->setPen(::pens.pointPen); |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
218 | for (const glm::vec3& point : drawState->polygon) |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
219 | { |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
220 | canvas->drawWorldPoint(painter, point); |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
221 | } |
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
222 | canvas->drawWorldPoint(painter, drawState->previewPoint); |
71
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
223 | } |
197
0e729e681a2c
move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents:
191
diff
changeset
|
224 | break; |
71
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
225 | } |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
226 | } |
64
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
227 | |
129 | 228 | /** |
170
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
229 | * @brief Renders labels such as +x at the ends of axes at the screen |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
230 | * @param painter |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
231 | */ |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
232 | void Canvas::renderAxesLabels(QPainter& painter) |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
233 | { |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
234 | QFont font; |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
235 | //font.setStyle(QFont::StyleItalic); |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
236 | painter.setFont(font); |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
237 | QFontMetrics fontMetrics{font}; |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
238 | const auto renderText = [&](const QString& text, const geom::PointOnRectagle& intersection) |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
239 | { |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
240 | QPointF position = toQPointF(intersection.position); |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
241 | const geom::RectangleSide side = intersection.side; |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
242 | switch (side) |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
243 | { |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
244 | case geom::RectangleSide::Top: |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
245 | position += QPointF{0, static_cast<qreal>(fontMetrics.ascent())}; |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
246 | break; |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
247 | case geom::RectangleSide::Left: |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
248 | break; |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
249 | case geom::RectangleSide::Bottom: |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
250 | position += QPointF{0, static_cast<qreal>(-fontMetrics.descent())}; |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
251 | break; |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
252 | case geom::RectangleSide::Right: |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
253 | position += QPointF{static_cast<qreal>(-fontMetrics.horizontalAdvance(text)), 0}; |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
254 | break; |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
255 | } |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
256 | painter.drawText(position, text); |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
257 | }; |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
258 | const QRectF box {QPointF{0, 0}, sizeToSizeF(this->size())}; |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
259 | const QPointF p1 = this->modelToScreenCoordinates(glm::vec3{0, 0, 0}); |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
260 | static const struct |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
261 | { |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
262 | QString text; |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
263 | glm::vec3 direction; |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
264 | } directions[] = |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
265 | { |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
266 | {"+𝑥", {1, 0, 0}}, |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
267 | {"-𝑥", {-1, 0, 0}}, |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
268 | {"+𝑦", {0, 1, 0}}, |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
269 | {"-𝑦", {0, -1, 0}}, |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
270 | {"+𝑧", {0, 0, 1}}, |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
271 | {"-𝑧", {0, 0, -1}}, |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
272 | }; |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
273 | for (const auto& axis : directions) |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
274 | { |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
275 | const QPointF x_p = this->modelToScreenCoordinates(axis.direction); |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
276 | const auto intersection = geom::rayRectangleIntersection( |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
277 | geom::rayFromPoints(toVec2(p1), toVec2(x_p)), |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
278 | box); |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
279 | if (intersection.has_value()) |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
280 | { |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
281 | renderText(axis.text, *intersection); |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
282 | } |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
283 | } |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
284 | } |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
285 | |
9b655f6fe5a1
Added a toggle for setting whether axes are drawn
Teemu Piippo <teemu@hecknology.net>
parents:
169
diff
changeset
|
286 | /** |
164
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
157
diff
changeset
|
287 | * @brief Draws a polyline to where the specified vector of 3D points would appear on the screen. |
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
157
diff
changeset
|
288 | * @param painter Painter to use to draw with |
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
157
diff
changeset
|
289 | * @param points 3D points to render |
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
157
diff
changeset
|
290 | */ |
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
157
diff
changeset
|
291 | void Canvas::drawWorldPolyline(QPainter *painter, const std::vector<glm::vec3> &points) |
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
157
diff
changeset
|
292 | { |
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
157
diff
changeset
|
293 | painter->drawPolyline(QPolygonF{this->convertWorldPointsToScreenPoints(points)}); |
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
157
diff
changeset
|
294 | } |
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
157
diff
changeset
|
295 | |
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
157
diff
changeset
|
296 | /** |
129 | 297 | * @brief Draws a polygon to where the specified vector of 3D points would appear on the screen. |
298 | * @param painter Painter to use to draw with | |
299 | * @param points 3D points to render | |
300 | */ | |
109
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
301 | void Canvas::drawWorldPolygon(QPainter* painter, const std::vector<glm::vec3> &points) |
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
302 | { |
164
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
157
diff
changeset
|
303 | painter->drawPolygon(QPolygonF{this->convertWorldPointsToScreenPoints(points)}); |
109
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
304 | } |
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
305 | |
168
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
166
diff
changeset
|
306 | Winding Canvas::worldPolygonWinding(const std::vector<glm::vec3> &points) const |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
166
diff
changeset
|
307 | { |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
166
diff
changeset
|
308 | return geom::winding(QPolygonF{this->convertWorldPointsToScreenPoints(points)}); |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
166
diff
changeset
|
309 | } |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
166
diff
changeset
|
310 | |
129 | 311 | /** |
312 | * @brief Gets the current position of the cursor in the model | |
313 | * @return 3D vector | |
314 | */ | |
110 | 315 | const std::optional<glm::vec3>& Canvas::getWorldPosition() const |
316 | { | |
317 | return this->worldPosition; | |
318 | } | |
319 | ||
128
7c834fe36b25
Moved automatic grid adjusting into a new action
Teemu Piippo <teemu@hecknology.net>
parents:
121
diff
changeset
|
320 | /** |
7c834fe36b25
Moved automatic grid adjusting into a new action
Teemu Piippo <teemu@hecknology.net>
parents:
121
diff
changeset
|
321 | * @brief Adjusts the grid to be so that it is perpendicular to the camera. |
7c834fe36b25
Moved automatic grid adjusting into a new action
Teemu Piippo <teemu@hecknology.net>
parents:
121
diff
changeset
|
322 | */ |
191
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
323 | void adjustGridToView(Canvas* canvas) |
128
7c834fe36b25
Moved automatic grid adjusting into a new action
Teemu Piippo <teemu@hecknology.net>
parents:
121
diff
changeset
|
324 | { |
191
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
325 | const glm::vec3 cameraDirection = canvas->cameraVector(); |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
326 | const glm::mat4& grid = canvas->getGridMatrix(); |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
327 | const glm::vec3 vector_x = glm::normalize(grid * glm::vec4{1, 0, 0, 1}); |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
328 | const glm::vec3 vector_y = glm::normalize(grid * glm::vec4{0, 1, 0, 1}); |
128
7c834fe36b25
Moved automatic grid adjusting into a new action
Teemu Piippo <teemu@hecknology.net>
parents:
121
diff
changeset
|
329 | const float angle_x = std::abs(glm::dot(vector_x, cameraDirection)); |
7c834fe36b25
Moved automatic grid adjusting into a new action
Teemu Piippo <teemu@hecknology.net>
parents:
121
diff
changeset
|
330 | const float angle_y = std::abs(glm::dot(vector_y, cameraDirection)); |
191
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
331 | canvas->setGridMatrix(glm::rotate( |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
332 | grid, |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
333 | pi<> * 0.5f, |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
334 | (angle_x < angle_y) ? glm::vec3{1, 0, 0} : glm::vec3{0, 1, 0} |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
335 | )); |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
189
diff
changeset
|
336 | canvas->update(); |
128
7c834fe36b25
Moved automatic grid adjusting into a new action
Teemu Piippo <teemu@hecknology.net>
parents:
121
diff
changeset
|
337 | } |
7c834fe36b25
Moved automatic grid adjusting into a new action
Teemu Piippo <teemu@hecknology.net>
parents:
121
diff
changeset
|
338 | |
129 | 339 | /** |
169
6da096930534
Added the delete action
Teemu Piippo <teemu@hecknology.net>
parents:
168
diff
changeset
|
340 | * @returns the ids of the currently selected objects |
6da096930534
Added the delete action
Teemu Piippo <teemu@hecknology.net>
parents:
168
diff
changeset
|
341 | */ |
6da096930534
Added the delete action
Teemu Piippo <teemu@hecknology.net>
parents:
168
diff
changeset
|
342 | const QSet<ldraw::id_t> Canvas::selectedObjects() const |
6da096930534
Added the delete action
Teemu Piippo <teemu@hecknology.net>
parents:
168
diff
changeset
|
343 | { |
6da096930534
Added the delete action
Teemu Piippo <teemu@hecknology.net>
parents:
168
diff
changeset
|
344 | return this->selection; |
6da096930534
Added the delete action
Teemu Piippo <teemu@hecknology.net>
parents:
168
diff
changeset
|
345 | } |
6da096930534
Added the delete action
Teemu Piippo <teemu@hecknology.net>
parents:
168
diff
changeset
|
346 | |
187 | 347 | const glm::mat4 &Canvas::getGridMatrix() const |
348 | { | |
349 | return this->gridMatrix; | |
350 | } | |
351 | ||
169
6da096930534
Added the delete action
Teemu Piippo <teemu@hecknology.net>
parents:
168
diff
changeset
|
352 | /** |
129 | 353 | * @brief Paints a circle at where @c worldPoint is located on the screen. |
354 | * @param painter Painter to use to render | |
355 | * @param worldPoint Point to render | |
356 | */ | |
109
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
357 | void Canvas::drawWorldPoint(QPainter* painter, const glm::vec3& worldPoint) const |
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
358 | { |
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
359 | const QPointF center = this->modelToScreenCoordinates(worldPoint); |
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
360 | painter->drawEllipse(geom::inscribe(geom::CircleF{center, 5})); |
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
361 | } |
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
362 | |
129 | 363 | /** |
364 | * @brief Changes the grid matrix to the one specified. Updates relevant member variables. | |
365 | * @param newMatrix New matrix to use | |
366 | */ | |
367 | void Canvas::setGridMatrix(const glm::mat4& newMatrix) | |
64
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
368 | { |
129 | 369 | this->gridMatrix = newMatrix; |
64
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
370 | const geom::Triangle triangle { |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
371 | 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
|
372 | 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
|
373 | 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
|
374 | }; |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
375 | this->gridPlane = geom::planeFromTriangle(triangle); |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
376 | this->gridProgram->setGridMatrix(this->gridMatrix); |
188
64ea7282611e
more work on circle tool + cleanup
Teemu Piippo <teemu@hecknology.net>
parents:
187
diff
changeset
|
377 | this->update(); |
64
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
61
diff
changeset
|
378 | } |
66
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
379 | |
129 | 380 | /** |
381 | * @brief Gets the current camera vector, i.e. the vector from the camera to the grid origin. | |
382 | * @return vector | |
383 | */ | |
67 | 384 | glm::vec3 Canvas::cameraVector() const |
385 | { | |
386 | // Find out where the grid is projected on the screen | |
387 | const QPoint gridOrigin2d = pointFToPoint(this->modelToScreenCoordinates(this->gridPlane.anchor)); | |
388 | // Find out which direction the camera is looking at the grid origin in 3d | |
389 | return glm::normalize(this->cameraLine(gridOrigin2d).direction); | |
390 | } | |
391 | ||
66
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
392 | /** |
129 | 393 | * @brief Calculates whether the screen is perpendicular to the current grid |
394 | * @return bool | |
66
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
395 | */ |
77c819262b7a
added a method to find out if the view is perpendicular to grid
Teemu Piippo <teemu@hecknology.net>
parents:
65
diff
changeset
|
396 | 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
|
397 | { |
67 | 398 | 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
|
399 | // 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
|
400 | // - 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
|
401 | // - 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
|
402 | // 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
|
403 | // 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
|
404 | // 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
|
405 | 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
|
406 | 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
|
407 | } |
105
6ca6e8c647d4
added preview layer code and fixed build warnings
Teemu Piippo <teemu@hecknology.net>
parents:
104
diff
changeset
|
408 | |
168
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
166
diff
changeset
|
409 | QVector<QPointF> Canvas::convertWorldPointsToScreenPoints(const std::vector<glm::vec3> &worldPoints) const |
164
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
157
diff
changeset
|
410 | { |
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
157
diff
changeset
|
411 | QVector<QPointF> points2d; |
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
157
diff
changeset
|
412 | points2d.reserve(worldPoints.size()); |
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
157
diff
changeset
|
413 | for (const glm::vec3& point : worldPoints) |
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
157
diff
changeset
|
414 | { |
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
157
diff
changeset
|
415 | points2d.push_back(this->modelToScreenCoordinates(point)); |
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
157
diff
changeset
|
416 | } |
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
157
diff
changeset
|
417 | return points2d; |
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
157
diff
changeset
|
418 | } |
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
157
diff
changeset
|
419 | |
165
f6eab2bd46c2
fixed the grid not being black on startup if settings has bright background color
Teemu Piippo <teemu@hecknology.net>
parents:
164
diff
changeset
|
420 | void Canvas::updateCanvasRenderPreferences() |
f6eab2bd46c2
fixed the grid not being black on startup if settings has bright background color
Teemu Piippo <teemu@hecknology.net>
parents:
164
diff
changeset
|
421 | { |
166
8857351912d0
Fix rendering of cursor coordinates on bright background
Teemu Piippo <teemu@hecknology.net>
parents:
165
diff
changeset
|
422 | this->isDark = luma(this->renderPreferences.backgroundColor) < 0.25; |
165
f6eab2bd46c2
fixed the grid not being black on startup if settings has bright background color
Teemu Piippo <teemu@hecknology.net>
parents:
164
diff
changeset
|
423 | if (this->gridProgram.has_value()) |
f6eab2bd46c2
fixed the grid not being black on startup if settings has bright background color
Teemu Piippo <teemu@hecknology.net>
parents:
164
diff
changeset
|
424 | { |
166
8857351912d0
Fix rendering of cursor coordinates on bright background
Teemu Piippo <teemu@hecknology.net>
parents:
165
diff
changeset
|
425 | this->gridProgram->setGridColor(this->isDark ? Qt::white : Qt::black); |
165
f6eab2bd46c2
fixed the grid not being black on startup if settings has bright background color
Teemu Piippo <teemu@hecknology.net>
parents:
164
diff
changeset
|
426 | } |
f6eab2bd46c2
fixed the grid not being black on startup if settings has bright background color
Teemu Piippo <teemu@hecknology.net>
parents:
164
diff
changeset
|
427 | } |
f6eab2bd46c2
fixed the grid not being black on startup if settings has bright background color
Teemu Piippo <teemu@hecknology.net>
parents:
164
diff
changeset
|
428 | |
109
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
429 | void Canvas::setOverpaintCallback(Canvas::OverpaintCallback fn) |
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
430 | { |
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
431 | this->overpaintCallback = fn; |
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
432 | } |