Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/external/bullet/LinearMath/btScalar.h @ 10777

Last change on this file since 10777 was 8393, checked in by rgrieder, 14 years ago

Updated Bullet from v2.77 to v2.78.
(I'm not going to make a branch for that since the update from 2.74 to 2.77 hasn't been tested that much either).

You will HAVE to do a complete RECOMPILE! I tested with MSVC and MinGW and they both threw linker errors at me.

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