Windows: Add support for building with clang.
[blender.git] / extern / bullet2 / src / LinearMath / btScalar.h
1 /*
2 Copyright (c) 2003-2009 Erwin Coumans  http://bullet.googlecode.com
3
4 This software is provided 'as-is', without any express or implied warranty.
5 In no event will the authors be held liable for any damages arising from the use of this software.
6 Permission is granted to anyone to use this software for any purpose, 
7 including commercial applications, and to alter it and redistribute it freely, 
8 subject to the following restrictions:
9
10 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.
11 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
12 3. 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 #if defined(_MSC_VER) && defined(__clang__) /* clang supplies it's own overloads already */
20 #define BT_NO_SIMD_OPERATOR_OVERLOADS
21 #endif
22
23 #ifdef BT_MANAGED_CODE
24 //Aligned data types not supported in managed code
25 #pragma unmanaged
26 #endif
27
28
29 #include <math.h>
30 #include <stdlib.h>//size_t for MSVC 6.0
31 #include <float.h>
32
33 /* SVN $Revision$ on $Date$ from http://bullet.googlecode.com*/
34 #define BT_BULLET_VERSION 284
35
36 inline int      btGetVersion()
37 {
38         return BT_BULLET_VERSION;
39 }
40
41 #if defined(DEBUG) || defined (_DEBUG)
42 #define BT_DEBUG
43 #endif
44
45
46 #ifdef _WIN32
47
48                 #if defined(__MINGW32__) || defined(__CYGWIN__) || (defined (_MSC_VER) && _MSC_VER < 1300)
49
50                         #define SIMD_FORCE_INLINE inline
51                         #define ATTRIBUTE_ALIGNED16(a) a
52                         #define ATTRIBUTE_ALIGNED64(a) a
53                         #define ATTRIBUTE_ALIGNED128(a) a
54                 #elif (_M_ARM)
55                         #define SIMD_FORCE_INLINE __forceinline
56                         #define ATTRIBUTE_ALIGNED16(a) __declspec() a
57                         #define ATTRIBUTE_ALIGNED64(a) __declspec() a
58                         #define ATTRIBUTE_ALIGNED128(a) __declspec () a
59                 #else
60                         //#define BT_HAS_ALIGNED_ALLOCATOR
61                         #pragma warning(disable : 4324) // disable padding warning
62 //                      #pragma warning(disable:4530) // Disable the exception disable but used in MSCV Stl warning.
63 //                      #pragma warning(disable:4996) //Turn off warnings about deprecated C routines
64 //                      #pragma warning(disable:4786) // Disable the "debug name too long" warning
65
66                         #define SIMD_FORCE_INLINE __forceinline
67                         #define ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a
68                         #define ATTRIBUTE_ALIGNED64(a) __declspec(align(64)) a
69                         #define ATTRIBUTE_ALIGNED128(a) __declspec (align(128)) a
70                 #ifdef _XBOX
71                         #define BT_USE_VMX128
72
73                         #include <ppcintrinsics.h>
74                         #define BT_HAVE_NATIVE_FSEL
75                         #define btFsel(a,b,c) __fsel((a),(b),(c))
76                 #else
77
78 #if defined (_M_ARM)
79             //Do not turn SSE on for ARM (may want to turn on BT_USE_NEON however)
80 #elif (defined (_WIN32) && (_MSC_VER) && _MSC_VER >= 1400) && (!defined (BT_USE_DOUBLE_PRECISION))
81                         #if _MSC_VER>1400
82                                 #define BT_USE_SIMD_VECTOR3
83                         #endif
84
85                         #define BT_USE_SSE
86                         #ifdef BT_USE_SSE
87
88 #if (_MSC_FULL_VER >= 170050727)//Visual Studio 2012 can compile SSE4/FMA3 (but SSE4/FMA3 is not enabled by default)
89                         //#define BT_ALLOW_SSE4 //disable this cause blender targets sse2 
90 #endif //(_MSC_FULL_VER >= 160040219)
91
92                         //BT_USE_SSE_IN_API is disabled under Windows by default, because 
93                         //it makes it harder to integrate Bullet into your application under Windows 
94                         //(structured embedding Bullet structs/classes need to be 16-byte aligned)
95                         //with relatively little performance gain
96                         //If you are not embedded Bullet data in your classes, or make sure that you align those classes on 16-byte boundaries
97                         //you can manually enable this line or set it in the build system for a bit of performance gain (a few percent, dependent on usage)
98                         //#define BT_USE_SSE_IN_API
99                         #endif //BT_USE_SSE
100                         #include <emmintrin.h>
101 #endif
102
103                 #endif//_XBOX
104
105                 #endif //__MINGW32__
106
107 #ifdef BT_DEBUG
108         #if defined(_MSC_VER) && !defined(__clang__)
109                 #include <stdio.h>
110                 #define btAssert(x) { if(!(x)){printf("Assert "__FILE__ ":%u ("#x")\n", __LINE__);__debugbreak();       }}
111         #else//_MSC_VER
112                 #include <assert.h>
113                 #define btAssert assert
114         #endif//_MSC_VER
115 #else
116                 #define btAssert(x)
117 #endif
118                 //btFullAssert is optional, slows down a lot
119                 #define btFullAssert(x)
120
121                 #define btLikely(_c)  _c
122                 #define btUnlikely(_c) _c
123
124 #else
125         
126 #if defined     (__CELLOS_LV2__)
127                 #define SIMD_FORCE_INLINE inline __attribute__((always_inline))
128                 #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
129                 #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
130                 #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
131                 #ifndef assert
132                 #include <assert.h>
133                 #endif
134 #ifdef BT_DEBUG
135 #ifdef __SPU__
136 #include <spu_printf.h>
137 #define printf spu_printf
138         #define btAssert(x) {if(!(x)){printf("Assert "__FILE__ ":%u ("#x")\n", __LINE__);spu_hcmpeq(0,0);}}
139 #else
140         #define btAssert assert
141 #endif
142         
143 #else
144                 #define btAssert(x)
145 #endif
146                 //btFullAssert is optional, slows down a lot
147                 #define btFullAssert(x)
148
149                 #define btLikely(_c)  _c
150                 #define btUnlikely(_c) _c
151
152 #else
153
154 #ifdef USE_LIBSPE2
155
156                 #define SIMD_FORCE_INLINE __inline
157                 #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
158                 #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
159                 #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
160                 #ifndef assert
161                 #include <assert.h>
162                 #endif
163 #ifdef BT_DEBUG
164                 #define btAssert assert
165 #else
166                 #define btAssert(x)
167 #endif
168                 //btFullAssert is optional, slows down a lot
169                 #define btFullAssert(x)
170
171
172                 #define btLikely(_c)   __builtin_expect((_c), 1)
173                 #define btUnlikely(_c) __builtin_expect((_c), 0)
174                 
175
176 #else
177         //non-windows systems
178
179 #if (defined (__APPLE__) && (!defined (BT_USE_DOUBLE_PRECISION)))
180     #if defined (__i386__) || defined (__x86_64__)
181                 #define BT_USE_SIMD_VECTOR3
182                 #define BT_USE_SSE
183                 //BT_USE_SSE_IN_API is enabled on Mac OSX by default, because memory is automatically aligned on 16-byte boundaries
184                 //if apps run into issues, we will disable the next line
185                 #define BT_USE_SSE_IN_API
186         #ifdef BT_USE_SSE
187             // include appropriate SSE level
188             #if defined (__SSE4_1__)
189                 #include <smmintrin.h>
190             #elif defined (__SSSE3__)
191                 #include <tmmintrin.h>
192             #elif defined (__SSE3__)
193                 #include <pmmintrin.h>
194             #else
195                 #include <emmintrin.h>
196             #endif
197         #endif //BT_USE_SSE
198     #elif defined( __ARM_NEON__ )
199         #ifdef __clang__
200             #define BT_USE_NEON 1
201                         #define BT_USE_SIMD_VECTOR3
202                 
203             #if defined BT_USE_NEON && defined (__clang__)
204                 #include <arm_neon.h>
205             #endif//BT_USE_NEON
206        #endif //__clang__
207     #endif//__arm__
208
209         #define SIMD_FORCE_INLINE inline __attribute__ ((always_inline))
210 ///@todo: check out alignment methods for other platforms/compilers
211         #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
212         #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
213         #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
214         #ifndef assert
215         #include <assert.h>
216         #endif
217
218         #if defined(DEBUG) || defined (_DEBUG)
219          #if defined (__i386__) || defined (__x86_64__)
220         #include <stdio.h>
221          #define btAssert(x)\
222         {\
223         if(!(x))\
224         {\
225                 printf("Assert %s in line %d, file %s\n",#x, __LINE__, __FILE__);\
226                 asm volatile ("int3");\
227         }\
228         }
229         #else//defined (__i386__) || defined (__x86_64__)
230                 #define btAssert assert
231         #endif//defined (__i386__) || defined (__x86_64__)
232         #else//defined(DEBUG) || defined (_DEBUG)
233                 #define btAssert(x)
234         #endif//defined(DEBUG) || defined (_DEBUG)
235
236         //btFullAssert is optional, slows down a lot
237         #define btFullAssert(x)
238         #define btLikely(_c)  _c
239         #define btUnlikely(_c) _c
240
241 #else
242
243                 #define SIMD_FORCE_INLINE inline
244                 ///@todo: check out alignment methods for other platforms/compilers
245                 ///#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
246                 ///#define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
247                 ///#define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
248                 #define ATTRIBUTE_ALIGNED16(a) a
249                 #define ATTRIBUTE_ALIGNED64(a) a
250                 #define ATTRIBUTE_ALIGNED128(a) a
251                 #ifndef assert
252                 #include <assert.h>
253                 #endif
254
255 #if defined(DEBUG) || defined (_DEBUG)
256                 #define btAssert assert
257 #else
258                 #define btAssert(x)
259 #endif
260
261                 //btFullAssert is optional, slows down a lot
262                 #define btFullAssert(x)
263                 #define btLikely(_c)  _c
264                 #define btUnlikely(_c) _c
265 #endif //__APPLE__ 
266
267 #endif // LIBSPE2
268
269 #endif  //__CELLOS_LV2__
270 #endif
271
272
273 ///The btScalar type abstracts floating point numbers, to easily switch between double and single floating point precision.
274 #if defined(BT_USE_DOUBLE_PRECISION)
275
276 typedef double btScalar;
277 //this number could be bigger in double precision
278 #define BT_LARGE_FLOAT 1e30
279 #else
280
281 typedef float btScalar;
282 //keep BT_LARGE_FLOAT*BT_LARGE_FLOAT < FLT_MAX
283 #define BT_LARGE_FLOAT 1e18f
284 #endif
285
286 #ifdef BT_USE_SSE
287 typedef __m128 btSimdFloat4;
288 #endif//BT_USE_SSE
289
290 #if defined (BT_USE_SSE)
291 //#if defined BT_USE_SSE_IN_API && defined (BT_USE_SSE)
292 #ifdef _WIN32
293
294 #ifndef BT_NAN
295 static int btNanMask = 0x7F800001;
296 #define BT_NAN (*(float*)&btNanMask)
297 #endif
298
299 #ifndef BT_INFINITY
300 static  int btInfinityMask = 0x7F800000;
301 #define BT_INFINITY (*(float*)&btInfinityMask)
302 inline int btGetInfinityMask()//suppress stupid compiler warning
303 {
304         return btInfinityMask;
305 }
306 #endif
307
308 //use this, in case there are clashes (such as xnamath.h)
309 #ifndef BT_NO_SIMD_OPERATOR_OVERLOADS
310 inline __m128 operator + (const __m128 A, const __m128 B)
311 {
312     return _mm_add_ps(A, B);
313 }
314
315 inline __m128 operator - (const __m128 A, const __m128 B)
316 {
317     return _mm_sub_ps(A, B);
318 }
319
320 inline __m128 operator * (const __m128 A, const __m128 B)
321 {
322     return _mm_mul_ps(A, B);
323 }
324 #endif //BT_NO_SIMD_OPERATOR_OVERLOADS
325
326 #define btCastfTo128i(a) (_mm_castps_si128(a))
327 #define btCastfTo128d(a) (_mm_castps_pd(a))
328 #define btCastiTo128f(a) (_mm_castsi128_ps(a))
329 #define btCastdTo128f(a) (_mm_castpd_ps(a))
330 #define btCastdTo128i(a) (_mm_castpd_si128(a))
331 #define btAssign128(r0,r1,r2,r3) _mm_setr_ps(r0,r1,r2,r3)
332
333 #else//_WIN32
334
335 #define btCastfTo128i(a) ((__m128i)(a))
336 #define btCastfTo128d(a) ((__m128d)(a))
337 #define btCastiTo128f(a)  ((__m128) (a))
338 #define btCastdTo128f(a) ((__m128) (a))
339 #define btCastdTo128i(a) ((__m128i)(a))
340 #define btAssign128(r0,r1,r2,r3) (__m128){r0,r1,r2,r3}
341 #define BT_INFINITY INFINITY
342 #define BT_NAN NAN
343 #endif//_WIN32
344 #else
345
346 #ifdef BT_USE_NEON
347         #include <arm_neon.h>
348
349         typedef float32x4_t btSimdFloat4;
350         #define BT_INFINITY INFINITY
351         #define BT_NAN NAN
352         #define btAssign128(r0,r1,r2,r3) (float32x4_t){r0,r1,r2,r3}
353 #else//BT_USE_NEON
354
355         #ifndef BT_INFINITY
356                 struct btInfMaskConverter
357                 {
358                         union {
359                                 float mask;
360                                 int intmask;
361                         };
362                         btInfMaskConverter(int mask=0x7F800000)
363                         :intmask(mask)
364                         {
365                         }
366                 };
367                 static btInfMaskConverter btInfinityMask = 0x7F800000;
368                 #define BT_INFINITY (btInfinityMask.mask)
369                 inline int btGetInfinityMask()//suppress stupid compiler warning
370                 {
371                         return btInfinityMask.intmask;
372                 }
373         #endif
374 #endif//BT_USE_NEON
375
376 #endif //BT_USE_SSE
377
378 #ifdef BT_USE_NEON
379 #include <arm_neon.h>
380
381 typedef float32x4_t btSimdFloat4;
382 #define BT_INFINITY INFINITY
383 #define BT_NAN NAN
384 #define btAssign128(r0,r1,r2,r3) (float32x4_t){r0,r1,r2,r3}
385 #endif
386
387
388
389
390
391 #define BT_DECLARE_ALIGNED_ALLOCATOR() \
392    SIMD_FORCE_INLINE void* operator new(size_t sizeInBytes)   { return btAlignedAlloc(sizeInBytes,16); }   \
393    SIMD_FORCE_INLINE void  operator delete(void* ptr)         { btAlignedFree(ptr); }   \
394    SIMD_FORCE_INLINE void* operator new(size_t, void* ptr)   { return ptr; }   \
395    SIMD_FORCE_INLINE void  operator delete(void*, void*)      { }   \
396    SIMD_FORCE_INLINE void* operator new[](size_t sizeInBytes)   { return btAlignedAlloc(sizeInBytes,16); }   \
397    SIMD_FORCE_INLINE void  operator delete[](void* ptr)         { btAlignedFree(ptr); }   \
398    SIMD_FORCE_INLINE void* operator new[](size_t, void* ptr)   { return ptr; }   \
399    SIMD_FORCE_INLINE void  operator delete[](void*, void*)      { }   \
400
401
402
403 #if defined(BT_USE_DOUBLE_PRECISION) || defined(BT_FORCE_DOUBLE_FUNCTIONS)
404                 
405 SIMD_FORCE_INLINE btScalar btSqrt(btScalar x) { return sqrt(x); }
406 SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabs(x); }
407 SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cos(x); }
408 SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sin(x); }
409 SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tan(x); }
410 SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { if (x<btScalar(-1))     x=btScalar(-1); if (x>btScalar(1))      x=btScalar(1); return acos(x); }
411 SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { if (x<btScalar(-1))     x=btScalar(-1); if (x>btScalar(1))      x=btScalar(1); return asin(x); }
412 SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atan(x); }
413 SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2(x, y); }
414 SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return exp(x); }
415 SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return log(x); }
416 SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return pow(x,y); }
417 SIMD_FORCE_INLINE btScalar btFmod(btScalar x,btScalar y) { return fmod(x,y); }
418
419 #else
420                 
421 SIMD_FORCE_INLINE btScalar btSqrt(btScalar y) 
422
423 #ifdef USE_APPROXIMATION
424 #ifdef __LP64__
425     float xhalf = 0.5f*y;
426     int i = *(int*)&y;
427     i = 0x5f375a86 - (i>>1);
428     y = *(float*)&i;
429     y = y*(1.5f - xhalf*y*y);
430     y = y*(1.5f - xhalf*y*y);
431     y = y*(1.5f - xhalf*y*y);
432     y=1/y;
433     return y;
434 #else
435     double x, z, tempf;
436     unsigned long *tfptr = ((unsigned long *)&tempf) + 1;
437     tempf = y;
438     *tfptr = (0xbfcdd90a - *tfptr)>>1; /* estimate of 1/sqrt(y) */
439     x =  tempf;
440     z =  y*btScalar(0.5);
441     x = (btScalar(1.5)*x)-(x*x)*(x*z);         /* iteration formula     */
442     x = (btScalar(1.5)*x)-(x*x)*(x*z);
443     x = (btScalar(1.5)*x)-(x*x)*(x*z);
444     x = (btScalar(1.5)*x)-(x*x)*(x*z);
445     x = (btScalar(1.5)*x)-(x*x)*(x*z);
446     return x*y;
447 #endif
448 #else
449         return sqrtf(y); 
450 #endif
451 }
452 SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabsf(x); }
453 SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cosf(x); }
454 SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); }
455 SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); }
456 SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { 
457         if (x<btScalar(-1))     
458                 x=btScalar(-1); 
459         if (x>btScalar(1))      
460                 x=btScalar(1);
461         return acosf(x); 
462 }
463 SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { 
464         if (x<btScalar(-1))     
465                 x=btScalar(-1); 
466         if (x>btScalar(1))      
467                 x=btScalar(1);
468         return asinf(x); 
469 }
470 SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); }
471 SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); }
472 SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return expf(x); }
473 SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return logf(x); }
474 SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return powf(x,y); }
475 SIMD_FORCE_INLINE btScalar btFmod(btScalar x,btScalar y) { return fmodf(x,y); }
476         
477 #endif
478
479 #define SIMD_PI           btScalar(3.1415926535897932384626433832795029)
480 #define SIMD_2_PI         (btScalar(2.0) * SIMD_PI)
481 #define SIMD_HALF_PI      (SIMD_PI * btScalar(0.5))
482 #define SIMD_RADS_PER_DEG (SIMD_2_PI / btScalar(360.0))
483 #define SIMD_DEGS_PER_RAD  (btScalar(360.0) / SIMD_2_PI)
484 #define SIMDSQRT12 btScalar(0.7071067811865475244008443621048490)
485
486 #define btRecipSqrt(x) ((btScalar)(btScalar(1.0)/btSqrt(btScalar(x))))          /* reciprocal square root */
487 #define btRecip(x) (btScalar(1.0)/btScalar(x))
488
489 #ifdef BT_USE_DOUBLE_PRECISION
490 #define SIMD_EPSILON      DBL_EPSILON
491 #define SIMD_INFINITY     DBL_MAX
492 #define BT_ONE                  1.0
493 #define BT_ZERO                 0.0
494 #define BT_TWO                  2.0
495 #define BT_HALF                 0.5
496 #else
497 #define SIMD_EPSILON      FLT_EPSILON
498 #define SIMD_INFINITY     FLT_MAX
499 #define BT_ONE                  1.0f
500 #define BT_ZERO                 0.0f
501 #define BT_TWO                  2.0f
502 #define BT_HALF                 0.5f
503 #endif
504
505 SIMD_FORCE_INLINE btScalar btAtan2Fast(btScalar y, btScalar x) 
506 {
507         btScalar coeff_1 = SIMD_PI / 4.0f;
508         btScalar coeff_2 = 3.0f * coeff_1;
509         btScalar abs_y = btFabs(y);
510         btScalar angle;
511         if (x >= 0.0f) {
512                 btScalar r = (x - abs_y) / (x + abs_y);
513                 angle = coeff_1 - coeff_1 * r;
514         } else {
515                 btScalar r = (x + abs_y) / (abs_y - x);
516                 angle = coeff_2 - coeff_1 * r;
517         }
518         return (y < 0.0f) ? -angle : angle;
519 }
520
521 SIMD_FORCE_INLINE bool      btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; }
522
523 SIMD_FORCE_INLINE bool  btEqual(btScalar a, btScalar eps) {
524         return (((a) <= eps) && !((a) < -eps));
525 }
526 SIMD_FORCE_INLINE bool  btGreaterEqual (btScalar a, btScalar eps) {
527         return (!((a) <= eps));
528 }
529
530
531 SIMD_FORCE_INLINE int       btIsNegative(btScalar x) {
532     return x < btScalar(0.0) ? 1 : 0;
533 }
534
535 SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; }
536 SIMD_FORCE_INLINE btScalar btDegrees(btScalar x) { return x * SIMD_DEGS_PER_RAD; }
537
538 #define BT_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
539
540 #ifndef btFsel
541 SIMD_FORCE_INLINE btScalar btFsel(btScalar a, btScalar b, btScalar c)
542 {
543         return a >= 0 ? b : c;
544 }
545 #endif
546 #define btFsels(a,b,c) (btScalar)btFsel(a,b,c)
547
548
549 SIMD_FORCE_INLINE bool btMachineIsLittleEndian()
550 {
551    long int i = 1;
552    const char *p = (const char *) &i;
553    if (p[0] == 1)  // Lowest address contains the least significant byte
554            return true;
555    else
556            return false;
557 }
558
559
560
561 ///btSelect avoids branches, which makes performance much better for consoles like Playstation 3 and XBox 360
562 ///Thanks Phil Knight. See also http://www.cellperformance.com/articles/2006/04/more_techniques_for_eliminatin_1.html
563 SIMD_FORCE_INLINE unsigned btSelect(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero) 
564 {
565     // Set testNz to 0xFFFFFFFF if condition is nonzero, 0x00000000 if condition is zero
566     // Rely on positive value or'ed with its negative having sign bit on
567     // and zero value or'ed with its negative (which is still zero) having sign bit off 
568     // Use arithmetic shift right, shifting the sign bit through all 32 bits
569     unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
570     unsigned testEqz = ~testNz;
571     return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); 
572 }
573 SIMD_FORCE_INLINE int btSelect(unsigned condition, int valueIfConditionNonZero, int valueIfConditionZero)
574 {
575     unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
576     unsigned testEqz = ~testNz; 
577     return static_cast<int>((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz));
578 }
579 SIMD_FORCE_INLINE float btSelect(unsigned condition, float valueIfConditionNonZero, float valueIfConditionZero)
580 {
581 #ifdef BT_HAVE_NATIVE_FSEL
582     return (float)btFsel((btScalar)condition - btScalar(1.0f), valueIfConditionNonZero, valueIfConditionZero);
583 #else
584     return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero; 
585 #endif
586 }
587
588 template<typename T> SIMD_FORCE_INLINE void btSwap(T& a, T& b)
589 {
590         T tmp = a;
591         a = b;
592         b = tmp;
593 }
594
595
596 //PCK: endian swapping functions
597 SIMD_FORCE_INLINE unsigned btSwapEndian(unsigned val)
598 {
599         return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8)  | ((val & 0x000000ff) << 24));
600 }
601
602 SIMD_FORCE_INLINE unsigned short btSwapEndian(unsigned short val)
603 {
604         return static_cast<unsigned short>(((val & 0xff00) >> 8) | ((val & 0x00ff) << 8));
605 }
606
607 SIMD_FORCE_INLINE unsigned btSwapEndian(int val)
608 {
609         return btSwapEndian((unsigned)val);
610 }
611
612 SIMD_FORCE_INLINE unsigned short btSwapEndian(short val)
613 {
614         return btSwapEndian((unsigned short) val);
615 }
616
617 ///btSwapFloat uses using char pointers to swap the endianness
618 ////btSwapFloat/btSwapDouble will NOT return a float, because the machine might 'correct' invalid floating point values
619 ///Not all values of sign/exponent/mantissa are valid floating point numbers according to IEEE 754. 
620 ///When a floating point unit is faced with an invalid value, it may actually change the value, or worse, throw an exception. 
621 ///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. 
622 ///so instead of returning a float/double, we return integer/long long integer
623 SIMD_FORCE_INLINE unsigned int  btSwapEndianFloat(float d)
624 {
625     unsigned int a = 0;
626     unsigned char *dst = (unsigned char *)&a;
627     unsigned char *src = (unsigned char *)&d;
628
629     dst[0] = src[3];
630     dst[1] = src[2];
631     dst[2] = src[1];
632     dst[3] = src[0];
633     return a;
634 }
635
636 // unswap using char pointers
637 SIMD_FORCE_INLINE float btUnswapEndianFloat(unsigned int a) 
638 {
639     float d = 0.0f;
640     unsigned char *src = (unsigned char *)&a;
641     unsigned char *dst = (unsigned char *)&d;
642
643     dst[0] = src[3];
644     dst[1] = src[2];
645     dst[2] = src[1];
646     dst[3] = src[0];
647
648     return d;
649 }
650
651
652 // swap using char pointers
653 SIMD_FORCE_INLINE void  btSwapEndianDouble(double d, unsigned char* dst)
654 {
655     unsigned char *src = (unsigned char *)&d;
656
657     dst[0] = src[7];
658     dst[1] = src[6];
659     dst[2] = src[5];
660     dst[3] = src[4];
661     dst[4] = src[3];
662     dst[5] = src[2];
663     dst[6] = src[1];
664     dst[7] = src[0];
665
666 }
667
668 // unswap using char pointers
669 SIMD_FORCE_INLINE double btUnswapEndianDouble(const unsigned char *src) 
670 {
671     double d = 0.0;
672     unsigned char *dst = (unsigned char *)&d;
673
674     dst[0] = src[7];
675     dst[1] = src[6];
676     dst[2] = src[5];
677     dst[3] = src[4];
678     dst[4] = src[3];
679     dst[5] = src[2];
680     dst[6] = src[1];
681     dst[7] = src[0];
682
683         return d;
684 }
685
686 template<typename T>
687 SIMD_FORCE_INLINE void btSetZero(T* a, int n)
688 {
689   T* acurr = a;
690   size_t ncurr = n;
691   while (ncurr > 0) 
692   {
693     *(acurr++) = 0;
694     --ncurr;
695   }
696 }
697
698
699 SIMD_FORCE_INLINE btScalar btLargeDot(const btScalar *a, const btScalar *b, int n)
700 {  
701   btScalar p0,q0,m0,p1,q1,m1,sum;
702   sum = 0;
703   n -= 2;
704   while (n >= 0) {
705     p0 = a[0]; q0 = b[0];
706     m0 = p0 * q0;
707     p1 = a[1]; q1 = b[1];
708     m1 = p1 * q1;
709     sum += m0;
710     sum += m1;
711     a += 2;
712     b += 2;
713     n -= 2;
714   }
715   n += 2;
716   while (n > 0) {
717     sum += (*a) * (*b);
718     a++;
719     b++;
720     n--;
721   }
722   return sum;
723 }
724
725
726 // returns normalized value in range [-SIMD_PI, SIMD_PI]
727 SIMD_FORCE_INLINE btScalar btNormalizeAngle(btScalar angleInRadians) 
728 {
729         angleInRadians = btFmod(angleInRadians, SIMD_2_PI);
730         if(angleInRadians < -SIMD_PI)
731         {
732                 return angleInRadians + SIMD_2_PI;
733         }
734         else if(angleInRadians > SIMD_PI)
735         {
736                 return angleInRadians - SIMD_2_PI;
737         }
738         else
739         {
740                 return angleInRadians;
741         }
742 }
743
744
745
746 ///rudimentary class to provide type info
747 struct btTypedObject
748 {
749         btTypedObject(int objectType)
750                 :m_objectType(objectType)
751         {
752         }
753         int     m_objectType;
754         inline int getObjectType() const
755         {
756                 return m_objectType;
757         }
758 };
759
760
761   
762 ///align a pointer to the provided alignment, upwards
763 template <typename T>T* btAlignPointer(T* unalignedPtr, size_t alignment)
764 {
765                 
766         struct btConvertPointerSizeT
767         {
768                 union 
769                 {
770                                 T* ptr;
771                                 size_t integer;
772                 };
773         };
774     btConvertPointerSizeT converter;
775     
776     
777         const size_t bit_mask = ~(alignment - 1);
778     converter.ptr = unalignedPtr;
779         converter.integer += alignment-1;
780         converter.integer &= bit_mask;
781         return converter.ptr;
782 }
783
784
785 #endif //BT_SCALAR_H