Tech ENABLE_RAYCAST_PICKING - Rendering for rectangle selection made only inside the rectangle, on systems supporting framebuffers

Various other refactorings & fixes

(cherry picked from commit prusa3d/PrusaSlicer@39b1222b22)
This commit is contained in:
enricoturri1966 2023-10-29 12:05:54 +08:00 committed by Noisyfox
parent f0199159e7
commit d2d77456ac
12 changed files with 289 additions and 105 deletions

View file

@ -106,6 +106,78 @@ void Camera::select_view(const std::string& direction)
}
}
double Camera::get_near_left() const
{
switch (m_type)
{
case EType::Perspective:
return m_frustrum_zs.first * (m_projection_matrix.matrix()(0, 2) - 1.0) / m_projection_matrix.matrix()(0, 0);
default:
case EType::Ortho:
return -1.0 / m_projection_matrix.matrix()(0, 0) - 0.5 * m_projection_matrix.matrix()(0, 0) * m_projection_matrix.matrix()(0, 3);
}
}
double Camera::get_near_right() const
{
switch (m_type)
{
case EType::Perspective:
return m_frustrum_zs.first * (m_projection_matrix.matrix()(0, 2) + 1.0) / m_projection_matrix.matrix()(0, 0);
default:
case EType::Ortho:
return 1.0 / m_projection_matrix.matrix()(0, 0) - 0.5 * m_projection_matrix.matrix()(0, 0) * m_projection_matrix.matrix()(0, 3);
}
}
double Camera::get_near_top() const
{
switch (m_type)
{
case EType::Perspective:
return m_frustrum_zs.first * (m_projection_matrix.matrix()(1, 2) + 1.0) / m_projection_matrix.matrix()(1, 1);
default:
case EType::Ortho:
return 1.0 / m_projection_matrix.matrix()(1, 1) - 0.5 * m_projection_matrix.matrix()(1, 1) * m_projection_matrix.matrix()(1, 3);
}
}
double Camera::get_near_bottom() const
{
switch (m_type)
{
case EType::Perspective:
return m_frustrum_zs.first * (m_projection_matrix.matrix()(1, 2) - 1.0) / m_projection_matrix.matrix()(1, 1);
default:
case EType::Ortho:
return -1.0 / m_projection_matrix.matrix()(1, 1) - 0.5 * m_projection_matrix.matrix()(1, 1) * m_projection_matrix.matrix()(1, 3);
}
}
double Camera::get_near_width() const
{
switch (m_type)
{
case EType::Perspective:
return 2.0 * m_frustrum_zs.first / m_projection_matrix.matrix()(0, 0);
default:
case EType::Ortho:
return 2.0 / m_projection_matrix.matrix()(0, 0);
}
}
double Camera::get_near_height() const
{
switch (m_type)
{
case EType::Perspective:
return 2.0 * m_frustrum_zs.first / m_projection_matrix.matrix()(1, 1);
default:
case EType::Ortho:
return 2.0 / m_projection_matrix.matrix()(1, 1);
}
}
double Camera::get_fov() const
{
switch (m_type)
@ -118,12 +190,16 @@ double Camera::get_fov() const
};
}
void Camera::apply_viewport(int x, int y, unsigned int w, unsigned int h)
void Camera::set_viewport(int x, int y, unsigned int w, unsigned int h)
{
glsafe(::glViewport(0, 0, w, h));
m_viewport = { 0, 0, int(w), int(h) };
}
void Camera::apply_viewport() const
{
glsafe(::glViewport(m_viewport[0], m_viewport[1], m_viewport[2], m_viewport[3]));
}
void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double far_z)
{
double w = 0.0;
@ -163,30 +239,33 @@ void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double fa
}
}
apply_projection(-w, w, -h, h, m_frustrum_zs.first, m_frustrum_zs.second);
}
void Camera::apply_projection(double left, double right, double bottom, double top, double near_z, double far_z)
{
assert(left != right && bottom != top && near_z != far_z);
const double inv_dx = 1.0 / (right - left);
const double inv_dy = 1.0 / (top - bottom);
const double inv_dz = 1.0 / (far_z - near_z);
switch (m_type)
{
default:
case EType::Ortho:
{
const double dz = m_frustrum_zs.second - m_frustrum_zs.first;
const double zz = m_frustrum_zs.first + m_frustrum_zs.second;
m_projection_matrix.matrix() << 1.0 / w, 0.0, 0.0, 0.0,
0.0, 1.0 / h, 0.0, 0.0,
0.0, 0.0, -2.0 / dz, -zz / dz,
0.0, 0.0, 0.0, 1.0;
m_projection_matrix.matrix() << 2.0 * inv_dx, 0.0, 0.0, -(left + right) * inv_dx,
0.0, 2.0 * inv_dy, 0.0, -(bottom + top) * inv_dy,
0.0, 0.0, -2.0 * inv_dz, -(near_z + far_z) * inv_dz,
0.0, 0.0, 0.0, 1.0;
break;
}
case EType::Perspective:
{
const double n = m_frustrum_zs.first;
const double f = m_frustrum_zs.second;
const double dz = f - n;
const double zz = n + f;
const double fn = n * f;
m_projection_matrix.matrix() << n / w, 0.0, 0.0, 0.0,
0.0, n / h, 0.0, 0.0,
0.0, 0.0, -zz / dz, -2.0 * fn / dz,
0.0, 0.0, -1.0, 0.0;
m_projection_matrix.matrix() << 2.0 * near_z * inv_dx, 0.0, (left + right) * inv_dx, 0.0,
0.0, 2.0 * near_z * inv_dy, (bottom + top) * inv_dy, 0.0,
0.0, 0.0, -(near_z + far_z) * inv_dz, -2.0 * near_z * far_z * inv_dz,
0.0, 0.0, -1.0, 0.0;
break;
}
}