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

/ray/src/lib/numerics/3d/triangle.cc

Go to the documentation of this file.
00001 #include <lib/numerics/3d/vector3.h>
00002 
00003 
00004 namespace NUM  // numerics
00005 {
00006 
00008 
00045 template<typename T,typename V>int IntersectTriangle(
00046     const Vector3<T> &orig,const Vector3<T> &dir,
00047     const Vector3<V> &vert0,const Vector3<V> &vert1,const Vector3<V> &vert2,
00048     T *t,T *u,T *v)
00049 {
00051 static const V EPSILON=0.000001;
00052 
00053     /* find vectors for two edges sharing vert0 */
00054     Vector3<V> edge1=vert1-vert0;
00055     Vector3<V> edge2=vert2-vert0;
00056     
00057     /* begin calculating determinant - also used to calculate U parameter */
00058     Vector3<V> pvec=cross(dir,edge2);
00059     
00060     /* if determinant is near zero, ray lies in plane of triangle */
00061     V det = dot(edge1,pvec);
00062     
00063 #ifdef TEST_CULL           /* define TEST_CULL if culling is desired */
00064     if(det < EPSILON)  return(0);
00065     
00066     /* calculate distance from vert0 to ray origin */
00067     Vector3<T> tvec=orig-vert0;
00068     
00069     /* calculate U parameter and test bounds */
00070     *u = dot<T>(tvec,pvec);
00071     if(*u < 0 || *u > det)  return(0);
00072     
00073     /* prepare to test V parameter */
00074     Vector3<V> qvec=cross(tvec,edge1);
00075     
00076     /* calculate V parameter and test bounds */
00077     *v = dot<T>(dir,qvec);
00078     if(*v < 0 || *u + *v > det)  return(0);
00079     
00080     /* calculate t, scale parameters, ray intersects triangle */
00081     *t = dot<T>(edge2,qvec);
00082     T inv_det = T(1)/det;
00083     *t *= inv_det;
00084     *u *= inv_det;
00085     *v *= inv_det;
00086 #else                    /* the non-culling branch */
00087     if(fabs(det) < EPSILON)  return(0);
00088     
00089     T inv_det = T(1)/det;
00090     
00091     /* calculate distance from vert0 to ray origin */
00092     Vector3<T> tvec=orig-vert0;
00093     
00094     /* calculate U parameter and test bounds */
00095     *u = dot<T>(tvec,pvec) * inv_det;
00096     if(*u < 0 || *u > 1)  return(0);
00097     
00098     /* prepare to test V parameter */
00099     Vector3<V> qvec=cross(tvec,edge1);
00100     
00101     /* calculate V parameter and test bounds */
00102     *v = DOT<T>(dir,qvec) * inv_det;
00103     if(*v < 0 || *u + *v > 1)  return(0);
00104     
00105     /* calculate t, ray intersects triangle */
00106     *t = dot<T>(edge2,qvec) * inv_det;
00107 #endif
00108     
00109     return(1);
00110 }
00111 
00112 
00113 #if 0
00114 
00125 template<typename T,typename V>int IntersectTriangle(
00126     const Vector3<T> &orig,const Vector3<T> &dir,
00127     const Vector3<V> &vert0,const Vector3<V> &vert1,const Vector3<V> &vert2,
00128     const Plane3d<V> &planeq,int i1,int i2,
00129     T *t,T *u,T *v)
00130 {
00132 static const T EPSILON=0.000001;
00133 
00134     /* is ray parallel to plane? */
00135     T dotval = dot<T>(planeq.normal(),dir);
00136     if(fabs(dotval) < EPSILON)      /* or use culling check */
00137         return(0);
00138     
00139     /* find distance to plane and intersection point */
00140     // T dot2 = dot<T>(planeq.normal(),orig);
00141     // *t = -( planeq.dist() + dot2 ) / dotval;
00142     *t = - distance(orig) / dotval;
00143     
00144     T point[2];
00145     point[0] = orig[i1] + dir[i1] * *t;
00146     point[1] = orig[i2] + dir[i2] * *t;
00147     
00148     /* begin barycentric intersection algorithm */
00149     T u0 = point[0] - vert0[i1];
00150     T v0 = point[1] - vert0[i2];
00151     V u1 = vert1[i1] - vert0[i1];
00152     V u2 = vert2[i1] - vert0[i1];
00153     V v1 = vert1[i2] - vert0[i2];
00154     V v2 = vert2[i2] - vert0[i2];
00155 
00156     /* calculate and compare barycentric coordinates */
00157     if(u1 == 0)
00158     {           /* uncommon case */
00159         *v = u0 / u2;
00160         if(*v < 0 || *v > 1)  return(0);
00161         *u = (v0 - *v * v2) / v1;
00162     }
00163     else
00164     {           /* common case, used for this analysis */
00165         *v = (v0 * u1 - u0 * v1) / (v2 * u1 - u2 * v1);
00166         if(*v < 0 || *v > 1)  return(0);
00167         *u = (u0 - *v * u2) / u1;
00168     }
00169     
00170     if (*u < 0 || *u + *v > 1)  return(0);
00171     
00172     return(1);
00173 }
00174 #endif
00175 
00176 }  // end of namespace NUM

Generated on Sat Feb 19 22:33:45 2005 for Ray by doxygen 1.3.5