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