FIX:calculate frustum of ortho view

jira: none
Change-Id: Ia0c30ebd9366ae1dfc5cdd555aa9f89a9dd878f1
This commit is contained in:
zhou.xu 2024-08-12 17:23:33 +08:00 committed by Lane.Wei
parent b7ab08e65b
commit 10e41fbd07
4 changed files with 42 additions and 9 deletions

View File

@ -51,10 +51,13 @@ Frustum::Plane::PlaneIntersects Frustum::Plane::intersects(const Vec3f &p0, cons
return Plane::Intersects_Tangent;
}
bool Frustum::intersects(const BoundingBoxf3 &box) const {
for (auto &plane : planes) {
if (plane.intersects(box) == Plane::Intersects_Back) {
return false;
bool Frustum::intersects(const BoundingBoxf3 &box, bool is_perspective) const
{
if (is_perspective) {
for (auto &plane : planes) {
if (plane.intersects(box) == Plane::Intersects_Back) {
return false;
}
}
}
// check box intersects

View File

@ -37,7 +37,7 @@ public:
float d_ = 0;
};
bool intersects(const BoundingBoxf3 &box) const;
bool intersects(const BoundingBoxf3 &box, bool is_perspective) const;
// check intersect with point (world space)
bool intersects(const Vec3f &p0) const;
// check intersect with line segment (world space)

View File

@ -1555,7 +1555,7 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type,
auto camera = GUI::wxGetApp().plater()->get_camera();
for (GLVolumeWithIdAndZ& volume : to_render) {
auto world_box = volume.first->transformed_bounding_box();
if (!camera.getFrustum().intersects(world_box)) {
if (!camera.getFrustum().intersects(world_box, camera.get_type_as_string() == "perspective")) {
continue;
}
#if ENABLE_MODIFIERS_ALWAYS_TRANSPARENT

View File

@ -151,9 +151,9 @@ void Camera::update_frustum()
float aspect_ = m_viewport[2] / (double)m_viewport[3];
float fov_ = (float) Geometry::deg2rad(get_fov());
float eps = 0.01;
if (m_last_eye.isApprox(eye_) && m_last_center.isApprox(center_) && m_last_up.isApprox(up_) &&
abs(m_last_near - near_) > eps && abs(m_last_far - far_) > eps &&
abs(m_last_aspect - aspect_) > eps && abs(m_last_fov - fov_) > eps) {
if (m_last_eye.isApprox(eye_) && m_last_center.isApprox(center_) && m_last_up.isApprox(up_)
&& abs(m_last_near - near_) < eps && abs(m_last_far - far_) < eps &&
abs(m_last_aspect - aspect_) < eps && abs(m_last_fov - fov_) < eps) {
return;
}
m_last_eye = eye_;
@ -181,7 +181,37 @@ void Camera::update_frustum()
Vec3f farCenter = eye_ + forward * far_;
Vec3f farNormal = -forward;
m_frustum.planes[1].set(farNormal, farCenter);
if (m_type == EType::Ortho) {
double right = 1.0 / m_projection_matrix.matrix()(0, 0) - 0.5 * m_projection_matrix.matrix()(0, 0) * m_projection_matrix.matrix()(0, 3);
double top = 1.0 / m_projection_matrix.matrix()(1, 1) - 0.5 * m_projection_matrix.matrix()(1, 1) * m_projection_matrix.matrix()(1, 3);
auto dz = (far_ - near_) / 2.0;
Vec3f center = eye_ + forward * (far_ + near_) /2.0f;
m_frustum.bbox.reset();
Vec3f corner = farCenter + up * top + side * right;
m_frustum.bbox.merge(corner.cast<double>());
corner = farCenter - up * top + side * right;
m_frustum.bbox.merge(corner.cast<double>());
corner = farCenter + up * top - side * right;
m_frustum.bbox.merge(corner.cast<double>());
corner = farCenter - up * top - side * right;
m_frustum.bbox.merge(corner.cast<double>());
//nearCenter
corner = nearCenter + up * top + side * right;
m_frustum.bbox.merge(corner.cast<double>());
corner = nearCenter - up * top + side * right;
m_frustum.bbox.merge(corner.cast<double>());
corner = nearCenter + up * top - side * right;
m_frustum.bbox.merge(corner.cast<double>());
corner = nearCenter - up * top - side * right;
m_frustum.bbox.merge(corner.cast<double>());
return;
}
// top plane
Vec3f topCenter = nearCenter + up * nearHeightHalf;
Vec3f topNormal = (topCenter - eye_).normalized().cross(side);