00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef __MATH_VECTOR_H__
00023 #define __MATH_VECTOR_H__
00024
00025 #pragma warning(disable : 4244)
00026
00027 #include <math.h>
00028 #include <assert.h>
00029
00030
00031
00032
00033
00034
00035
00036
00037 #define __VectorMA(v, s, b, o) ((o)[0]=(v)[0]+(b)[0]*(s),(o)[1]=(v)[1]+(b)[1]*(s),(o)[2]=(v)[2]+(b)[2]*(s))
00038
00039
00040 #define DotProduct4(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]+(x)[3]*(y)[3])
00041 #define VectorSubtract4(a,b,c) ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2],(c)[3]=(a)[3]-(b)[3])
00042 #define VectorAdd4(a,b,c) ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2],(c)[3]=(a)[3]+(b)[3])
00043 #define VectorCopy4(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3])
00044 #define VectorScale4(v, s, o) ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s),(o)[3]=(v)[3]*(s))
00045 #define VectorMA4(v, s, b, o) ((o)[0]=(v)[0]+(b)[0]*(s),(o)[1]=(v)[1]+(b)[1]*(s),(o)[2]=(v)[2]+(b)[2]*(s),(o)[3]=(v)[3]+(b)[3]*(s))
00046
00047
00048
00049 #define VectorNegate(a,b) ((b)[0]=-(a)[0],(b)[1]=-(a)[1],(b)[2]=-(a)[2])
00050
00051 #define Vector4Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3])
00052
00053 #define SnapVector(v) {v[0]=(int)v[0];v[1]=(int)v[1];v[2]=(int)v[2];}
00054
00055
00056
00057
00058 #ifndef EQUAL_EPSILON
00059 #define EQUAL_EPSILON 0.001
00060 #endif
00061
00062 float Q_fabs( float f );
00063
00064 #ifndef ID_INLINE
00065 #ifdef _WIN32
00066 #define ID_INLINE __inline
00067 #else
00068 #define ID_INLINE inline
00069 #endif
00070 #endif
00071
00072
00073
00074
00075
00076
00077
00078
00079 class angles_t;
00080 #ifdef __ppc__
00081
00082
00083
00084
00085
00086
00087
00088 static inline float idSqrt(float x) {
00089 const float half = 0.5;
00090 const float one = 1.0;
00091 float B, y0, y1;
00092
00093
00094 if (fabs(x) == 0.0)
00095 return x;
00096 B = x;
00097
00098 #ifdef __GNUC__
00099 asm("frsqrte %0,%1" : "=f" (y0) : "f" (B));
00100 #else
00101 y0 = __frsqrte(B);
00102 #endif
00103
00104
00105 y1 = y0 + half*y0*(one - B*y0*y0);
00106
00107
00108
00109 y0 = y1;
00110 y1 = y0 + half*y0*(one - B*y0*y0);
00111
00112
00113 return x * y1;
00114 }
00115 #else
00116 static inline double idSqrt(double x) {
00117 return sqrt(x);
00118 }
00119 #endif
00120
00121
00122
00123 class idVec3_t {
00124 public:
00125 #ifndef FAT_VEC3
00126 float x,y,z;
00127 #else
00128 float x,y,z,dist;
00129 #endif
00130
00131 #ifndef FAT_VEC3
00132 idVec3_t() {};
00133 #else
00134 idVec3_t() {dist = 0.0f;};
00135 #endif
00136 idVec3_t( const float x, const float y, const float z );
00137
00138 operator float *();
00139
00140 float operator[]( const int index ) const;
00141 float &operator[]( const int index );
00142
00143 void set( const float x, const float y, const float z );
00144
00145 idVec3_t operator-() const;
00146
00147 idVec3_t &operator=( const idVec3_t &a );
00148
00149 float operator*( const idVec3_t &a ) const;
00150 idVec3_t operator*( const float a ) const;
00151 friend idVec3_t operator*( float a, idVec3_t b );
00152
00153 idVec3_t operator+( const idVec3_t &a ) const;
00154 idVec3_t operator-( const idVec3_t &a ) const;
00155
00156 idVec3_t &operator+=( const idVec3_t &a );
00157 idVec3_t &operator-=( const idVec3_t &a );
00158 idVec3_t &operator*=( const float a );
00159
00160 int operator==( const idVec3_t &a ) const;
00161 int operator!=( const idVec3_t &a ) const;
00162
00163 idVec3_t Cross( const idVec3_t &a ) const;
00164 idVec3_t &Cross( const idVec3_t &a, const idVec3_t &b );
00165
00166 float Length( void ) const;
00167 float Normalize( void );
00168
00169 void Zero( void );
00170 void Snap( void );
00171 void SnapTowards( const idVec3_t &to );
00172
00173 float toYaw( void );
00174 float toPitch( void );
00175 angles_t toAngles( void );
00176 friend idVec3_t LerpVector( const idVec3_t &w1, const idVec3_t &w2, const float t );
00177
00178 char *string( void );
00179 };
00180
00181 extern idVec3_t vec_zero;
00182
00183 ID_INLINE idVec3_t::idVec3_t( const float x, const float y, const float z ) {
00184 this->x = x;
00185 this->y = y;
00186 this->z = z;
00187 #ifdef FAT_VEC3
00188 this->dist = 0.0f;
00189 #endif
00190 }
00191
00192 ID_INLINE float idVec3_t::operator[]( const int index ) const {
00193 return ( &x )[ index ];
00194 }
00195
00196 ID_INLINE float &idVec3_t::operator[]( const int index ) {
00197 return ( &x )[ index ];
00198 }
00199
00200 ID_INLINE idVec3_t::operator float *( void ) {
00201 return &x;
00202 }
00203
00204 ID_INLINE idVec3_t idVec3_t::operator-() const {
00205 return idVec3_t( -x, -y, -z );
00206 }
00207
00208 ID_INLINE idVec3_t &idVec3_t::operator=( const idVec3_t &a ) {
00209 x = a.x;
00210 y = a.y;
00211 z = a.z;
00212
00213 return *this;
00214 }
00215
00216 ID_INLINE void idVec3_t::set( const float x, const float y, const float z ) {
00217 this->x = x;
00218 this->y = y;
00219 this->z = z;
00220 }
00221
00222 ID_INLINE idVec3_t idVec3_t::operator-( const idVec3_t &a ) const {
00223 return idVec3_t( x - a.x, y - a.y, z - a.z );
00224 }
00225
00226 ID_INLINE float idVec3_t::operator*( const idVec3_t &a ) const {
00227 return x * a.x + y * a.y + z * a.z;
00228 }
00229
00230 ID_INLINE idVec3_t idVec3_t::operator*( const float a ) const {
00231 return idVec3_t( x * a, y * a, z * a );
00232 }
00233
00234 ID_INLINE idVec3_t operator*( const float a, const idVec3_t b ) {
00235 return idVec3_t( b.x * a, b.y * a, b.z * a );
00236 }
00237
00238 ID_INLINE idVec3_t idVec3_t::operator+( const idVec3_t &a ) const {
00239 return idVec3_t( x + a.x, y + a.y, z + a.z );
00240 }
00241
00242 ID_INLINE idVec3_t &idVec3_t::operator+=( const idVec3_t &a ) {
00243 x += a.x;
00244 y += a.y;
00245 z += a.z;
00246
00247 return *this;
00248 }
00249
00250 ID_INLINE idVec3_t &idVec3_t::operator-=( const idVec3_t &a ) {
00251 x -= a.x;
00252 y -= a.y;
00253 z -= a.z;
00254
00255 return *this;
00256 }
00257
00258 ID_INLINE idVec3_t &idVec3_t::operator*=( const float a ) {
00259 x *= a;
00260 y *= a;
00261 z *= a;
00262
00263 return *this;
00264 }
00265
00266 ID_INLINE int idVec3_t::operator==( const idVec3_t &a ) const {
00267 if ( Q_fabs( x - a.x ) > EQUAL_EPSILON ) {
00268 return false;
00269 }
00270
00271 if ( Q_fabs( y - a.y ) > EQUAL_EPSILON ) {
00272 return false;
00273 }
00274
00275 if ( Q_fabs( z - a.z ) > EQUAL_EPSILON ) {
00276 return false;
00277 }
00278
00279 return true;
00280 }
00281
00282 ID_INLINE int idVec3_t::operator!=( const idVec3_t &a ) const {
00283 if ( Q_fabs( x - a.x ) > EQUAL_EPSILON ) {
00284 return true;
00285 }
00286
00287 if ( Q_fabs( y - a.y ) > EQUAL_EPSILON ) {
00288 return true;
00289 }
00290
00291 if ( Q_fabs( z - a.z ) > EQUAL_EPSILON ) {
00292 return true;
00293 }
00294
00295 return false;
00296 }
00297
00298 ID_INLINE idVec3_t idVec3_t::Cross( const idVec3_t &a ) const {
00299 return idVec3_t( y * a.z - z * a.y, z * a.x - x * a.z, x * a.y - y * a.x );
00300 }
00301
00302 ID_INLINE idVec3_t &idVec3_t::Cross( const idVec3_t &a, const idVec3_t &b ) {
00303 x = a.y * b.z - a.z * b.y;
00304 y = a.z * b.x - a.x * b.z;
00305 z = a.x * b.y - a.y * b.x;
00306
00307 return *this;
00308 }
00309
00310 ID_INLINE float idVec3_t::Length( void ) const {
00311 float length;
00312
00313 length = x * x + y * y + z * z;
00314 return ( float )idSqrt( length );
00315 }
00316
00317 ID_INLINE float idVec3_t::Normalize( void ) {
00318 float length;
00319 float ilength;
00320
00321 length = this->Length();
00322 if ( length ) {
00323 ilength = 1.0f / length;
00324 x *= ilength;
00325 y *= ilength;
00326 z *= ilength;
00327 }
00328
00329 return length;
00330 }
00331
00332 ID_INLINE void idVec3_t::Zero( void ) {
00333 x = 0.0f;
00334 y = 0.0f;
00335 z = 0.0f;
00336 }
00337
00338 ID_INLINE void idVec3_t::Snap( void ) {
00339 x = float( int( x ) );
00340 y = float( int( y ) );
00341 z = float( int( z ) );
00342 }
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 ID_INLINE void idVec3_t::SnapTowards( const idVec3_t &to ) {
00355 if ( to.x <= x ) {
00356 x = float( int( x ) );
00357 } else {
00358 x = float( int( x ) + 1 );
00359 }
00360
00361 if ( to.y <= y ) {
00362 y = float( int( y ) );
00363 } else {
00364 y = float( int( y ) + 1 );
00365 }
00366
00367 if ( to.z <= z ) {
00368 z = float( int( z ) );
00369 } else {
00370 z = float( int( z ) + 1 );
00371 }
00372 }
00373
00374
00375
00376 class Bounds {
00377 public:
00378 idVec3_t b[2];
00379
00380 Bounds();
00381 Bounds( const idVec3_t &mins, const idVec3_t &maxs );
00382
00383 void Clear();
00384 void Zero();
00385 float Radius();
00386 idVec3_t Center();
00387 void AddPoint( const idVec3_t &v );
00388 void AddBounds( const Bounds &bb );
00389 bool IsCleared();
00390 bool ContainsPoint( const idVec3_t &p );
00391 bool IntersectsBounds( const Bounds &b2 );
00392 };
00393
00394 extern Bounds boundsZero;
00395
00396 ID_INLINE Bounds::Bounds(){
00397 }
00398
00399 ID_INLINE bool Bounds::IsCleared() {
00400 return b[0][0] > b[1][0];
00401 }
00402
00403 ID_INLINE bool Bounds::ContainsPoint( const idVec3_t &p ) {
00404 if ( p[0] < b[0][0] || p[1] < b[0][1] || p[2] < b[0][2]
00405 || p[0] > b[1][0] || p[1] > b[1][1] || p[2] > b[1][2] ) {
00406 return false;
00407 }
00408 return true;
00409 }
00410
00411 ID_INLINE bool Bounds::IntersectsBounds( const Bounds &b2 ) {
00412 if ( b2.b[1][0] < b[0][0] || b2.b[1][1] < b[0][1] || b2.b[1][2] < b[0][2]
00413 || b2.b[0][0] > b[1][0] || b2.b[0][1] > b[1][1] || b2.b[0][2] > b[1][2] ) {
00414 return false;
00415 }
00416 return true;
00417 }
00418
00419 ID_INLINE Bounds::Bounds( const idVec3_t &mins, const idVec3_t &maxs ) {
00420 b[0] = mins;
00421 b[1] = maxs;
00422 }
00423
00424 ID_INLINE idVec3_t Bounds::Center() {
00425 return idVec3_t( ( b[1][0] + b[0][0] ) * 0.5f, ( b[1][1] + b[0][1] ) * 0.5f, ( b[1][2] + b[0][2] ) * 0.5f );
00426 }
00427
00428 ID_INLINE void Bounds::Clear() {
00429 b[0][0] = b[0][1] = b[0][2] = 99999;
00430 b[1][0] = b[1][1] = b[1][2] = -99999;
00431 }
00432
00433 ID_INLINE void Bounds::Zero() {
00434 b[0][0] = b[0][1] = b[0][2] =
00435 b[1][0] = b[1][1] = b[1][2] = 0;
00436 }
00437
00438 ID_INLINE void Bounds::AddPoint( const idVec3_t &v ) {
00439 if ( v[0] < b[0][0]) {
00440 b[0][0] = v[0];
00441 }
00442 if ( v[0] > b[1][0]) {
00443 b[1][0] = v[0];
00444 }
00445 if ( v[1] < b[0][1] ) {
00446 b[0][1] = v[1];
00447 }
00448 if ( v[1] > b[1][1]) {
00449 b[1][1] = v[1];
00450 }
00451 if ( v[2] < b[0][2] ) {
00452 b[0][2] = v[2];
00453 }
00454 if ( v[2] > b[1][2]) {
00455 b[1][2] = v[2];
00456 }
00457 }
00458
00459
00460 ID_INLINE void Bounds::AddBounds( const Bounds &bb ) {
00461 if ( bb.b[0][0] < b[0][0]) {
00462 b[0][0] = bb.b[0][0];
00463 }
00464 if ( bb.b[0][1] < b[0][1]) {
00465 b[0][1] = bb.b[0][1];
00466 }
00467 if ( bb.b[0][2] < b[0][2]) {
00468 b[0][2] = bb.b[0][2];
00469 }
00470
00471 if ( bb.b[1][0] > b[1][0]) {
00472 b[1][0] = bb.b[1][0];
00473 }
00474 if ( bb.b[1][1] > b[1][1]) {
00475 b[1][1] = bb.b[1][1];
00476 }
00477 if ( bb.b[1][2] > b[1][2]) {
00478 b[1][2] = bb.b[1][2];
00479 }
00480 }
00481
00482 ID_INLINE float Bounds::Radius( ) {
00483 int i;
00484 float total;
00485 float a, aa;
00486
00487 total = 0;
00488 for (i=0 ; i<3 ; i++) {
00489 a = (float)fabs( b[0][i] );
00490 aa = (float)fabs( b[1][i] );
00491 if ( aa > a ) {
00492 a = aa;
00493 }
00494 total += a * a;
00495 }
00496
00497 return (float)idSqrt( total );
00498 }
00499
00500
00501
00502
00503 class idVec2_t {
00504 public:
00505 float x;
00506 float y;
00507
00508 operator float *();
00509 float operator[]( int index ) const;
00510 float &operator[]( int index );
00511 };
00512
00513 ID_INLINE float idVec2_t::operator[]( int index ) const {
00514 return ( &x )[ index ];
00515 }
00516
00517 ID_INLINE float& idVec2_t::operator[]( int index ) {
00518 return ( &x )[ index ];
00519 }
00520
00521 ID_INLINE idVec2_t::operator float *( void ) {
00522 return &x;
00523 }
00524
00525 class vec4_t : public idVec3_t {
00526 public:
00527 #ifndef FAT_VEC3
00528 float dist;
00529 #endif
00530 vec4_t();
00531 ~vec4_t() {};
00532
00533 vec4_t( float x, float y, float z, float dist );
00534 float operator[]( int index ) const;
00535 float &operator[]( int index );
00536 };
00537
00538 ID_INLINE vec4_t::vec4_t() {}
00539 ID_INLINE vec4_t::vec4_t( float x, float y, float z, float dist ) {
00540 this->x = x;
00541 this->y = y;
00542 this->z = z;
00543 this->dist = dist;
00544 }
00545
00546 ID_INLINE float vec4_t::operator[]( int index ) const {
00547 return ( &x )[ index ];
00548 }
00549
00550 ID_INLINE float& vec4_t::operator[]( int index ) {
00551 return ( &x )[ index ];
00552 }
00553
00554
00555 class idVec5_t : public idVec3_t {
00556 public:
00557 float s;
00558 float t;
00559 float operator[]( int index ) const;
00560 float &operator[]( int index );
00561 };
00562
00563
00564 ID_INLINE float idVec5_t::operator[]( int index ) const {
00565 return ( &x )[ index ];
00566 }
00567
00568 ID_INLINE float& idVec5_t::operator[]( int index ) {
00569 return ( &x )[ index ];
00570 }
00571
00572 #endif