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 <float.h>
24#include <math.h>
25#include <stdlib.h> //size_t for MSVC 6.0
26#include <stdint.h>
27
28/* SVN $Revision$ on $Date$ from http://bullet.googlecode.com*/
29#define BT_BULLET_VERSION 279
30
31// -- GODOT start --
32namespace VHACD {
33// -- GODOT end --
34
35inline int32_t btGetVersion()
36{
37 return BT_BULLET_VERSION;
38}
39
40// -- GODOT start --
41}; // namespace VHACD
42// -- GODOT end --
43
44#if defined(DEBUG) || defined(_DEBUG)
45#define BT_DEBUG
46#endif
47
48#ifdef _WIN32
49
50#if defined(__MINGW32__) || defined(__CYGWIN__) || (defined(_MSC_VER) && _MSC_VER < 1300)
51
52#define SIMD_FORCE_INLINE inline
53#define ATTRIBUTE_ALIGNED16(a) a
54#define ATTRIBUTE_ALIGNED64(a) a
55#define ATTRIBUTE_ALIGNED128(a) a
56#else
57//#define BT_HAS_ALIGNED_ALLOCATOR
58#pragma warning(disable : 4324) // disable padding warning
59// #pragma warning(disable:4530) // Disable the exception disable but used in MSCV Stl warning.
60// #pragma warning(disable:4996) //Turn off warnings about deprecated C routines
61// #pragma warning(disable:4786) // Disable the "debug name too long" warning
62
63#define SIMD_FORCE_INLINE __forceinline
64#define ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a
65#define ATTRIBUTE_ALIGNED64(a) __declspec(align(64)) a
66#define ATTRIBUTE_ALIGNED128(a) __declspec(align(128)) a
67#ifdef _XBOX
68#define BT_USE_VMX128
69
70#include <ppcintrinsics.h>
71#define BT_HAVE_NATIVE_FSEL
72#define btFsel(a, b, c) __fsel((a), (b), (c))
73#else
74
75// -- GODOT start --
76//#if (defined(_WIN32) && (_MSC_VER) && _MSC_VER >= 1400) && (!defined(BT_USE_DOUBLE_PRECISION))
77#if (defined(_WIN32) && (_MSC_VER) && _MSC_VER >= 1400) && (!defined(BT_USE_DOUBLE_PRECISION)) && (!defined(_M_ARM)) && (!defined(_M_ARM64))
78// -- GODOT end --
79#define BT_USE_SSE
80#include <emmintrin.h>
81#endif
82
83#endif //_XBOX
84
85#endif //__MINGW32__
86
87#include <assert.h>
88#ifdef BT_DEBUG
89#define btAssert assert
90#else
91#define btAssert(x)
92#endif
93//btFullAssert is optional, slows down a lot
94#define btFullAssert(x)
95
96#define btLikely(_c) _c
97#define btUnlikely(_c) _c
98
99#else
100
101#if defined(__CELLOS_LV2__)
102#define SIMD_FORCE_INLINE inline __attribute__((always_inline))
103#define ATTRIBUTE_ALIGNED16(a) a __attribute__((aligned(16)))
104#define ATTRIBUTE_ALIGNED64(a) a __attribute__((aligned(64)))
105#define ATTRIBUTE_ALIGNED128(a) a __attribute__((aligned(128)))
106#ifndef assert
107#include <assert.h>
108#endif
109#ifdef BT_DEBUG
110#ifdef __SPU__
111#include <spu_printf.h>
112#define printf spu_printf
113#define btAssert(x) \
114 { \
115 if (!(x)) { \
116 printf("Assert " __FILE__ ":%u (" #x ")\n", __LINE__); \
117 spu_hcmpeq(0, 0); \
118 } \
119 }
120#else
121#define btAssert assert
122#endif
123
124#else
125#define btAssert(x)
126#endif
127//btFullAssert is optional, slows down a lot
128#define btFullAssert(x)
129
130#define btLikely(_c) _c
131#define btUnlikely(_c) _c
132
133#else
134
135#ifdef USE_LIBSPE2
136
137#define SIMD_FORCE_INLINE __inline
138#define ATTRIBUTE_ALIGNED16(a) a __attribute__((aligned(16)))
139#define ATTRIBUTE_ALIGNED64(a) a __attribute__((aligned(64)))
140#define ATTRIBUTE_ALIGNED128(a) a __attribute__((aligned(128)))
141#ifndef assert
142#include <assert.h>
143#endif
144#ifdef BT_DEBUG
145#define btAssert assert
146#else
147#define btAssert(x)
148#endif
149//btFullAssert is optional, slows down a lot
150#define btFullAssert(x)
151
152#define btLikely(_c) __builtin_expect((_c), 1)
153#define btUnlikely(_c) __builtin_expect((_c), 0)
154
155#else
156//non-windows systems
157
158#if (defined(__APPLE__) && defined(__i386__) && (!defined(BT_USE_DOUBLE_PRECISION)))
159#define BT_USE_SSE
160#include <emmintrin.h>
161
162#define SIMD_FORCE_INLINE inline
163///@todo: check out alignment methods for other platforms/compilers
164#define ATTRIBUTE_ALIGNED16(a) a __attribute__((aligned(16)))
165#define ATTRIBUTE_ALIGNED64(a) a __attribute__((aligned(64)))
166#define ATTRIBUTE_ALIGNED128(a) a __attribute__((aligned(128)))
167#ifndef assert
168#include <assert.h>
169#endif
170
171#if defined(DEBUG) || defined(_DEBUG)
172#define btAssert assert
173#else
174#define btAssert(x)
175#endif
176
177//btFullAssert is optional, slows down a lot
178#define btFullAssert(x)
179#define btLikely(_c) _c
180#define btUnlikely(_c) _c
181
182#else
183
184#define SIMD_FORCE_INLINE inline
185///@todo: check out alignment methods for other platforms/compilers
186///#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
187///#define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
188///#define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
189#define ATTRIBUTE_ALIGNED16(a) a
190#define ATTRIBUTE_ALIGNED64(a) a
191#define ATTRIBUTE_ALIGNED128(a) a
192#ifndef assert
193#include <assert.h>
194#endif
195
196#if defined(DEBUG) || defined(_DEBUG)
197#define btAssert assert
198#else
199#define btAssert(x)
200#endif
201
202//btFullAssert is optional, slows down a lot
203#define btFullAssert(x)
204#define btLikely(_c) _c
205#define btUnlikely(_c) _c
206#endif //__APPLE__
207
208#endif // LIBSPE2
209
210#endif //__CELLOS_LV2__
211#endif
212
213// -- GODOT start --
214namespace VHACD {
215// -- GODOT end --
216
217///The btScalar type abstracts floating point numbers, to easily switch between double and single floating point precision.
218#if defined(BT_USE_DOUBLE_PRECISION)
219typedef double btScalar;
220//this number could be bigger in double precision
221#define BT_LARGE_FLOAT 1e30
222#else
223typedef float btScalar;
224//keep BT_LARGE_FLOAT*BT_LARGE_FLOAT < FLT_MAX
225#define BT_LARGE_FLOAT 1e18f
226#endif
227
228#define BT_DECLARE_ALIGNED_ALLOCATOR() \
229 SIMD_FORCE_INLINE void* operator new(size_t sizeInBytes) { return btAlignedAlloc(sizeInBytes, 16); } \
230 SIMD_FORCE_INLINE void operator delete(void* ptr) { btAlignedFree(ptr); } \
231 SIMD_FORCE_INLINE void* operator new(size_t, void* ptr) { return ptr; } \
232 SIMD_FORCE_INLINE void operator delete(void*, void*) {} \
233 SIMD_FORCE_INLINE void* operator new[](size_t sizeInBytes) { return btAlignedAlloc(sizeInBytes, 16); } \
234 SIMD_FORCE_INLINE void operator delete[](void* ptr) { btAlignedFree(ptr); } \
235 SIMD_FORCE_INLINE void* operator new[](size_t, void* ptr) { return ptr; } \
236 SIMD_FORCE_INLINE void operator delete[](void*, void*) {}
237
238#if defined(BT_USE_DOUBLE_PRECISION) || defined(BT_FORCE_DOUBLE_FUNCTIONS)
239
240SIMD_FORCE_INLINE btScalar btSqrt(btScalar x)
241{
242 return sqrt(x);
243}
244SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabs(x); }
245SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cos(x); }
246SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sin(x); }
247SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tan(x); }
248SIMD_FORCE_INLINE btScalar btAcos(btScalar x)
249{
250 if (x < btScalar(-1))
251 x = btScalar(-1);
252 if (x > btScalar(1))
253 x = btScalar(1);
254 return acos(x);
255}
256SIMD_FORCE_INLINE btScalar btAsin(btScalar x)
257{
258 if (x < btScalar(-1))
259 x = btScalar(-1);
260 if (x > btScalar(1))
261 x = btScalar(1);
262 return asin(x);
263}
264SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atan(x); }
265SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2(x, y); }
266SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return exp(x); }
267SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return log(x); }
268SIMD_FORCE_INLINE btScalar btPow(btScalar x, btScalar y) { return pow(x, y); }
269SIMD_FORCE_INLINE btScalar btFmod(btScalar x, btScalar y) { return fmod(x, y); }
270
271#else
272
273SIMD_FORCE_INLINE btScalar btSqrt(btScalar y)
274{
275#ifdef USE_APPROXIMATION
276 double x, z, tempf;
277 unsigned long* tfptr = ((unsigned long*)&tempf) + 1;
278
279 tempf = y;
280 *tfptr = (0xbfcdd90a - *tfptr) >> 1; /* estimate of 1/sqrt(y) */
281 x = tempf;
282 z = y * btScalar(0.5);
283 x = (btScalar(1.5) * x) - (x * x) * (x * z); /* iteration formula */
284 x = (btScalar(1.5) * x) - (x * x) * (x * z);
285 x = (btScalar(1.5) * x) - (x * x) * (x * z);
286 x = (btScalar(1.5) * x) - (x * x) * (x * z);
287 x = (btScalar(1.5) * x) - (x * x) * (x * z);
288 return x * y;
289#else
290 return sqrtf(y);
291#endif
292}
293SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabsf(x); }
294SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cosf(x); }
295SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); }
296SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); }
297SIMD_FORCE_INLINE btScalar btAcos(btScalar x)
298{
299 if (x < btScalar(-1))
300 x = btScalar(-1);
301 if (x > btScalar(1))
302 x = btScalar(1);
303 return acosf(x);
304}
305SIMD_FORCE_INLINE btScalar btAsin(btScalar x)
306{
307 if (x < btScalar(-1))
308 x = btScalar(-1);
309 if (x > btScalar(1))
310 x = btScalar(1);
311 return asinf(x);
312}
313SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); }
314SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); }
315SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return expf(x); }
316SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return logf(x); }
317SIMD_FORCE_INLINE btScalar btPow(btScalar x, btScalar y) { return powf(x, y); }
318SIMD_FORCE_INLINE btScalar btFmod(btScalar x, btScalar y) { return fmodf(x, y); }
319
320#endif
321
322#define SIMD_2_PI btScalar(6.283185307179586232)
323#define SIMD_PI (SIMD_2_PI * btScalar(0.5))
324#define SIMD_HALF_PI (SIMD_2_PI * btScalar(0.25))
325#define SIMD_RADS_PER_DEG (SIMD_2_PI / btScalar(360.0))
326#define SIMD_DEGS_PER_RAD (btScalar(360.0) / SIMD_2_PI)
327#define SIMDSQRT12 btScalar(0.7071067811865475244008443621048490)
328
329#define btRecipSqrt(x) ((btScalar)(btScalar(1.0) / btSqrt(btScalar(x)))) /* reciprocal square root */
330
331#ifdef BT_USE_DOUBLE_PRECISION
332#define SIMD_EPSILON DBL_EPSILON
333#define SIMD_INFINITY DBL_MAX
334#else
335#define SIMD_EPSILON FLT_EPSILON
336#define SIMD_INFINITY FLT_MAX
337#endif
338
339SIMD_FORCE_INLINE btScalar btAtan2Fast(btScalar y, btScalar x)
340{
341 btScalar coeff_1 = SIMD_PI / 4.0f;
342 btScalar coeff_2 = 3.0f * coeff_1;
343 btScalar abs_y = btFabs(y);
344 btScalar angle;
345 if (x >= 0.0f) {
346 btScalar r = (x - abs_y) / (x + abs_y);
347 angle = coeff_1 - coeff_1 * r;
348 }
349 else {
350 btScalar r = (x + abs_y) / (abs_y - x);
351 angle = coeff_2 - coeff_1 * r;
352 }
353 return (y < 0.0f) ? -angle : angle;
354}
355
356SIMD_FORCE_INLINE bool btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; }
357
358SIMD_FORCE_INLINE bool btEqual(btScalar a, btScalar eps)
359{
360 return (((a) <= eps) && !((a) < -eps));
361}
362SIMD_FORCE_INLINE bool btGreaterEqual(btScalar a, btScalar eps)
363{
364 return (!((a) <= eps));
365}
366
367SIMD_FORCE_INLINE int32_t btIsNegative(btScalar x)
368{
369 return x < btScalar(0.0) ? 1 : 0;
370}
371
372SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; }
373SIMD_FORCE_INLINE btScalar btDegrees(btScalar x) { return x * SIMD_DEGS_PER_RAD; }
374
375#define BT_DECLARE_HANDLE(name) \
376 typedef struct name##__ { \
377 int32_t unused; \
378 } * name
379
380#ifndef btFsel
381SIMD_FORCE_INLINE btScalar btFsel(btScalar a, btScalar b, btScalar c)
382{
383 return a >= 0 ? b : c;
384}
385#endif
386#define btFsels(a, b, c) (btScalar) btFsel(a, b, c)
387
388SIMD_FORCE_INLINE bool btMachineIsLittleEndian()
389{
390 long int i = 1;
391 const char* p = (const char*)&i;
392 if (p[0] == 1) // Lowest address contains the least significant byte
393 return true;
394 else
395 return false;
396}
397
398///btSelect avoids branches, which makes performance much better for consoles like Playstation 3 and XBox 360
399///Thanks Phil Knight. See also http://www.cellperformance.com/articles/2006/04/more_techniques_for_eliminatin_1.html
400SIMD_FORCE_INLINE unsigned btSelect(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero)
401{
402 // Set testNz to 0xFFFFFFFF if condition is nonzero, 0x00000000 if condition is zero
403 // Rely on positive value or'ed with its negative having sign bit on
404 // and zero value or'ed with its negative (which is still zero) having sign bit off
405 // Use arithmetic shift right, shifting the sign bit through all 32 bits
406 unsigned testNz = (unsigned)(((int32_t)condition | -(int32_t)condition) >> 31);
407 unsigned testEqz = ~testNz;
408 return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz));
409}
410SIMD_FORCE_INLINE int32_t btSelect(unsigned condition, int32_t valueIfConditionNonZero, int32_t valueIfConditionZero)
411{
412 unsigned testNz = (unsigned)(((int32_t)condition | -(int32_t)condition) >> 31);
413 unsigned testEqz = ~testNz;
414 return static_cast<int32_t>((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz));
415}
416SIMD_FORCE_INLINE float btSelect(unsigned condition, float valueIfConditionNonZero, float valueIfConditionZero)
417{
418#ifdef BT_HAVE_NATIVE_FSEL
419 return (float)btFsel((btScalar)condition - btScalar(1.0f), valueIfConditionNonZero, valueIfConditionZero);
420#else
421 return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero;
422#endif
423}
424
425template <typename T>
426SIMD_FORCE_INLINE void btSwap(T& a, T& b)
427{
428 T tmp = a;
429 a = b;
430 b = tmp;
431}
432
433//PCK: endian swapping functions
434SIMD_FORCE_INLINE unsigned btSwapEndian(unsigned val)
435{
436 return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
437}
438
439SIMD_FORCE_INLINE unsigned short btSwapEndian(unsigned short val)
440{
441 return static_cast<unsigned short>(((val & 0xff00) >> 8) | ((val & 0x00ff) << 8));
442}
443
444SIMD_FORCE_INLINE unsigned btSwapEndian(int32_t val)
445{
446 return btSwapEndian((unsigned)val);
447}
448
449SIMD_FORCE_INLINE unsigned short btSwapEndian(short val)
450{
451 return btSwapEndian((unsigned short)val);
452}
453
454///btSwapFloat uses using char pointers to swap the endianness
455////btSwapFloat/btSwapDouble will NOT return a float, because the machine might 'correct' invalid floating point values
456///Not all values of sign/exponent/mantissa are valid floating point numbers according to IEEE 754.
457///When a floating point unit is faced with an invalid value, it may actually change the value, or worse, throw an exception.
458///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.
459///so instead of returning a float/double, we return integer/long long integer
460SIMD_FORCE_INLINE uint32_t btSwapEndianFloat(float d)
461{
462 uint32_t a = 0;
463 unsigned char* dst = (unsigned char*)&a;
464 unsigned char* src = (unsigned char*)&d;
465
466 dst[0] = src[3];
467 dst[1] = src[2];
468 dst[2] = src[1];
469 dst[3] = src[0];
470 return a;
471}
472
473// unswap using char pointers
474SIMD_FORCE_INLINE float btUnswapEndianFloat(uint32_t a)
475{
476 float d = 0.0f;
477 unsigned char* src = (unsigned char*)&a;
478 unsigned char* dst = (unsigned char*)&d;
479
480 dst[0] = src[3];
481 dst[1] = src[2];
482 dst[2] = src[1];
483 dst[3] = src[0];
484
485 return d;
486}
487
488// swap using char pointers
489SIMD_FORCE_INLINE void btSwapEndianDouble(double d, unsigned char* dst)
490{
491 unsigned char* src = (unsigned char*)&d;
492
493 dst[0] = src[7];
494 dst[1] = src[6];
495 dst[2] = src[5];
496 dst[3] = src[4];
497 dst[4] = src[3];
498 dst[5] = src[2];
499 dst[6] = src[1];
500 dst[7] = src[0];
501}
502
503// unswap using char pointers
504SIMD_FORCE_INLINE double btUnswapEndianDouble(const unsigned char* src)
505{
506 double d = 0.0;
507 unsigned char* dst = (unsigned char*)&d;
508
509 dst[0] = src[7];
510 dst[1] = src[6];
511 dst[2] = src[5];
512 dst[3] = src[4];
513 dst[4] = src[3];
514 dst[5] = src[2];
515 dst[6] = src[1];
516 dst[7] = src[0];
517
518 return d;
519}
520
521// returns normalized value in range [-SIMD_PI, SIMD_PI]
522SIMD_FORCE_INLINE btScalar btNormalizeAngle(btScalar angleInRadians)
523{
524 angleInRadians = btFmod(angleInRadians, SIMD_2_PI);
525 if (angleInRadians < -SIMD_PI) {
526 return angleInRadians + SIMD_2_PI;
527 }
528 else if (angleInRadians > SIMD_PI) {
529 return angleInRadians - SIMD_2_PI;
530 }
531 else {
532 return angleInRadians;
533 }
534}
535
536///rudimentary class to provide type info
537struct btTypedObject {
538 btTypedObject(int32_t objectType)
539 : m_objectType(objectType)
540 {
541 }
542 int32_t m_objectType;
543 inline int32_t getObjectType() const
544 {
545 return m_objectType;
546 }
547};
548
549// -- GODOT start --
550// Cherry-picked from Bullet 2.88 to fix GH-27926
551///align a pointer to the provided alignment, upwards
552template <typename T>
553T *btAlignPointer(T *unalignedPtr, size_t alignment)
554{
555 struct btConvertPointerSizeT
556 {
557 union {
558 T *ptr;
559 size_t integer;
560 };
561 };
562 btConvertPointerSizeT converter;
563
564 const size_t bit_mask = ~(alignment - 1);
565 converter.ptr = unalignedPtr;
566 converter.integer += alignment - 1;
567 converter.integer &= bit_mask;
568 return converter.ptr;
569}
570// -- GODOT end --
571
572// -- GODOT start --
573}; // namespace VHACD
574// -- GODOT end --
575
576#endif //BT_SCALAR_H
577