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