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