00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef BT_SCALAR_H
00016 #define BT_SCALAR_H
00017
00018 #ifdef BT_MANAGED_CODE
00019
00020 #pragma unmanaged
00021 #endif
00022
00023 #include <float.h>
00024 #include <math.h>
00025 #include <stdlib.h>
00026 #include <stdint.h>
00027
00028
00029 #define BT_BULLET_VERSION 279
00030
00031 inline int32_t btGetVersion()
00032 {
00033 return BT_BULLET_VERSION;
00034 }
00035
00036 #if defined(DEBUG) || defined(_DEBUG)
00037 #define BT_DEBUG
00038 #endif
00039
00040 #ifdef _WIN32
00041
00042 #if defined(__MINGW32__) || defined(__CYGWIN__) || (defined(_MSC_VER) && _MSC_VER < 1300)
00043
00044 #define SIMD_FORCE_INLINE inline
00045 #define ATTRIBUTE_ALIGNED16(a) a
00046 #define ATTRIBUTE_ALIGNED64(a) a
00047 #define ATTRIBUTE_ALIGNED128(a) a
00048 #else
00049
00050 #pragma warning(disable : 4324) // disable padding warning
00051
00052
00053
00054
00055 #define SIMD_FORCE_INLINE __forceinline
00056 #define ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a
00057 #define ATTRIBUTE_ALIGNED64(a) __declspec(align(64)) a
00058 #define ATTRIBUTE_ALIGNED128(a) __declspec(align(128)) a
00059 #ifdef _XBOX
00060 #define BT_USE_VMX128
00061
00062 #include <ppcintrinsics.h>
00063 #define BT_HAVE_NATIVE_FSEL
00064 #define btFsel(a, b, c) __fsel((a), (b), (c))
00065 #else
00066
00067 #if (defined(_WIN32) && (_MSC_VER) && _MSC_VER >= 1400) && (!defined(BT_USE_DOUBLE_PRECISION))
00068 #define BT_USE_SSE
00069 #include <emmintrin.h>
00070 #endif
00071
00072 #endif //_XBOX
00073
00074 #endif //__MINGW32__
00075
00076 #include <assert.h>
00077 #ifdef BT_DEBUG
00078 #define btAssert assert
00079 #else
00080 #define btAssert(x)
00081 #endif
00082
00083 #define btFullAssert(x)
00084
00085 #define btLikely(_c) _c
00086 #define btUnlikely(_c) _c
00087
00088 #else
00089
00090 #if defined(__CELLOS_LV2__)
00091 #define SIMD_FORCE_INLINE inline __attribute__((always_inline))
00092 #define ATTRIBUTE_ALIGNED16(a) a __attribute__((aligned(16)))
00093 #define ATTRIBUTE_ALIGNED64(a) a __attribute__((aligned(64)))
00094 #define ATTRIBUTE_ALIGNED128(a) a __attribute__((aligned(128)))
00095 #ifndef assert
00096 #include <assert.h>
00097 #endif
00098 #ifdef BT_DEBUG
00099 #ifdef __SPU__
00100 #include <spu_printf.h>
00101 #define printf spu_printf
00102 #define btAssert(x) \
00103 { \
00104 if (!(x)) { \
00105 printf("Assert " __FILE__ ":%u (" #x ")\n", __LINE__); \
00106 spu_hcmpeq(0, 0); \
00107 } \
00108 }
00109 #else
00110 #define btAssert assert
00111 #endif
00112
00113 #else
00114 #define btAssert(x)
00115 #endif
00116
00117 #define btFullAssert(x)
00118
00119 #define btLikely(_c) _c
00120 #define btUnlikely(_c) _c
00121
00122 #else
00123
00124 #ifdef USE_LIBSPE2
00125
00126 #define SIMD_FORCE_INLINE __inline
00127 #define ATTRIBUTE_ALIGNED16(a) a __attribute__((aligned(16)))
00128 #define ATTRIBUTE_ALIGNED64(a) a __attribute__((aligned(64)))
00129 #define ATTRIBUTE_ALIGNED128(a) a __attribute__((aligned(128)))
00130 #ifndef assert
00131 #include <assert.h>
00132 #endif
00133 #ifdef BT_DEBUG
00134 #define btAssert assert
00135 #else
00136 #define btAssert(x)
00137 #endif
00138
00139 #define btFullAssert(x)
00140
00141 #define btLikely(_c) __builtin_expect((_c), 1)
00142 #define btUnlikely(_c) __builtin_expect((_c), 0)
00143
00144 #else
00145
00146
00147 #if (defined(__APPLE__) && defined(__i386__) && (!defined(BT_USE_DOUBLE_PRECISION)))
00148 #define BT_USE_SSE
00149 #include <emmintrin.h>
00150
00151 #define SIMD_FORCE_INLINE inline
00153 #define ATTRIBUTE_ALIGNED16(a) a __attribute__((aligned(16)))
00154 #define ATTRIBUTE_ALIGNED64(a) a __attribute__((aligned(64)))
00155 #define ATTRIBUTE_ALIGNED128(a) a __attribute__((aligned(128)))
00156 #ifndef assert
00157 #include <assert.h>
00158 #endif
00159
00160 #if defined(DEBUG) || defined(_DEBUG)
00161 #define btAssert assert
00162 #else
00163 #define btAssert(x)
00164 #endif
00165
00166
00167 #define btFullAssert(x)
00168 #define btLikely(_c) _c
00169 #define btUnlikely(_c) _c
00170
00171 #else
00172
00173 #define SIMD_FORCE_INLINE inline
00178 #define ATTRIBUTE_ALIGNED16(a) a
00179 #define ATTRIBUTE_ALIGNED64(a) a
00180 #define ATTRIBUTE_ALIGNED128(a) a
00181 #ifndef assert
00182 #include <assert.h>
00183 #endif
00184
00185 #if defined(DEBUG) || defined(_DEBUG)
00186 #define btAssert assert
00187 #else
00188 #define btAssert(x)
00189 #endif
00190
00191
00192 #define btFullAssert(x)
00193 #define btLikely(_c) _c
00194 #define btUnlikely(_c) _c
00195 #endif //__APPLE__
00196
00197 #endif // LIBSPE2
00198
00199 #endif //__CELLOS_LV2__
00200 #endif
00201
00203 #if defined(BT_USE_DOUBLE_PRECISION)
00204 typedef double btScalar;
00205
00206 #define BT_LARGE_FLOAT 1e30
00207 #else
00208 typedef float btScalar;
00209
00210 #define BT_LARGE_FLOAT 1e18f
00211 #endif
00212
00213 #define BT_DECLARE_ALIGNED_ALLOCATOR() \
00214 SIMD_FORCE_INLINE void* operator new(size_t sizeInBytes) { return btAlignedAlloc(sizeInBytes, 16); } \
00215 SIMD_FORCE_INLINE void operator delete(void* ptr) { btAlignedFree(ptr); } \
00216 SIMD_FORCE_INLINE void* operator new(size_t, void* ptr) { return ptr; } \
00217 SIMD_FORCE_INLINE void operator delete(void*, void*) {} \
00218 SIMD_FORCE_INLINE void* operator new[](size_t sizeInBytes) { return btAlignedAlloc(sizeInBytes, 16); } \
00219 SIMD_FORCE_INLINE void operator delete[](void* ptr) { btAlignedFree(ptr); } \
00220 SIMD_FORCE_INLINE void* operator new[](size_t, void* ptr) { return ptr; } \
00221 SIMD_FORCE_INLINE void operator delete[](void*, void*) {}
00222
00223 #if defined(BT_USE_DOUBLE_PRECISION) || defined(BT_FORCE_DOUBLE_FUNCTIONS)
00224
00225 SIMD_FORCE_INLINE btScalar btSqrt(btScalar x)
00226 {
00227 return sqrt(x);
00228 }
00229 SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabs(x); }
00230 SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cos(x); }
00231 SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sin(x); }
00232 SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tan(x); }
00233 SIMD_FORCE_INLINE btScalar btAcos(btScalar x)
00234 {
00235 if (x < btScalar(-1))
00236 x = btScalar(-1);
00237 if (x > btScalar(1))
00238 x = btScalar(1);
00239 return acos(x);
00240 }
00241 SIMD_FORCE_INLINE btScalar btAsin(btScalar x)
00242 {
00243 if (x < btScalar(-1))
00244 x = btScalar(-1);
00245 if (x > btScalar(1))
00246 x = btScalar(1);
00247 return asin(x);
00248 }
00249 SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atan(x); }
00250 SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2(x, y); }
00251 SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return exp(x); }
00252 SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return log(x); }
00253 SIMD_FORCE_INLINE btScalar btPow(btScalar x, btScalar y) { return pow(x, y); }
00254 SIMD_FORCE_INLINE btScalar btFmod(btScalar x, btScalar y) { return fmod(x, y); }
00255
00256 #else
00257
00258 SIMD_FORCE_INLINE btScalar btSqrt(btScalar y)
00259 {
00260 #ifdef USE_APPROXIMATION
00261 double x, z, tempf;
00262 unsigned long* tfptr = ((unsigned long*)&tempf) + 1;
00263
00264 tempf = y;
00265 *tfptr = (0xbfcdd90a - *tfptr) >> 1;
00266 x = tempf;
00267 z = y * btScalar(0.5);
00268 x = (btScalar(1.5) * x) - (x * x) * (x * z);
00269 x = (btScalar(1.5) * x) - (x * x) * (x * z);
00270 x = (btScalar(1.5) * x) - (x * x) * (x * z);
00271 x = (btScalar(1.5) * x) - (x * x) * (x * z);
00272 x = (btScalar(1.5) * x) - (x * x) * (x * z);
00273 return x * y;
00274 #else
00275 return sqrtf(y);
00276 #endif
00277 }
00278 SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabsf(x); }
00279 SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cosf(x); }
00280 SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); }
00281 SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); }
00282 SIMD_FORCE_INLINE btScalar btAcos(btScalar x)
00283 {
00284 if (x < btScalar(-1))
00285 x = btScalar(-1);
00286 if (x > btScalar(1))
00287 x = btScalar(1);
00288 return acosf(x);
00289 }
00290 SIMD_FORCE_INLINE btScalar btAsin(btScalar x)
00291 {
00292 if (x < btScalar(-1))
00293 x = btScalar(-1);
00294 if (x > btScalar(1))
00295 x = btScalar(1);
00296 return asinf(x);
00297 }
00298 SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); }
00299 SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); }
00300 SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return expf(x); }
00301 SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return logf(x); }
00302 SIMD_FORCE_INLINE btScalar btPow(btScalar x, btScalar y) { return powf(x, y); }
00303 SIMD_FORCE_INLINE btScalar btFmod(btScalar x, btScalar y) { return fmodf(x, y); }
00304
00305 #endif
00306
00307 #define SIMD_2_PI btScalar(6.283185307179586232)
00308 #define SIMD_PI (SIMD_2_PI * btScalar(0.5))
00309 #define SIMD_HALF_PI (SIMD_2_PI * btScalar(0.25))
00310 #define SIMD_RADS_PER_DEG (SIMD_2_PI / btScalar(360.0))
00311 #define SIMD_DEGS_PER_RAD (btScalar(360.0) / SIMD_2_PI)
00312 #define SIMDSQRT12 btScalar(0.7071067811865475244008443621048490)
00313
00314 #define btRecipSqrt(x) ((btScalar)(btScalar(1.0) / btSqrt(btScalar(x))))
00315
00316 #ifdef BT_USE_DOUBLE_PRECISION
00317 #define SIMD_EPSILON DBL_EPSILON
00318 #define SIMD_INFINITY DBL_MAX
00319 #else
00320 #define SIMD_EPSILON FLT_EPSILON
00321 #define SIMD_INFINITY FLT_MAX
00322 #endif
00323
00324 SIMD_FORCE_INLINE btScalar btAtan2Fast(btScalar y, btScalar x)
00325 {
00326 btScalar coeff_1 = SIMD_PI / 4.0f;
00327 btScalar coeff_2 = 3.0f * coeff_1;
00328 btScalar abs_y = btFabs(y);
00329 btScalar angle;
00330 if (x >= 0.0f) {
00331 btScalar r = (x - abs_y) / (x + abs_y);
00332 angle = coeff_1 - coeff_1 * r;
00333 }
00334 else {
00335 btScalar r = (x + abs_y) / (abs_y - x);
00336 angle = coeff_2 - coeff_1 * r;
00337 }
00338 return (y < 0.0f) ? -angle : angle;
00339 }
00340
00341 SIMD_FORCE_INLINE bool btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; }
00342
00343 SIMD_FORCE_INLINE bool btEqual(btScalar a, btScalar eps)
00344 {
00345 return (((a) <= eps) && !((a) < -eps));
00346 }
00347 SIMD_FORCE_INLINE bool btGreaterEqual(btScalar a, btScalar eps)
00348 {
00349 return (!((a) <= eps));
00350 }
00351
00352 SIMD_FORCE_INLINE int32_t btIsNegative(btScalar x)
00353 {
00354 return x < btScalar(0.0) ? 1 : 0;
00355 }
00356
00357 SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; }
00358 SIMD_FORCE_INLINE btScalar btDegrees(btScalar x) { return x * SIMD_DEGS_PER_RAD; }
00359
00360 #define BT_DECLARE_HANDLE(name) \
00361 typedef struct name##__ { \
00362 int32_t unused; \
00363 } * name
00364
00365 #ifndef btFsel
00366 SIMD_FORCE_INLINE btScalar btFsel(btScalar a, btScalar b, btScalar c)
00367 {
00368 return a >= 0 ? b : c;
00369 }
00370 #endif
00371 #define btFsels(a, b, c) (btScalar) btFsel(a, b, c)
00372
00373 SIMD_FORCE_INLINE bool btMachineIsLittleEndian()
00374 {
00375 long int i = 1;
00376 const char* p = (const char*)&i;
00377 if (p[0] == 1)
00378 return true;
00379 else
00380 return false;
00381 }
00382
00385 SIMD_FORCE_INLINE unsigned btSelect(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero)
00386 {
00387
00388
00389
00390
00391 unsigned testNz = (unsigned)(((int32_t)condition | -(int32_t)condition) >> 31);
00392 unsigned testEqz = ~testNz;
00393 return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz));
00394 }
00395 SIMD_FORCE_INLINE int32_t btSelect(unsigned condition, int32_t valueIfConditionNonZero, int32_t valueIfConditionZero)
00396 {
00397 unsigned testNz = (unsigned)(((int32_t)condition | -(int32_t)condition) >> 31);
00398 unsigned testEqz = ~testNz;
00399 return static_cast<int32_t>((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz));
00400 }
00401 SIMD_FORCE_INLINE float btSelect(unsigned condition, float valueIfConditionNonZero, float valueIfConditionZero)
00402 {
00403 #ifdef BT_HAVE_NATIVE_FSEL
00404 return (float)btFsel((btScalar)condition - btScalar(1.0f), valueIfConditionNonZero, valueIfConditionZero);
00405 #else
00406 return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero;
00407 #endif
00408 }
00409
00410 template <typename T>
00411 SIMD_FORCE_INLINE void btSwap(T& a, T& b)
00412 {
00413 T tmp = a;
00414 a = b;
00415 b = tmp;
00416 }
00417
00418
00419 SIMD_FORCE_INLINE unsigned btSwapEndian(unsigned val)
00420 {
00421 return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
00422 }
00423
00424 SIMD_FORCE_INLINE unsigned short btSwapEndian(unsigned short val)
00425 {
00426 return static_cast<unsigned short>(((val & 0xff00) >> 8) | ((val & 0x00ff) << 8));
00427 }
00428
00429 SIMD_FORCE_INLINE unsigned btSwapEndian(int32_t val)
00430 {
00431 return btSwapEndian((unsigned)val);
00432 }
00433
00434 SIMD_FORCE_INLINE unsigned short btSwapEndian(short val)
00435 {
00436 return btSwapEndian((unsigned short)val);
00437 }
00438
00445 SIMD_FORCE_INLINE uint32_t btSwapEndianFloat(float d)
00446 {
00447 uint32_t a = 0;
00448 unsigned char* dst = (unsigned char*)&a;
00449 unsigned char* src = (unsigned char*)&d;
00450
00451 dst[0] = src[3];
00452 dst[1] = src[2];
00453 dst[2] = src[1];
00454 dst[3] = src[0];
00455 return a;
00456 }
00457
00458
00459 SIMD_FORCE_INLINE float btUnswapEndianFloat(uint32_t a)
00460 {
00461 float d = 0.0f;
00462 unsigned char* src = (unsigned char*)&a;
00463 unsigned char* dst = (unsigned char*)&d;
00464
00465 dst[0] = src[3];
00466 dst[1] = src[2];
00467 dst[2] = src[1];
00468 dst[3] = src[0];
00469
00470 return d;
00471 }
00472
00473
00474 SIMD_FORCE_INLINE void btSwapEndianDouble(double d, unsigned char* dst)
00475 {
00476 unsigned char* src = (unsigned char*)&d;
00477
00478 dst[0] = src[7];
00479 dst[1] = src[6];
00480 dst[2] = src[5];
00481 dst[3] = src[4];
00482 dst[4] = src[3];
00483 dst[5] = src[2];
00484 dst[6] = src[1];
00485 dst[7] = src[0];
00486 }
00487
00488
00489 SIMD_FORCE_INLINE double btUnswapEndianDouble(const unsigned char* src)
00490 {
00491 double d = 0.0;
00492 unsigned char* dst = (unsigned char*)&d;
00493
00494 dst[0] = src[7];
00495 dst[1] = src[6];
00496 dst[2] = src[5];
00497 dst[3] = src[4];
00498 dst[4] = src[3];
00499 dst[5] = src[2];
00500 dst[6] = src[1];
00501 dst[7] = src[0];
00502
00503 return d;
00504 }
00505
00506
00507 SIMD_FORCE_INLINE btScalar btNormalizeAngle(btScalar angleInRadians)
00508 {
00509 angleInRadians = btFmod(angleInRadians, SIMD_2_PI);
00510 if (angleInRadians < -SIMD_PI) {
00511 return angleInRadians + SIMD_2_PI;
00512 }
00513 else if (angleInRadians > SIMD_PI) {
00514 return angleInRadians - SIMD_2_PI;
00515 }
00516 else {
00517 return angleInRadians;
00518 }
00519 }
00520
00522 struct btTypedObject {
00523 btTypedObject(int32_t objectType)
00524 : m_objectType(objectType)
00525 {
00526 }
00527 int32_t m_objectType;
00528 inline int32_t getObjectType() const
00529 {
00530 return m_objectType;
00531 }
00532 };
00533 #endif //BT_SCALAR_H