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

Bullet Collision Detection & Physics Library

btScalar.h
Go to the documentation of this file.
1/*
2Copyright (c) 2003-2009 Erwin Coumans http://bullet.googlecode.com
3
4This software is provided 'as-is', without any express or implied warranty.
5In no event will the authors be held liable for any damages arising from the use of this software.
6Permission is granted to anyone to use this software for any purpose,
7including commercial applications, and to alter it and redistribute it freely,
8subject to the following restrictions:
9
101. 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.
112. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
123. 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 324
29
30 inline int btGetVersion()
31{
32 return BT_BULLET_VERSION;
33}
34
35 inline int btIsDoublePrecision()
36{
37 #ifdef BT_USE_DOUBLE_PRECISION
38 return true;
39 #else
40 return false;
41 #endif
42}
43
44
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
47//
48// warning LNK4221: no public symbols found; archive member will be inaccessible
49//
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.
53//
54// see more https://stackoverflow.com/questions/1822887/what-is-the-best-way-to-eliminate-ms-visual-c-linker-warning-warning-lnk422
55
56#if defined(_MSC_VER)
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 \
61 namespace \
62 { \
63 char BT_NOT_EMPTY_FILE_CAT(NoEmptyFileDummy, __COUNTER__); \
64 }
65#else
66#define BT_NOT_EMPTY_FILE
67#endif
68
69// clang and most formatting tools don't support indentation of preprocessor guards, so turn it off
70// clang-format off
71#if defined(DEBUG) || defined (_DEBUG)
72 #define BT_DEBUG
73#endif
74
75#ifdef _WIN32
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
86 #elif defined(_M_ARM)
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
91 #else//__MINGW32__
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
97
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
102 #ifdef _XBOX
103 #define BT_USE_VMX128
104
105 #include <ppcintrinsics.h>
106 #define BT_HAVE_NATIVE_FSEL
107 #define btFsel(a,b,c) __fsel((a),(b),(c))
108 #else
109
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))
113
114#ifdef __clang__
115#define __BT_DISABLE_SSE__
116#endif
117#ifndef __BT_DISABLE_SSE__
118 #if _MSC_VER>1400
119 #define BT_USE_SIMD_VECTOR3
120 #endif
121 #define BT_USE_SSE
122#endif//__BT_DISABLE_SSE__
123 #ifdef BT_USE_SSE
124
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)
128
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
136 #endif //BT_USE_SSE
137 #include <emmintrin.h>
138#endif
139
140 #endif//_XBOX
141
142 #endif //__MINGW32__
143
144 #ifdef BT_DEBUG
145 #ifdef _MSC_VER
146 #include <stdio.h>
147 #define btAssert(x) { if(!(x)){printf("Assert " __FILE__ ":%u (%s)\n", __LINE__, #x);__debugbreak(); }}
148 #else//_MSC_VER
149 #include <assert.h>
150 #define btAssert assert
151 #endif//_MSC_VER
152 #else
153 #define btAssert(x)
154 #endif
155 //btFullAssert is optional, slows down a lot
156 #define btFullAssert(x)
157
158 #define btLikely(_c) _c
159 #define btUnlikely(_c) _c
160
161#else//_WIN32
162
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)))
168 #ifndef assert
169 #include <assert.h>
170 #endif
171 #ifdef BT_DEBUG
172 #ifdef __SPU__
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);}}
176 #else
177 #define btAssert assert
178 #endif
179
180 #else//BT_DEBUG
181 #define btAssert(x)
182 #endif//BT_DEBUG
183 //btFullAssert is optional, slows down a lot
184 #define btFullAssert(x)
185
186 #define btLikely(_c) _c
187 #define btUnlikely(_c) _c
188
189 #else//defined (__CELLOS_LV2__)
190
191 #ifdef USE_LIBSPE2
192
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)))
197 #ifndef assert
198 #include <assert.h>
199 #endif
200 #ifdef BT_DEBUG
201 #define btAssert assert
202 #else
203 #define btAssert(x)
204 #endif
205 //btFullAssert is optional, slows down a lot
206 #define btFullAssert(x)
207
208
209 #define btLikely(_c) __builtin_expect((_c), 1)
210 #define btUnlikely(_c) __builtin_expect((_c), 0)
211
212
213 #else//USE_LIBSPE2
214 //non-windows systems
215
216 #if (defined (__APPLE__) && (!defined (BT_USE_DOUBLE_PRECISION)))
217 #if defined (__i386__) || defined (__x86_64__)
218 #define BT_USE_SIMD_VECTOR3
219 #define BT_USE_SSE
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
223 #ifdef BT_USE_SSE
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>
231 #else
232 #include <emmintrin.h>
233 #endif
234 #endif //BT_USE_SSE
235 #elif defined( __ARM_NEON__ )
236 #ifdef __clang__
237 #define BT_USE_NEON 1
238 #define BT_USE_SIMD_VECTOR3
239
240 #if defined BT_USE_NEON && defined (__clang__)
241 #include <arm_neon.h>
242 #endif//BT_USE_NEON
243 #endif //__clang__
244 #endif//__arm__
245
246 #define SIMD_FORCE_INLINE inline __attribute__ ((always_inline))
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)))
251 #ifndef assert
252 #include <assert.h>
253 #endif
254
255 #if defined(DEBUG) || defined (_DEBUG)
256 #if defined (__i386__) || defined (__x86_64__)
257 #include <stdio.h>
258 #define btAssert(x)\
259 {\
260 if(!(x))\
261 {\
262 printf("Assert %s in line %d, file %s\n",#x, __LINE__, __FILE__);\
263 asm volatile ("int3");\
264 }\
265 }
266 #else//defined (__i386__) || defined (__x86_64__)
267 #define btAssert assert
268 #endif//defined (__i386__) || defined (__x86_64__)
269 #else//defined(DEBUG) || defined (_DEBUG)
270 #define btAssert(x)
271 #endif//defined(DEBUG) || defined (_DEBUG)
272
273 //btFullAssert is optional, slows down a lot
274 #define btFullAssert(x)
275 #define btLikely(_c) _c
276 #define btUnlikely(_c) _c
277
278 #else//__APPLE__
279
280 #define SIMD_FORCE_INLINE inline
285 #define ATTRIBUTE_ALIGNED16(a) a
286 #define ATTRIBUTE_ALIGNED64(a) a
287 #define ATTRIBUTE_ALIGNED128(a) a
288 #ifndef assert
289 #include <assert.h>
290 #endif
291
292 #if defined(DEBUG) || defined (_DEBUG)
293 #define btAssert assert
294 #else
295 #define btAssert(x)
296 #endif
297
298 //btFullAssert is optional, slows down a lot
299 #define btFullAssert(x)
300 #define btLikely(_c) _c
301 #define btUnlikely(_c) _c
302 #endif //__APPLE__
303 #endif // LIBSPE2
304 #endif //__CELLOS_LV2__
305#endif//_WIN32
306
307
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
313#else
314 typedef float btScalar;
315 //keep BT_LARGE_FLOAT*BT_LARGE_FLOAT < FLT_MAX
316 #define BT_LARGE_FLOAT 1e18f
317#endif
318
319#ifdef BT_USE_SSE
320 typedef __m128 btSimdFloat4;
321#endif //BT_USE_SSE
322
323#if defined(BT_USE_SSE)
324 //#if defined BT_USE_SSE_IN_API && defined (BT_USE_SSE)
325 #ifdef _WIN32
326
327 #ifndef BT_NAN
328 static int btNanMask = 0x7F800001;
329 #define BT_NAN (*(float *)&btNanMask)
330 #endif
331
332 #ifndef BT_INFINITY
333 static int btInfinityMask = 0x7F800000;
334 #define BT_INFINITY (*(float *)&btInfinityMask)
335 inline int btGetInfinityMask() //suppress stupid compiler warning
336 {
337 return btInfinityMask;
338 }
339 #endif
340
341
342
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)
346 {
347 return _mm_add_ps(A, B);
348 }
349
350 inline __m128 operator-(const __m128 A, const __m128 B)
351 {
352 return _mm_sub_ps(A, B);
353 }
354
355 inline __m128 operator*(const __m128 A, const __m128 B)
356 {
357 return _mm_mul_ps(A, B);
358 }
359 #endif //BT_NO_SIMD_OPERATOR_OVERLOADS
360
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)
367
368 #else //_WIN32
369
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
378 #define BT_NAN NAN
379 #endif //_WIN32
380#else//BT_USE_SSE
381
382 #ifdef BT_USE_NEON
383 #include <arm_neon.h>
384
385 typedef float32x4_t btSimdFloat4;
386 #define BT_INFINITY INFINITY
387 #define BT_NAN NAN
388 #define btAssign128(r0, r1, r2, r3) \
389 (float32x4_t) { r0, r1, r2, r3 }
390 #else //BT_USE_NEON
391
392 #ifndef BT_INFINITY
393 struct btInfMaskConverter
394 {
395 union {
396 float mask;
397 int intmask;
398 };
399 btInfMaskConverter(int _mask = 0x7F800000)
400 : intmask(_mask)
401 {
402 }
403 };
404 static btInfMaskConverter btInfinityMask = 0x7F800000;
405 #define BT_INFINITY (btInfinityMask.mask)
406 inline int btGetInfinityMask() //suppress stupid compiler warning
407 {
408 return btInfinityMask.intmask;
409 }
410 #endif
411 #endif //BT_USE_NEON
412
413#endif //BT_USE_SSE
414
415#ifdef BT_USE_NEON
416 #include <arm_neon.h>
417
418 typedef float32x4_t btSimdFloat4;
419 #define BT_INFINITY INFINITY
420 #define BT_NAN NAN
421 #define btAssign128(r0, r1, r2, r3) \
422 (float32x4_t) { r0, r1, r2, r3 }
423#endif//BT_USE_NEON
424
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 *) {}
434
435#if defined(BT_USE_DOUBLE_PRECISION) || defined(BT_FORCE_DOUBLE_FUNCTIONS)
436
437 SIMD_FORCE_INLINE btScalar btSqrt(btScalar x)
438 {
439 return sqrt(x);
440 }
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)
446 {
447 if (x < btScalar(-1)) x = btScalar(-1);
448 if (x > btScalar(1)) x = btScalar(1);
449 return acos(x);
450 }
451 SIMD_FORCE_INLINE btScalar btAsin(btScalar x)
452 {
453 if (x < btScalar(-1)) x = btScalar(-1);
454 if (x > btScalar(1)) x = btScalar(1);
455 return asin(x);
456 }
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); }
463
464#else//BT_USE_DOUBLE_PRECISION
465
466 SIMD_FORCE_INLINE btScalar btSqrt(btScalar y)
467 {
468 #ifdef USE_APPROXIMATION
469 #ifdef __LP64__
470 float xhalf = 0.5f * y;
471 int i = *(int *)&y;
472 i = 0x5f375a86 - (i >> 1);
473 y = *(float *)&i;
474 y = y * (1.5f - xhalf * y * y);
475 y = y * (1.5f - xhalf * y * y);
476 y = y * (1.5f - xhalf * y * y);
477 y = 1 / y;
478 return y;
479 #else
480 double x, z, tempf;
481 unsigned long *tfptr = ((unsigned long *)&tempf) + 1;
482 tempf = y;
483 *tfptr = (0xbfcdd90a - *tfptr) >> 1; /* estimate of 1/sqrt(y) */
484 x = tempf;
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);
491 return x * y;
492 #endif
493 #else
494 return sqrtf(y);
495 #endif
496 }
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)
502 {
503 if (x < btScalar(-1))
504 x = btScalar(-1);
505 if (x > btScalar(1))
506 x = btScalar(1);
507 return acosf(x);
508 }
509 SIMD_FORCE_INLINE btScalar btAsin(btScalar x)
510 {
511 if (x < btScalar(-1))
512 x = btScalar(-1);
513 if (x > btScalar(1))
514 x = btScalar(1);
515 return asinf(x);
516 }
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); }
523
524#endif//BT_USE_DOUBLE_PRECISION
525
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))
534
535#ifdef BT_USE_DOUBLE_PRECISION
536 #define SIMD_EPSILON DBL_EPSILON
537 #define SIMD_INFINITY DBL_MAX
538 #define BT_ONE 1.0
539 #define BT_ZERO 0.0
540 #define BT_TWO 2.0
541 #define BT_HALF 0.5
542#else
543 #define SIMD_EPSILON FLT_EPSILON
544 #define SIMD_INFINITY FLT_MAX
545 #define BT_ONE 1.0f
546 #define BT_ZERO 0.0f
547 #define BT_TWO 2.0f
548 #define BT_HALF 0.5f
549#endif
550
551// clang-format on
552
553 SIMD_FORCE_INLINE btScalar btAtan2Fast(btScalar y, btScalar x)
554{
555 btScalar coeff_1 = SIMD_PI / 4.0f;
556 btScalar coeff_2 = 3.0f * coeff_1;
557 btScalar abs_y = btFabs(y);
558 btScalar angle;
559 if (x >= 0.0f)
560 {
561 btScalar r = (x - abs_y) / (x + abs_y);
562 angle = coeff_1 - coeff_1 * r;
563 }
564 else
565 {
566 btScalar r = (x + abs_y) / (abs_y - x);
567 angle = coeff_2 - coeff_1 * r;
568 }
569 return (y < 0.0f) ? -angle : angle;
570}
571
572 SIMD_FORCE_INLINE bool btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; }
573
574 SIMD_FORCE_INLINE bool btEqual(btScalar a, btScalar eps)
575{
576 return (((a) <= eps) && !((a) < -eps));
577}
578 SIMD_FORCE_INLINE bool btGreaterEqual(btScalar a, btScalar eps)
579{
580 return (!((a) <= eps));
581}
582
583 SIMD_FORCE_INLINE int btIsNegative(btScalar x)
584{
585 return x < btScalar(0.0) ? 1 : 0;
586}
587
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; }
590
591#define BT_DECLARE_HANDLE(name) \
592 typedef struct name##__ \
593 { \
594 int unused; \
595 } * name
596
597#ifndef btFsel
598 SIMD_FORCE_INLINE btScalar btFsel(btScalar a, btScalar b, btScalar c)
599{
600 return a >= 0 ? b : c;
601}
602#endif
603#define btFsels(a, b, c) (btScalar) btFsel(a, b, c)
604
605 SIMD_FORCE_INLINE bool btMachineIsLittleEndian()
606{
607 long int i = 1;
608 const char *p = (const char *)&i;
609 if (p[0] == 1) // Lowest address contains the least significant byte
610 return true;
611 else
612 return false;
613}
614
617 SIMD_FORCE_INLINE unsigned btSelect(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero)
618{
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));
626}
627 SIMD_FORCE_INLINE int btSelect(unsigned condition, int valueIfConditionNonZero, int valueIfConditionZero)
628{
629 unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
630 unsigned testEqz = ~testNz;
631 return static_cast<int>((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz));
632}
633 SIMD_FORCE_INLINE float btSelect(unsigned condition, float valueIfConditionNonZero, float valueIfConditionZero)
634{
635#ifdef BT_HAVE_NATIVE_FSEL
636 return (float)btFsel((btScalar)condition - btScalar(1.0f), valueIfConditionNonZero, valueIfConditionZero);
637#else
638 return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero;
639#endif
640}
641
642template <typename T>
643 SIMD_FORCE_INLINE void btSwap(T &a, T &b)
644{
645 T tmp = a;
646 a = b;
647 b = tmp;
648}
649
650//PCK: endian swapping functions
651 SIMD_FORCE_INLINE unsigned btSwapEndian(unsigned val)
652{
653 return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
654}
655
656 SIMD_FORCE_INLINE unsigned short btSwapEndian(unsigned short val)
657{
658 return static_cast<unsigned short>(((val & 0xff00) >> 8) | ((val & 0x00ff) << 8));
659}
660
661 SIMD_FORCE_INLINE unsigned btSwapEndian(int val)
662{
663 return btSwapEndian((unsigned)val);
664}
665
666 SIMD_FORCE_INLINE unsigned short btSwapEndian(short val)
667{
668 return btSwapEndian((unsigned short)val);
669}
670
677 SIMD_FORCE_INLINE unsigned int btSwapEndianFloat(float d)
678{
679 unsigned int a = 0;
680 unsigned char *dst = (unsigned char *)&a;
681 unsigned char *src = (unsigned char *)&d;
682
683 dst[0] = src[3];
684 dst[1] = src[2];
685 dst[2] = src[1];
686 dst[3] = src[0];
687 return a;
688}
689
690// unswap using char pointers
691 SIMD_FORCE_INLINE float btUnswapEndianFloat(unsigned int a)
692{
693 float d = 0.0f;
694 unsigned char *src = (unsigned char *)&a;
695 unsigned char *dst = (unsigned char *)&d;
696
697 dst[0] = src[3];
698 dst[1] = src[2];
699 dst[2] = src[1];
700 dst[3] = src[0];
701
702 return d;
703}
704
705// swap using char pointers
706 SIMD_FORCE_INLINE void btSwapEndianDouble(double d, unsigned char *dst)
707{
708 unsigned char *src = (unsigned char *)&d;
709
710 dst[0] = src[7];
711 dst[1] = src[6];
712 dst[2] = src[5];
713 dst[3] = src[4];
714 dst[4] = src[3];
715 dst[5] = src[2];
716 dst[6] = src[1];
717 dst[7] = src[0];
718}
719
720// unswap using char pointers
721 SIMD_FORCE_INLINE double btUnswapEndianDouble(const unsigned char *src)
722{
723 double d = 0.0;
724 unsigned char *dst = (unsigned char *)&d;
725
726 dst[0] = src[7];
727 dst[1] = src[6];
728 dst[2] = src[5];
729 dst[3] = src[4];
730 dst[4] = src[3];
731 dst[5] = src[2];
732 dst[6] = src[1];
733 dst[7] = src[0];
734
735 return d;
736}
737
738template <typename T>
739 SIMD_FORCE_INLINE void btSetZero(T *a, int n)
740{
741 T *acurr = a;
742 size_t ncurr = n;
743 while (ncurr > 0)
744 {
745 *(acurr++) = 0;
746 --ncurr;
747 }
748}
749
750 SIMD_FORCE_INLINE btScalar btLargeDot(const btScalar *a, const btScalar *b, int n)
751{
752 btScalar p0, q0, m0, p1, q1, m1, sum;
753 sum = 0;
754 n -= 2;
755 while (n >= 0)
756 {
757 p0 = a[0];
758 q0 = b[0];
759 m0 = p0 * q0;
760 p1 = a[1];
761 q1 = b[1];
762 m1 = p1 * q1;
763 sum += m0;
764 sum += m1;
765 a += 2;
766 b += 2;
767 n -= 2;
768 }
769 n += 2;
770 while (n > 0)
771 {
772 sum += (*a) * (*b);
773 a++;
774 b++;
775 n--;
776 }
777 return sum;
778}
779
780// returns normalized value in range [-SIMD_PI, SIMD_PI]
781 SIMD_FORCE_INLINE btScalar btNormalizeAngle(btScalar angleInRadians)
782{
783 angleInRadians = btFmod(angleInRadians, SIMD_2_PI);
784 if (angleInRadians < -SIMD_PI)
785 {
786 return angleInRadians + SIMD_2_PI;
787 }
788 else if (angleInRadians > SIMD_PI)
789 {
790 return angleInRadians - SIMD_2_PI;
791 }
792 else
793 {
794 return angleInRadians;
795 }
796}
797
799 struct btTypedObject
800{
801 btTypedObject(int objectType)
802 : m_objectType(objectType)
803 {
804 }
805 int m_objectType;
806 inline int getObjectType() const
807 {
808 return m_objectType;
809 }
810};
811
813template <typename T>
814T *btAlignPointer(T *unalignedPtr, size_t alignment)
815{
816 struct btConvertPointerSizeT
817 {
818 union {
819 T *ptr;
820 size_t integer;
821 };
822 };
823 btConvertPointerSizeT converter;
824
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;
830}
831
832#endif //BT_SCALAR_H
operator*
btMatrix3x3 operator*(const btMatrix3x3 &m, const btScalar &k)
Definition: btMatrix3x3.h:930
operator+
btMatrix3x3 operator+(const btMatrix3x3 &m1, const btMatrix3x3 &m2)
Definition: btMatrix3x3.h:952
operator-
btMatrix3x3 operator-(const btMatrix3x3 &m1, const btMatrix3x3 &m2)
Definition: btMatrix3x3.h:976
btGetInfinityMask
int btGetInfinityMask()
Definition: btScalar.h:406
SIMD_RADS_PER_DEG
#define SIMD_RADS_PER_DEG
Definition: btScalar.h:529
btSwapEndianFloat
unsigned int btSwapEndianFloat(float d)
btSwapFloat uses using char pointers to swap the endianness
Definition: btScalar.h:677
btPow
btScalar btPow(btScalar x, btScalar y)
Definition: btScalar.h:521
btNormalizeAngle
btScalar btNormalizeAngle(btScalar angleInRadians)
Definition: btScalar.h:781
SIMD_PI
#define SIMD_PI
Definition: btScalar.h:526
btScalar
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:314
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:617
btSetZero
void btSetZero(T *a, int n)
Definition: btScalar.h:739
btMachineIsLittleEndian
bool btMachineIsLittleEndian()
Definition: btScalar.h:605
SIMD_DEGS_PER_RAD
#define SIMD_DEGS_PER_RAD
Definition: btScalar.h:530
btSqrt
btScalar btSqrt(btScalar y)
Definition: btScalar.h:466
btUnswapEndianFloat
float btUnswapEndianFloat(unsigned int a)
Definition: btScalar.h:691
btGetVersion
int btGetVersion()
Definition: btScalar.h:30
btSwapEndianDouble
void btSwapEndianDouble(double d, unsigned char *dst)
Definition: btScalar.h:706
btIsNegative
int btIsNegative(btScalar x)
Definition: btScalar.h:583
btDegrees
btScalar btDegrees(btScalar x)
Definition: btScalar.h:589
btAtan2
btScalar btAtan2(btScalar x, btScalar y)
Definition: btScalar.h:518
btInfinityMask
static btInfMaskConverter btInfinityMask
Definition: btScalar.h:404
btSin
btScalar btSin(btScalar x)
Definition: btScalar.h:499
btFabs
btScalar btFabs(btScalar x)
Definition: btScalar.h:497
btTan
btScalar btTan(btScalar x)
Definition: btScalar.h:500
SIMD_FORCE_INLINE
#define SIMD_FORCE_INLINE
Definition: btScalar.h:98
btExp
btScalar btExp(btScalar x)
Definition: btScalar.h:519
btEqual
bool btEqual(btScalar a, btScalar eps)
Definition: btScalar.h:574
btSwapEndian
unsigned btSwapEndian(unsigned val)
Definition: btScalar.h:651
btFmod
btScalar btFmod(btScalar x, btScalar y)
Definition: btScalar.h:522
btAlignPointer
T * btAlignPointer(T *unalignedPtr, size_t alignment)
align a pointer to the provided alignment, upwards
Definition: btScalar.h:814
btCos
btScalar btCos(btScalar x)
Definition: btScalar.h:498
btGreaterEqual
bool btGreaterEqual(btScalar a, btScalar eps)
Definition: btScalar.h:578
btLog
btScalar btLog(btScalar x)
Definition: btScalar.h:520
btUnswapEndianDouble
double btUnswapEndianDouble(const unsigned char *src)
Definition: btScalar.h:721
btRadians
btScalar btRadians(btScalar x)
Definition: btScalar.h:588
BT_BULLET_VERSION
#define BT_BULLET_VERSION
Definition: btScalar.h:28
btIsDoublePrecision
int btIsDoublePrecision()
Definition: btScalar.h:35
btAtan2Fast
btScalar btAtan2Fast(btScalar y, btScalar x)
Definition: btScalar.h:553
btFsel
btScalar btFsel(btScalar a, btScalar b, btScalar c)
Definition: btScalar.h:598
btAtan
btScalar btAtan(btScalar x)
Definition: btScalar.h:517
SIMD_EPSILON
#define SIMD_EPSILON
Definition: btScalar.h:543
btAcos
btScalar btAcos(btScalar x)
Definition: btScalar.h:501
btLargeDot
btScalar btLargeDot(const btScalar *a, const btScalar *b, int n)
Definition: btScalar.h:750
btSwap
void btSwap(T &a, T &b)
Definition: btScalar.h:643
btAsin
btScalar btAsin(btScalar x)
Definition: btScalar.h:509
btFuzzyZero
bool btFuzzyZero(btScalar x)
Definition: btScalar.h:572
SIMD_2_PI
#define SIMD_2_PI
Definition: btScalar.h:527
sum
static T sum(const btAlignedObjectArray< T > &items)
Definition: btSoftBodyHelpers.cpp:95
eps
const btScalar eps
Definition: poly34.cpp:11
btInfMaskConverter
Definition: btScalar.h:394
btInfMaskConverter::intmask
int intmask
Definition: btScalar.h:397
btInfMaskConverter::mask
float mask
Definition: btScalar.h:396
btInfMaskConverter::btInfMaskConverter
btInfMaskConverter(int _mask=0x7F800000)
Definition: btScalar.h:399
btTypedObject
rudimentary class to provide type info
Definition: btScalar.h:800
btTypedObject::btTypedObject
btTypedObject(int objectType)
Definition: btScalar.h:801
btTypedObject::m_objectType
int m_objectType
Definition: btScalar.h:805
btTypedObject::getObjectType
int getObjectType() const
Definition: btScalar.h:806