"L. Spiro Engine"

F:/My Projects/LSEngine/Modules/LSMathLib/Src/LSMMathLib.h

00001 
00026 #ifndef __LSM_MATHLIB_H__
00027 #define __LSM_MATHLIB_H__
00028 
00029 #include "LSSTDStandardLib.h"
00030 using namespace ::lsstd;
00031 
00032 #include <cassert>
00033 #include <cmath>
00034 #include "Fixed/LSMFixed.h"                     // Include the fixed-point class.
00035 
00036 #pragma warning( push )
00037 
00038 // warning C4127: conditional expression is constant
00039 #pragma warning( disable : 4127 )
00040 
00049 #define LSM_PERFORMANCE                         3
00050 
00051 
00052 
00053 
00054 
00055 // ========================================
00056 // Base type.
00057 // ========================================
00058 // The types of basics available.  This is just an enumeration.
00059 // This type is used in all vectors/matrices/etc.
00060 #define LSM_FLOAT                                       0
00061 #define LSM_DOUBLE                                      1
00062 #define LSM_FIXED                                       2
00063 // Now select one from the above list to actually be used.
00064 #ifndef LSM_BASETYPE
00065 #define LSM_BASETYPE                            LSM_FLOAT
00066 #endif  // #ifndef LSM_BASETYPE
00067 // ========================================
00068 
00069 
00070 // ========================================
00071 // Performance.
00072 // ========================================
00073 // The performance desired.  Certain calculations
00074 //      are modified depending on this, losing precision
00075 //      in favor of speed or vice-versa.
00076 // Values from 0 to 4 are allowed.
00077 //      0 = Fastest, but less accuracy.
00078 //      4 =     Slowest, but more accurate.
00079 #ifndef LSM_PERFORMANCE
00080 #define LSM_PERFORMANCE                         2
00081 #endif  // #ifndef LSM_PERFORMANCE
00082 // ========================================
00083 
00084 
00085 
00086 // Define all the constants.
00087 #include "LSMConstants.h"
00088 
00089 
00090 namespace lsm {
00091 
00092         // Create the basic type based on the LSM_BASETYPE macro.
00093         // LSREAL is the type we use throughout the engine for all math.
00094         // This also changes which cos(), sin(), etc. functions are used.
00095 #if LSM_BASETYPE == LSM_FLOAT
00096         typedef float                                   LSREAL;
00097         typedef double                                  LSREALHP;                       // High-precision type.
00098         // Cast from regular precision and high precision.
00099 #define LSREAL_TO_HP( VAL )                     (static_cast<LSREALHP>(VAL))
00100         // Cast from high-precision back to regular precision.
00101 #define HP_TO_LSREAL( VAL )                     (static_cast<LSREAL>(VAL))
00102 #define LSMCOS( F )                                     ::cosf( static_cast<LSREAL>(F) )
00103 #define LSMACOS( F )                            ::acosf( static_cast<LSREAL>(F) )
00104 #define LSMSIN( F )                                     ::sinf( static_cast<LSREAL>(F) )
00105 #define LSMASIN( F )                            ::asinf( static_cast<LSREAL>(F) )
00106 #define LSMSQRT( F )                            ::sqrtf( static_cast<LSREAL>(F) )
00107 #define LSMPOW( F, Q )                          ::powf( static_cast<LSREAL>(F), static_cast<LSREAL>(Q) )
00108 #define LSMLOG( F )                                     ::logf( static_cast<LSREAL>(F) )
00109 #define LSMEXP( F )                                     ::expf( static_cast<LSREAL>(F) )
00110 #define LSMABS( F )                                     ::fabsf( static_cast<LSREAL>(F) )
00111 #define LSMTAN( F )                                     ::tanf( static_cast<LSREAL>(F) )
00112 #define LSMATAN( F )                            ::atanf( static_cast<LSREAL>(F) )
00113 #define LSMATAN2F( Y, X )                       ::atan2f( static_cast<LSREAL>(Y), static_cast<LSREAL>(X) )
00114 #define LSMFMOD( Y, X )                         ::fmodf( static_cast<LSREAL>(Y), static_cast<LSREAL>(X) )
00115 #define LSMFLOOR( F )                           ::floorf( static_cast<LSREAL>(F) )
00116 #define LSMCEIL( F )                            ::ceilf( static_cast<LSREAL>(F) )
00117 
00118 #define LSMCOSHP( F )                           ::cos( static_cast<LSREALHP>(F) )
00119 #define LSMACOSHP( F )                          ::acos( static_cast<LSREALHP>(F) )
00120 #define LSMSINHP( F )                           ::sin( static_cast<LSREALHP>(F) )
00121 #define LSMASINHP( F )                          ::asin( static_cast<LSREALHP>(F) )
00122 #define LSMSQRTHP( F )                          ::sqrt( static_cast<LSREALHP>(F) )
00123 #define LSMPOWHP( F, Q )                        ::pow( static_cast<LSREALHP>(F), static_cast<LSREALHP>(Q) )
00124 #define LSMEXPHP( F )                           ::exp( static_cast<LSREALHP>(F) )
00125 #define LSMABSHP( F )                           ::fabs( static_cast<LSREALHP>(F) )
00126 #define LSMTANHP( F )                           ::tan( static_cast<LSREALHP>(F) )
00127 #define LSMATANHP( F )                          ::atan( static_cast<LSREALHP>(F) )
00128 #define LSMATAN2FHP( Y, X )                     ::atan2( static_cast<LSREALHP>(Y), static_cast<LSREALHP>(X) )
00129 #define LSMFMODHP( Y, X )                       ::fmod( static_cast<LSREALHP>(Y), static_cast<LSREALHP>(X) )
00130 #define LSMFLOORHP( F )                         ::floor( static_cast<LSREALHP>(F) )
00131 #define LSMCEILHP( F )                          ::ceil( static_cast<LSREALHP>(F) )
00132 #elif LSM_BASETYPE == LSM_DOUBLE
00133         typedef double                                  LSREAL;
00134         typedef long double                             LSREALHP;                       // High-precision type.
00135         // Cast from regular precision and high precision.
00136 #define LSREAL_TO_HP( VAL )                     (static_cast<LSREALHP>(VAL))
00137         // Cast from high-precision back to regular precision.
00138 #define HP_TO_LSREAL( VAL )                     (static_cast<LSREAL>(VAL))
00139 #define LSMCOS( F )                                     ::cos( static_cast<LSREAL>(F) )
00140 #define LSMACOS( F )                            ::acos( static_cast<LSREAL>(F) )
00141 #define LSMSIN( F )                                     ::sin( static_cast<LSREAL>(F) )
00142 #define LSMASIN( F )                            ::asin( static_cast<LSREAL>(F) )
00143 #define LSMSQRT( F )                            ::sqrt( static_cast<LSREAL>(F) )
00144 #define LSMPOW( F, Q )                          ::pow( static_cast<LSREAL>(F), static_cast<LSREAL>(Q) )
00145 #define LSMLOG( F )                                     ::log( static_cast<LSREAL>(F) )
00146 #define LSMEXP( F )                                     ::exp( static_cast<LSREAL>(F) )
00147 #define LSMABS( F )                                     ::fabs( static_cast<LSREAL>(F) )
00148 #define LSMTAN( F )                                     ::tan( static_cast<LSREAL>(F) )
00149 #define LSMATAN( F )                            ::atan( static_cast<LSREAL>(F) )
00150 #define LSMATAN2F( Y, X )                       ::atan2( static_cast<LSREAL>(Y), static_cast<LSREAL>(X) )
00151 #define LSMFMOD( Y, X )                         ::fmod( static_cast<LSREAL>(Y), static_cast<LSREAL>(X) )
00152 #define LSMFLOOR( F )                           ::floor( static_cast<LSREAL>(F) )
00153 #define LSMCEIL( F )                            ::ceil( static_cast<LSREAL>(F) )
00154 
00155 #define LSMCOSHP( F )                           ::cos( static_cast<LSREALHP>(F) )
00156 #define LSMACOSHP( F )                          ::acos( static_cast<LSREALHP>(F) )
00157 #define LSMSINHP( F )                           ::sin( static_cast<LSREALHP>(F) )
00158 #define LSMASINHP( F )                          ::asin( static_cast<LSREALHP>(F) )
00159 #define LSMSQRTHP( F )                          ::sqrt( static_cast<LSREALHP>(F) )
00160 #define LSMPOWHP( F, Q )                        ::pow( static_cast<LSREALHP>(F), static_cast<LSREALHP>(Q) )
00161 #define LSMEXPHP( F )                           ::exp( static_cast<LSREALHP>(F) )
00162 #define LSMABSHP( F )                           ::fabs( static_cast<LSREALHP>(F) )
00163 #define LSMTANHP( F )                           ::tan( static_cast<LSREALHP>(F) )
00164 #define LSMATANHP( F )                          ::atan( static_cast<LSREALHP>(F) )
00165 #define LSMATAN2FHP( Y, X )                     ::atan2( static_cast<LSREALHP>(Y), static_cast<LSREALHP>(X) )
00166 #define LSMFMODHP( Y, X )                       ::fmod( static_cast<LSREALHP>(Y), static_cast<LSREALHP>(X) )
00167 #define LSMFLOORHP( F )                         ::floor( static_cast<LSREALHP>(F) )
00168 #define LSMCEILHP( F )                          ::ceil( static_cast<LSREALHP>(F) )
00169 #elif LSM_BASETYPE == LSM_FIXED
00170         typedef CFixed<LSINT32, 10>             LSREAL;
00171         typedef CFixed<LSINT64, 24>             LSREALHP;                       // High-precision type.
00172 // Cast from regular precision to high precision.
00173 #define LSREAL_TO_HP( VAL )                     (LSREALHP( LSREALHP::CFixedRawType( (VAL).GetRawValue() << (LSREALHP::Bits() - LSREAL::Bits()) ) ))
00174 // Cast from high-precision back to regular precision.
00175 #define HP_TO_LSREAL( VAL )                     (LSREAL( LSREAL::CFixedRawType( LSREAL::Cast( (VAL).GetRawValue() >> (LSREALHP::Bits() - LSREAL::Bits()) ) ) ))
00176 #define LSMCOS( F )                                     static_cast<LSREAL>(::cosf( static_cast<LSFLOAT>(F) ))
00177 #define LSMACOS( F )                            static_cast<LSREAL>(::acosf( static_cast<LSFLOAT>(F) ))
00178 #define LSMSIN( F )                                     static_cast<LSREAL>(::sinf( static_cast<LSFLOAT>(F) ))
00179 #define LSMASIN( F )                            static_cast<LSREAL>(::asinf( static_cast<LSFLOAT>(F) ))
00180 #define LSMSQRT( F )                            static_cast<LSREAL>(::sqrtf( static_cast<LSFLOAT>(F) ))
00181 #define LSMPOW( F, Q )                          static_cast<LSREAL>(::powf( static_cast<LSFLOAT>(F), static_cast<LSFLOAT>(Q) ))
00182 #define LSMLOG( F )                                     static_cast<LSREAL>(::log( static_cast<LSREAL>(F) ))
00183 #define LSMEXP( F )                                     static_cast<LSREAL>(::expf( static_cast<LSFLOAT>(F) ))
00184 #define LSMABS( F )                                     static_cast<LSREAL>(::fabs( static_cast<LSFLOAT>(F) ))
00185 #define LSMTAN( F )                                     static_cast<LSREAL>(::tanf( static_cast<LSFLOAT>(F) ))
00186 #define LSMATAN( F )                            static_cast<LSREAL>(::atanf( static_cast<LSFLOAT>(F) ))
00187 #define LSMATAN2F( Y, X )                       static_cast<LSREAL>(::atan2f( static_cast<LSFLOAT>(Y), static_cast<LSFLOAT>(X) ))
00188 #define LSMFMOD( Y, X )                         static_cast<LSREAL>(::fmodf( static_cast<LSFLOAT>(Y), static_cast<LSFLOAT>(X) ))
00189 #define LSMFLOOR( F )                           static_cast<LSREAL>(::floorf( static_cast<LSFLOAT>(F) ))
00190 #define LSMCEIL( F )                            static_cast<LSREAL>(::ceilf( static_cast<LSFLOAT>(F) ))
00191 
00192 #define LSMCOSHP( F )                           static_cast<LSREALHP>(::cos( static_cast<LSMDOUBLE>(F) ))
00193 #define LSMACOSHP( F )                          static_cast<LSREALHP>(::acos( static_cast<LSMDOUBLE>(F) ))
00194 #define LSMSINHP( F )                           static_cast<LSREALHP>(::sin( static_cast<LSMDOUBLE>(F) ))
00195 #define LSMASINHP( F )                          static_cast<LSREALHP>(::asin( static_cast<LSMDOUBLE>(F) ))
00196 #define LSMSQRTHP( F )                          static_cast<LSREALHP>(::sqrt( static_cast<LSMDOUBLE>(F) ))
00197 #define LSMPOWHP( F, Q )                        static_cast<LSREALHP>(::pow( static_cast<LSMDOUBLE>(F), static_cast<LSMDOUBLE>(Q) ))
00198 #define LSMEXPHP( F )                           static_cast<LSREALHP>(::exp( static_cast<LSMDOUBLE>(F) ))
00199 #define LSMABSHP( F )                           static_cast<LSREALHP>(::fabs( static_cast<LSMDOUBLE>(F) ))
00200 #define LSMTANHP( F )                           static_cast<LSREALHP>(::tan( static_cast<LSMDOUBLE>(F) ))
00201 #define LSMATANHP( F )                          static_cast<LSREALHP>(::atan( static_cast<LSMDOUBLE>(F) ))
00202 #define LSMATAN2FHP( Y, X )                     static_cast<LSREALHP>(::atan2( static_cast<LSMDOUBLE>(Y), static_cast<LSMDOUBLE>(X) ))
00203 #define LSMFMODHP( Y, X )                       static_cast<LSREALHP>(::fmod( static_cast<LSMDOUBLE>(Y), static_cast<LSMDOUBLE>(X) ))
00204 #define LSMFLOORHP( F )                         static_cast<LSREALHP>(::floor( static_cast<LSMDOUBLE>(F) ))
00205 #define LSMCEILHP( F )                          static_cast<LSREALHP>(::ceil( static_cast<LSMDOUBLE>(F) ))
00206 #else
00207 #error "LSM_BASETYPE must be set to LSM_FLOAT, LSM_DOUBLE, or LSM_FIXED."
00208 #endif  // LSM_BASETYPE
00209 
00210 
00227         class CMathLib {
00228         public :
00233                 static LSVOID LSE_FCALL         Init();
00234 
00235 
00236                 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00237                 // Math functions, built either for speed or for power, depending on the
00238                 //      LSM_PERFORMANCE macro.
00239                 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00243                 static LSREAL LSE_FCALL         InvSqrt( LSREAL _fX );
00244 
00248                 static LSREAL LSE_FCALL         Sqrt( LSREAL _fX );
00249 
00253                 static LSREAL LSE_FCALL         Sin( LSREAL _fX );
00254 
00258                 static LSREAL LSE_FCALL         Cos( LSREAL _fX );
00259 
00263                 static LSVOID LSE_FCALL         SinCos( LSREAL _fA, LSREAL &_fSine, LSREAL &_fCosine );
00264 
00268                 static LSREAL LSE_FCALL         Tan( LSREAL _fX );
00269 
00273                 static LSREAL LSE_FCALL         ASin( LSREAL _fX );
00274 
00278                 static LSREAL LSE_FCALL         ACos( LSREAL _fX );
00279 
00283                 static LSREAL LSE_FCALL         ATan( LSREAL _fX );
00284 
00288                 static LSREAL LSE_FCALL         ATan( LSREAL _fY, LSREAL _fX );
00289 
00293                 static LSREAL LSE_FCALL         Pow( LSREAL _fX, LSREAL _fY );
00294 
00298                 static LSREAL LSE_FCALL         Exp( LSREAL _fX );
00299 
00307                 static LSREAL LSE_FCALL         Log( LSREAL _fX, LSREAL _fY );
00308 
00312                 static LSREAL LSE_FCALL         Abs( LSREAL _fX );
00313 
00317                 template <typename _tType>
00318                 static _tType LSE_FCALL         AbsT( _tType _fX );
00319 
00323                 static LSBOOL LSE_FCALL         SameSign( LSREAL _fLeft, LSREAL _fRight );
00324 
00328                 static LSREAL LSE_FCALL         FMod( LSREAL _fX, LSREAL _fMod );
00329 
00333                 static LSREAL LSE_FCALL         Floor( LSREAL _fX );
00334 
00341                 static LSREAL LSE_FCALL         Ceil( LSREAL _fX );
00342 
00346                 template <typename _tType>
00347                 static _tType LSE_FCALL         Max( _tType _fX, _tType _fY );
00348 
00352                 template <typename _tType>
00353                 static _tType LSE_FCALL         Min( _tType _fX, _tType _fY );
00354 
00361                 template <typename _tType>
00362                 static LSVOID LSE_FCALL         Swap( LSE_UNALIGNED _tType &_fLeft, LSE_UNALIGNED _tType &_fRight );
00363 
00372                 template <typename _tType>
00373                 static _tType LSE_FCALL         Clamp( _tType _fValue, _tType _fLow, _tType _fHigh );
00374 
00383                 static LSBOOL LSE_FCALL         Equals( LSREAL _fX, LSREAL _fY, LSREAL _fEpsilon );
00384 
00393                 template <typename _tType>
00394                 static LSBOOL LSE_FCALL         EqualsT( _tType _fX, _tType _fY, _tType _fEpsilon );
00395 
00396         protected :
00397 #if LSM_BASETYPE == LSM_FLOAT || LSM_BASETYPE == LSM_DOUBLE
00398                 union LSM_FLINT {
00399                         LSUINT32                                ui32Int;
00400                         LSREAL                                  fReal;
00401                 };
00402 #endif  // #if LSM_BASETYPE == LSM_FLOAT || LSM_BASETYPE == LSM_DOUBLE
00403 
00407                 static LSBOOL                           m_bInitialized;
00408 
00409                 
00410 
00411 #if LSM_PERFORMANCE <= 2
00412                 // We have tables for fast cosine and sine look-up if performance
00413                 //      is desired.
00414                 // If you change the table size you must also change the LSMCOS_F() and LSMSIN_F() macros.
00415                 //      Currently they rely on this size to save time by casting the value to LSUINT16
00416                 //      (preventing array overflow).  You can change LSM_TABLESIZE, but you may have
00417                 //      to add a % operator for array sanity, which will be slower.
00418 #define LSM_TABLESIZE                           (0xFFFF+1)
00419                 static LSREAL                           m_fCosTable[LSM_TABLESIZE];
00420                 static LSREAL                           m_fSinTable[LSM_TABLESIZE];
00421 
00422                 // Easily change between the look-up table and the real value.
00423 #define LSMCOS_F( F )                           m_fCosTable[static_cast<LSUINT16>(static_cast<LSFLOAT>(1.0/(LSM_PI_DOUBLE*2.0)*LSM_TABLESIZE)*(F))]
00424 #define LSMSIN_F( F )                           m_fSinTable[static_cast<LSUINT16>(static_cast<LSFLOAT>(1.0/(LSM_PI_DOUBLE*2.0)*LSM_TABLESIZE)*(F))]
00425 #else
00426 #define LSMCOS_F( F )                           LSMCOS( F )
00427 #define LSMSIN_F( F )                           LSMSIN( F )
00428 #endif  // LSM_PERFORMANCE <= 2
00429         };
00430 
00431 
00432         // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00433         // DEFINITIONS
00434         // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00435         // == Functions.
00439         LSE_INLINE LSREAL LSE_FCALL CMathLib::InvSqrt( LSREAL _fX ) {
00440 #if LSM_BASETYPE == LSM_FLOAT
00441 #if defined( LSE_GCC )
00442                 // Strange problem with these machines.  Maybe they should upgrade their FPU's.
00443                 if ( _fX == LSM_ZERO ) {
00444                         return (LSM_INFINITY * static_cast<LSREAL>(0.25));
00445                 }
00446 #endif  // #if defined( LSE_GCC )
00447                 LSFLOAT fY, fR;
00448                 union {
00449                         LSFLOAT fVal;
00450                         LSINT32 i32Val;
00451                 } uVal;
00452 
00453                 uVal.fVal = _fX;
00454 
00455                 fY = _fX * LSM_HALF;
00456                 uVal.i32Val = /*0x5F375A86*/0x5F3759DF - (uVal.i32Val >> 1);
00457                 fR = uVal.fVal * (1.5f - uVal.fVal * uVal.fVal * fY);
00458                 fR = fR * (1.5f - fR * fR * fY);
00459 
00460                 // More accuracy?
00461 #if LSM_PERFORMANCE >= 3
00462                 fR = fR * (1.5f - fR * fR * fY);
00463 #endif  // #if LSM_PERFORMANCE >= 3
00464 
00465                 // Even MORE accuracy?
00466 #if LSM_PERFORMANCE >= 4
00467                 fR = fR * (1.5f - fR * fR * fY);
00468 #endif  // #if LSM_PERFORMANCE >= 4
00469                 return static_cast<LSREAL>(fR);
00470 #else   // #if LSM_BASETYPE == LSM_FLOAT
00471                 return static_cast<LSREAL>(1.0f / ::sqrtf( static_cast<LSFLOAT>(_fX) ));
00472 #endif  // #if LSM_BASETYPE == LSM_FLOAT
00473         }
00474 
00478         LSE_INLINE LSREAL LSE_FCALL CMathLib::Sqrt( LSREAL _fX ) {
00479 #if LSM_BASETYPE == LSM_FLOAT
00480                 return _fX * InvSqrt( _fX );
00481 #else   // #if LSM_BASETYPE == LSM_FLOAT
00482                 return LSMSQRT( _fX );
00483 #endif  // #if LSM_BASETYPE == LSM_FLOAT
00484         }
00485 
00489         LSE_INLINE LSREAL LSE_FCALL CMathLib::Sin( LSREAL _fX ) {
00490                 return LSMSIN_F( _fX );
00491         }
00492 
00496         LSE_INLINE LSREAL LSE_FCALL CMathLib::Cos( LSREAL _fX ) {
00497                 return LSMCOS_F( _fX );
00498         }
00499 
00503         LSE_INLINE LSVOID LSE_FCALL CMathLib::SinCos( LSREAL _fA, LSREAL &_fSine, LSREAL &_fCosine ) {
00504 #if LSM_PERFORMANCE <= 2
00505                 _fCosine = Cos( _fA );
00506                 _fSine = Sin( _fA );
00507 #else   // #if LSM_PERFORMANCE <= 2
00508 #if defined( LSE_X86 ) && (LSM_BASETYPE == LSM_FLOAT || LSM_BASETYPE == LSM_DOUBLE)
00509                 LSE_ASM_BEGIN
00510                         fld             _fA
00511                         fsincos
00512                         mov             ecx, _fCosine
00513                         mov             edx, _fSine
00514 #if LSM_BASETYPE == LSM_FLOAT
00515                         fstp    dword ptr [ecx]
00516                         fstp    dword ptr [edx]
00517 #elif LSM_BASETYPE == LSM_DOUBLE
00518                         fstp    qword ptr [ecx]
00519                         fstp    qword ptr [edx]
00520 #endif  // #if LSM_BASETYPE == LSM_FLOAT
00521                 LSE_ASM_END
00522 #else   // #if defined( LSE_X86 ) && (LSM_BASETYPE == LSM_FLOAT || LSM_BASETYPE == LSM_DOUBLE)
00523                 _fCosine = Cos( _fA );
00524                 _fSine = Sin( _fA );
00525 #endif  // #if defined( LSE_X86 ) && (LSM_BASETYPE == LSM_FLOAT || LSM_BASETYPE == LSM_DOUBLE)
00526 #endif  // #if LSM_PERFORMANCE <= 2
00527         }
00528 
00532         LSE_INLINE LSREAL LSE_FCALL CMathLib::Tan( LSREAL _fX ) {
00533                 return LSMTAN( _fX );
00534         }
00535 
00539         LSE_INLINE LSREAL LSE_FCALL CMathLib::ASin( LSREAL _fX ) {
00540                 if ( _fX <= static_cast<LSREAL>(-1.0) ) { return -LSM_HALFPI; }
00541                 if ( _fX >= LSM_ONE ) { return LSM_HALFPI; }
00542                 return LSMASIN( _fX );
00543         }
00544 
00548         LSE_INLINE LSREAL LSE_FCALL CMathLib::ACos( LSREAL _fX ) {
00549                 if ( _fX <= static_cast<LSREAL>(-1.0) ) { return LSM_PI; }
00550                 if ( _fX >= LSM_ONE ) { return LSM_ZERO; }
00551                 return LSMACOS( _fX );
00552         }
00553 
00557         LSE_INLINE LSREAL LSE_FCALL CMathLib::ATan( LSREAL _fX ) {
00558                 return LSMATAN( _fX );
00559         }
00560 
00564         LSE_INLINE LSREAL LSE_FCALL CMathLib::ATan( LSREAL _fY, LSREAL _fX ) {
00565                 return LSMATAN2F( _fY, _fX );
00566         }
00567 
00571         LSE_INLINE LSREAL LSE_FCALL CMathLib::Pow( LSREAL _fX, LSREAL _fY ) {
00572                 return LSMPOW( _fX, _fY );
00573         }
00574 
00578         LSE_INLINE LSREAL LSE_FCALL CMathLib::Exp( LSREAL _fX ) {
00579                 return LSMEXP( _fX );
00580         }
00581 
00589         LSE_INLINE LSREAL LSE_FCALL CMathLib::Log( LSREAL _fX, LSREAL _fY ) {
00590                 return LSMLOG( _fX ) / LSMLOG( _fY );
00591         }
00592 
00596         LSE_INLINE LSREAL LSE_FCALL CMathLib::Abs( LSREAL _fX ) {
00597 #if LSM_BASETYPE == LSM_FIXED
00598                 return LSREAL::CFixedRawType( (_fX.GetRawValue() & LSREAL::SignMask()) ? (0 - _fX.GetRawValue()) : _fX.GetRawValue() );
00599 #else   // #if LSM_BASETYPE == LSM_FIXED
00600                 return LSMABS( _fX );
00601 #endif  // #if LSM_BASETYPE == LSM_FIXED
00602         }
00603 
00607         template <typename _tType>
00608         _tType LSE_FCALL CMathLib::AbsT( _tType _fX ) {
00609                 return _fX < static_cast<_tType>(0.0) ? -_fX : _fX;
00610         }
00611 
00615         LSE_INLINE LSBOOL LSE_FCALL CMathLib::SameSign( LSREAL _fLeft, LSREAL _fRight ) {
00616 #if LSM_BASETYPE == LSM_FLOAT
00617                 return ((*reinterpret_cast<LSUINT32 *>(&_fLeft)) & 0x80000000) ==
00618                         ((*reinterpret_cast<LSUINT32 *>(&_fRight)) & 0x80000000);
00619 #elif LSM_BASETYPE == LSM_DOUBLE
00620                 return ((*reinterpret_cast<LSUINT64 *>(&_fLeft)) & 0x8000000000000000ULL) ==
00621                         ((*reinterpret_cast<LSUINT64 *>(&_fRight)) & 0x8000000000000000ULL);
00622 #elif LSM_BASETYPE == LSM_FIXED
00623                 return (_fLeft.GetRawValue() & LSREAL::SignMask()) == (_fRight.GetRawValue() & LSREAL::SignMask());
00624 #else   // #if LSM_BASETYPE == LSM_FLOAT
00625                 return (_fLeft >= LSM_ZERO && _fRight >= LSM_ZERO) ||
00626                         (_fLeft < LSM_ZERO && _fRight < LSM_ZERO);
00627 #endif  // #if LSM_BASETYPE == LSM_FLOAT
00628         }
00629 
00633         LSE_INLINE LSREAL LSE_FCALL CMathLib::FMod( LSREAL _fX, LSREAL _fMod ) {
00634 #if LSM_BASETYPE == LSM_FIXED
00635                 return LSREAL::CFixedRawType( _fX.GetRawValue() % _fMod.GetRawValue() );
00636 #else   // #if LSM_BASETYPE == LSM_FIXED
00637                 return LSMFMOD( _fX, _fMod );
00638 #endif  // #if LSM_BASETYPE == LSM_FIXED
00639         }
00640 
00644         LSE_INLINE LSREAL LSE_FCALL CMathLib::Floor( LSREAL _fX ) {
00645                 return LSMFLOOR( _fX );
00646         }
00647 
00654         LSE_INLINE LSREAL LSE_FCALL CMathLib::Ceil( LSREAL _fX ) {
00655                 return LSMCEIL( _fX );
00656         }
00657 
00661         template <typename _tType>
00662         _tType LSE_FCALL CMathLib::Max( _tType _fX, _tType _fY ) {
00663                 return _fX > _fY ? _fX : _fY;
00664         }
00665 
00669         template <typename _tType>
00670         _tType LSE_FCALL CMathLib::Min( _tType _fX, _tType _fY ) {
00671                 return _fX < _fY ? _fX : _fY;
00672         }
00673 
00680         template <typename _tType>
00681         LSVOID LSE_FCALL CMathLib::Swap( LSE_UNALIGNED _tType &_fLeft, LSE_UNALIGNED _tType &_fRight ) {
00682                 _tType fTemp = _fLeft;
00683                 _fLeft = _fRight;
00684                 _fRight = fTemp;
00685         }
00686 
00695         template <typename _tType>
00696         _tType LSE_FCALL CMathLib::Clamp( _tType _fValue, _tType _fLow, _tType _fHigh ) {
00697                 if ( _fValue < _fLow ) { return _fLow; }
00698                 return (_fValue > _fHigh) ? _fHigh : _fValue;
00699         }
00700 
00709         LSE_INLINE LSBOOL LSE_FCALL CMathLib::Equals( LSREAL _fX, LSREAL _fY, LSREAL _fEpsilon ) {
00710                 LSREAL fMax = CMathLib::Max( CMathLib::Abs( _fX ), CMathLib::Abs( _fY ) );
00711                 return CMathLib::Abs( _fX - _fY ) <= _fEpsilon * CMathLib::Max( fMax, LSM_ONE );
00712         }
00713 
00722         template <typename _tType>
00723         LSBOOL LSE_FCALL CMathLib::EqualsT( _tType _fX, _tType _fY, _tType _fEpsilon ) {
00724                 _tType fMax = CMathLib::Max<_tType>( CMathLib::AbsT( _fX ), CMathLib::AbsT( _fY ) );
00725                 return CMathLib::AbsT( _fX - _fY ) <= _fEpsilon * CMathLib::Max<_tType>( fMax, _tType( 1 ) );
00726         }
00727 
00728 }       // namespace lsm
00729 
00730 #pragma warning( pop )
00731 
00732 #endif  // __LSM_MATHLIB_H__
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator