osg::Line Class Reference
[Base]

#include <OSGLine.h>

List of all members.

Public Member Functions

Constructors


 Line (void)
 Line (const Line &obj)
 Line (const Pnt3f &p0, const Pnt3f &p1)
 Line (const Pnt3f &pos, const Vec3f &dir)
Destructor


 ~Line (void)
Set


void setValue (const Pnt3f &p0, const Pnt3f &p1)
void setValue (const Pnt3f &pos, const Vec3f &dir)
Class Specific


bool getClosestPoints (const Line &line2, Pnt3f &ptOnThis, Pnt3f &ptOnLine2) const
Pnt3f getClosestPoint (const Pnt3f &point) const
Real32 distance (const Pnt3f &point) const
Get


const Pnt3fgetPosition (void) const
const Vec3fgetDirection (void) const
Intersection


bool intersect (const SphereVolume &sphere) const
bool intersect (const SphereVolume &sphere, Real32 &enter, Real32 &exit) const
bool intersect (const CylinderVolume &cyl) const
bool intersect (const CylinderVolume &cyl, Real32 &enter, Real32 &exit) const
bool intersect (const FrustumVolume &frustum) const
bool intersect (const FrustumVolume &frustum, Real32 &enter, Real32 &exit) const
bool intersect (const BoxVolume &box, Real32 &enter, Real32 &exit) const
bool intersect (Real32 angle, const BoxVolume &box) const
bool intersect (Real32 angle, const Vec3f &point) const
bool intersect (Real32 angle, const Vec3f &v0, const Vec3f &v1, Vec3f &pt) const
bool intersect (const Pnt3f &v0, const Pnt3f &v1, const Pnt3f &v2, Real32 &t, Vec3f *normal=NULL) const

Private Attributes

Pnt3f _pos
Vec3f _dir


Detailed Description

A line starting at a point p and extending infinitely far into the direction d. This will probably split up into multiple classes for dual-inifinite and non-infinite lines

Definition at line 56 of file OSGLine.h.


Constructor & Destructor Documentation

Line::Line ( void   ) 

Definition at line 68 of file OSGLine.cpp.

00068                : 
00069     _pos(0.f, 0.f ,0.f), 
00070     _dir(0.f, 0.f, 0.f)
00071 {
00072 }

Line::Line ( const Line obj  ) 

Definition at line 75 of file OSGLine.cpp.

00075                           : 
00076     _pos(obj._pos), 
00077     _dir(obj._dir)
00078 {
00079 }

Line::Line ( const Pnt3f p0,
const Pnt3f p1 
)

Definition at line 82 of file OSGLine.cpp.

References setValue().

00083 {
00084     setValue(p0, p1);
00085 }

Line::Line ( const Pnt3f pos,
const Vec3f dir 
)

Definition at line 88 of file OSGLine.cpp.

References setValue().

00089 {
00090     setValue(pos, dir);
00091 }

Line::~Line ( void   ) 

Definition at line 96 of file OSGLine.cpp.

00097 {
00098 }


Member Function Documentation

void Line::setValue ( const Pnt3f p0,
const Pnt3f p1 
)

void Line::setValue ( const Pnt3f pos,
const Vec3f dir 
)

Definition at line 111 of file OSGLine.cpp.

References _dir, _pos, and osg::VectorInterface< ValueTypeT, StorageInterfaceT >::normalize().

00112 {
00113     _pos = pos;
00114     _dir = dir;
00115     _dir.normalize();
00116 }

bool Line::getClosestPoints ( const Line line2,
Pnt3f ptOnThis,
Pnt3f ptOnLine2 
) const

Find closest points between the two lines. Return false if they are parallel, otherwise return true.

Definition at line 122 of file OSGLine.cpp.

References _dir, _pos, osg::VectorInterface< ValueTypeT, StorageInterfaceT >::cross(), osg::VectorInterface< ValueTypeT, StorageInterfaceT >::dot(), osg::PointInterface< ValueTypeT, StorageInterfaceT >::isZero(), and osg::VectorInterface< ValueTypeT, StorageInterfaceT >::squareLength().

