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:
enricoturri1966 2024-10-23 10:23:00 +02:00 committed by Lukas Matena
parent 360f7a84b4
commit 90136d3ad3
4 changed files with 34 additions and 12 deletions

View File

@ -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();
}
}

View File

@ -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; }

View File

@ -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:

View File

@ -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