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

intersecttriangle.cpp

Go to the documentation of this file.
00001 /*
00002     toxic - A Global Illumination Renderer
00003     Copyright (C) 2003-2004 Francois Beaune
00004     Contact: http://toxicengine.sourceforge.net/
00005 
00006     This file is part of toxic.
00007 
00008     toxic is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012 
00013     toxic is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016     GNU General Public License for more details.
00017 
00018     You should have received a copy of the GNU General Public License
00019     along with toxic; if not, write to the Free Software
00020     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021 */
00022 
00023 /* Ray-Triangle Intersection Test Routines          */
00024 /* Different optimizations of my and Ben Trumbore's */
00025 /* code from journals of graphics tools (JGT)       */
00026 /* http://www.acm.org/jgt/                          */
00027 /* by Tomas Moller, May 2000                        */
00028 
00029 #include "intersecttriangle.h"  // include first
00030 #include "ray.h"
00031 
00032 #include <cmath>
00033 
00034 using namespace sheep;
00035 using namespace toxic;
00036 
00037 const Real EPSILON = 0.000001;
00038 
00039 // The original jgt code.
00040 bool toxic::intersect_triangle(const Ray &ray,
00041                                const Vector3 &vert0,
00042                                const Vector3 &vert1,
00043                                const Vector3 &vert2,
00044                                Real *t, Real *u, Real *v)
00045 {
00046     // Find vectors for two edges sharing vert0.
00047     const Vector3 edge1 = vert1 - vert0;
00048     const Vector3 edge2 = vert2 - vert0;
00049 
00050     // Begin calculating determinant - also used to calculate U parameter.
00051     const Vector3 pvec = ray.m_direction ^ edge2;
00052 
00053     // If determinant is near zero, ray lies in plane of triangle.
00054     const Real det = edge1 * pvec;
00055 //  if(det > -EPSILON && det < EPSILON)
00056 //      return false;
00057     if(det == 0.0)
00058         return false;
00059 
00060     const Real inv_det = 1.0 / det;
00061 
00062     // Calculate distance from vert0 to ray origin.
00063     const Vector3 tvec = ray.m_origin - vert0;
00064 
00065     // Calculate U parameter and test bounds.
00066     *u = (tvec * pvec) * inv_det;
00067     if(*u < 0.0 || *u > 1.0)
00068         return false;
00069 
00070     // Prepare to test V parameter.
00071     const Vector3 qvec = tvec ^ edge1;
00072 
00073     // Calculate V parameter and test bounds.
00074     *v = (ray.m_direction * qvec) * inv_det;
00075     if(*v < 0.0 || *u + *v > 1.0)
00076         return false;
00077 
00078     // Calculate t, ray intersects triangle.
00079     *t = (edge2 * qvec) * inv_det;
00080 
00081     return true;
00082 }
00083 
00084 // Code rewritten to do tests on the sign of the determinant.
00085 // The division is at the end in the code.
00086 bool toxic::intersect_triangle1(const Ray &ray,
00087                                 const Vector3 &vert0,
00088                                 const Vector3 &vert1,
00089                                 const Vector3 &vert2,
00090                                 Real *t, Real *u, Real *v)
00091 {
00092     // Find vectors for two edges sharing vert0.
00093     const Vector3 edge1 = vert1 - vert0;
00094     const Vector3 edge2 = vert2 - vert0;
00095 
00096     // Begin calculating determinant - also used to calculate U parameter.
00097     const Vector3 pvec = ray.m_direction ^ edge2;
00098 
00099     // If determinant is near zero, ray lies in plane of triangle.
00100     const Real det = edge1 * pvec;
00101 
00102     Vector3 qvec;
00103 
00104     if(det > EPSILON) {
00105         // Calculate distance from vert0 to ray origin.
00106         const Vector3 tvec = ray.m_origin - vert0;
00107 
00108         // Calculate U parameter and test bounds.
00109         *u = tvec * pvec;
00110         if(*u < 0.0 || *u > det)
00111             return false;
00112 
00113         // Prepare to test V parameter.
00114         qvec = tvec ^ edge1;
00115 
00116         // Calculate V parameter and test bounds.
00117         *v = ray.m_direction * qvec;
00118         if(*v < 0.0 || *u + *v > det)
00119             return false;
00120     }
00121     else if(det < -EPSILON) {
00122         // Calculate distance from vert0 to ray origin.
00123         const Vector3 tvec = ray.m_origin - vert0;
00124 
00125         // Calculate U parameter and test bounds.
00126         *u = tvec * pvec;
00127         if(*u > 0.0 || *u < det)
00128             return false;
00129 
00130         // Prepare to test V parameter.
00131         qvec = tvec ^ edge1;
00132 
00133         // Calculate V parameter and test bounds.
00134         *v = ray.m_direction * qvec;
00135         if(*v > 0.0 || *u + *v < det)
00136             return false;
00137     }
00138     else return false;  // ray is parallel to the plane of the triangle
00139 
00140     const Real inv_det = 1.0 / det;
00141 
00142     // Calculate t, ray intersects triangle.
00143     *t = (edge2 * qvec) * inv_det;
00144     (*u) *= inv_det;
00145     (*v) *= inv_det;
00146 
00147     return true;
00148 }
00149 
00150 // Code rewritten to do tests on the sign of the determinant.
00151 // The division is before the test of the sign of the determinant.
00152 bool toxic::intersect_triangle2(const Ray &ray,
00153                                 const Vector3 &vert0,
00154                                 const Vector3 &vert1,
00155                                 const Vector3 &vert2,
00156                                 Real *t, Real *u, Real *v)
00157 {
00158     // Find vectors for two edges sharing vert0.
00159     const Vector3 edge1 = vert1 - vert0;
00160     const Vector3 edge2 = vert2 - vert0;
00161 
00162     // Begin calculating determinant - also used to calculate U parameter.
00163     const Vector3 pvec = ray.m_direction ^ edge2;
00164 
00165     // If determinant is near zero, ray lies in plane of triangle.
00166     const Real det = edge1 * pvec;
00167 
00168     // Calculate distance from vert0 to ray origin.
00169     const Vector3 tvec = ray.m_origin - vert0;
00170 
00171     const Real inv_det = 1.0 / det;
00172 
00173     Vector3 qvec;
00174 
00175     if(det > EPSILON) {
00176         // Calculate U parameter and test bounds.
00177         *u = tvec * pvec;
00178         if(*u < 0.0 || *u > det)
00179             return false;
00180 
00181         // Prepare to test V parameter.
00182         qvec = tvec ^ edge1;
00183 
00184         // Calculate V parameter and test bounds.
00185         *v = ray.m_direction * qvec;
00186         if(*v < 0.0 || *u + *v > det)
00187             return false;
00188     }
00189     else if(det < -EPSILON) {
00190         // Calculate U parameter and test bounds.
00191         *u = tvec * pvec;
00192         if(*u > 0.0 || *u < det)
00193             return false;
00194 
00195         // Prepare to test V parameter.
00196         qvec = tvec ^ edge1;
00197 
00198         // Calculate V parameter and test bounds.
00199         *v = ray.m_direction * qvec;
00200         if(*v > 0.0 || *u + *v < det)
00201             return false;
00202     }
00203     else return false;  // ray is parallel to the plane of the triangle
00204 
00205     // Calculate t, ray intersects triangle.
00206     *t = (edge2 * qvec) * inv_det;
00207     (*u) *= inv_det;
00208     (*v) *= inv_det;
00209 
00210     return true;
00211 }
00212 
00213 // Code rewritten to do tests on the sign of the determinant.
00214 // The division is before the test of the sign of the determinant and
00215 // one cross product has been moved out from the if-else if-else.
00216 bool toxic::intersect_triangle3(const Ray &ray,
00217                                 const Vector3 &vert0,
00218                                 const Vector3 &vert1,
00219                                 const Vector3 &vert2,
00220                                 Real *t, Real *u, Real *v)
00221 {
00222     // Find vectors for two edges sharing vert0.
00223     const Vector3 edge1 = vert1 - vert0;
00224     const Vector3 edge2 = vert2 - vert0;
00225 
00226     // Begin calculating determinant - also used to calculate U parameter.
00227     const Vector3 pvec = ray.m_direction ^ edge2;
00228 
00229     // If determinant is near zero, ray lies in plane of triangle.
00230     const Real det = edge1 * pvec;
00231 
00232     // Calculate distance from vert0 to ray origin.
00233     const Vector3 tvec = ray.m_origin - vert0;
00234 
00235     const Real inv_det = 1.0 / det;
00236 
00237     const Vector3 qvec = tvec ^ edge1;
00238 
00239     if(det > EPSILON) {
00240         // Calculate U parameter and test bounds.
00241         *u = tvec * pvec;
00242         if(*u < 0.0 || *u > det)
00243             return false;
00244 
00245         // Calculate V parameter and test bounds.
00246         *v = ray.m_direction * qvec;
00247         if(*v < 0.0 || *u + *v > det)
00248             return false;
00249     }
00250     else if(det < -EPSILON) {
00251         // Calculate U parameter and test bounds.
00252         *u = tvec * pvec;
00253         if(*u > 0.0 || *u < det)
00254             return false;
00255 
00256         // Calculate V parameter and test bounds.
00257         *v = ray.m_direction * qvec;
00258         if(*v > 0.0 || *u + *v < det)
00259             return false;
00260     }
00261     else return false;  // ray is parallel to the plane of the triangle
00262 
00263     // Calculate t, ray intersects triangle.
00264     *t = (edge2 * qvec) * inv_det;
00265     (*u) *= inv_det;
00266     (*v) *= inv_det;
00267 
00268     return true;
00269 }

Generated on Tue May 11 01:31:50 2004 for toxic by doxygen 1.3.6