00126 {
00127     // Assumes that _dir and line2._dir are valid and normalized
00128 
00129     Vec3f normal=_dir.cross(line2._dir);
00130     if(normal.isZero()) return false; // Lines are parallel
00131 
00132     Vec3f p0p1=line2._pos-_pos;
00133     Real32 lengthSqr=normal.squareLength();
00134     Real32 s=p0p1.cross(line2._dir).dot(normal) / lengthSqr;
00135     Real32 t=p0p1.cross(      _dir).dot(normal) / lengthSqr;
00136 
00137     ptOnThis =      _pos + s *       _dir;
00138     ptOnLine2=line2._pos + t * line2._dir;
00139 
00140     return true;
00141 }

Pnt3f Line::getClosestPoint ( const Pnt3f point  )  const

Returns the closest point on the line to the given point.

Definition at line 146 of file OSGLine.cpp.

References _dir, _pos, and osg::VectorInterface< ValueTypeT, StorageInterfaceT >::dot().

Referenced by distance().

00147 {
00148     Vec3f vec(point - _pos);
00149 
00150     return _pos + _dir * vec.dot(_dir);
00151 }

Real32 Line::distance ( const Pnt3f point  )  const

Returns the distance of the given point to the line.

Definition at line 157 of file OSGLine.cpp.

References getClosestPoint().

00158 {
00159     return (point - getClosestPoint(point)).length();
00160 }

const Pnt3f & osg::Line::getPosition ( void   )  const [inline]

const Vec3f & osg::Line::getDirection ( void   )  const [inline]

bool Line::intersect ( const SphereVolume sphere  )  const

Intersect the Line with a Sphere

Definition at line 168 of file OSGLine.cpp.

Referenced by osg::SphereVolume::intersect(), intersect(), osg::Geometry::intersect(), osg::FrustumVolume::intersect(), osg::CylinderVolume::intersect(), and osg::BoxVolume::intersect().

00169 {
00170     Real32 ent;
00171     Real32 ex;
00172 
00173     return this->intersect(sphere, ent, ex);
00174 }

bool Line::intersect ( const SphereVolume sphere,
Real32 enter,
Real32 exit 
) const

Intersect the line with a sphere, returns points of intersection

Definition at line 179 of file OSGLine.cpp.

References _dir, _pos, osg::VectorInterface< ValueTypeT, StorageInterfaceT >::dot(), osg::Eps, osg::SphereVolume::getCenter(), osg::SphereVolume::getRadius(), and osg::osgsqrt().

00182 {
00183 
00184     Vec3f v;
00185     Pnt3f center;
00186 
00187     sphere.getCenter(center);
00188 
00189     Real32 radius;
00190     Real32 h;
00191     Real32 b;
00192     Real32 d;
00193     Real32 t1;
00194     Real32 t2;
00195 
00196     radius = sphere.getRadius();
00197 
00198     v = center - _pos;
00199 
00200     h = (v.dot(v))-(radius*radius);
00201     b = (v.dot(_dir));
00202 
00203     if(h >= 0 && b <= 0)
00204         return false;
00205 
00206     d = b * b - h;
00207 
00208     if(d < 0)
00209         return false;
00210 
00211     d  = osgsqrt(d);
00212     t1 = b - d;
00213 
00214 //    if (t1 > 1)
00215 //        return false;
00216 
00217     t2 = b + d;
00218 
00219     if( t1 < Eps )
00220     {
00221         if( t2 < Eps /*|| t2 > 1*/)
00222         {
00223             return false;
00224         }
00225     }
00226 
00227     enter = t1;
00228     exit  = t2;
00229 
00230     return true;
00231 }

bool Line::intersect ( const CylinderVolume cyl  )  const

Intersect the line with a cylinder

Definition at line 236 of file OSGLine.cpp.

References intersect().

00237 {
00238     Real32 ent;
00239     Real32 ex;
00240 
00241     return this->intersect(cyl, ent, ex);
00242 }

