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