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 <math.h>
00027 #include <common/Triangle.h>
00028 #include <common/Defines.h>
00029
00030
00031
00032
00033
00034 Triangle::Triangle()
00035 {
00036
00037 }
00038
00039 Triangle::~Triangle()
00040 {
00041
00042 }
00043
00044 void Triangle::setPointComponents(const float ptA1, const float ptA2, const float ptA3,
00045 Vector &normalA,
00046 const float ptB1, const float ptB2, const float ptB3,
00047 Vector &normalB,
00048 const float ptC1, const float ptC2, const float ptC3,
00049 Vector &normalC)
00050 {
00051 ptA_.initialise(ptA1, ptA2, ptA3);
00052 ptB_.initialise(ptB1, ptB2, ptB3);
00053 ptC_.initialise(ptC1, ptC2, ptC3);
00054
00055 faceN_ += normalA;
00056 faceN_ += normalB;
00057 faceN_ += normalC;
00058 faceN_ /= 3.0f;
00059 calcLargest();
00060 }
00061
00062 void Triangle::calcLargest()
00063 {
00064 largest_ = scalarZ;
00065 float f0 = fabsf(faceN_[0]);
00066 float f1 = fabsf(faceN_[1]);
00067 float f2 = fabsf(faceN_[2]);
00068 if (f0 >= f1)
00069 {
00070 if (f0 >= f2) largest_ = scalarX;
00071 }
00072 else
00073 {
00074 if (f1 >= f2) largest_ = scalarY;
00075 }
00076 }
00077
00078 bool Triangle::pointInBoundingBox(const Vector &pt)
00079 {
00080 float max0 = MAX(ptA_[0], MAX(ptB_[0], ptC_[0]));
00081 float max1 = MAX(ptA_[1], MAX(ptB_[1], ptC_[1]));
00082 float max2 = MAX(ptA_[2], MAX(ptB_[2], ptC_[2]));
00083 float min0 = MIN(ptA_[0], MIN(ptB_[0], ptC_[0]));
00084 float min1 = MIN(ptA_[1], MIN(ptB_[1], ptC_[1]));
00085 float min2 = MIN(ptA_[2], MIN(ptB_[2], ptC_[2]));
00086
00087 Vector &Pt = (Vector &) pt;
00088 if (Pt[0] < min0-0.1f || Pt[0] > max0+0.1f) return false;
00089 if (Pt[1] < min1-0.1f || Pt[1] > max1+0.1f) return false;
00090 if (Pt[2] < min2-0.1f || Pt[2] > max2+0.1f) return false;
00091
00092 return true;
00093 }
00094
00095 bool Triangle::pointInTriangle(const Vector &pt)
00096 {
00097 Vector u, v;
00098 switch (largest_)
00099 {
00100 case scalarX:
00101 u[0] = pt[1] - ptA_[1];
00102 v[0] = pt[2] - ptA_[2];
00103 u[1] = ptB_[1] - ptA_[1];
00104 v[1] = ptB_[2] - ptA_[2];
00105 u[2] = ptC_[1] - ptA_[1];
00106 v[2] = ptC_[2] - ptA_[2];
00107 break;
00108 case scalarY:
00109 u[0] = pt[0] - ptA_[0];
00110 v[0] = pt[2] - ptA_[2];
00111 u[1] = ptB_[0] - ptA_[0];
00112 v[1] = ptB_[2] - ptA_[2];
00113 u[2] = ptC_[0] - ptA_[0];
00114 v[2] = ptC_[2] - ptA_[2];
00115 break;
00116 case scalarZ:
00117 u[0] = pt[0] - ptA_[0];
00118 v[0] = pt[1] - ptA_[1];
00119 u[1] = ptB_[0] - ptA_[0];
00120 v[1] = ptB_[1] - ptA_[1];
00121 u[2] = ptC_[0] - ptA_[0];
00122 v[2] = ptC_[1] - ptA_[1];
00123 break;
00124 default:
00125 return false;
00126 break;
00127 }
00128
00129 float alpha, beta;
00130 if (u[1] == 0.0)
00131 {
00132 if (u[2] != 0.0) beta = u[0] / u[2];
00133 else return false;
00134 if (beta>=0.0 && beta<=1.0)
00135 {
00136 alpha = (v[0] - beta * v[2]) / v[1];
00137 if (alpha<0.0 || alpha>1.0) return false;
00138 }
00139 else return false;
00140 }
00141 else
00142 {
00143 beta=(v[0] * u[1] - u[0] * v[1]) / (v[2] * u[1] - u[2] * v[1]);
00144 if (beta>=0.0 && beta<=1.0)
00145 {
00146 alpha = (u[0] - beta * u[2]) / u[1];
00147 if (alpha<0.0 || alpha>1.0) return false;
00148 }
00149 else return false;
00150 }
00151
00152 if (alpha+beta > 1.0) return false;
00153 return true;
00154 }
00155
00156 bool Triangle::rayIntersect(const Line &ray,
00157 Vector &intersectPt,
00158 Vector &intersectN,
00159 float &intersectDist,
00160 const bool checkPtOnLine)
00161 {
00162
00163 Line &Ray = (Line &) ray;
00164
00165
00166 float sd = faceN_.dotP((Vector &) Ray.getDirection());
00167 if (sd == 0.0f) return false;
00168
00169
00170
00171
00172
00173 intersectPt = ptA_;
00174 intersectPt -= Ray.getStart();
00175 float si = -intersectPt.dotP(faceN_) / sd;
00176
00177 intersectPt = (Vector &) Ray.getDirection();
00178 intersectPt *= - si;
00179 intersectPt += Ray.getStart();
00180 intersectDist = -si;
00181 intersectN = faceN_;
00182
00183
00184 if (checkPtOnLine)
00185 {
00186 if (si > 0.0f || si < -1.0) return false;
00187 }
00188
00189
00190 if (!pointInBoundingBox(intersectPt)) return false;
00191 if (!pointInTriangle(intersectPt)) return false;
00192 return true;
00193 }
00194
00195 bool Triangle::sphereIntersect(
00196 Vector &sphereCentre,
00197 float &sphereRadius,
00198 Vector &intersectPt,
00199 Vector &intersectN,
00200 float &intersectDist)
00201 {
00202 Vector actualPosition = sphereCentre + (faceN_ * sphereRadius);
00203 Vector destPosition = sphereCentre - (faceN_ * sphereRadius);
00204 Line direction(actualPosition, destPosition);
00205
00206 if (rayIntersect(direction, intersectPt, intersectN, intersectDist, true))
00207 {
00208 float diameter = sphereRadius + sphereRadius;
00209
00210 intersectDist = (diameter) - (intersectDist * diameter);
00211 return true;
00212 }
00213 return false;
00214 }