gKitGL
|
00001 00002 #ifndef _RT_TRIANGLE_H 00003 #define _RT_TRIANGLE_H 00004 00005 #include "Triangle.h" 00006 #include "Geometry.h" 00007 00008 namespace gk { 00009 00010 //! representation d'un triangle pour l'intersecteur rayon / triangle. 00011 struct RTTriangle 00012 { 00013 Point pa; 00014 Vector ab; 00015 Vector ac; 00016 unsigned int id; 00017 00018 //! constructeur par defaut. 00019 RTTriangle( ) {} 00020 00021 //! construit un triangle connaissant ses 3 sommets. 00022 RTTriangle( const Point& _a, const Point& _b, const Point& _c ) 00023 : 00024 pa(_a), ab(_a, _b), ac(_a, _c) 00025 {} 00026 00027 //! construit un triangle a partir d'un triangle 'geometrique'. 00028 RTTriangle( const Triangle& triangle ) 00029 : 00030 pa(triangle.a), ab(triangle.a, triangle.b), ac(triangle.a, triangle.c) 00031 {} 00032 00033 //! destructeur. 00034 ~RTTriangle( ) {} 00035 00036 gk::Point a( ) const 00037 { 00038 return pa; 00039 } 00040 00041 gk::Point b( ) const 00042 { 00043 return pa + ab; 00044 } 00045 00046 gk::Point c( ) const 00047 { 00048 return pa + ac; 00049 } 00050 00051 float getArea( ) const 00052 { 00053 return .5f * Cross(ab, ac).Length(); 00054 } 00055 00056 BBox getBBox( ) const 00057 { 00058 BBox bbox(pa, pa+ab); 00059 bbox.Union(pa + ac); 00060 return bbox; 00061 } 00062 00063 float getBBoxCenter( const int axis ) const 00064 { 00065 float pMin ; 00066 float pMax; 00067 pMin= std::min(pa[axis], pa[axis] + ab[axis]); 00068 pMin= std::min(pMin, pa[axis] + ac[axis]); 00069 pMax= std::max(pa[axis], pa[axis] + ab[axis]); 00070 pMax= std::max(pMax, pa[axis] + ac[axis]); 00071 return .5f * (pMin + pMax); 00072 } 00073 00074 Point getCenter( ) const 00075 { 00076 return pa + (ab + ac) / 3.f; 00077 } 00078 00079 float getCenter( const int axis ) const 00080 { 00081 return pa[axis] + (ab[axis] + ac[axis]) / 3.f; 00082 } 00083 00084 //! calcule la normale geometrique du triangle. 00085 void getTriangleNormal( Normal &n ) const 00086 { 00087 n= Normal( Normalize(Cross(ab, ac)) ) ; 00088 } 00089 00090 Normal getTriangleNormal( ) const 00091 { 00092 return Normal( Normalize( Cross(ab, ac) )); 00093 } 00094 00095 //! intersection avec un rayon. 00096 //! renvoie faux s'il n'y a pas d'intersection, une intersection peut exister mais peut ne pas se trouver dans [tmin tmax] du rayon. 00097 //! renvoie vrai + les coordonnees barycentriques du point d'intersection + sa position le long du rayon. 00098 //! convention barycentrique : t(u, v)= (1 - u - v) * a + u * b + v * c 00099 /*! "Fast, Minimum Storage Ray/Triangle Intersection" 00100 cf http://www.acm.org/jgt/papers/MollerTrumbore97/ 00101 */ 00102 bool Intersect( const Ray &ray, const float htmax, 00103 float &rt, float &ru, float&rv ) const 00104 { 00105 /* begin calculating determinant - also used to calculate U parameter */ 00106 const Vector pvec= Cross(ray.d, ac); 00107 00108 /* if determinant is near zero, ray lies in plane of triangle */ 00109 const float det= Dot(ab, pvec); 00110 if (det > -EPSILON && det < EPSILON) 00111 return false; 00112 00113 const float inv_det= 1.0f / det; 00114 00115 /* calculate distance from vert0 to ray origin */ 00116 const Vector tvec(pa, ray.o); 00117 00118 /* calculate U parameter and test bounds */ 00119 const float u= Dot(tvec, pvec) * inv_det; 00120 if(u < 0.0f || u > 1.0f) 00121 return false; 00122 00123 /* prepare to test V parameter */ 00124 const Vector qvec= Cross(tvec, ab); 00125 00126 /* calculate V parameter and test bounds */ 00127 const float v= Dot(ray.d, qvec) * inv_det; 00128 if(v < 0.0f || u + v > 1.0f) 00129 return false; 00130 00131 /* calculate t, ray intersects triangle */ 00132 rt= Dot(ac, qvec) * inv_det; 00133 ru= u; 00134 rv= v; 00135 00136 // ne renvoie vrai que si l'intersection est valide (comprise entre tmin et tmax du rayon) 00137 //~ return (rt < htmax && rt > ray.tmin); 00138 return (rt < htmax && rt > RAY_EPSILON); 00139 } 00140 00141 bool Intersect( const BasicRay &ray, const float htmax, 00142 float &rt, float &ru, float&rv ) const 00143 { 00144 /* begin calculating determinant - also used to calculate U parameter */ 00145 const Vector pvec= Cross(ray.d, ac); 00146 00147 /* if determinant is near zero, ray lies in plane of triangle */ 00148 const float det= Dot(ab, pvec); 00149 if (det > -EPSILON && det < EPSILON) 00150 return false; 00151 00152 const float inv_det= 1.0f / det; 00153 00154 /* calculate distance from vert0 to ray origin */ 00155 const Vector tvec(pa, ray.o); 00156 00157 /* calculate U parameter and test bounds */ 00158 const float u= Dot(tvec, pvec) * inv_det; 00159 if(u < 0.0f || u > 1.0f) 00160 return false; 00161 00162 /* prepare to test V parameter */ 00163 const Vector qvec= Cross(tvec, ab); 00164 00165 /* calculate V parameter and test bounds */ 00166 const float v= Dot(ray.d, qvec) * inv_det; 00167 if(v < 0.0f || u + v > 1.0f) 00168 return false; 00169 00170 /* calculate t, ray intersects triangle */ 00171 rt= Dot(ac, qvec) * inv_det; 00172 ru= u; 00173 rv= v; 00174 00175 // ne renvoie vrai que si l'intersection est valide (comprise entre tmin et tmax du rayon) 00176 //~ return (rt < htmax && rt > ray.tmin); 00177 return (rt < htmax && rt > RAY_EPSILON); 00178 } 00179 }; 00180 00181 } 00182 00183 #endif