16 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 */ |
17 */ |
18 |
18 |
19 #include <glm/ext/matrix_transform.hpp> |
19 #include <glm/ext/matrix_transform.hpp> |
20 #include <glm/ext/matrix_clip_space.hpp> |
20 #include <glm/ext/matrix_clip_space.hpp> |
|
21 #include <QPainter> |
21 #include <GL/glu.h> |
22 #include <GL/glu.h> |
22 #include <QMouseEvent> |
23 #include <QMouseEvent> |
23 #include <QMessageBox> |
24 #include <QMessageBox> |
24 #include <QAbstractButton> |
25 #include <QAbstractButton> |
25 #include "geometry.h" |
26 #include "geometry.h" |
290 |
295 |
291 void PartRenderer::mouseMoveEvent(QMouseEvent* event) |
296 void PartRenderer::mouseMoveEvent(QMouseEvent* event) |
292 { |
297 { |
293 const bool left = event->buttons() & Qt::LeftButton; |
298 const bool left = event->buttons() & Qt::LeftButton; |
294 const QPoint move = event->pos() - this->lastMousePosition; |
299 const QPoint move = event->pos() - this->lastMousePosition; |
|
300 this->totalMouseMove += move.manhattanLength(); |
295 if (left and not move.isNull()) |
301 if (left and not move.isNull()) |
296 { |
302 { |
297 // q_x is the rotation of the brick along the vertical y-axis, because turning the |
303 // q_x is the rotation of the brick along the vertical y-axis, because turning the |
298 // vertical axis causes horizontal (=x) rotation. Likewise q_y is the rotation of the |
304 // vertical axis causes horizontal (=x) rotation. Likewise q_y is the rotation of the |
299 // brick along the horizontal x-axis, which causes vertical rotation. |
305 // brick along the horizontal x-axis, which causes vertical rotation. |
304 const glm::quat q_y = glm::angleAxis(scalar * move_y, glm::vec3{-1, 0, 0}); |
310 const glm::quat q_y = glm::angleAxis(scalar * move_y, glm::vec3{-1, 0, 0}); |
305 this->modelQuaternion = q_x * q_y * this->modelQuaternion; |
311 this->modelQuaternion = q_x * q_y * this->modelQuaternion; |
306 this->updateModelMatrix(); |
312 this->updateModelMatrix(); |
307 } |
313 } |
308 this->lastMousePosition = event->pos(); |
314 this->lastMousePosition = event->pos(); |
|
315 for (RenderLayer* layer : this->activeRenderLayers) { |
|
316 layer->mouseMoved(event); |
|
317 } |
|
318 this->update(); |
|
319 } |
|
320 |
|
321 void PartRenderer::mousePressEvent(QMouseEvent* event) |
|
322 { |
|
323 this->totalMouseMove = 0; |
|
324 this->lastMousePosition = event->pos(); |
|
325 } |
|
326 |
|
327 void PartRenderer::mouseReleaseEvent(QMouseEvent* event) |
|
328 { |
|
329 if (this->totalMouseMove < (2.0 / sqrt(2)) * 5.0) |
|
330 { |
|
331 for (RenderLayer* layer : this->activeRenderLayers) { |
|
332 layer->mouseClick(event); |
|
333 } |
|
334 this->update(); |
|
335 } |
309 } |
336 } |
310 |
337 |
311 void PartRenderer::wheelEvent(QWheelEvent* event) |
338 void PartRenderer::wheelEvent(QWheelEvent* event) |
312 { |
339 { |
313 static constexpr double WHEEL_STEP = 1 / 1000.0; |
340 static constexpr double WHEEL_STEP = 1 / 1000.0; |
362 */ |
390 */ |
363 QPointF PartRenderer::modelToScreenCoordinates(const glm::vec3& point) const |
391 QPointF PartRenderer::modelToScreenCoordinates(const glm::vec3& point) const |
364 { |
392 { |
365 const glm::vec3 projected = glm::project( |
393 const glm::vec3 projected = glm::project( |
366 point, |
394 point, |
367 this->viewMatrix * glm::mat4_cast(this->modelQuaternion), |
395 this->viewMatrix * this->modelMatrix, |
368 this->projectionMatrix, |
396 this->projectionMatrix, |
369 this->viewportVector); |
397 this->viewportVector); |
370 return toQPointF(glm::vec2{projected.x, this->height() - projected.y}); |
398 return toQPointF(glm::vec2{projected.x, this->height() - projected.y}); |
371 } |
399 } |
372 |
400 |
|
401 bool PartRenderer::isDark() const |
|
402 { |
|
403 return luma(this->renderPreferences.backgroundColor) < 0.25; |
|
404 } |
|
405 |
373 Line<3> PartRenderer::cameraLine(const QPointF& point) const |
406 Line<3> PartRenderer::cameraLine(const QPointF& point) const |
374 { |
407 { |
375 const glm::vec3 p1 = this->unproject({point.x(), point.y(), 0}); |
408 const glm::vec3 p1 = this->unproject({point.x(), point.y(), 0}); |
376 const glm::vec3 p2 = this->unproject({point.x(), point.y(), 1}); |
409 const glm::vec3 p2 = this->unproject({point.x(), point.y(), 1}); |
377 return lineFromPoints(p1, p2); |
410 return lineFromPoints(p1, p2); |
384 */ |
417 */ |
385 glm::vec3 PartRenderer::unproject(const glm::vec3& win) const |
418 glm::vec3 PartRenderer::unproject(const glm::vec3& win) const |
386 { |
419 { |
387 return glm::unProject( |
420 return glm::unProject( |
388 glm::vec3{win.x, this->height() - win.y, win.z}, |
421 glm::vec3{win.x, this->height() - win.y, win.z}, |
389 this->viewMatrix * glm::mat4_cast(this->modelQuaternion), |
422 this->viewMatrix * this->modelMatrix, |
390 this->projectionMatrix, |
423 this->projectionMatrix, |
391 viewportVector); |
424 viewportVector); |
392 } |
425 } |
393 |
426 |
394 ModelId PartRenderer::pick(QPoint where) |
427 ModelId PartRenderer::pick(QPoint where) |