Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/kicklib2/src/external/bullet/LinearMath/btScalar.h @ 8422

Last change on this file since 8422 was 8284, checked in by rgrieder, 14 years ago

Merged revisions 7978 - 8096 from kicklib to kicklib2.

  • Property svn:eol-style set to native
File size: 15.9 KB
RevLine 
[1963]1/*
[8284]2Copyright (c) 2003-2009 Erwin Coumans  http://bullet.googlecode.com
[1963]3
4This software is provided 'as-is', without any express or implied warranty.
5In no event will the authors be held liable for any damages arising from the use of this software.
[2472]6Permission is granted to anyone to use this software for any purpose,
7including commercial applications, and to alter it and redistribute it freely,
[1963]8subject to the following restrictions:
9
101. 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.
112. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
123. This notice may not be removed or altered from any source distribution.
13*/
14
15
16
17#ifndef SIMD___SCALAR_H
18#define SIMD___SCALAR_H
19
[8284]20#ifdef BT_MANAGED_CODE
21//Aligned data types not supported in managed code
22#pragma unmanaged
23#endif
24
25
[1963]26#include <math.h>
27#include <stdlib.h>//size_t for MSVC 6.0
28#include <cstdlib>
29#include <cfloat>
30#include <float.h>
31
[8284]32/* SVN $Revision$ on $Date$ from http://bullet.googlecode.com*/
33#define BT_BULLET_VERSION 277
[1963]34
35inline int      btGetVersion()
36{
37        return BT_BULLET_VERSION;
38}
39
40#if defined(DEBUG) || defined (_DEBUG)
41#define BT_DEBUG
42#endif
43
44
[8284]45#ifdef _WIN32
[1963]46
47                #if defined(__MINGW32__) || defined(__CYGWIN__) || (defined (_MSC_VER) && _MSC_VER < 1300)
48
49                        #define SIMD_FORCE_INLINE inline
50                        #define ATTRIBUTE_ALIGNED16(a) a
[8284]51                        #define ATTRIBUTE_ALIGNED64(a) a
[1963]52                        #define ATTRIBUTE_ALIGNED128(a) a
53                #else
[2882]54                        //#define BT_HAS_ALIGNED_ALLOCATOR
[1963]55                        #pragma warning(disable : 4324) // disable padding warning
56//                      #pragma warning(disable:4530) // Disable the exception disable but used in MSCV Stl warning.
57//                      #pragma warning(disable:4996) //Turn off warnings about deprecated C routines
58//                      #pragma warning(disable:4786) // Disable the "debug name too long" warning
59
60                        #define SIMD_FORCE_INLINE __forceinline
61                        #define ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a
[8284]62                        #define ATTRIBUTE_ALIGNED64(a) __declspec(align(64)) a
[1963]63                        #define ATTRIBUTE_ALIGNED128(a) __declspec (align(128)) a
64                #ifdef _XBOX
65                        #define BT_USE_VMX128
66
67                        #include <ppcintrinsics.h>
68                        #define BT_HAVE_NATIVE_FSEL
69                        #define btFsel(a,b,c) __fsel((a),(b),(c))
70                #else
[2882]71
[8284]72#if (defined (_WIN32) && (_MSC_VER) && _MSC_VER >= 1400) && (!defined (BT_USE_DOUBLE_PRECISION))
[1963]73                        #define BT_USE_SSE
[2882]74                        #include <emmintrin.h>
75#endif
76
77                #endif//_XBOX
78
[1963]79                #endif //__MINGW32__
80
81                #include <assert.h>
[2430]82#ifdef BT_DEBUG
[1963]83                #define btAssert assert
84#else
85                #define btAssert(x)
86#endif
87                //btFullAssert is optional, slows down a lot
88                #define btFullAssert(x)
89
90                #define btLikely(_c)  _c
91                #define btUnlikely(_c) _c
92
93#else
[2472]94       
[1963]95#if defined     (__CELLOS_LV2__)
[8284]96                #define SIMD_FORCE_INLINE inline __attribute__((always_inline))
[1963]97                #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
[8284]98                #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
[1963]99                #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
100                #ifndef assert
101                #include <assert.h>
102                #endif
[2430]103#ifdef BT_DEBUG
[8284]104#ifdef __SPU__
105#include <spu_printf.h>
106#define printf spu_printf
107        #define btAssert(x) {if(!(x)){printf("Assert "__FILE__ ":%u ("#x")\n", __LINE__);spu_hcmpeq(0,0);}}
[2430]108#else
[8284]109        #define btAssert assert
110#endif
111       
112#else
[2430]113                #define btAssert(x)
114#endif
[1963]115                //btFullAssert is optional, slows down a lot
116                #define btFullAssert(x)
117
118                #define btLikely(_c)  _c
119                #define btUnlikely(_c) _c
120
121#else
122
123#ifdef USE_LIBSPE2
124
125                #define SIMD_FORCE_INLINE __inline
126                #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
[8284]127                #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
[1963]128                #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
129                #ifndef assert
130                #include <assert.h>
131                #endif
[2430]132#ifdef BT_DEBUG
[1963]133                #define btAssert assert
[2430]134#else
135                #define btAssert(x)
136#endif
[1963]137                //btFullAssert is optional, slows down a lot
138                #define btFullAssert(x)
139
140
141                #define btLikely(_c)   __builtin_expect((_c), 1)
142                #define btUnlikely(_c) __builtin_expect((_c), 0)
[2472]143               
[1963]144
145#else
146        //non-windows systems
147
[8284]148#if (defined (__APPLE__) && defined (__i386__) && (!defined (BT_USE_DOUBLE_PRECISION)))
149        #define BT_USE_SSE
150        #include <emmintrin.h>
151
152        #define SIMD_FORCE_INLINE inline
153///@todo: check out alignment methods for other platforms/compilers
154        #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
155        #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
156        #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
157        #ifndef assert
158        #include <assert.h>
159        #endif
160
161        #if defined(DEBUG) || defined (_DEBUG)
162                #define btAssert assert
163        #else
164                #define btAssert(x)
165        #endif
166
167        //btFullAssert is optional, slows down a lot
168        #define btFullAssert(x)
169        #define btLikely(_c)  _c
170        #define btUnlikely(_c) _c
171
172#else
173
[1963]174                #define SIMD_FORCE_INLINE inline
[2882]175                ///@todo: check out alignment methods for other platforms/compilers
176                ///#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
[8284]177                ///#define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
[2882]178                ///#define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
[1963]179                #define ATTRIBUTE_ALIGNED16(a) a
[8284]180                #define ATTRIBUTE_ALIGNED64(a) a
[1963]181                #define ATTRIBUTE_ALIGNED128(a) a
182                #ifndef assert
183                #include <assert.h>
184                #endif
185
186#if defined(DEBUG) || defined (_DEBUG)
187                #define btAssert assert
188#else
189                #define btAssert(x)
190#endif
191
192                //btFullAssert is optional, slows down a lot
193                #define btFullAssert(x)
194                #define btLikely(_c)  _c
195                #define btUnlikely(_c) _c
[8284]196#endif //__APPLE__
[1963]197
198#endif // LIBSPE2
199
200#endif  //__CELLOS_LV2__
201#endif
202
203
204///The btScalar type abstracts floating point numbers, to easily switch between double and single floating point precision.
205#if defined(BT_USE_DOUBLE_PRECISION)
206typedef double btScalar;
[8284]207//this number could be bigger in double precision
208#define BT_LARGE_FLOAT 1e30
[1963]209#else
210typedef float btScalar;
[8284]211//keep BT_LARGE_FLOAT*BT_LARGE_FLOAT < FLT_MAX
212#define BT_LARGE_FLOAT 1e18f
[1963]213#endif
214
215
216
217#define BT_DECLARE_ALIGNED_ALLOCATOR() \
218   SIMD_FORCE_INLINE void* operator new(size_t sizeInBytes)   { return btAlignedAlloc(sizeInBytes,16); }   \
219   SIMD_FORCE_INLINE void  operator delete(void* ptr)         { btAlignedFree(ptr); }   \
220   SIMD_FORCE_INLINE void* operator new(size_t, void* ptr)   { return ptr; }   \
221   SIMD_FORCE_INLINE void  operator delete(void*, void*)      { }   \
222   SIMD_FORCE_INLINE void* operator new[](size_t sizeInBytes)   { return btAlignedAlloc(sizeInBytes,16); }   \
223   SIMD_FORCE_INLINE void  operator delete[](void* ptr)         { btAlignedFree(ptr); }   \
224   SIMD_FORCE_INLINE void* operator new[](size_t, void* ptr)   { return ptr; }   \
225   SIMD_FORCE_INLINE void  operator delete[](void*, void*)      { }   \
226
227
228
229#if defined(BT_USE_DOUBLE_PRECISION) || defined(BT_FORCE_DOUBLE_FUNCTIONS)
[2472]230               
[1963]231SIMD_FORCE_INLINE btScalar btSqrt(btScalar x) { return sqrt(x); }
232SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabs(x); }
233SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cos(x); }
234SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sin(x); }
235SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tan(x); }
[8284]236SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { if (x<btScalar(-1))     x=btScalar(-1); if (x>btScalar(1))      x=btScalar(1); return acos(x); }
237SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { if (x<btScalar(-1))     x=btScalar(-1); if (x>btScalar(1))      x=btScalar(1); return asin(x); }
[1963]238SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atan(x); }
239SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2(x, y); }
240SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return exp(x); }
241SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return log(x); }
242SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return pow(x,y); }
[8284]243SIMD_FORCE_INLINE btScalar btFmod(btScalar x,btScalar y) { return fmod(x,y); }
[1963]244
245#else
[2472]246               
247SIMD_FORCE_INLINE btScalar btSqrt(btScalar y) 
248{ 
[1963]249#ifdef USE_APPROXIMATION
250    double x, z, tempf;
251    unsigned long *tfptr = ((unsigned long *)&tempf) + 1;
252
253        tempf = y;
254        *tfptr = (0xbfcdd90a - *tfptr)>>1; /* estimate of 1/sqrt(y) */
255        x =  tempf;
[8284]256        z =  y*btScalar(0.5);
[1963]257        x = (btScalar(1.5)*x)-(x*x)*(x*z);         /* iteration formula     */
258        x = (btScalar(1.5)*x)-(x*x)*(x*z);
259        x = (btScalar(1.5)*x)-(x*x)*(x*z);
260        x = (btScalar(1.5)*x)-(x*x)*(x*z);
261        x = (btScalar(1.5)*x)-(x*x)*(x*z);
262        return x*y;
263#else
[2472]264        return sqrtf(y); 
[1963]265#endif
266}
267SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabsf(x); }
268SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cosf(x); }
269SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); }
270SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); }
[2472]271SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { 
[8284]272        if (x<btScalar(-1))     
273                x=btScalar(-1); 
274        if (x>btScalar(1))     
275                x=btScalar(1);
[2472]276        return acosf(x); 
[1963]277}
[8284]278SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { 
279        if (x<btScalar(-1))     
280                x=btScalar(-1); 
281        if (x>btScalar(1))     
282                x=btScalar(1);
283        return asinf(x); 
284}
[1963]285SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); }
286SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); }
287SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return expf(x); }
288SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return logf(x); }
[2883]289  #if defined( __MINGW32__ )
290  SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return pow(x,y); }
291  #else
292  SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return powf(x,y); }
293  #endif
[8284]294SIMD_FORCE_INLINE btScalar btFmod(btScalar x,btScalar y) { return fmodf(x,y); }
[2882]295       
[1963]296#endif
297
298#define SIMD_2_PI         btScalar(6.283185307179586232)
299#define SIMD_PI           (SIMD_2_PI * btScalar(0.5))
300#define SIMD_HALF_PI      (SIMD_2_PI * btScalar(0.25))
301#define SIMD_RADS_PER_DEG (SIMD_2_PI / btScalar(360.0))
302#define SIMD_DEGS_PER_RAD  (btScalar(360.0) / SIMD_2_PI)
[8284]303#define SIMDSQRT12 btScalar(0.7071067811865475244008443621048490)
[1963]304
[8284]305#define btRecipSqrt(x) ((btScalar)(btScalar(1.0)/btSqrt(btScalar(x))))          /* reciprocal square root */
306
307
[1963]308#ifdef BT_USE_DOUBLE_PRECISION
309#define SIMD_EPSILON      DBL_EPSILON
310#define SIMD_INFINITY     DBL_MAX
311#else
312#define SIMD_EPSILON      FLT_EPSILON
313#define SIMD_INFINITY     FLT_MAX
314#endif
315
[2472]316SIMD_FORCE_INLINE btScalar btAtan2Fast(btScalar y, btScalar x) 
[1963]317{
318        btScalar coeff_1 = SIMD_PI / 4.0f;
319        btScalar coeff_2 = 3.0f * coeff_1;
320        btScalar abs_y = btFabs(y);
321        btScalar angle;
322        if (x >= 0.0f) {
323                btScalar r = (x - abs_y) / (x + abs_y);
324                angle = coeff_1 - coeff_1 * r;
325        } else {
326                btScalar r = (x + abs_y) / (abs_y - x);
327                angle = coeff_2 - coeff_1 * r;
328        }
329        return (y < 0.0f) ? -angle : angle;
330}
331
332SIMD_FORCE_INLINE bool      btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; }
333
334SIMD_FORCE_INLINE bool  btEqual(btScalar a, btScalar eps) {
335        return (((a) <= eps) && !((a) < -eps));
336}
337SIMD_FORCE_INLINE bool  btGreaterEqual (btScalar a, btScalar eps) {
338        return (!((a) <= eps));
339}
340
341
342SIMD_FORCE_INLINE int       btIsNegative(btScalar x) {
343    return x < btScalar(0.0) ? 1 : 0;
344}
345
346SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; }
347SIMD_FORCE_INLINE btScalar btDegrees(btScalar x) { return x * SIMD_DEGS_PER_RAD; }
348
349#define BT_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
350
351#ifndef btFsel
352SIMD_FORCE_INLINE btScalar btFsel(btScalar a, btScalar b, btScalar c)
353{
354        return a >= 0 ? b : c;
355}
356#endif
357#define btFsels(a,b,c) (btScalar)btFsel(a,b,c)
358
359
360SIMD_FORCE_INLINE bool btMachineIsLittleEndian()
361{
362   long int i = 1;
363   const char *p = (const char *) &i;
364   if (p[0] == 1)  // Lowest address contains the least significant byte
365           return true;
366   else
367           return false;
368}
369
370
371
372///btSelect avoids branches, which makes performance much better for consoles like Playstation 3 and XBox 360
373///Thanks Phil Knight. See also http://www.cellperformance.com/articles/2006/04/more_techniques_for_eliminatin_1.html
[2472]374SIMD_FORCE_INLINE unsigned btSelect(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero) 
[1963]375{
376    // Set testNz to 0xFFFFFFFF if condition is nonzero, 0x00000000 if condition is zero
377    // Rely on positive value or'ed with its negative having sign bit on
[2472]378    // and zero value or'ed with its negative (which is still zero) having sign bit off
[1963]379    // Use arithmetic shift right, shifting the sign bit through all 32 bits
380    unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
381    unsigned testEqz = ~testNz;
[2472]382    return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); 
[1963]383}
384SIMD_FORCE_INLINE int btSelect(unsigned condition, int valueIfConditionNonZero, int valueIfConditionZero)
385{
386    unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
[2472]387    unsigned testEqz = ~testNz; 
[1963]388    return static_cast<int>((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz));
389}
390SIMD_FORCE_INLINE float btSelect(unsigned condition, float valueIfConditionNonZero, float valueIfConditionZero)
391{
392#ifdef BT_HAVE_NATIVE_FSEL
393    return (float)btFsel((btScalar)condition - btScalar(1.0f), valueIfConditionNonZero, valueIfConditionZero);
394#else
[2472]395    return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero; 
[1963]396#endif
397}
398
399template<typename T> SIMD_FORCE_INLINE void btSwap(T& a, T& b)
400{
401        T tmp = a;
402        a = b;
403        b = tmp;
404}
405
406
407//PCK: endian swapping functions
408SIMD_FORCE_INLINE unsigned btSwapEndian(unsigned val)
409{
410        return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8)  | ((val & 0x000000ff) << 24));
411}
412
413SIMD_FORCE_INLINE unsigned short btSwapEndian(unsigned short val)
414{
415        return static_cast<unsigned short>(((val & 0xff00) >> 8) | ((val & 0x00ff) << 8));
416}
417
418SIMD_FORCE_INLINE unsigned btSwapEndian(int val)
419{
420        return btSwapEndian((unsigned)val);
421}
422
423SIMD_FORCE_INLINE unsigned short btSwapEndian(short val)
424{
425        return btSwapEndian((unsigned short) val);
426}
427
428///btSwapFloat uses using char pointers to swap the endianness
429////btSwapFloat/btSwapDouble will NOT return a float, because the machine might 'correct' invalid floating point values
[2472]430///Not all values of sign/exponent/mantissa are valid floating point numbers according to IEEE 754.
431///When a floating point unit is faced with an invalid value, it may actually change the value, or worse, throw an exception.
432///In most systems, running user mode code, you wouldn't get an exception, but instead the hardware/os/runtime will 'fix' the number for you.
[1963]433///so instead of returning a float/double, we return integer/long long integer
434SIMD_FORCE_INLINE unsigned int  btSwapEndianFloat(float d)
435{
436    unsigned int a = 0;
437    unsigned char *dst = (unsigned char *)&a;
438    unsigned char *src = (unsigned char *)&d;
439
440    dst[0] = src[3];
441    dst[1] = src[2];
442    dst[2] = src[1];
443    dst[3] = src[0];
444    return a;
445}
446
447// unswap using char pointers
[2472]448SIMD_FORCE_INLINE float btUnswapEndianFloat(unsigned int a) 
[1963]449{
450    float d = 0.0f;
451    unsigned char *src = (unsigned char *)&a;
452    unsigned char *dst = (unsigned char *)&d;
453
454    dst[0] = src[3];
455    dst[1] = src[2];
456    dst[2] = src[1];
457    dst[3] = src[0];
458
459    return d;
460}
461
462
463// swap using char pointers
464SIMD_FORCE_INLINE void  btSwapEndianDouble(double d, unsigned char* dst)
465{
466    unsigned char *src = (unsigned char *)&d;
467
468    dst[0] = src[7];
469    dst[1] = src[6];
470    dst[2] = src[5];
471    dst[3] = src[4];
472    dst[4] = src[3];
473    dst[5] = src[2];
474    dst[6] = src[1];
475    dst[7] = src[0];
476
477}
478
479// unswap using char pointers
[2472]480SIMD_FORCE_INLINE double btUnswapEndianDouble(const unsigned char *src) 
[1963]481{
482    double d = 0.0;
483    unsigned char *dst = (unsigned char *)&d;
484
485    dst[0] = src[7];
486    dst[1] = src[6];
487    dst[2] = src[5];
488    dst[3] = src[4];
489    dst[4] = src[3];
490    dst[5] = src[2];
491    dst[6] = src[1];
492    dst[7] = src[0];
493
494        return d;
495}
496
[8284]497// returns normalized value in range [-SIMD_PI, SIMD_PI]
498SIMD_FORCE_INLINE btScalar btNormalizeAngle(btScalar angleInRadians) 
499{
500        angleInRadians = btFmod(angleInRadians, SIMD_2_PI);
501        if(angleInRadians < -SIMD_PI)
502        {
503                return angleInRadians + SIMD_2_PI;
504        }
505        else if(angleInRadians > SIMD_PI)
506        {
507                return angleInRadians - SIMD_2_PI;
508        }
509        else
510        {
511                return angleInRadians;
512        }
513}
[1963]514
[8284]515///rudimentary class to provide type info
516struct btTypedObject
517{
518        btTypedObject(int objectType)
519                :m_objectType(objectType)
520        {
521        }
522        int     m_objectType;
523        inline int getObjectType() const
524        {
525                return m_objectType;
526        }
527};
[1963]528#endif //SIMD___SCALAR_H
Note: See TracBrowser for help on using the repository browser.