Back to index

supertuxkart  0.5+dfsg1
btScalar.h
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans  http://continuousphysics.com/Bullet/
00003 
00004 This software is provided 'as-is', without any express or implied warranty.
00005 In no event will the authors be held liable for any damages arising from the use of this software.
00006 Permission is granted to anyone to use this software for any purpose, 
00007 including commercial applications, and to alter it and redistribute it freely, 
00008 subject to the following restrictions:
00009 
00010 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.
00011 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00012 3. This notice may not be removed or altered from any source distribution.
00013 */
00014 
00015 
00016 
00017 #ifndef SIMD___SCALAR_H
00018 #define SIMD___SCALAR_H
00019 
00020 #include <math.h>
00021 
00022 #include <cstdlib>
00023 #include <cfloat>
00024 #include <float.h>
00025 
00026 #define BT_BULLET_VERSION 268
00027 
00028 inline int    btGetVersion()
00029 {
00030        return BT_BULLET_VERSION;
00031 }
00032 
00033 #if defined(DEBUG) || defined (_DEBUG)
00034 #define BT_DEBUG
00035 #endif
00036 
00037 
00038 #ifdef WIN32
00039 
00040               #if defined(__MINGW32__) || defined(__CYGWIN__) || (defined (_MSC_VER) && _MSC_VER < 1300)
00041 
00042                      #define SIMD_FORCE_INLINE inline
00043                      #define ATTRIBUTE_ALIGNED16(a) a
00044                      #define ATTRIBUTE_ALIGNED128(a) a
00045               #else
00046                      #define BT_HAS_ALIGNED_ALLOCATOR
00047                      #pragma warning(disable:4530)
00048                      #pragma warning(disable:4996)
00049                      #pragma warning(disable:4786)
00050                      #define SIMD_FORCE_INLINE __forceinline
00051                      #define ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a
00052                      #define ATTRIBUTE_ALIGNED128(a) __declspec (align(128)) a
00053               #ifdef _XBOX
00054                      #define BT_USE_VMX128
00055 
00056                      #include <ppcintrinsics.h>
00057                      #define BT_HAVE_NATIVE_FSEL
00058                      #define btFsel(a,b,c) __fsel((a),(b),(c))
00059               #else
00060                      #define BT_USE_SSE
00061               #endif
00062               #endif //__MINGW32__
00063 
00064               #include <assert.h>
00065               #define btAssert assert
00066               //btFullAssert is optional, slows down a lot
00067               #define btFullAssert(x)
00068 
00069               #define btLikely(_c)  _c
00070               #define btUnlikely(_c) _c
00071 
00072 #else
00073        
00074 #if defined   (__CELLOS_LV2__)
00075               #define SIMD_FORCE_INLINE inline
00076               #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
00077               #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
00078               #ifndef assert
00079               #include <assert.h>
00080               #endif
00081               #define btAssert assert
00082               //btFullAssert is optional, slows down a lot
00083               #define btFullAssert(x)
00084 
00085               #define btLikely(_c)  _c
00086               #define btUnlikely(_c) _c
00087 
00088 #else
00089 
00090 #ifdef USE_LIBSPE2
00091 
00092               #define SIMD_FORCE_INLINE __inline
00093               #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
00094               #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
00095               #ifndef assert
00096               #include <assert.h>
00097               #endif
00098               #define btAssert assert
00099               //btFullAssert is optional, slows down a lot
00100               #define btFullAssert(x)
00101 
00102 
00103               #define btLikely(_c)   __builtin_expect((_c), 1)
00104               #define btUnlikely(_c) __builtin_expect((_c), 0)
00105               
00106 
00107 #else
00108        //non-windows systems
00109 
00110               #define SIMD_FORCE_INLINE inline
00111               #define ATTRIBUTE_ALIGNED16(a) a
00112               #define ATTRIBUTE_ALIGNED128(a) a
00113               #ifndef assert
00114               #include <assert.h>
00115               #endif
00116               #define btAssert assert
00117               //btFullAssert is optional, slows down a lot
00118               #define btFullAssert(x)
00119               #define btLikely(_c)  _c
00120               #define btUnlikely(_c) _c
00121 
00122 
00123 #endif // LIBSPE2
00124 
00125 #endif //__CELLOS_LV2__
00126 #endif
00127 
00130 #if defined (__sun) || defined (__sun__) || defined (__sparc) || (defined (__APPLE__) && ! defined (__i386__))
00131 //use slow double float precision operation on those platforms
00132 #ifndef BT_USE_DOUBLE_PRECISION
00133 #define BT_FORCE_DOUBLE_FUNCTIONS
00134 #endif
00135 #endif
00136 
00137 #if defined(BT_USE_DOUBLE_PRECISION)
00138 typedef double btScalar;
00139 #else
00140 typedef float btScalar;
00141 #endif
00142 
00143 
00144 #define BT_DECLARE_ALIGNED_ALLOCATOR() \
00145        SIMD_FORCE_INLINE void* operator new(size_t sizeInBytes)       { return btAlignedAlloc(sizeInBytes,16); }       \
00146        SIMD_FORCE_INLINE void  operator delete(void* ptr)                    { btAlignedFree(ptr); }     \
00147        SIMD_FORCE_INLINE void* operator new(size_t, void* ptr) { return ptr; }      \
00148        SIMD_FORCE_INLINE void  operator delete(void*, void*)          { }    \
00149 
00150 
00151 
00152 #if defined(BT_USE_DOUBLE_PRECISION) || defined(BT_FORCE_DOUBLE_FUNCTIONS)
00153               
00154 SIMD_FORCE_INLINE btScalar btSqrt(btScalar x) { return sqrt(x); }
00155 SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabs(x); }
00156 SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cos(x); }
00157 SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sin(x); }
00158 SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tan(x); }
00159 SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { return acos(x); }
00160 SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { return asin(x); }
00161 SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atan(x); }
00162 SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2(x, y); }
00163 SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return exp(x); }
00164 SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return log(x); }
00165 SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return pow(x,y); }
00166 
00167 #else
00168               
00169 SIMD_FORCE_INLINE btScalar btSqrt(btScalar y) 
00170 { 
00171 #ifdef USE_APPROXIMATION
00172     double x, z, tempf;
00173     unsigned long *tfptr = ((unsigned long *)&tempf) + 1;
00174 
00175        tempf = y;
00176        *tfptr = (0xbfcdd90a - *tfptr)>>1; /* estimate of 1/sqrt(y) */
00177        x =  tempf;
00178        z =  y*btScalar(0.5);                        /* hoist out the /2    */
00179        x = (btScalar(1.5)*x)-(x*x)*(x*z);         /* iteration formula     */
00180        x = (btScalar(1.5)*x)-(x*x)*(x*z);
00181        x = (btScalar(1.5)*x)-(x*x)*(x*z);
00182        x = (btScalar(1.5)*x)-(x*x)*(x*z);
00183        x = (btScalar(1.5)*x)-(x*x)*(x*z);
00184        return x*y;
00185 #else
00186        return sqrtf(y); 
00187 #endif
00188 }
00189 SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabsf(x); }
00190 SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cosf(x); }
00191 SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); }
00192 SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); }
00193 SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { 
00194        btAssert(x <= btScalar(1.));
00195        return acosf(x); 
00196 }
00197 SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { return asinf(x); }
00198 SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); }
00199 SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); }
00200 SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return expf(x); }
00201 SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return logf(x); }
00202 SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return powf(x,y); }
00203        
00204 #endif
00205 
00206 #define SIMD_2_PI         btScalar(6.283185307179586232)
00207 #define SIMD_PI           (SIMD_2_PI * btScalar(0.5))
00208 #define SIMD_HALF_PI      (SIMD_2_PI * btScalar(0.25))
00209 #define SIMD_RADS_PER_DEG (SIMD_2_PI / btScalar(360.0))
00210 #define SIMD_DEGS_PER_RAD  (btScalar(360.0) / SIMD_2_PI)
00211 
00212 #ifdef BT_USE_DOUBLE_PRECISION
00213 #define SIMD_EPSILON      DBL_EPSILON
00214 #define SIMD_INFINITY     DBL_MAX
00215 #else
00216 #define SIMD_EPSILON      FLT_EPSILON
00217 #define SIMD_INFINITY     FLT_MAX
00218 #endif
00219 
00220 SIMD_FORCE_INLINE btScalar btAtan2Fast(btScalar y, btScalar x) 
00221 {
00222        btScalar coeff_1 = SIMD_PI / 4.0f;
00223        btScalar coeff_2 = 3.0f * coeff_1;
00224        btScalar abs_y = btFabs(y);
00225        btScalar angle;
00226        if (x >= 0.0f) {
00227               btScalar r = (x - abs_y) / (x + abs_y);
00228               angle = coeff_1 - coeff_1 * r;
00229        } else {
00230               btScalar r = (x + abs_y) / (abs_y - x);
00231               angle = coeff_2 - coeff_1 * r;
00232        }
00233        return (y < 0.0f) ? -angle : angle;
00234 }
00235 
00236 SIMD_FORCE_INLINE bool      btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; }
00237 
00238 SIMD_FORCE_INLINE bool      btEqual(btScalar a, btScalar eps) {
00239        return (((a) <= eps) && !((a) < -eps));
00240 }
00241 SIMD_FORCE_INLINE bool      btGreaterEqual (btScalar a, btScalar eps) {
00242        return (!((a) <= eps));
00243 }
00244 
00245 
00246 SIMD_FORCE_INLINE int       btIsNegative(btScalar x) {
00247     return x < btScalar(0.0) ? 1 : 0;
00248 }
00249 
00250 SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; }
00251 SIMD_FORCE_INLINE btScalar btDegrees(btScalar x) { return x * SIMD_DEGS_PER_RAD; }
00252 
00253 #define BT_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
00254 
00255 #ifndef btFsel
00256 SIMD_FORCE_INLINE btScalar btFsel(btScalar a, btScalar b, btScalar c)
00257 {
00258        return a >= 0 ? b : c;
00259 }
00260 #endif
00261 #define btFsels(a,b,c) (btScalar)btFsel(a,b,c)
00262 
00263 
00264 SIMD_FORCE_INLINE bool btMachineIsLittleEndian()
00265 {
00266    long int i = 1;
00267    const char *p = (const char *) &i;
00268    if (p[0] == 1)  // Lowest address contains the least significant byte
00269           return true;
00270    else
00271           return false;
00272 }
00273 
00274 
00275 
00278 SIMD_FORCE_INLINE unsigned btSelect(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero) 
00279 {
00280     // Set testNz to 0xFFFFFFFF if condition is nonzero, 0x00000000 if condition is zero
00281     // Rely on positive value or'ed with its negative having sign bit on
00282     // and zero value or'ed with its negative (which is still zero) having sign bit off 
00283     // Use arithmetic shift right, shifting the sign bit through all 32 bits
00284     unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
00285     unsigned testEqz = ~testNz;
00286     return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); 
00287 }
00288 SIMD_FORCE_INLINE int btSelect(unsigned condition, int valueIfConditionNonZero, int valueIfConditionZero)
00289 {
00290     unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
00291     unsigned testEqz = ~testNz; 
00292     return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz));
00293 }
00294 SIMD_FORCE_INLINE float btSelect(unsigned condition, float valueIfConditionNonZero, float valueIfConditionZero)
00295 {
00296 #ifdef BT_HAVE_NATIVE_FSEL
00297     return (float)btFsel((btScalar)condition - btScalar(1.0f), valueIfConditionNonZero, valueIfConditionZero);
00298 #else
00299     return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero; 
00300 #endif
00301 }
00302 
00303 template<typename T> SIMD_FORCE_INLINE void btSwap(T& a, T& b)
00304 {
00305        T tmp = a;
00306        a = b;
00307        b = tmp;
00308 }
00309 
00310 
00311 //PCK: endian swapping functions
00312 SIMD_FORCE_INLINE unsigned btSwapEndian(unsigned val)
00313 {
00314        return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8)  | ((val & 0x000000ff) << 24));
00315 }
00316 
00317 SIMD_FORCE_INLINE unsigned short btSwapEndian(unsigned short val)
00318 {
00319        return (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8));
00320 }
00321 
00322 SIMD_FORCE_INLINE unsigned btSwapEndian(int val)
00323 {
00324        return btSwapEndian((unsigned)val);
00325 }
00326 
00327 SIMD_FORCE_INLINE unsigned short btSwapEndian(short val)
00328 {
00329        return btSwapEndian((unsigned short) val);
00330 }
00331 
00338 SIMD_FORCE_INLINE unsigned int  btSwapEndianFloat(float d)
00339 {
00340     unsigned int a;
00341     unsigned char *dst = (unsigned char *)&a;
00342     unsigned char *src = (unsigned char *)&d;
00343 
00344     dst[0] = src[3];
00345     dst[1] = src[2];
00346     dst[2] = src[1];
00347     dst[3] = src[0];
00348     return a;
00349 }
00350 
00351 // unswap using char pointers
00352 SIMD_FORCE_INLINE float btUnswapEndianFloat(unsigned int a) 
00353 {
00354     float d;
00355     unsigned char *src = (unsigned char *)&a;
00356     unsigned char *dst = (unsigned char *)&d;
00357 
00358     dst[0] = src[3];
00359     dst[1] = src[2];
00360     dst[2] = src[1];
00361     dst[3] = src[0];
00362 
00363     return d;
00364 }
00365 
00366 
00367 // swap using char pointers
00368 SIMD_FORCE_INLINE void  btSwapEndianDouble(double d, unsigned char* dst)
00369 {
00370     unsigned char *src = (unsigned char *)&d;
00371 
00372     dst[0] = src[7];
00373     dst[1] = src[6];
00374     dst[2] = src[5];
00375     dst[3] = src[4];
00376     dst[4] = src[3];
00377     dst[5] = src[2];
00378     dst[6] = src[1];
00379     dst[7] = src[0];
00380 
00381 }
00382 
00383 // unswap using char pointers
00384 SIMD_FORCE_INLINE double btUnswapEndianDouble(const unsigned char *src) 
00385 {
00386     double d;
00387     unsigned char *dst = (unsigned char *)&d;
00388 
00389     dst[0] = src[7];
00390     dst[1] = src[6];
00391     dst[2] = src[5];
00392     dst[3] = src[4];
00393     dst[4] = src[3];
00394     dst[5] = src[2];
00395     dst[6] = src[1];
00396     dst[7] = src[0];
00397 
00398        return d;
00399 }
00400 
00401 
00402 #endif //SIMD___SCALAR_H