00001
00002
00008
00009
00011
00017
00018
00020
00021 #include "Stdafx.h"
00022
00023 using namespace IceMaths;
00024
00026
00031
00032 bool OBB::ContainsPoint(const Point& p) const
00033 {
00034
00035
00036
00037 Point RelPoint = p - mCenter;
00038
00039
00040
00041
00042 float f = mRot.m[0][0] * RelPoint.x + mRot.m[0][1] * RelPoint.y + mRot.m[0][2] * RelPoint.z;
00043 if(f >= mExtents.x || f <= -mExtents.x) return false;
00044
00045 f = mRot.m[1][0] * RelPoint.x + mRot.m[1][1] * RelPoint.y + mRot.m[1][2] * RelPoint.z;
00046 if(f >= mExtents.y || f <= -mExtents.y) return false;
00047
00048 f = mRot.m[2][0] * RelPoint.x + mRot.m[2][1] * RelPoint.y + mRot.m[2][2] * RelPoint.z;
00049 if(f >= mExtents.z || f <= -mExtents.z) return false;
00050 return true;
00051 }
00052
00054
00059
00060 void OBB::Create(const AABB& aabb, const Matrix4x4& mat)
00061 {
00062
00063
00064 aabb.GetCenter(mCenter);
00065 aabb.GetExtents(mExtents);
00066
00067
00068
00069
00070 mCenter *= mat;
00071
00072 mRot = mat;
00073 }
00074
00076
00081
00082 bool OBB::ComputePlanes(Plane* planes) const
00083 {
00084
00085 if(!planes) return false;
00086
00087 Point Axis0 = mRot[0];
00088 Point Axis1 = mRot[1];
00089 Point Axis2 = mRot[2];
00090
00091
00092 planes[0].n = Axis0;
00093 planes[1].n = -Axis0;
00094 planes[2].n = Axis1;
00095 planes[3].n = -Axis1;
00096 planes[4].n = Axis2;
00097 planes[5].n = -Axis2;
00098
00099
00100 Point p0 = mCenter + Axis0 * mExtents.x;
00101 Point p1 = mCenter - Axis0 * mExtents.x;
00102 Point p2 = mCenter + Axis1 * mExtents.y;
00103 Point p3 = mCenter - Axis1 * mExtents.y;
00104 Point p4 = mCenter + Axis2 * mExtents.z;
00105 Point p5 = mCenter - Axis2 * mExtents.z;
00106
00107
00108 planes[0].d = -(planes[0].n|p0);
00109 planes[1].d = -(planes[1].n|p1);
00110 planes[2].d = -(planes[2].n|p2);
00111 planes[3].d = -(planes[3].n|p3);
00112 planes[4].d = -(planes[4].n|p4);
00113 planes[5].d = -(planes[5].n|p5);
00114
00115 return true;
00116 }
00117
00119
00124
00125 bool OBB::ComputePoints(Point* pts) const
00126 {
00127
00128 if(!pts) return false;
00129
00130 Point Axis0 = mRot[0];
00131 Point Axis1 = mRot[1];
00132 Point Axis2 = mRot[2];
00133
00134 Axis0 *= mExtents.x;
00135 Axis1 *= mExtents.y;
00136 Axis2 *= mExtents.z;
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 pts[0] = mCenter - Axis0 - Axis1 - Axis2;
00148 pts[1] = mCenter + Axis0 - Axis1 - Axis2;
00149 pts[2] = mCenter + Axis0 + Axis1 - Axis2;
00150 pts[3] = mCenter - Axis0 + Axis1 - Axis2;
00151 pts[4] = mCenter - Axis0 - Axis1 + Axis2;
00152 pts[5] = mCenter + Axis0 - Axis1 + Axis2;
00153 pts[6] = mCenter + Axis0 + Axis1 + Axis2;
00154 pts[7] = mCenter - Axis0 + Axis1 + Axis2;
00155
00156 return true;
00157 }
00158
00160
00165
00166 bool OBB::ComputeVertexNormals(Point* pts) const
00167 {
00168 static float VertexNormals[] =
00169 {
00170 -INVSQRT3, -INVSQRT3, -INVSQRT3,
00171 INVSQRT3, -INVSQRT3, -INVSQRT3,
00172 INVSQRT3, INVSQRT3, -INVSQRT3,
00173 -INVSQRT3, INVSQRT3, -INVSQRT3,
00174 -INVSQRT3, -INVSQRT3, INVSQRT3,
00175 INVSQRT3, -INVSQRT3, INVSQRT3,
00176 INVSQRT3, INVSQRT3, INVSQRT3,
00177 -INVSQRT3, INVSQRT3, INVSQRT3
00178 };
00179
00180 if(!pts) return false;
00181
00182 const Point* VN = (const Point*)VertexNormals;
00183 for(udword i=0;i<8;i++)
00184 {
00185 pts[i] = VN[i] * mRot;
00186 }
00187
00188 return true;
00189 }
00190
00192
00196
00197 const udword* OBB::GetEdges() const
00198 {
00199 static udword Indices[] = {
00200 0, 1, 1, 2, 2, 3, 3, 0,
00201 7, 6, 6, 5, 5, 4, 4, 7,
00202 1, 5, 6, 2,
00203 3, 7, 4, 0
00204 };
00205 return Indices;
00206 }
00207
00209
00213
00214 const Point* OBB::GetLocalEdgeNormals() const
00215 {
00216 static float EdgeNormals[] =
00217 {
00218 0, -INVSQRT2, -INVSQRT2,
00219 INVSQRT2, 0, -INVSQRT2,
00220 0, INVSQRT2, -INVSQRT2,
00221 -INVSQRT2, 0, -INVSQRT2,
00222
00223 0, INVSQRT2, INVSQRT2,
00224 INVSQRT2, 0, INVSQRT2,
00225 0, -INVSQRT2, INVSQRT2,
00226 -INVSQRT2, 0, INVSQRT2,
00227
00228 INVSQRT2, -INVSQRT2, 0,
00229 INVSQRT2, INVSQRT2, 0,
00230 -INVSQRT2, INVSQRT2, 0,
00231 -INVSQRT2, -INVSQRT2, 0
00232 };
00233 return (const Point*)EdgeNormals;
00234 }
00235
00237
00242
00243 void OBB::ComputeWorldEdgeNormal(udword edge_index, Point& world_normal) const
00244 {
00245 ASSERT(edge_index<12);
00246 world_normal = GetLocalEdgeNormals()[edge_index] * mRot;
00247 }
00248
00250
00254
00255 void OBB::ComputeLSS(LSS& lss) const
00256 {
00257 Point Axis0 = mRot[0];
00258 Point Axis1 = mRot[1];
00259 Point Axis2 = mRot[2];
00260
00261 switch(mExtents.LargestAxis())
00262 {
00263 case 0:
00264 lss.mRadius = (mExtents.y + mExtents.z)*0.5f;
00265 lss.mP0 = mCenter + Axis0 * (mExtents.x - lss.mRadius);
00266 lss.mP1 = mCenter - Axis0 * (mExtents.x - lss.mRadius);
00267 break;
00268 case 1:
00269 lss.mRadius = (mExtents.x + mExtents.z)*0.5f;
00270 lss.mP0 = mCenter + Axis1 * (mExtents.y - lss.mRadius);
00271 lss.mP1 = mCenter - Axis1 * (mExtents.y - lss.mRadius);
00272 break;
00273 case 2:
00274 lss.mRadius = (mExtents.x + mExtents.y)*0.5f;
00275 lss.mP0 = mCenter + Axis2 * (mExtents.z - lss.mRadius);
00276 lss.mP1 = mCenter - Axis2 * (mExtents.z - lss.mRadius);
00277 break;
00278 }
00279 }
00280
00282
00287
00288 BOOL OBB::IsInside(const OBB& box) const
00289 {
00290
00291 Matrix4x4 M0Inv;
00292 {
00293 Matrix4x4 M0 = box.mRot;
00294 M0.SetTrans(box.mCenter);
00295 InvertPRMatrix(M0Inv, M0);
00296 }
00297
00298
00299 OBB _1in0;
00300 Rotate(M0Inv, _1in0);
00301
00302
00303
00304
00305
00306
00307
00308 const Matrix3x3& mtx = _1in0.mRot;
00309
00310 float f = fabsf(mtx.m[0][0] * mExtents.x) + fabsf(mtx.m[1][0] * mExtents.y) + fabsf(mtx.m[2][0] * mExtents.z) - box.mExtents.x;
00311 if(f > _1in0.mCenter.x) return FALSE;
00312 if(-f < _1in0.mCenter.x) return FALSE;
00313
00314 f = fabsf(mtx.m[0][1] * mExtents.x) + fabsf(mtx.m[1][1] * mExtents.y) + fabsf(mtx.m[2][1] * mExtents.z) - box.mExtents.y;
00315 if(f > _1in0.mCenter.y) return FALSE;
00316 if(-f < _1in0.mCenter.y) return FALSE;
00317
00318 f = fabsf(mtx.m[0][2] * mExtents.x) + fabsf(mtx.m[1][2] * mExtents.y) + fabsf(mtx.m[2][2] * mExtents.z) - box.mExtents.z;
00319 if(f > _1in0.mCenter.z) return FALSE;
00320 if(-f < _1in0.mCenter.z) return FALSE;
00321
00322 return TRUE;
00323 }