From 10e41fbd07aeb0a18768e75c0ed757e290f1b522 Mon Sep 17 00:00:00 2001 From: "zhou.xu" Date: Mon, 12 Aug 2024 17:23:33 +0800 Subject: [PATCH] FIX:calculate frustum of ortho view jira: none Change-Id: Ia0c30ebd9366ae1dfc5cdd555aa9f89a9dd878f1 --- src/libslic3r/Frustum.cpp | 11 +++++++---- src/libslic3r/Frustum.hpp | 2 +- src/slic3r/GUI/3DScene.cpp | 2 +- src/slic3r/GUI/Camera.cpp | 36 +++++++++++++++++++++++++++++++++--- 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/libslic3r/Frustum.cpp b/src/libslic3r/Frustum.cpp index b01de8c20..10fae9145 100644 --- a/src/libslic3r/Frustum.cpp +++ b/src/libslic3r/Frustum.cpp @@ -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 diff --git a/src/libslic3r/Frustum.hpp b/src/libslic3r/Frustum.hpp index c31ba92a0..26b12e1dc 100644 --- a/src/libslic3r/Frustum.hpp +++ b/src/libslic3r/Frustum.hpp @@ -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) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index f3eba0dbe..f355ecaad 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -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 diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp index ae19304a5..76b59ef5b 100644 --- a/src/slic3r/GUI/Camera.cpp +++ b/src/slic3r/GUI/Camera.cpp @@ -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()); + corner = farCenter - up * top + side * right; + m_frustum.bbox.merge(corner.cast()); + + corner = farCenter + up * top - side * right; + m_frustum.bbox.merge(corner.cast()); + + corner = farCenter - up * top - side * right; + m_frustum.bbox.merge(corner.cast()); + //nearCenter + corner = nearCenter + up * top + side * right; + m_frustum.bbox.merge(corner.cast()); + + corner = nearCenter - up * top + side * right; + m_frustum.bbox.merge(corner.cast()); + + corner = nearCenter + up * top - side * right; + m_frustum.bbox.merge(corner.cast()); + + corner = nearCenter - up * top - side * right; + m_frustum.bbox.merge(corner.cast()); + return; + } // top plane Vec3f topCenter = nearCenter + up * nearHeightHalf; Vec3f topNormal = (topCenter - eye_).normalized().cross(side);