src/gl/partrenderer.cpp

changeset 66
77c819262b7a
parent 61
4585d8d7a7ec
child 70
f21b800b02a4
equal deleted inserted replaced
65:87c906545fc3 66:77c819262b7a
279 * the camera, no value is returned. 279 * the camera, no value is returned.
280 * @param point 2D window co-ordinates to convert. 280 * @param point 2D window co-ordinates to convert.
281 * @param plane Plane to raycast against 281 * @param plane Plane to raycast against
282 * @return world co-ordinates, or no value if the point is behind the camera. 282 * @return world co-ordinates, or no value if the point is behind the camera.
283 */ 283 */
284 std::optional<glm::vec3> PartRenderer::screenToModelCoordinates(const QPoint& point, const geom::Plane& plane) 284 std::optional<glm::vec3> PartRenderer::screenToModelCoordinates(const QPoint& point, const geom::Plane& plane) const
285 { 285 {
286 const glm::vec3 p1 = this->unproject({point.x(), point.y(), 0}); 286 const geom::Line line = this->cameraLine(point);
287 const glm::vec3 p2 = this->unproject({point.x(), point.y(), 1});
288 const geom::Line line = geom::lineFromPoints(p1, p2);
289 std::optional<glm::vec3> result; 287 std::optional<glm::vec3> result;
290 result = geom::linePlaneIntersection(line, plane, 0.01f); 288 result = geom::linePlaneIntersection(line, plane, 0.01f);
291 // If the point lies behind the camera, do not return a result. 289 // If the point lies behind the camera, do not return a result.
292 if (result.has_value() and glm::dot(line.direction, *result - p1) < 0) 290 if (result.has_value() and glm::dot(line.direction, *result - line.anchor) < 0)
293 { 291 {
294 result.reset(); 292 result.reset();
295 } 293 }
296 return result; 294 return result;
297 } 295 }
299 /** 297 /**
300 * @brief Converts the specified point to 2D window coordinates, with Y-coordinate inverted for Qt 298 * @brief Converts the specified point to 2D window coordinates, with Y-coordinate inverted for Qt
301 * @param point Point to unproject 299 * @param point Point to unproject
302 * @return screen coordinates 300 * @return screen coordinates
303 */ 301 */
304 QPointF PartRenderer::modelToScreenCoordinates(const glm::vec3& point) 302 QPointF PartRenderer::modelToScreenCoordinates(const glm::vec3& point) const
305 { 303 {
306 const glm::vec3 projected = glm::project( 304 const glm::vec3 projected = glm::project(
307 point, 305 point,
308 this->viewMatrix * glm::mat4_cast(this->modelQuaternion), 306 this->viewMatrix * glm::mat4_cast(this->modelQuaternion),
309 this->projectionMatrix, 307 this->projectionMatrix,
310 this->viewportVector); 308 this->viewportVector);
311 return toQPointF(glm::vec2{projected.x, this->height() - projected.y}); 309 return toQPointF(glm::vec2{projected.x, this->height() - projected.y});
312 } 310 }
313 311
312 geom::Line PartRenderer::cameraLine(const QPoint& point) const
313 {
314 const glm::vec3 p1 = this->unproject({point.x(), point.y(), 0});
315 const glm::vec3 p2 = this->unproject({point.x(), point.y(), 1});
316 return geom::lineFromPoints(p1, p2);
317 }
318
314 /** 319 /**
315 * @brief Unprojects the specified window coordinates to model coordinates 320 * @brief Unprojects the specified window coordinates to model coordinates
316 * @param win Window coordinates to project. Z-coordinate indicates depth 321 * @param win Window coordinates to project. Z-coordinate indicates depth
317 * @return model coordinates 322 * @return model coordinates
318 */ 323 */
319 glm::vec3 PartRenderer::unproject(const glm::vec3& win) 324 glm::vec3 PartRenderer::unproject(const glm::vec3& win) const
320 { 325 {
321 return glm::unProject( 326 return glm::unProject(
322 glm::vec3{win.x, this->height() - win.y, win.z}, 327 glm::vec3{win.x, this->height() - win.y, win.z},
323 this->viewMatrix * glm::mat4_cast(this->modelQuaternion), 328 this->viewMatrix * glm::mat4_cast(this->modelQuaternion),
324 this->projectionMatrix, 329 this->projectionMatrix,

mercurial