Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 8703 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
Line 
1/*
2Copyright (c) 2003-2009 Erwin Coumans  http://bullet.googlecode.com
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.
6Permission is granted to anyone to use this software for any purpose,
7including commercial applications, and to alter it and redistribute it freely,
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
20#ifdef BT_MANAGED_CODE
21//Aligned data types not supported in managed code
22#pragma unmanaged
23#endif
24
25
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
32/* SVN $Revision$ on $Date$ from http://bullet.googlecode.com*/
33#define BT_BULLET_VERSION 277
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
45#ifdef _WIN32
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
51                        #define ATTRIBUTE_ALIGNED64(a) a
52                        #define ATTRIBUTE_ALIGNED128(a) a
53                #else
54                        //#define BT_HAS_ALIGNED_ALLOCATOR
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
62                        #define ATTRIBUTE_ALIGNED64(a) __declspec(align(64)) a
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
71
72#if (defined (_WIN32) && (_MSC_VER) && _MSC_VER >= 1400) && (!defined (BT_USE_DOUBLE_PRECISION))
73                        #define BT_USE_SSE
74                        #include <emmintrin.h>
75#endif
76
77                #endif//_XBOX
78
79                #endif //__MINGW32__
80
81                #include <assert.h>
82#ifdef BT_DEBUG
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
94       
95#if defined     (__CELLOS_LV2__)
96                #define SIMD_FORCE_INLINE inline __attribute__((always_inline))
97                #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
98                #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
99                #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
100                #ifndef assert
101                #include <assert.h>
102                #endif
103#ifdef BT_DEBUG
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);}}
108#else
109        #define btAssert assert
110#endif
111       
112#else
113                #define btAssert(x)
114#endif
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)))
127                #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
128                #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
129                #ifndef assert
130                #include <assert.h>
131                #endif
132#ifdef BT_DEBUG
133                #define btAssert assert
134#else
135                #define btAssert(x)
136#endif
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)
143               
144
145#else
146        //non-windows systems
147
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
174                #define SIMD_FORCE_INLINE inline
175                ///@todo: check out alignment methods for other platforms/compilers
176                ///#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
177                ///#define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
178                ///#define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
179                #define ATTRIBUTE_ALIGNED16(a) a
180                #define ATTRIBUTE_ALIGNED64(a) a
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
196#endif //__APPLE__
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;
207//this number could be bigger in double precision
208#define BT_LARGE_FLOAT 1e30
209#else
210typedef float btScalar;
211//keep BT_LARGE_FLOAT*BT_LARGE_FLOAT < FLT_MAX
212#define BT_LARGE_FLOAT 1e18f
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)
230               
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); }
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); }
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); }
243SIMD_FORCE_INLINE btScalar btFmod(btScalar x,btScalar y) { return fmod(x,y); }
244
245#else
246               
247SIMD_FORCE_INLINE btScalar btSqrt(btScalar y) 
248{ 
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;
256        z =  y*btScalar(0.5);
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
264        return sqrtf(y); 
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); }
271SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { 
272        if (x<btScalar(-1))     
273                x=btScalar(-1); 
274        if (x>btScalar(1))     
275                x=btScalar(1);
276        return acosf(x); 
277}
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}
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); }
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
294SIMD_FORCE_INLINE btScalar btFmod(btScalar x,btScalar y) { return fmodf(x,y); }
295       
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)
303#define SIMDSQRT12 btScalar(0.7071067811865475244008443621048490)
304
305#define btRecipSqrt(x) ((btScalar)(btScalar(1.0)/btSqrt(btScalar(x))))          /* reciprocal square root */
306
307
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
316SIMD_FORCE_INLINE btScalar btAtan2Fast(btScalar y, btScalar x) 
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
374SIMD_FORCE_INLINE unsigned btSelect(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero) 
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
378    // and zero value or'ed with its negative (which is still zero) having sign bit off
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;
382    return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); 
383}
384SIMD_FORCE_INLINE int btSelect(unsigned condition, int valueIfConditionNonZero, int valueIfConditionZero)
385{
386    unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
387    unsigned testEqz = ~testNz; 
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
395    return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero; 
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
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.
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
448SIMD_FORCE_INLINE float btUnswapEndianFloat(unsigned int a) 
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
480SIMD_FORCE_INLINE double btUnswapEndianDouble(const unsigned char *src) 
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
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}
514
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};
528#endif //SIMD___SCALAR_H
Note: See TracBrowser for help on using the repository browser.