00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00043 #ifndef _orxOBOX_H_
00044 #define _orxOBOX_H_
00045
00046 #include "orxInclude.h"
00047
00048 #include "math/orxVector.h"
00049
00050
00053 typedef struct __orxOBOX_t
00054 {
00055 orxVECTOR vPosition;
00056 orxVECTOR vPivot;
00057 orxVECTOR vX;
00058 orxVECTOR vY;
00059 orxVECTOR vZ;
00061 } orxOBOX;
00062
00063
00064
00065
00066
00075 static orxINLINE orxOBOX * orxOBox_2DSet(orxOBOX *_pstRes, const orxVECTOR *_pvWorldPosition, const orxVECTOR *_pvPivot, const orxVECTOR *_pvSize, orxFLOAT _fAngle)
00076 {
00077 orxFLOAT fCos, fSin;
00078
00079
00080 orxASSERT(_pstRes != orxNULL);
00081 orxASSERT(_pvWorldPosition != orxNULL);
00082 orxASSERT(_pvPivot != orxNULL);
00083
00084
00085 if(_fAngle == orxFLOAT_0)
00086 {
00087 fCos = orxFLOAT_1;
00088 fSin = orxFLOAT_0;
00089 }
00090 else
00091 {
00092 fCos = orxMath_Cos(_fAngle);
00093 fSin = orxMath_Sin(_fAngle);
00094 }
00095
00096
00097 orxVector_Set(&(_pstRes->vX), fCos * _pvSize->fX, fSin * _pvSize->fX, orxFLOAT_0);
00098 orxVector_Set(&(_pstRes->vY), -fSin * _pvSize->fY, fCos * _pvSize->fY, orxFLOAT_0);
00099 orxVector_Set(&(_pstRes->vZ), orxFLOAT_0, orxFLOAT_0, _pvSize->fZ);
00100
00101
00102 orxVector_Set(&(_pstRes->vPivot), (fCos * _pvPivot->fX) - (fSin * _pvPivot->fY), (fSin * _pvPivot->fX) + (fCos * _pvPivot->fY), _pvPivot->fZ);
00103
00104
00105 orxVector_Copy(&(_pstRes->vPosition), _pvWorldPosition);
00106
00107
00108 return _pstRes;
00109 }
00110
00116 static orxINLINE orxOBOX * orxOBox_Copy(orxOBOX *_pstDst, const orxOBOX *_pstSrc)
00117 {
00118
00119 orxASSERT(_pstDst != orxNULL);
00120 orxASSERT(_pstSrc != orxNULL);
00121
00122
00123 orxMemory_Copy(_pstDst, _pstSrc, sizeof(orxOBOX));
00124
00125
00126 return _pstDst;
00127 }
00128
00134 static orxINLINE orxVECTOR * orxOBox_GetCenter(const orxOBOX *_pstOp, orxVECTOR *_pvRes)
00135 {
00136
00137 orxASSERT(_pstOp != orxNULL);
00138 orxASSERT(_pvRes != orxNULL);
00139
00140
00141 orxVector_Add(_pvRes, orxVector_Add(_pvRes, &(_pstOp->vX), &(_pstOp->vY)), &(_pstOp->vZ));
00142 orxVector_Mulf(_pvRes, _pvRes, orx2F(0.5f));
00143 orxVector_Sub(_pvRes, orxVector_Add(_pvRes, _pvRes, &(_pstOp->vPosition)), &(_pstOp->vPivot));
00144
00145
00146 return _pvRes;
00147 }
00148
00155 static orxINLINE orxOBOX * orxOBox_Move(orxOBOX *_pstRes, const orxOBOX *_pstOp, const orxVECTOR *_pvMove)
00156 {
00157
00158 orxASSERT(_pstRes != orxNULL);
00159 orxASSERT(_pstOp != orxNULL);
00160 orxASSERT(_pvMove != orxNULL);
00161
00162
00163 orxVector_Add(&(_pstRes->vPosition), &(_pstOp->vPosition), _pvMove);
00164
00165
00166 return _pstRes;
00167 }
00168
00175 static orxINLINE orxOBOX * orxOBox_2DRotate(orxOBOX *_pstRes, const orxOBOX *_pstOp, orxFLOAT _fAngle)
00176 {
00177 register orxFLOAT fSin, fCos;
00178
00179
00180 orxASSERT(_pstRes != orxNULL);
00181 orxASSERT(_pstOp != orxNULL);
00182
00183
00184 if(_fAngle == orxFLOAT_0)
00185 {
00186 fCos = orxFLOAT_1;
00187 fSin = orxFLOAT_0;
00188 }
00189 else
00190 {
00191 fCos = orxMath_Cos(_fAngle);
00192 fSin = orxMath_Sin(_fAngle);
00193 }
00194
00195
00196 orxVector_Set(&(_pstRes->vX), (fCos * _pstRes->vX.fX) - (fSin * _pstRes->vX.fY), (fSin * _pstRes->vX.fX) + (fCos * _pstRes->vX.fY), _pstRes->vX.fZ);
00197 orxVector_Set(&(_pstRes->vY), (fCos * _pstRes->vY.fX) - (fSin * _pstRes->vY.fY), (fSin * _pstRes->vY.fX) + (fCos * _pstRes->vY.fY), _pstRes->vY.fZ);
00198
00199
00200 orxVector_Set(&(_pstRes->vPivot), (fCos * _pstRes->vPivot.fX) - (fSin * _pstRes->vPivot.fY), (fSin * _pstRes->vPivot.fX) + (fCos * _pstRes->vPivot.fY), _pstRes->vPivot.fZ);
00201
00202
00203 return _pstRes;
00204 }
00205
00211 static orxINLINE orxBOOL orxOBox_IsInside(const orxOBOX *_pstBox, const orxVECTOR *_pvPosition)
00212 {
00213 register orxBOOL bResult = orxFALSE;
00214 orxFLOAT fProj;
00215 orxVECTOR vToPos;
00216
00217
00218 orxASSERT(_pstBox != orxNULL);
00219 orxASSERT(_pvPosition != orxNULL);
00220
00221
00222 orxVector_Sub(&vToPos, _pvPosition, orxVector_Sub(&vToPos, &(_pstBox->vPosition), &(_pstBox->vPivot)));
00223
00224
00225 if(((fProj = orxVector_Dot(&vToPos, &(_pstBox->vZ))) >= orxFLOAT_0)
00226 && (fProj <= orxVector_GetSquareSize(&(_pstBox->vZ))))
00227 {
00228
00229 if(((fProj = orxVector_Dot(&vToPos, &(_pstBox->vX))) >= orxFLOAT_0)
00230 && (fProj <= orxVector_GetSquareSize(&(_pstBox->vX))))
00231 {
00232
00233 if(((fProj = orxVector_Dot(&vToPos, &(_pstBox->vY))) >= orxFLOAT_0)
00234 && (fProj <= orxVector_GetSquareSize(&(_pstBox->vY))))
00235 {
00236
00237 bResult = orxTRUE;
00238 }
00239 }
00240 }
00241
00242
00243 return bResult;
00244 }
00245
00251 static orxINLINE orxBOOL orxOBox_2DIsInside(const orxOBOX *_pstBox, const orxVECTOR *_pvPosition)
00252 {
00253 register orxBOOL bResult = orxFALSE;
00254 orxFLOAT fProj;
00255 orxVECTOR vToPos;
00256
00257
00258 orxASSERT(_pstBox != orxNULL);
00259 orxASSERT(_pvPosition != orxNULL);
00260
00261
00262 orxVector_Sub(&vToPos, _pvPosition, orxVector_Sub(&vToPos, &(_pstBox->vPosition), &(_pstBox->vPivot)));
00263
00264
00265 if(((fProj = orxVector_Dot(&vToPos, &(_pstBox->vX))) >= orxFLOAT_0)
00266 && (fProj <= orxVector_GetSquareSize(&(_pstBox->vX))))
00267 {
00268
00269 if(((fProj = orxVector_Dot(&vToPos, &(_pstBox->vY))) >= orxFLOAT_0)
00270 && (fProj <= orxVector_GetSquareSize(&(_pstBox->vY))))
00271 {
00272
00273 bResult = orxTRUE;
00274 }
00275 }
00276
00277
00278 return bResult;
00279 }
00280
00286 static orxINLINE orxBOOL orxOBox_ZAlignedTestIntersection(const orxOBOX *_pstBox1, const orxOBOX *_pstBox2)
00287 {
00288 register orxBOOL bResult;
00289
00290
00291 orxASSERT(_pstBox1 != orxNULL);
00292 orxASSERT(_pstBox2 != orxNULL);
00293 orxASSERT((_pstBox1->vZ.fX == orxFLOAT_0) && (_pstBox1->vZ.fX == orxFLOAT_0));
00294 orxASSERT((_pstBox1->vZ.fY == orxFLOAT_0) && (_pstBox1->vZ.fY == orxFLOAT_0));
00295 orxASSERT((_pstBox1->vZ.fZ >= orxFLOAT_0) && (_pstBox1->vZ.fZ >= orxFLOAT_0));
00296
00297
00298 if((_pstBox2->vPosition.fZ + _pstBox2->vZ.fZ >= _pstBox1->vPosition.fZ)
00299 && (_pstBox2->vPosition.fZ <= _pstBox1->vPosition.fZ + _pstBox1->vZ.fZ))
00300 {
00301 orxU32 i;
00302 orxVECTOR vOrigin1, vOrigin2, *pvOrigin1 = &vOrigin1, *pvOrigin2 = &vOrigin2, *pvTemp;
00303 const orxOBOX *pstBox1 = _pstBox1, *pstBox2 = _pstBox2, *pstTemp;
00304
00305
00306 vOrigin1.fX = _pstBox1->vPosition.fX - pstBox1->vPivot.fX;
00307 vOrigin1.fY = _pstBox1->vPosition.fY - pstBox1->vPivot.fY;
00308 vOrigin2.fX = _pstBox2->vPosition.fX - pstBox2->vPivot.fX;
00309 vOrigin2.fY = _pstBox2->vPosition.fY - pstBox2->vPivot.fY;
00310
00311
00312 for(i = 2, bResult = orxTRUE;
00313 i != 0;
00314 i--, pstTemp = pstBox1, pstBox1 = pstBox2, pstBox2 = pstTemp, pvTemp = pvOrigin1, pvOrigin1 = pvOrigin2, pvOrigin2 = pvTemp)
00315 {
00316 orxVECTOR vToCorner[4];
00317 const orxVECTOR *pvAxis;
00318 orxU32 j;
00319
00320
00321 vToCorner[0].fX = pvOrigin2->fX - pvOrigin1->fX;
00322 vToCorner[0].fY = pvOrigin2->fY - pvOrigin1->fY;
00323 vToCorner[1].fX = vToCorner[0].fX + pstBox2->vX.fX;
00324 vToCorner[1].fY = vToCorner[0].fY + pstBox2->vX.fY;
00325 vToCorner[2].fX = vToCorner[1].fX + pstBox2->vY.fX;
00326 vToCorner[2].fY = vToCorner[1].fY + pstBox2->vY.fY;
00327 vToCorner[3].fX = vToCorner[0].fX + pstBox2->vY.fX;
00328 vToCorner[3].fY = vToCorner[0].fY + pstBox2->vY.fY;
00329
00330
00331 for(j = 2, pvAxis = &(pstBox1->vX);
00332 j != 0;
00333 j--, pvAxis++)
00334 {
00335 orxFLOAT fMin, fMax, fProj;
00336 orxU32 k;
00337
00338
00339 fMin = fMax = fProj = orxVector_2DDot(&vToCorner[0], pvAxis);
00340
00341
00342 for(k = 1; k < 4; k++)
00343 {
00344
00345 fProj = orxVector_2DDot(&vToCorner[k], pvAxis);
00346
00347
00348 if(fProj > fMax)
00349 {
00350 fMax = fProj;
00351 }
00352 else if(fProj < fMin)
00353 {
00354 fMin = fProj;
00355 }
00356 }
00357
00358
00359 if((fMax < orxFLOAT_0)
00360 || (fMin > orxVector_GetSquareSize(pvAxis)))
00361 {
00362
00363 bResult = orxFALSE;
00364 break;
00365 }
00366 }
00367 }
00368 }
00369 else
00370 {
00371
00372 bResult = orxFALSE;
00373 }
00374
00375
00376 return bResult;
00377 }
00378
00379 #endif
00380