diff --git a/wrap/gui/trackball.cpp b/wrap/gui/trackball.cpp index 9536c563..91b53164 100644 --- a/wrap/gui/trackball.cpp +++ b/wrap/gui/trackball.cpp @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.4 2004/04/07 10:54:10 cignoni +Commented out unused parameter names and other minor warning related issues + Revision 1.3 2004/03/31 15:08:03 ponchio Fixed current_action initialization. @@ -33,16 +36,21 @@ Adding copyright. ****************************************************************************/ +#include + #include "trackball.h" + #include +#include using namespace vcg; #include //debug! using namespace std; Transform::Transform() { - local.SetIdentity(); track.SetIdentity(); + radius=1.0f; + center=Point3f(0,0,0); } Trackball::Trackball(): current_button(0), last_x(-1), last_y(-1), dragging(false), @@ -57,12 +65,11 @@ Trackball::Trackball(): current_button(0), last_x(-1), last_y(-1), dragging(fals } void Trackball::SetIdentity() { - local.SetIdentity(); + track.SetIdentity(); Reset(); } -void Trackball::SetPosition(const Similarityf &m, int /* millisec */) { - local = m; - //millisec ignored at the moment. +void Trackball::SetPosition(const Point3f &c, int /* millisec */) { + center = c; } //operating @@ -70,13 +77,15 @@ void Trackball::GetView() { camera.GetView(); //lets get view matrix - Similarityf m = local * last_track; - Point3f c_obj = Point3f(0, 0, 0) * m; //coordinate of the center of the trackball in obj coords - Point3f c_view = camera.Project(c_obj); //center of the trackball in screen coords. - Point3f X, Y, Z, C; - X = camera.UnProject(Point3f(c_view[0] + 100, c_view[1], c_view[2])); - Y = camera.UnProject(Point3f(c_view[0], c_view[1] - 100, c_view[2])); - Z = camera.UnProject(Point3f(c_view[0], c_view[1], c_view[2] + 0.1f)); + 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 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)); C = c_obj; X = X - C; X.Normalize(); Y = Y - C; Y.Normalize(); @@ -93,30 +102,124 @@ void Trackball::GetView() { //spinning ignored } void Trackball::Apply() { - Matrix44f a = track.Matrix(); - //Transpose(a); - glMultMatrix(a); - //glMultMatrix(track.Matrix()); - //glMultMatrix(track); + 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::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::Draw() { glPushMatrix(); - glMultMatrix(local.Matrix()); - //Disegnamo un cubo: - glColor3f(1, 0, 0); - glScalef(0.5, 0.5, 0.5); - glBegin(GL_LINE_STRIP); - glVertex3f(-1, -1, -1); - glVertex3f( 1, -1, -1); - glVertex3f( 1, 1, -1); - glVertex3f(-1, 1, -1); - glVertex3f(-1, 1, 1); - glVertex3f( 1, 1, 1); - glVertex3f( 1, -1, 1); - glVertex3f(-1, -1, 1); - glVertex3f(-1, -1, 1); - glEnd(); + 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); + + 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(); + } + glPopMatrix(); } @@ -140,32 +243,14 @@ void Trackball::MouseMove(int x, int y) { return; } - Point3f origin = camera.ViewportToScreen(ScreenOrigin()); - Point3f new_point = camera.ViewportToScreen(Point3f(float(x), float(y), 0)) - origin; - Point3f old_point = camera.ViewportToScreen(Point3f(float(last_x), float(last_y), 0)) - origin; - new_point *= 2; - old_point *= 2; - - Similarityf u; TrackMode *mode = CurrentMode(); - Similarityf new_track = mode->Apply(new_point, u); - Similarityf old_track = mode->Apply(old_point, u); - delete mode; + mode->tb=this; - Invert(old_track); - new_track = old_track * new_track; - - Similarityf diff; - switch(current_action.system) { - case VIEW: - u = last_view * Similarityf((-local.tra) * Similarityf(last_track.rot)) * Similarityf(-last_track.tra); - diff = Inverse(u) * new_track * u; - break; - default: break; - } - - track = diff * last_track; + 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; } void Trackball::MouseUp(int /* x */, int /* y */, Trackball::Button button) { @@ -240,24 +325,24 @@ TrackMode *Trackball::CurrentMode() { } return mode; } -//return center of trackball in Screen coordinates. -Point3f Trackball::ScreenOrigin() { - return camera.Project(ModelOrigin()); -} +////return center of trackball in Window coordinates. +//Point3f Trackball::ScreenOrigin() { +// return camera.Project(ModelOrigin()); +//} + //return center of trackball in Model coordinates Point3f Trackball::ModelOrigin() { - Similarityf m = local * last_track; - return Point3f(0, 0, 0) * m; + return center; } -Matrix44f Trackball::ScreenToModel() { - return camera.inverse; -} - -Similarityf Trackball::ModelToLocal() { - Similarityf m = local * last_track; - return m; -} +//Matrix44f Trackball::ScreenToModel() { +// return camera.inverse; +//} +// +//Similarityf Trackball::ModelToLocal() { +// Similarityf m = local * last_track; +// return m; +//} diff --git a/wrap/gui/trackball.h b/wrap/gui/trackball.h index e211dcd6..221f9a4f 100644 --- a/wrap/gui/trackball.h +++ b/wrap/gui/trackball.h @@ -2,7 +2,8 @@ * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * -* Copyright(C) 2004 \/)\/ * +* Copyright(C) 2004 +\/)\/ * * Visual Computing Lab /\/| * * ISTI - Italian National Research Council | * * \ * @@ -24,6 +25,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.3 2004/04/07 10:54:10 cignoni +Commented out unused parameter names and other minor warning related issues + Revision 1.2 2004/03/25 14:55:25 ponchio Adding copyright. @@ -40,16 +44,27 @@ 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. +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; - Similarityf local; + + 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; }; Transform interpolate(const Transform &a, const Transform &b, float t); - +class TrackMode; class Trackball: public Transform { public: enum Button { BUTTON_NONE = 0x0000, @@ -64,8 +79,10 @@ public: Trackball(); void SetIdentity(); - void SetPosition(const Similarityf &local, int millisec = 0); + 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(); //operating void GetView(); @@ -73,6 +90,12 @@ public: void Draw(); void Reset(); + // Internal Drawing stuff + void DrawCircle (); + void DrawPlane(); + void DrawPlaneHandle(); + + //interface void MouseDown(int x, int y, Button button); void MouseMove(int x, int y); @@ -120,10 +143,13 @@ public: ///Find the current action ussing the current button void SetCurrentAction(); -protected: +//protected: View camera; Similarityf view; //Rotate LOCAL coordinate into VIEW coordinates + float ScreenRadius; + Point3f ScreenCenter; + int current_button; Action current_action; @@ -144,7 +170,7 @@ protected: int history_size; - Point3f ScreenOrigin(); //center of trackball in Screen coord + //Point3f ScreenOrigin(); //center of trackball in Screen coord Point3f ModelOrigin(); //center of trackball in Model coord Matrix44f ScreenToModel(); //forse non serve..... diff --git a/wrap/gui/trackmode.cpp b/wrap/gui/trackmode.cpp index 250e7fad..310efcc4 100644 --- a/wrap/gui/trackmode.cpp +++ b/wrap/gui/trackmode.cpp @@ -24,81 +24,116 @@ History $Log: not supported by cvs2svn $ +Revision 1.3 2004/04/07 10:54:11 cignoni +Commented out unused parameter names and other minor warning related issues + Revision 1.2 2004/03/25 14:55:25 ponchio Adding copyright. ****************************************************************************/ -#include "trackmode.h" +#include #include +#include +#include +#include "trackmode.h" #include using namespace vcg; -Similarityf SphereMode::Apply(const Point3f &p, const Similarityf & /* m */) { - float u = p[0]; - float w = p[1]; - float thr = 1/math::Sqrt(2.0f); //in the plane x-y distance from origin, above this use hyperboloid - - float dist = math::Sqrt(u * u + w * w); - Point3f result; - if(dist < thr) { // First case: The ray is nearer to the sphere than r/sqrt(2) - float z = math::Sqrt(1 - u * u - w* w); - result = Point3f(u, w, z); - } else { // Second case: The ray should hit the 1/d hyperboloid - float a = thr; - result = Point3f(u, w, -a*(u*u + w * w) + 3*a/2); - result.Normalize(); - } - if(result == Point3f(0, 0, 1)) - 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); + + +/* +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); + return pl; } -Similarityf PlaneMode::Apply(const Point3f &p, const Similarityf &a) { - return Similarityf(Point3f(p[0], p[1], 0)); - Point3f r = x * a; - Point3f u = y * a; - int leading = 0; //leadiing x. - if(fabs(u[2]) < fabs(r[2])) //sceglie l'asse principale: quello che piu' e' parallelo al piano di vista. - leading = 1; - r[2] = 0; - u[2] = 0; - if(r == Point3f(0,0,0)) //casi degeneri: un asse e' perpendicolare al piano di vista. - r = Point3f(0, 1, 0); - if(u == Point3f(0,0,0)) - u = Point3f(0, 1, 0); - r.Normalize(); - u.Normalize(); - float cu, cr; - if(leading == 0) { //leading x - if(u == r || u == -r) { //caso degenere: i due assi si proiettano sullo stesso - u[0] = -r[1]; - u[1] = r[0]; - } - u = u - r * (r * u); - u.Normalize(); - } else { - if(r == u || r == -u) { //caso degenere: i due assi si proiettano sullo stesso - r[0] = -u[1]; - r[1] = u[0]; - } - r = r - u * (u * r); - r.Normalize(); - } - cr = r * p; - cu = u * p; - return Similarityf(x * cr + y * cu); -} \ No newline at end of file + + +/* 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. + 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 + + */ + +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]); + + 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); + + 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 ); + } + 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; +} + +/* + Nella trackball classica si considera + +*/ +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 e7364e0f..e8d38c54 100644 --- a/wrap/gui/trackmode.h +++ b/wrap/gui/trackmode.h @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.3 2004/04/07 10:54:11 cignoni +Commented out unused parameter names and other minor warning related issues + Revision 1.2 2004/03/25 14:55:25 ponchio Adding copyright. @@ -35,19 +38,28 @@ Adding copyright. #include #include +#include namespace vcg { - +class Trackball; class TrackMode { public: virtual ~TrackMode() {} - virtual void Draw() {} - virtual Similarityf Apply(const Point3f &/* p */, const Similarityf &/*a*/) { return Similarityf().SetIdentity(); } + //virtual void Draw() {} + virtual Similarityf ComputeFromWindow(const Point3f &/* oldp */, const Point3f &/* newp */) { return Similarityf().SetIdentity(); } + Point3f Hit(const Point3f &p); + Trackball *tb; + }; class SphereMode: public TrackMode { public: - Similarityf Apply(const Point3f &p, const Similarityf &/*a*/); + 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 { @@ -64,7 +76,7 @@ protected: class PlaneMode: public TrackMode { public: PlaneMode(const Point3f _x, const Point3f _y): x(_x), y(_y) { x.Normalize(); y.Normalize(); } - Similarityf Apply(const Point3f &p, const Similarityf &a); + Similarityf ComputeFromWindow(const Point3f &oldP, const Point3f &newP); protected: Point3f x; Point3f y; diff --git a/wrap/gui/view.h b/wrap/gui/view.h index f06975b7..d42d93ab 100644 --- a/wrap/gui/view.h +++ b/wrap/gui/view.h @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.4 2004/04/07 10:54:11 cignoni +Commented out unused parameter names and other minor warning related issues + Revision 1.3 2004/03/31 15:07:37 ponchio CAMERA_H -> VCG_CAMERA_H @@ -36,13 +39,24 @@ Adding copyright. #ifndef VCG_CAMERA_H #define VCG_CAMERA_H -#include -#include +/********************** +WARNING +Everything here assumes the opengl window coord system. +the 0,0 is bottom left +y is upward! +**********************/ -#include -#include +#include +#include +#include +#include namespace vcg { +/** +This class represent the viewing parameters under opengl. +Mainly it stores the projection and modelview matrix and the viewport +and it is used to simply project back and forth points, computing line of sight, planes etc. +*/ template class View { public: @@ -51,10 +65,18 @@ public: Point3 Project(const Point3 &p) const; Point3 UnProject(const Point3 &p) const; Point3 ViewPoint(); - //convert coordinates range 0-1 to range 0 viewport[2] - Point3 ScreenToViewport(const Point3 &p) const; - //viceversa - Point3 ViewportToScreen(const Point3 &p) const; + + /// Return the plane perpendicular to the view axis and passing through point P. + Plane3 ViewPlaneFromModel(const Point3 &p); + + /// Return the line passing through the point p and the observer. + Line3 ViewLineFromWindow(const Point3 &p); + + /// Convert coordinates from the range -1..1 of Normalized Device Coords to range 0 viewport[2] + Point3 NormDevCoordToWindowCoord(const Point3 &p) const; + + /// Convert coordinates from 0--viewport[2] to the range -1..1 of Normalized Device Coords to + Point3 WindowCoordToNormDevCoord(const Point3 &p) const; Matrix44 proj; Matrix44 model; @@ -65,14 +87,14 @@ public: template void View::GetView() { double m[16]; - glGetDoublev(GL_PROJECTION_MATRIX, m); + glGetDoublev(GL_TRANSPOSE_PROJECTION_MATRIX_ARB, m); proj.Import(Matrix44d(m)); - glGetDoublev(GL_MODELVIEW_MATRIX, m); + glGetDoublev(GL_TRANSPOSE_MODELVIEW_MATRIX_ARB, m); model.Import(Matrix44d(m)); glGetIntegerv(GL_VIEWPORT, viewport); - matrix = model * proj; + matrix = proj*model; inverse = matrix; Invert(inverse); } @@ -82,56 +104,65 @@ template void View::SetView() { } template Point3 View::ViewPoint() { - return inverse * Point3(0, 0, 0); - /*Matrix44d model(model_matrix); - model.Invert(); - Point3d view = model * Point3d(0, 0, 0); - return Point3(view[0], view[1], view[2]); */ + Matrix44 mi=model; + Invert(mi); + return mi* Point3(0, 0, 0); +} +// Note that p it is assumed to be in model coordinate. +template Plane3 View::ViewPlaneFromModel(const Point3 &p) +{ + Point3 vp=ViewPoint(); + Plane3 pl; // plane perpedicular to view direction and passing through manip center + pl.n=(vp-p); + pl.d=pl.n*p; + return pl; +} +// Note that p it is assumed to be in window coordinate. +template Line3 View::ViewLineFromWindow(const Point3 &p) +{ + Point3 vp=ViewPoint(); + Line3 ln; // plane perpedicular to view direction and passing through manip center + /*Matrix44 mi=model; + Invert(mi); + */Point3f pp=UnProject(p); + ln.SetOrigin(vp); + ln.SetDirection(pp-vp); + return ln; } template Point3 View::Project(const Point3 &p) const { Point3 r; - r = p * matrix; - r[0] = (r[0]+1)*(viewport[2]/(T)2.0)+viewport[0]; - r[1] =(r[1]+1)*(viewport[3]/(T)2.0)+viewport[1]; - r[1] = viewport[3]-r[1]; - return r; - /*double r[3]; - gluProject(p[0], p[1], p[2], model_matrix, proj_matrix, viewport, &r[0], &r[1], &r[2]); - return Point3((T)r[0], (T)r[1], (T)r[2]);*/ -} + r = matrix * p; + return NormDevCoordToWindowCoord(r); + } template Point3 View::UnProject(const Point3 &p) const { - Point3 s = p; - s[0] = (p[0]- viewport[0])/ (viewport[2]/(T)2.0) - 1; - s[1] = (p[1]- viewport[1])/ (viewport[3]/(T)2.0) - 1; - s[1] = -s[1]; - s[2] = p[2]; - //s[1] = -s[1]; // pezza aggiunta per il tan2.... ????????????? - - s = s * inverse; + Point3 s = WindowCoordToNormDevCoord(p); + s = inverse * s ; return s; - /*double r[3]; - gluUnProject(p[0], p[1], p[2], model_matrix, proj_matrix, viewport, &r[0], &r[1], &r[2]); - return Point3((T)r[0], (T)r[1], (T)r[2]);*/ } -template Point3 View::ScreenToViewport(const Point3 &p) const { +// Come spiegato nelle glspec +// dopo la perspective division le coordinate sono dette normalized device coords ( NDC ). +// Per passare alle window coords si deve fare la viewport transformation. +// Le coordinate di viewport stanno tra -1 e 1 + +template Point3 View::NormDevCoordToWindowCoord(const Point3 &p) const { Point3 a; a[0] = (p[0]+1)*(viewport[2]/(T)2.0)+viewport[0]; - a[1] =(p[1]+1)*(viewport[3]/(T)2.0)+viewport[1]; - a[1] = viewport[3] - a[1]; + a[1] = (p[1]+1)*(viewport[3]/(T)2.0)+viewport[1]; + //a[1] = viewport[3] - a[1]; a[2] = p[2]; return a; } - //viceversa -template Point3 View::ViewportToScreen(const Point3 &p) const { + + +template Point3 View::WindowCoordToNormDevCoord(const Point3 &p) const { Point3 a; a[0] = (p[0]- viewport[0])/ (viewport[2]/(T)2.0) - 1; a[1] = (p[1]- viewport[1])/ (viewport[3]/(T)2.0) - 1; - a[1] = -a[1]; + //a[1] = -a[1]; a[2] = p[2]; - //a[1] = -a[1]; // pezza aggiunta per il tan2.... ????????????? return a; }