00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "intersecttriangle.h"
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
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
00047 const Vector3 edge1 = vert1 - vert0;
00048 const Vector3 edge2 = vert2 - vert0;
00049
00050
00051 const Vector3 pvec = ray.m_direction ^ edge2;
00052
00053
00054 const Real det = edge1 * pvec;
00055
00056
00057 if(det == 0.0)
00058 return false;
00059
00060 const Real inv_det = 1.0 / det;
00061
00062
00063 const Vector3 tvec = ray.m_origin - vert0;
00064
00065
00066 *u = (tvec * pvec) * inv_det;
00067 if(*u < 0.0 || *u > 1.0)
00068 return false;
00069
00070
00071 const Vector3 qvec = tvec ^ edge1;
00072
00073
00074 *v = (ray.m_direction * qvec) * inv_det;
00075 if(*v < 0.0 || *u + *v > 1.0)
00076 return false;
00077
00078
00079 *t = (edge2 * qvec) * inv_det;
00080
00081 return true;
00082 }
00083
00084
00085
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
00093 const Vector3 edge1 = vert1 - vert0;
00094 const Vector3 edge2 = vert2 - vert0;
00095
00096
00097 const Vector3 pvec = ray.m_direction ^ edge2;
00098
00099
00100 const Real det = edge1 * pvec;
00101
00102 Vector3 qvec;
00103
00104 if(det > EPSILON) {
00105
00106 const Vector3 tvec = ray.m_origin - vert0;
00107
00108
00109 *u = tvec * pvec;
00110 if(*u < 0.0 || *u > det)
00111 return false;
00112
00113
00114 qvec = tvec ^ edge1;
00115
00116
00117 *v = ray.m_direction * qvec;
00118 if(*v < 0.0 || *u + *v > det)
00119 return false;
00120 }
00121 else if(det < -EPSILON) {
00122
00123 const Vector3 tvec = ray.m_origin - vert0;
00124
00125
00126 *u = tvec * pvec;
00127 if(*u > 0.0 || *u < det)
00128 return false;
00129
00130
00131 qvec = tvec ^ edge1;
00132
00133
00134 *v = ray.m_direction * qvec;
00135 if(*v > 0.0 || *u + *v < det)
00136 return false;
00137 }
00138 else return false;
00139
00140 const Real inv_det = 1.0 / det;
00141
00142
00143 *t = (edge2 * qvec) * inv_det;
00144 (*u) *= inv_det;
00145 (*v) *= inv_det;
00146
00147 return true;
00148 }
00149
00150
00151
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
00159 const Vector3 edge1 = vert1 - vert0;
00160 const Vector3 edge2 = vert2 - vert0;
00161
00162
00163 const Vector3 pvec = ray.m_direction ^ edge2;
00164
00165
00166 const Real det = edge1 * pvec;
00167
00168
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
00177 *u = tvec * pvec;
00178 if(*u < 0.0 || *u > det)
00179 return false;
00180
00181
00182 qvec = tvec ^ edge1;
00183
00184
00185 *v = ray.m_direction * qvec;
00186 if(*v < 0.0 || *u + *v > det)
00187 return false;
00188 }
00189 else if(det < -EPSILON) {
00190
00191 *u = tvec * pvec;
00192 if(*u > 0.0 || *u < det)
00193 return false;
00194
00195
00196 qvec = tvec ^ edge1;
00197
00198
00199 *v = ray.m_direction * qvec;
00200 if(*v > 0.0 || *u + *v < det)
00201 return false;
00202 }
00203 else return false;
00204
00205
00206 *t = (edge2 * qvec) * inv_det;
00207 (*u) *= inv_det;
00208 (*v) *= inv_det;
00209
00210 return true;
00211 }
00212
00213
00214
00215
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
00223 const Vector3 edge1 = vert1 - vert0;
00224 const Vector3 edge2 = vert2 - vert0;
00225
00226
00227 const Vector3 pvec = ray.m_direction ^ edge2;
00228
00229
00230 const Real det = edge1 * pvec;
00231
00232
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
00241 *u = tvec * pvec;
00242 if(*u < 0.0 || *u > det)
00243 return false;
00244
00245
00246 *v = ray.m_direction * qvec;
00247 if(*v < 0.0 || *u + *v > det)
00248 return false;
00249 }
00250 else if(det < -EPSILON) {
00251
00252 *u = tvec * pvec;
00253 if(*u > 0.0 || *u < det)
00254 return false;
00255
00256
00257 *v = ray.m_direction * qvec;
00258 if(*v > 0.0 || *u + *v < det)
00259 return false;
00260 }
00261 else return false;
00262
00263
00264 *t = (edge2 * qvec) * inv_det;
00265 (*u) *= inv_det;
00266 (*v) *= inv_det;
00267
00268 return true;
00269 }