bool Line::intersect ( const CylinderVolume cyl,
Real32 enter,
Real32 exit 
) const

Intersect the line with a cylinder, returns points of intersection based on GGems IV

Definition at line 248 of file OSGLine.cpp.

References _dir, _pos, osg::VectorInterface< ValueTypeT, StorageInterfaceT >::cross(), osg::VectorInterface< ValueTypeT, StorageInterfaceT >::dot(), osg::CylinderVolume::getAxis(), osg::CylinderVolume::getRadius(), osg::Inf, osg::Plane::intersect(), osg::Plane::isInHalfSpace(), osg::VectorInterface< ValueTypeT, StorageInterfaceT >::length(), osg::VectorInterface< ValueTypeT, StorageInterfaceT >::normalize(), osg::osgabs(), and osg::osgsqrt().

00251 {
00252     Real32 radius = cyl.getRadius();
00253 
00254     Vec3f adir;
00255     Vec3f o_adir;
00256     Pnt3f apos;
00257 
00258     cyl.getAxis(apos, adir);
00259 
00260     o_adir = adir;
00261     adir.normalize();
00262 
00263     bool isect;
00264 
00265     Real32 ln;
00266     Real32 dl;
00267     Vec3f  RC;
00268     Vec3f  n;
00269     Vec3f  D;
00270 
00271     RC = _pos - apos;
00272 
00273     n  = _dir.cross (adir);
00274     ln =  n  .length(    );
00275 
00276     if(ln == 0)    // IntersectionLine is parallel to CylinderAxis
00277     {
00278         D  = RC - (RC.dot(adir)) * adir;
00279         dl = D.length();
00280 
00281         if(dl <= radius)   // line lies in cylinder
00282         {
00283             enter = 0;
00284             exit  = Inf;
00285         }
00286         else
00287         {
00288             return false;
00289         }
00290     }
00291     else
00292     {
00293         n.normalize();
00294 
00295         dl    = osgabs(RC.dot(n));        //shortest distance
00296         isect = (dl <= radius);
00297 
00298         if(isect)
00299         {                 // if ray hits cylinder
00300             Real32 t;
00301             Real32 s;
00302             Vec3f  O;
00303 
00304             O = RC.cross(adir);
00305             t = - (O.dot(n)) / ln;
00306             O = n.cross(adir);
00307 
00308             O.normalize();
00309 
00310             s = osgabs (
00311                 (osgsqrt ((radius * radius) - (dl * dl))) / (_dir.dot(O)));
00312 
00313             exit = t + s;
00314 
00315             if(exit < 0)
00316                 return false;
00317 
00318             enter = t - s;
00319 
00320             if(enter < 0)
00321                 enter = 0;
00322         }
00323         else
00324         {
00325             return false;
00326         }
00327     }
00328 
00329     Real32 t;
00330 
00331     Plane bottom(-adir, apos);
00332 
00333     if(bottom.intersect(*this, t))
00334     {
00335         if(bottom.isInHalfSpace(_pos))
00336         {
00337             if(t > enter) 
00338                 enter = t;
00339         }
00340         else
00341         {
00342             if(t < exit) 
00343                 exit = t;
00344         }
00345     }
00346     else
00347     {
00348         if(bottom.isInHalfSpace(_pos))
00349             return false;
00350     }
00351     
00352     Plane top(adir, apos + o_adir);
00353 
00354     if(top.intersect(*this, t))
00355     {
00356         if(top.isInHalfSpace(_pos))
00357         {
00358             if(t > enter)
00359                 enter = t;
00360         }
00361         else
00362         {
00363             if(t < exit)
00364                 exit = t;
00365         }
00366     }
00367     else
00368     {
00369         if(top.isInHalfSpace(_pos))
00370             return false;
00371     }
00372 
00373     return (enter < exit);
00374 }

bool Line::intersect ( const FrustumVolume frustum  )  const

Intersect the line with a frustum

