From 8381f2f5a0cb052cc723288d18c1b54365e23de9 Mon Sep 17 00:00:00 2001 From: ponchio Date: Fri, 14 May 2004 03:15:09 +0000 Subject: [PATCH] Redesigned partial version. --- wrap/gui/trackball.cpp | 334 ++++++++++++++++++++--------------------- wrap/gui/trackball.h | 241 ++++++++++++++--------------- wrap/gui/trackmode.cpp | 170 +++++++++++---------- wrap/gui/trackmode.h | 63 ++++---- 4 files changed, 408 insertions(+), 400 deletions(-) diff --git a/wrap/gui/trackball.cpp b/wrap/gui/trackball.cpp index 67ceb7fd..4c4f4572 100644 --- a/wrap/gui/trackball.cpp +++ b/wrap/gui/trackball.cpp @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.6 2004/05/12 20:55:18 ponchio +*** empty log message *** + Revision 1.5 2004/05/07 12:46:08 cignoni Restructured and adapted in a better way to opengl @@ -54,17 +57,24 @@ Transform::Transform() { center=Point3f(0,0,0); } -Trackball::Trackball(): current_button(0), last_x(-1), last_y(-1), dragging(false), - spinnable(true), spinning(false), history_size(10) { - //qui si aggiungono tutte le actions - actions[0] = Action(LOCAL, NONE); - actions[BUTTON_LEFT] = Action(VIEW, ROTATE); - actions[BUTTON_LEFT | KEY_CTRL] = Action(VIEW, DRAG_XY); - actions[BUTTON_LEFT | KEY_SHIFT] = Action(VIEW, SCALE); - actions[WHEEL] = Action(SCREEN, SCALE); +Trackball::Trackball(): current_button(0), current_mode(NULL), + dragging(false), spinnable(true), spinning(false), + history_size(10) { + //here we add mode + modes[0] = NULL; + modes[BUTTON_LEFT] = new SphereMode(); + modes[BUTTON_LEFT | KEY_CTRL] = new PlaneMode(Plane3f(0, Point3f(1, 0, 0))); + modes[BUTTON_LEFT | KEY_SHIFT] = new ScaleMode(); + modes[WHEEL] = new ScaleMode(); SetCurrentAction(); } +Trackball::~Trackball() { + map::iterator i; + for(i = modes.begin(); i != modes.end(); i++) + delete (*i).second; +} + void Trackball::SetIdentity() { track.SetIdentity(); Reset(); @@ -73,153 +83,163 @@ void Trackball::SetPosition(const Point3f &c, int /* millisec */) { center = c; } -//operating void Trackball::GetView() { camera.GetView(); - //lets get view matrix + /* //lets get view matrix Similarityf m = last_track; - Point3f c_obj = m*center; //coordinate of the center of the trackball in obj coords - ScreenCenter = camera.Project(c_obj); //center of the trackball in screen coords. - ScreenRadius = 10.0f/Distance(center, camera.UnProject(Point3f(ScreenCenter[0] + 10, ScreenCenter[1], ScreenCenter[2]))); - + Point3f c_obj = m*center; //coordinate of the center of the trackball in obj coords + Point3f ScreenCenter = camera.Project(c_obj); //center of the trackball in screen coords. + Point3f ScreenRadius = 10.0f/Distance(center, camera.UnProject(Point3f(ScreenCenter[0] + 10, ScreenCenter[1], ScreenCenter[2]))); + Point3f X, Y, Z, C; - X = camera.UnProject(Point3f(ScreenCenter[0] + 100, ScreenCenter[1], ScreenCenter[2])); - Y = camera.UnProject(Point3f(ScreenCenter[0], ScreenCenter[1] - 100, ScreenCenter[2])); - Z = camera.UnProject(Point3f(ScreenCenter[0], ScreenCenter[1], ScreenCenter[2] + 0.1f)); + X = camera.UnProject(Point3f(ScreenCenter[0] + 100, ScreenCenter[1], ScreenCenter[2])); + Y = camera.UnProject(Point3f(ScreenCenter[0], ScreenCenter[1] - 100, ScreenCenter[2])); + Z = camera.UnProject(Point3f(ScreenCenter[0], ScreenCenter[1], ScreenCenter[2] + 0.1f)); C = c_obj; - X = X - C; X.Normalize(); - Y = Y - C; Y.Normalize(); - Z = X ^ Y; - - Matrix44f view_axis; //this is before applying last (or track...) + X = X - C; X.Normalize(); + Y = Y - C; Y.Normalize(); + Z = X ^ Y; + + Matrix44f view_axis; //this is before applying last (or track...) view_axis.SetIdentity(); - view_axis.element(0, 0) = X[0]; view_axis.element(0, 1) = X[1]; view_axis.element(0, 2) = X[2]; - view_axis.element(1, 0) = Y[0]; view_axis.element(1, 1) = Y[1]; view_axis.element(1, 2) = Y[2]; - view_axis.element(2, 0) = Z[0]; view_axis.element(2, 1) = Z[1]; view_axis.element(2, 2) = Z[2]; - view.SetIdentity(); - view.FromMatrix(view_axis); - //view = view * Inverse(Similarityf(track.rot)); - //spinning ignored + view_axis.element(0, 0) = X[0]; view_axis.element(0, 1) = X[1]; view_axis.element(0, 2) = X[2]; + view_axis.element(1, 0) = Y[0]; view_axis.element(1, 1) = Y[1]; view_axis.element(1, 2) = Y[2]; + view_axis.element(2, 0) = Z[0]; view_axis.element(2, 1) = Z[1]; view_axis.element(2, 2) = Z[2]; + view.SetIdentity(); + view.FromMatrix(view_axis); */ } + void Trackball::Apply() { glMultMatrix(track.Matrix()); } /***************************************************************/ -void Trackball::DrawCircle() -{ - const int nside=18; - const double pi2=3.14159265*2.0; - glBegin(GL_LINE_STRIP); - for(double i=0;i<=nside;i++){ - glNormal3d(cos(i*pi2/nside), sin(i*pi2/nside), 0.0); - glVertex3d(cos(i*pi2/nside), sin(i*pi2/nside), 0.0); - } - glEnd(); - DrawPlaneHandle(); +void Trackball::DrawCircle() { + const int nside=18; + const double pi2=3.14159265*2.0; + glBegin(GL_LINE_STRIP); + for(double i=0;i<=nside;i++){ + glNormal3d(cos(i*pi2/nside), sin(i*pi2/nside), 0.0); + glVertex3d(cos(i*pi2/nside), sin(i*pi2/nside), 0.0); + } + glEnd(); + DrawPlaneHandle(); } -void Trackball::DrawPlane() -{ - const int nl=10; - float w=5.0f/3.0f; - float u; - glBegin(GL_LINES); - glNormal3f(0.0,0.0,1.0); - for( u=-w; u<=w+0.01f; u+=2*w/nl){ - glVertex3f(-w, +u, 0); - glVertex3f(+w, +u, 0); - glVertex3f(+u, -w, 0); - glVertex3f(+u, +w, 0); - } - glEnd(); - } +void Trackball::DrawPlane() { + const int nl=10; + float w=5.0f/3.0f; + float u; + glBegin(GL_LINES); + glNormal3f(0.0,0.0,1.0); + for( u=-w; u<=w+0.01f; u+=2*w/nl){ + glVertex3f(-w, +u, 0); + glVertex3f(+w, +u, 0); + glVertex3f(+u, -w, 0); + glVertex3f(+u, +w, 0); + } + glEnd(); +} -void Trackball::DrawPlaneHandle() -{ - float r=1.0; - float dr=r/10.0f; - glBegin(GL_LINE_STRIP); - glVertex3f(+r+dr, +r, 0.0); - glVertex3f(+r , +r+dr,0.0); - glVertex3f(+r-dr, +r, 0.0); - glVertex3f(+r , +r-dr,0.0); - glVertex3f(+r+dr, +r, 0.0); - glEnd(); - glBegin(GL_LINE_STRIP); - glVertex3f(-r+dr, -r, 0.0); - glVertex3f(-r , -r+dr,0.0); - glVertex3f(-r-dr, -r, 0.0); - glVertex3f(-r , -r-dr,0.0); - glVertex3f(-r+dr, -r, 0.0); - glEnd(); +void Trackball::DrawPlaneHandle() { + float r=1.0; + float dr=r/10.0f; + glBegin(GL_LINE_STRIP); + glVertex3f(+r+dr, +r, 0.0); + glVertex3f(+r , +r+dr,0.0); + glVertex3f(+r-dr, +r, 0.0); + glVertex3f(+r , +r-dr,0.0); + glVertex3f(+r+dr, +r, 0.0); + glEnd(); + glBegin(GL_LINE_STRIP); + glVertex3f(-r+dr, -r, 0.0); + glVertex3f(-r , -r+dr,0.0); + glVertex3f(-r-dr, -r, 0.0); + glVertex3f(-r , -r-dr,0.0); + glVertex3f(-r+dr, -r, 0.0); + glEnd(); } void Trackball::Draw() { glPushMatrix(); + glTranslate(center); glScalef(radius,radius,radius); /// Here start the real drawing stuff - float amb[4] ={.3f,.3f,.3f,1.0f}; - float col[4] ={.5f,.5f,.8f,1.0f}; - float col2[4]={.9f,.9f,1.0f,1.0f}; - glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT); - glLineWidth(2.0); - glEnable(GL_LIGHTING); - glEnable(GL_LINE_SMOOTH); - glEnable(GL_BLEND); + float amb[4] ={.3f,.3f,.3f,1.0f}; + float col[4] ={.5f,.5f,.8f,1.0f}; + float col2[4]={.9f,.9f,1.0f,1.0f}; + glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT); + glLineWidth(2.0); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_LINE_SMOOTH); + glEnable(GL_BLEND); - glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,amb); - glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,col); - glPushMatrix(); - DrawCircle(); - glPushMatrix(); - glRotatef(90,1,0,0); - DrawCircle(); - glRotatef(90,0,1,0); - DrawCircle(); - glPopMatrix(); - glPopMatrix(); + glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,amb); + glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,col); + glPushMatrix(); + + DrawCircle(); + glPushMatrix(); + + glRotatef(90,1,0,0); + DrawCircle(); + glRotatef(90,0,1,0); + DrawCircle(); + + glPopMatrix(); + + glPopMatrix(); - - glColor4f(1.0,.8f,.8f,1.0f); - if(current_action.motion==ROTATE_X || current_action.motion==ROTATE_Y || current_action.motion==ROTATE_Z ){ - //Point3d raxt(0,0,0),rax;// compute the rotation axis - //raxt[current_action.motion-ROTATE_X]=1; - //RotM.Apply(rax,raxt); - // - //glDisable(GL_LIGHTING); - //glBegin(GL_LINE_STRIP); - // glVertex(Manip.c-raxt*TrackballRadius*1.3); - // glVertex(Manip.c+raxt*TrackballRadius*1.3); - //glEnd(); - } - glPopAttrib(); - - if(current_action.motion==DRAG_XY) { - glPushMatrix(); - //glTranslate(Manip.c); - DrawPlane(); - glPopMatrix(); - } - if(current_action.motion==DRAG_XZ) { - glPushMatrix(); - //glTranslate(Manip.c); - glRotatef(90,1,0,0); - DrawPlane(); - glPopMatrix(); - } - if(current_action.motion==DRAG_YZ) { - glPushMatrix(); - //glTranslate(Manip.c); - glRotatef(90,0,1,0); - DrawPlane(); - glPopMatrix(); - } + glColor4f(1.0,.8f,.8f,1.0f); + + /* switch(current_action) { + case TRACK_ROTATE_X: + case TRACK_ROTATE_Y: + case TRACK_ROTATE_Z: + //Point3d raxt(0,0,0),rax;// compute the rotation axis + //raxt[current_action.motion-ROTATE_X]=1; + //RotM.Apply(rax,raxt); + // + //glDisable(GL_LIGHTING); + //glBegin(GL_LINE_STRIP); + // glVertex(Manip.c-raxt*TrackballRadius*1.3); + // glVertex(Manip.c+raxt*TrackballRadius*1.3); + //glEnd(); + break; + + case DRAG_XY: + glPushMatrix(); + //glTranslate(Manip.c); + DrawPlane(); + glPopMatrix(); + break; + + case DRAG_XY: + glPushMatrix(); + //glTranslate(Manip.c); + glRotatef(90,1,0,0); + DrawPlane(); + glPopMatrix(); + break; + + case DRAG_XY: + glPushMatrix(); + //glTranslate(Manip.c); + glRotatef(90,0,1,0); + DrawPlane(); + glPopMatrix(); + break; + default: + break; + }*/ + + glPopAttrib(); glPopMatrix(); } @@ -232,26 +252,16 @@ void Trackball::Reset() { void Trackball::MouseDown(int x, int y, Trackball::Button button) { current_button |= button; SetCurrentAction(); - last_x = x; - last_y = y; + last_point = Point3f((float)x, (float)y, 0); } void Trackball::MouseMove(int x, int y) { - if(current_action.motion == NONE) return; - if(last_x == -1 && last_y == -1) { //changed mode in the middle of moving - last_x = x; - last_y = y; + if(current_mode == NULL) return; + if(last_point[2] == -1) { //changed mode in the middle of moving + last_point = Point3f((float)x, (float)y, 0); return; } - - TrackMode *mode = CurrentMode(); - mode->tb=this; - - Point3f new_point = Point3f(float(x), float(y), 0); - Point3f old_point = Point3f(float(last_x), float(last_y), 0); - Similarityf diff=mode->ComputeFromWindow(old_point,new_point); - - track = last_track*diff; + current_mode->Apply(this, Point3f(float(x), float(y), 0)); } void Trackball::MouseUp(int /* x */, int /* y */, Trackball::Button button) { @@ -293,39 +303,17 @@ void Trackball::HistorySize(int /* lenght */){} void Trackball::SetCurrentAction() { //I use strict matching. - assert(actions.count(0)); - if(!actions.count(current_button)) - current_action = actions[0]; + assert(modes.count(0)); + if(!modes.count(current_button)) + current_mode = NULL; else - current_action = actions[current_button]; + current_mode = modes[current_button]; - last_x = -1; - last_y = -1; + last_point = Point3f(0, 0, -1); last_track = track; - last_view = view; + // last_view = view; } -TrackMode *Trackball::CurrentMode() { - Point3f x(1, 0, 0), y(0, 1, 0), z(0, 0, 1); - TrackMode *mode = NULL; - switch(current_action.motion) { - case NONE: mode = new TrackMode(); break; - case ROTATE: mode = new SphereMode(); break; - case ROTATE_DUMMY: mode = new GravityMode(); break; - case ROTATE_X: mode = new CylinderMode(x); break; - case ROTATE_Y: mode = new CylinderMode(y); break; - case ROTATE_Z: mode = new CylinderMode(z); break; - case DRAG_X: mode = new LineMode(x); break; - case DRAG_Y: mode = new LineMode(y); break; - case DRAG_Z: mode = new LineMode(z); break; - case DRAG_XY: mode = new PlaneMode(x, y); break; - case DRAG_YZ: mode = new PlaneMode(y, z); break; - case DRAG_XZ: mode = new PlaneMode(z, x); break; - case SCALE: mode = new ScaleMode(); break; - default: break; - } - return mode; -} ////return center of trackball in Window coordinates. //Point3f Trackball::ScreenOrigin() { // return camera.Project(ModelOrigin()); @@ -333,9 +321,9 @@ TrackMode *Trackball::CurrentMode() { //return center of trackball in Model coordinates -Point3f Trackball::ModelOrigin() { - return center; -} +//Point3f Trackball::ModelOrigin() { +// return center; +//} //Matrix44f Trackball::ScreenToModel() { // return camera.inverse; diff --git a/wrap/gui/trackball.h b/wrap/gui/trackball.h index f82de1bd..b378851a 100644 --- a/wrap/gui/trackball.h +++ b/wrap/gui/trackball.h @@ -25,6 +25,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.5 2004/05/12 20:55:18 ponchio +*** empty log message *** + Revision 1.4 2004/05/07 12:46:08 cignoni Restructured and adapted in a better way to opengl @@ -47,144 +50,144 @@ Adding copyright. #include namespace vcg { -/* A trackball stores two transformations -the first one, local, is the one 'placing' the trackball somewhere, -the second one, track, is the one that effectively rotate the object. + /* A trackball stores two transformations + the first one, local, is the one 'placing' the trackball somewhere, + the second one, track, is the one that effectively rotate the object. -The 'local' transformation is the one that contains information about -the rotation center, the size and the orientation of the trackball. -the 'track' is the one implementing the effective transformation. + The 'local' transformation is the one that contains information about + the rotation center, the size and the orientation of the trackball. + the 'track' is the one implementing the effective transformation. -*/ -class Transform { -public: - Transform(); - Similarityf track; + */ - Point3f center; // la posizione della trackball nello spazio di modello. il defgault e' 000 - float radius; /// size of the widget in spazio di modello. - //Quaternion orientation; -}; + class Transform { + public: + Transform(); + Similarityf track; + + /// la posizione della track nello spazio di modello. il defgault e' 000 + Point3f center; + /// size of the widget in spazio di modello. + float radius; + }; -Transform interpolate(const Transform &a, const Transform &b, float t); -class TrackMode; -class Trackball: public Transform { -public: - enum Button { BUTTON_NONE = 0x0000, - BUTTON_LEFT = 0x0001, - BUTTON_MIDDLE = 0x0002, - BUTTON_RIGHT = 0x0004, - WHEEL = 0x0008, - KEY_SHIFT = 0x0010, - KEY_CTRL = 0x0020, - KEY_ALT = 0x0040, - HANDLE = 0x0080 }; + Transform interpolate(const Transform &a, const Transform &b, float t); - Trackball(); - void SetIdentity(); - void SetPosition(const Point3f &c, int millisec = 0); - void SetScale(const float s) {radius=s;}; - void SetTransform(const Transform &transform, int miilisec = 0); -// float ScreenScale(); + class TrackMode; - //operating - void GetView(); - void Apply(); - void Draw(); - void ApplynDraw() { Apply(); Draw(); } - void Reset(); + class Trackball: public Transform { + public: + enum Button { BUTTON_NONE = 0x0000, + BUTTON_LEFT = 0x0001, + BUTTON_MIDDLE = 0x0002, + BUTTON_RIGHT = 0x0004, + WHEEL = 0x0008, + KEY_SHIFT = 0x0010, + KEY_CTRL = 0x0020, + KEY_ALT = 0x0040, + HANDLE = 0x0080 }; - // Internal Drawing stuff - void DrawCircle (); - void DrawPlane(); - void DrawPlaneHandle(); + Trackball(); + ~Trackball(); + void SetIdentity(); + void SetPosition(const Point3f &c, int millisec = 0); + void SetScale(const float s) {radius=s;}; + void SetTransform(const Transform &transform, int miilisec = 0); + //operating + void GetView(); + void Apply(); + void Draw(); + void ApplynDraw() { Apply(); Draw(); } + void Reset(); - //interface - void MouseDown(int x, int y, Button button); - void MouseMove(int x, int y); - void MouseUp(int x, int y, Button button); - void MouseWheel(Button notch); - void ButtonUp(Button button); - void ButtonDown(Button button); + // Internal Drawing stuff + static void DrawCircle (); + static void DrawPlane(); + static void DrawPlaneHandle(); - //default sensitivity 1 - void SetSensitivity(float s); + //interface + void MouseDown(int x, int y, Button button); + void MouseMove(int x, int y); + void MouseUp(int x, int y, Button button); + void MouseWheel(Button notch); + void ButtonUp(Button button); + void ButtonDown(Button button); - //spinning interface - void SetSpinnable(bool on); - bool IsSpinnable(); - void SetSpinning(Quaternionf &spin); - void StopSpinning(); - bool IsSpinning(); + //default sensitivity 1 + void SetSensitivity(float s); - //interfaccia navigation: - void Back(); - void Forward(); - void Home(); - void Store(); - void HistorySize(int lenght); + //spinning interface + void SetSpinnable(bool on); + bool IsSpinnable(); + void SetSpinning(Quaternionf &spin); + void StopSpinning(); + bool IsSpinning(); - //internals + //interfaccia navigation: + void Back(); + void Forward(); + void Home(); + void Store(); + void HistorySize(int lenght); - enum System { LOCAL, VIEW, SCREEN }; - - enum Motion { NONE = 0, ROTATE = 1, ROTATE_DUMMY = 2, //really makes sense only in VIEW system - ROTATE_X = 3, ROTATE_Y = 4, ROTATE_Z = 5, // Axis Constrained Rotation - DRAG_X = 6, DRAG_Y = 7, DRAG_Z = 8, // Drag constrained to an axis (trackball axis) - DRAG_XY = 9, DRAG_YZ = 10, DRAG_XZ = 11, // Drag constrained to a plane - SCALE = 12 //scale respect to center of trackball - }; + //internals + enum Action { NONE = 0, + VIEW_ROTATE = 1, + // Axis Constrained Rotation + TRACK_ROTATE_X = 3, TRACK_ROTATE_Y = 4, TRACK_ROTATE_Z = 5, + // Drag constrained to an axis (trackball axis) + DRAG_X = 6, DRAG_Y = 7, DRAG_Z = 8, + // Drag constrained to a plane + DRAG_XY = 9, DRAG_YZ = 10, DRAG_XZ = 11, + //scale model respect to center of trackball + VIEW_SCALE = 12, + //scale trackball and model + TRACK_SCALE = 13 + }; + ///Find the current action ussing the current button - struct Action { - System system; - Motion motion; - Action() {} - Action(System s, Motion m): system(s), motion(m) {} + + //protected: + View camera; + + /* float ScreenRadius; + Point3f ScreenCenter;*/ + + void SetCurrentAction(); + + int current_button; + TrackMode *current_mode; + + std::map modes; + + Similarityf last_track; + Similarityf last_view; + Point3f last_point; + bool dragging; + int button_mask; + + Quaternionf spin; + bool spinnable; + bool spinning; + + std::list history; + int history_size; + + //Point3f ScreenOrigin(); //center of trackball in Screen coord + //Point3f ModelOrigin(); //center of trackball in Model coord + + // Matrix44f ScreenToModel(); //forse non serve..... + // Similarityf ModelToLocal(); + + //Point3f ScreenToLocal(const Point3f &p); + //Point3f LocalToScreen(const Point3f &p); + friend class TrackMode; }; - ///Find the current action ussing the current button - void SetCurrentAction(); - -//protected: - View camera; - Similarityf view; //Rotate LOCAL coordinate into VIEW coordinates - - float ScreenRadius; - Point3f ScreenCenter; - - int current_button; - Action current_action; - - TrackMode *CurrentMode(); - std::map actions; - - Similarityf last_track; - Similarityf last_view; - int last_x, last_y; - bool dragging; - int button_mask; - - Quaternionf spin; - bool spinnable; - bool spinning; - - std::list history; - int history_size; - - - //Point3f ScreenOrigin(); //center of trackball in Screen coord - Point3f ModelOrigin(); //center of trackball in Model coord - - Matrix44f ScreenToModel(); //forse non serve..... - Similarityf ModelToLocal(); - - //Point3f ScreenToLocal(const Point3f &p); - //Point3f LocalToScreen(const Point3f &p); -}; }//namespace -#endif \ No newline at end of file +#endif diff --git a/wrap/gui/trackmode.cpp b/wrap/gui/trackmode.cpp index 310efcc4..0b64d7d7 100644 --- a/wrap/gui/trackmode.cpp +++ b/wrap/gui/trackmode.cpp @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.4 2004/05/07 12:46:08 cignoni +Restructured and adapted in a better way to opengl + Revision 1.3 2004/04/07 10:54:11 cignoni Commented out unused parameter names and other minor warning related issues @@ -33,107 +36,114 @@ Adding copyright. ****************************************************************************/ -#include -#include -#include + +#include +#include #include -#include "trackmode.h" #include +#include +using namespace std; using namespace vcg; - - - -/* -Le varie Apply prendono una coppia di punti in screen space e restituiscono una trasformazione -*/ - -Plane3f SphereMode::GetViewPlane() -{ - Point3f mo=tb->ModelOrigin(); - Point3f vp; vp.Import(tb->camera.ViewPoint()); - Plane3f pl; // plane perpedicular to view direction and passing through manip center - pl.Set(vp-tb->center, (vp-tb->center)*tb->center); +Plane3f TrackMode::GetViewPlane(const View &camera, Point3f center) { + Point3f vp = camera.ViewPoint(); + + Plane3f pl; //plane perpedicular to view dir and passing through manip center + pl.Set(vp - center, (vp - center)*center); return pl; } +Point3f TrackMode::HitViewPlane(Trackball *tb, const Point3f &p) { + // plane perpedicular to view direction and passing through manip center + Plane3f vp = GetViewPlane(tb->camera, tb->center); + Line3fN ln= tb->camera.ViewLineFromWindow(Point3f(p[0],p[1],0)); + + Point3f PonVP; + bool res = Intersection(vp,ln,PonVP); + return PonVP; +} + + +void SphereMode::Apply(Trackball *tb, Point3f new_point) { + Point3f hitOld=Hit(tb, tb->last_point); + Point3f hitNew=Hit(tb, new_point); + + Point3f ref = (tb->camera.ViewPoint() - tb->center).Normalize(); + + + Point3f axis = hitNew^ref; + axis.Normalize(); + float dist = (hitNew - ref).Norm()/2; + float phi = 2 * math::Asin(dist); + + Point3f oaxis = hitOld^ref; + oaxis.Normalize(); + float odist = (hitOld - ref).Norm()/2; + float ophi = 2 * math::Asin(odist); + + + Quaternionf r = tb->last_track.rot; + Quaternionf diff = r * Quaternionf(phi, axis) * + Quaternionf(-ophi, oaxis) * Inverse(r); + + tb->track = Similarityf().SetRotate(diff) * tb->last_track; +} /* dato un punto in coordinate di schermo e.g. in pixel stile opengl - restituisce un punto in coordinate di mondo sulla superficie della trackball - La superficie della trackball e' data da una sfera + una porzione di iperboloide di rotazione - assumiamo la sfera di raggio unitario e centrata sull'origine e di guardare lungo la y negativa. + restituisce un punto in coordinate di mondo sulla superficie + della trackball. + La superficie della trackball e' data da una sfera + una porzione + di iperboloide di rotazione. + Assumiamo la sfera di raggio unitario e centrata sull'origine e + di guardare lungo la y negativa. + X 0 sqrt(1/2) 1 eq sfera: y=sqrt(1-x*x); 1 sqrt(1/2) 0 eq iperboloide : y=1/2x; inf sqrt(1/2) 1/2 + eq cono y=x+sqrt(2); */ -Point3f SphereMode::Hit(const Point3f &p) -{ - printf("Hit in screen space at %5.3f %5.3f %5.3f\n",p[0],p[1],p[2]); +Point3f SphereMode::Hit(Trackball *tb, const Point3f &p) { + const float Thr = tb->radius/math::Sqrt(2.0f); + Line3fN vn = tb->camera.ViewLineFromModel(tb->center); + Line3fN ln = tb->camera.ViewLineFromWindow(Point3f(p[0],p[1],0)); + Point3f viewpoint = tb->camera.ViewPoint(); - Plane3f vp=GetViewPlane(); // plane perpedicular to view direction and passing through manip center - Line3fN ln= tb->camera.ViewLineFromWindow(Point3f(p[0],p[1],0)); - //Point3f P0,P1; - Point3f PonVP; - bool res=Intersection(vp,ln,PonVP); - const float Thr=tb->radius/math::Sqrt(2.0f); + Plane3f vp = GetViewPlane(tb->camera, tb->center); + vp.SetOffset(vp.Offset() + Thr); - Point3f HitPoint; - float dd=Distance(tb->center,PonVP); - if(ddradius*tb->radius - dd*dd); - HitPoint=PonVP+ln.Direction()*hh; - printf("Hit the sphere point on plane is %5.3f %5.3f %5.3f\n",PonVP[0],PonVP[1],PonVP[2]); - printf(" Distance from center is %5.3f \n",dd); - printf(" Heigth for view plane should be %5.3f \n",hh ); + Point3f hit; + bool res = Intersection(vp, ln, hit); + float d = Distance(tb->center - vn.Direction()*Thr, hit); + if(d < Thr) { + Point3f hit2; + Sphere3f sphere(tb->center, tb->radius); + bool res = Intersection(sphere, ln, hit, hit2); + + //find closest intersection to sphere + float d = (hit - viewpoint).Norm(); + float d2 = (hit2 - viewpoint).Norm(); + if(d > d2) hit = hit2; + hit -= tb->center; + } else { + if(d > 2.99 * Thr) + d = 2.99 * Thr; + Point3f norm = (hit - tb->center)^(viewpoint - tb->center); + norm.Normalize(); + float phi = -M_PI/4 - 3*M_PI/8 *(d - Thr)/Thr; + + Quaternionf q(phi, norm); + hit = q.Rotate((viewpoint - tb->center).Normalize() * tb->radius); } - else - { // Second Case we hit the hyperboloid - float hh=tb->radius/(2.0f*(dd/tb->radius)); - HitPoint=PonVP+ln.Direction()*hh; - - printf("Hit the hiperboloid at %5.3f %5.3f %5.3f\n",PonVP[0],PonVP[1],PonVP[2]); - printf(" Distance from center is %5.3f \n",dd); - printf(" Heigth for view plane should be %5.3f \n",hh ); - - } - return HitPoint; + hit.Normalize(); + return hit; } -/* - Nella trackball classica si considera +void PlaneMode::Apply(Trackball *tb, Point3f new_point) { + Point3f hitOld=HitViewPlane(tb, tb->last_point); + Point3f hitNew=HitViewPlane(tb, new_point); -*/ -Similarityf PlaneMode::ComputeFromWindow(const Point3f &oldP, const Point3f &newP) -{ - return Similarityf().SetIdentity(); -} -/* -Restituisce la trasformazione originata dal drag in window coord da oldp a newp. -*/ -Similarityf SphereMode::ComputeFromWindow(const Point3f &oldP, const Point3f &newP) -{ - Point3f hitOld=Hit(oldP); - Point3f hitNew=Hit(newP); - // Now compute the rotation defined on the sphere... - - Point3f norm; - - return Similarityf().SetIdentity(); - - //Point3f axis = Point3f(0, 0, 1)^result; /* Axis of rotation */ - //axis.Normalize(); - //Point3f d = result - Point3f(0, 0, 1); - //float t = d.Norm() / 2.0f; - //if(t > thr) - // t += (t - thr) * 0.7f; - //if (t > 1.0f) t = 1.0f; - //if (t < -1.0f) t = -1.0f; - // float phi = 2 * math::Asin(t); - ////return Similarityf().SetRotate(phi * 180/(float)M_PI, axis); - // return Similarityf().SetRotate(phi, axis); } diff --git a/wrap/gui/trackmode.h b/wrap/gui/trackmode.h index e8d38c54..27e6ed12 100644 --- a/wrap/gui/trackmode.h +++ b/wrap/gui/trackmode.h @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.4 2004/05/07 12:46:08 cignoni +Restructured and adapted in a better way to opengl + Revision 1.3 2004/04/07 10:54:11 cignoni Commented out unused parameter names and other minor warning related issues @@ -36,63 +39,67 @@ Adding copyright. #ifndef TRACKMODE_H #define TRACKMODE_H -#include -#include -#include +#include +#include +#include namespace vcg { + class Trackball; + class TrackMode { public: virtual ~TrackMode() {} + virtual void Apply(Trackball *trackball, Point3f new_point) = 0; + virtual void Draw() {} //virtual void Draw() {} - virtual Similarityf ComputeFromWindow(const Point3f &/* oldp */, const Point3f &/* newp */) { return Similarityf().SetIdentity(); } - Point3f Hit(const Point3f &p); - Trackball *tb; - + // virtual Similarityf ComputeFromWindow(const Point3f &old_point, + //const Point3f &new_point) = 0; + // Point3f Hit(const Point3f &p); + protected: + Plane3f GetViewPlane(const View &view, Point3f center); + Point3f HitViewPlane(Trackball *trackball, const Point3f &p); }; - + +/* View space modes */ + class SphereMode: public TrackMode { -public: - Similarityf ComputeFromWindow(const Point3f &oldP, const Point3f &newP); - //Plane3f SetViewPlane(); - Point3f Hit(const Point3f &p); - Plane3f GetViewPlane(); -// Line3f GetViewLine(const Point3f &p); - -}; - -class GravityMode: public TrackMode { -public: + public: + void Apply(Trackball *trackball, Point3f new_point); + protected: + Point3f Hit(Trackball *trackball, const Point3f &p); }; class CylinderMode: public TrackMode { public: - CylinderMode(const Point3f _axis): axis(_axis) { axis.Normalize(); } + CylinderMode(const Line3f &line, float radius = 1) {} + void Apply(Trackball *trackball, Point3f new_point) {} protected: - Point3f axis; + Line3f line; + float radius; }; class PlaneMode: public TrackMode { public: - PlaneMode(const Point3f _x, const Point3f _y): x(_x), y(_y) { x.Normalize(); y.Normalize(); } - Similarityf ComputeFromWindow(const Point3f &oldP, const Point3f &newP); + PlaneMode(const Plane3f &pl): plane(pl) {} + void Apply(Trackball *trackball, Point3f new_point); protected: - Point3f x; - Point3f y; + Plane3f plane; }; class LineMode: public TrackMode { public: - LineMode(const Point3f _axis): axis(_axis) { axis.Normalize();} + LineMode(const Line3f &line) {} + void Apply(Trackball *trackball, Point3f new_point) {} protected: - Point3f axis; + Line3f line; }; class ScaleMode: public TrackMode { public: + void Apply(Trackball *trackball, Point3f new_point) {} }; }//namespace -#endif \ No newline at end of file +#endif