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 <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 --
32 namespace VHACD {
33 // -- GODOT end --
34 
btGetVersion()35 inline 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))
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 --
214 namespace 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)
219 typedef double btScalar;
220 //this number could be bigger in double precision
221 #define BT_LARGE_FLOAT 1e30
222 #else
223 typedef 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 
btSqrt(btScalar x)240 SIMD_FORCE_INLINE btScalar btSqrt(btScalar x)
241 {
242     return sqrt(x);
243 }
btFabs(btScalar x)244 SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabs(x); }
btCos(btScalar x)245 SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cos(x); }
btSin(btScalar x)246 SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sin(x); }
btTan(btScalar x)247 SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tan(x); }
btAcos(btScalar x)248 SIMD_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 }
btAsin(btScalar x)256 SIMD_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 }
btAtan(btScalar x)264 SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atan(x); }
btAtan2(btScalar x,btScalar y)265 SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2(x, y); }
btExp(btScalar x)266 SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return exp(x); }
btLog(btScalar x)267 SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return log(x); }
btPow(btScalar x,btScalar y)268 SIMD_FORCE_INLINE btScalar btPow(btScalar x, btScalar y) { return pow(x, y); }
btFmod(btScalar x,btScalar y)269 SIMD_FORCE_INLINE btScalar btFmod(btScalar x, btScalar y) { return fmod(x, y); }
270 
271 #else
272 
btSqrt(btScalar y)273 SIMD_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 }
btFabs(btScalar x)293 SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabsf(x); }
btCos(btScalar x)294 SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cosf(x); }
btSin(btScalar x)295 SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); }
btTan(btScalar x)296 SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); }
btAcos(btScalar x)297 SIMD_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 }
btAsin(btScalar x)305 SIMD_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 }
btAtan(btScalar x)313 SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); }
btAtan2(btScalar x,btScalar y)314 SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); }
btExp(btScalar x)315 SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return expf(x); }
btLog(btScalar x)316 SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return logf(x); }
btPow(btScalar x,btScalar y)317 SIMD_FORCE_INLINE btScalar btPow(btScalar x, btScalar y) { return powf(x, y); }
btFmod(btScalar x,btScalar y)318 SIMD_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 
btAtan2Fast(btScalar y,btScalar x)339 SIMD_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 
btFuzzyZero(btScalar x)356 SIMD_FORCE_INLINE bool btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; }
357 
btEqual(btScalar a,btScalar eps)358 SIMD_FORCE_INLINE bool btEqual(btScalar a, btScalar eps)
359 {
360     return (((a) <= eps) && !((a) < -eps));
361 }
btGreaterEqual(btScalar a,btScalar eps)362 SIMD_FORCE_INLINE bool btGreaterEqual(btScalar a, btScalar eps)
363 {
364     return (!((a) <= eps));
365 }
366 
btIsNegative(btScalar x)367 SIMD_FORCE_INLINE int32_t btIsNegative(btScalar x)
368 {
369     return x < btScalar(0.0) ? 1 : 0;
370 }
371 
btRadians(btScalar x)372 SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; }
btDegrees(btScalar x)373 SIMD_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
btFsel(btScalar a,btScalar b,btScalar c)381 SIMD_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 
btMachineIsLittleEndian()388 SIMD_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
btSelect(unsigned condition,unsigned valueIfConditionNonZero,unsigned valueIfConditionZero)400 SIMD_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 }
btSelect(unsigned condition,int32_t valueIfConditionNonZero,int32_t valueIfConditionZero)410 SIMD_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 }
btSelect(unsigned condition,float valueIfConditionNonZero,float valueIfConditionZero)416 SIMD_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 
425 template <typename T>
btSwap(T & a,T & b)426 SIMD_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
btSwapEndian(unsigned val)434 SIMD_FORCE_INLINE unsigned btSwapEndian(unsigned val)
435 {
436     return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
437 }
438 
btSwapEndian(unsigned short val)439 SIMD_FORCE_INLINE unsigned short btSwapEndian(unsigned short val)
440 {
441     return static_cast<unsigned short>(((val & 0xff00) >> 8) | ((val & 0x00ff) << 8));
442 }
443 
btSwapEndian(int32_t val)444 SIMD_FORCE_INLINE unsigned btSwapEndian(int32_t val)
445 {
446     return btSwapEndian((unsigned)val);
447 }
448 
btSwapEndian(short val)449 SIMD_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
btSwapEndianFloat(float d)460 SIMD_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
btUnswapEndianFloat(uint32_t a)474 SIMD_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
btSwapEndianDouble(double d,unsigned char * dst)489 SIMD_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
btUnswapEndianDouble(const unsigned char * src)504 SIMD_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]
btNormalizeAngle(btScalar angleInRadians)522 SIMD_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
537 struct btTypedObject {
btTypedObjectbtTypedObject538     btTypedObject(int32_t objectType)
539         : m_objectType(objectType)
540     {
541     }
542     int32_t m_objectType;
getObjectTypebtTypedObject543     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
552 template <typename T>
btAlignPointer(T * unalignedPtr,size_t alignment)553 T *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