From c624d6bb0a2ea122c6ba63cea30acb31452ecba0 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 14 Jun 2018 15:32:26 +0200 Subject: [PATCH] Hover on gizmo grabbers rendering --- xs/src/slic3r/GUI/GLCanvas3D.cpp | 40 +++++++++++++--- xs/src/slic3r/GUI/GLCanvas3D.hpp | 3 ++ xs/src/slic3r/GUI/GLGizmo.cpp | 82 +++++++++++++++++++++++++++++--- xs/src/slic3r/GUI/GLGizmo.hpp | 10 +++- 4 files changed, 121 insertions(+), 14 deletions(-) diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp index 0112f7a3c..64538d940 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp @@ -1202,6 +1202,18 @@ void GLCanvas3D::Gizmos::reset_all_states() m_current = Undefined; } +void GLCanvas3D::Gizmos::set_hover_id(int id) +{ + if (!m_enabled) + return; + + for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) + { + if ((it->second != nullptr) && (it->second->get_state() == GLGizmoBase::On)) + it->second->set_hover_id(id); + } +} + bool GLCanvas3D::Gizmos::overlay_contains_mouse(const GLCanvas3D& canvas, const Pointf& mouse_pos) const { if (!m_enabled) @@ -1245,6 +1257,20 @@ void GLCanvas3D::Gizmos::render(const GLCanvas3D& canvas, const BoundingBoxf3& b ::glPopMatrix(); } +void GLCanvas3D::Gizmos::render_current_gizmo_for_picking_pass(const BoundingBoxf3& box) const +{ + if (!m_enabled) + return; + + ::glDisable(GL_DEPTH_TEST); + + GizmosMap::const_iterator it = m_gizmos.find(m_current); + if (it == m_gizmos.end()) + return; + + it->second->render_for_picking(box); +} + void GLCanvas3D::Gizmos::_reset() { for (GizmosMap::value_type& gizmo : m_gizmos) @@ -3098,11 +3124,8 @@ void GLCanvas3D::_picking_pass() const ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - ::glPushAttrib(GL_ENABLE_BIT); - _render_volumes(true); - - ::glPopAttrib(); + m_gizmos.render_current_gizmo_for_picking_pass(_selected_volumes_bounding_box()); if (m_multisample_allowed) ::glEnable(GL_MULTISAMPLE); @@ -3110,7 +3133,7 @@ void GLCanvas3D::_picking_pass() const const Size& cnv_size = get_canvas_size(); GLubyte color[4]; - ::glReadPixels(pos.x, cnv_size.get_height() - pos.y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)color); + ::glReadPixels(pos.x, cnv_size.get_height() - pos.y - 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)color); int volume_id = color[0] + color[1] * 256 + color[2] * 256 * 256; m_hover_volume_id = -1; @@ -3133,7 +3156,10 @@ void GLCanvas3D::_picking_pass() const vol->hover = true; } } + m_gizmos.set_hover_id(-1); } + else + m_gizmos.set_hover_id(254 - (int)color[2]); // updates gizmos overlay if (_get_first_selected_object_id() != -1) @@ -3335,7 +3361,7 @@ void GLCanvas3D::_render_layer_editing_overlay() const void GLCanvas3D::_render_volumes(bool fake_colors) const { - static const float INV_255 = 1.0f / 255.0f; + static const GLfloat INV_255 = 1.0f / 255.0f; if (fake_colors) ::glDisable(GL_LIGHTING); @@ -3360,7 +3386,7 @@ void GLCanvas3D::_render_volumes(bool fake_colors) const unsigned int r = (volume_id & 0x000000FF) >> 0; unsigned int g = (volume_id & 0x0000FF00) >> 8; unsigned int b = (volume_id & 0x00FF0000) >> 16; - ::glColor4f((float)r * INV_255, (float)g * INV_255, (float)b * INV_255, 1.0f); + ::glColor3f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255); } else { diff --git a/xs/src/slic3r/GUI/GLCanvas3D.hpp b/xs/src/slic3r/GUI/GLCanvas3D.hpp index cdfc75876..5b835a806 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.hpp @@ -354,9 +354,12 @@ public: void update_on_off_state(const GLCanvas3D& canvas, const Pointf& mouse_pos); void reset_all_states(); + void set_hover_id(int id); + bool overlay_contains_mouse(const GLCanvas3D& canvas, const Pointf& mouse_pos) const; void render(const GLCanvas3D& canvas, const BoundingBoxf3& box) const; + void render_current_gizmo_for_picking_pass(const BoundingBoxf3& box) const; private: void _reset(); diff --git a/xs/src/slic3r/GUI/GLGizmo.cpp b/xs/src/slic3r/GUI/GLGizmo.cpp index 64df649d4..dd4e097b5 100644 --- a/xs/src/slic3r/GUI/GLGizmo.cpp +++ b/xs/src/slic3r/GUI/GLGizmo.cpp @@ -13,9 +13,11 @@ namespace GUI { const float GLGizmoBase::BaseColor[3] = { 1.0f, 1.0f, 1.0f }; const float GLGizmoBase::HighlightColor[3] = { 1.0f, 0.38f, 0.0f }; const float GLGizmoBase::GrabberHalfSize = 2.0f; +const float GLGizmoBase::HoverOffset = 0.5f; GLGizmoBase::GLGizmoBase() : m_state(Off) + , m_hover_id(-1) { } @@ -48,12 +50,22 @@ int GLGizmoBase::get_textures_size() const return m_textures[Off].get_width(); } +void GLGizmoBase::set_hover_id(int id) +{ + m_hover_id = id; +} + void GLGizmoBase::render(const BoundingBoxf3& box) const { on_render(box); } -void GLGizmoBase::_render_square(const Pointf3& center) const +void GLGizmoBase::render_for_picking(const BoundingBoxf3& box) const +{ + on_render_for_picking(box); +} + +void GLGizmoBase::render_grabber(const Pointf3& center, bool hover) const { float min_x = (float)center.x - GrabberHalfSize; float max_x = (float)center.x + GrabberHalfSize; @@ -70,6 +82,21 @@ void GLGizmoBase::_render_square(const Pointf3& center) const ::glVertex3f((GLfloat)min_x, (GLfloat)min_y, 0.0f); ::glEnd(); ::glEnable(GL_CULL_FACE); + + if (hover) + { + min_x -= HoverOffset; + max_x += HoverOffset; + min_y -= HoverOffset; + max_y += HoverOffset; + + ::glBegin(GL_LINE_LOOP); + ::glVertex3f((GLfloat)min_x, (GLfloat)min_y, 0.0f); + ::glVertex3f((GLfloat)max_x, (GLfloat)min_y, 0.0f); + ::glVertex3f((GLfloat)max_x, (GLfloat)max_y, 0.0f); + ::glVertex3f((GLfloat)min_x, (GLfloat)max_y, 0.0f); + ::glEnd(); + } } const float GLGizmoRotate::Offset = 5.0f; @@ -129,6 +156,22 @@ void GLGizmoRotate::on_render(const BoundingBoxf3& box) const _render_grabber(center, radius); } +void GLGizmoRotate::on_render_for_picking(const BoundingBoxf3& box) const +{ + ::glDisable(GL_LIGHTING); + ::glDisable(GL_DEPTH_TEST); + + const Pointf3& size = box.size(); + const Pointf3& center = box.center(); + + float radius = Offset + ::sqrt(sqr(0.5f * size.x) + sqr(0.5f * size.y)) + GrabberOffset; + float x = center.x + ::cos(m_angle_z) * radius; + float y = center.y + ::sin(m_angle_z) * radius; + + ::glColor3f(1.0f, 1.0f, 254.0f / 255.0f); + render_grabber(Pointf3((coordf_t)x, (coordf_t)y, 0.0), false); +} + void GLGizmoRotate::_render_circle(const Pointf3& center, float radius) const { ::glBegin(GL_LINE_LOOP); @@ -206,7 +249,7 @@ void GLGizmoRotate::_render_grabber(const Pointf3& center, float radius) const ::glEnd(); ::glColor3fv(HighlightColor); - _render_square(Pointf3((coordf_t)x, (coordf_t)y, 0.0)); + render_grabber(Pointf3((coordf_t)x, (coordf_t)y, 0.0), (m_hover_id != -1)); } const float GLGizmoScale::Offset = 5.0f; @@ -264,10 +307,37 @@ void GLGizmoScale::on_render(const BoundingBoxf3& box) const // draw grabbers ::glColor3fv(HighlightColor); - _render_square(Pointf3(min_x, min_y, 0.0)); - _render_square(Pointf3(max_x, min_y, 0.0)); - _render_square(Pointf3(max_x, max_y, 0.0)); - _render_square(Pointf3(min_x, max_y, 0.0)); + render_grabber(Pointf3(min_x, min_y, 0.0), (m_hover_id == 0)); + render_grabber(Pointf3(max_x, min_y, 0.0), (m_hover_id == 1)); + render_grabber(Pointf3(max_x, max_y, 0.0), (m_hover_id == 2)); + render_grabber(Pointf3(min_x, max_y, 0.0), (m_hover_id == 3)); +} + +void GLGizmoScale::on_render_for_picking(const BoundingBoxf3& box) const +{ + static const GLfloat INV_255 = 1.0f / 255.0f; + + ::glDisable(GL_LIGHTING); + ::glDisable(GL_DEPTH_TEST); + + const Pointf3& size = box.size(); + const Pointf3& center = box.center(); + + Pointf half_scaled_size = 0.5 * Pointf((coordf_t)m_scale_x * size.x, (coordf_t)m_scale_y * size.y); + coordf_t min_x = center.x - half_scaled_size.x - (coordf_t)Offset; + coordf_t max_x = center.x + half_scaled_size.x + (coordf_t)Offset; + coordf_t min_y = center.y - half_scaled_size.y - (coordf_t)Offset; + coordf_t max_y = center.y + half_scaled_size.y + (coordf_t)Offset; + + // draw grabbers + ::glColor3f(1.0f, 1.0f, 254.0f * INV_255); + render_grabber(Pointf3(min_x, min_y, 0.0), false); + ::glColor3f(1.0f, 1.0f, 253.0f * INV_255); + render_grabber(Pointf3(max_x, min_y, 0.0), false); + ::glColor3f(1.0f, 1.0f, 252.0f * INV_255); + render_grabber(Pointf3(max_x, max_y, 0.0), false); + ::glColor3f(1.0f, 1.0f, 251.0f * INV_255); + render_grabber(Pointf3(min_x, max_y, 0.0), false); } } // namespace GUI diff --git a/xs/src/slic3r/GUI/GLGizmo.hpp b/xs/src/slic3r/GUI/GLGizmo.hpp index b3e6fd8fd..5ee5f3bee 100644 --- a/xs/src/slic3r/GUI/GLGizmo.hpp +++ b/xs/src/slic3r/GUI/GLGizmo.hpp @@ -16,6 +16,7 @@ protected: static const float BaseColor[3]; static const float HighlightColor[3]; static const float GrabberHalfSize; + static const float HoverOffset; public: enum EState @@ -31,6 +32,7 @@ protected: // textures are assumed to be square and all with the same size in pixels // no internal check is done GLTexture m_textures[Num_States]; + int m_hover_id; public: GLGizmoBase(); @@ -44,13 +46,17 @@ public: unsigned int get_textures_id() const; int get_textures_size() const; + void set_hover_id(int id); + void render(const BoundingBoxf3& box) const; + void render_for_picking(const BoundingBoxf3& box) const; protected: virtual bool on_init() = 0; virtual void on_render(const BoundingBoxf3& box) const = 0; + virtual void on_render_for_picking(const BoundingBoxf3& box) const = 0; - void _render_square(const Pointf3& center) const; + void render_grabber(const Pointf3& center, bool hover) const; }; class GLGizmoRotate : public GLGizmoBase @@ -75,6 +81,7 @@ public: protected: virtual bool on_init(); virtual void on_render(const BoundingBoxf3& box) const; + virtual void on_render_for_picking(const BoundingBoxf3& box) const; private: void _render_circle(const Pointf3& center, float radius) const; @@ -98,6 +105,7 @@ public: protected: virtual bool on_init(); virtual void on_render(const BoundingBoxf3& box) const; + virtual void on_render_for_picking(const BoundingBoxf3& box) const; }; } // namespace GUI