src/ui/canvas.cpp

Wed, 25 May 2022 20:36:34 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Wed, 25 May 2022 20:36:34 +0300
changeset 199
6988973515d2
parent 198
eb9d900dc79a
child 200
ca23936b455b
permissions
-rw-r--r--

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
cd6704009eb9 picking works now
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
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
cd6704009eb9 picking works now
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
5 #include "canvas.h"
cd6704009eb9 picking works now
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
6
cd6704009eb9 picking works now
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
7 Canvas::Canvas(
cd6704009eb9 picking works now
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
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
cd6704009eb9 picking works now
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
10 DocumentManager* documents,
cd6704009eb9 picking works now
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
11 const ldraw::ColorTable& colorTable,
cd6704009eb9 picking works now
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
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
cd6704009eb9 picking works now
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
15 {
cd6704009eb9 picking works now
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
16 this->setMouseTracking(true);
cd6704009eb9 picking works now
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
17 }
cd6704009eb9 picking works now
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
18
129
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
19 /**
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
20 * @brief Handles a change of selection
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
21 * @param selectedIds IDs of objects to select
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
22 * @param deselectedIds IDs of objects to deselect.
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
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
1a9eac27698d selection works now
Teemu Piippo <teemu@hecknology.net>
parents: 48
diff changeset
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
1a9eac27698d selection works now
Teemu Piippo <teemu@hecknology.net>
parents: 48
diff changeset
27 this->selection.subtract(deselectedIds);
1a9eac27698d selection works now
Teemu Piippo <teemu@hecknology.net>
parents: 48
diff changeset
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
1a9eac27698d selection works now
Teemu Piippo <teemu@hecknology.net>
parents: 48
diff changeset
30 this->update();
1a9eac27698d selection works now
Teemu Piippo <teemu@hecknology.net>
parents: 48
diff changeset
31 }
1a9eac27698d selection works now
Teemu Piippo <teemu@hecknology.net>
parents: 48
diff changeset
32
129
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
33 /**
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
34 * @brief Updates vertex rendering
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
35 * @param document Document to get vertices from
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
36 */
118
8e1c9f18ae15 Add vertex rendering
Teemu Piippo <teemu@hecknology.net>
parents: 115
diff changeset
37 void Canvas::rebuildVertices(Document* document)
8e1c9f18ae15 Add vertex rendering
Teemu Piippo <teemu@hecknology.net>
parents: 115
diff changeset
38 {
8e1c9f18ae15 Add vertex rendering
Teemu Piippo <teemu@hecknology.net>
parents: 115
diff changeset
39 if (this->vertexProgram.has_value())
8e1c9f18ae15 Add vertex rendering
Teemu Piippo <teemu@hecknology.net>
parents: 115
diff changeset
40 {
8e1c9f18ae15 Add vertex rendering
Teemu Piippo <teemu@hecknology.net>
parents: 115
diff changeset
41 this->vertexProgram->build(document);
8e1c9f18ae15 Add vertex rendering
Teemu Piippo <teemu@hecknology.net>
parents: 115
diff changeset
42 this->update();
8e1c9f18ae15 Add vertex rendering
Teemu Piippo <teemu@hecknology.net>
parents: 115
diff changeset
43 }
8e1c9f18ae15 Add vertex rendering
Teemu Piippo <teemu@hecknology.net>
parents: 115
diff changeset
44 }
8e1c9f18ae15 Add vertex rendering
Teemu Piippo <teemu@hecknology.net>
parents: 115
diff changeset
45
47
cd6704009eb9 picking works now
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
46 void Canvas::mouseMoveEvent(QMouseEvent* event)
cd6704009eb9 picking works now
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
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
cb81ecb5fb23 grid stuff
Teemu Piippo <teemu@hecknology.net>
parents: 52
diff changeset
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
cd6704009eb9 picking works now
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
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
cd6704009eb9 picking works now
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
72 }
51
1a9eac27698d selection works now
Teemu Piippo <teemu@hecknology.net>
parents: 48
diff changeset
73
1a9eac27698d selection works now
Teemu Piippo <teemu@hecknology.net>
parents: 48
diff changeset
74 void Canvas::mousePressEvent(QMouseEvent* event)
1a9eac27698d selection works now
Teemu Piippo <teemu@hecknology.net>
parents: 48
diff changeset
75 {
1a9eac27698d selection works now
Teemu Piippo <teemu@hecknology.net>
parents: 48
diff changeset
76 this->totalMouseMove = 0;
1a9eac27698d selection works now
Teemu Piippo <teemu@hecknology.net>
parents: 48
diff changeset
77 this->lastMousePosition = event->pos();
1a9eac27698d selection works now
Teemu Piippo <teemu@hecknology.net>
parents: 48
diff changeset
78 PartRenderer::mousePressEvent(event);
1a9eac27698d selection works now
Teemu Piippo <teemu@hecknology.net>
parents: 48
diff changeset
79 }
1a9eac27698d selection works now
Teemu Piippo <teemu@hecknology.net>
parents: 48
diff changeset
80
1a9eac27698d selection works now
Teemu Piippo <teemu@hecknology.net>
parents: 48
diff changeset
81 void Canvas::mouseReleaseEvent(QMouseEvent* event)
1a9eac27698d selection works now
Teemu Piippo <teemu@hecknology.net>
parents: 48
diff changeset
82 {
1a9eac27698d selection works now
Teemu Piippo <teemu@hecknology.net>
parents: 48
diff changeset
83 if (this->totalMouseMove < (2.0 / sqrt(2)) * 5.0)
1a9eac27698d selection works now
Teemu Piippo <teemu@hecknology.net>
parents: 48
diff changeset
84 {
197
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
85 Q_EMIT this->mouseClick(event);
51
1a9eac27698d selection works now
Teemu Piippo <teemu@hecknology.net>
parents: 48
diff changeset
86 }
1a9eac27698d selection works now
Teemu Piippo <teemu@hecknology.net>
parents: 48
diff changeset
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
1a9eac27698d selection works now
Teemu Piippo <teemu@hecknology.net>
parents: 48
diff changeset
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
f21b800b02a4 Added axes rendering
Teemu Piippo <teemu@hecknology.net>
parents: 68
diff changeset
97 this->axesProgram.emplace(this);
f21b800b02a4 Added axes rendering
Teemu Piippo <teemu@hecknology.net>
parents: 68
diff changeset
98 this->axesProgram->initialize();
118
8e1c9f18ae15 Add vertex rendering
Teemu Piippo <teemu@hecknology.net>
parents: 115
diff changeset
99 this->vertexProgram.emplace(this);
8e1c9f18ae15 Add vertex rendering
Teemu Piippo <teemu@hecknology.net>
parents: 115
diff changeset
100 this->vertexProgram->initialize();
70
f21b800b02a4 Added axes rendering
Teemu Piippo <teemu@hecknology.net>
parents: 68
diff changeset
101 for (AbstractBasicShaderProgram* program : {
f21b800b02a4 Added axes rendering
Teemu Piippo <teemu@hecknology.net>
parents: 68
diff changeset
102 static_cast<AbstractBasicShaderProgram*>(&*this->gridProgram),
f21b800b02a4 Added axes rendering
Teemu Piippo <teemu@hecknology.net>
parents: 68
diff changeset
103 static_cast<AbstractBasicShaderProgram*>(&*this->axesProgram),
118
8e1c9f18ae15 Add vertex rendering
Teemu Piippo <teemu@hecknology.net>
parents: 115
diff changeset
104 static_cast<AbstractBasicShaderProgram*>(&*this->vertexProgram),
70
f21b800b02a4 Added axes rendering
Teemu Piippo <teemu@hecknology.net>
parents: 68
diff changeset
105 })
61
4585d8d7a7ec moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents: 58
diff changeset
106 {
70
f21b800b02a4 Added axes rendering
Teemu Piippo <teemu@hecknology.net>
parents: 68
diff changeset
107 connect(this, &PartRenderer::projectionMatrixChanged,
f21b800b02a4 Added axes rendering
Teemu Piippo <teemu@hecknology.net>
parents: 68
diff changeset
108 program, &AbstractBasicShaderProgram::setProjectionMatrix);
f21b800b02a4 Added axes rendering
Teemu Piippo <teemu@hecknology.net>
parents: 68
diff changeset
109 connect(this, &PartRenderer::modelMatrixChanged,
f21b800b02a4 Added axes rendering
Teemu Piippo <teemu@hecknology.net>
parents: 68
diff changeset
110 program, &AbstractBasicShaderProgram::setModelMatrix);
f21b800b02a4 Added axes rendering
Teemu Piippo <teemu@hecknology.net>
parents: 68
diff changeset
111 connect(this, &PartRenderer::viewMatrixChanged,
f21b800b02a4 Added axes rendering
Teemu Piippo <teemu@hecknology.net>
parents: 68
diff changeset
112 program, &AbstractBasicShaderProgram::setViewMatrix);
f21b800b02a4 Added axes rendering
Teemu Piippo <teemu@hecknology.net>
parents: 68
diff changeset
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
f21b800b02a4 Added axes rendering
Teemu Piippo <teemu@hecknology.net>
parents: 68
diff changeset
116 // Set up XZ grid matrix
129
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
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
Teemu Piippo <teemu@hecknology.net>
parents: 118
diff changeset
150 // Render vertices
Teemu Piippo <teemu@hecknology.net>
parents: 118
diff changeset
151 {
172
50f055543ff6 Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents: 170
diff changeset
152 glCullFace(GL_FRONT);
119
Teemu Piippo <teemu@hecknology.net>
parents: 118
diff changeset
153 this->vertexProgram->draw();
Teemu Piippo <teemu@hecknology.net>
parents: 118
diff changeset
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
869fe95c4e5e improve grid rendering
Teemu Piippo <teemu@hecknology.net>
parents: 129
diff changeset
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
869fe95c4e5e improve grid rendering
Teemu Piippo <teemu@hecknology.net>
parents: 129
diff changeset
159 glLineStipple(1, 0x8888);
869fe95c4e5e improve grid rendering
Teemu Piippo <teemu@hecknology.net>
parents: 129
diff changeset
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
869fe95c4e5e improve grid rendering
Teemu Piippo <teemu@hecknology.net>
parents: 129
diff changeset
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
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
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
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
297 * @brief Draws a polygon to where the specified vector of 3D points would appear on the screen.
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
298 * @param painter Painter to use to draw with
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
299 * @param points 3D points to render
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
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
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
311 /**
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
312 * @brief Gets the current position of the cursor in the model
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
313 * @return 3D vector
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
314 */
110
Teemu Piippo <teemu@hecknology.net>
parents: 109
diff changeset
315 const std::optional<glm::vec3>& Canvas::getWorldPosition() const
Teemu Piippo <teemu@hecknology.net>
parents: 109
diff changeset
316 {
Teemu Piippo <teemu@hecknology.net>
parents: 109
diff changeset
317 return this->worldPosition;
Teemu Piippo <teemu@hecknology.net>
parents: 109
diff changeset
318 }
Teemu Piippo <teemu@hecknology.net>
parents: 109
diff changeset
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
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
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
30204975694a work on circle tool
Teemu Piippo <teemu@hecknology.net>
parents: 172
diff changeset
347 const glm::mat4 &Canvas::getGridMatrix() const
30204975694a work on circle tool
Teemu Piippo <teemu@hecknology.net>
parents: 172
diff changeset
348 {
30204975694a work on circle tool
Teemu Piippo <teemu@hecknology.net>
parents: 172
diff changeset
349 return this->gridMatrix;
30204975694a work on circle tool
Teemu Piippo <teemu@hecknology.net>
parents: 172
diff changeset
350 }
30204975694a work on circle tool
Teemu Piippo <teemu@hecknology.net>
parents: 172
diff changeset
351
169
6da096930534 Added the delete action
Teemu Piippo <teemu@hecknology.net>
parents: 168
diff changeset
352 /**
129
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
353 * @brief Paints a circle at where @c worldPoint is located on the screen.
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
354 * @param painter Painter to use to render
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
355 * @param worldPoint Point to render
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
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
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
363 /**
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
364 * @brief Changes the grid matrix to the one specified. Updates relevant member variables.
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
365 * @param newMatrix New matrix to use
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
366 */
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
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
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
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
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
380 /**
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
381 * @brief Gets the current camera vector, i.e. the vector from the camera to the grid origin.
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
382 * @return vector
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
383 */
67
612213a168da grid autorotation
Teemu Piippo <teemu@hecknology.net>
parents: 66
diff changeset
384 glm::vec3 Canvas::cameraVector() const
612213a168da grid autorotation
Teemu Piippo <teemu@hecknology.net>
parents: 66
diff changeset
385 {
612213a168da grid autorotation
Teemu Piippo <teemu@hecknology.net>
parents: 66
diff changeset
386 // Find out where the grid is projected on the screen
612213a168da grid autorotation
Teemu Piippo <teemu@hecknology.net>
parents: 66
diff changeset
387 const QPoint gridOrigin2d = pointFToPoint(this->modelToScreenCoordinates(this->gridPlane.anchor));
612213a168da grid autorotation
Teemu Piippo <teemu@hecknology.net>
parents: 66
diff changeset
388 // Find out which direction the camera is looking at the grid origin in 3d
612213a168da grid autorotation
Teemu Piippo <teemu@hecknology.net>
parents: 66
diff changeset
389 return glm::normalize(this->cameraLine(gridOrigin2d).direction);
612213a168da grid autorotation
Teemu Piippo <teemu@hecknology.net>
parents: 66
diff changeset
390 }
612213a168da grid autorotation
Teemu Piippo <teemu@hecknology.net>
parents: 66
diff changeset
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
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
393 * @brief Calculates whether the screen is perpendicular to the current grid
f35843351601 Add documentation
Teemu Piippo <teemu@hecknology.net>
parents: 128
diff changeset
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
612213a168da grid autorotation
Teemu Piippo <teemu@hecknology.net>
parents: 66
diff changeset
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 }

mercurial