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
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
00075 Wpt ray_pt = ray.line().intersect(Wline(point(i), point(i+1)));
00076
00077
00078 if ((ray_pt - ray.point()) * ray.vec() > 0 ) {
00079
00080
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
00090
00091 surf_norm = -ray.vec().normalized();
00092 }
00093 }
00094 }
00095
00096
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
00107
00108
00109
00110
00111 return _draw(COLOR::black, 1, _width, false);
00112 }
00113
00114 int
00115 LINE3D::draw(CVIEWptr& v)
00116 {
00117
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
00142 if (num() == 1) {
00143
00144 glPushAttrib(GL_ENABLE_BIT | GL_POINT_BIT | GL_CURRENT_BIT);
00145 glPointSize(float(w));
00146 } else {
00147
00148 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_CURRENT_BIT);
00149 glLineWidth(float(w));
00150 if (do_stipple) {
00151 glLineStipple(1,0x00ff);
00152 glEnable(GL_LINE_STIPPLE);
00153 }
00154 }
00155
00156 if (_no_depth)
00157 glDisable(GL_DEPTH_TEST);
00158
00159
00160 glDisable(GL_LIGHTING);
00161
00162
00163 GL_COL(col, a);
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