69 this->update(); |
69 this->update(); |
70 } |
70 } |
71 |
71 |
72 void PartRenderer::resizeGL(int width, int height) |
72 void PartRenderer::resizeGL(int width, int height) |
73 { |
73 { |
|
74 this->viewportVector = {0, 0, width, height}; |
74 glViewport(0, 0, width, height); |
75 glViewport(0, 0, width, height); |
75 this->projectionMatrix = glm::perspective( |
76 this->projectionMatrix = glm::perspective( |
76 glm::radians(45.0f), |
77 glm::radians(45.0f), |
77 static_cast<float>(width) / static_cast<float>(height), |
78 static_cast<float>(width) / static_cast<float>(height), |
78 0.1f, |
79 0.1f, |
94 return GL_QUADS; |
95 return GL_QUADS; |
95 } |
96 } |
96 throw std::runtime_error{"Bad vbo class passed to getGlTypeForVboClass"}; |
97 throw std::runtime_error{"Bad vbo class passed to getGlTypeForVboClass"}; |
97 } |
98 } |
98 |
99 |
99 #include <QPainter> |
|
100 void PartRenderer::paintGL() |
100 void PartRenderer::paintGL() |
101 { |
101 { |
102 glEnable(GL_DEPTH_TEST); |
102 glEnable(GL_DEPTH_TEST); |
103 glShadeModel(GL_SMOOTH); |
103 glShadeModel(GL_SMOOTH); |
104 this->renderScene(); |
104 this->renderScene(); |
105 QPainter painter{this}; |
|
106 painter.setPen(Qt::white); |
|
107 painter.setBrush(Qt::red); |
|
108 for (float x : {1, -1}) |
|
109 { |
|
110 for (float y : {1, -1}) |
|
111 { |
|
112 for (float z : {1, -1}) |
|
113 { |
|
114 painter.drawEllipse(this->modelToScreenCoordinates({x, y, z}), 10, 10); |
|
115 } |
|
116 } |
|
117 } |
|
118 } |
105 } |
119 |
106 |
120 void PartRenderer::renderScene() |
107 void PartRenderer::renderScene() |
121 { |
108 { |
122 this->checkForGLErrors(); |
109 this->checkForGLErrors(); |
299 return viewport(point, this->width(), this->height()); |
286 return viewport(point, this->width(), this->height()); |
300 } |
287 } |
301 |
288 |
302 std::optional<glm::vec3> PartRenderer::screenToModelCoordinates(const QPoint& point) |
289 std::optional<glm::vec3> PartRenderer::screenToModelCoordinates(const QPoint& point) |
303 { |
290 { |
304 glm::vec3 pp = {point.x(), this->height() - point.y(), 1}; |
291 auto p1 = this->unproject({point.x(), point.y(), 0}); |
305 glm::mat4 matrix; |
292 auto p2 = this->unproject({point.x(), point.y(), 1}); |
306 matrix = this->projectionMatrix * this->viewMatrix * glm::mat4_cast(this->modelQuaternion); |
|
307 matrix = glm::transpose(glm::inverse(matrix)); |
|
308 auto p1 = matrix * glm::vec4{pp.x, pp.y, 0, 1}; |
|
309 auto p2 = matrix * glm::vec4{pp.x, pp.y, 1, 1}; |
|
310 geom::Line line = geom::lineFromPoints(p1, p2); |
293 geom::Line line = geom::lineFromPoints(p1, p2); |
311 return geom::linePlaneIntersection(line, geom::XY); |
294 return geom::linePlaneIntersection(line, geom::XY); |
312 } |
295 } |
313 |
296 |
314 QPointF PartRenderer::modelToScreenCoordinates(const glm::vec3& point) |
297 QPointF PartRenderer::modelToScreenCoordinates(const glm::vec3& point) |
319 p = this->projectionMatrix * p; |
302 p = this->projectionMatrix * p; |
320 glm::vec2 pp = this->viewport({p.x / p.w, p.y / p.w, 1}); |
303 glm::vec2 pp = this->viewport({p.x / p.w, p.y / p.w, 1}); |
321 return toQPointF(pp); |
304 return toQPointF(pp); |
322 } |
305 } |
323 |
306 |
|
307 glm::vec3 PartRenderer::unproject(const glm::vec3& win) |
|
308 { |
|
309 return glm::unProject( |
|
310 glm::vec3{win.x, this->height() - win.y, win.z}, |
|
311 this->viewMatrix * glm::mat4_cast(this->modelQuaternion), |
|
312 this->projectionMatrix, |
|
313 viewportVector); |
|
314 } |
|
315 |
324 ldraw::Id PartRenderer::pick(const QPoint& where) |
316 ldraw::Id PartRenderer::pick(const QPoint& where) |
325 { |
317 { |
326 const gl::RenderStyle oldRenderStyle = this->renderPreferences.style; |
318 const gl::RenderStyle oldRenderStyle = this->renderPreferences.style; |
327 this->renderPreferences.style = gl::RenderStyle::PickScene; |
319 this->renderPreferences.style = gl::RenderStyle::PickScene; |
328 this->makeCurrent(); |
320 this->makeCurrent(); |