trackutils.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 * VCGLib                                                            o o     *
00003 * Visual and Computer Graphics Library                            o     o   *
00004 *                                                                _   O  _   *
00005 * Copyright(C) 2004                                                \/)\/    *
00006 * Visual Computing Lab                                            /\/|      *
00007 * ISTI - Italian National Research Council                           |      *
00008 *                                                                    \      *
00009 * All rights reserved.                                                      *
00010 *                                                                           *
00011 * This program is free software; you can redistribute it and/or modify      *
00012 * it under the terms of the GNU General Public License as published by      *
00013 * the Free Software Foundation; either version 2 of the License, or         *
00014 * (at your option) any later version.                                       *
00015 *                                                                           *
00016 * This program is distributed in the hope that it will be useful,           *
00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
00019 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
00020 * for more details.                                                         *
00021 *                                                                           *
00022 ****************************************************************************/
00023 
00024 
00025 #ifndef TRACKUTILS_H
00026 #define TRACKUTILS_H
00027 
00028 #include <assert.h>
00029 #include <vcg/math/base.h>
00030 #include <vcg/math/similarity.h>
00031 #include <vcg/space/intersection3.h>
00032 #include <vcg/space/line3.h>
00033 #include <vcg/space/plane3.h>
00034 #include <wrap/gl/math.h>
00035 #include <wrap/gl/space.h>
00036 #include <vector>
00037 #include <iostream>
00038 using namespace std;
00039 
00040 namespace vcg {
00041 
00048 namespace trackutils {
00049 
00057 Plane3f GetViewPlane (const View < float >&camera, const Point3f & center)
00058 {
00059   Point3f vp = camera.ViewPoint ();
00060   Plane3f pl;
00061   Point3f plnorm = vp - center;
00062   plnorm.Normalize();
00063   pl.Set(plnorm, plnorm.dot(center));
00064   return pl;
00065 }
00066 
00073 Ray3f line2ray(const Line3f &l){
00074   Ray3f r(l.Origin(),l.Direction());
00075   r.Normalize();
00076   return r;
00077 }
00078 
00079 
00087 Point3f HitViewPlane (Trackball * tb, const Point3f & p)
00088 {
00089   Plane3f vp = GetViewPlane (tb->camera, tb->center);
00090   Line3fN ln = tb->camera.ViewLineFromWindow (Point3f (p[0], p[1], 0));
00091   Point3f PonVP;
00092   IntersectionPlaneLine < float >(vp, ln, PonVP);
00093   return PonVP;
00094 }
00095 
00096 // nota: non ho scritto io questa funzione,
00097 // quindi la documentazione doxy potrebbe non essere accurata al 100%.
00135 bool HitHyper (Point3f center, float radius, Point3f viewpoint, Plane3f viewplane,
00136                            Point3f hitOnViewplane, Point3f & hit)
00137 {
00138   float hitplaney = Distance (center, hitOnViewplane);
00139   float viewpointx = Distance (center, viewpoint);
00140 
00141   float a = hitplaney / viewpointx;
00142   float b = -hitplaney;
00143   float c = radius * radius / 2.0f;
00144   float delta = b * b - 4 * a * c;
00145   float x1, x2, xval, yval;
00146 
00147   if (delta > 0) {
00148     x1 = (-b - sqrt (delta)) / (2.0f * a);
00149     x2 = (-b + sqrt (delta)) / (2.0f * a);
00150 
00151     xval = x1;                  // always take the minimum value solution
00152     yval = c / xval;            //  alternatively it also could be the other part of the equation yval=-(hitplaney/viewpointx)*xval+hitplaney;
00153   }
00154   else {
00155     return false;
00156   }
00157   // Computing the result in 3d space;
00158   Point3f dirRadial = hitOnViewplane - center;
00159   dirRadial.Normalize ();
00160   Point3f dirView = viewplane.Direction ();
00161   dirView.Normalize ();
00162   hit = center + dirRadial * yval + dirView * xval;
00163   return true;
00164 }
00179 bool HitHyperOrtho(Point3f center, float radius, Point3f viewpoint, Plane3f viewplane,
00180                    Point3f hitOnViewplane, Point3f & hit)
00181 {
00182   float xval = Distance (center, hitOnViewplane);
00183 
00184   float yval = (1.0 / xval ) *  radius * radius / 2.0f;
00185 
00186   // Computing the result in 3d space;
00187   Point3f dirRadial = hitOnViewplane - center;
00188   dirRadial.Normalize ();
00189   Point3f dirView = viewplane.Direction ();
00190   dirView.Normalize ();
00191   hit = center + dirRadial * xval + dirView * yval;
00192 
00193   return true;
00194 }
00195 
00196 // nota: non ho scritto io questa funzione,
00197 // quindi la documentazione doxy potrebbe non essere accurata al 100%.
00221 Point3f HitSphere (Trackball * tb, const Point3f & p)
00222 {
00223   Point3f center = tb->center;
00224   Line3fN ln = tb->camera.ViewLineFromWindow (Point3f (p[0], p[1], 0));
00225   Plane3f vp = GetViewPlane (tb->camera, center);
00226   Point3f hitPlane(0,0,0), //intersection view plane with point touched
00227           hitSphere(0,0,0),
00228           hitSphere1(0,0,0),
00229           hitSphere2(0,0,0),
00230           hitHyper(0,0,0);
00231 
00232   Sphere3f sphere (center, tb->radius);//trackball sphere
00233   bool resSp = IntersectionLineSphere < float >(sphere, ln, hitSphere1, hitSphere2);
00234 
00235   Point3f viewpoint = tb->camera.ViewPoint ();
00236   if (resSp == true) {
00237     if (Distance (viewpoint, hitSphere1) < Distance (viewpoint, hitSphere2))
00238       hitSphere = hitSphere1;
00239     else
00240       hitSphere = hitSphere2;
00241   }
00242 
00243   /*float dl= */ Distance (ln, center);
00244   bool resHp;
00245   IntersectionPlaneLine < float >(vp, ln, hitPlane);
00246   if(tb->camera.isOrtho)
00247     resHp= HitHyperOrtho (center, tb->radius, viewpoint, vp, hitPlane, hitHyper);
00248   else
00249     resHp= HitHyper (center, tb->radius, viewpoint, vp, hitPlane, hitHyper);
00250 
00251   // four cases
00252 
00253   // 1) Degenerate line tangent to both sphere and hyperboloid!
00254   if ((!resSp && !resHp)) {
00255     Point3f hit = ClosestPoint (ln, center);
00256     //printf("closest point to line %f\n",Distance(hit,tb->center));
00257     return hit;
00258   }
00259   if ((resSp && !resHp))
00260     return hitSphere;           // 2) line cross only the sphere
00261   if ((!resSp && resHp))
00262     return hitHyper;            // 3) line cross only the hyperboloid
00263 
00264   // 4) line cross both sphere and hyperboloid: choose according angle.
00265   float angleDeg = math::ToDeg (Angle ((viewpoint - center), (hitSphere - center)));
00266 
00267 //  qDebug("Angle %f (%5.2f %5.2f %5.2f) (%5.2f %5.2f %5.2f)",angleDeg,hitSphere[0],hitSphere[1],hitSphere[2],hitHyper[0],hitHyper[1],hitHyper[2]);
00268   if (angleDeg < 45)
00269     return hitSphere;
00270   else
00271     return hitHyper;
00272 
00273   // Codice ORIGINALE PONCHIO
00274   //vp.SetOffset(vp.Offset() + Thr);
00275 
00276   //Point3f hit;
00277   //bool res = Intersection<float>(vp, ln, hit);
00278   //float d = Distance(tb->center - vn.Direction()*Thr, hit);
00279   //if(d < Thr) {
00280   //  Point3f hit2;
00281   //  Sphere3f sphere(tb->center, tb->radius);
00282   //  bool res = Intersection<float>(sphere, ln, hit, hit2);
00283 
00284   //  //find closest intersection to sphere
00285   //  float d = (hit - viewpoint).Norm();
00286   //  float d2 = (hit2 - viewpoint).Norm();
00287   //  if(d > d2) hit = hit2;
00288   //  hit -= tb->center;
00289   //} else {
00290   //  if(d > 2.99 * Thr)
00291   //    d = 2.99 * Thr;
00292   //  Point3f norm = (hit - tb->center)^(viewpoint - tb->center);
00293   //  norm.Normalize();
00294   //  float phi = -M_PI/4 - 3*M_PI/8 *(d - Thr)/Thr;
00295 
00296   //  Quaternionf q(phi, norm);
00297   //  hit = q.Rotate((viewpoint - tb->center).Normalize() * tb->radius);
00298   //}
00299   // hit.Normalize();
00300   // return hit;
00301 }
00302 
00321 std::pair< float, bool > LineLineDistance(const Line3f & P,const Line3f & Q,Point3f & P_s, Point3f & Q_t){
00322   Point3f p0 = P.Origin (), Vp = P.Direction ();
00323   Point3f q0 = Q.Origin (), Vq = Q.Direction ();
00324   float VPVP = Vp.dot(Vp);
00325   float VQVQ = Vq.dot(Vq);
00326   float VPVQ = Vp.dot(Vq);
00327   const float det = ( VPVP * VQVQ ) - ( VPVQ * VPVQ );
00328   const float EPSILON = 0.00001f;
00329   if ( fabs(det) < EPSILON ) {
00330     return std::make_pair(Distance(P,q0), true);
00331   }
00332   float b1= (q0 - p0).dot(Vp);
00333   float b2= (p0 - q0).dot(Vq);
00334   float s = ( (VQVQ * b1) + (VPVQ * b2) ) / det;
00335   float t = ( (VPVQ * b1) + (VPVP * b2) ) / det;
00336   P_s = p0 + (Vp * s);
00337   Q_t = q0 + (Vq * t);
00338   return std::make_pair(Distance(P_s,Q_t),false);
00339 }
00340 
00357 std::pair< float, bool > RayLineDistance(const Ray3f & R,const Line3f & Q,Point3f & R_s, Point3f & Q_t){
00358   Point3f r0 = R.Origin (), Vr = R.Direction ();
00359   Point3f q0 = Q.Origin (), Vq = Q.Direction ();
00360   float VRVR = Vr.dot(Vr);
00361   float VQVQ = Vq.dot(Vq);
00362   float VRVQ = Vr.dot(Vq);
00363   const float det = ( VRVR * VQVQ ) - ( VRVQ * VRVQ );
00364   const float EPSILON = 0.00001f;
00365   if ( ( det >= 0.0f ? det : -det) < EPSILON ) {
00366     return std::make_pair(Distance(Q,r0), true);
00367   }
00368   float b1= (q0 - r0).dot(Vr);
00369   float b2= (r0 - q0).dot(Vq);
00370   float s = ( (VQVQ * b1) + (VRVQ * b2) ) / det;
00371   float t = ( (VRVQ * b1) + (VRVR * b2) ) / det;
00372   if(s<0){
00373     R_s = r0;
00374     Q_t = ClosestPoint(Q,R_s);
00375   }else {
00376     R_s = r0 + (Vr * s);
00377     Q_t = q0 + (Vq * t);
00378   }
00379   return std::make_pair(Distance(R_s,Q_t),false);
00380 }
00381 
00383 //  @brief Calculates the minimal distance between 2 segments.
00384 //
00385 //  R e Q are the segments, R_s and Q_t are set to be the closest points on
00386 //  the segments.
00387 //
00388 //  it's returned the distance from R_s and Q_t, and a boolean value which is true
00389 //  if the segments are parallel enough.
00390 //  @param R the first segment.
00391 //  @param Q the second segment.
00392 //  @param R_s the point on R closest to Q.
00393 //  @param Q_t the point on Q closest to R.
00394 //  @return a std::pair made with the distance from R_s to Q_t and a boolean value, true if and only if P and Q are almost parallel.
00395 //*/
00396 //std::pair< float, bool > SegmentSegmentDistance(const Segment3f & R, const Segment3f & Q, Point3f & R_s, Point3f & Q_t)
00397 //{
00398 //  float R_len=Distance(R.P0(),R.P1());
00399 //  float Q_len=Distance(Q.P0(),Q.P1());
00400 //  const float EPSILON_LENGTH = std::max(R_len,Q_len)*0.0001f;
00401 //  if(R_len < EPSILON_LENGTH){
00402 //      R_s=R.P0();
00403 //      Q_t=ClosestPoint(Q,R_s);
00404 //      return std::make_pair(Distance(R_s,Q_t),true);
00405 //  }
00406 //  if( Q_len < EPSILON_LENGTH){
00407 //      Q_t=Q.P0();
00408 //      R_s=ClosestPoint(R,Q_t);
00409 //      return std::make_pair(Distance(R_s,Q_t),true);
00410 //  }
00411 //  Point3f r0 = R.P0(), Vr = (R.P1()-R.P0()).normalized();
00412 //  Point3f q0 = Q.P0(), Vq = (Q.P1()-Q.P0()).normalized();
00413 //  float VRVR = Vr.dot(Vr);
00414 //  float VQVQ = Vq.dot(Vq);
00415 //  float VRVQ = Vr.dot(Vq);
00416 //  const float det = ( VRVR * VQVQ ) - ( VRVQ * VRVQ );
00417 //  const float EPSILON = 0.00001f;
00418 //  if ( ( det >= 0.0f ? det : -det) < EPSILON ) {
00419 //      Line3f lR(R.P0(),R.P1());
00420 //      float qa=lR.Projection(Q.P0());
00421 //      float qb=lR.Projection(Q.P1());
00422 //      if( (qa<=0.0f) && qb<=(0.0f)){
00423 //      R_s=R.P0();
00424 //      Q_t=ClosestPoint(Q,R_s);
00425 //      } else if ( (qa >= 1.0f) && (qb >= 1.0f) ){
00426 //      R_s=R.P1();
00427 //      Q_t=ClosestPoint(Q,R_s);
00428 //      } else {
00429 //      if( (qa >= 0.0f) && (qa <= 1.0f) ){
00430 //        Q_t=Q.P0();
00431 //              R_s=ClosestPoint(R,Q_t);
00432 //        } else if((qb >= 0.0f) && (qb <= 1.0f) ){
00433 //        Q_t=Q.P1();
00434 //        R_s=ClosestPoint(R,Q_t);
00435 //      } else {
00436 //        if( ( ((qa<=0.0f)&&(qb>=1.0f)) || (((qb<=0.0f)&&(qa>=1.0f))))){
00437 //           R_s=R.P0();
00438 //           Q_t=ClosestPoint(Q,R_s);
00439 //        }else{
00440 //           assert(0);
00441 //        }
00442 //      }
00443 //      }
00444 //      return std::make_pair(Distance(R_s,Q_t),true);
00445 //  }
00446 //  float b1= (q0 - r0).dot(Vr);
00447 //  float b2= (r0 - q0).dot(Vq);
00448 //  float s = ( (VQVQ * b1) + (VRVQ * b2) ) / det;
00449 //  float t = ( (VRVQ * b1) + (VRVR * b2) ) / det;
00450 //  if( s < 0 ){
00451 //    R_s = R.P0();
00452 //  }else if ( s > R_len ){
00453 //    R_s = R.P1();
00454 //  } else {
00455 //    R_s = r0 + (Vr * s);
00456 //  }
00457 //  if( t < 0){
00458 //      Q_t = Q.P0();
00459 //  }else if ( t > Q_len ){
00460 //    Q_t = Q.P1();
00461 //  }else{
00462 //    Q_t = q0 + (Vq * t);
00463 //  }
00464 //  return std::make_pair(Distance(R_s,Q_t),false);
00465 //}
00466 
00479 std::pair< Point3f,bool > HitNearestPointOnAxis (Trackball * tb,Line3f axis, Point3f point)
00480 {
00481   Ray3fN ray = line2ray(tb->camera.ViewLineFromWindow (point));
00482   Point3f axis_p(0,0,0), ray_p(0,0,0);
00483   std::pair< float, bool > resp=RayLineDistance(ray,axis,ray_p,axis_p);
00484   if(resp.second || (ray_p == ray.Origin())){
00485     return std::make_pair(Point3f(0,0,0),false);
00486   }
00487   return std::make_pair(axis_p,true);
00488 }
00489 
00500 Line3f ProjectLineOnPlane(const Line3f & ln, const Plane3f & pl)
00501 {
00502   Point3f l0=ln.Origin();
00503   Point3f l1=l0+ln.Direction();
00504   Point3f p1,p2;
00505   p1=pl.Projection(l0);
00506   p2=pl.Projection(l1);
00507   Line3f res(p1,p2-p1);
00508   return res;
00509 }
00510 
00520 float signedDistance(Line3f line,Point3f pt,Point3f positive_dir)
00521 {
00522   return Distance(line,pt) * ((((pt-ClosestPoint(line,pt)).dot(positive_dir)) >= 0.0f )? 1.0f: -1.0f);
00523 }
00524 
00532 float getDeltaY(Trackball * tb, Point3f new_point)
00533 {
00534   float ScreenHeight = float (tb->camera.viewport[3] - tb->camera.viewport[1]);
00535   return (new_point[1] - tb->last_point[1]) / ScreenHeight;
00536 }
00537 
00546 template<class T>
00547   inline bool IntersectionRayPlane( const Plane3<T> & pl, const Ray3<T> & ray, Point3<T> &po){
00548   const T epsilon = T(1e-8);
00549 
00550   T k = pl.Direction().dot(ray.Direction()); // Compute 'k' factor
00551   if( (k > -epsilon) && (k < epsilon))
00552     return false;
00553   T r = (pl.Offset() - pl.Direction().dot(ray.Origin()))/k;  // Compute ray distance
00554   if (r < 0)
00555     return false;
00556   po = ray.Origin() + ray.Direction()*r;
00557   return true;
00558 }
00559 
00573 std::pair< Point3f, bool > HitPlane (Trackball * tb, Point3f point, Plane3f plane)
00574 {
00575   Ray3fN ray = line2ray(tb->camera.ViewLineFromWindow (point));
00576   Point3f p(0,0,0);
00577   bool res = IntersectionRayPlane < float >(plane, ray, p);
00578   return std::make_pair(p,res);
00579 }
00580 
00581 
00582 // drawing section
00583 
00584 // nota: non ho scritto io questa classe,
00585 // quindi la documentazione doxy potrebbe non essere accurata al 100%.
00593 class DrawingHint {
00594 public:
00600   DrawingHint () {
00601     CircleStep = 64;
00602     HideStill = false;
00603     DrawTrack = false;
00604     LineWidthStill = 0.9f;
00605     LineWidthMoving = 1.8f;
00606     color = Color4b::LightBlue;
00607   }
00609   int CircleStep;
00611   bool HideStill;
00613   bool DrawTrack;
00615   Color4b color;
00617   float LineWidthStill;
00619   float LineWidthMoving;
00620 };
00621 
00623 DrawingHint DH;
00624 
00625 // nota: non ho scritto io questa funzione,
00626 // quindi la documentazione doxy potrebbe non essere accurata al 100%.
00630 void DrawPlaneHandle ()
00631 {
00632   float r = 1.0;
00633   float dr = r / 10.0f;
00634 
00635   glBegin (GL_LINE_STRIP);
00636   glVertex3f (+r + dr, +r, 0.0);
00637   glVertex3f (+r, +r + dr, 0.0);
00638   glVertex3f (+r - dr, +r, 0.0);
00639   glVertex3f (+r, +r - dr, 0.0);
00640   glVertex3f (+r + dr, +r, 0.0);
00641   glEnd ();
00642   glBegin (GL_LINE_STRIP);
00643   glVertex3f (-r + dr, -r, 0.0);
00644   glVertex3f (-r, -r + dr, 0.0);
00645   glVertex3f (-r - dr, -r, 0.0);
00646   glVertex3f (-r, -r - dr, 0.0);
00647   glVertex3f (-r + dr, -r, 0.0);
00648   glEnd ();
00649 }
00650 
00651 // nota: non ho scritto io questa funzione,
00652 // quindi la documentazione doxy potrebbe non essere accurata al 100%.
00656 void DrawCircle (bool planehandle=true)
00657 {
00658   int nside = DH.CircleStep;
00659   const double pi2 = 3.14159265 * 2.0;
00660   glBegin (GL_LINE_LOOP);
00661   for (double i = 0; i < nside; i++) {
00662     glNormal3d (cos (i * pi2 / nside), sin (i * pi2 / nside), 0.0);
00663     glVertex3d (cos (i * pi2 / nside), sin (i * pi2 / nside), 0.0);
00664   }
00665   glEnd ();
00666   if(planehandle)
00667     DrawPlaneHandle();
00668 }
00669 
00676 void DrawSphereIcon (Trackball * tb, bool active, bool planeshandle=false)
00677 {
00678   glPushAttrib(GL_TRANSFORM_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LINE_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT);
00679   glMatrixMode(GL_MODELVIEW);
00680   glPushMatrix ();
00681   glDepthMask(GL_FALSE);
00682 
00683   Point3f center = tb->center + tb->track.InverseMatrix()*Point3f(0, 0, 0);
00684   glTranslate(center);
00685   glScale (tb->radius/tb->track.sca);
00686 
00687   float amb[4] = { .35f, .35f, .35f, 1.0f };
00688   float col[4] = { .5f, .5f, .8f, 1.0f };
00689   glEnable (GL_LINE_SMOOTH);
00690   if (active)
00691     glLineWidth (DH.LineWidthMoving);
00692   else
00693     glLineWidth (DH.LineWidthStill);
00694   glDisable(GL_COLOR_MATERIAL); // has to be disabled, it is used by wrapper to draw meshes, and prevent direct material setting, used here
00695 
00696   glEnable (GL_LIGHTING);
00697   glEnable (GL_LIGHT0);
00698   glEnable (GL_BLEND);
00699   glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00700   glColor (DH.color);
00701   glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, amb);
00702 
00703   col[0] = .40f; col[1] = .40f; col[2] = .85f;
00704   glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, col);
00705     DrawCircle(planeshandle);
00706 
00707   glRotatef (90, 1, 0, 0);
00708   col[0] = .40f; col[1] = .85f; col[2] = .40f;
00709   glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, col);
00710   DrawCircle(planeshandle);
00711 
00712   glRotatef (90, 0, 1, 0);
00713   col[0] = .85f; col[1] = .40f; col[2] = .40f;
00714   glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, col);
00715     DrawCircle(planeshandle);
00716 
00717     glPopMatrix ();
00718     glPopAttrib ();
00719 }
00720 
00721 // TEMPORARY drawing section
00722 // Disclaimer: the following code is of VERY POOR quality
00723 // feel free to delete and rewrite everything
00724 
00731 void prepare_attrib()
00732 {
00733   float amb[4] = { .3f, .3f, .3f, 1.0f };
00734   float col[4] = { .5f, .5f, .8f, 1.0f };
00735   glEnable (GL_LIGHTING);
00736   glEnable (GL_LIGHT0);
00737   glEnable (GL_LINE_SMOOTH);
00738   glEnable (GL_BLEND);
00739   glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00740   glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, amb);
00741   glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, col);
00742 }
00743 
00752 void DrawUglyLetter(Trackball * tb,std::vector<Point3f> ugly_letter)
00753 {
00754   Point3f center=tb->camera.Project(tb->center);
00755   float offset=0;
00756   offset=(std::max)(offset,Distance(center,tb->camera.Project(tb->center+(Point3f(1,0,0) * tb->radius))));
00757   offset=(std::max)(offset,Distance(center,tb->camera.Project(tb->center+(Point3f(0,1,0) * tb->radius))));
00758   offset=(std::max)(offset,Distance(center,tb->camera.Project(tb->center+(Point3f(0,0,1) * tb->radius))));
00759   glPushMatrix();
00760   glPushAttrib (GL_ALL_ATTRIB_BITS);
00761    // go to world coords
00762   glTranslate (tb->center);
00763   glMultMatrix (tb->track.InverseMatrix ());
00764   glTranslate (-tb->center);
00765   prepare_attrib();
00766   glColor3f(1,1,1);
00767   glLineWidth(4.0);
00768 
00769   glBegin(GL_LINE_STRIP);
00770     for(unsigned int i=0;i<ugly_letter.size();i++){
00771       glVertex(tb->camera.UnProject(center+(ugly_letter[i] * offset * 0.25)
00772                +Point3f(-offset,-offset,0)));
00773     }
00774   glEnd();
00775   glPopAttrib ();
00776   glPopMatrix();
00777 
00778 }
00779 
00787 void DrawUglyPanMode(Trackball * tb)
00788 {
00789   std::vector<Point3f> ugly_p;
00790   ugly_p.push_back(Point3f(-1,-1,0));
00791   ugly_p.push_back(Point3f(-1,1,0));
00792   ugly_p.push_back(Point3f(1,1,0));
00793   ugly_p.push_back(Point3f(1,0,0));
00794   ugly_p.push_back(Point3f(-1,0,0));
00795 
00796   DrawUglyLetter(tb,ugly_p);
00797 }
00798 
00806 void DrawUglyZMode(Trackball * tb)
00807 {
00808   std::vector<Point3f> ugly_z;
00809   ugly_z.push_back(Point3f(-1,1,0));
00810   ugly_z.push_back(Point3f(1,1,0));
00811   ugly_z.push_back(Point3f(-1,-1,0));
00812   ugly_z.push_back(Point3f(1,-1,0));
00813   DrawUglyLetter(tb,ugly_z);
00814 }
00815 
00823 void DrawUglyScaleMode(Trackball * tb)
00824 {
00825   std::vector<Point3f> ugly_s;
00826   ugly_s.push_back(Point3f(1,1,0));
00827   ugly_s.push_back(Point3f(-1,1,0));
00828   ugly_s.push_back(Point3f(-1,0,0));
00829   ugly_s.push_back(Point3f(1,0,0));
00830   ugly_s.push_back(Point3f(1,-1,0));
00831   ugly_s.push_back(Point3f(-1,-1,0));
00832   DrawUglyLetter(tb,ugly_s);
00833 }
00834 
00843 void DrawUglyAxisMode(Trackball * tb,Line3f axis)
00844 {
00845   glPushMatrix();
00846   glPushAttrib (GL_ALL_ATTRIB_BITS);
00847   // go to world coords
00848   glTranslate (tb->center);
00849   glMultMatrix (tb->track.InverseMatrix ());
00850   glTranslate (-tb->center);
00851   prepare_attrib();
00852   glColor3f(0.9f, 0.9f, 0.2f);
00853   glLineWidth(2.0);
00854    glBegin(GL_LINES);
00855     glVertex(axis.Origin()+(axis.Direction()*100));
00856     glVertex(axis.Origin()-(axis.Direction()*100));
00857   glEnd();
00858   glPointSize(8.0);
00859   glColor3f(0.2f, 0.2f, 0.9f);
00860   glBegin(GL_POINTS);
00861     glVertex(axis.Origin());
00862   glEnd();
00863   glPopAttrib ();
00864   glPopMatrix();
00865 }
00866 
00875 void DrawUglyPlaneMode(Trackball * tb,Plane3f plane)
00876 {
00877   glPushMatrix();
00878   glPushAttrib (GL_ALL_ATTRIB_BITS);
00879   // go to world coords
00880   glTranslate (tb->center);
00881   glMultMatrix (tb->track.InverseMatrix ());
00882   glTranslate (-tb->center);
00883   prepare_attrib();
00884   Point3f p0,d1,d2,norm;
00885   norm=plane.Direction();
00886   p0=plane.Projection(Point3f(0,0,0));
00887   d1=Point3f(0,1,0);
00888   if(norm == d1 || norm == -d1)
00889     d1 = Point3f(1,0,0);
00890   d2=plane.Projection(d1);
00891   d1=(d2 - p0).normalized();
00892   d2=(d1 ^ norm).normalized();
00893   glLineWidth(3.0);
00894   glColor3f(0.2f, 0.2f, 0.9f);
00895   glBegin(GL_LINES);
00896     glVertex(p0);
00897     glVertex(p0+norm);
00898   glEnd();
00899   glLineWidth(1.0);
00900   for(float i=0.5f; i<100.0f; i+=0.7f){
00901     glBegin(GL_LINE_LOOP);
00902     for(int a=0;a<360;a+=10){
00903       float f0=i*cosf((float(M_PI)*float(a))/180.0f);
00904       float f1=i*sinf((float(M_PI)*float(a))/180.0f);
00905       glVertex(p0+(d1*f0)+(d2*f1));
00906     }
00907     glEnd();
00908   }
00909   glColor3f(0.9f, 0.9f, 0.2f);
00910   glPointSize(8.0f);
00911   glBegin(GL_POINTS);
00912     glVertex(p0);
00913   glEnd();
00914   glColor3f(0.7f, 0.7f, 0.0f);
00915   glPointSize(6.0);
00916   glBegin(GL_POINTS);
00917     glVertex(p0+norm);
00918   glEnd();
00919   glPopAttrib ();
00920   glPopMatrix();
00921 }
00922 
00931 void DrawUglyCylinderMode(Trackball * tb,Line3f axis)
00932 {
00933   glPushMatrix();
00934   glPushAttrib (GL_ALL_ATTRIB_BITS);
00935   // go to world coords
00936   glTranslate (tb->center);
00937   glMultMatrix (tb->track.InverseMatrix ());
00938   glTranslate (-tb->center);
00939   prepare_attrib();
00940   Plane3f plane;
00941   plane.Init(axis.Origin(),axis.Direction());
00942   Point3f p0,d1,d2,norm;
00943   norm=plane.Direction();
00944   p0=plane.Projection(Point3f(0,0,0));
00945   d1=Point3f(0,1,0);
00946   if(norm == d1 || norm == -d1)
00947     d1 = Point3f(1,0,0);
00948   d2=plane.Projection(d1);
00949   d1=(d2 - p0).normalized();
00950   d2=(d1 ^ norm).normalized();
00951   glLineWidth(1.0);
00952   glColor3f(0.2f, 0.2f, 0.9f);
00953   for(int i=-100;i<100;i++){
00954     glBegin(GL_LINE_LOOP);
00955     for(int a=0;a<360;a+=10){
00956       float f0=(tb->radius)*cosf((float(M_PI)*float(a))/180.0f);
00957       float f1=(tb->radius)*sinf((float(M_PI)*float(a))/180.0f);
00958       glVertex(axis.Origin()+p0+(norm*float(i))+(d1*f0)+(d2*f1));
00959     }
00960     glEnd();
00961   }
00962   glLineWidth(3.0);
00963   glColor3f(0.2f, 0.2f, 0.9f);
00964   glBegin(GL_LINES);
00965      glVertex(axis.Origin());
00966      glVertex(axis.Origin()+(axis.Direction()*100));
00967   glEnd();
00968   glLineWidth(1.5);
00969   glColor3f(0.9f, 0.2f, 0.9f);
00970   glBegin(GL_LINES);
00971     glVertex(axis.Origin());
00972     glVertex(axis.Origin()-(axis.Direction()*100));
00973   glEnd();
00974   glColor3f(0.9f, 0.9f, 0.2f);
00975   glPointSize(8.0);
00976   glBegin(GL_POINTS);
00977     glVertex(axis.Origin());
00978   glEnd();
00979   glPopAttrib ();
00980   glPopMatrix();
00981 }
00982 
00996 void DrawUglyPathMode(Trackball * tb,const std::vector < Point3f > &points,
00997                       Point3f current_point,Point3f prev_point,
00998                       Point3f next_point,Point3f old_hitpoint,bool wrap)
00999 {
01000   glPushMatrix();
01001   glPushAttrib (GL_ALL_ATTRIB_BITS);
01002   // go to world coords
01003   glTranslate (tb->center);
01004   glMultMatrix (tb->track.InverseMatrix ());
01005   glTranslate (-tb->center);
01006   prepare_attrib();
01007   glColor3f(0.9f, 0.9f, 0.2f);
01008   glLineWidth(2.0);
01009   if(wrap)
01010     glBegin(GL_LINE_LOOP);
01011   else
01012     glBegin(GL_LINE_STRIP);
01013   for (std::vector < Point3f >::const_iterator i = points.begin (); i != points.end (); ++i){
01014     glVertex(*i);
01015   }
01016   glEnd();
01017   glColor3f(1,0,1);
01018   glPointSize(8.0);
01019   glBegin(GL_POINTS);
01020     glVertex(current_point);
01021   glEnd();
01022   glColor3f(0.6f, 0.0f, 0.6f);
01023   glPointSize(7.0);
01024   glBegin(GL_POINTS);
01025     glVertex(old_hitpoint);
01026   glEnd();
01027   glColor3f(0.7f, 0.7f, 0.7f);
01028   glPointSize(6.5);
01029   glBegin(GL_POINTS);
01030     glVertex(prev_point);
01031     glVertex(next_point);
01032   glEnd();
01033   glPopAttrib ();
01034   glPopMatrix();
01035 }
01036 
01050 void DrawUglyAreaMode(Trackball * tb,const std::vector < Point3f > &points,
01051                       Point3f status,Point3f old_status,Plane3f plane,
01052                       const std::vector < Point3f > &path,Point3f rubberband_handle)
01053 {
01054   glPushMatrix();
01055   glPushAttrib (GL_ALL_ATTRIB_BITS);
01056   // go to world coords
01057   glTranslate (tb->center);
01058   glMultMatrix (tb->track.InverseMatrix ());
01059   glTranslate (-tb->center);
01060   prepare_attrib();
01061   glColor3f(0.9f, 0.9f, 0.2f);
01062   glLineWidth(2.0);
01063   glBegin(GL_LINE_LOOP);
01064   for (std::vector < Point3f >::const_iterator i = points.begin (); i != points.end (); ++i){
01065     glVertex(*i);
01066   }
01067   glEnd();
01068   glColor3f(0.0f, 0.9f, 0.2f);
01069   glLineWidth(1.2f);
01070   glBegin(GL_LINE_STRIP);
01071   for (std::vector < Point3f >::const_iterator i = path.begin (); i != path.end (); ++i){
01072     glVertex(*i);
01073   }
01074   glEnd();
01075    glColor3f(1,0,1);
01076   glPointSize(8.0);
01077   glBegin(GL_POINTS);
01078     glVertex(status);
01079   glEnd();
01080   glColor3f(0.6f, 0.0f, 0.6f);
01081   glPointSize(7.0);
01082   glBegin(GL_POINTS);
01083     glVertex(old_status);
01084   glEnd();
01085   glColor3f(0.6f, 0.0f, 0.0f);
01086   glPointSize(6.0);
01087   glBegin(GL_POINTS);
01088     glVertex(rubberband_handle);
01089   glEnd();
01090   glLineWidth(1.0);
01091   glBegin(GL_LINES);
01092     glVertex(rubberband_handle);
01093     glVertex(status);
01094   glEnd();
01095   Point3f p0,d1,d2,norm;
01096   norm=plane.Direction();
01097   p0=plane.Projection(Point3f(0,0,0));
01098   d1=Point3f(0,1,0);
01099   if(norm == d1 || norm == -d1)
01100     d1 = Point3f(1,0,0);
01101   d2=plane.Projection(d1);
01102   d1=(d2 - p0).normalized();
01103   d2=(d1 ^ norm).normalized();
01104   glLineWidth(3.0);
01105   glColor3f(0.2f, 0.2f, 0.9f);
01106   glBegin(GL_LINES);
01107     glVertex(p0);
01108     glVertex(p0+norm);
01109   glEnd();
01110   glLineWidth(0.1f);
01111   for(float i=0.5f;i<100.0f; i+=0.7f){
01112     glBegin(GL_LINE_LOOP);
01113     for(int a=0;a<360;a+=10){
01114       float f0=i*cosf((float(M_PI)*float(a))/180.0f);
01115       float f1=i*sinf((float(M_PI)*float(a))/180.0f);
01116       glVertex(p0+(d1*f0)+(d2*f1));
01117     }
01118     glEnd();
01119   }
01120 
01121   glPopAttrib ();
01122   glPopMatrix();
01123 }
01124 
01125 
01126 } //end namespace trackutils
01127 
01128 } //end namespace vcg
01129 
01130 #endif //TRACKUTILS_H


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:37:26