diff options
author | Enrico Turri <enricoturri@seznam.cz> | 2019-04-01 11:00:10 +0300 |
---|---|---|
committer | Enrico Turri <enricoturri@seznam.cz> | 2019-04-01 11:00:10 +0300 |
commit | d87b478d6057de5085feaf0890a16fcc9b407438 (patch) | |
tree | 81b38f4a4bde2abe8265320ff3f14dcdadb533dc /src | |
parent | 1ce3bb690c1378a5af71594876fde24b9e79739e (diff) | |
parent | ba89f04429cd89da25c97c9d474697ac4fe14700 (diff) |
Camera refactoring
1) All camera related OpenGL calls moved into class
2) The Camera class now stores the view matrix, the projection matrix and the viewport
3) The Camera class now exposes methods to get the camera orientation vectors, the camera position, the view matrix, the projection matrix and the viewport
4) All the code operating on the camera or requiring camera data has been modified to use the new methods
Diffstat (limited to 'src')
-rw-r--r-- | src/slic3r/GUI/3DScene.cpp | 15 | ||||
-rw-r--r-- | src/slic3r/GUI/3DScene.hpp | 4 | ||||
-rw-r--r-- | src/slic3r/GUI/Camera.cpp | 70 | ||||
-rw-r--r-- | src/slic3r/GUI/Camera.hpp | 20 | ||||
-rw-r--r-- | src/slic3r/GUI/GLCanvas3D.cpp | 128 | ||||
-rw-r--r-- | src/slic3r/GUI/GLCanvas3D.hpp | 3 | ||||
-rw-r--r-- | src/slic3r/GUI/GLToolbar.cpp | 12 | ||||
-rw-r--r-- | src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 30 | ||||
-rw-r--r-- | src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 2 | ||||
-rw-r--r-- | src/slic3r/GUI/Selection.cpp | 18 |
10 files changed, 168 insertions, 134 deletions
diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index aafc3215a..ce8f651ff 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -714,7 +714,7 @@ int GLVolumeCollection::load_wipe_tower_preview( typedef std::pair<GLVolume*, double> GLVolumeWithZ; typedef std::vector<GLVolumeWithZ> GLVolumesWithZList; -static GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollection::ERenderType type, std::function<bool(const GLVolume&)> filter_func) +static GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollection::ERenderType type, const Transform3d& view_matrix, std::function<bool(const GLVolume&)> filter_func) { GLVolumesWithZList list; list.reserve(volumes.size()); @@ -731,12 +731,9 @@ static GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolum if ((type == GLVolumeCollection::Transparent) && (list.size() > 1)) { - Transform3d modelview_matrix; - glsafe(::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data())); - for (GLVolumeWithZ& volume : list) { - volume.second = volume.first->bounding_box.transformed(modelview_matrix * volume.first->world_matrix()).max(2); + volume.second = volume.first->bounding_box.transformed(view_matrix * volume.first->world_matrix()).max(2); } std::sort(list.begin(), list.end(), @@ -747,7 +744,7 @@ static GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolum return list; } -void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool disable_cullface, std::function<bool(const GLVolume&)> filter_func) const +void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function<bool(const GLVolume&)> filter_func) const { glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); @@ -778,7 +775,7 @@ void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool if (z_range_id != -1) glsafe(::glUniform2fv(z_range_id, 1, (const GLfloat*)z_range)); - GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, filter_func); + GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, view_matrix, filter_func); for (GLVolumeWithZ& volume : to_render) { volume.first->set_render_color(); volume.first->render_VBOs(color_id, print_box_detection_id, print_box_worldmatrix_id); @@ -796,7 +793,7 @@ void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool glsafe(::glDisable(GL_BLEND)); } -void GLVolumeCollection::render_legacy(ERenderType type, bool disable_cullface, std::function<bool(const GLVolume&)> filter_func) const +void GLVolumeCollection::render_legacy(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function<bool(const GLVolume&)> filter_func) const { glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); @@ -808,7 +805,7 @@ void GLVolumeCollection::render_legacy(ERenderType type, bool disable_cullface, glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); - GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, filter_func); + GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, view_matrix, filter_func); for (GLVolumeWithZ& volume : to_render) { volume.first->set_render_color(); diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index a1dee9e57..d9ae0ec74 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -464,8 +464,8 @@ public: int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool use_VBOs, bool size_unknown, float brim_width); // Render the volumes by OpenGL. - void render_VBOs(ERenderType type, bool disable_cullface, std::function<bool(const GLVolume&)> filter_func = std::function<bool(const GLVolume&)>()) const; - void render_legacy(ERenderType type, bool disable_cullface, std::function<bool(const GLVolume&)> filter_func = std::function<bool(const GLVolume&)>()) const; + void render_VBOs(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function<bool(const GLVolume&)> filter_func = std::function<bool(const GLVolume&)>()) const; + void render_legacy(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function<bool(const GLVolume&)> filter_func = std::function<bool(const GLVolume&)>()) const; // Finalize the initialization of the geometry & indices, // upload the geometry and indices to OpenGL VBO objects diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp index c748efa64..7a1023e62 100644 --- a/src/slic3r/GUI/Camera.cpp +++ b/src/slic3r/GUI/Camera.cpp @@ -1,9 +1,21 @@ #include "libslic3r/libslic3r.h" #include "Camera.hpp" +#include "3DScene.hpp" + +#include <GL/glew.h> static const float GIMBALL_LOCK_THETA_MAX = 180.0f; +// phi / theta angles to orient the camera. +static const float VIEW_DEFAULT[2] = { 45.0f, 45.0f }; +static const float VIEW_LEFT[2] = { 90.0f, 90.0f }; +static const float VIEW_RIGHT[2] = { -90.0f, 90.0f }; +static const float VIEW_TOP[2] = { 0.0f, 0.0f }; +static const float VIEW_BOTTOM[2] = { 0.0f, 180.0f }; +static const float VIEW_FRONT[2] = { 0.0f, 90.0f }; +static const float VIEW_REAR[2] = { 180.0f, 90.0f }; + namespace Slic3r { namespace GUI { @@ -57,6 +69,64 @@ void Camera::set_scene_box(const BoundingBoxf3& box) m_scene_box = box; } +bool Camera::select_view(const std::string& direction) +{ + const float* dir_vec = nullptr; + + if (direction == "iso") + dir_vec = VIEW_DEFAULT; + else if (direction == "left") + dir_vec = VIEW_LEFT; + else if (direction == "right") + dir_vec = VIEW_RIGHT; + else if (direction == "top") + dir_vec = VIEW_TOP; + else if (direction == "bottom") + dir_vec = VIEW_BOTTOM; + else if (direction == "front") + dir_vec = VIEW_FRONT; + else if (direction == "rear") + dir_vec = VIEW_REAR; + + if (dir_vec != nullptr) + { + phi = dir_vec[0]; + set_theta(dir_vec[1], false); + return true; + } + else + return false; +} + +void Camera::apply_viewport(int x, int y, unsigned int w, unsigned int h) const +{ + glsafe(::glViewport(0, 0, w, h)); + glsafe(::glGetIntegerv(GL_VIEWPORT, m_viewport.data())); +} + +void Camera::apply_view_matrix() const +{ + glsafe(::glMatrixMode(GL_MODELVIEW)); + glsafe(::glLoadIdentity()); + + glsafe(::glRotatef(-m_theta, 1.0f, 0.0f, 0.0f)); // pitch + glsafe(::glRotatef(phi, 0.0f, 0.0f, 1.0f)); // yaw + glsafe(::glTranslated(-m_target(0), -m_target(1), -m_target(2))); + + glsafe(::glGetDoublev(GL_MODELVIEW_MATRIX, m_view_matrix.data())); +} + +void Camera::apply_ortho_projection(float x_min, float x_max, float y_min, float y_max, float z_min, float z_max) const +{ + glsafe(::glMatrixMode(GL_PROJECTION)); + glsafe(::glLoadIdentity()); + + glsafe(::glOrtho(x_min, x_max, y_min, y_max, z_min, z_max)); + glsafe(::glGetDoublev(GL_PROJECTION_MATRIX, m_projection_matrix.data())); + + glsafe(::glMatrixMode(GL_MODELVIEW)); +} + } // GUI } // Slic3r diff --git a/src/slic3r/GUI/Camera.hpp b/src/slic3r/GUI/Camera.hpp index d50dc6e4d..ff2d3aa31 100644 --- a/src/slic3r/GUI/Camera.hpp +++ b/src/slic3r/GUI/Camera.hpp @@ -26,6 +26,10 @@ private: Vec3d m_target; float m_theta; + mutable std::array<int, 4> m_viewport; + mutable Transform3d m_view_matrix; + mutable Transform3d m_projection_matrix; + BoundingBoxf3 m_scene_box; public: @@ -41,6 +45,22 @@ public: const BoundingBoxf3& get_scene_box() const { return m_scene_box; } void set_scene_box(const BoundingBoxf3& box); + + bool select_view(const std::string& direction); + + const std::array<int, 4>& get_viewport() const { return m_viewport; } + const Transform3d& get_view_matrix() const { return m_view_matrix; } + const Transform3d& get_projection_matrix() const { return m_projection_matrix; } + + Vec3d get_dir_right() const { return m_view_matrix.matrix().block(0, 0, 3, 3).row(0); } + Vec3d get_dir_up() const { return m_view_matrix.matrix().block(0, 0, 3, 3).row(1); } + Vec3d get_dir_forward() const { return m_view_matrix.matrix().block(0, 0, 3, 3).row(2); } + + Vec3d get_position() const { return m_view_matrix.matrix().block(0, 0, 3, 3).row(3); } + + void apply_viewport(int x, int y, unsigned int w, unsigned int h) const; + void apply_view_matrix() const; + void apply_ortho_projection(float x_min, float x_max, float y_min, float y_max, float z_min, float z_max) const; }; } // GUI diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 76a23373d..99b9faddb 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -56,15 +56,6 @@ static const float TRACKBALLSIZE = 0.8f; static const float GROUND_Z = -0.02f; -// phi / theta angles to orient the camera. -static const float VIEW_DEFAULT[2] = { 45.0f, 45.0f }; -static const float VIEW_LEFT[2] = { 90.0f, 90.0f }; -static const float VIEW_RIGHT[2] = { -90.0f, 90.0f }; -static const float VIEW_TOP[2] = { 0.0f, 0.0f }; -static const float VIEW_BOTTOM[2] = { 0.0f, 180.0f }; -static const float VIEW_FRONT[2] = { 0.0f, 90.0f }; -static const float VIEW_REAR[2] = { 180.0f, 90.0f }; - static const float GIZMO_RESET_BUTTON_HEIGHT = 22.0f; static const float GIZMO_RESET_BUTTON_WIDTH = 70.f; @@ -374,7 +365,7 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas) float half_w = 0.5f * (float)cnv_size.get_width(); float half_h = 0.5f * (float)cnv_size.get_height(); - float zoom = canvas.get_camera_zoom(); + float zoom = canvas.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; return Rect((half_w - thickness_bar_width(canvas)) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, (-half_h + reset_button_height(canvas)) * inv_zoom); @@ -386,7 +377,7 @@ Rect GLCanvas3D::LayersEditing::get_reset_rect_viewport(const GLCanvas3D& canvas float half_w = 0.5f * (float)cnv_size.get_width(); float half_h = 0.5f * (float)cnv_size.get_height(); - float zoom = canvas.get_camera_zoom(); + float zoom = canvas.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; return Rect((half_w - thickness_bar_width(canvas)) * inv_zoom, (-half_h + reset_button_height(canvas)) * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom); @@ -417,7 +408,7 @@ void GLCanvas3D::LayersEditing::_render_tooltip_texture(const GLCanvas3D& canvas const float width = (float)m_tooltip_texture.get_width() * scale; const float height = (float)m_tooltip_texture.get_height() * scale; - float zoom = canvas.get_camera_zoom(); + float zoom = canvas.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; float gap = 10.0f * inv_zoom; @@ -871,7 +862,7 @@ void GLCanvas3D::WarningTexture::render(const GLCanvas3D& canvas) const glsafe(::glLoadIdentity()); const Size& cnv_size = canvas.get_canvas_size(); - float zoom = canvas.get_camera_zoom(); + float zoom = canvas.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; float left = (-0.5f * (float)m_original_width) * inv_zoom; float top = (-0.5f * (float)cnv_size.get_height() + (float)m_original_height + 2.0f) * inv_zoom; @@ -1140,7 +1131,7 @@ void GLCanvas3D::LegendTexture::render(const GLCanvas3D& canvas) const glsafe(::glLoadIdentity()); const Size& cnv_size = canvas.get_canvas_size(); - float zoom = canvas.get_camera_zoom(); + float zoom = canvas.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; float left = (-0.5f * (float)cnv_size.get_width()) * inv_zoom; float top = (0.5f * (float)cnv_size.get_height()) * inv_zoom; @@ -1424,11 +1415,6 @@ void GLCanvas3D::set_color_by(const std::string& value) m_color_by = value; } -float GLCanvas3D::get_camera_zoom() const -{ - return m_camera.zoom; -} - BoundingBoxf3 GLCanvas3D::volumes_bounding_box() const { BoundingBoxf3 bb; @@ -1542,30 +1528,8 @@ void GLCanvas3D::zoom_to_selection() void GLCanvas3D::select_view(const std::string& direction) { - const float* dir_vec = nullptr; - - if (direction == "iso") - dir_vec = VIEW_DEFAULT; - else if (direction == "left") - dir_vec = VIEW_LEFT; - else if (direction == "right") - dir_vec = VIEW_RIGHT; - else if (direction == "top") - dir_vec = VIEW_TOP; - else if (direction == "bottom") - dir_vec = VIEW_BOTTOM; - else if (direction == "front") - dir_vec = VIEW_FRONT; - else if (direction == "rear") - dir_vec = VIEW_REAR; - - if (dir_vec != nullptr) - { - m_camera.phi = dir_vec[0]; - m_camera.set_theta(dir_vec[1], false); - if (m_canvas != nullptr) - m_canvas->Refresh(); - } + if (m_camera.select_view(direction) && (m_canvas != nullptr)) + m_canvas->Refresh(); } void GLCanvas3D::update_volumes_colors_by_extruder() @@ -1609,7 +1573,7 @@ void GLCanvas3D::render() m_camera.requires_zoom_to_bed = false; } - _camera_tranform(); + m_camera.apply_view_matrix(); GLfloat position_cam[4] = { 1.0f, 0.0f, 1.0f, 0.0f }; glsafe(::glLightfv(GL_LIGHT1, GL_POSITION, position_cam)); @@ -2661,11 +2625,8 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) // vector from the starting position to the found intersection Vec3d inters_vec = inters - m_mouse.drag.start_position_3D; - // get the view matrix back from opengl - GLfloat matrix[16]; - glsafe(::glGetFloatv(GL_MODELVIEW_MATRIX, matrix)); - Vec3d camera_right((double)matrix[0], (double)matrix[4], (double)matrix[8]); - Vec3d camera_up((double)matrix[1], (double)matrix[5], (double)matrix[9]); + Vec3d camera_right = m_camera.get_dir_right(); + Vec3d camera_up = m_camera.get_dir_up(); // finds projection of the vector along the camera axes double projection_x = inters_vec.dot(camera_right); @@ -3103,7 +3064,7 @@ void GLCanvas3D::do_mirror() void GLCanvas3D::set_camera_zoom(float zoom) { zoom = std::max(std::min(zoom, 4.0f), -4.0f) / 10.0f; - zoom = get_camera_zoom() / (1.0f - zoom); + zoom = m_camera.zoom / (1.0f - zoom); // Don't allow to zoom too far outside the scene. float zoom_min = _get_zoom_to_bounding_box_factor(_max_bounding_box()); @@ -3346,10 +3307,7 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h) // ensures that this canvas is current _set_current(); - glsafe(::glViewport(0, 0, w, h)); - - glsafe(::glMatrixMode(GL_PROJECTION)); - glsafe(::glLoadIdentity()); + m_camera.apply_viewport(0, 0, w, h); const BoundingBoxf3& bbox = _max_bounding_box(); @@ -3359,7 +3317,7 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h) { float w2 = w; float h2 = h; - float two_zoom = 2.0f * get_camera_zoom(); + float two_zoom = 2.0f * m_camera.zoom; if (two_zoom != 0.0f) { float inv_two_zoom = 1.0f / two_zoom; @@ -3369,7 +3327,7 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h) // FIXME: calculate a tighter value for depth will improve z-fighting float depth = 5.0f * (float)bbox.max_size(); - glsafe(::glOrtho(-w2, w2, -h2, h2, -depth, depth)); + m_camera.apply_ortho_projection(-w2, w2, -h2, h2, -depth, depth); break; } @@ -3402,8 +3360,6 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h) } } - glsafe(::glMatrixMode(GL_MODELVIEW)); - m_dirty = false; } @@ -3437,16 +3393,11 @@ float GLCanvas3D::_get_zoom_to_bounding_box_factor(const BoundingBoxf3& bbox) co // then calculates the vertices coordinate on this plane along the camera xy axes // we need the view matrix, we let opengl calculate it (same as done in render()) - _camera_tranform(); + m_camera.apply_view_matrix(); - // get the view matrix back from opengl - GLfloat matrix[16]; - glsafe(::glGetFloatv(GL_MODELVIEW_MATRIX, matrix)); - - // camera axes - Vec3d right((double)matrix[0], (double)matrix[4], (double)matrix[8]); - Vec3d up((double)matrix[1], (double)matrix[5], (double)matrix[9]); - Vec3d forward((double)matrix[2], (double)matrix[6], (double)matrix[10]); + Vec3d right = m_camera.get_dir_right(); + Vec3d up = m_camera.get_dir_up(); + Vec3d forward = m_camera.get_dir_forward(); Vec3d bb_min = bbox.min; Vec3d bb_max = bbox.max; @@ -3507,17 +3458,6 @@ void GLCanvas3D::_refresh_if_shown_on_screen() } } -void GLCanvas3D::_camera_tranform() const -{ - glsafe(::glMatrixMode(GL_MODELVIEW)); - glsafe(::glLoadIdentity()); - - glsafe(::glRotatef(-m_camera.get_theta(), 1.0f, 0.0f, 0.0f)); // pitch - glsafe(::glRotatef(m_camera.phi, 0.0f, 0.0f, 1.0f)); // yaw - Vec3d target = -m_camera.get_target(); - glsafe(::glTranslated(target(0), target(1), target(2))); -} - void GLCanvas3D::_picking_pass() const { const Vec2d& pos = m_mouse.position; @@ -3648,19 +3588,19 @@ void GLCanvas3D::_render_objects() const m_shader.start_using(); if (m_picking_enabled && m_layers_editing.is_enabled() && m_layers_editing.last_object_id != -1) { int object_id = m_layers_editing.last_object_id; - m_volumes.render_VBOs(GLVolumeCollection::Opaque, false, [object_id](const GLVolume &volume) { + m_volumes.render_VBOs(GLVolumeCollection::Opaque, false, m_camera.get_view_matrix(), [object_id](const GLVolume &volume) { // Which volume to paint without the layer height profile shader? - return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id); + return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id); }); // Let LayersEditing handle rendering of the active object using the layer height profile shader. m_layers_editing.render_volumes(*this, this->m_volumes); } else { // do not cull backfaces to show broken geometry, if any - m_volumes.render_VBOs(GLVolumeCollection::Opaque, m_picking_enabled, [this](const GLVolume& volume) { + m_volumes.render_VBOs(GLVolumeCollection::Opaque, m_picking_enabled, m_camera.get_view_matrix(), [this](const GLVolume& volume) { return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0); }); } - m_volumes.render_VBOs(GLVolumeCollection::Transparent, false); + m_volumes.render_VBOs(GLVolumeCollection::Transparent, false, m_camera.get_view_matrix()); m_shader.stop_using(); } else @@ -3674,10 +3614,10 @@ void GLCanvas3D::_render_objects() const } // do not cull backfaces to show broken geometry, if any - m_volumes.render_legacy(GLVolumeCollection::Opaque, m_picking_enabled, [this](const GLVolume& volume) { - return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0); - }); - m_volumes.render_legacy(GLVolumeCollection::Transparent, false); + m_volumes.render_legacy(GLVolumeCollection::Opaque, m_picking_enabled, m_camera.get_view_matrix(), [this](const GLVolume& volume) { + return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0); + }); + m_volumes.render_legacy(GLVolumeCollection::Transparent, false, m_camera.get_view_matrix()); if (m_use_clipping_planes) { @@ -3796,7 +3736,7 @@ void GLCanvas3D::_render_toolbar() const #endif // ENABLE_RETINA_GL Size cnv_size = get_canvas_size(); - float zoom = get_camera_zoom(); + float zoom = m_camera.zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; GLToolbar::Layout::EOrientation orientation = m_toolbar.get_layout_orientation(); @@ -3859,7 +3799,7 @@ void GLCanvas3D::_render_view_toolbar() const #endif // ENABLE_RETINA_GL Size cnv_size = get_canvas_size(); - float zoom = get_camera_zoom(); + float zoom = m_camera.zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; // places the toolbar on the bottom-left corner of the 3d scene @@ -4113,14 +4053,10 @@ Vec3d GLCanvas3D::_mouse_to_3d(const Point& mouse_pos, float* z) if (m_canvas == nullptr) return Vec3d(DBL_MAX, DBL_MAX, DBL_MAX); - _camera_tranform(); - GLint viewport[4]; - glsafe(::glGetIntegerv(GL_VIEWPORT, viewport)); - GLdouble modelview_matrix[16]; - glsafe(::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix)); - GLdouble projection_matrix[16]; - glsafe(::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix)); + const std::array<int, 4>& viewport = m_camera.get_viewport(); + const Transform3d& modelview_matrix = m_camera.get_view_matrix(); + const Transform3d& projection_matrix = m_camera.get_projection_matrix(); GLint y = viewport[3] - (GLint)mouse_pos(1); GLfloat mouse_z; @@ -4130,7 +4066,7 @@ Vec3d GLCanvas3D::_mouse_to_3d(const Point& mouse_pos, float* z) mouse_z = *z; GLdouble out_x, out_y, out_z; - ::gluUnProject((GLdouble)mouse_pos(0), (GLdouble)y, (GLdouble)mouse_z, modelview_matrix, projection_matrix, viewport, &out_x, &out_y, &out_z); + ::gluUnProject((GLdouble)mouse_pos(0), (GLdouble)y, (GLdouble)mouse_z, (GLdouble*)modelview_matrix.data(), (GLdouble*)projection_matrix.data(), (GLint*)viewport.data(), &out_x, &out_y, &out_z); return Vec3d((double)out_x, (double)out_y, (double)out_z); } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 9c196aa20..c53e1df8c 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -483,7 +483,7 @@ public: void set_color_by(const std::string& value); - float get_camera_zoom() const; + const Camera& get_camera() const { return m_camera; } BoundingBoxf3 volumes_bounding_box() const; BoundingBoxf3 scene_bounding_box() const; @@ -593,7 +593,6 @@ private: void _refresh_if_shown_on_screen(); - void _camera_tranform() const; void _picking_pass() const; void _render_background() const; void _render_bed(float theta) const; diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index 985c6aa84..144d02476 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -612,7 +612,7 @@ std::string GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLC { // NB: mouse_pos is already scaled appropriately - float zoom = parent.get_camera_zoom(); + float zoom = parent.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; #if ENABLE_SVG_ICONS float factor = m_layout.scale * inv_zoom; @@ -717,7 +717,7 @@ std::string GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCan { // NB: mouse_pos is already scaled appropriately - float zoom = parent.get_camera_zoom(); + float zoom = parent.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; #if ENABLE_SVG_ICONS float factor = m_layout.scale * inv_zoom; @@ -834,7 +834,7 @@ int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3 { // NB: mouse_pos is already scaled appropriately - float zoom = parent.get_camera_zoom(); + float zoom = parent.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; #if ENABLE_SVG_ICONS float factor = m_layout.scale * inv_zoom; @@ -917,7 +917,7 @@ int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D& { // NB: mouse_pos is already scaled appropriately - float zoom = parent.get_camera_zoom(); + float zoom = parent.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; #if ENABLE_SVG_ICONS float factor = m_layout.scale * inv_zoom; @@ -1013,7 +1013,7 @@ void GLToolbar::render_horizontal(const GLCanvas3D& parent) const return; #endif // !ENABLE_SVG_ICONS - float zoom = parent.get_camera_zoom(); + float zoom = parent.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; #if ENABLE_SVG_ICONS float factor = inv_zoom * m_layout.scale; @@ -1168,7 +1168,7 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent) const return; #endif // !ENABLE_SVG_ICONS - float zoom = parent.get_camera_zoom(); + float zoom = parent.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; #if ENABLE_SVG_ICONS float factor = inv_zoom * m_layout.scale; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index e21fddefa..2a5f35596 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -273,17 +273,15 @@ std::pair<Vec3f, Vec3f> GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse if (m_V.size() == 0) update_mesh(); - Eigen::Matrix<GLint, 4, 1, Eigen::DontAlign> viewport; - glsafe(::glGetIntegerv(GL_VIEWPORT, viewport.data())); - Eigen::Matrix<GLdouble, 4, 4, Eigen::DontAlign> modelview_matrix; - glsafe(::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data())); - Eigen::Matrix<GLdouble, 4, 4, Eigen::DontAlign> projection_matrix; - glsafe(::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix.data())); + const Camera& camera = m_parent.get_camera(); + const std::array<int, 4>& viewport = camera.get_viewport(); + const Transform3d& modelview_matrix = camera.get_view_matrix(); + const Transform3d& projection_matrix = camera.get_projection_matrix(); Vec3d point1; Vec3d point2; - ::gluUnProject(mouse_pos(0), viewport(3)-mouse_pos(1), 0.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point1(0), &point1(1), &point1(2)); - ::gluUnProject(mouse_pos(0), viewport(3)-mouse_pos(1), 1.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point2(0), &point2(1), &point2(2)); + ::gluUnProject(mouse_pos(0), viewport[3] - mouse_pos(1), 0.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point1(0), &point1(1), &point1(2)); + ::gluUnProject(mouse_pos(0), viewport[3] - mouse_pos(1), 1.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point2(0), &point2(1), &point2(2)); igl::Hit hit; @@ -365,12 +363,10 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous // left up with selection rectangle - select points inside the rectangle: if ((action == SLAGizmoEventType::LeftUp || action == SLAGizmoEventType::ShiftUp) && m_selection_rectangle_active) { const Transform3d& instance_matrix = m_model_object->instances[m_active_instance]->get_transformation().get_matrix(); - GLint viewport[4]; - glsafe(::glGetIntegerv(GL_VIEWPORT, viewport)); - GLdouble modelview_matrix[16]; - glsafe(::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix)); - GLdouble projection_matrix[16]; - glsafe(::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix)); + const Camera& camera = m_parent.get_camera(); + const std::array<int, 4>& viewport = camera.get_viewport(); + const Transform3d& modelview_matrix = camera.get_view_matrix(); + const Transform3d& projection_matrix = camera.get_projection_matrix(); const Selection& selection = m_parent.get_selection(); const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); @@ -381,7 +377,7 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous const Transform3d& instance_matrix_no_translation = volume->get_instance_transformation().get_matrix(true); // we'll recover current look direction from the modelview matrix (in world coords)... - Vec3f direction_to_camera(modelview_matrix[2], modelview_matrix[6], modelview_matrix[10]); + Vec3f direction_to_camera = camera.get_dir_forward().cast<float>(); // ...and transform it to model coords. direction_to_camera = (instance_matrix_no_translation.inverse().cast<float>() * direction_to_camera).normalized().eval(); @@ -391,8 +387,8 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous Vec3f pos = instance_matrix.cast<float>() * support_point.pos; pos(2) += z_offset; GLdouble out_x, out_y, out_z; - ::gluProject((GLdouble)pos(0), (GLdouble)pos(1), (GLdouble)pos(2), modelview_matrix, projection_matrix, viewport, &out_x, &out_y, &out_z); - out_y = m_canvas_height - out_y; + ::gluProject((GLdouble)pos(0), (GLdouble)pos(1), (GLdouble)pos(2), (GLdouble*)modelview_matrix.data(), (GLdouble*)projection_matrix.data(), (GLint*)viewport.data(), &out_x, &out_y, &out_z); + out_y = m_canvas_height - out_y; if (rectangle.contains(Point(out_x, out_y))) { bool is_obscured = false; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 7f4d4d495..3935e240a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -827,7 +827,7 @@ void GLGizmosManager::do_render_overlay(const GLCanvas3D& canvas, const Selectio float cnv_w = (float)canvas.get_canvas_size().get_width(); float cnv_h = (float)canvas.get_canvas_size().get_height(); - float zoom = canvas.get_camera_zoom(); + float zoom = canvas.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; float height = get_total_overlay_height(); diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 3f5f6ba4f..c568b41a8 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -971,7 +971,23 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field) const glsafe(::glTranslated(center(0), center(1), center(2))); if (!boost::starts_with(sidebar_field, "position")) { - Transform3d orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); + Transform3d orient_matrix = Transform3d::Identity(); + if (boost::starts_with(sidebar_field, "scale")) + orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); + else if (boost::starts_with(sidebar_field, "rotation")) + { + if (boost::ends_with(sidebar_field, "x")) + orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); + else if (boost::ends_with(sidebar_field, "y")) + { + const Vec3d& rotation = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation(); + if (rotation(0) == 0.0) + orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); + else + orient_matrix.rotate(Eigen::AngleAxisd(rotation(2), Vec3d::UnitZ())); + } + } + glsafe(::glMultMatrixd(orient_matrix.data())); } } |