btScalar.h
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2003-2009 Erwin Coumans  http://bullet.googlecode.com
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 #ifdef BT_MANAGED_CODE
00021 //Aligned data types not supported in managed code
00022 #pragma unmanaged
00023 #endif
00024 
00025 
00026 #include <math.h>
00027 #include <stdlib.h>//size_t for MSVC 6.0
00028 #include <cstdlib>
00029 #include <cfloat>
00030 #include <float.h>
00031 
00032 /* SVN $Revision$ on $Date$ from http://bullet.googlecode.com*/
00033 #define BT_BULLET_VERSION 276
00034 
00035 inline int      btGetVersion()
00036 {
00037         return BT_BULLET_VERSION;
00038 }
00039 
00040 #if defined(DEBUG) || defined (_DEBUG)
00041 #define BT_DEBUG
00042 #endif
00043 
00044 
00045 #ifdef _WIN32
00046 
00047                 #if defined(__MINGW32__) || defined(__CYGWIN__) || (defined (_MSC_VER) && _MSC_VER < 1300)
00048 
00049                         #define SIMD_FORCE_INLINE inline
00050                         #define ATTRIBUTE_ALIGNED16(a) a
00051                         #define ATTRIBUTE_ALIGNED64(a) a
00052                         #define ATTRIBUTE_ALIGNED128(a) a
00053                 #else
00054                         //#define BT_HAS_ALIGNED_ALLOCATOR
00055                         #pragma warning(disable : 4324) // disable padding warning
00056 //                      #pragma warning(disable:4530) // Disable the exception disable but used in MSCV Stl warning.
00057 //                      #pragma warning(disable:4996) //Turn off warnings about deprecated C routines
00058 //                      #pragma warning(disable:4786) // Disable the "debug name too long" warning
00059 
00060                         #define SIMD_FORCE_INLINE __forceinline
00061                         #define ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a
00062                         #define ATTRIBUTE_ALIGNED64(a) __declspec(align(64)) a
00063                         #define ATTRIBUTE_ALIGNED128(a) __declspec (align(128)) a
00064                 #ifdef _XBOX
00065                         #define BT_USE_VMX128
00066 
00067                         #include <ppcintrinsics.h>
00068                         #define BT_HAVE_NATIVE_FSEL
00069                         #define btFsel(a,b,c) __fsel((a),(b),(c))
00070                 #else
00071 
00072 #if (defined (_WIN32) && (_MSC_VER) && _MSC_VER >= 1400) && (!defined (BT_USE_DOUBLE_PRECISION))
00073                         #define BT_USE_SSE
00074                         #include <emmintrin.h>
00075 #endif
00076 
00077                 #endif//_XBOX
00078 
00079                 #endif //__MINGW32__
00080 
00081                 #include <assert.h>
00082 #ifdef BT_DEBUG
00083                 #define btAssert assert
00084 #else
00085                 #define btAssert(x)
00086 #endif
00087                 //btFullAssert is optional, slows down a lot
00088                 #define btFullAssert(x)
00089 
00090                 #define btLikely(_c)  _c
00091                 #define btUnlikely(_c) _c
00092 
00093 #else
00094         
00095 #if defined     (__CELLOS_LV2__)
00096                 #define SIMD_FORCE_INLINE inline
00097                 #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
00098                 #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
00099                 #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
00100                 #ifndef assert
00101                 #include <assert.h>
00102                 #endif
00103 #ifdef BT_DEBUG
00104                 #define btAssert assert
00105 #else
00106                 #define btAssert(x)
00107 #endif
00108                 //btFullAssert is optional, slows down a lot
00109                 #define btFullAssert(x)
00110 
00111                 #define btLikely(_c)  _c
00112                 #define btUnlikely(_c) _c
00113 
00114 #else
00115 
00116 #ifdef USE_LIBSPE2
00117 
00118                 #define SIMD_FORCE_INLINE __inline
00119                 #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
00120                 #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
00121                 #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
00122                 #ifndef assert
00123                 #include <assert.h>
00124                 #endif
00125 #ifdef BT_DEBUG
00126                 #define btAssert assert
00127 #else
00128                 #define btAssert(x)
00129 #endif
00130                 //btFullAssert is optional, slows down a lot
00131                 #define btFullAssert(x)
00132 
00133 
00134                 #define btLikely(_c)   __builtin_expect((_c), 1)
00135                 #define btUnlikely(_c) __builtin_expect((_c), 0)
00136                 
00137 
00138 #else
00139         //non-windows systems
00140 
00141 #if (defined (__APPLE__) && defined (__i386__) && (!defined (BT_USE_DOUBLE_PRECISION)))
00142         #define BT_USE_SSE
00143         #include <emmintrin.h>
00144 
00145         #define SIMD_FORCE_INLINE inline
00146 
00147         #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
00148         #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
00149         #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
00150         #ifndef assert
00151         #include <assert.h>
00152         #endif
00153 
00154         #if defined(DEBUG) || defined (_DEBUG)
00155                 #define btAssert assert
00156         #else
00157                 #define btAssert(x)
00158         #endif
00159 
00160         //btFullAssert is optional, slows down a lot
00161         #define btFullAssert(x)
00162         #define btLikely(_c)  _c
00163         #define btUnlikely(_c) _c
00164 
00165 #else
00166 
00167                 #define SIMD_FORCE_INLINE inline
00168 
00169 
00170 
00171 
00172                 #define ATTRIBUTE_ALIGNED16(a) a
00173                 #define ATTRIBUTE_ALIGNED64(a) a
00174                 #define ATTRIBUTE_ALIGNED128(a) a
00175                 #ifndef assert
00176                 #include <assert.h>
00177                 #endif
00178 
00179 #if defined(DEBUG) || defined (_DEBUG)
00180                 #define btAssert assert
00181 #else
00182                 #define btAssert(x)
00183 #endif
00184 
00185                 //btFullAssert is optional, slows down a lot
00186                 #define btFullAssert(x)
00187                 #define btLikely(_c)  _c
00188                 #define btUnlikely(_c) _c
00189 #endif //__APPLE__ 
00190 
00191 #endif // LIBSPE2
00192 
00193 #endif  //__CELLOS_LV2__
00194 #endif
00195 
00196 
00198 #if defined(BT_USE_DOUBLE_PRECISION)
00199 typedef double btScalar;
00200 //this number could be bigger in double precision
00201 #define BT_LARGE_FLOAT 1e30
00202 #else
00203 typedef float btScalar;
00204 //keep BT_LARGE_FLOAT*BT_LARGE_FLOAT < FLT_MAX
00205 #define BT_LARGE_FLOAT 1e18f
00206 #endif
00207 
00208 
00209 
00210 #define BT_DECLARE_ALIGNED_ALLOCATOR() \
00211    SIMD_FORCE_INLINE void* operator new(size_t sizeInBytes)   { return btAlignedAlloc(sizeInBytes,16); }   \
00212    SIMD_FORCE_INLINE void  operator delete(void* ptr)         { btAlignedFree(ptr); }   \
00213    SIMD_FORCE_INLINE void* operator new(size_t, void* ptr)   { return ptr; }   \
00214    SIMD_FORCE_INLINE void  operator delete(void*, void*)      { }   \
00215    SIMD_FORCE_INLINE void* operator new[](size_t sizeInBytes)   { return btAlignedAlloc(sizeInBytes,16); }   \
00216    SIMD_FORCE_INLINE void  operator delete[](void* ptr)         { btAlignedFree(ptr); }   \
00217    SIMD_FORCE_INLINE void* operator new[](size_t, void* ptr)   { return ptr; }   \
00218    SIMD_FORCE_INLINE void  operator delete[](void*, void*)      { }   \
00219 
00220 
00221 
00222 #if defined(BT_USE_DOUBLE_PRECISION) || defined(BT_FORCE_DOUBLE_FUNCTIONS)
00223                 
00224 SIMD_FORCE_INLINE btScalar btSqrt(btScalar x) { return sqrt(x); }
00225 SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabs(x); }
00226 SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cos(x); }
00227 SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sin(x); }
00228 SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tan(x); }
00229 SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { if (x<btScalar(-1))     x=btScalar(-1); if (x>btScalar(1))      x=btScalar(1); return acos(x); }
00230 SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { if (x<btScalar(-1))     x=btScalar(-1); if (x>btScalar(1))      x=btScalar(1); return asin(x); }
00231 SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atan(x); }
00232 SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2(x, y); }
00233 SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return exp(x); }
00234 SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return log(x); }
00235 SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return pow(x,y); }
00236 SIMD_FORCE_INLINE btScalar btFmod(btScalar x,btScalar y) { return fmod(x,y); }
00237 
00238 #else
00239                 
00240 SIMD_FORCE_INLINE btScalar btSqrt(btScalar y) 
00241 { 
00242 #ifdef USE_APPROXIMATION
00243     double x, z, tempf;
00244     unsigned long *tfptr = ((unsigned long *)&tempf) + 1;
00245 
00246         tempf = y;
00247         *tfptr = (0xbfcdd90a - *tfptr)>>1; /* estimate of 1/sqrt(y) */
00248         x =  tempf;
00249         z =  y*btScalar(0.5);                        /* hoist out the “/2”    */
00250         x = (btScalar(1.5)*x)-(x*x)*(x*z);         /* iteration formula     */
00251         x = (btScalar(1.5)*x)-(x*x)*(x*z);
00252         x = (btScalar(1.5)*x)-(x*x)*(x*z);
00253         x = (btScalar(1.5)*x)-(x*x)*(x*z);
00254         x = (btScalar(1.5)*x)-(x*x)*(x*z);
00255         return x*y;
00256 #else
00257         return sqrtf(y); 
00258 #endif
00259 }
00260 SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabsf(x); }
00261 SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cosf(x); }
00262 SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); }
00263 SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); }
00264 SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { 
00265         if (x<btScalar(-1))     
00266                 x=btScalar(-1); 
00267         if (x>btScalar(1))      
00268                 x=btScalar(1);
00269         return acosf(x); 
00270 }
00271 SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { 
00272         if (x<btScalar(-1))     
00273                 x=btScalar(-1); 
00274         if (x>btScalar(1))      
00275                 x=btScalar(1);
00276         return asinf(x); 
00277 }
00278 SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); }
00279 SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); }
00280 SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return expf(x); }
00281 SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return logf(x); }
00282 SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return powf(x,y); }
00283 SIMD_FORCE_INLINE btScalar btFmod(btScalar x,btScalar y) { return fmodf(x,y); }
00284         
00285 #endif
00286 
00287 #define SIMD_2_PI         btScalar(6.283185307179586232)
00288 #define SIMD_PI           (SIMD_2_PI * btScalar(0.5))
00289 #define SIMD_HALF_PI      (SIMD_2_PI * btScalar(0.25))
00290 #define SIMD_RADS_PER_DEG (SIMD_2_PI / btScalar(360.0))
00291 #define SIMD_DEGS_PER_RAD  (btScalar(360.0) / SIMD_2_PI)
00292 #define SIMDSQRT12 btScalar(0.7071067811865475244008443621048490)
00293 
00294 #define btRecipSqrt(x) ((btScalar)(btScalar(1.0)/btSqrt(btScalar(x))))          /* reciprocal square root */
00295 
00296 
00297 #ifdef BT_USE_DOUBLE_PRECISION
00298 #define SIMD_EPSILON      DBL_EPSILON
00299 #define SIMD_INFINITY     DBL_MAX
00300 #else
00301 #define SIMD_EPSILON      FLT_EPSILON
00302 #define SIMD_INFINITY     FLT_MAX
00303 #endif
00304 
00305 SIMD_FORCE_INLINE btScalar btAtan2Fast(btScalar y, btScalar x) 
00306 {
00307         btScalar coeff_1 = SIMD_PI / 4.0f;
00308         btScalar coeff_2 = 3.0f * coeff_1;
00309         btScalar abs_y = btFabs(y);
00310         btScalar angle;
00311         if (x >= 0.0f) {
00312                 btScalar r = (x - abs_y) / (x + abs_y);
00313                 angle = coeff_1 - coeff_1 * r;
00314         } else {
00315                 btScalar r = (x + abs_y) / (abs_y - x);
00316                 angle = coeff_2 - coeff_1 * r;
00317         }
00318         return (y < 0.0f) ? -angle : angle;
00319 }
00320 
00321 SIMD_FORCE_INLINE bool      btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; }
00322 
00323 SIMD_FORCE_INLINE bool  btEqual(btScalar a, btScalar eps) {
00324         return (((a) <= eps) && !((a) < -eps));
00325 }
00326 SIMD_FORCE_INLINE bool  btGreaterEqual (btScalar a, btScalar eps) {
00327         return (!((a) <= eps));
00328 }
00329 
00330 
00331 SIMD_FORCE_INLINE int       btIsNegative(btScalar x) {
00332     return x < btScalar(0.0) ? 1 : 0;
00333 }
00334 
00335 SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; }
00336 SIMD_FORCE_INLINE btScalar btDegrees(btScalar x) { return x * SIMD_DEGS_PER_RAD; }
00337 
00338 #define BT_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
00339 
00340 #ifndef btFsel
00341 SIMD_FORCE_INLINE btScalar btFsel(btScalar a, btScalar b, btScalar c)
00342 {
00343         return a >= 0 ? b : c;
00344 }
00345 #endif
00346 #define btFsels(a,b,c) (btScalar)btFsel(a,b,c)
00347 
00348 
00349 SIMD_FORCE_INLINE bool btMachineIsLittleEndian()
00350 {
00351    long int i = 1;
00352    const char *p = (const char *) &i;
00353    if (p[0] == 1)  // Lowest address contains the least significant byte
00354            return true;
00355    else
00356            return false;
00357 }
00358 
00359 
00360 
00363 SIMD_FORCE_INLINE unsigned btSelect(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero) 
00364 {
00365     // Set testNz to 0xFFFFFFFF if condition is nonzero, 0x00000000 if condition is zero
00366     // Rely on positive value or'ed with its negative having sign bit on
00367     // and zero value or'ed with its negative (which is still zero) having sign bit off 
00368     // Use arithmetic shift right, shifting the sign bit through all 32 bits
00369     unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
00370     unsigned testEqz = ~testNz;
00371     return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); 
00372 }
00373 SIMD_FORCE_INLINE int btSelect(unsigned condition, int valueIfConditionNonZero, int valueIfConditionZero)
00374 {
00375     unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
00376     unsigned testEqz = ~testNz; 
00377     return static_cast<int>((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz));
00378 }
00379 SIMD_FORCE_INLINE float btSelect(unsigned condition, float valueIfConditionNonZero, float valueIfConditionZero)
00380 {
00381 #ifdef BT_HAVE_NATIVE_FSEL
00382     return (float)btFsel((btScalar)condition - btScalar(1.0f), valueIfConditionNonZero, valueIfConditionZero);
00383 #else
00384     return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero; 
00385 #endif
00386 }
00387 
00388 template<typename T> SIMD_FORCE_INLINE void btSwap(T& a, T& b)
00389 {
00390         T tmp = a;
00391         a = b;
00392         b = tmp;
00393 }
00394 
00395 
00396 //PCK: endian swapping functions
00397 SIMD_FORCE_INLINE unsigned btSwapEndian(unsigned val)
00398 {
00399         return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8)  | ((val & 0x000000ff) << 24));
00400 }
00401 
00402 SIMD_FORCE_INLINE unsigned short btSwapEndian(unsigned short val)
00403 {
00404         return static_cast<unsigned short>(((val & 0xff00) >> 8) | ((val & 0x00ff) << 8));
00405 }
00406 
00407 SIMD_FORCE_INLINE unsigned btSwapEndian(int val)
00408 {
00409         return btSwapEndian((unsigned)val);
00410 }
00411 
00412 SIMD_FORCE_INLINE unsigned short btSwapEndian(short val)
00413 {
00414         return btSwapEndian((unsigned short) val);
00415 }
00416 
00423 SIMD_FORCE_INLINE unsigned int  btSwapEndianFloat(float d)
00424 {
00425     unsigned int a = 0;
00426     unsigned char *dst = (unsigned char *)&a;
00427     unsigned char *src = (unsigned char *)&d;
00428 
00429     dst[0] = src[3];
00430     dst[1] = src[2];
00431     dst[2] = src[1];
00432     dst[3] = src[0];
00433     return a;
00434 }
00435 
00436 // unswap using char pointers
00437 SIMD_FORCE_INLINE float btUnswapEndianFloat(unsigned int a) 
00438 {
00439     float d = 0.0f;
00440     unsigned char *src = (unsigned char *)&a;
00441     unsigned char *dst = (unsigned char *)&d;
00442 
00443     dst[0] = src[3];
00444     dst[1] = src[2];
00445     dst[2] = src[1];
00446     dst[3] = src[0];
00447 
00448     return d;
00449 }
00450 
00451 
00452 // swap using char pointers
00453 SIMD_FORCE_INLINE void  btSwapEndianDouble(double d, unsigned char* dst)
00454 {
00455     unsigned char *src = (unsigned char *)&d;
00456 
00457     dst[0] = src[7];
00458     dst[1] = src[6];
00459     dst[2] = src[5];
00460     dst[3] = src[4];
00461     dst[4] = src[3];
00462     dst[5] = src[2];
00463     dst[6] = src[1];
00464     dst[7] = src[0];
00465 
00466 }
00467 
00468 // unswap using char pointers
00469 SIMD_FORCE_INLINE double btUnswapEndianDouble(const unsigned char *src) 
00470 {
00471     double d = 0.0;
00472     unsigned char *dst = (unsigned char *)&d;
00473 
00474     dst[0] = src[7];
00475     dst[1] = src[6];
00476     dst[2] = src[5];
00477     dst[3] = src[4];
00478     dst[4] = src[3];
00479     dst[5] = src[2];
00480     dst[6] = src[1];
00481     dst[7] = src[0];
00482 
00483         return d;
00484 }
00485 
00486 // returns normalized value in range [-SIMD_PI, SIMD_PI]
00487 SIMD_FORCE_INLINE btScalar btNormalizeAngle(btScalar angleInRadians) 
00488 {
00489         angleInRadians = btFmod(angleInRadians, SIMD_2_PI);
00490         if(angleInRadians < -SIMD_PI)
00491         {
00492                 return angleInRadians + SIMD_2_PI;
00493         }
00494         else if(angleInRadians > SIMD_PI)
00495         {
00496                 return angleInRadians - SIMD_2_PI;
00497         }
00498         else
00499         {
00500                 return angleInRadians;
00501         }
00502 }
00503 
00505 struct btTypedObject
00506 {
00507         btTypedObject(int objectType)
00508                 :m_objectType(objectType)
00509         {
00510         }
00511         int     m_objectType;
00512         inline int getObjectType() const
00513         {
00514                 return m_objectType;
00515         }
00516 };
00517 #endif //SIMD___SCALAR_H


tf2
Author(s): Tully Foote, Eitan Marder-Eppstein, Wim Meeussen
autogenerated on Mon Oct 6 2014 00:12:43