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

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
 

Definition at line 102 of file OSGLine.cpp.

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

Referenced by osg::Navigator::calcDeltas(), osg::Camera::calcViewRay(), osg::WalkNavigator::forward(), osg::Plane::intersect(), osg::Transform::intersectEnter(), Line(), and osg::WalkNavigator::right().

00103 {
00104     _pos = p0;
00105     _dir = p1 - p0;
00106 
00107     _dir.normalize();
00108 }

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]
 

Accessors for position

Definition at line 52 of file OSGLine.inl.

References _pos.

Referenced by osg::Navigator::buttonRelease(), osg::Navigator::calcDeltas(), osg::IntersectAction::getHitPoint(), osg::Navigator::getIntersectionPoint(), osg::Plane::intersect(), osg::Transform::intersectEnter(), osg::InverseTransform::intersectEnter(), osg::Billboard::intersectEnter(), osg::Plane::intersectInfinite(), osg::Transform::intersectLeave(), osg::InverseTransform::intersectLeave(), and osg::Billboard::intersectLeave().

00053 {
00054     return _pos;
00055 }

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

Accessors for direction

Definition at line 61 of file OSGLine.inl.

References _dir.

Referenced by osg::Navigator::buttonRelease(), osg::Navigator::calcDeltas(), osg::IntersectAction::getHitPoint(), osg::Navigator::getIntersectionPoint(), osg::Plane::intersect(), osg::Transform::intersectEnter(), osg::InverseTransform::intersectEnter(), osg::Billboard::intersectEnter(), osg::Plane::intersectInfinite(), osg::Transform::intersectLeave(), osg::InverseTransform::intersectLeave(), and osg::Billboard::intersectLeave().

00062 {
00063     return _dir;
00064 }

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 Sphere

Definition at line 409 of file OSGLine.cpp.

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

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     return enter-exit < Eps;
00627 }

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

Intersect the line with a box.

Definition at line 636 of file OSGLine.cpp.

00638 {
00639     // TODO
00640     assert(false);
00641     return false;
00642 }

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

Intersect the line with a point.

Definition at line 647 of file OSGLine.cpp.

00649 {
00650     // TODO
00651     assert(false);
00652     return false;
00653 }

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

Intersect the line with a line.

Definition at line 658 of file OSGLine.cpp.

00662 {
00663     // TODO
00664     assert(false);
00665     return false;
00666 }

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 675 of file OSGLine.cpp.

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

00680 {
00681     // Eps (1E-6f) didn't work with very small geometries!
00682     static const Real32 sEps = 1E-10f;
00683 
00684     // find vectors for two edges sharing v0.
00685     Vec3f edge1 = v1 - v0;
00686     Vec3f edge2 = v2 - v0;
00687 
00688     // begin calculating determinant - also used to calculate U parameter.
00689     Vec3f pvec = _dir.cross(edge2);
00690 
00691     // if determinant is near zero, ray lies in plane of triangle.
00692     Real32 det = edge1.dot(pvec);
00693     Vec3f qvec;
00694 
00695     if(det > sEps)
00696     {
00697         // calculate distance from v0 to ray origin.
00698         Vec3f tvec = _pos - v0;
00699 
00700         // calculate U parameter and test bounds.
00701         Real32 u = tvec.dot(pvec);
00702 
00703         if(u < 0.0 || u > det)
00704             return false;
00705 
00706         // prepare to test V parameter.
00707         qvec = tvec.cross(edge1);
00708 
00709         // calculate V parameter and test bounds.
00710         Real32 v = _dir.dot(qvec);
00711 
00712         if(v < 0.0 || u + v > det)
00713             return false;
00714     }
00715     else if(det < -sEps)
00716     {
00717         // calculate distance from v0 to ray origin.
00718         Vec3f tvec = _pos - v0;
00719 
00720         // calculate U parameter and test bounds.
00721         Real32 u = tvec.dot(pvec);
00722 
00723         if(u > 0.0 || u < det)
00724             return false;
00725 
00726         // prepare to test V parameter.
00727         qvec = tvec.cross(edge1);
00728 
00729         // calculate V parameter and test bounds.
00730         Real32 v = _dir.dot(qvec);
00731 
00732         if(v > 0.0 || u + v < det)
00733             return false;
00734     }
00735     else
00736         return false;  // ray is parallel to the plane of the triangle.
00737 
00738     Real32 inv_det = 1.0 / det;
00739 
00740     // calculate t, ray intersects triangle.
00741     t = edge2.dot(qvec) * inv_det;
00742 
00743     if(norm != NULL)
00744         *norm = pvec;
00745 
00746     return true;
00747 }


Member Data Documentation

Pnt3f osg::Line::_pos [private]
 

Definition at line 143 of file OSGLine.h.

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

Vec3f osg::Line::_dir [private]
 

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 Thu Aug 25 04:12:34 2005 for OpenSG by  doxygen 1.4.3