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 }