mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-31 14:02:02 +08:00
Camera + shading
Zoom to bed command set to zoom to active bed Added camera rotation pivot which is updated whenever the active bed changes SPE-2506 - Follow up of a2873759aba1eb13a31591d9e852be0f1e21786b - Fixed camera position after zoom to bed
This commit is contained in:
parent
360f7a84b4
commit
90136d3ad3
@ -60,7 +60,10 @@ void Camera::set_target(const Vec3d& target)
|
||||
const Vec3d new_displacement = new_target - m_target;
|
||||
if (!new_displacement.isApprox(Vec3d::Zero())) {
|
||||
m_target = new_target;
|
||||
m_view_matrix.translate(-new_displacement);
|
||||
Transform3d inv_view_matrix = m_view_matrix.inverse();
|
||||
inv_view_matrix.translation() = m_target - m_distance * get_dir_forward();
|
||||
m_view_matrix = inv_view_matrix.inverse();
|
||||
m_rotation_pivot = m_target;
|
||||
}
|
||||
}
|
||||
|
||||
@ -347,11 +350,11 @@ void Camera::rotate_on_sphere(double delta_azimut_rad, double delta_zenit_rad, b
|
||||
}
|
||||
}
|
||||
|
||||
const Vec3d translation = m_view_matrix.translation() + m_view_rotation * m_target;
|
||||
const Vec3d translation = m_view_matrix.translation() + m_view_rotation * m_rotation_pivot;
|
||||
const auto rot_z = Eigen::AngleAxisd(delta_azimut_rad, Vec3d::UnitZ());
|
||||
m_view_rotation *= rot_z * Eigen::AngleAxisd(delta_zenit_rad, rot_z.inverse() * get_dir_right());
|
||||
m_view_rotation.normalize();
|
||||
m_view_matrix.fromPositionOrientationScale(m_view_rotation * (- m_target) + translation, m_view_rotation, Vec3d(1., 1., 1.));
|
||||
m_view_matrix.fromPositionOrientationScale(m_view_rotation * (-m_rotation_pivot) + translation, m_view_rotation, Vec3d(1., 1., 1.));
|
||||
}
|
||||
|
||||
// Virtual trackball, rotate around an axis, where the eucledian norm of the axis gives the rotation angle in radians.
|
||||
@ -359,11 +362,11 @@ void Camera::rotate_local_around_target(const Vec3d& rotation_rad)
|
||||
{
|
||||
const double angle = rotation_rad.norm();
|
||||
if (std::abs(angle) > EPSILON) {
|
||||
const Vec3d translation = m_view_matrix.translation() + m_view_rotation * m_target;
|
||||
const Vec3d translation = m_view_matrix.translation() + m_view_rotation * m_rotation_pivot;
|
||||
const Vec3d axis = m_view_rotation.conjugate() * rotation_rad.normalized();
|
||||
m_view_rotation *= Eigen::Quaterniond(Eigen::AngleAxisd(angle, axis));
|
||||
m_view_rotation.normalize();
|
||||
m_view_matrix.fromPositionOrientationScale(m_view_rotation * (-m_target) + translation, m_view_rotation, Vec3d(1., 1., 1.));
|
||||
m_view_matrix.fromPositionOrientationScale(m_view_rotation * (-m_rotation_pivot) + translation, m_view_rotation, Vec3d(1., 1., 1.));
|
||||
update_zenit();
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ private:
|
||||
EType m_type{ EType::Perspective };
|
||||
bool m_update_config_on_type_change_enabled{ false };
|
||||
Vec3d m_target{ Vec3d::Zero() };
|
||||
Vec3d m_rotation_pivot{ Vec3d::Zero() };
|
||||
float m_zenit{ 45.0f };
|
||||
double m_zoom{ 1.0 };
|
||||
// Distance between camera position and camera target measured along the camera Z axis
|
||||
@ -66,6 +67,9 @@ public:
|
||||
const Vec3d& get_target() const { return m_target; }
|
||||
void set_target(const Vec3d& target);
|
||||
|
||||
const Vec3d& get_rotation_pivot() const { return m_rotation_pivot; }
|
||||
void set_rotation_pivot(const Vec3d& pivot) { m_rotation_pivot = pivot; }
|
||||
|
||||
double get_distance() const { return (get_position() - m_target).norm(); }
|
||||
double get_gui_scale() const { return m_gui_scale; }
|
||||
|
||||
|
@ -1746,8 +1746,10 @@ void GLCanvas3D::enable_layers_editing(bool enable)
|
||||
void GLCanvas3D::zoom_to_bed()
|
||||
{
|
||||
BoundingBoxf3 box = m_bed.build_volume().bounding_volume();
|
||||
box.translate(s_multiple_beds.get_bed_translation(s_multiple_beds.get_active_bed()));
|
||||
box.min.z() = 0.0;
|
||||
box.max.z() = 0.0;
|
||||
|
||||
_zoom_to_box(box);
|
||||
}
|
||||
|
||||
@ -1839,6 +1841,14 @@ void GLCanvas3D::render()
|
||||
|
||||
camera.apply_projection(_max_bounding_box(true, true));
|
||||
|
||||
const int curr_active_bed_id = s_multiple_beds.get_active_bed();
|
||||
if (m_last_active_bed_id != curr_active_bed_id) {
|
||||
const Vec3d bed_offset = s_multiple_beds.get_bed_translation(s_multiple_beds.get_active_bed());
|
||||
const Vec2d bed_center = m_bed.build_volume().bed_center() + Vec2d(bed_offset.x(), bed_offset.y());
|
||||
camera.set_rotation_pivot({ bed_center.x(), bed_center.y(), 0.0f });
|
||||
m_last_active_bed_id = curr_active_bed_id;
|
||||
}
|
||||
|
||||
wxGetApp().imgui()->new_frame();
|
||||
|
||||
if (m_picking_enabled) {
|
||||
@ -5923,18 +5933,22 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type)
|
||||
m_layers_editing.select_object(*m_model, this->is_layers_editing_enabled() ? m_selection.get_object_idx() : -1);
|
||||
|
||||
if (const BuildVolume &build_volume = m_bed.build_volume(); build_volume.valid()) {
|
||||
switch (build_volume.type()) {
|
||||
const Vec3d bed_offset = s_multiple_beds.get_bed_translation(s_multiple_beds.get_active_bed());
|
||||
switch (build_volume.type()) {
|
||||
case BuildVolume::Type::Rectangle: {
|
||||
const BoundingBox3Base<Vec3d> bed_bb = build_volume.bounding_volume().inflated(BuildVolume::SceneEpsilon);
|
||||
m_volumes.set_print_volume({ 0, // circle
|
||||
{ float(bed_bb.min.x()), float(bed_bb.min.y()), float(bed_bb.max.x()), float(bed_bb.max.y()) },
|
||||
{ 0.0f, float(build_volume.max_print_height()) } });
|
||||
m_volumes.set_print_volume({ 0, // rectangle
|
||||
{ float(bed_bb.min.x() + bed_offset.x()), float(bed_bb.min.y() + bed_offset.y()),
|
||||
float(bed_bb.max.x() + bed_offset.x()), float(bed_bb.max.y() + bed_offset.y()) },
|
||||
{ float(0.0 + bed_offset.z()), float(build_volume.max_print_height() + bed_offset.z()) } });
|
||||
break;
|
||||
}
|
||||
case BuildVolume::Type::Circle: {
|
||||
m_volumes.set_print_volume({ 1, // rectangle
|
||||
{ unscaled<float>(build_volume.circle().center.x()), unscaled<float>(build_volume.circle().center.y()), unscaled<float>(build_volume.circle().radius + BuildVolume::SceneEpsilon), 0.0f },
|
||||
{ 0.0f, float(build_volume.max_print_height() + BuildVolume::SceneEpsilon) } });
|
||||
m_volumes.set_print_volume({ 1, // circle
|
||||
{ unscaled<float>(build_volume.circle().center.x() + bed_offset.x()),
|
||||
unscaled<float>(build_volume.circle().center.y() + bed_offset.y()),
|
||||
unscaled<float>(build_volume.circle().radius + BuildVolume::SceneEpsilon), 0.0f },
|
||||
{ float(0.0 + bed_offset.z()), float(build_volume.max_print_height() + bed_offset.z() + BuildVolume::SceneEpsilon) } });
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -486,6 +486,7 @@ private:
|
||||
wxGLContext* m_context;
|
||||
SceneRaycaster m_scene_raycaster;
|
||||
Bed3D &m_bed;
|
||||
int m_last_active_bed_id{ -1 };
|
||||
#if ENABLE_RETINA_GL
|
||||
std::unique_ptr<RetinaHelper> m_retina_helper;
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user