Definition at line 379 of file OSGLine.cpp.

References intersect().

00380 {
00381     Real32 ent;
00382     Real32 ex;
00383 
00384     return this->intersect(frustum, ent, ex);
00385 }

bool Line::intersect ( const FrustumVolume frustum,
Real32 enter,
Real32 exit 
) const

Intersect the line with a frustum, returns points of intersection based on Cyrus Beck Algorithm for clipping a line segment to a convex volume.

Definition at line 409 of file OSGLine.cpp.

References _dir, _pos, osg::VectorInterface< ValueTypeT, StorageInterfaceT >::dot(), osg::Plane::getNormal(), osg::FrustumVolume::getPlanes(), and osg::Plane::intersect().

00412 {
00413     const Real32 inf = 2 << 16;
00414 
00415     Pnt3f enter_point = _pos + _dir * 0;
00416     Pnt3f exit_point  = _pos + _dir * inf;
00417 
00418     face faces[6];
00419 
00420     const Plane *planes = frustum.getPlanes();
00421 
00422     Line lines[2];
00423 
00424     //ln[0] - intersection of right and top planes
00425     planes[3].intersect(planes[4], lines[0]); 
00426 
00427     //ln[1] - left and bottom
00428     planes[2].intersect(planes[5], lines[1]); 
00429 
00430     Pnt3f pointA;
00431     Pnt3f pointB;
00432 
00433     if(!planes[0].intersectInfinite(lines[0],pointA))
00434         std::cout << "This should never happen (A)!!!!";
00435                     
00436     if(!planes[1].intersectInfinite(lines[1],pointB))
00437         std::cout << "This should never happen (B)!!!!";
00438 
00439     faces[0].point        = pointA; 
00440     faces[0].inner_vector = pointB - pointA;
00441 
00442     faces[1].point        = pointB; 
00443     faces[1].inner_vector = pointA - pointB;
00444 
00445     faces[2].point        = pointB; 
00446     faces[2].inner_vector = pointA - pointB;
00447 
00448     faces[3].point        = pointA; 
00449     faces[3].inner_vector = pointB - pointA;
00450 
00451     faces[4].point        = pointA; 
00452     faces[4].inner_vector = pointB - pointA;
00453 
00454     faces[5].point        = pointB; 
00455     faces[5].inner_vector = pointA - pointB;
00456 
00457     for(Int32 i = 0; i < 6; i++)
00458     {
00459         faces[i].inner_normal=planes[i].getNormal();
00460 
00461         if(faces[i].inner_normal.dot(faces[i].inner_vector) < 0.f)
00462             faces[i].inner_normal=-faces[i].inner_normal;
00463 
00464         Vec3f test_enp = enter_point - faces[i].point;
00465         Vec3f test_exp = exit_point  - faces[i].point;
00466 
00467         Real32 value_enp = test_enp.dot(faces[i].inner_normal);
00468         Real32 value_exp = test_exp.dot(faces[i].inner_normal);
00469 
00470         if(value_enp < 0.f && value_exp < 0.f) 
00471             return false;
00472 
00473         if(value_enp > 0.f && value_exp < 0.f) 
00474             planes[i].intersect(*this, exit_point );
00475 
00476         if(value_enp < 0.f && value_exp > 0.f) 
00477             planes[i].intersect(*this, enter_point);
00478     }
00479     
00480     Real32 a;
00481     
00482     if((a = (enter_point - _pos).dot(_dir)) != 0.f)
00483     {
00484         enter = (enter_point - _pos).dot(enter_point - _pos) / a;
00485     }
00486     else 
00487     {
00488         enter = 0.f;
00489     }
00490 
00491     if((a = (exit_point  - _pos).dot(_dir)) != 0.f)
00492     {
00493         exit  = (exit_point  - _pos).dot(exit_point  - _pos) / a;
00494     }
00495     else
00496     {
00497         enter = 0.f;              
00498     }
00499 
00500     return true;
00501 }

bool Line::intersect ( const BoxVolume box,
Real32 enter,
Real32 exit 
) const

