mirror of
https://github.com/KevinMidboe/linguist.git
synced 2025-10-29 17:50:22 +00:00
C++ .inl file extension
This commit is contained in:
530
samples/C++/Math.inl
Normal file
530
samples/C++/Math.inl
Normal file
@@ -0,0 +1,530 @@
|
||||
/*
|
||||
===========================================================================
|
||||
The Open Game Libraries.
|
||||
Copyright (C) 2007-2010 Lusito Software
|
||||
|
||||
Author: Santo Pfingsten (TTK-Bandit)
|
||||
Purpose: Math namespace
|
||||
-----------------------------------------
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __OG_MATH_INL__
|
||||
#define __OG_MATH_INL__
|
||||
|
||||
namespace og {
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
Math
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Abs
|
||||
================
|
||||
*/
|
||||
OG_INLINE int Math::Abs( int i ) {
|
||||
#if 1
|
||||
if ( i & 0x80000000 )
|
||||
return 0x80000000 - (i & MASK_SIGNED);
|
||||
return i;
|
||||
#else
|
||||
int y = x >> 31;
|
||||
return ( ( x ^ y ) - y );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Fabs
|
||||
================
|
||||
*/
|
||||
OG_INLINE float Math::Fabs( float f ) {
|
||||
#if 1
|
||||
uInt *pf = reinterpret_cast<uInt*>(&f);
|
||||
*(pf) &= MASK_SIGNED;
|
||||
return f;
|
||||
#else
|
||||
return fabsf( f );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Round
|
||||
================
|
||||
*/
|
||||
OG_INLINE float Math::Round( float f ) {
|
||||
return floorf( f + 0.5f );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Floor
|
||||
================
|
||||
*/
|
||||
OG_INLINE float Math::Floor( float f ) {
|
||||
return floorf( f );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Ceil
|
||||
================
|
||||
*/
|
||||
OG_INLINE float Math::Ceil( float f ) {
|
||||
return ceilf( f );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Ftoi
|
||||
|
||||
ok since this is SSE, why should the other ftoi be the faster one ?
|
||||
and: we might need to add a check for SSE extensions..
|
||||
because sse isn't *really* faster (I actually read that GCC does not handle
|
||||
SSE extensions perfectly. I'll find the link and send it to you when you're online)
|
||||
================
|
||||
*/
|
||||
OG_INLINE int Math::Ftoi( float f ) {
|
||||
//! @todo needs testing
|
||||
// note: sse function cvttss2si
|
||||
#if OG_ASM_MSVC
|
||||
int i;
|
||||
#if defined(OG_FTOI_USE_SSE)
|
||||
if( SysInfo::cpu.general.SSE ) {
|
||||
__asm cvttss2si eax, f
|
||||
__asm mov i, eax
|
||||
return i;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
__asm fld f
|
||||
__asm fistp i
|
||||
//__asm mov eax, i // do we need this ? O_o
|
||||
}
|
||||
return i;
|
||||
#elif OG_ASM_GNU
|
||||
int i;
|
||||
#if defined(OG_FTOI_USE_SSE)
|
||||
if( SysInfo::cpu.general.SSE ) {
|
||||
__asm__ __volatile__( "cvttss2si %1 \n\t"
|
||||
: "=m" (i)
|
||||
: "m" (f)
|
||||
);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
__asm__ __volatile__( "flds %1 \n\t"
|
||||
"fistpl %0 \n\t"
|
||||
: "=m" (i)
|
||||
: "m" (f)
|
||||
);
|
||||
}
|
||||
return i;
|
||||
#else
|
||||
// we use c++ cast instead of c cast (not sure why id did that)
|
||||
return static_cast<int>(f);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::FtoiFast
|
||||
================
|
||||
*/
|
||||
OG_INLINE int Math::FtoiFast( float f ) {
|
||||
#if OG_ASM_MSVC
|
||||
int i;
|
||||
__asm fld f
|
||||
__asm fistp i
|
||||
//__asm mov eax, i // do we need this ? O_o
|
||||
return i;
|
||||
#elif OG_ASM_GNU
|
||||
int i;
|
||||
__asm__ __volatile__( "flds %1 \n\t"
|
||||
"fistpl %0 \n\t"
|
||||
: "=m" (i)
|
||||
: "m" (f)
|
||||
);
|
||||
return i;
|
||||
#else
|
||||
// we use c++ cast instead of c cast (not sure why id did that)
|
||||
return static_cast<int>(f);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Ftol
|
||||
================
|
||||
*/
|
||||
OG_INLINE long Math::Ftol( float f ) {
|
||||
#if OG_ASM_MSVC
|
||||
long i;
|
||||
__asm fld f
|
||||
__asm fistp i
|
||||
//__asm mov eax, i // do we need this ? O_o
|
||||
return i;
|
||||
#elif OG_ASM_GNU
|
||||
long i;
|
||||
__asm__ __volatile__( "flds %1 \n\t"
|
||||
"fistpl %0 \n\t"
|
||||
: "=m" (i)
|
||||
: "m" (f)
|
||||
);
|
||||
return i;
|
||||
#else
|
||||
// we use c++ cast instead of c cast (not sure why id did that)
|
||||
return static_cast<long>(f);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Sign
|
||||
================
|
||||
*/
|
||||
OG_INLINE float Math::Sign( float f ) {
|
||||
if ( f > 0.0f )
|
||||
return 1.0f;
|
||||
if ( f < 0.0f )
|
||||
return -1.0f;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Fmod
|
||||
================
|
||||
*/
|
||||
OG_INLINE float Math::Fmod( float numerator, float denominator ) {
|
||||
return fmodf( numerator, denominator );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Modf
|
||||
================
|
||||
*/
|
||||
OG_INLINE float Math::Modf( float f, float& i ) {
|
||||
return modff( f, &i );
|
||||
}
|
||||
OG_INLINE float Math::Modf( float f ) {
|
||||
float i;
|
||||
return modff( f, &i );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Sqrt
|
||||
================
|
||||
*/
|
||||
OG_INLINE float Math::Sqrt( float f ) {
|
||||
return sqrtf( f );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::InvSqrt
|
||||
|
||||
Cannot be 0.0f
|
||||
================
|
||||
*/
|
||||
OG_INLINE float Math::InvSqrt( float f ) {
|
||||
OG_ASSERT( f != 0.0f );
|
||||
return 1.0f / sqrtf( f );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::RSqrt
|
||||
|
||||
Can be 0.0f
|
||||
================
|
||||
*/
|
||||
OG_INLINE float Math::RSqrt( float f ) {
|
||||
float g = 0.5f * f;
|
||||
int i = *reinterpret_cast<int *>(&f);
|
||||
|
||||
// do a guess
|
||||
i = 0x5f375a86 - ( i>>1 );
|
||||
f = *reinterpret_cast<float *>(&i);
|
||||
|
||||
// Newtons calculation
|
||||
f = f * ( 1.5f - g * f * f );
|
||||
return f;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Log/Log2/Log10
|
||||
|
||||
Log of 0 is bad.
|
||||
I've also heard you're not really
|
||||
supposed to do log of negatives, yet
|
||||
they work fine.
|
||||
================
|
||||
*/
|
||||
OG_INLINE float Math::Log( float f ) {
|
||||
OG_ASSERT( f != 0.0f );
|
||||
return logf( f );
|
||||
}
|
||||
OG_INLINE float Math::Log2( float f ) {
|
||||
OG_ASSERT( f != 0.0f );
|
||||
return INV_LN_2 * logf( f );
|
||||
}
|
||||
OG_INLINE float Math::Log10( float f ) {
|
||||
OG_ASSERT( f != 0.0f );
|
||||
return INV_LN_10 * logf( f );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Pow
|
||||
================
|
||||
*/
|
||||
OG_INLINE float Math::Pow( float base, float exp ) {
|
||||
return powf( base, exp );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Exp
|
||||
================
|
||||
*/
|
||||
OG_INLINE float Math::Exp( float f ) {
|
||||
return expf( f );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::IsPowerOfTwo
|
||||
================
|
||||
*/
|
||||
OG_INLINE bool Math::IsPowerOfTwo( int x ) {
|
||||
// This is the faster of the two known methods
|
||||
// with the x > 0 check moved to the beginning
|
||||
return x > 0 && ( x & ( x - 1 ) ) == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::HigherPowerOfTwo
|
||||
================
|
||||
*/
|
||||
OG_INLINE int Math::HigherPowerOfTwo( int x ) {
|
||||
x--;
|
||||
x |= x >> 1;
|
||||
x |= x >> 2;
|
||||
x |= x >> 4;
|
||||
x |= x >> 8;
|
||||
x |= x >> 16;
|
||||
return x + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::LowerPowerOfTwo
|
||||
================
|
||||
*/
|
||||
OG_INLINE int Math::LowerPowerOfTwo( int x ) {
|
||||
return HigherPowerOfTwo( x ) >> 1;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::FloorPowerOfTwo
|
||||
================
|
||||
*/
|
||||
OG_INLINE int Math::FloorPowerOfTwo( int x ) {
|
||||
return IsPowerOfTwo( x ) ? x : LowerPowerOfTwo( x );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::CeilPowerOfTwo
|
||||
================
|
||||
*/
|
||||
OG_INLINE int Math::CeilPowerOfTwo( int x ) {
|
||||
return IsPowerOfTwo( x ) ? x : HigherPowerOfTwo( x );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::ClosestPowerOfTwo
|
||||
================
|
||||
*/
|
||||
OG_INLINE int Math::ClosestPowerOfTwo( int x ) {
|
||||
if ( IsPowerOfTwo( x ) )
|
||||
return x;
|
||||
int high = HigherPowerOfTwo( x );
|
||||
int low = high >> 1;
|
||||
return ((high-x) < (x-low)) ? high : low;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Digits
|
||||
================
|
||||
*/
|
||||
OG_INLINE int Math::Digits( int x ) {
|
||||
int digits = 1;
|
||||
int step = 10;
|
||||
while (step <= x) {
|
||||
digits++;
|
||||
step *= 10;
|
||||
}
|
||||
return digits;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Sin/ASin
|
||||
================
|
||||
*/
|
||||
OG_INLINE float Math::Sin( float f ) {
|
||||
return sinf( f );
|
||||
}
|
||||
OG_INLINE float Math::ASin( float f ) {
|
||||
if ( f <= -1.0f )
|
||||
return -HALF_PI;
|
||||
if ( f >= 1.0f )
|
||||
return HALF_PI;
|
||||
return asinf( f );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Cos/ACos
|
||||
================
|
||||
*/
|
||||
OG_INLINE float Math::Cos( float f ) {
|
||||
return cosf( f );
|
||||
}
|
||||
OG_INLINE float Math::ACos( float f ) {
|
||||
if ( f <= -1.0f )
|
||||
return PI;
|
||||
if ( f >= 1.0f )
|
||||
return 0.0f;
|
||||
return acosf( f );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Tan/ATan
|
||||
================
|
||||
*/
|
||||
OG_INLINE float Math::Tan( float f ) {
|
||||
return tanf( f );
|
||||
}
|
||||
OG_INLINE float Math::ATan( float f ) {
|
||||
return atanf( f );
|
||||
}
|
||||
OG_INLINE float Math::ATan( float f1, float f2 ) {
|
||||
return atan2f( f1, f2 );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::SinCos
|
||||
================
|
||||
*/
|
||||
OG_INLINE void Math::SinCos( float f, float &s, float &c ) {
|
||||
#if OG_ASM_MSVC
|
||||
// sometimes assembler is just waaayy faster
|
||||
_asm {
|
||||
fld f
|
||||
fsincos
|
||||
mov ecx, c
|
||||
mov edx, s
|
||||
fstp dword ptr [ecx]
|
||||
fstp dword ptr [edx]
|
||||
}
|
||||
#elif OG_ASM_GNU
|
||||
asm ("fsincos" : "=t" (c), "=u" (s) : "0" (f));
|
||||
#else
|
||||
s = Sin(f);
|
||||
c = Sqrt( 1.0f - s * s ); // faster than calling Cos(f)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Deg2Rad
|
||||
================
|
||||
*/
|
||||
OG_INLINE float Math::Deg2Rad( float f ) {
|
||||
return f * DEG_TO_RAD;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Rad2Deg
|
||||
================
|
||||
*/
|
||||
OG_INLINE float Math::Rad2Deg( float f ) {
|
||||
return f * RAD_TO_DEG;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Square
|
||||
================
|
||||
*/
|
||||
OG_INLINE float Math::Square( float v ) {
|
||||
return v * v;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Cube
|
||||
================
|
||||
*/
|
||||
OG_INLINE float Math::Cube( float v ) {
|
||||
return v * v * v;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Sec2Ms
|
||||
================
|
||||
*/
|
||||
OG_INLINE int Math::Sec2Ms( int sec ) {
|
||||
return sec * 1000;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Math::Ms2Sec
|
||||
================
|
||||
*/
|
||||
OG_INLINE int Math::Ms2Sec( int ms ) {
|
||||
return FtoiFast( ms * 0.001f );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user