Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics_merge/src/bullet/LinearMath/btScalar.h @ 2442

Last change on this file since 2442 was 2442, checked in by rgrieder, 15 years ago

Finally merged physics stuff. Target is physics_merge because I'll have to do some testing first.

  • Property svn:eol-style set to native
File size: 13.2 KB
Line 
1/*
2Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans  http://continuousphysics.com/Bullet/
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#include <math.h>
21
22#include <stdlib.h>//size_t for MSVC 6.0
23
24#include <cstdlib>
25#include <cfloat>
26#include <float.h>
27
28#define BT_BULLET_VERSION 273
29
30inline int      btGetVersion()
31{
32        return BT_BULLET_VERSION;
33}
34
35#if defined(DEBUG) || defined (_DEBUG)
36#define BT_DEBUG
37#endif
38
39
40#ifdef WIN32
41
42                #if defined(__MINGW32__) || defined(__CYGWIN__) || (defined (_MSC_VER) && _MSC_VER < 1300)
43
44                        #define SIMD_FORCE_INLINE inline
45                        #define ATTRIBUTE_ALIGNED16(a) a
46                        #define ATTRIBUTE_ALIGNED128(a) a
47                #else
48                        #define BT_HAS_ALIGNED_ALLOCATOR
49                        #pragma warning(disable : 4324) // disable padding warning
50//                      #pragma warning(disable:4530) // Disable the exception disable but used in MSCV Stl warning.
51//                      #pragma warning(disable:4996) //Turn off warnings about deprecated C routines
52//                      #pragma warning(disable:4786) // Disable the "debug name too long" warning
53
54                        #define SIMD_FORCE_INLINE __forceinline
55                        #define ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a
56                        #define ATTRIBUTE_ALIGNED128(a) __declspec (align(128)) a
57                #ifdef _XBOX
58                        #define BT_USE_VMX128
59
60                        #include <ppcintrinsics.h>
61                        #define BT_HAVE_NATIVE_FSEL
62                        #define btFsel(a,b,c) __fsel((a),(b),(c))
63                #else
64                        #define BT_USE_SSE
65                #endif
66                #endif //__MINGW32__
67
68                #include <assert.h>
69#ifdef BT_DEBUG
70                #define btAssert assert
71#else
72                #define btAssert(x)
73#endif
74                //btFullAssert is optional, slows down a lot
75                #define btFullAssert(x)
76
77                #define btLikely(_c)  _c
78                #define btUnlikely(_c) _c
79
80#else
81       
82#if defined     (__CELLOS_LV2__)
83                #define SIMD_FORCE_INLINE inline
84                #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
85                #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
86                #ifndef assert
87                #include <assert.h>
88                #endif
89#ifdef BT_DEBUG
90                #define btAssert assert
91#else
92                #define btAssert(x)
93#endif
94                //btFullAssert is optional, slows down a lot
95                #define btFullAssert(x)
96
97                #define btLikely(_c)  _c
98                #define btUnlikely(_c) _c
99
100#else
101
102#ifdef USE_LIBSPE2
103
104                #define SIMD_FORCE_INLINE __inline
105                #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
106                #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
107                #ifndef assert
108                #include <assert.h>
109                #endif
110#ifdef BT_DEBUG
111                #define btAssert assert
112#else
113                #define btAssert(x)
114#endif
115                //btFullAssert is optional, slows down a lot
116                #define btFullAssert(x)
117
118
119                #define btLikely(_c)   __builtin_expect((_c), 1)
120                #define btUnlikely(_c) __builtin_expect((_c), 0)
121               
122
123#else
124        //non-windows systems
125
126                #define SIMD_FORCE_INLINE inline
127                #define ATTRIBUTE_ALIGNED16(a) a
128                #define ATTRIBUTE_ALIGNED128(a) a
129                #ifndef assert
130                #include <assert.h>
131                #endif
132
133#if defined(DEBUG) || defined (_DEBUG)
134                #define btAssert assert
135#else
136                #define btAssert(x)
137#endif
138
139                //btFullAssert is optional, slows down a lot
140                #define btFullAssert(x)
141                #define btLikely(_c)  _c
142                #define btUnlikely(_c) _c
143
144
145#endif // LIBSPE2
146
147#endif  //__CELLOS_LV2__
148#endif
149
150/// older compilers (gcc 3.x) and Sun needs double version of sqrt etc.
151/// exclude Apple Intel (i's assumed to be a Macbook or new Intel Dual Core Processor)
152#if defined (__sun) || defined (__sun__) || defined (__sparc) || (defined (__APPLE__) && ! defined (__i386__))
153//use slow double float precision operation on those platforms
154#ifndef BT_USE_DOUBLE_PRECISION
155#define BT_FORCE_DOUBLE_FUNCTIONS
156#endif
157#endif
158
159///The btScalar type abstracts floating point numbers, to easily switch between double and single floating point precision.
160#if defined(BT_USE_DOUBLE_PRECISION)
161typedef double btScalar;
162#else
163typedef float btScalar;
164#endif
165
166
167
168#define BT_DECLARE_ALIGNED_ALLOCATOR() \
169   SIMD_FORCE_INLINE void* operator new(size_t sizeInBytes)   { return btAlignedAlloc(sizeInBytes,16); }   \
170   SIMD_FORCE_INLINE void  operator delete(void* ptr)         { btAlignedFree(ptr); }   \
171   SIMD_FORCE_INLINE void* operator new(size_t, void* ptr)   { return ptr; }   \
172   SIMD_FORCE_INLINE void  operator delete(void*, void*)      { }   \
173   SIMD_FORCE_INLINE void* operator new[](size_t sizeInBytes)   { return btAlignedAlloc(sizeInBytes,16); }   \
174   SIMD_FORCE_INLINE void  operator delete[](void* ptr)         { btAlignedFree(ptr); }   \
175   SIMD_FORCE_INLINE void* operator new[](size_t, void* ptr)   { return ptr; }   \
176   SIMD_FORCE_INLINE void  operator delete[](void*, void*)      { }   \
177
178
179
180#if defined(BT_USE_DOUBLE_PRECISION) || defined(BT_FORCE_DOUBLE_FUNCTIONS)
181               
182SIMD_FORCE_INLINE btScalar btSqrt(btScalar x) { return sqrt(x); }
183SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabs(x); }
184SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cos(x); }
185SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sin(x); }
186SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tan(x); }
187SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { return acos(x); }
188SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { return asin(x); }
189SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atan(x); }
190SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2(x, y); }
191SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return exp(x); }
192SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return log(x); }
193SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return pow(x,y); }
194
195#else
196               
197SIMD_FORCE_INLINE btScalar btSqrt(btScalar y) 
198{ 
199#ifdef USE_APPROXIMATION
200    double x, z, tempf;
201    unsigned long *tfptr = ((unsigned long *)&tempf) + 1;
202
203        tempf = y;
204        *tfptr = (0xbfcdd90a - *tfptr)>>1; /* estimate of 1/sqrt(y) */
205        x =  tempf;
206        z =  y*btScalar(0.5);                        /* hoist out the “/2”    */
207        x = (btScalar(1.5)*x)-(x*x)*(x*z);         /* iteration formula     */
208        x = (btScalar(1.5)*x)-(x*x)*(x*z);
209        x = (btScalar(1.5)*x)-(x*x)*(x*z);
210        x = (btScalar(1.5)*x)-(x*x)*(x*z);
211        x = (btScalar(1.5)*x)-(x*x)*(x*z);
212        return x*y;
213#else
214        return sqrtf(y); 
215#endif
216}
217SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabsf(x); }
218SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cosf(x); }
219SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); }
220SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); }
221SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { 
222        btAssert(x <= btScalar(1.));
223        return acosf(x); 
224}
225SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { return asinf(x); }
226SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); }
227SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); }
228SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return expf(x); }
229SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return logf(x); }
230SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return powf(x,y); }
231       
232#endif
233
234#define SIMD_2_PI         btScalar(6.283185307179586232)
235#define SIMD_PI           (SIMD_2_PI * btScalar(0.5))
236#define SIMD_HALF_PI      (SIMD_2_PI * btScalar(0.25))
237#define SIMD_RADS_PER_DEG (SIMD_2_PI / btScalar(360.0))
238#define SIMD_DEGS_PER_RAD  (btScalar(360.0) / SIMD_2_PI)
239
240#ifdef BT_USE_DOUBLE_PRECISION
241#define SIMD_EPSILON      DBL_EPSILON
242#define SIMD_INFINITY     DBL_MAX
243#else
244#define SIMD_EPSILON      FLT_EPSILON
245#define SIMD_INFINITY     FLT_MAX
246#endif
247
248SIMD_FORCE_INLINE btScalar btAtan2Fast(btScalar y, btScalar x) 
249{
250        btScalar coeff_1 = SIMD_PI / 4.0f;
251        btScalar coeff_2 = 3.0f * coeff_1;
252        btScalar abs_y = btFabs(y);
253        btScalar angle;
254        if (x >= 0.0f) {
255                btScalar r = (x - abs_y) / (x + abs_y);
256                angle = coeff_1 - coeff_1 * r;
257        } else {
258                btScalar r = (x + abs_y) / (abs_y - x);
259                angle = coeff_2 - coeff_1 * r;
260        }
261        return (y < 0.0f) ? -angle : angle;
262}
263
264SIMD_FORCE_INLINE bool      btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; }
265
266SIMD_FORCE_INLINE bool  btEqual(btScalar a, btScalar eps) {
267        return (((a) <= eps) && !((a) < -eps));
268}
269SIMD_FORCE_INLINE bool  btGreaterEqual (btScalar a, btScalar eps) {
270        return (!((a) <= eps));
271}
272
273
274SIMD_FORCE_INLINE int       btIsNegative(btScalar x) {
275    return x < btScalar(0.0) ? 1 : 0;
276}
277
278SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; }
279SIMD_FORCE_INLINE btScalar btDegrees(btScalar x) { return x * SIMD_DEGS_PER_RAD; }
280
281#define BT_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
282
283#ifndef btFsel
284SIMD_FORCE_INLINE btScalar btFsel(btScalar a, btScalar b, btScalar c)
285{
286        return a >= 0 ? b : c;
287}
288#endif
289#define btFsels(a,b,c) (btScalar)btFsel(a,b,c)
290
291
292SIMD_FORCE_INLINE bool btMachineIsLittleEndian()
293{
294   long int i = 1;
295   const char *p = (const char *) &i;
296   if (p[0] == 1)  // Lowest address contains the least significant byte
297           return true;
298   else
299           return false;
300}
301
302
303
304///btSelect avoids branches, which makes performance much better for consoles like Playstation 3 and XBox 360
305///Thanks Phil Knight. See also http://www.cellperformance.com/articles/2006/04/more_techniques_for_eliminatin_1.html
306SIMD_FORCE_INLINE unsigned btSelect(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero) 
307{
308    // Set testNz to 0xFFFFFFFF if condition is nonzero, 0x00000000 if condition is zero
309    // Rely on positive value or'ed with its negative having sign bit on
310    // and zero value or'ed with its negative (which is still zero) having sign bit off
311    // Use arithmetic shift right, shifting the sign bit through all 32 bits
312    unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
313    unsigned testEqz = ~testNz;
314    return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); 
315}
316SIMD_FORCE_INLINE int btSelect(unsigned condition, int valueIfConditionNonZero, int valueIfConditionZero)
317{
318    unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
319    unsigned testEqz = ~testNz; 
320    return static_cast<int>((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz));
321}
322SIMD_FORCE_INLINE float btSelect(unsigned condition, float valueIfConditionNonZero, float valueIfConditionZero)
323{
324#ifdef BT_HAVE_NATIVE_FSEL
325    return (float)btFsel((btScalar)condition - btScalar(1.0f), valueIfConditionNonZero, valueIfConditionZero);
326#else
327    return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero; 
328#endif
329}
330
331template<typename T> SIMD_FORCE_INLINE void btSwap(T& a, T& b)
332{
333        T tmp = a;
334        a = b;
335        b = tmp;
336}
337
338
339//PCK: endian swapping functions
340SIMD_FORCE_INLINE unsigned btSwapEndian(unsigned val)
341{
342        return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8)  | ((val & 0x000000ff) << 24));
343}
344
345SIMD_FORCE_INLINE unsigned short btSwapEndian(unsigned short val)
346{
347        return static_cast<unsigned short>(((val & 0xff00) >> 8) | ((val & 0x00ff) << 8));
348}
349
350SIMD_FORCE_INLINE unsigned btSwapEndian(int val)
351{
352        return btSwapEndian((unsigned)val);
353}
354
355SIMD_FORCE_INLINE unsigned short btSwapEndian(short val)
356{
357        return btSwapEndian((unsigned short) val);
358}
359
360///btSwapFloat uses using char pointers to swap the endianness
361////btSwapFloat/btSwapDouble will NOT return a float, because the machine might 'correct' invalid floating point values
362///Not all values of sign/exponent/mantissa are valid floating point numbers according to IEEE 754.
363///When a floating point unit is faced with an invalid value, it may actually change the value, or worse, throw an exception.
364///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.
365///so instead of returning a float/double, we return integer/long long integer
366SIMD_FORCE_INLINE unsigned int  btSwapEndianFloat(float d)
367{
368    unsigned int a = 0;
369    unsigned char *dst = (unsigned char *)&a;
370    unsigned char *src = (unsigned char *)&d;
371
372    dst[0] = src[3];
373    dst[1] = src[2];
374    dst[2] = src[1];
375    dst[3] = src[0];
376    return a;
377}
378
379// unswap using char pointers
380SIMD_FORCE_INLINE float btUnswapEndianFloat(unsigned int a) 
381{
382    float d = 0.0f;
383    unsigned char *src = (unsigned char *)&a;
384    unsigned char *dst = (unsigned char *)&d;
385
386    dst[0] = src[3];
387    dst[1] = src[2];
388    dst[2] = src[1];
389    dst[3] = src[0];
390
391    return d;
392}
393
394
395// swap using char pointers
396SIMD_FORCE_INLINE void  btSwapEndianDouble(double d, unsigned char* dst)
397{
398    unsigned char *src = (unsigned char *)&d;
399
400    dst[0] = src[7];
401    dst[1] = src[6];
402    dst[2] = src[5];
403    dst[3] = src[4];
404    dst[4] = src[3];
405    dst[5] = src[2];
406    dst[6] = src[1];
407    dst[7] = src[0];
408
409}
410
411// unswap using char pointers
412SIMD_FORCE_INLINE double btUnswapEndianDouble(const unsigned char *src) 
413{
414    double d = 0.0;
415    unsigned char *dst = (unsigned char *)&d;
416
417    dst[0] = src[7];
418    dst[1] = src[6];
419    dst[2] = src[5];
420    dst[3] = src[4];
421    dst[4] = src[3];
422    dst[5] = src[2];
423    dst[6] = src[1];
424    dst[7] = src[0];
425
426        return d;
427}
428
429
430#endif //SIMD___SCALAR_H
Note: See TracBrowser for help on using the repository browser.