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
117 | 1 | #include "vertexmap.h" |
2 | #include "linetypes/polygonobject.h" | |
3 | ||
120
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
4 | unsigned int hashVertex(const glm::vec3& vec) |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
5 | { |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
6 | return qHash(glm::ivec3{ |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
7 | int(vec.x * 10000), |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
8 | int(vec.y * 10000), |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
9 | int(vec.z * 10000), |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
10 | }); |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
11 | } |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
12 | |
117 | 13 | VertexMap::VertexMap(const Model *model) : |
14 | model{model} | |
15 | { | |
16 | connect( | |
17 | model, | |
18 | &Model::dataChanged, | |
19 | this, | |
20 | &VertexMap::build | |
21 | ); | |
22 | connect( | |
23 | model, | |
24 | &Model::rowsInserted, | |
25 | this, | |
26 | &VertexMap::build | |
27 | ); | |
28 | connect( | |
29 | model, | |
30 | &Model::rowsRemoved, | |
31 | this, | |
32 | &VertexMap::build | |
33 | ); | |
34 | this->build(); | |
35 | } | |
36 | ||
120
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
37 | struct Edge |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
38 | { |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
39 | const glm::vec3& a; |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
40 | const glm::vec3& b; |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
41 | }; |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
42 | |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
43 | inline void edges(const ldraw::Object* object, std::function<void(Edge&&)> fn) |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
44 | { |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
45 | for (int i = 0; i < object->numPoints() - 1; i += 1) |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
46 | { |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
47 | const glm::vec3 p1 = object->getPoint(i); |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
48 | const glm::vec3 p2 = object->getPoint((i + 1) % object->numPoints()); |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
49 | fn(Edge{p1, p2}); |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
50 | } |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
51 | } |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
52 | |
117 | 53 | void VertexMap::build() |
54 | { | |
55 | this->map.clear(); | |
118 | 56 | this->vertices.clear(); |
119 | 57 | this->vertexHashes.clear(); |
151 | 58 | applyToModel<ldraw::Object>(*this->model, [&](const ldraw::Object* object) |
117 | 59 | { |
120
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
60 | glm::mat4 matrix; |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
61 | if (object->numPoints() > 2) |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
62 | { |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
63 | const auto& p0 = object->getPoint(0); |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
64 | const auto& p1 = object->getPoint(1); |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
65 | const auto& p2 = object->getPoint(2); |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
66 | const glm::vec3 a = glm::normalize(p1 - p0); |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
67 | const glm::vec3 b = glm::normalize(p2 - p0); |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
68 | const glm::vec3 c = glm::normalize(glm::cross(a, b)); |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
69 | const glm::vec3 d = glm::normalize(glm::cross(a, c)); |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
70 | matrix = glm::mat4{{a, 0}, {-c, 0}, {d, 0}, {}}; |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
71 | } |
117 | 72 | for (int i = 0; i < object->numPoints(); i += 1) |
73 | { | |
74 | const glm::vec3& point = object->getPoint(i); | |
120
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
75 | const unsigned int hash = hashVertex(point); |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
76 | VertexInfo& info = this->map[hash]; |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
77 | info.point = point; |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
78 | info.objects.insert(object->id); |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
79 | if (object->numPoints() > 2 and not info.transformSet) |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
80 | { |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
81 | info.transform = matrix; |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
82 | info.transform[3] = {point, 1}; |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
83 | info.transformSet = true; |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
84 | } |
119 | 85 | if (not this->vertexHashes.contains(hash)) |
86 | { | |
87 | this->vertexHashes.insert(hash); | |
88 | this->vertices.push_back(point); | |
89 | } | |
117 | 90 | } |
91 | }); | |
120
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
92 | for (auto& pair : this->map) |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
93 | { |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
94 | auto& info = pair.second; |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
95 | // If there's no transformation calculated yet, make up a simple one that at least |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
96 | // contains translation. |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
97 | if (not info.transformSet) |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
98 | { |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
99 | info.transform = glm::translate(glm::identity<glm::mat4>(), info.point); |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
100 | info.transformSet = true; |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
101 | } |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
102 | float scale = 1.0f; |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
103 | for (const ldraw::id_t objectId : info.objects) |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
104 | { |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
105 | edges(model->get(objectId), [&](Edge&& edge) |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
106 | { |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
107 | if (hashVertex(edge.a) == pair.first or hashVertex(edge.b) == pair.first) |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
108 | { |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
109 | scale = std::min(scale, glm::length(edge.b - edge.a) / 3); |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
110 | } |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
111 | }); |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
112 | } |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
113 | info.transform = glm::scale(info.transform, glm::vec3{scale, scale, scale}); |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
114 | } |
118 | 115 | Q_EMIT this->verticesChanged(); |
117 | 116 | } |
118 | 117 | |
118 | /** | |
119 | * @brief Apply \c fn for all vertices in the map. | |
120 | * @param fn | |
121 | */ | |
122 | void VertexMap::apply(ApplyFunction fn) const | |
123 | { | |
119 | 124 | for (unsigned int i = 0; i < this->vertices.size(); i += 1) |
118 | 125 | { |
119 | 126 | const glm::vec3& point = this->vertices[i]; |
120
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
127 | fn(point, this->map.at(hashVertex(point))); |
118 | 128 | } |
129 | } |