DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

Vector.cpp (8020B)


      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 #pragma hdrstop
     30 #include "../precompiled.h"
     31 
     32 idVec2 vec2_origin( 0.0f, 0.0f );
     33 idVec3 vec3_origin( 0.0f, 0.0f, 0.0f );
     34 idVec4 vec4_origin( 0.0f, 0.0f, 0.0f, 0.0f );
     35 idVec5 vec5_origin( 0.0f, 0.0f, 0.0f, 0.0f, 0.0f );
     36 idVec6 vec6_origin( 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f );
     37 idVec6 vec6_infinity( idMath::INFINITY, idMath::INFINITY, idMath::INFINITY, idMath::INFINITY, idMath::INFINITY, idMath::INFINITY );
     38 
     39 
     40 //===============================================================
     41 //
     42 //	idVec2
     43 //
     44 //===============================================================
     45 
     46 /*
     47 =============
     48 idVec2::ToString
     49 =============
     50 */
     51 const char *idVec2::ToString( int precision ) const {
     52 	return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision );
     53 }
     54 
     55 /*
     56 =============
     57 Lerp
     58 
     59 Linearly inperpolates one vector to another.
     60 =============
     61 */
     62 void idVec2::Lerp( const idVec2 &v1, const idVec2 &v2, const float l ) {
     63 	if ( l <= 0.0f ) {
     64 		(*this) = v1;
     65 	} else if ( l >= 1.0f ) {
     66 		(*this) = v2;
     67 	} else {
     68 		(*this) = v1 + l * ( v2 - v1 );
     69 	}
     70 }
     71 
     72 
     73 //===============================================================
     74 //
     75 //	idVec3
     76 //
     77 //===============================================================
     78 
     79 /*
     80 =============
     81 idVec3::ToYaw
     82 =============
     83 */
     84 float idVec3::ToYaw() const {
     85 	float yaw;
     86 	
     87 	if ( ( y == 0.0f ) && ( x == 0.0f ) ) {
     88 		yaw = 0.0f;
     89 	} else {
     90 		yaw = RAD2DEG( atan2( y, x ) );
     91 		if ( yaw < 0.0f ) {
     92 			yaw += 360.0f;
     93 		}
     94 	}
     95 
     96 	return yaw;
     97 }
     98 
     99 /*
    100 =============
    101 idVec3::ToPitch
    102 =============
    103 */
    104 float idVec3::ToPitch() const {
    105 	float	forward;
    106 	float	pitch;
    107 	
    108 	if ( ( x == 0.0f ) && ( y == 0.0f ) ) {
    109 		if ( z > 0.0f ) {
    110 			pitch = 90.0f;
    111 		} else {
    112 			pitch = 270.0f;
    113 		}
    114 	} else {
    115 		forward = ( float )idMath::Sqrt( x * x + y * y );
    116 		pitch = RAD2DEG( atan2( z, forward ) );
    117 		if ( pitch < 0.0f ) {
    118 			pitch += 360.0f;
    119 		}
    120 	}
    121 
    122 	return pitch;
    123 }
    124 
    125 /*
    126 =============
    127 idVec3::ToAngles
    128 =============
    129 */
    130 idAngles idVec3::ToAngles() const {
    131 	float forward;
    132 	float yaw;
    133 	float pitch;
    134 	
    135 	if ( ( x == 0.0f ) && ( y == 0.0f ) ) {
    136 		yaw = 0.0f;
    137 		if ( z > 0.0f ) {
    138 			pitch = 90.0f;
    139 		} else {
    140 			pitch = 270.0f;
    141 		}
    142 	} else {
    143 		yaw = RAD2DEG( atan2( y, x ) );
    144 		if ( yaw < 0.0f ) {
    145 			yaw += 360.0f;
    146 		}
    147 
    148 		forward = ( float )idMath::Sqrt( x * x + y * y );
    149 		pitch = RAD2DEG( atan2( z, forward ) );
    150 		if ( pitch < 0.0f ) {
    151 			pitch += 360.0f;
    152 		}
    153 	}
    154 
    155 	return idAngles( -pitch, yaw, 0.0f );
    156 }
    157 
    158 /*
    159 =============
    160 idVec3::ToPolar
    161 =============
    162 */
    163 idPolar3 idVec3::ToPolar() const {
    164 	float forward;
    165 	float yaw;
    166 	float pitch;
    167 	
    168 	if ( ( x == 0.0f ) && ( y == 0.0f ) ) {
    169 		yaw = 0.0f;
    170 		if ( z > 0.0f ) {
    171 			pitch = 90.0f;
    172 		} else {
    173 			pitch = 270.0f;
    174 		}
    175 	} else {
    176 		yaw = RAD2DEG( atan2( y, x ) );
    177 		if ( yaw < 0.0f ) {
    178 			yaw += 360.0f;
    179 		}
    180 
    181 		forward = ( float )idMath::Sqrt( x * x + y * y );
    182 		pitch = RAD2DEG( atan2( z, forward ) );
    183 		if ( pitch < 0.0f ) {
    184 			pitch += 360.0f;
    185 		}
    186 	}
    187 	return idPolar3( idMath::Sqrt( x * x + y * y + z * z ), yaw, -pitch );
    188 }
    189 
    190 /*
    191 =============
    192 idVec3::ToMat3
    193 =============
    194 */
    195 idMat3 idVec3::ToMat3() const {
    196 	idMat3	mat;
    197 	float	d;
    198 
    199 	mat[0] = *this;
    200 	d = x * x + y * y;
    201 	if ( !d ) {
    202 		mat[1][0] = 1.0f;
    203 		mat[1][1] = 0.0f;
    204 		mat[1][2] = 0.0f;
    205 	} else {
    206 		d = idMath::InvSqrt( d );
    207 		mat[1][0] = -y * d;
    208 		mat[1][1] = x * d;
    209 		mat[1][2] = 0.0f;
    210 	}
    211 	mat[2] = Cross( mat[1] );
    212 
    213 	return mat;
    214 }
    215 
    216 /*
    217 =============
    218 idVec3::ToString
    219 =============
    220 */
    221 const char *idVec3::ToString( int precision ) const {
    222 	return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision );
    223 }
    224 
    225 /*
    226 =============
    227 Lerp
    228 
    229 Linearly inperpolates one vector to another.
    230 =============
    231 */
    232 void idVec3::Lerp( const idVec3 &v1, const idVec3 &v2, const float l ) {
    233 	if ( l <= 0.0f ) {
    234 		(*this) = v1;
    235 	} else if ( l >= 1.0f ) {
    236 		(*this) = v2;
    237 	} else {
    238 		(*this) = v1 + l * ( v2 - v1 );
    239 	}
    240 }
    241 
    242 /*
    243 =============
    244 SLerp
    245 
    246 Spherical linear interpolation from v1 to v2.
    247 Vectors are expected to be normalized.
    248 =============
    249 */
    250 #define LERP_DELTA 1e-6
    251 
    252 void idVec3::SLerp( const idVec3 &v1, const idVec3 &v2, const float t ) {
    253 	float omega, cosom, sinom, scale0, scale1;
    254 
    255 	if ( t <= 0.0f ) {
    256 		(*this) = v1;
    257 		return;
    258 	} else if ( t >= 1.0f ) {
    259 		(*this) = v2;
    260 		return;
    261 	}
    262 
    263 	cosom = v1 * v2;
    264 	if ( ( 1.0f - cosom ) > LERP_DELTA ) {
    265 		omega = acos( cosom );
    266 		sinom = sin( omega );
    267 		scale0 = sin( ( 1.0f - t ) * omega ) / sinom;
    268 		scale1 = sin( t * omega ) / sinom;
    269 	} else {
    270 		scale0 = 1.0f - t;
    271 		scale1 = t;
    272 	}
    273 
    274 	(*this) = ( v1 * scale0 + v2 * scale1 );
    275 }
    276 
    277 /*
    278 =============
    279 ProjectSelfOntoSphere
    280 
    281 Projects the z component onto a sphere.
    282 =============
    283 */
    284 void idVec3::ProjectSelfOntoSphere( const float radius ) {
    285 	float rsqr = radius * radius;
    286 	float len = Length();
    287 	if ( len  < rsqr * 0.5f ) {
    288 		z = sqrt( rsqr - len );
    289 	} else {
    290 		z = rsqr / ( 2.0f * sqrt( len ) );
    291 	}
    292 }
    293 
    294 
    295 
    296 //===============================================================
    297 //
    298 //	idVec4
    299 //
    300 //===============================================================
    301 
    302 /*
    303 =============
    304 idVec4::ToString
    305 =============
    306 */
    307 const char *idVec4::ToString( int precision ) const {
    308 	return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision );
    309 }
    310 
    311 /*
    312 =============
    313 Lerp
    314 
    315 Linearly inperpolates one vector to another.
    316 =============
    317 */
    318 void idVec4::Lerp( const idVec4 &v1, const idVec4 &v2, const float l ) {
    319 	if ( l <= 0.0f ) {
    320 		(*this) = v1;
    321 	} else if ( l >= 1.0f ) {
    322 		(*this) = v2;
    323 	} else {
    324 		(*this) = v1 + l * ( v2 - v1 );
    325 	}
    326 }
    327 
    328 
    329 //===============================================================
    330 //
    331 //	idVec5
    332 //
    333 //===============================================================
    334 
    335 /*
    336 =============
    337 idVec5::ToString
    338 =============
    339 */
    340 const char *idVec5::ToString( int precision ) const {
    341 	return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision );
    342 }
    343 
    344 /*
    345 =============
    346 idVec5::Lerp
    347 =============
    348 */
    349 void idVec5::Lerp( const idVec5 &v1, const idVec5 &v2, const float l ) {
    350 	if ( l <= 0.0f ) {
    351 		(*this) = v1;
    352 	} else if ( l >= 1.0f ) {
    353 		(*this) = v2;
    354 	} else {
    355 		x = v1.x + l * ( v2.x - v1.x );
    356 		y = v1.y + l * ( v2.y - v1.y );
    357 		z = v1.z + l * ( v2.z - v1.z );
    358 		s = v1.s + l * ( v2.s - v1.s );
    359 		t = v1.t + l * ( v2.t - v1.t );
    360 	}
    361 }
    362 
    363 
    364 //===============================================================
    365 //
    366 //	idVec6
    367 //
    368 //===============================================================
    369 
    370 /*
    371 =============
    372 idVec6::ToString
    373 =============
    374 */
    375 const char *idVec6::ToString( int precision ) const {
    376 	return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision );
    377 }