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