From dffab7d2dfe2897f4c4021a6a486123ecd6189ee Mon Sep 17 00:00:00 2001 From: brunoherbelin Date: Mon, 8 Jun 2020 00:03:57 +0200 Subject: [PATCH] Fix rotation transform --- Decorations.cpp | 25 +++++++++++++++++++++++-- PickingVisitor.cpp | 9 ++++----- View.cpp | 10 ++++++++-- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/Decorations.cpp b/Decorations.cpp index 26a9336..7fe74e0 100644 --- a/Decorations.cpp +++ b/Decorations.cpp @@ -1,11 +1,13 @@ #include #include +#include #include "Decorations.h" #include "Visitor.h" #include "ImageShader.h" #include "GlmToolkit.h" +#include "Log.h" Frame::Frame(Type type) : Node(), type_(type), side_(nullptr), top_(nullptr), shadow_(nullptr), square_(nullptr) @@ -163,6 +165,11 @@ void Handles::draw(glm::mat4 modelview, glm::mat4 projection) glm::vec3 rot(0.f); glm::vec4 vec = modelview * glm::vec4(1.f, 0.f, 0.f, 0.f); rot.z = glm::orientedAngle( glm::vec3(1.f, 0.f, 0.f), glm::normalize(glm::vec3(vec)), glm::vec3(0.f, 0.f, 1.f) ); + vec = modelview * glm::vec4(0.f, 1.f, 0.f, 1.f); +// glm::vec3 scale( vec.x > 0.f ? 1.f : -1.f, vec.y > 0.f ? 1.f : -1.f, 1.f); +// glm::vec3 scale(1.f, 1.f, 1.f); + +// Log::Info(" (0,1) becomes (%f, %f)", scale.x, scale.y); if ( type_ == RESIZE ) { @@ -207,10 +214,24 @@ void Handles::draw(glm::mat4 modelview, glm::mat4 projection) // one icon in top right corner // 1. Fixed displacement by (0.12,0.12) along the rotation.. ctm = GlmToolkit::transform(glm::vec4(0.f), rot, glm::vec3(1.f)); - vec = ctm * glm::vec4(0.12f, 0.12f, 0.f, 1.f); + glm::vec4 pos = ctm * glm::vec4(0.12f, 0.12f, 0.f, 1.f); +// Log::Info(" (0.12,0.12) becomes (%f, %f)", pos.x, pos.y); // 2. ..from the top right corner (1,1) - vec = ( modelview * glm::vec4(1.f, 1.f, 0.f, 1.f) ) + vec; + vec = ( modelview * glm::vec4(1.f, 1.f, 0.f, 1.f) ) + pos; ctm = GlmToolkit::transform(vec, rot, glm::vec3(1.f)); + +// TODO fix problem with negative scale +// glm::vec4 target = modelview * glm::vec4(1.2f, 1.2f, 0.f, 1.f); + +// vec = modelview * glm::vec4(1.f, 1.f, 0.f, 1.f); +// glm::vec4 dv = target - vec; + +// Log::Info("dv (%f, %f)", dv.x, dv.y); +// float m = dv.x < dv.y ? dv.x : dv.y; +// Log::Info("min %f", m); + +// ctm = GlmToolkit::transform( glm::vec3(target), rot, glm::vec3(1.f)); + handle_->draw( ctm, projection ); } } diff --git a/PickingVisitor.cpp b/PickingVisitor.cpp index de473e0..88feebc 100644 --- a/PickingVisitor.cpp +++ b/PickingVisitor.cpp @@ -78,8 +78,6 @@ void PickingVisitor::visit(Handles &n) // apply inverse transform to the point of interest glm::vec4 P = glm::inverse(modelview_) * glm::vec4( point_, 0.f, 1.f ); - Log::Info("P (%f, %f)", P.x, P.y); - // inverse transform to check the scale glm::vec4 S = glm::inverse(modelview_) * glm::vec4( 0.05f, 0.05f, 0.f, 0.f ); float scale = glm::length( glm::vec2(S) ); @@ -103,9 +101,10 @@ void PickingVisitor::visit(Handles &n) glm::length(glm::vec2(0.f, -1.f)- glm::vec2(P)) < scale ); } else if ( n.type() == Handles::ROTATE ){ - // the icon for rotation is on the right top corner at (0.12, 0.12) in screen coordinates - glm::vec4 vec = glm::inverse(modelview_) * glm::vec4( 0.12f, 0.12f, 0.f, 0.f ); - picked = glm::length( glm::vec2( 1.f + glm::abs(vec.x), 1.f + glm::abs(vec.y)) - glm::vec2(P) ) < scale; + // the icon for rotation is on the right top corner at (0.12, 0.12) in scene coordinates + glm::vec4 vec = glm::inverse(modelview_) * glm::vec4( 0.1f, 0.1f, 0.f, 0.f ); + float l = glm::length( glm::vec2(vec) ); + picked = glm::length( glm::vec2( 1.f + l, 1.f + l) - glm::vec2(P) ) < 1.5f * scale; } if ( picked ) diff --git a/View.cpp b/View.cpp index 03deb34..c7a3ba1 100644 --- a/View.cpp +++ b/View.cpp @@ -384,11 +384,11 @@ View::Cursor GeometryView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::p // grab coordinates in scene-View reference frame glm::vec3 gl_Position_from = Rendering::manager().unProject(from, scene.root()->transform_); - glm::vec3 gl_Position_to = Rendering::manager().unProject(to, scene.root()->transform_); + glm::vec3 gl_Position_to = Rendering::manager().unProject(to, scene.root()->transform_); // grab coordinates in source-root reference frame glm::vec4 S_from = glm::inverse(sourceNode->transform_) * glm::vec4( gl_Position_from, 1.f ); - glm::vec4 S_to = glm::inverse(sourceNode->transform_) * glm::vec4( gl_Position_to, 1.f ); + glm::vec4 S_to = glm::inverse(sourceNode->transform_) * glm::vec4( gl_Position_to, 1.f ); glm::vec3 S_resize = glm::vec3(S_to) / glm::vec3(S_from); // Log::Info(" screen coordinates ( %.1f, %.1f ) ", to.x, to.y); @@ -441,7 +441,13 @@ View::Cursor GeometryView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::p } // picking on the rotating handle else if ( pick.first == s->rotate_handle_ ) { + // rotation center to center of source + glm::mat4 T = glm::translate(glm::identity(), start_translation); + S_from = glm::inverse(T) * glm::vec4( gl_Position_from, 1.f ); + S_to = glm::inverse(T) * glm::vec4( gl_Position_to, 1.f ); + // angle float angle = glm::orientedAngle( glm::normalize(glm::vec2(S_from)), glm::normalize(glm::vec2(S_to))); + // apply rotation on Z axis sourceNode->rotation_ = start_rotation + glm::vec3(0.f, 0.f, angle); int degrees = int( glm::degrees(sourceNode->rotation_.z) );