Intersect the line with a box, returns points of intersection

Definition at line 507 of file OSGLine.cpp.

References _dir, _pos, osg::Eps, osg::BoxVolume::getBounds(), and osg::Inf.

00510 {
00511     Pnt3f low;
00512     Pnt3f high;
00513     
00514     box.getBounds(low, high);
00515     
00516     Real32 r;
00517     Real32 te;
00518     Real32 tl;
00519     
00520     Real32 in  = 0.f;
00521     Real32 out = Inf;
00522     
00523     if(_dir[0] > Eps)
00524     {
00525         r = 1.f / _dir[0];
00526     
00527         te = (low [0] - _pos[0]) * r;
00528         tl = (high[0] - _pos[0]) * r;
00529     
00530         if(tl < out)   
00531             out = tl;
00532     
00533         if(te > in)    
00534             in  = te;
00535     }
00536     else if(_dir[0] < -Eps)
00537     {
00538         r = 1.f / _dir[0];
00539     
00540         te = (high[0] - _pos[0]) * r;
00541         tl = (low [0] - _pos[0]) * r;
00542     
00543         if(tl < out)   
00544             out = tl;
00545     
00546         if(te > in)    
00547             in  = te;
00548     }
00549     else if(_pos[0] < low[0] || _pos[0] > high[0])
00550     {
00551         return false;
00552     }
00553     
00554     if(_dir[1] > Eps)
00555     {
00556         r = 1.f / _dir[1];
00557     
00558         te = (low [1] - _pos[1]) * r;
00559         tl = (high[1] - _pos[1]) * r;
00560     
00561         if(tl < out)   
00562             out = tl;
00563     
00564         if(te > in)    
00565             in  = te;
00566     
00567         if(in-out >= Eps)
00568             return false;
00569     }
00570     else if(_dir[1] < -Eps)
00571     {
00572         r = 1.f / _dir[1];
00573     
00574         te = (high[1] - _pos[1]) * r;
00575         tl = (low [1] - _pos[1]) * r;
00576     
00577         if(tl < out)   
00578             out = tl;
00579     
00580         if(te > in)    
00581             in  = te;
00582     
00583         if(in-out >= Eps)
00584             return false;
00585     }
00586     else if(_pos[1] < low[1] || _pos[1] > high[1])
00587     {
00588         return false;
00589     }
00590     
00591     if(_dir[2] > Eps)
00592     {
00593         r = 1.f / _dir[2];
00594     
00595         te = (low [2] - _pos[2]) * r;
00596         tl = (high[2] - _pos[2]) * r;
00597     
00598         if(tl < out)   
00599             out = tl;
00600     
00601         if(te > in)    
00602             in  = te;
00603     }
00604     else if(_dir[2] < -Eps)
00605     {
00606         r = 1.f / _dir[2];
00607     
00608         te = (high[2] - _pos[2]) * r;
00609         tl = (low [2] - _pos[2]) * r;
00610     
00611         if(tl < out)   
00612             out = tl;
00613     
00614         if(te > in)    
00615             in  = te;
00616     }
00617     else if(_pos[2] < low[2] || _pos[2] > high[2])
00618     {
00619         return false;
00620     }
00621     
00622     enter = in;
00623     exit  = out;
00624     
00625     // Eps: count flat boxes as intersected
00626 
00627 
00628     // BUGFIXED, was:  
00629 
00630     // return enter-exit < Eps;
00631 
00632     // This got unstable with bbox check of huge planes
00633     // and if compiled as opt lib (at least with my gcc 4.0.2).
00634     // However it worked when compiled as dbg lib. 
00635 
00636     // And now something completely different...
00637 
00638     return in-out < Eps;
00639 
00640     // To get you even more confused: It also works if you leave it
00641     // as "enter-exit" but declare in/out as Real64.
00642 
00643     // Now think about it......and if it is not 42, please tell!
00644 }

bool Line::intersect ( Real32  angle,
const BoxVolume box 
) const

