20 #include <glm/ext/matrix_transform.hpp> |
20 #include <glm/ext/matrix_transform.hpp> |
21 #include <glm/ext/matrix_clip_space.hpp> |
21 #include <glm/ext/matrix_clip_space.hpp> |
22 #include <QMouseEvent> |
22 #include <QMouseEvent> |
23 #include <QMessageBox> |
23 #include <QMessageBox> |
24 #include <QAbstractButton> |
24 #include <QAbstractButton> |
|
25 #include "geometry.h" |
25 #include "partrenderer.h" |
26 #include "partrenderer.h" |
26 |
27 |
27 PartRenderer::PartRenderer( |
28 PartRenderer::PartRenderer( |
28 Model* model, |
29 Model* model, |
29 DocumentManager* documents, |
30 DocumentManager* documents, |
60 this->compiler->initialize(); |
61 this->compiler->initialize(); |
61 this->compiler->build(this->model, this->documents, this->renderPreferences); |
62 this->compiler->build(this->model, this->documents, this->renderPreferences); |
62 this->initialized = true; |
63 this->initialized = true; |
63 this->modelQuaternion = glm::angleAxis(glm::radians(30.0f), glm::vec3{-1, 0, 0}); |
64 this->modelQuaternion = glm::angleAxis(glm::radians(30.0f), glm::vec3{-1, 0, 0}); |
64 this->modelQuaternion *= glm::angleAxis(glm::radians(225.0f), glm::vec3{-0, 1, 0}); |
65 this->modelQuaternion *= glm::angleAxis(glm::radians(225.0f), glm::vec3{-0, 1, 0}); |
|
66 this->setupBackgroundColor(); |
|
67 this->updateModelMatrix(); |
65 this->updateViewMatrix(); |
68 this->updateViewMatrix(); |
66 this->update(); |
69 this->update(); |
67 } |
70 } |
68 |
71 |
69 void PartRenderer::resizeGL(int width, int height) |
72 void PartRenderer::resizeGL(int width, int height) |
70 { |
73 { |
71 glViewport(0, 0, width, height); |
74 glViewport(0, 0, width, height); |
|
75 this->viewportMatrix = { |
|
76 {1, 0, 0}, |
|
77 {0, 1, 0}, |
|
78 {width * 0.5f, height * 0.5f, 1} |
|
79 }; |
72 this->projectionMatrix = glm::perspective( |
80 this->projectionMatrix = glm::perspective( |
73 glm::radians(45.0f), |
81 glm::radians(45.0f), |
74 static_cast<float>(width) / static_cast<float>(height), |
82 static_cast<float>(width) / static_cast<float>(height), |
75 0.1f, |
83 0.1f, |
76 10000.f); |
84 10000.f); |
192 this->viewMatrix = glm::lookAt(glm::vec3{0, 0, z}, {0, 0, 0}, {0, -1, 0}); |
200 this->viewMatrix = glm::lookAt(glm::vec3{0, 0, z}, {0, 0, 0}, {0, -1, 0}); |
193 this->compiler->setUniformMatrix("viewMatrix", this->viewMatrix); |
201 this->compiler->setUniformMatrix("viewMatrix", this->viewMatrix); |
194 this->gridProgram->setViewMatrix(this->viewMatrix); |
202 this->gridProgram->setViewMatrix(this->viewMatrix); |
195 } |
203 } |
196 |
204 |
|
205 void PartRenderer::updateModelMatrix() |
|
206 { |
|
207 const glm::mat4 modelMatrix = glm::mat4_cast(this->modelQuaternion); |
|
208 this->compiler->setUniformMatrix("modelMatrix", modelMatrix); |
|
209 this->gridProgram->setModelMatrix(modelMatrix); |
|
210 this->update(); |
|
211 } |
|
212 |
|
213 void PartRenderer::setupBackgroundColor() |
|
214 { |
|
215 if (this->gridProgram.has_value()) |
|
216 { |
|
217 const bool isDark = luma(this->renderPreferences.backgroundColor) < 0.25; |
|
218 this->gridProgram->setGridColor(isDark ? Qt::white : Qt::black); |
|
219 } |
|
220 } |
|
221 |
197 void PartRenderer::renderVao(const gl::ArrayClass arrayClass) |
222 void PartRenderer::renderVao(const gl::ArrayClass arrayClass) |
198 { |
223 { |
199 this->compiler->bindVertexArray(arrayClass); |
224 this->compiler->bindVertexArray(arrayClass); |
200 const std::size_t vertexCount = this->compiler->vertexCount(arrayClass); |
225 const std::size_t vertexCount = this->compiler->vertexCount(arrayClass); |
201 this->checkForGLErrors(); |
226 this->checkForGLErrors(); |
244 const float move_x = static_cast<float>(move.x()); |
269 const float move_x = static_cast<float>(move.x()); |
245 const float move_y = static_cast<float>(move.y()); |
270 const float move_y = static_cast<float>(move.y()); |
246 const glm::quat q_x = glm::angleAxis(scalar * move_x, glm::vec3{0, -1, 0}); |
271 const glm::quat q_x = glm::angleAxis(scalar * move_x, glm::vec3{0, -1, 0}); |
247 const glm::quat q_y = glm::angleAxis(scalar * move_y, glm::vec3{-1, 0, 0}); |
272 const glm::quat q_y = glm::angleAxis(scalar * move_y, glm::vec3{-1, 0, 0}); |
248 this->modelQuaternion = q_x * q_y * this->modelQuaternion; |
273 this->modelQuaternion = q_x * q_y * this->modelQuaternion; |
249 const glm::mat4 modelMatrix = glm::mat4_cast(this->modelQuaternion); |
274 this->updateModelMatrix(); |
250 this->compiler->setUniformMatrix("modelMatrix", modelMatrix); |
|
251 this->gridProgram->setModelMatrix(modelMatrix); |
|
252 this->update(); |
|
253 } |
275 } |
254 this->lastMousePosition = pointToPointF(event->pos()); |
276 this->lastMousePosition = pointToPointF(event->pos()); |
255 } |
277 } |
256 |
278 |
257 void PartRenderer::wheelEvent(QWheelEvent* event) |
279 void PartRenderer::wheelEvent(QWheelEvent* event) |
259 static constexpr double WHEEL_STEP = 1 / 1000.0; |
281 static constexpr double WHEEL_STEP = 1 / 1000.0; |
260 const double move = (-event->angleDelta().y()) * WHEEL_STEP; |
282 const double move = (-event->angleDelta().y()) * WHEEL_STEP; |
261 this->zoom = std::clamp(this->zoom + move, MIN_ZOOM, MAX_ZOOM); |
283 this->zoom = std::clamp(this->zoom + move, MIN_ZOOM, MAX_ZOOM); |
262 this->updateViewMatrix(); |
284 this->updateViewMatrix(); |
263 this->update(); |
285 this->update(); |
|
286 } |
|
287 |
|
288 std::optional<glm::vec3> PartRenderer::cameraToGrid(const QPoint& point) |
|
289 { |
|
290 glm::vec3 pp = {point.x(), this->height() - point.y(), 1}; |
|
291 pp = glm::inverse(this->viewportMatrix) * pp; |
|
292 glm::mat4 matrix; |
|
293 matrix = this->projectionMatrix * this->viewMatrix * glm::mat4_cast(this->modelQuaternion); |
|
294 matrix = glm::transpose(glm::inverse(matrix)); |
|
295 auto p1 = matrix * glm::vec4{pp.x, pp.y, 0, 1}; |
|
296 auto p2 = matrix * glm::vec4{pp.x, pp.y, 1, 1}; |
|
297 geom::Line line = geom::lineFromPoints(p1, p2); |
|
298 return geom::linePlaneIntersection(line, geom::XY); |
|
299 } |
|
300 |
|
301 QPointF PartRenderer::worldToCamera(const glm::vec3& point) |
|
302 { |
|
303 glm::vec4 p = {point, 1}; |
|
304 p = glm::mat4_cast(this->modelQuaternion) * p; |
|
305 p = this->viewMatrix * p; |
|
306 p = this->projectionMatrix * p; |
|
307 glm::vec2 pp = this->viewportMatrix * glm::vec3{p.x, p.y, 1}; |
|
308 return toQPointF(pp); |
|
309 /* |
|
310 const glm::mat4 matrix = this->projectionMatrix * this->viewMatrix * glm::mat4_cast(this->modelQuaternion); |
|
311 return toQPointF(matrix * glm::vec4{point, 1}); |
|
312 */ |
264 } |
313 } |
265 |
314 |
266 ldraw::Id PartRenderer::pick(const QPoint& where) |
315 ldraw::Id PartRenderer::pick(const QPoint& where) |
267 { |
316 { |
268 const gl::RenderStyle oldRenderStyle = this->renderPreferences.style; |
317 const gl::RenderStyle oldRenderStyle = this->renderPreferences.style; |
297 bool backgroundColorChanged = this->renderPreferences.backgroundColor != newPreferences.backgroundColor; |
346 bool backgroundColorChanged = this->renderPreferences.backgroundColor != newPreferences.backgroundColor; |
298 this->renderPreferences = newPreferences; |
347 this->renderPreferences = newPreferences; |
299 if (mainColorChanged or backgroundColorChanged) |
348 if (mainColorChanged or backgroundColorChanged) |
300 { |
349 { |
301 this->compiler->build(this->model, this->documents, this->renderPreferences); |
350 this->compiler->build(this->model, this->documents, this->renderPreferences); |
302 } |
351 this->setupBackgroundColor(); |
303 this->update(); |
352 |
304 } |
353 } |
|
354 this->update(); |
|
355 } |