Bullet Collision Detection & Physics Library: btScalar.h Source File

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
373 struct btInfMaskConverter
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
417 SIMD_FORCE_INLINE btScalar btSqrt(btScalar x)
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); }
425 SIMD_FORCE_INLINE btScalar btAcos(btScalar x)
426 {
427 if (x < btScalar(-1)) x = btScalar(-1);
428 if (x > btScalar(1)) x = btScalar(1);
429 return acos(x);
430 }
431 SIMD_FORCE_INLINE btScalar btAsin(btScalar x)
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
446 SIMD_FORCE_INLINE btScalar btSqrt(btScalar y)
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); }
481 SIMD_FORCE_INLINE btScalar btAcos(btScalar 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 }
489 SIMD_FORCE_INLINE btScalar btAsin(btScalar x)
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
533 SIMD_FORCE_INLINE btScalar btAtan2Fast(btScalar y, btScalar x)
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
552 SIMD_FORCE_INLINE bool btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; }
553
554 SIMD_FORCE_INLINE bool btEqual(btScalar a, btScalar eps)
555 {
556 return (((a) <= eps) && !((a) < -eps));
557 }
558 SIMD_FORCE_INLINE bool btGreaterEqual(btScalar a, btScalar eps)
559 {
560 return (!((a) <= eps));
561 }
562
563 SIMD_FORCE_INLINE int btIsNegative(btScalar x)
564 {
565 return x < btScalar(0.0) ? 1 : 0;
566 }
567
568 SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; }
569 SIMD_FORCE_INLINE btScalar btDegrees(btScalar x) { return x * SIMD_DEGS_PER_RAD; }
570
571 #define BT_DECLARE_HANDLE(name) \
572 typedef struct name##__ \
573 { \
574 int unused; \
575 } * name
576
577 #ifndef btFsel
578 SIMD_FORCE_INLINE btScalar btFsel(btScalar a, btScalar b, btScalar c)
579 {
580 return a >= 0 ? b : c;
581 }
582 #endif
583 #define btFsels(a, b, c) (btScalar) btFsel(a, b, c)
584
585 SIMD_FORCE_INLINE bool btMachineIsLittleEndian()
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
641 SIMD_FORCE_INLINE unsigned btSwapEndian(int val)
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
657 SIMD_FORCE_INLINE unsigned int btSwapEndianFloat(float d)
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
671 SIMD_FORCE_INLINE float btUnswapEndianFloat(unsigned int a)
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
730 SIMD_FORCE_INLINE btScalar btLargeDot(const btScalar *a, const btScalar *b, int n)
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]
761 SIMD_FORCE_INLINE btScalar btNormalizeAngle(btScalar angleInRadians)
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
779 struct btTypedObject
780 {
781 btTypedObject(int objectType)
782 : m_objectType(objectType)
783 {
784 }
785 int m_objectType;
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
btIsNegative
int btIsNegative(btScalar x)
Definition: btScalar.h:563
sum
static T sum(const btAlignedObjectArray< T > &items)
Definition: btSoftBodyHelpers.cpp:89
SIMD_EPSILON
#define SIMD_EPSILON
Definition: btScalar.h:523
btSelect
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
btRadians
btScalar btRadians(btScalar x)
Definition: btScalar.h:568
btDegrees
btScalar btDegrees(btScalar x)
Definition: btScalar.h:569
btSin
btScalar btSin(btScalar x)
Definition: btScalar.h:479
btSqrt
btScalar btSqrt(btScalar y)
Definition: btScalar.h:446
btGreaterEqual
bool btGreaterEqual(btScalar a, btScalar eps)
Definition: btScalar.h:558
btInfMaskConverter
Definition: btScalar.h:373
SIMD_FORCE_INLINE
#define SIMD_FORCE_INLINE
Definition: btScalar.h:83
btEqual
bool btEqual(btScalar a, btScalar eps)
Definition: btScalar.h:554
operator+
btMatrix3x3 operator+(const btMatrix3x3 &m1, const btMatrix3x3 &m2)
Definition: btMatrix3x3.h:929
btTypedObject::getObjectType
int getObjectType() const
Definition: btScalar.h:786
btFsel
btScalar btFsel(btScalar a, btScalar b, btScalar c)
Definition: btScalar.h:578
SIMD_PI
#define SIMD_PI
Definition: btScalar.h:506
SIMD_2_PI
#define SIMD_2_PI
Definition: btScalar.h:507
btSwap
void btSwap(T &a, T &b)
Definition: btScalar.h:623
btMachineIsLittleEndian
bool btMachineIsLittleEndian()
Definition: btScalar.h:585
btGetInfinityMask
int btGetInfinityMask()
Definition: btScalar.h:386
btAtan2Fast
btScalar btAtan2Fast(btScalar y, btScalar x)
Definition: btScalar.h:533
SIMD_DEGS_PER_RAD
#define SIMD_DEGS_PER_RAD
Definition: btScalar.h:510
btAtan2
btScalar btAtan2(btScalar x, btScalar y)
Definition: btScalar.h:498
btTypedObject::btTypedObject
btTypedObject(int objectType)
Definition: btScalar.h:781
operator*
btMatrix3x3 operator*(const btMatrix3x3 &m, const btScalar &k)
Definition: btMatrix3x3.h:907
btSetZero
void btSetZero(T *a, int n)
Definition: btScalar.h:719
btGetVersion
int btGetVersion()
Definition: btScalar.h:30
btPow
btScalar btPow(btScalar x, btScalar y)
Definition: btScalar.h:501
btAcos
btScalar btAcos(btScalar x)
Definition: btScalar.h:481
btSwapEndianFloat
unsigned int btSwapEndianFloat(float d)
btSwapFloat uses using char pointers to swap the endianness
Definition: btScalar.h:657
btNormalizeAngle
btScalar btNormalizeAngle(btScalar angleInRadians)
Definition: btScalar.h:761
btAtan
btScalar btAtan(btScalar x)
Definition: btScalar.h:497
btLog
btScalar btLog(btScalar x)
Definition: btScalar.h:500
operator-
btMatrix3x3 operator-(const btMatrix3x3 &m1, const btMatrix3x3 &m2)
Definition: btMatrix3x3.h:953
btTypedObject
rudimentary class to provide type info
Definition: btScalar.h:779
btFmod
btScalar btFmod(btScalar x, btScalar y)
Definition: btScalar.h:502
btFuzzyZero
bool btFuzzyZero(btScalar x)
Definition: btScalar.h:552
btInfMaskConverter::intmask
int intmask
Definition: btScalar.h:377
BT_BULLET_VERSION
#define BT_BULLET_VERSION
Definition: btScalar.h:28
btExp
btScalar btExp(btScalar x)
Definition: btScalar.h:499
btSwapEndianDouble
void btSwapEndianDouble(double d, unsigned char *dst)
Definition: btScalar.h:686
btSwapEndian
unsigned btSwapEndian(unsigned val)
Definition: btScalar.h:631
btInfinityMask
static btInfMaskConverter btInfinityMask
Definition: btScalar.h:384
btInfMaskConverter::btInfMaskConverter
btInfMaskConverter(int _mask=0x7F800000)
Definition: btScalar.h:379
btAlignPointer
T * btAlignPointer(T *unalignedPtr, size_t alignment)
align a pointer to the provided alignment, upwards
Definition: btScalar.h:794
btAsin
btScalar btAsin(btScalar x)
Definition: btScalar.h:489
btInfMaskConverter::mask
float mask
Definition: btScalar.h:376
SIMD_RADS_PER_DEG
#define SIMD_RADS_PER_DEG
Definition: btScalar.h:509
btUnswapEndianFloat
float btUnswapEndianFloat(unsigned int a)
Definition: btScalar.h:671
btTan
btScalar btTan(btScalar x)
Definition: btScalar.h:480
btScalar
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:294
btCos
btScalar btCos(btScalar x)
Definition: btScalar.h:478
btLargeDot
btScalar btLargeDot(const btScalar *a, const btScalar *b, int n)
Definition: btScalar.h:730
btTypedObject::m_objectType
int m_objectType
Definition: btScalar.h:785
btFabs
btScalar btFabs(btScalar x)
Definition: btScalar.h:477
btUnswapEndianDouble
double btUnswapEndianDouble(const unsigned char *src)
Definition: btScalar.h:701