Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

line3d.C

Go to the documentation of this file.
00001 #include "disp/ray.H"
00002 #include "geom/gl_util.H"
00003 #include "geom/world.H"
00004 #include "geom/line3d.H"
00005 
00006 using mlib::Wpt;
00007 using mlib::CWpt;
00008 using mlib::CWpt_list;
00009 using mlib::Wvec;
00010 using mlib::Wline;
00011 using mlib::CWtransf;
00012 using mlib::XYpt;
00013 using mlib::PIXEL;
00014 
00015 LINE3D::LINE3D() :
00016    _width(3.0),
00017    _color(COLOR::black),
00018    _alpha(1.0),
00019    _do_stipple(false),
00020    _no_depth(false)
00021 {}
00022 
00023 LINE3D::LINE3D(CWpt_list& pts) :
00024    _pts(pts),
00025    _width(3.0),
00026    _color(COLOR::black),
00027    _alpha(1.0),
00028    _do_stipple(false),
00029    _no_depth(false)
00030 {
00031    _pts.update_length();
00032 }
00033 
00034 LINE3D::~LINE3D() 
00035 {
00036 }
00037 
00038 void
00039 LINE3D::add(CWpt& p)
00040 {
00041    _pts += p;
00042    _pts.update_length();
00043 }
00044 
00045 void 
00046 LINE3D::set(int i, CWpt& p)
00047 {
00048    assert(_pts.valid_index(i));
00049    _pts[i] = p;
00050    _pts.update_length();
00051 }
00052 
00053 void
00054 LINE3D::add(CWpt_list& pts)
00055 {
00056    _pts.operator+=(pts);
00057    _pts.update_length();
00058 }
00059 
00060 RAYhit &
00061 LINE3D::intersect(
00062    RAYhit  &ray,
00063    CWtransf&,
00064    int 
00065    ) const
00066 {
00067    // Find the intersection point, its distance, and some kind of normal
00068    double distance = -1, d_2d = -1;
00069    Wvec   surf_norm;
00070    Wpt    nearpt;
00071 
00072    for (int i=0; i<num()-1; i++) {
00073 
00074       // Find the nearest point on the ray to the segment.
00075       Wpt ray_pt = ray.line().intersect(Wline(point(i), point(i+1)));
00076 
00077       // Accept only if ray_pt is in front of the ray
00078       if ((ray_pt - ray.point()) * ray.vec() > 0 ) {
00079 
00080          // Ok if the ray passes within 10 pixels of the segment
00081          const double PIX_THRESH = 10.0;
00082          Wpt hit_pt = nearest_pt_to_line_seg(ray_pt, point(i), point(i+1)); 
00083          double screen_dist = PIXEL(hit_pt).dist(ray_pt);
00084          if ((screen_dist < PIX_THRESH) && (d_2d < 0 || screen_dist < d_2d)) {
00085             d_2d      = screen_dist;
00086             distance  = ray.point().dist(ray_pt);
00087             nearpt    = hit_pt;
00088 
00089             // XXX - What should be the "normal"?  For now,
00090             //       just the vector pointing back to the camera.
00091             surf_norm = -ray.vec().normalized();
00092          }
00093       } 
00094    }
00095 
00096    // Then call ray.check() passing it all this stuff
00097    if (distance >= 0)
00098       ray.check(distance, 1, 0, (GEL*)this, surf_norm, nearpt, nearpt,
00099                 0, XYpt());
00100    return ray;
00101 }
00102 
00103 int
00104 LINE3D::draw_vis_ref() 
00105 {
00106    // Draw the polyline in black in the visibility reference
00107    // image so meshes that are behind the line get obscured. No
00108    // transparency (alpha = 1). Don't scale the width, which is
00109    // useful only when rendering high-resolution color reference
00110    // images. And no stippling:
00111    return _draw(COLOR::black, 1, _width, false);
00112 }
00113 
00114 int
00115 LINE3D::draw(CVIEWptr& v) 
00116 {
00117    // See draw_vis_ref() for why you wouldn't always want these params:
00118    return _draw(_color, _alpha, v->line_scale()*_width, _do_stipple);
00119 }
00120 
00121 int
00122 LINE3D::_draw(CCOLOR& col, double a, double w, bool do_stipple)
00123 {
00124    if (empty())
00125       return 0;     
00126          
00127    draw_start(col, a, w, do_stipple);
00128    draw_pts();
00129    draw_end();
00130    
00131    return 0;
00132 
00133 }
00134 
00135 void
00136 LINE3D::draw_start(CCOLOR& col, double a, double w, bool do_stipple)
00137 {
00138    if (empty())
00139       return;
00140 
00141    // Draw a single point, or a polyline?
00142    if (num() == 1) {
00143       // Draw a point
00144       glPushAttrib(GL_ENABLE_BIT | GL_POINT_BIT | GL_CURRENT_BIT);
00145       glPointSize(float(w));            // GL_POINT_BIT
00146    } else {
00147       // Draw a polyline
00148       glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_CURRENT_BIT);
00149       glLineWidth(float(w));            // GL_LINE_BIT
00150       if (do_stipple) {
00151          glLineStipple(1,0x00ff);       // GL_LINE_BIT
00152          glEnable(GL_LINE_STIPPLE);     // GL_ENABLE_BIT
00153       }
00154    }
00155 
00156    if (_no_depth)
00157       glDisable(GL_DEPTH_TEST);
00158 
00159    // No lighting:
00160    glDisable(GL_LIGHTING);              // GL_ENABLE_BIT
00161 
00162    // Set the color:
00163    GL_COL(col, a);                      // GL_CURRENT_BIT
00164     
00165 }
00166 
00167 void
00168 LINE3D::draw_pts()
00169 {
00170    if (empty())
00171       return;
00172 
00173    glBegin(num()==1 ? GL_POINTS : GL_LINE_STRIP);
00174    for (int k=0; k<_pts.num(); k++)
00175       glVertex3dv(_pts[k].data());
00176    glEnd();
00177 }
00178 
00179 void
00180 LINE3D::draw_end()
00181 {
00182    if (empty())
00183       return;
00184 
00185    glPopAttrib();
00186 }
00187 
00188 // end of file line3d.C

Generated on Mon Sep 18 11:39:32 2006 for jot by  doxygen 1.4.4