diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp index 00fac429da..682f15b310 100644 --- a/src/slic3r/GUI/Camera.cpp +++ b/src/slic3r/GUI/Camera.cpp @@ -43,8 +43,6 @@ void Camera::set_type(EType type) m_type = type; if (m_update_config_on_type_change_enabled) wxGetApp().app_config->set("use_perspective_camera", (m_type == EType::Perspective) ? "1" : "0"); - - update_projection(); } } @@ -605,37 +603,6 @@ void Camera::update_zenit() m_zenit = Geometry::rad2deg(0.5 * M_PI - std::acos(std::clamp(-get_dir_forward().dot(Vec3d::UnitZ()), -1.0, 1.0))); } -void Camera::update_projection() -{ - double w = 0.5 * (double)m_viewport[2]; - double h = 0.5 * (double)m_viewport[3]; - - const double inv_zoom = get_inv_zoom(); - w *= inv_zoom; - h *= inv_zoom; - - switch (m_type) - { - default: - case EType::Ortho: - { - m_gui_scale = 1.0; - break; - } - case EType::Perspective: - { - // scale near plane to keep w and h constant on the plane at z = m_distance - const double scale = m_frustrum_zs.first / m_distance; - w *= scale; - h *= scale; - m_gui_scale = scale; - break; - } - } - - apply_projection(-w, w, -h, h, m_frustrum_zs.first, m_frustrum_zs.second); -} - } // GUI } // Slic3r diff --git a/src/slic3r/GUI/Camera.hpp b/src/slic3r/GUI/Camera.hpp index 057892353f..e8915f1a5c 100644 --- a/src/slic3r/GUI/Camera.hpp +++ b/src/slic3r/GUI/Camera.hpp @@ -157,7 +157,6 @@ private: void set_default_orientation(); Vec3d validate_target(const Vec3d& target) const; void update_zenit(); - void update_projection(); }; } // GUI diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 51d56fa996..7203247c3c 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -6996,13 +6996,29 @@ Vec3d GLCanvas3D::_mouse_to_3d(const Point& mouse_pos, const float* z, bool use_ else { Camera& camera = wxGetApp().plater()->get_camera(); const Camera::EType type = camera.get_type(); - if (use_ortho) - camera.set_type(Camera::EType::Ortho); const Vec4i viewport(camera.get_viewport().data()); + Transform3d projection_matrix; + if (use_ortho && type != Camera::EType::Ortho) { + const double inv_zoom = camera.get_inv_zoom(); + const double left = -0.5 * inv_zoom * double(viewport[2]); + const double bottom = -0.5 * inv_zoom * double(viewport[3]); + const double right = 0.5 * inv_zoom * double(viewport[2]); + const double top = 0.5 * inv_zoom * double(viewport[3]); + const double near_z = camera.get_near_z(); + const double far_z = camera.get_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); + 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; + } + else + projection_matrix = camera.get_projection_matrix(); + Vec3d out; - igl::unproject(Vec3d(mouse_pos.x(), viewport[3] - mouse_pos.y(), *z), camera.get_view_matrix().matrix(), camera.get_projection_matrix().matrix(), viewport, out); - if (use_ortho) - camera.set_type(type); + igl::unproject(Vec3d(mouse_pos.x(), viewport[3] - mouse_pos.y(), *z), camera.get_view_matrix().matrix(), projection_matrix.matrix(), viewport, out); return out; } }