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 _orxVECTOR_H_
00044 #define _orxVECTOR_H_
00045
00046 #include "orxInclude.h"
00047
00048 #include "debug/orxDebug.h"
00049 #include "memory/orxMemory.h"
00050 #include "math/orxMath.h"
00051
00052
00055 typedef struct __orxVECTOR_t
00056 {
00058 union
00059 {
00060 orxFLOAT fX;
00061 orxFLOAT fRho;
00062 orxFLOAT fR;
00063 orxFLOAT fH;
00064 };
00065
00066 union
00067 {
00068 orxFLOAT fY;
00069 orxFLOAT fTheta;
00070 orxFLOAT fG;
00071 orxFLOAT fS;
00072 };
00073
00074 union
00075 {
00076 orxFLOAT fZ;
00077 orxFLOAT fPhi;
00078 orxFLOAT fB;
00079 orxFLOAT fL;
00080 orxFLOAT fV;
00081 };
00082
00083 } orxVECTOR;
00084
00085
00086
00087
00088
00096 static orxINLINE orxVECTOR * orxVector_Set(orxVECTOR *_pvVec, orxFLOAT _fX, orxFLOAT _fY, orxFLOAT _fZ)
00097 {
00098
00099 orxASSERT(_pvVec != orxNULL);
00100
00101
00102 _pvVec->fX = _fX;
00103 _pvVec->fY = _fY;
00104 _pvVec->fZ = _fZ;
00105
00106
00107 return _pvVec;
00108 }
00109
00115 static orxINLINE orxVECTOR * orxVector_SetAll(orxVECTOR *_pvVec, orxFLOAT _fValue)
00116 {
00117
00118 return(orxVector_Set(_pvVec, _fValue, _fValue, _fValue));
00119 }
00120
00126 static orxINLINE orxVECTOR * orxVector_Copy(orxVECTOR *_pvDst, const orxVECTOR *_pvSrc)
00127 {
00128
00129 orxASSERT(_pvDst != orxNULL);
00130 orxASSERT(_pvSrc != orxNULL);
00131
00132
00133 orxMemory_Copy(_pvDst, _pvSrc, sizeof(orxVECTOR));
00134
00135
00136 return _pvDst;
00137 }
00138
00145 static orxINLINE orxVECTOR * orxVector_Add(orxVECTOR *_pvRes, const orxVECTOR *_pvOp1, const orxVECTOR *_pvOp2)
00146 {
00147
00148 orxASSERT(_pvRes != orxNULL);
00149 orxASSERT(_pvOp1 != orxNULL);
00150 orxASSERT(_pvOp2 != orxNULL);
00151
00152
00153 _pvRes->fX = _pvOp1->fX + _pvOp2->fX;
00154 _pvRes->fY = _pvOp1->fY + _pvOp2->fY;
00155 _pvRes->fZ = _pvOp1->fZ + _pvOp2->fZ;
00156
00157
00158 return _pvRes;
00159 }
00160
00167 static orxINLINE orxVECTOR * orxVector_Sub(orxVECTOR *_pvRes, const orxVECTOR *_pvOp1, const orxVECTOR *_pvOp2)
00168 {
00169
00170 orxASSERT(_pvRes != orxNULL);
00171 orxASSERT(_pvOp1 != orxNULL);
00172 orxASSERT(_pvOp2 != orxNULL);
00173
00174
00175 _pvRes->fX = _pvOp1->fX - _pvOp2->fX;
00176 _pvRes->fY = _pvOp1->fY - _pvOp2->fY;
00177 _pvRes->fZ = _pvOp1->fZ - _pvOp2->fZ;
00178
00179
00180 return _pvRes;
00181 }
00182
00189 static orxINLINE orxVECTOR * orxVector_Mulf(orxVECTOR *_pvRes, const orxVECTOR *_pvOp1, orxFLOAT _fOp2)
00190 {
00191
00192 orxASSERT(_pvRes != orxNULL);
00193 orxASSERT(_pvOp1 != orxNULL);
00194
00195
00196 _pvRes->fX = _pvOp1->fX * _fOp2;
00197 _pvRes->fY = _pvOp1->fY * _fOp2;
00198 _pvRes->fZ = _pvOp1->fZ * _fOp2;
00199
00200
00201 return _pvRes;
00202 }
00203
00210 static orxINLINE orxVECTOR * orxVector_Mul(orxVECTOR *_pvRes, const orxVECTOR *_pvOp1, const orxVECTOR *_pvOp2)
00211 {
00212
00213 orxASSERT(_pvRes != orxNULL);
00214 orxASSERT(_pvOp1 != orxNULL);
00215 orxASSERT(_pvOp2 != orxNULL);
00216
00217
00218 _pvRes->fX = _pvOp1->fX * _pvOp2->fX;
00219 _pvRes->fY = _pvOp1->fY * _pvOp2->fY;
00220 _pvRes->fZ = _pvOp1->fZ * _pvOp2->fZ;
00221
00222
00223 return _pvRes;
00224 }
00225
00232 static orxINLINE orxVECTOR * orxVector_Divf(orxVECTOR *_pvRes, const orxVECTOR *_pvOp1, orxFLOAT _fOp2)
00233 {
00234 register orxFLOAT fRecCoef;
00235
00236
00237 orxASSERT(_pvRes != orxNULL);
00238 orxASSERT(_pvOp1 != orxNULL);
00239 orxASSERT(_fOp2 != orxFLOAT_0);
00240
00241
00242 fRecCoef = orxFLOAT_1 / _fOp2;
00243
00244
00245 _pvRes->fX = _pvOp1->fX * fRecCoef;
00246 _pvRes->fY = _pvOp1->fY * fRecCoef;
00247 _pvRes->fZ = _pvOp1->fZ * fRecCoef;
00248
00249
00250 return _pvRes;
00251 }
00252
00259 static orxINLINE orxVECTOR * orxVector_Div(orxVECTOR *_pvRes, const orxVECTOR *_pvOp1, const orxVECTOR *_pvOp2)
00260 {
00261
00262 orxASSERT(_pvRes != orxNULL);
00263 orxASSERT(_pvOp1 != orxNULL);
00264 orxASSERT(_pvOp2 != orxNULL);
00265 orxASSERT(_pvOp2->fX != orxFLOAT_0);
00266 orxASSERT(_pvOp2->fY != orxFLOAT_0);
00267 orxASSERT(_pvOp2->fZ != orxFLOAT_0);
00268
00269
00270 _pvRes->fX = _pvOp1->fX / _pvOp2->fX;
00271 _pvRes->fY = _pvOp1->fY / _pvOp2->fY;
00272 _pvRes->fZ = _pvOp1->fZ / _pvOp2->fZ;
00273
00274
00275 return _pvRes;
00276 }
00277
00285 static orxINLINE orxVECTOR * orxVector_Lerp(orxVECTOR *_pvRes, const orxVECTOR *_pvOp1, const orxVECTOR *_pvOp2, orxFLOAT _fOp)
00286 {
00287
00288 orxASSERT(_pvRes != orxNULL);
00289 orxASSERT(_pvOp1 != orxNULL);
00290 orxASSERT(_pvOp2 != orxNULL);
00291 orxASSERT(_fOp >= orxFLOAT_0);
00292
00293
00294 _pvRes->fX = orxLERP(_pvOp1->fX, _pvOp2->fX, _fOp);
00295 _pvRes->fY = orxLERP(_pvOp1->fY, _pvOp2->fY, _fOp);
00296 _pvRes->fZ = orxLERP(_pvOp1->fZ, _pvOp2->fZ, _fOp);
00297
00298
00299 return _pvRes;
00300 }
00301
00308 static orxINLINE orxVECTOR * orxVector_Min(orxVECTOR *_pvRes, const orxVECTOR *_pvOp1, const orxVECTOR *_pvOp2)
00309 {
00310
00311 orxASSERT(_pvRes != orxNULL);
00312 orxASSERT(_pvOp1 != orxNULL);
00313 orxASSERT(_pvOp2 != orxNULL);
00314
00315
00316 _pvRes->fX = orxMIN(_pvOp1->fX, _pvOp2->fX);
00317 _pvRes->fY = orxMIN(_pvOp1->fY, _pvOp2->fY);
00318 _pvRes->fZ = orxMIN(_pvOp1->fZ, _pvOp2->fZ);
00319
00320
00321 return _pvRes;
00322 }
00323
00330 static orxINLINE orxVECTOR * orxVector_Max(orxVECTOR *_pvRes, const orxVECTOR *_pvOp1, const orxVECTOR *_pvOp2)
00331 {
00332
00333 orxASSERT(_pvRes != orxNULL);
00334 orxASSERT(_pvOp1 != orxNULL);
00335 orxASSERT(_pvOp2 != orxNULL);
00336
00337
00338 _pvRes->fX = orxMAX(_pvOp1->fX, _pvOp2->fX);
00339 _pvRes->fY = orxMAX(_pvOp1->fY, _pvOp2->fY);
00340 _pvRes->fZ = orxMAX(_pvOp1->fZ, _pvOp2->fZ);
00341
00342
00343 return _pvRes;
00344 }
00345
00353 static orxINLINE orxVECTOR * orxVector_Clamp(orxVECTOR *_pvRes, const orxVECTOR *_pvOp, const orxVECTOR *_pvMin, const orxVECTOR *_pvMax)
00354 {
00355
00356 orxASSERT(_pvRes != orxNULL);
00357 orxASSERT(_pvOp != orxNULL);
00358 orxASSERT(_pvMin != orxNULL);
00359 orxASSERT(_pvMax != orxNULL);
00360
00361
00362 _pvRes->fX = orxCLAMP(_pvOp->fX, _pvMin->fX, _pvMax->fX);
00363 _pvRes->fY = orxCLAMP(_pvOp->fY, _pvMin->fY, _pvMax->fY);
00364 _pvRes->fZ = orxCLAMP(_pvOp->fZ, _pvMin->fZ, _pvMax->fZ);
00365
00366
00367 return _pvRes;
00368 }
00369
00375 static orxINLINE orxVECTOR * orxVector_Neg(orxVECTOR *_pvRes, const orxVECTOR *_pvOp)
00376 {
00377
00378 orxASSERT(_pvRes != orxNULL);
00379 orxASSERT(_pvOp != orxNULL);
00380
00381
00382 _pvRes->fX = -(_pvOp->fX);
00383 _pvRes->fY = -(_pvOp->fY);
00384 _pvRes->fZ = -(_pvOp->fZ);
00385
00386
00387 return _pvRes;
00388 }
00389
00395 static orxINLINE orxVECTOR * orxVector_Rec(orxVECTOR *_pvRes, const orxVECTOR *_pvOp)
00396 {
00397
00398 orxASSERT(_pvRes != orxNULL);
00399 orxASSERT(_pvOp != orxNULL);
00400
00401
00402 _pvRes->fX = orxFLOAT_1 / _pvOp->fX;
00403 _pvRes->fY = orxFLOAT_1 / _pvOp->fY;
00404 _pvRes->fZ = orxFLOAT_1 / _pvOp->fZ;
00405
00406
00407 return _pvRes;
00408 }
00409
00415 static orxINLINE orxVECTOR * orxVector_Floor(orxVECTOR *_pvRes, const orxVECTOR *_pvOp)
00416 {
00417
00418 orxASSERT(_pvRes != orxNULL);
00419 orxASSERT(_pvOp != orxNULL);
00420
00421
00422 _pvRes->fX = orxMath_Floor(_pvOp->fX);
00423 _pvRes->fY = orxMath_Floor(_pvOp->fY);
00424 _pvRes->fZ = orxMath_Floor(_pvOp->fZ);
00425
00426
00427 return _pvRes;
00428 }
00429
00435 static orxINLINE orxVECTOR * orxVector_Round(orxVECTOR *_pvRes, const orxVECTOR *_pvOp)
00436 {
00437
00438 orxASSERT(_pvRes != orxNULL);
00439 orxASSERT(_pvOp != orxNULL);
00440
00441
00442 _pvRes->fX = orxMath_Round(_pvOp->fX);
00443 _pvRes->fY = orxMath_Round(_pvOp->fY);
00444 _pvRes->fZ = orxMath_Round(_pvOp->fZ);
00445
00446
00447 return _pvRes;
00448 }
00449
00454 static orxINLINE orxFLOAT orxVector_GetSquareSize(const orxVECTOR *_pvOp)
00455 {
00456 register orxFLOAT fResult;
00457
00458
00459 orxASSERT(_pvOp != orxNULL);
00460
00461
00462 fResult = (_pvOp->fX * _pvOp->fX) + (_pvOp->fY * _pvOp->fY) + (_pvOp->fZ * _pvOp->fZ);
00463
00464
00465 return fResult;
00466 }
00467
00472 static orxINLINE orxFLOAT orxVector_GetSize(const orxVECTOR *_pvOp)
00473 {
00474 register orxFLOAT fResult;
00475
00476
00477 orxASSERT(_pvOp != orxNULL);
00478
00479
00480 fResult = orxMath_Sqrt((_pvOp->fX * _pvOp->fX) + (_pvOp->fY * _pvOp->fY) + (_pvOp->fZ * _pvOp->fZ));
00481
00482
00483 return fResult;
00484 }
00485
00491 static orxINLINE orxFLOAT orxVector_GetSquareDistance(const orxVECTOR *_pvOp1, const orxVECTOR *_pvOp2)
00492 {
00493 orxVECTOR vTemp;
00494 register orxFLOAT fResult;
00495
00496
00497 orxASSERT(_pvOp1 != orxNULL);
00498 orxASSERT(_pvOp2 != orxNULL);
00499
00500
00501 orxVector_Sub(&vTemp, _pvOp2, _pvOp1);
00502
00503
00504 fResult = orxVector_GetSquareSize(&vTemp);
00505
00506
00507 return fResult;
00508 }
00509
00515 static orxINLINE orxFLOAT orxVector_GetDistance(const orxVECTOR *_pvOp1, const orxVECTOR *_pvOp2)
00516 {
00517 orxVECTOR vTemp;
00518 register orxFLOAT fResult;
00519
00520
00521 orxASSERT(_pvOp1 != orxNULL);
00522 orxASSERT(_pvOp2 != orxNULL);
00523
00524
00525 orxVector_Sub(&vTemp, _pvOp2, _pvOp1);
00526
00527
00528 fResult = orxVector_GetSize(&vTemp);
00529
00530
00531 return fResult;
00532 }
00533
00539 static orxINLINE orxVECTOR * orxVector_Normalize(orxVECTOR *_pvRes, const orxVECTOR *_pvOp)
00540 {
00541 register orxFLOAT fOp;
00542
00543
00544 orxASSERT(_pvRes != orxNULL);
00545 orxASSERT(_pvOp != orxNULL);
00546
00547
00548 fOp = (_pvOp->fX * _pvOp->fX) + (_pvOp->fY * _pvOp->fY) + (_pvOp->fZ * _pvOp->fZ);
00549
00550
00551 if(fOp > orxFLOAT_0)
00552 {
00553
00554 fOp = orxFLOAT_1 / orxMath_Sqrt(fOp);
00555
00556
00557 _pvRes->fX = fOp * _pvOp->fX;
00558 _pvRes->fY = fOp * _pvOp->fY;
00559 _pvRes->fZ = fOp * _pvOp->fZ;
00560 }
00561 else
00562 {
00563
00564 orxMemory_Zero(_pvRes, sizeof(orxVECTOR));
00565 }
00566
00567
00568 return _pvRes;
00569 }
00570
00577 static orxINLINE orxVECTOR * orxVector_2DRotate(orxVECTOR *_pvRes, const orxVECTOR *_pvOp, orxFLOAT _fAngle)
00578 {
00579 register orxFLOAT fSin, fCos;
00580
00581
00582 orxASSERT(_pvRes != orxNULL);
00583 orxASSERT(_pvOp != orxNULL);
00584
00585
00586 fCos = orxMath_Cos(_fAngle);
00587 fSin = orxMath_Sin(_fAngle);
00588
00589
00590 orxVector_Set(_pvRes, (fCos * _pvOp->fX) - (fSin * _pvOp->fY), (fSin * _pvOp->fX) + (fCos * _pvOp->fY), _pvOp->fZ);
00591
00592
00593 return _pvRes;
00594 }
00595
00600 static orxINLINE orxBOOL orxVector_IsNull(const orxVECTOR *_pvOp)
00601 {
00602 orxBOOL bResult;
00603
00604
00605 orxASSERT(_pvOp != orxNULL);
00606
00607
00608 bResult = ((_pvOp->fX == orxFLOAT_0) && (_pvOp->fY == orxFLOAT_0) && (_pvOp->fZ == orxFLOAT_0)) ? orxTRUE : orxFALSE;
00609
00610
00611 return bResult;
00612 }
00613
00619 static orxINLINE orxBOOL orxVector_AreEqual(const orxVECTOR *_pvOp1, const orxVECTOR *_pvOp2)
00620 {
00621 orxBOOL bResult;
00622
00623
00624 orxASSERT(_pvOp1 != orxNULL);
00625 orxASSERT(_pvOp2 != orxNULL);
00626
00627
00628 bResult = ((_pvOp1->fX == _pvOp2->fX) && (_pvOp1->fY == _pvOp2->fY) && (_pvOp1->fZ == _pvOp2->fZ)) ? orxTRUE : orxFALSE;
00629
00630
00631 return bResult;
00632 }
00633
00639 static orxINLINE orxVECTOR * orxVector_FromCartesianToSpherical(orxVECTOR *_pvRes, const orxVECTOR *_pvOp)
00640 {
00641
00642 orxASSERT(_pvRes != orxNULL);
00643 orxASSERT(_pvOp != orxNULL);
00644
00645
00646 if((_pvOp->fX == orxFLOAT_0)
00647 && (_pvOp->fY == orxFLOAT_0)
00648 && (_pvOp->fZ == orxFLOAT_0))
00649 {
00650
00651 _pvRes->fRho = _pvRes->fTheta = _pvRes->fPhi = orxFLOAT_0;
00652 }
00653 else
00654 {
00655 orxFLOAT fRho, fTheta, fPhi;
00656
00657
00658 if(_pvOp->fZ == orxFLOAT_0)
00659 {
00660
00661 if(_pvOp->fX == orxFLOAT_0)
00662 {
00663
00664 fRho = orxMath_Abs(_pvOp->fY);
00665 }
00666
00667 else if(_pvOp->fY == orxFLOAT_0)
00668 {
00669
00670 fRho = orxMath_Abs(_pvOp->fX);
00671 }
00672
00673 else
00674 {
00675
00676 fRho = orxMath_Sqrt((_pvOp->fX * _pvOp->fX) + (_pvOp->fY * _pvOp->fY));
00677 }
00678
00679
00680 fPhi = orxMATH_KF_PI_BY_2;
00681 }
00682 else
00683 {
00684
00685 if((_pvOp->fX == orxFLOAT_0) && (_pvOp->fY == orxFLOAT_0))
00686 {
00687
00688 if(_pvOp->fZ < orxFLOAT_0)
00689 {
00690
00691 fRho = orxMath_Abs(_pvOp->fZ);
00692
00693
00694 fPhi = orxMATH_KF_PI;
00695 }
00696 else
00697 {
00698
00699 fRho = _pvOp->fZ;
00700
00701
00702 fPhi = orxFLOAT_0;
00703 }
00704 }
00705 else
00706 {
00707
00708 fRho = orxMath_Sqrt(orxVector_GetSquareSize(_pvOp));
00709
00710
00711 fPhi = orxMath_ACos(_pvOp->fZ / fRho);
00712 }
00713 }
00714
00715
00716 fTheta = orxMath_ATan(_pvOp->fY, _pvOp->fX);
00717
00718
00719 _pvRes->fRho = fRho;
00720 _pvRes->fTheta = fTheta;
00721 _pvRes->fPhi = fPhi;
00722 }
00723
00724
00725 return _pvRes;
00726 }
00727
00733 static orxINLINE orxVECTOR * orxVector_FromSphericalToCartesian(orxVECTOR *_pvRes, const orxVECTOR *_pvOp)
00734 {
00735 orxFLOAT fSinPhi, fCosPhi, fSinTheta, fCosTheta, fRho;
00736
00737
00738 orxASSERT(_pvRes != orxNULL);
00739 orxASSERT(_pvOp != orxNULL);
00740
00741
00742 fRho = _pvOp->fRho;
00743
00744
00745 fSinTheta = orxMath_Sin(_pvOp->fTheta);
00746 fCosTheta = orxMath_Cos(_pvOp->fTheta);
00747 fSinPhi = orxMath_Sin(_pvOp->fPhi);
00748 fCosPhi = orxMath_Cos(_pvOp->fPhi);
00749 if(orxMath_Abs(fSinTheta) < orxMATH_KF_EPSILON)
00750 {
00751 fSinTheta = orxFLOAT_0;
00752 }
00753 if(orxMath_Abs(fCosTheta) < orxMATH_KF_EPSILON)
00754 {
00755 fCosTheta = orxFLOAT_0;
00756 }
00757 if(orxMath_Abs(fSinPhi) < orxMATH_KF_EPSILON)
00758 {
00759 fSinPhi = orxFLOAT_0;
00760 }
00761 if(orxMath_Abs(fCosPhi) < orxMATH_KF_EPSILON)
00762 {
00763 fCosPhi = orxFLOAT_0;
00764 }
00765
00766
00767 _pvRes->fX = fRho * fCosTheta * fSinPhi;
00768 _pvRes->fY = fRho * fSinTheta * fSinPhi;
00769 _pvRes->fZ = fRho * fCosPhi;
00770
00771
00772 return _pvRes;
00773 }
00774
00780 static orxINLINE orxFLOAT orxVector_Dot(const orxVECTOR *_pvOp1, const orxVECTOR *_pvOp2)
00781 {
00782 orxFLOAT fResult;
00783
00784
00785 orxASSERT(_pvOp1 != orxNULL);
00786 orxASSERT(_pvOp2 != orxNULL);
00787
00788
00789 fResult = (_pvOp1->fX * _pvOp2->fX) + (_pvOp1->fY * _pvOp2->fY) + (_pvOp1->fZ * _pvOp2->fZ);
00790
00791
00792 return fResult;
00793 }
00794
00800 static orxINLINE orxFLOAT orxVector_2DDot(const orxVECTOR *_pvOp1, const orxVECTOR *_pvOp2)
00801 {
00802 orxFLOAT fResult;
00803
00804
00805 orxASSERT(_pvOp1 != orxNULL);
00806 orxASSERT(_pvOp2 != orxNULL);
00807
00808
00809 fResult = (_pvOp1->fX * _pvOp2->fX) + (_pvOp1->fY * _pvOp2->fY);
00810
00811
00812 return fResult;
00813 }
00814
00821 static orxINLINE orxVECTOR * orxVector_Cross(orxVECTOR *_pvRes, const orxVECTOR *_pvOp1, const orxVECTOR *_pvOp2)
00822 {
00823 orxFLOAT fTemp1, fTemp2;
00824
00825
00826 orxASSERT(_pvRes != orxNULL);
00827 orxASSERT(_pvOp1 != orxNULL);
00828 orxASSERT(_pvOp2 != orxNULL);
00829
00830
00831 fTemp1 = (_pvOp1->fY * _pvOp2->fZ) - (_pvOp1->fZ * _pvOp2->fY);
00832 fTemp2 = (_pvOp1->fZ * _pvOp2->fX) - (_pvOp1->fX * _pvOp2->fZ);
00833 _pvRes->fZ = (_pvOp1->fX * _pvOp2->fY) - (_pvOp1->fY * _pvOp2->fX);
00834 _pvRes->fY = fTemp2;
00835 _pvRes->fX = fTemp1;
00836
00837
00838 return _pvRes;
00839 }
00840
00841
00842
00843
00844
00845 extern orxDLLAPI const orxVECTOR orxVECTOR_X;
00846 extern orxDLLAPI const orxVECTOR orxVECTOR_Y;
00847 extern orxDLLAPI const orxVECTOR orxVECTOR_Z;
00849 extern orxDLLAPI const orxVECTOR orxVECTOR_0;
00850 extern orxDLLAPI const orxVECTOR orxVECTOR_1;
00852 extern orxDLLAPI const orxVECTOR orxVECTOR_RED;
00853 extern orxDLLAPI const orxVECTOR orxVECTOR_GREEN;
00854 extern orxDLLAPI const orxVECTOR orxVECTOR_BLUE;
00855 extern orxDLLAPI const orxVECTOR orxVECTOR_BLACK;
00856 extern orxDLLAPI const orxVECTOR orxVECTOR_WHITE;
00858 #endif
00859