diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp index 841a678ca7..341bfd4322 100644 --- a/src/slic3r/GUI/Camera.cpp +++ b/src/slic3r/GUI/Camera.cpp @@ -44,6 +44,8 @@ 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(); } } @@ -634,6 +636,37 @@ 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 183086fe27..2729474d60 100644 --- a/src/slic3r/GUI/Camera.hpp +++ b/src/slic3r/GUI/Camera.hpp @@ -164,6 +164,7 @@ 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 39dde081a1..9533319ca2 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -7053,10 +7053,13 @@ Vec3d GLCanvas3D::_mouse_to_3d(const Point& mouse_pos, const float* z) return hit.is_valid() ? hit.position.cast() : _mouse_to_bed_3d(mouse_pos); } else { - const Camera& camera = wxGetApp().plater()->get_camera(); + Camera& camera = wxGetApp().plater()->get_camera(); + const Camera::EType type = camera.get_type(); + camera.set_type(Camera::EType::Ortho); const Vec4i viewport(camera.get_viewport().data()); 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); + camera.set_type(type); return out; } }