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 #include <limits>
00027
00028
00029
00030
00031 #include <Intersection.hpp>
00032
00033
00034
00035
00036 #define TRIANGLE_EPSILON 0.000001
00037 #define OBB_EPSILON 1e-20
00038
00039
00040
00041
00042 namespace kn{
00043
00044
00045
00046
00047
00048 std::pair<kn::Vector2d,double> intersectTriangle(const kn::Vector3d & pointA, const kn::Vector3d & pointB, const kn::Vector3d & pointC,
00049 const kn::Vector3d & rayDirection ,const kn::Vector3d & rayOrigin) {
00050 kn::Vector3d edge1;
00051 kn::Vector3d edge2;
00052 kn::Vector3d tvec;
00053 kn::Vector3d pvec;
00054 kn::Vector3d qvec;
00055
00056 double det, inv_det;
00057 double u, t, v;
00058
00059
00060 edge1 = pointB - pointA;
00061 edge2 = pointC - pointA;
00062
00063
00064 pvec = rayDirection ^ edge2;
00065
00066
00067 det = edge1*pvec;
00068
00069 if (det > -TRIANGLE_EPSILON && det < TRIANGLE_EPSILON)
00070 return std::pair<kn::Vector2d, double>(kn::Vector2d(),-1.0);
00071 inv_det = 1.0 / det;
00072
00073
00074 tvec = rayOrigin - pointA;
00075
00076
00077 u = (tvec * pvec) * inv_det;
00078 if (u < 0.0 || u > 1.0)
00079 return std::pair<kn::Vector2d, double>(kn::Vector2d(),-1.0);
00080
00081
00082 qvec = tvec^edge1;
00083
00084
00085 v = (rayDirection*qvec) * inv_det;
00086 if (v < 0.0 || u + v > 1.0)
00087 return std::pair<kn::Vector2d, double>(kn::Vector2d(),-1.0);
00088
00089
00090 t = (edge2*qvec) * inv_det;
00091
00092 return std::pair<kn::Vector2d, double>(kn::Vector2d(u,v),t);
00093 }
00094
00095 std::pair<kn::Vector3d,double> intersectOBB(const kn::Vector3d & center, const kn::Vector3d a[3], const kn::Vector3d & h,
00096 const kn::Vector3d & rayDirection ,const kn::Vector3d & rayOrigin) {
00097 double tmin = std::numeric_limits<double>::min();
00098 double tmax = std::numeric_limits<double>::max();
00099 kn::Vector3d p = center - rayOrigin;
00100
00101
00102 for (int i=0; i < 3; i++) {
00103 double e = a[i]*p;
00104 double f = a[i]*rayDirection;
00105
00106 if (fabs(f) > OBB_EPSILON) {
00107 double f1 = 1.0/f;
00108 double t1 = (e+h[i])*f1;
00109 double t2 = (e-h[i])*f1;
00110 if (t1>t2) std::swap(t1,t2);
00111 if (t1>tmin) tmin = t1;
00112 if (t2 < tmax) tmax= t2;
00113 if (tmin > tmax) return std::pair<kn::Vector3d, double>(kn::Vector3d(0.0),-1.0);
00114 if (tmax < 0) return std::pair<kn::Vector3d, double>(kn::Vector3d(0.0),-1.0);
00115 }
00116 else if (-e - h[i]>0.0 || -e+h[i] <0.0) { return std::pair<kn::Vector3d, double>(kn::Vector3d(0.0),-1.0); }
00117 }
00118
00119 if (tmin>0) return std::pair<kn::Vector3d, double>(rayOrigin+tmin*rayDirection,tmin);
00120 else return std::pair<kn::Vector3d, double>(rayOrigin+tmax*rayDirection,tmax);
00121 }
00122
00123 std::pair<kn::Vector3d, double> intersectSphere(const kn::Vector3d & spherePosition, double sphereRadius,
00124 const kn::Vector3d & rayDirection ,const kn::Vector3d & rayOrigin) {
00125 kn::Vector3d intersectionPosition;
00126 double t = -1.0;
00127 kn::Vector3d l = spherePosition - rayOrigin;
00128 double s = l*rayDirection;
00129 double l2 = l*l;
00130 double r2 = sphereRadius*sphereRadius;
00131
00132 if (s<0 && l2 > r2)
00133 return std::pair<kn::Vector3d, double>(intersectionPosition,-1.0);
00134
00135 double m2 = l2 - s*s;
00136 if (m2 > r2)
00137 return std::pair<kn::Vector3d, double>(intersectionPosition,-1.0);
00138
00139 double q = sqrt(r2-m2);
00140
00141 if (l2>r2)
00142 t=s-q;
00143 else
00144 t=s+q;
00145
00146 return std::pair<kn::Vector3d, double>(rayOrigin+t*rayDirection,t);
00147 }
00148
00149
00150
00151
00152
00153
00154 }