2 Copyright (c) 2003-2009 Erwin Coumans http://bullet.googlecode.com
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:
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.
18 #ifdef BT_MANAGED_CODE
19 //Aligned data types not supported in managed code
24 #include <stdlib.h> //size_t for MSVC 6.0
27 /* SVN $Revision$ on $Date$ from http://bullet.googlecode.com*/
28 #define BT_BULLET_VERSION 325
30 inline int btGetVersion()
32 return BT_BULLET_VERSION;
35 inline int btIsDoublePrecision()
37 #ifdef BT_USE_DOUBLE_PRECISION
45 // The following macro "BT_NOT_EMPTY_FILE" can be put into a file
46 // in order suppress the MS Visual C++ Linker warning 4221
48 // warning LNK4221: no public symbols found; archive member will be inaccessible
50 // This warning occurs on PC and XBOX when a file compiles out completely
51 // has no externally visible symbols which may be dependant on configuration
52 // #defines and options.
54 // see more https://stackoverflow.com/questions/1822887/what-is-the-best-way-to-eliminate-ms-visual-c-linker-warning-warning-lnk422
57 #define BT_NOT_EMPTY_FILE_CAT_II(p, res) res
58 #define BT_NOT_EMPTY_FILE_CAT_I(a, b) BT_NOT_EMPTY_FILE_CAT_II(~, a##b)
59 #define BT_NOT_EMPTY_FILE_CAT(a, b) BT_NOT_EMPTY_FILE_CAT_I(a, b)
60 #define BT_NOT_EMPTY_FILE \
63 char BT_NOT_EMPTY_FILE_CAT(NoEmptyFileDummy, __COUNTER__); \
66 #define BT_NOT_EMPTY_FILE
69 // clang and most formatting tools don't support indentation of preprocessor guards, so turn it off
71 #if defined(DEBUG) || defined (_DEBUG)
76 #if defined(__GNUC__) // it should handle both MINGW and CYGWIN
77 #define SIMD_FORCE_INLINE __inline__ __attribute__((always_inline))
78 #define ATTRIBUTE_ALIGNED16(a) a __attribute__((aligned(16)))
79 #define ATTRIBUTE_ALIGNED64(a) a __attribute__((aligned(64)))
80 #define ATTRIBUTE_ALIGNED128(a) a __attribute__((aligned(128)))
81 #elif ( defined(_MSC_VER) && _MSC_VER < 1300 )
82 #define SIMD_FORCE_INLINE inline
83 #define ATTRIBUTE_ALIGNED16(a) a
84 #define ATTRIBUTE_ALIGNED64(a) a
85 #define ATTRIBUTE_ALIGNED128(a) a
87 #define SIMD_FORCE_INLINE __forceinline
88 #define ATTRIBUTE_ALIGNED16(a) __declspec() a
89 #define ATTRIBUTE_ALIGNED64(a) __declspec() a
90 #define ATTRIBUTE_ALIGNED128(a) __declspec () a
92 //#define BT_HAS_ALIGNED_ALLOCATOR
93 #pragma warning(disable : 4324) // disable padding warning
94 // #pragma warning(disable:4530) // Disable the exception disable but used in MSCV Stl warning.
95 #pragma warning(disable:4996) //Turn off warnings about deprecated C routines
96 // #pragma warning(disable:4786) // Disable the "debug name too long" warning
98 #define SIMD_FORCE_INLINE __forceinline
99 #define ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a
100 #define ATTRIBUTE_ALIGNED64(a) __declspec(align(64)) a
101 #define ATTRIBUTE_ALIGNED128(a) __declspec (align(128)) a
103 #define BT_USE_VMX128
105 #include <ppcintrinsics.h>
106 #define BT_HAVE_NATIVE_FSEL
107 #define btFsel(a,b,c) __fsel((a),(b),(c))
110 #if defined (_M_ARM) || defined (_M_ARM64)
111 //Do not turn SSE on for ARM (may want to turn on BT_USE_NEON however)
112 #elif (defined (_WIN32) && (_MSC_VER) && _MSC_VER >= 1400) && (!defined (BT_USE_DOUBLE_PRECISION))
115 #define __BT_DISABLE_SSE__
117 #ifndef __BT_DISABLE_SSE__
119 #define BT_USE_SIMD_VECTOR3
122 #endif//__BT_DISABLE_SSE__
125 #if (_MSC_FULL_VER >= 170050727)//Visual Studio 2012 can compile SSE4/FMA3 (but SSE4/FMA3 is not enabled by default)
126 #define BT_ALLOW_SSE4
127 #endif //(_MSC_FULL_VER >= 160040219)
129 //BT_USE_SSE_IN_API is disabled under Windows by default, because
130 //it makes it harder to integrate Bullet into your application under Windows
131 //(structured embedding Bullet structs/classes need to be 16-byte aligned)
132 //with relatively little performance gain
133 //If you are not embedded Bullet data in your classes, or make sure that you align those classes on 16-byte boundaries
134 //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)
135 //#define BT_USE_SSE_IN_API
137 #include <emmintrin.h>
147 #define btAssert(x) { if(!(x)){printf("Assert " __FILE__ ":%u (%s)\n", __LINE__, #x);__debugbreak(); }}
150 #define btAssert assert
155 //btFullAssert is optional, slows down a lot
156 #define btFullAssert(x)
158 #define btLikely(_c) _c
159 #define btUnlikely(_c) _c
163 #if defined (__CELLOS_LV2__)
164 #define SIMD_FORCE_INLINE inline __attribute__((always_inline))
165 #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
166 #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
167 #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
173 #include <spu_printf.h>
174 #define printf spu_printf
175 #define btAssert(x) {if(!(x)){printf("Assert " __FILE__ ":%u ("#x")\n", __LINE__);spu_hcmpeq(0,0);}}
177 #define btAssert assert
183 //btFullAssert is optional, slows down a lot
184 #define btFullAssert(x)
186 #define btLikely(_c) _c
187 #define btUnlikely(_c) _c
189 #else//defined (__CELLOS_LV2__)
193 #define SIMD_FORCE_INLINE __inline
194 #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
195 #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
196 #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
201 #define btAssert assert
205 //btFullAssert is optional, slows down a lot
206 #define btFullAssert(x)
209 #define btLikely(_c) __builtin_expect((_c), 1)
210 #define btUnlikely(_c) __builtin_expect((_c), 0)
214 //non-windows systems
216 #if (defined (__APPLE__) && (!defined (BT_USE_DOUBLE_PRECISION)))
217 #if defined (__i386__) || defined (__x86_64__)
218 #define BT_USE_SIMD_VECTOR3
220 //BT_USE_SSE_IN_API is enabled on Mac OSX by default, because memory is automatically aligned on 16-byte boundaries
221 //if apps run into issues, we will disable the next line
222 #define BT_USE_SSE_IN_API
224 // include appropriate SSE level
225 #if defined (__SSE4_1__)
226 #include <smmintrin.h>
227 #elif defined (__SSSE3__)
228 #include <tmmintrin.h>
229 #elif defined (__SSE3__)
230 #include <pmmintrin.h>
232 #include <emmintrin.h>
235 #elif defined( __ARM_NEON__ )
237 #define BT_USE_NEON 1
238 #define BT_USE_SIMD_VECTOR3
240 #if defined BT_USE_NEON && defined (__clang__)
241 #include <arm_neon.h>
246 #define SIMD_FORCE_INLINE inline __attribute__ ((always_inline))
247 ///@todo: check out alignment methods for other platforms/compilers
248 #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
249 #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
250 #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
255 #if defined(DEBUG) || defined (_DEBUG)
256 #if defined (__i386__) || defined (__x86_64__)
262 printf("Assert %s in line %d, file %s\n",#x, __LINE__, __FILE__);\
263 asm volatile ("int3");\
266 #else//defined (__i386__) || defined (__x86_64__)
267 #define btAssert assert
268 #endif//defined (__i386__) || defined (__x86_64__)
269 #else//defined(DEBUG) || defined (_DEBUG)
271 #endif//defined(DEBUG) || defined (_DEBUG)
273 //btFullAssert is optional, slows down a lot
274 #define btFullAssert(x)
275 #define btLikely(_c) _c
276 #define btUnlikely(_c) _c
280 #define SIMD_FORCE_INLINE inline
281 ///@todo: check out alignment methods for other platforms/compilers
282 ///#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
283 ///#define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
284 ///#define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
285 #define ATTRIBUTE_ALIGNED16(a) a
286 #define ATTRIBUTE_ALIGNED64(a) a
287 #define ATTRIBUTE_ALIGNED128(a) a
292 #if defined(DEBUG) || defined (_DEBUG)
293 #define btAssert assert
298 //btFullAssert is optional, slows down a lot
299 #define btFullAssert(x)
300 #define btLikely(_c) _c
301 #define btUnlikely(_c) _c
304 #endif //__CELLOS_LV2__
308 ///The btScalar type abstracts floating point numbers, to easily switch between double and single floating point precision.
309 #if defined(BT_USE_DOUBLE_PRECISION)
310 typedef double btScalar;
311 //this number could be bigger in double precision
312 #define BT_LARGE_FLOAT 1e30
314 typedef float btScalar;
315 //keep BT_LARGE_FLOAT*BT_LARGE_FLOAT < FLT_MAX
316 #define BT_LARGE_FLOAT 1e18f
320 typedef __m128 btSimdFloat4;
323 #if defined(BT_USE_SSE)
324 //#if defined BT_USE_SSE_IN_API && defined (BT_USE_SSE)
328 static int btNanMask = 0x7F800001;
329 #define BT_NAN (*(float *)&btNanMask)
333 static int btInfinityMask = 0x7F800000;
334 #define BT_INFINITY (*(float *)&btInfinityMask)
335 inline int btGetInfinityMask() //suppress stupid compiler warning
337 return btInfinityMask;
343 //use this, in case there are clashes (such as xnamath.h)
344 #ifndef BT_NO_SIMD_OPERATOR_OVERLOADS
345 inline __m128 operator+(const __m128 A, const __m128 B)
347 return _mm_add_ps(A, B);
350 inline __m128 operator-(const __m128 A, const __m128 B)
352 return _mm_sub_ps(A, B);
355 inline __m128 operator*(const __m128 A, const __m128 B)
357 return _mm_mul_ps(A, B);
359 #endif //BT_NO_SIMD_OPERATOR_OVERLOADS
361 #define btCastfTo128i(a) (_mm_castps_si128(a))
362 #define btCastfTo128d(a) (_mm_castps_pd(a))
363 #define btCastiTo128f(a) (_mm_castsi128_ps(a))
364 #define btCastdTo128f(a) (_mm_castpd_ps(a))
365 #define btCastdTo128i(a) (_mm_castpd_si128(a))
366 #define btAssign128(r0, r1, r2, r3) _mm_setr_ps(r0, r1, r2, r3)
370 #define btCastfTo128i(a) ((__m128i)(a))
371 #define btCastfTo128d(a) ((__m128d)(a))
372 #define btCastiTo128f(a) ((__m128)(a))
373 #define btCastdTo128f(a) ((__m128)(a))
374 #define btCastdTo128i(a) ((__m128i)(a))
375 #define btAssign128(r0, r1, r2, r3) \
376 (__m128) { r0, r1, r2, r3 }
377 #define BT_INFINITY INFINITY
383 #include <arm_neon.h>
385 typedef float32x4_t btSimdFloat4;
386 #define BT_INFINITY INFINITY
388 #define btAssign128(r0, r1, r2, r3) \
389 (float32x4_t) { r0, r1, r2, r3 }
393 struct btInfMaskConverter
399 btInfMaskConverter(int _mask = 0x7F800000)
404 static btInfMaskConverter btInfinityMask = 0x7F800000;
405 #define BT_INFINITY (btInfinityMask.mask)
406 inline int btGetInfinityMask() //suppress stupid compiler warning
408 return btInfinityMask.intmask;
416 #include <arm_neon.h>
418 typedef float32x4_t btSimdFloat4;
419 #define BT_INFINITY INFINITY
421 #define btAssign128(r0, r1, r2, r3) \
422 (float32x4_t) { r0, r1, r2, r3 }
425 #define BT_DECLARE_ALIGNED_ALLOCATOR() \
426 SIMD_FORCE_INLINE void *operator new(size_t sizeInBytes) { return btAlignedAlloc(sizeInBytes, 16); } \
427 SIMD_FORCE_INLINE void operator delete(void *ptr) { btAlignedFree(ptr); } \
428 SIMD_FORCE_INLINE void *operator new(size_t, void *ptr) { return ptr; } \
429 SIMD_FORCE_INLINE void operator delete(void *, void *) {} \
430 SIMD_FORCE_INLINE void *operator new[](size_t sizeInBytes) { return btAlignedAlloc(sizeInBytes, 16); } \
431 SIMD_FORCE_INLINE void operator delete[](void *ptr) { btAlignedFree(ptr); } \
432 SIMD_FORCE_INLINE void *operator new[](size_t, void *ptr) { return ptr; } \
433 SIMD_FORCE_INLINE void operator delete[](void *, void *) {}
435 #if defined(BT_USE_DOUBLE_PRECISION) || defined(BT_FORCE_DOUBLE_FUNCTIONS)
437 SIMD_FORCE_INLINE btScalar btSqrt(btScalar x)
441 SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabs(x); }
442 SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cos(x); }
443 SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sin(x); }
444 SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tan(x); }
445 SIMD_FORCE_INLINE btScalar btAcos(btScalar x)
447 if (x < btScalar(-1)) x = btScalar(-1);
448 if (x > btScalar(1)) x = btScalar(1);
451 SIMD_FORCE_INLINE btScalar btAsin(btScalar x)
453 if (x < btScalar(-1)) x = btScalar(-1);
454 if (x > btScalar(1)) x = btScalar(1);
457 SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atan(x); }
458 SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2(x, y); }
459 SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return exp(x); }
460 SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return log(x); }
461 SIMD_FORCE_INLINE btScalar btPow(btScalar x, btScalar y) { return pow(x, y); }
462 SIMD_FORCE_INLINE btScalar btFmod(btScalar x, btScalar y) { return fmod(x, y); }
464 #else//BT_USE_DOUBLE_PRECISION
466 SIMD_FORCE_INLINE btScalar btSqrt(btScalar y)
468 #ifdef USE_APPROXIMATION
470 float xhalf = 0.5f * y;
472 i = 0x5f375a86 - (i >> 1);
474 y = y * (1.5f - xhalf * y * y);
475 y = y * (1.5f - xhalf * y * y);
476 y = y * (1.5f - xhalf * y * y);
481 unsigned long *tfptr = ((unsigned long *)&tempf) + 1;
483 *tfptr = (0xbfcdd90a - *tfptr) >> 1; /* estimate of 1/sqrt(y) */
485 z = y * btScalar(0.5);
486 x = (btScalar(1.5) * x) - (x * x) * (x * z); /* iteration formula */
487 x = (btScalar(1.5) * x) - (x * x) * (x * z);
488 x = (btScalar(1.5) * x) - (x * x) * (x * z);
489 x = (btScalar(1.5) * x) - (x * x) * (x * z);
490 x = (btScalar(1.5) * x) - (x * x) * (x * z);
497 SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabsf(x); }
498 SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cosf(x); }
499 SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); }
500 SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); }
501 SIMD_FORCE_INLINE btScalar btAcos(btScalar x)
503 if (x < btScalar(-1))
509 SIMD_FORCE_INLINE btScalar btAsin(btScalar x)
511 if (x < btScalar(-1))
517 SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); }
518 SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); }
519 SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return expf(x); }
520 SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return logf(x); }
521 SIMD_FORCE_INLINE btScalar btPow(btScalar x, btScalar y) { return powf(x, y); }
522 SIMD_FORCE_INLINE btScalar btFmod(btScalar x, btScalar y) { return fmodf(x, y); }
524 #endif//BT_USE_DOUBLE_PRECISION
526 #define SIMD_PI btScalar(3.1415926535897932384626433832795029)
527 #define SIMD_2_PI (btScalar(2.0) * SIMD_PI)
528 #define SIMD_HALF_PI (SIMD_PI * btScalar(0.5))
529 #define SIMD_RADS_PER_DEG (SIMD_2_PI / btScalar(360.0))
530 #define SIMD_DEGS_PER_RAD (btScalar(360.0) / SIMD_2_PI)
531 #define SIMDSQRT12 btScalar(0.7071067811865475244008443621048490)
532 #define btRecipSqrt(x) ((btScalar)(btScalar(1.0) / btSqrt(btScalar(x)))) /* reciprocal square root */
533 #define btRecip(x) (btScalar(1.0) / btScalar(x))
535 #ifdef BT_USE_DOUBLE_PRECISION
536 #define SIMD_EPSILON DBL_EPSILON
537 #define SIMD_INFINITY DBL_MAX
543 #define SIMD_EPSILON FLT_EPSILON
544 #define SIMD_INFINITY FLT_MAX
553 SIMD_FORCE_INLINE btScalar btAtan2Fast(btScalar y, btScalar x)
555 btScalar coeff_1 = SIMD_PI / 4.0f;
556 btScalar coeff_2 = 3.0f * coeff_1;
557 btScalar abs_y = btFabs(y);
561 btScalar r = (x - abs_y) / (x + abs_y);
562 angle = coeff_1 - coeff_1 * r;
566 btScalar r = (x + abs_y) / (abs_y - x);
567 angle = coeff_2 - coeff_1 * r;
569 return (y < 0.0f) ? -angle : angle;
572 SIMD_FORCE_INLINE bool btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; }
574 SIMD_FORCE_INLINE bool btEqual(btScalar a, btScalar eps)
576 return (((a) <= eps) && !((a) < -eps));
578 SIMD_FORCE_INLINE bool btGreaterEqual(btScalar a, btScalar eps)
580 return (!((a) <= eps));
583 SIMD_FORCE_INLINE int btIsNegative(btScalar x)
585 return x < btScalar(0.0) ? 1 : 0;
588 SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; }
589 SIMD_FORCE_INLINE btScalar btDegrees(btScalar x) { return x * SIMD_DEGS_PER_RAD; }
591 #define BT_DECLARE_HANDLE(name) \
592 typedef struct name##__ \
598 SIMD_FORCE_INLINE btScalar btFsel(btScalar a, btScalar b, btScalar c)
600 return a >= 0 ? b : c;
603 #define btFsels(a, b, c) (btScalar) btFsel(a, b, c)
605 SIMD_FORCE_INLINE bool btMachineIsLittleEndian()
608 const char *p = (const char *)&i;
609 if (p[0] == 1) // Lowest address contains the least significant byte
615 ///btSelect avoids branches, which makes performance much better for consoles like Playstation 3 and XBox 360
616 ///Thanks Phil Knight. See also http://www.cellperformance.com/articles/2006/04/more_techniques_for_eliminatin_1.html
617 SIMD_FORCE_INLINE unsigned btSelect(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero)
619 // Set testNz to 0xFFFFFFFF if condition is nonzero, 0x00000000 if condition is zero
620 // Rely on positive value or'ed with its negative having sign bit on
621 // and zero value or'ed with its negative (which is still zero) having sign bit off
622 // Use arithmetic shift right, shifting the sign bit through all 32 bits
623 unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
624 unsigned testEqz = ~testNz;
625 return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz));
627 SIMD_FORCE_INLINE int btSelect(unsigned condition, int valueIfConditionNonZero, int valueIfConditionZero)
629 unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
630 unsigned testEqz = ~testNz;
631 return static_cast<int>((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz));
633 SIMD_FORCE_INLINE float btSelect(unsigned condition, float valueIfConditionNonZero, float valueIfConditionZero)
635 #ifdef BT_HAVE_NATIVE_FSEL
636 return (float)btFsel((btScalar)condition - btScalar(1.0f), valueIfConditionNonZero, valueIfConditionZero);
638 return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero;
642 template <typename T>
643 SIMD_FORCE_INLINE void btSwap(T &a, T &b)
650 //PCK: endian swapping functions
651 SIMD_FORCE_INLINE unsigned btSwapEndian(unsigned val)
653 return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
656 SIMD_FORCE_INLINE unsigned short btSwapEndian(unsigned short val)
658 return static_cast<unsigned short>(((val & 0xff00) >> 8) | ((val & 0x00ff) << 8));
661 SIMD_FORCE_INLINE unsigned btSwapEndian(int val)
663 return btSwapEndian((unsigned)val);
666 SIMD_FORCE_INLINE unsigned short btSwapEndian(short val)
668 return btSwapEndian((unsigned short)val);
671 ///btSwapFloat uses using char pointers to swap the endianness
672 ////btSwapFloat/btSwapDouble will NOT return a float, because the machine might 'correct' invalid floating point values
673 ///Not all values of sign/exponent/mantissa are valid floating point numbers according to IEEE 754.
674 ///When a floating point unit is faced with an invalid value, it may actually change the value, or worse, throw an exception.
675 ///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.
676 ///so instead of returning a float/double, we return integer/long long integer
677 SIMD_FORCE_INLINE unsigned int btSwapEndianFloat(float d)
680 unsigned char *dst = (unsigned char *)&a;
681 unsigned char *src = (unsigned char *)&d;
690 // unswap using char pointers
691 SIMD_FORCE_INLINE float btUnswapEndianFloat(unsigned int a)
694 unsigned char *src = (unsigned char *)&a;
695 unsigned char *dst = (unsigned char *)&d;
705 // swap using char pointers
706 SIMD_FORCE_INLINE void btSwapEndianDouble(double d, unsigned char *dst)
708 unsigned char *src = (unsigned char *)&d;
720 // unswap using char pointers
721 SIMD_FORCE_INLINE double btUnswapEndianDouble(const unsigned char *src)
724 unsigned char *dst = (unsigned char *)&d;
738 template <typename T>
739 SIMD_FORCE_INLINE void btSetZero(T *a, int n)
750 SIMD_FORCE_INLINE btScalar btLargeDot(const btScalar *a, const btScalar *b, int n)
752 btScalar p0, q0, m0, p1, q1, m1, sum;
780 // returns normalized value in range [-SIMD_PI, SIMD_PI]
781 SIMD_FORCE_INLINE btScalar btNormalizeAngle(btScalar angleInRadians)
783 angleInRadians = btFmod(angleInRadians, SIMD_2_PI);
784 if (angleInRadians < -SIMD_PI)
786 return angleInRadians + SIMD_2_PI;
788 else if (angleInRadians > SIMD_PI)
790 return angleInRadians - SIMD_2_PI;
794 return angleInRadians;
798 ///rudimentary class to provide type info
801 btTypedObject(int objectType)
802 : m_objectType(objectType)
806 inline int getObjectType() const
812 ///align a pointer to the provided alignment, upwards
813 template <typename T>
814 T *btAlignPointer(T *unalignedPtr, size_t alignment)
816 struct btConvertPointerSizeT
823 btConvertPointerSizeT converter;
825 const size_t bit_mask = ~(alignment - 1);
826 converter.ptr = unalignedPtr;
827 converter.integer += alignment - 1;
828 converter.integer &= bit_mask;
829 return converter.ptr;