Intersect the line with a box.

Definition at line 653 of file OSGLine.cpp.

00655 {
00656     // TODO
00657     assert(false);
00658     return false;
00659 }

bool Line::intersect ( Real32  angle,
const Vec3f point 
) const

Intersect the line with a point.

Definition at line 664 of file OSGLine.cpp.

00666 {
00667     // TODO
00668     assert(false);
00669     return false;
00670 }

bool Line::intersect ( Real32  angle,
const Vec3f v0,
const Vec3f v1,
Vec3f pt 
) const

Intersect the line with a line.

Definition at line 675 of file OSGLine.cpp.

00679 {
00680     // TODO
00681     assert(false);
00682     return false;
00683 }

bool Line::intersect ( const Pnt3f v0,
const Pnt3f v1,
const Pnt3f v2,
Real32 t,
Vec3f norm = NULL 
) const

Intersect the line with a triangle.

Definition at line 692 of file OSGLine.cpp.

References _dir, _pos, osg::VectorInterface< ValueTypeT, StorageInterfaceT >::cross(), osg::VectorInterface< ValueTypeT, StorageInterfaceT >::dot(), and osg::VectorInterface< ValueTypeT, StorageInterfaceT >::normalize().

00697 {
00698     // Eps (1E-6f) didn't work with very small geometries!
00699     static const Real32 sEps = 1E-10f;
00700 
00701     // find vectors for two edges sharing v0.
00702     Vec3f edge1 = v1 - v0;
00703     Vec3f edge2 = v2 - v0;
00704 
00705     // begin calculating determinant - also used to calculate U parameter.
00706     Vec3f pvec = _dir.cross(edge2);
00707 
00708     // if determinant is near zero, ray lies in plane of triangle.
00709     Real32 det = edge1.dot(pvec);
00710     Vec3f qvec;
00711 
00712     if(det > sEps)
00713     {
00714         // calculate distance from v0 to ray origin.
00715         Vec3f tvec = _pos - v0;
00716 
00717         // calculate U parameter and test bounds.
00718         Real32 u = tvec.dot(pvec);
00719 
00720         if(u < 0.0 || u > det)
00721             return false;
00722 
00723         // prepare to test V parameter.
00724         qvec = tvec.cross(edge1);
00725 
00726         // calculate V parameter and test bounds.
00727         Real32 v = _dir.dot(qvec);
00728 
00729         if(v < 0.0 || u + v > det)
00730             return false;
00731     }
00732     else if(det < -sEps)
00733     {
00734         // calculate distance from v0 to ray origin.
00735         Vec3f tvec = _pos - v0;
00736 
00737         // calculate U parameter and test bounds.
00738         Real32 u = tvec.dot(pvec);
00739 
00740         if(u > 0.0 || u < det)
00741             return false;
00742 
00743         // prepare to test V parameter.
00744         qvec = tvec.cross(edge1);
00745 
00746         // calculate V parameter and test bounds.
00747         Real32 v = _dir.dot(qvec);
00748 
00749         if(v > 0.0 || u + v < det)
00750             return false;
00751     }
00752     else
00753         return false;  // ray is parallel to the plane of the triangle.
00754 
00755     Real32 inv_det = 1.0 / det;
00756 
00757     // calculate t, ray intersects triangle.
00758     t = edge2.dot(qvec) * inv_det;
00759 
00760     if(norm != NULL)
00761     {
00762         *norm = edge1.cross(edge2);
00763         norm->normalize();
00764     }
00765     
00766     return true;
00767 }


Member Data Documentation

Definition at line 143 of file OSGLine.h.

Referenced by getClosestPoint(), getClosestPoints(), getPosition(), intersect(), and setValue().

Definition at line 144 of file OSGLine.h.

Referenced by getClosestPoint(), getClosestPoints(), getDirection(), intersect(), and setValue().


The documentation for this class was generated from the following files:

Generated on Mon Mar 17 11:10:46 2008 for OpenSG by  doxygen 1.5.5