DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

Math.cpp (6391B)


      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 const int SMALLEST_NON_DENORMAL					= 1<<IEEE_FLT_MANTISSA_BITS;
     33 const int NAN_VALUE								= 0x7f800000;
     34 
     35 const float	idMath::PI				= 3.14159265358979323846f;
     36 const float	idMath::TWO_PI			= 2.0f * PI;
     37 const float	idMath::HALF_PI			= 0.5f * PI;
     38 const float	idMath::ONEFOURTH_PI	= 0.25f * PI;
     39 const float idMath::ONEOVER_PI		= 1.0f / idMath::PI;
     40 const float idMath::ONEOVER_TWOPI	= 1.0f / idMath::TWO_PI;
     41 const float idMath::E				= 2.71828182845904523536f;
     42 const float idMath::SQRT_TWO		= 1.41421356237309504880f;
     43 const float idMath::SQRT_THREE		= 1.73205080756887729352f;
     44 const float	idMath::SQRT_1OVER2		= 0.70710678118654752440f;
     45 const float	idMath::SQRT_1OVER3		= 0.57735026918962576450f;
     46 const float	idMath::M_DEG2RAD		= PI / 180.0f;
     47 const float	idMath::M_RAD2DEG		= 180.0f / PI;
     48 const float	idMath::M_SEC2MS		= 1000.0f;
     49 const float	idMath::M_MS2SEC		= 0.001f;
     50 const float	idMath::INFINITY		= 1e30f;
     51 const float idMath::FLT_EPSILON		= 1.192092896e-07f;
     52 const float idMath::FLT_SMALLEST_NON_DENORMAL	= * reinterpret_cast< const float * >( & SMALLEST_NON_DENORMAL );	// 1.1754944e-038f
     53 
     54 #if defined( ID_WIN_X86_SSE_INTRIN )
     55 const __m128 idMath::SIMD_SP_zero				= { 0.0f, 0.0f, 0.0f, 0.0f };
     56 const __m128 idMath::SIMD_SP_255				= { 255.0f, 255.0f, 255.0f, 255.0f };
     57 const __m128 idMath::SIMD_SP_min_char			= { -128.0f, -128.0f, -128.0f, -128.0f };
     58 const __m128 idMath::SIMD_SP_max_char			= { 127.0f, 127.0f, 127.0f, 127.0f };
     59 const __m128 idMath::SIMD_SP_min_short			= { -32768.0f, -32768.0f, -32768.0f, -32768.0f };
     60 const __m128 idMath::SIMD_SP_max_short			= { 32767.0f, 32767.0f, 32767.0f, 32767.0f };
     61 const __m128 idMath::SIMD_SP_smallestNonDenorm	= { FLT_SMALLEST_NON_DENORMAL, FLT_SMALLEST_NON_DENORMAL, FLT_SMALLEST_NON_DENORMAL, FLT_SMALLEST_NON_DENORMAL };
     62 const __m128 idMath::SIMD_SP_tiny				= { 1e-4f, 1e-4f, 1e-4f, 1e-4f };
     63 const __m128 idMath::SIMD_SP_rsqrt_c0			= { 3.0f, 3.0f, 3.0f, 3.0f };
     64 const __m128 idMath::SIMD_SP_rsqrt_c1			= { -0.5f, -0.5f, -0.5f, -0.5f };
     65 #endif
     66 
     67 bool		idMath::initialized		= false;
     68 dword		idMath::iSqrt[SQRT_TABLE_SIZE];		// inverse square root lookup table
     69 
     70 /*
     71 ===============
     72 idMath::Init
     73 ===============
     74 */
     75 void idMath::Init() {
     76     union _flint fi, fo;
     77 
     78     for ( int i = 0; i < SQRT_TABLE_SIZE; i++ ) {
     79         fi.i	 = ((EXP_BIAS-1) << EXP_POS) | (i << LOOKUP_POS);
     80         fo.f	 = (float)( 1.0 / sqrt( fi.f ) );
     81         iSqrt[i] = ((dword)(((fo.i + (1<<(SEED_POS-2))) >> SEED_POS) & 0xFF))<<SEED_POS;
     82     }
     83     
     84 	iSqrt[SQRT_TABLE_SIZE / 2] = ((dword)(0xFF))<<(SEED_POS); 
     85 
     86 	initialized = true;
     87 }
     88 
     89 /*
     90 ================
     91 idMath::FloatToBits
     92 ================
     93 */
     94 int idMath::FloatToBits( float f, int exponentBits, int mantissaBits ) {
     95 	int i, sign, exponent, mantissa, value;
     96 
     97 	assert( exponentBits >= 2 && exponentBits <= 8 );
     98 	assert( mantissaBits >= 2 && mantissaBits <= 23 );
     99 
    100 	int maxBits = ( ( ( 1 << ( exponentBits - 1 ) ) - 1 ) << mantissaBits ) | ( ( 1 << mantissaBits ) - 1 );
    101 	int minBits = ( ( ( 1 <<   exponentBits       ) - 2 ) << mantissaBits ) | 1;
    102 
    103 	float max = BitsToFloat( maxBits, exponentBits, mantissaBits );
    104 	float min = BitsToFloat( minBits, exponentBits, mantissaBits );
    105 
    106 	if ( f >= 0.0f ) {
    107 		if ( f >= max ) {
    108 			return maxBits;
    109 		} else if ( f <= min ) {
    110 			return minBits;
    111 		}
    112 	} else {
    113 		if ( f <= -max ) {
    114 			return ( maxBits | ( 1 << ( exponentBits + mantissaBits ) ) );
    115 		} else if ( f >= -min ) {
    116 			return ( minBits | ( 1 << ( exponentBits + mantissaBits ) ) );
    117 		}
    118 	}
    119 
    120 	exponentBits--;
    121 	i = *reinterpret_cast<int *>(&f);
    122 	sign = ( i >> IEEE_FLT_SIGN_BIT ) & 1;
    123 	exponent = ( ( i >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS;
    124 	mantissa = i & ( ( 1 << IEEE_FLT_MANTISSA_BITS ) - 1 );
    125 	value = sign << ( 1 + exponentBits + mantissaBits );
    126 	value |= ( ( INT32_SIGNBITSET( exponent ) << exponentBits ) | ( abs( exponent ) & ( ( 1 << exponentBits ) - 1 ) ) ) << mantissaBits;
    127 	value |= mantissa >> ( IEEE_FLT_MANTISSA_BITS - mantissaBits );
    128 	return value;
    129 }
    130 
    131 /*
    132 ================
    133 idMath::BitsToFloat
    134 ================
    135 */
    136 float idMath::BitsToFloat( int i, int exponentBits, int mantissaBits ) {
    137 	static int exponentSign[2] = { 1, -1 };
    138 	int sign, exponent, mantissa, value;
    139 
    140 	assert( exponentBits >= 2 && exponentBits <= 8 );
    141 	assert( mantissaBits >= 2 && mantissaBits <= 23 );
    142 
    143 	exponentBits--;
    144 	sign = i >> ( 1 + exponentBits + mantissaBits );
    145 	exponent = ( ( i >> mantissaBits ) & ( ( 1 << exponentBits ) - 1 ) ) * exponentSign[( i >> ( exponentBits + mantissaBits ) ) & 1];
    146 	mantissa = ( i & ( ( 1 << mantissaBits ) - 1 ) ) << ( IEEE_FLT_MANTISSA_BITS - mantissaBits );
    147 	value = sign << IEEE_FLT_SIGN_BIT | ( exponent + IEEE_FLT_EXPONENT_BIAS ) << IEEE_FLT_MANTISSA_BITS | mantissa;
    148 	return *reinterpret_cast<float *>(&value);
    149 }