DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

Vector.h (35156B)


      1 /*
      2 ===========================================================================
      3 
      4 Doom 3 BFG Edition GPL Source Code
      5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 
      6 
      7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").  
      8 
      9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
     10 it under the terms of the GNU General Public License as published by
     11 the Free Software Foundation, either version 3 of the License, or
     12 (at your option) any later version.
     13 
     14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
     15 but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 GNU General Public License for more details.
     18 
     19 You should have received a copy of the GNU General Public License
     20 along with Doom 3 BFG Edition Source Code.  If not, see <http://www.gnu.org/licenses/>.
     21 
     22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code.  If not, please request a copy in writing from id Software at the address below.
     23 
     24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
     25 
     26 ===========================================================================
     27 */
     28 
     29 #ifndef __MATH_VECTOR_H__
     30 #define __MATH_VECTOR_H__
     31 
     32 /*
     33 ===============================================================================
     34 
     35   Vector classes
     36 
     37 ===============================================================================
     38 */
     39 
     40 #include "../containers/Array.h" // for idTupleSize
     41 
     42 #define VECTOR_EPSILON		0.001f
     43 
     44 class idAngles;
     45 class idPolar3;
     46 class idMat3;
     47 
     48 //===============================================================
     49 //
     50 //	idVec2 - 2D vector
     51 //
     52 //===============================================================
     53 
     54 class idVec2 {
     55 public:
     56 	float			x;
     57 	float			y;
     58 
     59 					idVec2();
     60 					explicit idVec2( const float x, const float y );
     61 
     62 	void 			Set( const float x, const float y );
     63 	void			Zero();
     64 
     65 	float			operator[]( int index ) const;
     66 	float &			operator[]( int index );
     67 	idVec2			operator-() const;
     68 	float			operator*( const idVec2 &a ) const;
     69 	idVec2			operator*( const float a ) const;
     70 	idVec2			operator/( const float a ) const;
     71 	idVec2			operator+( const idVec2 &a ) const;
     72 	idVec2			operator-( const idVec2 &a ) const;
     73 	idVec2 &		operator+=( const idVec2 &a );
     74 	idVec2 &		operator-=( const idVec2 &a );
     75 	idVec2 &		operator/=( const idVec2 &a );
     76 	idVec2 &		operator/=( const float a );
     77 	idVec2 &		operator*=( const float a );
     78 
     79 	friend idVec2	operator*( const float a, const idVec2 b );
     80 
     81 	idVec2			Scale( const idVec2 &a ) const;
     82 
     83 	bool			Compare( const idVec2 &a ) const;							// exact compare, no epsilon
     84 	bool			Compare( const idVec2 &a, const float epsilon ) const;		// compare with epsilon
     85 	bool			operator==(	const idVec2 &a ) const;						// exact compare, no epsilon
     86 	bool			operator!=(	const idVec2 &a ) const;						// exact compare, no epsilon
     87 
     88 	float			Length() const;
     89 	float			LengthFast() const;
     90 	float			LengthSqr() const;
     91 	float			Normalize();			// returns length
     92 	float			NormalizeFast();		// returns length
     93 	idVec2			Truncate( float length ) const;	// cap length
     94 	void			Clamp( const idVec2 &min, const idVec2 &max );
     95 	void			Snap();				// snap to closest integer value
     96 	void			SnapInt();			// snap towards integer (floor)
     97 
     98 	int				GetDimension() const;
     99 
    100 	const float *	ToFloatPtr() const;
    101 	float *			ToFloatPtr();
    102 	const char *	ToString( int precision = 2 ) const;
    103 
    104 	void			Lerp( const idVec2 &v1, const idVec2 &v2, const float l );
    105 };
    106 
    107 extern idVec2 vec2_origin;
    108 #define vec2_zero vec2_origin
    109 
    110 ID_INLINE idVec2::idVec2() {
    111 }
    112 
    113 ID_INLINE idVec2::idVec2( const float x, const float y ) {
    114 	this->x = x;
    115 	this->y = y;
    116 }
    117 
    118 ID_INLINE void idVec2::Set( const float x, const float y ) {
    119 	this->x = x;
    120 	this->y = y;
    121 }
    122 
    123 ID_INLINE void idVec2::Zero() {
    124 	x = y = 0.0f;
    125 }
    126 
    127 ID_INLINE bool idVec2::Compare( const idVec2 &a ) const {
    128 	return ( ( x == a.x ) && ( y == a.y ) );
    129 }
    130 
    131 ID_INLINE bool idVec2::Compare( const idVec2 &a, const float epsilon ) const {
    132 	if ( idMath::Fabs( x - a.x ) > epsilon ) {
    133 		return false;
    134 	}
    135 			
    136 	if ( idMath::Fabs( y - a.y ) > epsilon ) {
    137 		return false;
    138 	}
    139 
    140 	return true;
    141 }
    142 
    143 ID_INLINE bool idVec2::operator==( const idVec2 &a ) const {
    144 	return Compare( a );
    145 }
    146 
    147 ID_INLINE bool idVec2::operator!=( const idVec2 &a ) const {
    148 	return !Compare( a );
    149 }
    150 
    151 ID_INLINE float idVec2::operator[]( int index ) const {
    152 	return ( &x )[ index ];
    153 }
    154 
    155 ID_INLINE float& idVec2::operator[]( int index ) {
    156 	return ( &x )[ index ];
    157 }
    158 
    159 ID_INLINE float idVec2::Length() const {
    160 	return ( float )idMath::Sqrt( x * x + y * y );
    161 }
    162 
    163 ID_INLINE float idVec2::LengthFast() const {
    164 	float sqrLength;
    165 
    166 	sqrLength = x * x + y * y;
    167 	return sqrLength * idMath::InvSqrt( sqrLength );
    168 }
    169 
    170 ID_INLINE float idVec2::LengthSqr() const {
    171 	return ( x * x + y * y );
    172 }
    173 
    174 ID_INLINE float idVec2::Normalize() {
    175 	float sqrLength, invLength;
    176 
    177 	sqrLength = x * x + y * y;
    178 	invLength = idMath::InvSqrt( sqrLength );
    179 	x *= invLength;
    180 	y *= invLength;
    181 	return invLength * sqrLength;
    182 }
    183 
    184 ID_INLINE float idVec2::NormalizeFast() {
    185 	float lengthSqr, invLength;
    186 
    187 	lengthSqr = x * x + y * y;
    188 	invLength = idMath::InvSqrt( lengthSqr );
    189 	x *= invLength;
    190 	y *= invLength;
    191 	return invLength * lengthSqr;
    192 }
    193 
    194 ID_INLINE idVec2 idVec2::Truncate( float length ) const {
    195 	if ( length < idMath::FLT_SMALLEST_NON_DENORMAL ) {
    196 		return vec2_zero;
    197 	} else {
    198 		float length2 = LengthSqr();
    199 		if ( length2 > length * length ) {
    200 			float ilength = length * idMath::InvSqrt( length2 );
    201 			return *this * ilength;
    202 		}
    203 	}
    204 	return *this;
    205 }
    206 
    207 ID_INLINE void idVec2::Clamp( const idVec2 &min, const idVec2 &max ) {
    208 	if ( x < min.x ) {
    209 		x = min.x;
    210 	} else if ( x > max.x ) {
    211 		x = max.x;
    212 	}
    213 	if ( y < min.y ) {
    214 		y = min.y;
    215 	} else if ( y > max.y ) {
    216 		y = max.y;
    217 	}
    218 }
    219 
    220 ID_INLINE void idVec2::Snap() {
    221 	x = floor( x + 0.5f );
    222 	y = floor( y + 0.5f );
    223 }
    224 
    225 ID_INLINE void idVec2::SnapInt() {
    226 	x = float( int( x ) );
    227 	y = float( int( y ) );
    228 }
    229 
    230 ID_INLINE idVec2 idVec2::operator-() const {
    231 	return idVec2( -x, -y );
    232 }
    233 	
    234 ID_INLINE idVec2 idVec2::operator-( const idVec2 &a ) const {
    235 	return idVec2( x - a.x, y - a.y );
    236 }
    237 
    238 ID_INLINE float idVec2::operator*( const idVec2 &a ) const {
    239 	return x * a.x + y * a.y;
    240 }
    241 
    242 ID_INLINE idVec2 idVec2::operator*( const float a ) const {
    243 	return idVec2( x * a, y * a );
    244 }
    245 
    246 ID_INLINE idVec2 idVec2::operator/( const float a ) const {
    247 	float inva = 1.0f / a;
    248 	return idVec2( x * inva, y * inva );
    249 }
    250 
    251 ID_INLINE idVec2 operator*( const float a, const idVec2 b ) {
    252 	return idVec2( b.x * a, b.y * a );
    253 }
    254 
    255 ID_INLINE idVec2 idVec2::operator+( const idVec2 &a ) const {
    256 	return idVec2( x + a.x, y + a.y );
    257 }
    258 
    259 ID_INLINE idVec2 &idVec2::operator+=( const idVec2 &a ) {
    260 	x += a.x;
    261 	y += a.y;
    262 
    263 	return *this;
    264 }
    265 
    266 ID_INLINE idVec2 &idVec2::operator/=( const idVec2 &a ) {
    267 	x /= a.x;
    268 	y /= a.y;
    269 
    270 	return *this;
    271 }
    272 
    273 ID_INLINE idVec2 &idVec2::operator/=( const float a ) {
    274 	float inva = 1.0f / a;
    275 	x *= inva;
    276 	y *= inva;
    277 
    278 	return *this;
    279 }
    280 
    281 ID_INLINE idVec2 &idVec2::operator-=( const idVec2 &a ) {
    282 	x -= a.x;
    283 	y -= a.y;
    284 
    285 	return *this;
    286 }
    287 
    288 ID_INLINE idVec2 &idVec2::operator*=( const float a ) {
    289 	x *= a;
    290 	y *= a;
    291 
    292 	return *this;
    293 }
    294 
    295 ID_INLINE idVec2 idVec2::Scale( const idVec2 &a ) const {
    296 	return idVec2( x * a.x, y * a.y );
    297 }
    298 
    299 ID_INLINE int idVec2::GetDimension() const {
    300 	return 2;
    301 }
    302 
    303 ID_INLINE const float *idVec2::ToFloatPtr() const {
    304 	return &x;
    305 }
    306 
    307 ID_INLINE float *idVec2::ToFloatPtr() {
    308 	return &x;
    309 }
    310 
    311 
    312 //===============================================================
    313 //
    314 //	idVec3 - 3D vector
    315 //
    316 //===============================================================
    317 
    318 class idVec3 {
    319 public:	
    320 	float			x;
    321 	float			y;
    322 	float			z;
    323 
    324 					idVec3();
    325 					explicit idVec3( const float xyz ) { Set( xyz, xyz, xyz ); }
    326 					explicit idVec3( const float x, const float y, const float z );
    327 
    328 	void 			Set( const float x, const float y, const float z );
    329 	void			Zero();
    330 
    331 	float			operator[]( const int index ) const;
    332 	float &			operator[]( const int index );
    333 	idVec3			operator-() const;
    334 	idVec3 &		operator=( const idVec3 &a );		// required because of a msvc 6 & 7 bug
    335 	float			operator*( const idVec3 &a ) const;
    336 	idVec3			operator*( const float a ) const;
    337 	idVec3			operator/( const float a ) const;
    338 	idVec3			operator+( const idVec3 &a ) const;
    339 	idVec3			operator-( const idVec3 &a ) const;
    340 	idVec3 &		operator+=( const idVec3 &a );
    341 	idVec3 &		operator-=( const idVec3 &a );
    342 	idVec3 &		operator/=( const idVec3 &a );
    343 	idVec3 &		operator/=( const float a );
    344 	idVec3 &		operator*=( const float a );
    345 
    346 	friend idVec3	operator*( const float a, const idVec3 b );
    347 
    348 	bool			Compare( const idVec3 &a ) const;							// exact compare, no epsilon
    349 	bool			Compare( const idVec3 &a, const float epsilon ) const;		// compare with epsilon
    350 	bool			operator==(	const idVec3 &a ) const;						// exact compare, no epsilon
    351 	bool			operator!=(	const idVec3 &a ) const;						// exact compare, no epsilon
    352 
    353 	bool			FixDegenerateNormal();	// fix degenerate axial cases
    354 	bool			FixDenormals();			// change tiny numbers to zero
    355 
    356 	idVec3			Cross( const idVec3 &a ) const;
    357 	idVec3 &		Cross( const idVec3 &a, const idVec3 &b );
    358 	float			Length() const;
    359 	float			LengthSqr() const;
    360 	float			LengthFast() const;
    361 	float			Normalize();				// returns length
    362 	float			NormalizeFast();			// returns length
    363 	idVec3			Truncate( float length ) const;		// cap length
    364 	void			Clamp( const idVec3 &min, const idVec3 &max );
    365 	void			Snap();					// snap to closest integer value
    366 	void			SnapInt();				// snap towards integer (floor)
    367 
    368 	int				GetDimension() const;
    369 
    370 	float			ToYaw() const;
    371 	float			ToPitch() const;
    372 	idAngles		ToAngles() const;
    373 	idPolar3		ToPolar() const;
    374 	idMat3			ToMat3() const;		// vector should be normalized
    375 	const idVec2 &	ToVec2() const;
    376 	idVec2 &		ToVec2();
    377 	const float *	ToFloatPtr() const;
    378 	float *			ToFloatPtr();
    379 	const char *	ToString( int precision = 2 ) const;
    380 
    381 	void			NormalVectors( idVec3 &left, idVec3 &down ) const;	// vector should be normalized
    382 	void			OrthogonalBasis( idVec3 &left, idVec3 &up ) const;
    383 
    384 	void			ProjectOntoPlane( const idVec3 &normal, const float overBounce = 1.0f );
    385 	bool			ProjectAlongPlane( const idVec3 &normal, const float epsilon, const float overBounce = 1.0f );
    386 	void			ProjectSelfOntoSphere( const float radius );
    387 
    388 	void			Lerp( const idVec3 &v1, const idVec3 &v2, const float l );
    389 	void			SLerp( const idVec3 &v1, const idVec3 &v2, const float l );
    390 };
    391 
    392 extern idVec3 vec3_origin;
    393 #define vec3_zero vec3_origin
    394 
    395 ID_INLINE idVec3::idVec3() {
    396 }
    397 
    398 ID_INLINE idVec3::idVec3( const float x, const float y, const float z ) {
    399 	this->x = x;
    400 	this->y = y;
    401 	this->z = z;
    402 }
    403 
    404 ID_INLINE float idVec3::operator[]( const int index ) const {
    405 	return ( &x )[ index ];
    406 }
    407 
    408 ID_INLINE float &idVec3::operator[]( const int index ) {
    409 	return ( &x )[ index ];
    410 }
    411 
    412 ID_INLINE void idVec3::Set( const float x, const float y, const float z ) {
    413 	this->x = x;
    414 	this->y = y;
    415 	this->z = z;
    416 }
    417 
    418 ID_INLINE void idVec3::Zero() {
    419 	x = y = z = 0.0f;
    420 }
    421 
    422 ID_INLINE idVec3 idVec3::operator-() const {
    423 	return idVec3( -x, -y, -z );
    424 }
    425 
    426 ID_INLINE idVec3 &idVec3::operator=( const idVec3 &a ) {
    427 	x = a.x;
    428 	y = a.y;
    429 	z = a.z;
    430 	return *this;
    431 }
    432 
    433 ID_INLINE idVec3 idVec3::operator-( const idVec3 &a ) const {
    434 	return idVec3( x - a.x, y - a.y, z - a.z );
    435 }
    436 
    437 ID_INLINE float idVec3::operator*( const idVec3 &a ) const {
    438 	return x * a.x + y * a.y + z * a.z;
    439 }
    440 
    441 ID_INLINE idVec3 idVec3::operator*( const float a ) const {
    442 	return idVec3( x * a, y * a, z * a );
    443 }
    444 
    445 ID_INLINE idVec3 idVec3::operator/( const float a ) const {
    446 	float inva = 1.0f / a;
    447 	return idVec3( x * inva, y * inva, z * inva );
    448 }
    449 
    450 ID_INLINE idVec3 operator*( const float a, const idVec3 b ) {
    451 	return idVec3( b.x * a, b.y * a, b.z * a );
    452 }
    453 
    454 ID_INLINE idVec3 operator/( const float a, const idVec3 b ) {
    455 	return idVec3( a / b.x, a / b.y, a / b.z );
    456 }
    457 
    458 ID_INLINE idVec3 idVec3::operator+( const idVec3 &a ) const {
    459 	return idVec3( x + a.x, y + a.y, z + a.z );
    460 }
    461 
    462 ID_INLINE idVec3 &idVec3::operator+=( const idVec3 &a ) {
    463 	x += a.x;
    464 	y += a.y;
    465 	z += a.z;
    466 
    467 	return *this;
    468 }
    469 
    470 ID_INLINE idVec3 &idVec3::operator/=( const idVec3 &a ) {
    471 	x /= a.x;
    472 	y /= a.y;
    473 	z /= a.z;
    474 
    475 	return *this;
    476 }
    477 
    478 ID_INLINE idVec3 &idVec3::operator/=( const float a ) {
    479 	float inva = 1.0f / a;
    480 	x *= inva;
    481 	y *= inva;
    482 	z *= inva;
    483 
    484 	return *this;
    485 }
    486 
    487 ID_INLINE idVec3 &idVec3::operator-=( const idVec3 &a ) {
    488 	x -= a.x;
    489 	y -= a.y;
    490 	z -= a.z;
    491 
    492 	return *this;
    493 }
    494 
    495 ID_INLINE idVec3 &idVec3::operator*=( const float a ) {
    496 	x *= a;
    497 	y *= a;
    498 	z *= a;
    499 
    500 	return *this;
    501 }
    502 
    503 ID_INLINE bool idVec3::Compare( const idVec3 &a ) const {
    504 	return ( ( x == a.x ) && ( y == a.y ) && ( z == a.z ) );
    505 }
    506 
    507 ID_INLINE bool idVec3::Compare( const idVec3 &a, const float epsilon ) const {
    508 	if ( idMath::Fabs( x - a.x ) > epsilon ) {
    509 		return false;
    510 	}
    511 			
    512 	if ( idMath::Fabs( y - a.y ) > epsilon ) {
    513 		return false;
    514 	}
    515 
    516 	if ( idMath::Fabs( z - a.z ) > epsilon ) {
    517 		return false;
    518 	}
    519 
    520 	return true;
    521 }
    522 
    523 ID_INLINE bool idVec3::operator==( const idVec3 &a ) const {
    524 	return Compare( a );
    525 }
    526 
    527 ID_INLINE bool idVec3::operator!=( const idVec3 &a ) const {
    528 	return !Compare( a );
    529 }
    530 
    531 ID_INLINE float idVec3::NormalizeFast() {
    532 	float sqrLength, invLength;
    533 
    534 	sqrLength = x * x + y * y + z * z;
    535 	invLength = idMath::InvSqrt( sqrLength );
    536 	x *= invLength;
    537 	y *= invLength;
    538 	z *= invLength;
    539 	return invLength * sqrLength;
    540 }
    541 
    542 ID_INLINE bool idVec3::FixDegenerateNormal() {
    543 	if ( x == 0.0f ) {
    544 		if ( y == 0.0f ) {
    545 			if ( z > 0.0f ) {
    546 				if ( z != 1.0f ) {
    547 					z = 1.0f;
    548 					return true;
    549 				}
    550 			} else {
    551 				if ( z != -1.0f ) {
    552 					z = -1.0f;
    553 					return true;
    554 				}
    555 			}
    556 			return false;
    557 		} else if ( z == 0.0f ) {
    558 			if ( y > 0.0f ) {
    559 				if ( y != 1.0f ) {
    560 					y = 1.0f;
    561 					return true;
    562 				}
    563 			} else {
    564 				if ( y != -1.0f ) {
    565 					y = -1.0f;
    566 					return true;
    567 				}
    568 			}
    569 			return false;
    570 		}
    571 	} else if ( y == 0.0f ) {
    572 		if ( z == 0.0f ) {
    573 			if ( x > 0.0f ) {
    574 				if ( x != 1.0f ) {
    575 					x = 1.0f;
    576 					return true;
    577 				}
    578 			} else {
    579 				if ( x != -1.0f ) {
    580 					x = -1.0f;
    581 					return true;
    582 				}
    583 			}
    584 			return false;
    585 		}
    586 	}
    587 	if ( idMath::Fabs( x ) == 1.0f ) {
    588 		if ( y != 0.0f || z != 0.0f ) {
    589 			y = z = 0.0f;
    590 			return true;
    591 		}
    592 		return false;
    593 	} else if ( idMath::Fabs( y ) == 1.0f ) {
    594 		if ( x != 0.0f || z != 0.0f ) {
    595 			x = z = 0.0f;
    596 			return true;
    597 		}
    598 		return false;
    599 	} else if ( idMath::Fabs( z ) == 1.0f ) {
    600 		if ( x != 0.0f || y != 0.0f ) {
    601 			x = y = 0.0f;
    602 			return true;
    603 		}
    604 		return false;
    605 	}
    606 	return false;
    607 }
    608 
    609 ID_INLINE bool idVec3::FixDenormals() {
    610 	bool denormal = false;
    611 	if ( fabs( x ) < 1e-30f ) {
    612 		x = 0.0f;
    613 		denormal = true;
    614 	}
    615 	if ( fabs( y ) < 1e-30f ) {
    616 		y = 0.0f;
    617 		denormal = true;
    618 	}
    619 	if ( fabs( z ) < 1e-30f ) {
    620 		z = 0.0f;
    621 		denormal = true;
    622 	}
    623 	return denormal;
    624 }
    625 
    626 ID_INLINE idVec3 idVec3::Cross( const idVec3 &a ) const {
    627 	return idVec3( y * a.z - z * a.y, z * a.x - x * a.z, x * a.y - y * a.x );
    628 }
    629 
    630 ID_INLINE idVec3 &idVec3::Cross( const idVec3 &a, const idVec3 &b ) {
    631 	x = a.y * b.z - a.z * b.y;
    632 	y = a.z * b.x - a.x * b.z;
    633 	z = a.x * b.y - a.y * b.x;
    634 
    635 	return *this;
    636 }
    637 
    638 ID_INLINE float idVec3::Length() const {
    639 	return ( float )idMath::Sqrt( x * x + y * y + z * z );
    640 }
    641 
    642 ID_INLINE float idVec3::LengthSqr() const {
    643 	return ( x * x + y * y + z * z );
    644 }
    645 
    646 ID_INLINE float idVec3::LengthFast() const {
    647 	float sqrLength;
    648 
    649 	sqrLength = x * x + y * y + z * z;
    650 	return sqrLength * idMath::InvSqrt( sqrLength );
    651 }
    652 
    653 ID_INLINE float idVec3::Normalize() {
    654 	float sqrLength, invLength;
    655 
    656 	sqrLength = x * x + y * y + z * z;
    657 	invLength = idMath::InvSqrt( sqrLength );
    658 	x *= invLength;
    659 	y *= invLength;
    660 	z *= invLength;
    661 	return invLength * sqrLength;
    662 }
    663 
    664 ID_INLINE idVec3 idVec3::Truncate( float length ) const {
    665 	if ( length < idMath::FLT_SMALLEST_NON_DENORMAL ) {
    666 		return vec3_zero;
    667 	} else {
    668 		float length2 = LengthSqr();
    669 		if ( length2 > length * length ) {
    670 			float ilength = length * idMath::InvSqrt( length2 );
    671 			return *this * ilength;
    672 		}
    673 	}
    674 	return *this;
    675 }
    676 
    677 ID_INLINE void idVec3::Clamp( const idVec3 &min, const idVec3 &max ) {
    678 	if ( x < min.x ) {
    679 		x = min.x;
    680 	} else if ( x > max.x ) {
    681 		x = max.x;
    682 	}
    683 	if ( y < min.y ) {
    684 		y = min.y;
    685 	} else if ( y > max.y ) {
    686 		y = max.y;
    687 	}
    688 	if ( z < min.z ) {
    689 		z = min.z;
    690 	} else if ( z > max.z ) {
    691 		z = max.z;
    692 	}
    693 }
    694 
    695 ID_INLINE void idVec3::Snap() {
    696 	x = floor( x + 0.5f );
    697 	y = floor( y + 0.5f );
    698 	z = floor( z + 0.5f );
    699 }
    700 
    701 ID_INLINE void idVec3::SnapInt() {
    702 	x = float( int( x ) );
    703 	y = float( int( y ) );
    704 	z = float( int( z ) );
    705 }
    706 
    707 ID_INLINE int idVec3::GetDimension() const {
    708 	return 3;
    709 }
    710 
    711 ID_INLINE const idVec2 &idVec3::ToVec2() const {
    712 	return *reinterpret_cast<const idVec2 *>(this);
    713 }
    714 
    715 ID_INLINE idVec2 &idVec3::ToVec2() {
    716 	return *reinterpret_cast<idVec2 *>(this);
    717 }
    718 
    719 ID_INLINE const float *idVec3::ToFloatPtr() const {
    720 	return &x;
    721 }
    722 
    723 ID_INLINE float *idVec3::ToFloatPtr() {
    724 	return &x;
    725 }
    726 
    727 ID_INLINE void idVec3::NormalVectors( idVec3 &left, idVec3 &down ) const {
    728 	float d;
    729 
    730 	d = x * x + y * y;
    731 	if ( !d ) {
    732 		left[0] = 1;
    733 		left[1] = 0;
    734 		left[2] = 0;
    735 	} else {
    736 		d = idMath::InvSqrt( d );
    737 		left[0] = -y * d;
    738 		left[1] = x * d;
    739 		left[2] = 0;
    740 	}
    741 	down = left.Cross( *this );
    742 }
    743 
    744 ID_INLINE void idVec3::OrthogonalBasis( idVec3 &left, idVec3 &up ) const {
    745 	float l, s;
    746 
    747 	if ( idMath::Fabs( z ) > 0.7f ) {
    748 		l = y * y + z * z;
    749 		s = idMath::InvSqrt( l );
    750 		up[0] = 0;
    751 		up[1] = z * s;
    752 		up[2] = -y * s;
    753 		left[0] = l * s;
    754 		left[1] = -x * up[2];
    755 		left[2] = x * up[1];
    756 	}
    757 	else {
    758 		l = x * x + y * y;
    759 		s = idMath::InvSqrt( l );
    760 		left[0] = -y * s;
    761 		left[1] = x * s;
    762 		left[2] = 0;
    763 		up[0] = -z * left[1];
    764 		up[1] = z * left[0];
    765 		up[2] = l * s;
    766 	}
    767 }
    768 
    769 ID_INLINE void idVec3::ProjectOntoPlane( const idVec3 &normal, const float overBounce ) {
    770 	float backoff;
    771 	
    772 	backoff = *this * normal;
    773 	
    774 	if ( overBounce != 1.0 ) {
    775 		if ( backoff < 0 ) {
    776 			backoff *= overBounce;
    777 		} else {
    778 			backoff /= overBounce;
    779 		}
    780 	}
    781 
    782 	*this -= backoff * normal;
    783 }
    784 
    785 ID_INLINE bool idVec3::ProjectAlongPlane( const idVec3 &normal, const float epsilon, const float overBounce ) {
    786 	idVec3 cross;
    787 	float len;
    788 
    789 	cross = this->Cross( normal ).Cross( (*this) );
    790 	// normalize so a fixed epsilon can be used
    791 	cross.Normalize();
    792 	len = normal * cross;
    793 	if ( idMath::Fabs( len ) < epsilon ) {
    794 		return false;
    795 	}
    796 	cross *= overBounce * ( normal * (*this) ) / len;
    797 	(*this) -= cross;
    798 	return true;
    799 }
    800 
    801 //===============================================================
    802 //
    803 //	idTupleSize< idVec3 > - Specialization to get the size
    804 //	of an idVec3 generically.
    805 //
    806 //===============================================================
    807 
    808 template<>
    809 struct idTupleSize< idVec3 > {
    810 	enum { value = 3 };
    811 };
    812 
    813 //===============================================================
    814 //
    815 //	idVec4 - 4D vector
    816 //
    817 //===============================================================
    818 
    819 class idVec4 {
    820 public:	
    821 	float			x;
    822 	float			y;
    823 	float			z;
    824 	float			w;
    825 
    826 					idVec4() { }
    827 					explicit idVec4( const float x ) { Set( x, x, x, x ); }
    828 					explicit idVec4( const float x, const float y, const float z, const float w ) { Set( x, y, z, w ); }
    829 
    830 	void 			Set( const float x, const float y, const float z, const float w );
    831 	void			Zero();
    832 
    833 	float			operator[]( const int index ) const;
    834 	float &			operator[]( const int index );
    835 	idVec4			operator-() const;
    836 	float			operator*( const idVec4 &a ) const;
    837 	idVec4			operator*( const float a ) const;
    838 	idVec4			operator/( const float a ) const;
    839 	idVec4			operator+( const idVec4 &a ) const;
    840 	idVec4			operator-( const idVec4 &a ) const;
    841 	idVec4 &		operator+=( const idVec4 &a );
    842 	idVec4 &		operator-=( const idVec4 &a );
    843 	idVec4 &		operator/=( const idVec4 &a );
    844 	idVec4 &		operator/=( const float a );
    845 	idVec4 &		operator*=( const float a );
    846 
    847 	friend idVec4	operator*( const float a, const idVec4 b );
    848 
    849 	idVec4			Multiply( const idVec4 & a ) const;
    850 
    851 	bool			Compare( const idVec4 &a ) const;							// exact compare, no epsilon
    852 	bool			Compare( const idVec4 &a, const float epsilon ) const;		// compare with epsilon
    853 	bool			operator==(	const idVec4 &a ) const;						// exact compare, no epsilon
    854 	bool			operator!=(	const idVec4 &a ) const;						// exact compare, no epsilon
    855 
    856 	float			Length() const;
    857 	float			LengthSqr() const;
    858 	float			Normalize();			// returns length
    859 	float			NormalizeFast();		// returns length
    860 
    861 	int				GetDimension() const;
    862 
    863 	const idVec2 &	ToVec2() const;
    864 	idVec2 &		ToVec2();
    865 	const idVec3 &	ToVec3() const;
    866 	idVec3 &		ToVec3();
    867 	const float *	ToFloatPtr() const;
    868 	float *			ToFloatPtr();
    869 	const char *	ToString( int precision = 2 ) const;
    870 
    871 	void			Lerp( const idVec4 &v1, const idVec4 &v2, const float l );
    872 };
    873 
    874 extern idVec4 vec4_origin;
    875 #define vec4_zero vec4_origin
    876 
    877 ID_INLINE void idVec4::Set( const float x, const float y, const float z, const float w ) {
    878 	this->x = x;
    879 	this->y = y;
    880 	this->z = z;
    881 	this->w = w;
    882 }
    883 
    884 ID_INLINE void idVec4::Zero() {
    885 	x = y = z = w = 0.0f;
    886 }
    887 
    888 ID_INLINE float idVec4::operator[]( int index ) const {
    889 	return ( &x )[ index ];
    890 }
    891 
    892 ID_INLINE float& idVec4::operator[]( int index ) {
    893 	return ( &x )[ index ];
    894 }
    895 
    896 ID_INLINE idVec4 idVec4::operator-() const {
    897 	return idVec4( -x, -y, -z, -w );
    898 }
    899 
    900 ID_INLINE idVec4 idVec4::operator-( const idVec4 &a ) const {
    901 	return idVec4( x - a.x, y - a.y, z - a.z, w - a.w );
    902 }
    903 
    904 ID_INLINE float idVec4::operator*( const idVec4 &a ) const {
    905 	return x * a.x + y * a.y + z * a.z + w * a.w;
    906 }
    907 
    908 ID_INLINE idVec4 idVec4::operator*( const float a ) const {
    909 	return idVec4( x * a, y * a, z * a, w * a );
    910 }
    911 
    912 ID_INLINE idVec4 idVec4::operator/( const float a ) const {
    913 	float inva = 1.0f / a;
    914 	return idVec4( x * inva, y * inva, z * inva, w * inva );
    915 }
    916 
    917 ID_INLINE idVec4 operator*( const float a, const idVec4 b ) {
    918 	return idVec4( b.x * a, b.y * a, b.z * a, b.w * a );
    919 }
    920 
    921 ID_INLINE idVec4 idVec4::operator+( const idVec4 &a ) const {
    922 	return idVec4( x + a.x, y + a.y, z + a.z, w + a.w );
    923 }
    924 
    925 ID_INLINE idVec4 &idVec4::operator+=( const idVec4 &a ) {
    926 	x += a.x;
    927 	y += a.y;
    928 	z += a.z;
    929 	w += a.w;
    930 
    931 	return *this;
    932 }
    933 
    934 ID_INLINE idVec4 &idVec4::operator/=( const idVec4 &a ) {
    935 	x /= a.x;
    936 	y /= a.y;
    937 	z /= a.z;
    938 	w /= a.w;
    939 
    940 	return *this;
    941 }
    942 
    943 ID_INLINE idVec4 &idVec4::operator/=( const float a ) {
    944 	float inva = 1.0f / a;
    945 	x *= inva;
    946 	y *= inva;
    947 	z *= inva;
    948 	w *= inva;
    949 
    950 	return *this;
    951 }
    952 
    953 ID_INLINE idVec4 &idVec4::operator-=( const idVec4 &a ) {
    954 	x -= a.x;
    955 	y -= a.y;
    956 	z -= a.z;
    957 	w -= a.w;
    958 
    959 	return *this;
    960 }
    961 
    962 ID_INLINE idVec4 &idVec4::operator*=( const float a ) {
    963 	x *= a;
    964 	y *= a;
    965 	z *= a;
    966 	w *= a;
    967 
    968 	return *this;
    969 }
    970 
    971 ID_INLINE idVec4 idVec4::Multiply( const idVec4 & a ) const {
    972 	return idVec4( x * a.x, y * a.y, z * a.z, w * a.w );
    973 }
    974 
    975 ID_INLINE bool idVec4::Compare( const idVec4 &a ) const {
    976 	return ( ( x == a.x ) && ( y == a.y ) && ( z == a.z ) && w == a.w );
    977 }
    978 
    979 ID_INLINE bool idVec4::Compare( const idVec4 &a, const float epsilon ) const {
    980 	if ( idMath::Fabs( x - a.x ) > epsilon ) {
    981 		return false;
    982 	}
    983 			
    984 	if ( idMath::Fabs( y - a.y ) > epsilon ) {
    985 		return false;
    986 	}
    987 
    988 	if ( idMath::Fabs( z - a.z ) > epsilon ) {
    989 		return false;
    990 	}
    991 
    992 	if ( idMath::Fabs( w - a.w ) > epsilon ) {
    993 		return false;
    994 	}
    995 
    996 	return true;
    997 }
    998 
    999 ID_INLINE bool idVec4::operator==( const idVec4 &a ) const {
   1000 	return Compare( a );
   1001 }
   1002 
   1003 ID_INLINE bool idVec4::operator!=( const idVec4 &a ) const {
   1004 	return !Compare( a );
   1005 }
   1006 
   1007 ID_INLINE float idVec4::Length() const {
   1008 	return ( float )idMath::Sqrt( x * x + y * y + z * z + w * w );
   1009 }
   1010 
   1011 ID_INLINE float idVec4::LengthSqr() const {
   1012 	return ( x * x + y * y + z * z + w * w );
   1013 }
   1014 
   1015 ID_INLINE float idVec4::Normalize() {
   1016 	float sqrLength, invLength;
   1017 
   1018 	sqrLength = x * x + y * y + z * z + w * w;
   1019 	invLength = idMath::InvSqrt( sqrLength );
   1020 	x *= invLength;
   1021 	y *= invLength;
   1022 	z *= invLength;
   1023 	w *= invLength;
   1024 	return invLength * sqrLength;
   1025 }
   1026 
   1027 ID_INLINE float idVec4::NormalizeFast() {
   1028 	float sqrLength, invLength;
   1029 
   1030 	sqrLength = x * x + y * y + z * z + w * w;
   1031 	invLength = idMath::InvSqrt( sqrLength );
   1032 	x *= invLength;
   1033 	y *= invLength;
   1034 	z *= invLength;
   1035 	w *= invLength;
   1036 	return invLength * sqrLength;
   1037 }
   1038 
   1039 ID_INLINE int idVec4::GetDimension() const {
   1040 	return 4;
   1041 }
   1042 
   1043 ID_INLINE const idVec2 &idVec4::ToVec2() const {
   1044 	return *reinterpret_cast<const idVec2 *>(this);
   1045 }
   1046 
   1047 ID_INLINE idVec2 &idVec4::ToVec2() {
   1048 	return *reinterpret_cast<idVec2 *>(this);
   1049 }
   1050 
   1051 ID_INLINE const idVec3 &idVec4::ToVec3() const {
   1052 	return *reinterpret_cast<const idVec3 *>(this);
   1053 }
   1054 
   1055 ID_INLINE idVec3 &idVec4::ToVec3() {
   1056 	return *reinterpret_cast<idVec3 *>(this);
   1057 }
   1058 
   1059 ID_INLINE const float *idVec4::ToFloatPtr() const {
   1060 	return &x;
   1061 }
   1062 
   1063 ID_INLINE float *idVec4::ToFloatPtr() {
   1064 	return &x;
   1065 }
   1066 
   1067 
   1068 //===============================================================
   1069 //
   1070 //	idVec5 - 5D vector
   1071 //
   1072 //===============================================================
   1073 
   1074 class idVec5 {
   1075 public:
   1076 	float			x;
   1077 	float			y;
   1078 	float			z;
   1079 	float			s;
   1080 	float			t;
   1081 
   1082 					idVec5();
   1083 					explicit idVec5( const idVec3 &xyz, const idVec2 &st );
   1084 					explicit idVec5( const float x, const float y, const float z, const float s, const float t );
   1085 
   1086 	float			operator[]( int index ) const;
   1087 	float &			operator[]( int index );
   1088 	idVec5 &		operator=( const idVec3 &a );
   1089 
   1090 	int				GetDimension() const;
   1091 
   1092 	const idVec3 &	ToVec3() const;
   1093 	idVec3 &		ToVec3();
   1094 	const float *	ToFloatPtr() const;
   1095 	float *			ToFloatPtr();
   1096 	const char *	ToString( int precision = 2 ) const;
   1097 
   1098 	void			Lerp( const idVec5 &v1, const idVec5 &v2, const float l );
   1099 };
   1100 
   1101 extern idVec5 vec5_origin;
   1102 #define vec5_zero vec5_origin
   1103 
   1104 ID_INLINE idVec5::idVec5() {
   1105 }
   1106 
   1107 ID_INLINE idVec5::idVec5( const idVec3 &xyz, const idVec2 &st ) {
   1108 	x = xyz.x;
   1109 	y = xyz.y;
   1110 	z = xyz.z;
   1111 	s = st[0];
   1112 	t = st[1];
   1113 }
   1114 
   1115 ID_INLINE idVec5::idVec5( const float x, const float y, const float z, const float s, const float t ) {
   1116 	this->x = x;
   1117 	this->y = y;
   1118 	this->z = z;
   1119 	this->s = s;
   1120 	this->t = t;
   1121 }
   1122 
   1123 ID_INLINE float idVec5::operator[]( int index ) const {
   1124 	return ( &x )[ index ];
   1125 }
   1126 
   1127 ID_INLINE float& idVec5::operator[]( int index ) {
   1128 	return ( &x )[ index ];
   1129 }
   1130 
   1131 ID_INLINE idVec5 &idVec5::operator=( const idVec3 &a ) { 
   1132 	x = a.x;
   1133 	y = a.y;
   1134 	z = a.z;
   1135 	s = t = 0;
   1136 	return *this;
   1137 }
   1138 
   1139 ID_INLINE int idVec5::GetDimension() const {
   1140 	return 5;
   1141 }
   1142 
   1143 ID_INLINE const idVec3 &idVec5::ToVec3() const {
   1144 	return *reinterpret_cast<const idVec3 *>(this);
   1145 }
   1146 
   1147 ID_INLINE idVec3 &idVec5::ToVec3() {
   1148 	return *reinterpret_cast<idVec3 *>(this);
   1149 }
   1150 
   1151 ID_INLINE const float *idVec5::ToFloatPtr() const {
   1152 	return &x;
   1153 }
   1154 
   1155 ID_INLINE float *idVec5::ToFloatPtr() {
   1156 	return &x;
   1157 }
   1158 
   1159 
   1160 //===============================================================
   1161 //
   1162 //	idVec6 - 6D vector
   1163 //
   1164 //===============================================================
   1165 
   1166 class idVec6 {
   1167 public:	
   1168 					idVec6();
   1169 					explicit idVec6( const float *a );
   1170 					explicit idVec6( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 );
   1171 
   1172 	void 			Set( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 );
   1173 	void			Zero();
   1174 
   1175 	float			operator[]( const int index ) const;
   1176 	float &			operator[]( const int index );
   1177 	idVec6			operator-() const;
   1178 	idVec6			operator*( const float a ) const;
   1179 	idVec6			operator/( const float a ) const;
   1180 	float			operator*( const idVec6 &a ) const;
   1181 	idVec6			operator-( const idVec6 &a ) const;
   1182 	idVec6			operator+( const idVec6 &a ) const;
   1183 	idVec6 &		operator*=( const float a );
   1184 	idVec6 &		operator/=( const float a );
   1185 	idVec6 &		operator+=( const idVec6 &a );
   1186 	idVec6 &		operator-=( const idVec6 &a );
   1187 
   1188 	friend idVec6	operator*( const float a, const idVec6 b );
   1189 
   1190 	bool			Compare( const idVec6 &a ) const;							// exact compare, no epsilon
   1191 	bool			Compare( const idVec6 &a, const float epsilon ) const;		// compare with epsilon
   1192 	bool			operator==(	const idVec6 &a ) const;						// exact compare, no epsilon
   1193 	bool			operator!=(	const idVec6 &a ) const;						// exact compare, no epsilon
   1194 
   1195 	float			Length() const;
   1196 	float			LengthSqr() const;
   1197 	float			Normalize();			// returns length
   1198 	float			NormalizeFast();		// returns length
   1199 
   1200 	int				GetDimension() const;
   1201 
   1202 	const idVec3 &	SubVec3( int index ) const;
   1203 	idVec3 &		SubVec3( int index );
   1204 	const float *	ToFloatPtr() const;
   1205 	float *			ToFloatPtr();
   1206 	const char *	ToString( int precision = 2 ) const;
   1207 
   1208 private:
   1209 	float			p[6];
   1210 };
   1211 
   1212 extern idVec6 vec6_origin;
   1213 #define vec6_zero vec6_origin
   1214 extern idVec6 vec6_infinity;
   1215 
   1216 ID_INLINE idVec6::idVec6() {
   1217 }
   1218 
   1219 ID_INLINE idVec6::idVec6( const float *a ) {
   1220 	memcpy( p, a, 6 * sizeof( float ) );
   1221 }
   1222 
   1223 ID_INLINE idVec6::idVec6( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 ) {
   1224 	p[0] = a1;
   1225 	p[1] = a2;
   1226 	p[2] = a3;
   1227 	p[3] = a4;
   1228 	p[4] = a5;
   1229 	p[5] = a6;
   1230 }
   1231 
   1232 ID_INLINE idVec6 idVec6::operator-() const {
   1233 	return idVec6( -p[0], -p[1], -p[2], -p[3], -p[4], -p[5] );
   1234 }
   1235 
   1236 ID_INLINE float idVec6::operator[]( const int index ) const {
   1237 	return p[index];
   1238 }
   1239 
   1240 ID_INLINE float &idVec6::operator[]( const int index ) {
   1241 	return p[index];
   1242 }
   1243 
   1244 ID_INLINE idVec6 idVec6::operator*( const float a ) const {
   1245 	return idVec6( p[0]*a, p[1]*a, p[2]*a, p[3]*a, p[4]*a, p[5]*a );
   1246 }
   1247 
   1248 ID_INLINE float idVec6::operator*( const idVec6 &a ) const {
   1249 	return p[0] * a[0] + p[1] * a[1] + p[2] * a[2] + p[3] * a[3] + p[4] * a[4] + p[5] * a[5];
   1250 }
   1251 
   1252 ID_INLINE idVec6 idVec6::operator/( const float a ) const {
   1253 	float inva;
   1254 
   1255 	assert( a != 0.0f );
   1256 	inva = 1.0f / a;
   1257 	return idVec6( p[0]*inva, p[1]*inva, p[2]*inva, p[3]*inva, p[4]*inva, p[5]*inva );
   1258 }
   1259 
   1260 ID_INLINE idVec6 idVec6::operator+( const idVec6 &a ) const {
   1261 	return idVec6( p[0] + a[0], p[1] + a[1], p[2] + a[2], p[3] + a[3], p[4] + a[4], p[5] + a[5] );
   1262 }
   1263 
   1264 ID_INLINE idVec6 idVec6::operator-( const idVec6 &a ) const {
   1265 	return idVec6( p[0] - a[0], p[1] - a[1], p[2] - a[2], p[3] - a[3], p[4] - a[4], p[5] - a[5] );
   1266 }
   1267 
   1268 ID_INLINE idVec6 &idVec6::operator*=( const float a ) {
   1269 	p[0] *= a;
   1270 	p[1] *= a;
   1271 	p[2] *= a;
   1272 	p[3] *= a;
   1273 	p[4] *= a;
   1274 	p[5] *= a;
   1275 	return *this;
   1276 }
   1277 
   1278 ID_INLINE idVec6 &idVec6::operator/=( const float a ) {
   1279 	float inva;
   1280 
   1281 	assert( a != 0.0f );
   1282 	inva = 1.0f / a;
   1283 	p[0] *= inva;
   1284 	p[1] *= inva;
   1285 	p[2] *= inva;
   1286 	p[3] *= inva;
   1287 	p[4] *= inva;
   1288 	p[5] *= inva;
   1289 	return *this;
   1290 }
   1291 
   1292 ID_INLINE idVec6 &idVec6::operator+=( const idVec6 &a ) {
   1293 	p[0] += a[0];
   1294 	p[1] += a[1];
   1295 	p[2] += a[2];
   1296 	p[3] += a[3];
   1297 	p[4] += a[4];
   1298 	p[5] += a[5];
   1299 	return *this;
   1300 }
   1301 
   1302 ID_INLINE idVec6 &idVec6::operator-=( const idVec6 &a ) {
   1303 	p[0] -= a[0];
   1304 	p[1] -= a[1];
   1305 	p[2] -= a[2];
   1306 	p[3] -= a[3];
   1307 	p[4] -= a[4];
   1308 	p[5] -= a[5];
   1309 	return *this;
   1310 }
   1311 
   1312 ID_INLINE idVec6 operator*( const float a, const idVec6 b ) {
   1313 	return b * a;
   1314 }
   1315 
   1316 ID_INLINE bool idVec6::Compare( const idVec6 &a ) const {
   1317 	return ( ( p[0] == a[0] ) && ( p[1] == a[1] ) && ( p[2] == a[2] ) &&
   1318 			( p[3] == a[3] ) && ( p[4] == a[4] ) && ( p[5] == a[5] ) );
   1319 }
   1320 
   1321 ID_INLINE bool idVec6::Compare( const idVec6 &a, const float epsilon ) const {
   1322 	if ( idMath::Fabs( p[0] - a[0] ) > epsilon ) {
   1323 		return false;
   1324 	}
   1325 			
   1326 	if ( idMath::Fabs( p[1] - a[1] ) > epsilon ) {
   1327 		return false;
   1328 	}
   1329 
   1330 	if ( idMath::Fabs( p[2] - a[2] ) > epsilon ) {
   1331 		return false;
   1332 	}
   1333 
   1334 	if ( idMath::Fabs( p[3] - a[3] ) > epsilon ) {
   1335 		return false;
   1336 	}
   1337 
   1338 	if ( idMath::Fabs( p[4] - a[4] ) > epsilon ) {
   1339 		return false;
   1340 	}
   1341 
   1342 	if ( idMath::Fabs( p[5] - a[5] ) > epsilon ) {
   1343 		return false;
   1344 	}
   1345 
   1346 	return true;
   1347 }
   1348 
   1349 ID_INLINE bool idVec6::operator==( const idVec6 &a ) const {
   1350 	return Compare( a );
   1351 }
   1352 
   1353 ID_INLINE bool idVec6::operator!=( const idVec6 &a ) const {
   1354 	return !Compare( a );
   1355 }
   1356 
   1357 ID_INLINE void idVec6::Set( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 ) {
   1358 	p[0] = a1;
   1359 	p[1] = a2;
   1360 	p[2] = a3;
   1361 	p[3] = a4;
   1362 	p[4] = a5;
   1363 	p[5] = a6;
   1364 }
   1365 
   1366 ID_INLINE void idVec6::Zero() {
   1367 	p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = 0.0f;
   1368 }
   1369 
   1370 ID_INLINE float idVec6::Length() const {
   1371 	return ( float )idMath::Sqrt( p[0] * p[0] + p[1] * p[1] + p[2] * p[2] + p[3] * p[3] + p[4] * p[4] + p[5] * p[5] );
   1372 }
   1373 
   1374 ID_INLINE float idVec6::LengthSqr() const {
   1375 	return ( p[0] * p[0] + p[1] * p[1] + p[2] * p[2] + p[3] * p[3] + p[4] * p[4] + p[5] * p[5] );
   1376 }
   1377 
   1378 ID_INLINE float idVec6::Normalize() {
   1379 	float sqrLength, invLength;
   1380 
   1381 	sqrLength = p[0] * p[0] + p[1] * p[1] + p[2] * p[2] + p[3] * p[3] + p[4] * p[4] + p[5] * p[5];
   1382 	invLength = idMath::InvSqrt( sqrLength );
   1383 	p[0] *= invLength;
   1384 	p[1] *= invLength;
   1385 	p[2] *= invLength;
   1386 	p[3] *= invLength;
   1387 	p[4] *= invLength;
   1388 	p[5] *= invLength;
   1389 	return invLength * sqrLength;
   1390 }
   1391 
   1392 ID_INLINE float idVec6::NormalizeFast() {
   1393 	float sqrLength, invLength;
   1394 
   1395 	sqrLength = p[0] * p[0] + p[1] * p[1] + p[2] * p[2] + p[3] * p[3] + p[4] * p[4] + p[5] * p[5];
   1396 	invLength = idMath::InvSqrt( sqrLength );
   1397 	p[0] *= invLength;
   1398 	p[1] *= invLength;
   1399 	p[2] *= invLength;
   1400 	p[3] *= invLength;
   1401 	p[4] *= invLength;
   1402 	p[5] *= invLength;
   1403 	return invLength * sqrLength;
   1404 }
   1405 
   1406 ID_INLINE int idVec6::GetDimension() const {
   1407 	return 6;
   1408 }
   1409 
   1410 ID_INLINE const idVec3 &idVec6::SubVec3( int index ) const {
   1411 	return *reinterpret_cast<const idVec3 *>(p + index * 3);
   1412 }
   1413 
   1414 ID_INLINE idVec3 &idVec6::SubVec3( int index ) {
   1415 	return *reinterpret_cast<idVec3 *>(p + index * 3);
   1416 }
   1417 
   1418 ID_INLINE const float *idVec6::ToFloatPtr() const {
   1419 	return p;
   1420 }
   1421 
   1422 ID_INLINE float *idVec6::ToFloatPtr() {
   1423 	return p;
   1424 }
   1425 
   1426 //===============================================================
   1427 //
   1428 //	idPolar3
   1429 //
   1430 //===============================================================
   1431 
   1432 class idPolar3 {
   1433 public:	
   1434 	float			radius, theta, phi;
   1435 
   1436 					idPolar3();
   1437 					explicit idPolar3( const float radius, const float theta, const float phi );
   1438 
   1439 	void 			Set( const float radius, const float theta, const float phi );
   1440 
   1441 	float			operator[]( const int index ) const;
   1442 	float &			operator[]( const int index );
   1443 	idPolar3		operator-() const;
   1444 	idPolar3 &		operator=( const idPolar3 &a );
   1445 
   1446 	idVec3			ToVec3() const;
   1447 };
   1448 
   1449 ID_INLINE idPolar3::idPolar3() {
   1450 }
   1451 
   1452 ID_INLINE idPolar3::idPolar3( const float radius, const float theta, const float phi ) {
   1453 	assert( radius > 0 );
   1454 	this->radius = radius;
   1455 	this->theta = theta;
   1456 	this->phi = phi;
   1457 }
   1458 	
   1459 ID_INLINE void idPolar3::Set( const float radius, const float theta, const float phi ) {
   1460 	assert( radius > 0 );
   1461 	this->radius = radius;
   1462 	this->theta = theta;
   1463 	this->phi = phi;
   1464 }
   1465 
   1466 ID_INLINE float idPolar3::operator[]( const int index ) const {
   1467 	return ( &radius )[ index ];
   1468 }
   1469 
   1470 ID_INLINE float &idPolar3::operator[]( const int index ) {
   1471 	return ( &radius )[ index ];
   1472 }
   1473 
   1474 ID_INLINE idPolar3 idPolar3::operator-() const {
   1475 	return idPolar3( radius, -theta, -phi );
   1476 }
   1477 
   1478 ID_INLINE idPolar3 &idPolar3::operator=( const idPolar3 &a ) { 
   1479 	radius = a.radius;
   1480 	theta = a.theta;
   1481 	phi = a.phi;
   1482 	return *this;
   1483 }
   1484 
   1485 ID_INLINE idVec3 idPolar3::ToVec3() const {
   1486 	float sp, cp, st, ct;
   1487 	idMath::SinCos( phi, sp, cp );
   1488 	idMath::SinCos( theta, st, ct );
   1489  	return idVec3( cp * radius * ct, cp * radius * st, radius * sp );
   1490 }
   1491 
   1492 
   1493 /*
   1494 ===============================================================================
   1495 
   1496 	Old 3D vector macros, should no longer be used.
   1497 
   1498 ===============================================================================
   1499 */
   1500 
   1501 #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))
   1502 
   1503 #endif /* !__MATH_VECTOR_H__ */