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 287
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
371 struct btInfMaskConverter
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
415 SIMD_FORCE_INLINE btScalar btSqrt(btScalar x)
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); }
423 SIMD_FORCE_INLINE btScalar btAcos(btScalar x)
424 {
425 if (x < btScalar(-1)) x = btScalar(-1);
426 if (x > btScalar(1)) x = btScalar(1);
427 return acos(x);
428 }
429 SIMD_FORCE_INLINE btScalar btAsin(btScalar x)
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
444 SIMD_FORCE_INLINE btScalar btSqrt(btScalar y)
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); }
479 SIMD_FORCE_INLINE btScalar btAcos(btScalar 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 }
487 SIMD_FORCE_INLINE btScalar btAsin(btScalar x)
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
531 SIMD_FORCE_INLINE btScalar btAtan2Fast(btScalar y, btScalar x)
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
550 SIMD_FORCE_INLINE bool btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; }
551
552 SIMD_FORCE_INLINE bool btEqual(btScalar a, btScalar eps)
553 {
554 return (((a) <= eps) && !((a) < -eps));
555 }
556 SIMD_FORCE_INLINE bool btGreaterEqual(btScalar a, btScalar eps)
557 {
558 return (!((a) <= eps));
559 }
560
561 SIMD_FORCE_INLINE int btIsNegative(btScalar x)
562 {
563 return x < btScalar(0.0) ? 1 : 0;
564 }
565
566 SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; }
567 SIMD_FORCE_INLINE btScalar btDegrees(btScalar x) { return x * SIMD_DEGS_PER_RAD; }
568
569 #define BT_DECLARE_HANDLE(name) \
570 typedef struct name##__ \
571 { \
572 int unused; \
573 } * name
574
575 #ifndef btFsel
576 SIMD_FORCE_INLINE btScalar btFsel(btScalar a, btScalar b, btScalar c)
577 {
578 return a >= 0 ? b : c;
579 }
580 #endif
581 #define btFsels(a, b, c) (btScalar) btFsel(a, b, c)
582
583 SIMD_FORCE_INLINE bool btMachineIsLittleEndian()
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
639 SIMD_FORCE_INLINE unsigned btSwapEndian(int val)
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
655 SIMD_FORCE_INLINE unsigned int btSwapEndianFloat(float d)
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
669 SIMD_FORCE_INLINE float btUnswapEndianFloat(unsigned int a)
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
728 SIMD_FORCE_INLINE btScalar btLargeDot(const btScalar *a, const btScalar *b, int n)
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]
759 SIMD_FORCE_INLINE btScalar btNormalizeAngle(btScalar angleInRadians)
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
777 struct btTypedObject
778 {
779 btTypedObject(int objectType)
780 : m_objectType(objectType)
781 {
782 }
783 int m_objectType;
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
btIsNegative
int btIsNegative(btScalar x)
Definition: btScalar.h:561
sum
static T sum(const btAlignedObjectArray< T > &items)
Definition: btSoftBodyHelpers.cpp:84
SIMD_EPSILON
#define SIMD_EPSILON
Definition: btScalar.h:521
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:595
btRadians
btScalar btRadians(btScalar x)
Definition: btScalar.h:566
btDegrees
btScalar btDegrees(btScalar x)
Definition: btScalar.h:567
btSin
btScalar btSin(btScalar x)
Definition: btScalar.h:477
btSqrt
btScalar btSqrt(btScalar y)
Definition: btScalar.h:444
btGreaterEqual
bool btGreaterEqual(btScalar a, btScalar eps)
Definition: btScalar.h:556
btInfMaskConverter
Definition: btScalar.h:371
SIMD_FORCE_INLINE
#define SIMD_FORCE_INLINE
Definition: btScalar.h:81
btEqual
bool btEqual(btScalar a, btScalar eps)
Definition: btScalar.h:552
operator+
btMatrix3x3 operator+(const btMatrix3x3 &m1, const btMatrix3x3 &m2)
Definition: btMatrix3x3.h:858
btTypedObject::getObjectType
int getObjectType() const
Definition: btScalar.h:784
btFsel
btScalar btFsel(btScalar a, btScalar b, btScalar c)
Definition: btScalar.h:576
SIMD_PI
#define SIMD_PI
Definition: btScalar.h:504
SIMD_2_PI
#define SIMD_2_PI
Definition: btScalar.h:505
btSwap
void btSwap(T &a, T &b)
Definition: btScalar.h:621
btMachineIsLittleEndian
bool btMachineIsLittleEndian()
Definition: btScalar.h:583
btGetInfinityMask
int btGetInfinityMask()
Definition: btScalar.h:384
btAtan2Fast
btScalar btAtan2Fast(btScalar y, btScalar x)
Definition: btScalar.h:531
SIMD_DEGS_PER_RAD
#define SIMD_DEGS_PER_RAD
Definition: btScalar.h:508
btAtan2
btScalar btAtan2(btScalar x, btScalar y)
Definition: btScalar.h:496
btTypedObject::btTypedObject
btTypedObject(int objectType)
Definition: btScalar.h:779
operator*
btMatrix3x3 operator*(const btMatrix3x3 &m, const btScalar &k)
Definition: btMatrix3x3.h:836
btSetZero
void btSetZero(T *a, int n)
Definition: btScalar.h:717
btGetVersion
int btGetVersion()
Definition: btScalar.h:30
btPow
btScalar btPow(btScalar x, btScalar y)
Definition: btScalar.h:499
btAcos
btScalar btAcos(btScalar x)
Definition: btScalar.h:479
btSwapEndianFloat
unsigned int btSwapEndianFloat(float d)
btSwapFloat uses using char pointers to swap the endianness
Definition: btScalar.h:655
btNormalizeAngle
btScalar btNormalizeAngle(btScalar angleInRadians)
Definition: btScalar.h:759
btAtan
btScalar btAtan(btScalar x)
Definition: btScalar.h:495
btLog
btScalar btLog(btScalar x)
Definition: btScalar.h:498
operator-
btMatrix3x3 operator-(const btMatrix3x3 &m1, const btMatrix3x3 &m2)
Definition: btMatrix3x3.h:882
btTypedObject
rudimentary class to provide type info
Definition: btScalar.h:777
btFmod
btScalar btFmod(btScalar x, btScalar y)
Definition: btScalar.h:500
btFuzzyZero
bool btFuzzyZero(btScalar x)
Definition: btScalar.h:550
btInfMaskConverter::intmask
int intmask
Definition: btScalar.h:375
BT_BULLET_VERSION
#define BT_BULLET_VERSION
Definition: btScalar.h:28
btExp
btScalar btExp(btScalar x)
Definition: btScalar.h:497
btSwapEndianDouble
void btSwapEndianDouble(double d, unsigned char *dst)
Definition: btScalar.h:684
btSwapEndian
unsigned btSwapEndian(unsigned val)
Definition: btScalar.h:629
btInfinityMask
static btInfMaskConverter btInfinityMask
Definition: btScalar.h:382
btInfMaskConverter::btInfMaskConverter
btInfMaskConverter(int _mask=0x7F800000)
Definition: btScalar.h:377
btAlignPointer
T * btAlignPointer(T *unalignedPtr, size_t alignment)
align a pointer to the provided alignment, upwards
Definition: btScalar.h:792
btAsin
btScalar btAsin(btScalar x)
Definition: btScalar.h:487
btInfMaskConverter::mask
float mask
Definition: btScalar.h:374
SIMD_RADS_PER_DEG
#define SIMD_RADS_PER_DEG
Definition: btScalar.h:507
btUnswapEndianFloat
float btUnswapEndianFloat(unsigned int a)
Definition: btScalar.h:669
btTan
btScalar btTan(btScalar x)
Definition: btScalar.h:478
btScalar
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:292
btCos
btScalar btCos(btScalar x)
Definition: btScalar.h:476
btLargeDot
btScalar btLargeDot(const btScalar *a, const btScalar *b, int n)
Definition: btScalar.h:728
btTypedObject::m_objectType
int m_objectType
Definition: btScalar.h:783
btFabs
btScalar btFabs(btScalar x)
Definition: btScalar.h:475
btUnswapEndianDouble
double btUnswapEndianDouble(const unsigned char *src)
Definition: btScalar.h:699