From bc5640eef4e9f3dcbe83cc52dfa35fed6fe6a480 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 14 Jun 2018 10:00:59 +0200 Subject: Rotate gizmo rendering --- xs/src/slic3r/GUI/GLGizmo.cpp | 158 +++++++++++++++++++++++++++++++++++------- xs/src/slic3r/GUI/GLGizmo.hpp | 28 ++++++-- 2 files changed, 157 insertions(+), 29 deletions(-) (limited to 'xs') diff --git a/xs/src/slic3r/GUI/GLGizmo.cpp b/xs/src/slic3r/GUI/GLGizmo.cpp index 75f39aad9..d98864931 100644 --- a/xs/src/slic3r/GUI/GLGizmo.cpp +++ b/xs/src/slic3r/GUI/GLGizmo.cpp @@ -10,6 +10,10 @@ namespace Slic3r { 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; + GLGizmoBase::GLGizmoBase() : m_state(Off) { @@ -49,6 +53,35 @@ void GLGizmoBase::render(const BoundingBoxf3& box) const on_render(box); } +void GLGizmoBase::_render_square(const Pointf3& center) const +{ + float min_x = (float)center.x - GrabberHalfSize; + float max_x = (float)center.x + GrabberHalfSize; + float min_y = (float)center.y - GrabberHalfSize; + float max_y = (float)center.y + GrabberHalfSize; + + ::glDisable(GL_CULL_FACE); + ::glBegin(GL_TRIANGLES); + ::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)max_x, (GLfloat)max_y, 0.0f); + ::glVertex3f((GLfloat)min_x, (GLfloat)max_y, 0.0f); + ::glVertex3f((GLfloat)min_x, (GLfloat)min_y, 0.0f); + ::glEnd(); + ::glEnable(GL_CULL_FACE); +} + +const float GLGizmoRotate::Offset = 5.0f; +const unsigned int GLGizmoRotate::CircleResolution = 64; +const unsigned int GLGizmoRotate::ScaleStepsCount = 60; +const float GLGizmoRotate::ScaleStepRad = 2.0f * (float)PI / GLGizmoRotate::ScaleStepsCount; +const unsigned int GLGizmoRotate::ScaleLongEvery = 5; +const float GLGizmoRotate::ScaleLongTooth = 2.0f; +const float GLGizmoRotate::ScaleShortTooth = 1.0f; +const unsigned int GLGizmoRotate::SnapRegionsCount = 8; +const float GLGizmoRotate::GrabberOffset = 5.0f; + GLGizmoRotate::GLGizmoRotate() : GLGizmoBase() , m_angle_x(0.0f) @@ -78,11 +111,105 @@ bool GLGizmoRotate::on_init() void GLGizmoRotate::on_render(const BoundingBoxf3& box) const { - std::cout << "GLGizmoRotate::render()" << std::endl; + ::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)); + + ::glLineWidth(2.0f); + ::glColor3fv(BaseColor); + + _render_circle(center, radius); + _render_scale(center, radius); + _render_snap_radii(center, radius); + _render_reference_radius(center, radius); + _render_grabber(center, radius); +} + +void GLGizmoRotate::_render_circle(const Pointf3& center, float radius) const +{ + ::glBegin(GL_LINE_LOOP); + for (unsigned int i = 0; i < ScaleStepsCount; ++i) + { + float angle = (float)i * ScaleStepRad; + float x = center.x + ::cos(angle) * radius; + float y = center.y + ::sin(angle) * radius; + ::glVertex3f((GLfloat)x, (GLfloat)y, 0.0f); + } + ::glEnd(); +} + +void GLGizmoRotate::_render_scale(const Pointf3& center, float radius) const +{ + float out_radius_long = radius + ScaleLongTooth; + float out_radius_short = radius + ScaleShortTooth; + + ::glBegin(GL_LINES); + for (unsigned int i = 0; i < ScaleStepsCount; ++i) + { + float angle = (float)i * ScaleStepRad; + float cosa = ::cos(angle); + float sina = ::sin(angle); + float in_x = center.x + cosa * radius; + float in_y = center.y + sina * radius; + float out_x = (i % ScaleLongEvery == 0) ? center.x + cosa * out_radius_long : center.x + cosa * out_radius_short; + float out_y = (i % ScaleLongEvery == 0) ? center.y + sina * out_radius_long : center.y + sina * out_radius_short; + ::glVertex3f((GLfloat)in_x, (GLfloat)in_y, 0.0f); + ::glVertex3f((GLfloat)out_x, (GLfloat)out_y, 0.0f); + } + ::glEnd(); +} + +void GLGizmoRotate::_render_snap_radii(const Pointf3& center, float radius) const +{ + float step_deg = 2.0f * (float)PI / (float)SnapRegionsCount; + + float in_radius = radius / 3.0f; + float out_radius = 2.0f * in_radius; + + ::glBegin(GL_LINES); + for (unsigned int i = 0; i < SnapRegionsCount; ++i) + { + float angle = (float)i * step_deg; + float cosa = ::cos(angle); + float sina = ::sin(angle); + float in_x = center.x + cosa * in_radius; + float in_y = center.y + sina * in_radius; + float out_x = center.x + cosa * out_radius; + float out_y = center.y + sina * out_radius; + ::glVertex3f((GLfloat)in_x, (GLfloat)in_y, 0.0f); + ::glVertex3f((GLfloat)out_x, (GLfloat)out_y, 0.0f); + } + ::glEnd(); +} + +void GLGizmoRotate::_render_reference_radius(const Pointf3& center, float radius) const +{ + ::glBegin(GL_LINES); + ::glVertex3f((GLfloat)center.x, (GLfloat)center.y, 0.0f); + ::glVertex3f((GLfloat)center.x + radius, (GLfloat)center.y, 0.0f); + ::glEnd(); +} + +void GLGizmoRotate::_render_grabber(const Pointf3& center, float radius) const +{ + float grabber_radius = radius + GrabberOffset; + float x = center.x + ::cos(m_angle_z) * grabber_radius; + float y = center.y + ::sin(m_angle_z) * grabber_radius; + + ::glBegin(GL_LINES); + ::glVertex3f((GLfloat)center.x, (GLfloat)center.y, 0.0f); + ::glVertex3f((GLfloat)x, (GLfloat)y, 0.0f); + ::glEnd(); + + ::glColor3fv(HighlightColor); + _render_square(Pointf3((coordf_t)x, (coordf_t)y, 0.0)); } const float GLGizmoScale::Offset = 5.0f; -const float GLGizmoScale::SquareHalfSize = 2.0f; GLGizmoScale::GLGizmoScale() : GLGizmoBase() @@ -119,16 +246,16 @@ void GLGizmoScale::on_render(const BoundingBoxf3& box) const const Pointf3& size = box.size(); const Pointf3& center = box.center(); - Pointf3 half_scaled_size = 0.5 * Pointf3((coordf_t)m_scale_x * size.x, (coordf_t)m_scale_y * size.y, (coordf_t)m_scale_z * size.z); + 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; ::glLineWidth(2.0f); - ::glBegin(GL_LINE_LOOP); + ::glColor3fv(BaseColor); // draw outline - ::glColor3f(1.0f, 1.0f, 1.0f); + ::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); @@ -136,30 +263,11 @@ void GLGizmoScale::on_render(const BoundingBoxf3& box) const ::glEnd(); // draw grabbers - ::glColor3f(1.0f, 0.38f, 0.0f); - ::glDisable(GL_CULL_FACE); + ::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)); - ::glEnable(GL_CULL_FACE); -} - -void GLGizmoScale::_render_square(const Pointf3& center) const -{ - float min_x = (float)center.x - SquareHalfSize; - float max_x = (float)center.x + SquareHalfSize; - float min_y = (float)center.y - SquareHalfSize; - float max_y = (float)center.y + SquareHalfSize; - - ::glBegin(GL_TRIANGLES); - ::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)max_x, (GLfloat)max_y, 0.0f); - ::glVertex3f((GLfloat)min_x, (GLfloat)max_y, 0.0f); - ::glVertex3f((GLfloat)min_x, (GLfloat)min_y, 0.0f); - ::glEnd(); } } // namespace GUI diff --git a/xs/src/slic3r/GUI/GLGizmo.hpp b/xs/src/slic3r/GUI/GLGizmo.hpp index a626305c1..b3e6fd8fd 100644 --- a/xs/src/slic3r/GUI/GLGizmo.hpp +++ b/xs/src/slic3r/GUI/GLGizmo.hpp @@ -12,6 +12,11 @@ namespace GUI { class GLGizmoBase { +protected: + static const float BaseColor[3]; + static const float HighlightColor[3]; + static const float GrabberHalfSize; + public: enum EState { @@ -44,10 +49,22 @@ public: protected: virtual bool on_init() = 0; virtual void on_render(const BoundingBoxf3& box) const = 0; + + void _render_square(const Pointf3& center) const; }; class GLGizmoRotate : public GLGizmoBase { + static const float Offset; + static const unsigned int CircleResolution; + static const unsigned int ScaleStepsCount; + static const float ScaleStepRad; + static const unsigned int ScaleLongEvery; + static const float ScaleLongTooth; + static const float ScaleShortTooth; + static const unsigned int SnapRegionsCount; + static const float GrabberOffset; + float m_angle_x; float m_angle_y; float m_angle_z; @@ -58,12 +75,18 @@ public: protected: virtual bool on_init(); virtual void on_render(const BoundingBoxf3& box) const; + +private: + void _render_circle(const Pointf3& center, float radius) const; + void _render_scale(const Pointf3& center, float radius) const; + void _render_snap_radii(const Pointf3& center, float radius) const; + void _render_reference_radius(const Pointf3& center, float radius) const; + void _render_grabber(const Pointf3& center, float radius) const; }; class GLGizmoScale : public GLGizmoBase { static const float Offset; - static const float SquareHalfSize; float m_scale_x; float m_scale_y; @@ -75,9 +98,6 @@ public: protected: virtual bool on_init(); virtual void on_render(const BoundingBoxf3& box) const; - -private: - void _render_square(const Pointf3& center) const; }; } // namespace GUI -- cgit v1.2.3