src/gl/partrenderer.cpp

changeset 217
6d95c1a41e6e
parent 215
34c6e7bc4ee1
child 231
a9bf6bab5ea2
equal deleted inserted replaced
216:c7241f504117 217:6d95c1a41e6e
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"
130 glShadeModel(GL_SMOOTH); 131 glShadeModel(GL_SMOOTH);
131 this->renderScene(); 132 this->renderScene();
132 for (RenderLayer* layer : this->activeRenderLayers) { 133 for (RenderLayer* layer : this->activeRenderLayers) {
133 layer->paintGL(); 134 layer->paintGL();
134 } 135 }
136 QPainter painter{this};
137 for (RenderLayer* layer : this->activeRenderLayers) {
138 layer->overpaint(&painter);
139 }
135 } 140 }
136 141
137 void PartRenderer::renderScene() 142 void PartRenderer::renderScene()
138 { 143 {
139 if (this->needBuild) 144 if (this->needBuild)
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;
318 } 345 }
319 346
320 void PartRenderer::addRenderLayer(RenderLayer* layer) 347 void PartRenderer::addRenderLayer(RenderLayer* layer)
321 { 348 {
322 this->activeRenderLayers.push_back(layer); 349 this->activeRenderLayers.push_back(layer);
350 layer->setRendererPointer(this);
323 this->update(); 351 this->update();
324 } 352 }
325 353
326 void PartRenderer::setLayerEnabled(RenderLayer* layer, bool enabled) 354 void PartRenderer::setLayerEnabled(RenderLayer* layer, bool enabled)
327 { 355 {
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)
443 */ 476 */
444 ModelId PartRenderer::getHighlightedObject() const 477 ModelId PartRenderer::getHighlightedObject() const
445 { 478 {
446 return this->highlighted; 479 return this->highlighted;
447 } 480 }
481
482 void PartRenderer::setSelection(const QSet<ModelId>& selection)
483 {
484 Q_ASSERT(not selection.contains({0}));
485 gl::setModelShaderSelectedObjects(&this->shaders, selection);
486 this->update();
487 }

mercurial