From 96bd100474a4b58aa3d0ed250f4b72fa7645ceb1 Mon Sep 17 00:00:00 2001 From: Sylvain Thery Date: Mon, 18 Jul 2011 17:29:29 +0200 Subject: [PATCH] Add 2D manipulation on frames --- Apps/Examples/frame_manip.cpp | 108 ++++++++++++++++++++++--------- include/Utils/frameManipulator.h | 11 ++++ src/Utils/frameManipulator.cpp | 60 ++++++++++++++--- src/Utils/pickables.cpp | 5 -- src/Utils/qtgl.cpp | 2 +- 5 files changed, 140 insertions(+), 46 deletions(-) diff --git a/Apps/Examples/frame_manip.cpp b/Apps/Examples/frame_manip.cpp index 917238c5..e3742ec1 100644 --- a/Apps/Examples/frame_manip.cpp +++ b/Apps/Examples/frame_manip.cpp @@ -174,9 +174,6 @@ void MyQT::cb_mousePress(int button, int x, int y) m_pickedAxis=fr_picked; } - // project center & axis on screen for easy manipulation - if (m_pickedAxis != Utils::FrameManipulator::NONE) - m_frame->storeProjection(m_pickedAxis); // highlighting m_frame->highlight(m_pickedAxis); @@ -192,33 +189,60 @@ void MyQT::cb_mousePress(int button, int x, int y) } } + // store origin & selected axis on on screen projection for easy manipulation. + m_frame->storeProjection(m_pickedAxis); + updateGL(); } -void MyQT::cb_mouseMove(int button, int x, int y) +void MyQT::cb_mouseMove(int buttons, int x, int y) { if (!Shift()) return; + // rotation selected ? if (Utils::FrameManipulator::rotationAxis(m_pickedAxis)) { - float angle = m_frame->angleFromMouse(x,y,x-m_begX, y-m_begY); - m_frame->rotate(m_pickedAxis, angle); + if (buttons&1) + { + float angle = m_frame->angleFromMouse(x,y,x-m_begX, y-m_begY); + m_frame->rotate(m_pickedAxis, angle); + } + else if (buttons&2) + m_frame->rotateInScreen(x-m_begX, y-m_begY); + m_lastPickedObject->transfo() = m_frame->transfo(); } + // translation selected else if (Utils::FrameManipulator::translationAxis(m_pickedAxis)) { - float dist = m_frame->distanceFromMouse(x-m_begX, y-m_begY); - m_frame->translate(m_pickedAxis, dist); + if (buttons&1) + { + float dist = m_frame->distanceFromMouse(x-m_begX, y-m_begY); + m_frame->translate(m_pickedAxis, dist); + } + else if (buttons&2) + m_frame->translateInScreen(x-m_begX, y-m_begY); + m_lastPickedObject->transfo() = m_frame->transfo(); } + // scale selected else if (Utils::FrameManipulator::scaleAxis(m_pickedAxis) ) { float scale = m_frame->scaleFromMouse(x-m_begX, y-m_begY); m_frame->scale(m_pickedAxis, scale ); m_lastPickedObject->transfo() = m_frame->transfo(); } +// // nothing selected: using screen translation/rotation (button left/right) +// else if (m_lastPickedObject) +// { +// if (buttons&1) +// m_frame->translateInScreen(x-m_begX, y-m_begY); +// else if (buttons&2) +// m_frame->rotateInScreen(x-m_begX, y-m_begY); +// m_lastPickedObject->transfo() = m_frame->transfo(); +// } m_begX = x; m_begY = y; @@ -274,42 +298,61 @@ void MyQT::cb_keyPress(int code) m_frame->setTransformation(m_lastPickedObject->transfo()); break; case 'x': - m_frame->lock(Utils::FrameManipulator::Xt); + if (m_frame->locked(Utils::FrameManipulator::Xt)) + m_frame->unlock(Utils::FrameManipulator::Xt); + else + m_frame->lock(Utils::FrameManipulator::Xt); break; case 'y': - m_frame->lock(Utils::FrameManipulator::Yt); + if (m_frame->locked(Utils::FrameManipulator::Yt)) + m_frame->unlock(Utils::FrameManipulator::Yt); + else + m_frame->lock(Utils::FrameManipulator::Yt); break; case 'z': - m_frame->lock(Utils::FrameManipulator::Zt); - break; - case 'X': - m_frame->unlock(Utils::FrameManipulator::Xt); - break; - case 'Y': - m_frame->unlock(Utils::FrameManipulator::Yt); - break; - case 'Z': - m_frame->unlock(Utils::FrameManipulator::Zt); + if (m_frame->locked(Utils::FrameManipulator::Zt)) + m_frame->unlock(Utils::FrameManipulator::Zt); + else + m_frame->lock(Utils::FrameManipulator::Zt); break; - case 'a': - m_frame->lock(Utils::FrameManipulator::Xr); + if (m_frame->locked(Utils::FrameManipulator::Xr)) + m_frame->unlock(Utils::FrameManipulator::Xr); + else + m_frame->lock(Utils::FrameManipulator::Xr); break; case 'b': - m_frame->lock(Utils::FrameManipulator::Yr); + if (m_frame->locked(Utils::FrameManipulator::Yr)) + m_frame->unlock(Utils::FrameManipulator::Yr); + else + m_frame->lock(Utils::FrameManipulator::Yr); break; case 'c': - m_frame->lock(Utils::FrameManipulator::Zr); + if (m_frame->locked(Utils::FrameManipulator::Zr)) + m_frame->unlock(Utils::FrameManipulator::Zr); + else + m_frame->lock(Utils::FrameManipulator::Zr); break; - case 'A': - m_frame->unlock(Utils::FrameManipulator::Xr); + + case 's': + if (m_frame->locked(Utils::FrameManipulator::Xs)) + m_frame->unlock(Utils::FrameManipulator::Xs); + else + m_frame->lock(Utils::FrameManipulator::Xs); break; - case 'B': - m_frame->unlock(Utils::FrameManipulator::Yr); + case 't': + if (m_frame->locked(Utils::FrameManipulator::Ys)) + m_frame->unlock(Utils::FrameManipulator::Ys); + else + m_frame->lock(Utils::FrameManipulator::Ys); break; - case 'C': - m_frame->unlock(Utils::FrameManipulator::Zr); + case 'u': + if (m_frame->locked(Utils::FrameManipulator::Zs)) + m_frame->unlock(Utils::FrameManipulator::Zs); + else + m_frame->lock(Utils::FrameManipulator::Zs); break; + } updateGL(); } @@ -326,6 +369,11 @@ int main(int argc, char **argv) if (argc>1) sqt.NBP = atoi(argv[1]); + + sqt.setHelpMsg("Param :size of grid (number of objects)\nMpuse:\n" + " -click on object: selection\n -left click on frame: constraint 3d Rotation/Translation/Scale\n" + " -right click on frame :free 2D Rotation/Translation\nKeys:\n x/y/z lock/unlock translation\n a/b/c lock/unlock rotation\n s/t/u lock/unlock scaling"); + // bounding box Geom::Vec3f lPosObj = Geom::Vec3f(0.0f,0.0f,0.0f); float lWidthObj = sqt.NBP*4.0f; diff --git a/include/Utils/frameManipulator.h b/include/Utils/frameManipulator.h index d98ff139..e3f9074c 100644 --- a/include/Utils/frameManipulator.h +++ b/include/Utils/frameManipulator.h @@ -428,6 +428,11 @@ public: */ void unlock(unsigned int axis); + /** + * is an axis locked + */ + bool locked(unsigned int axis); + /** * higlight an axis (change width rendering). * To unhighlight, just highlight NONE or highlight a already highlighted axis @@ -508,6 +513,12 @@ public: static bool translationAxis(unsigned int axis) { return (axis>=Xt) && (axis<=Zt);} static bool scaleAxis(unsigned int axis) { return ((axis>=Xs) && (axis<=Zs))|| (axis==CENTER);} + /** + * translate from screen mouse move + */ + void translateInScreen(int dx, int dy); + + void rotateInScreen(int dx, int dy); }; diff --git a/src/Utils/frameManipulator.cpp b/src/Utils/frameManipulator.cpp index a731bec1..bc974169 100644 --- a/src/Utils/frameManipulator.cpp +++ b/src/Utils/frameManipulator.cpp @@ -618,17 +618,21 @@ void FrameManipulator::setTransformation( const glm::mat4& transfo) m_rotations[2][2] = Rz[2]; } -void FrameManipulator::lock(unsigned int axis) +void FrameManipulator::lock(unsigned int axis) { m_locked_axis[axis] = true; } -void FrameManipulator::unlock(unsigned int axis) +void FrameManipulator::unlock(unsigned int axis) { m_locked_axis[axis] = false; } +bool FrameManipulator::locked(unsigned int axis) +{ + return m_locked_axis[axis]; +} Geom::Vec3f FrameManipulator::getAxis(unsigned int ax) { @@ -641,19 +645,20 @@ Geom::Vec3f FrameManipulator::getAxis(unsigned int ax) void FrameManipulator::storeProjection(unsigned int ax) { Geom::Vec3f O = getPosition(); - Geom::Vec3f A = getAxis(ax); - A += O; glm::i32vec4 viewport; glGetIntegerv(GL_VIEWPORT, &(viewport[0])); glm::vec3 winO = glm::project(glm::vec3(O[0],O[1],O[2]), GLSLShader::currentModelView(), GLSLShader::currentProjection(), viewport); - glm::vec3 winA = glm::project(glm::vec3(A[0],A[1],A[2]), GLSLShader::currentModelView(), GLSLShader::currentProjection(), viewport); + m_projectedOrigin = Geom::Vec3f(winO[0], winO[1], winO[2]); + + if (ax>CENTER) + { + Geom::Vec3f A = getAxis(ax); + A += O; + glm::vec3 winA = glm::project(glm::vec3(A[0],A[1],A[2]), GLSLShader::currentModelView(), GLSLShader::currentProjection(), viewport); + m_projectedSelectedAxis = Geom::Vec3f(winA[0]-winO[0], winA[1]-winO[1],winA[2]-winO[2]); + } - m_projectedOrigin = Geom::Vec3f(winO[0],winO[1],0.0f); - if (winA[2]-winO[2] < 0.0f) - m_projectedSelectedAxis = Geom::Vec3f(winA[0]-winO[0], winA[1]-winO[1],-1.0f); - else - m_projectedSelectedAxis = Geom::Vec3f(winA[0]-winO[0], winA[1]-winO[1],1.0f); } @@ -693,5 +698,40 @@ float FrameManipulator::scaleFromMouse(int dx, int dy) return 1.0f + sc; } +void FrameManipulator::translateInScreen(int dx, int dy) +{ + glm::i32vec4 viewport; + glGetIntegerv(GL_VIEWPORT, &(viewport[0])); + + Geom::Vec3f NO = m_projectedOrigin+Geom::Vec3f(float(dx), float(dy), 0.0f); + + glm::vec3 P = glm::unProject(glm::vec3(NO[0],NO[1],NO[2]), GLSLShader::currentModelView(), GLSLShader::currentProjection(), viewport); + + m_trans[0] = P[0]; + m_trans[1] = P[1]; + m_trans[2] = P[2]; + storeProjection(NONE); + +} + +void FrameManipulator::rotateInScreen(int dx, int dy) +{ + glm::i32vec4 viewport; + glGetIntegerv(GL_VIEWPORT, &(viewport[0])); + + Geom::Vec3f NO = m_projectedOrigin+Geom::Vec3f(float(-dy), float(dx), 0.0f); + + glm::vec3 P = glm::unProject(glm::vec3(NO[0],NO[1],NO[2]), GLSLShader::currentModelView(), GLSLShader::currentProjection(), viewport); + + Geom::Vec3f axisRotation(P[0]-m_trans[0], P[1]-m_trans[1], P[2]-m_trans[2]); + axisRotation.normalize(); + + glm::mat4 tr = glm::rotate(glm::mat4(1.0f),float(sqrtf(dx*dx+dy*dy))/2.0f,glm::vec3(axisRotation[0],axisRotation[1],axisRotation[2])); + m_rotations = tr*m_rotations; + +} + + + } } diff --git a/src/Utils/pickables.cpp b/src/Utils/pickables.cpp index 54b50b9a..8d68b219 100644 --- a/src/Utils/pickables.cpp +++ b/src/Utils/pickables.cpp @@ -333,14 +333,9 @@ void Sphere::changeTopo(unsigned int parp, unsigned int mer) unsigned int merAll = merfactor * mer; unsigned int parAll = parfactor* (par+1); -// parAll += 1; - std::vector points; points.reserve(parAll*merAll+2); - - std::cout << "PAR="<