Blender V2.61 - r43446
|
00001 /* 00002 Copyright (c) 2003-2009 Erwin Coumans http://bullet.googlecode.com 00003 00004 This software is provided 'as-is', without any express or implied warranty. 00005 In no event will the authors be held liable for any damages arising from the use of this software. 00006 Permission is granted to anyone to use this software for any purpose, 00007 including commercial applications, and to alter it and redistribute it freely, 00008 subject to the following restrictions: 00009 00010 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. 00011 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 00012 3. This notice may not be removed or altered from any source distribution. 00013 */ 00014 00015 00016 00017 #ifndef SIMD___SCALAR_H 00018 #define SIMD___SCALAR_H 00019 00020 #ifdef BT_MANAGED_CODE 00021 //Aligned data types not supported in managed code 00022 #pragma unmanaged 00023 #endif 00024 00025 00026 #include <math.h> 00027 #include <stdlib.h>//size_t for MSVC 6.0 00028 #include <cstdlib> 00029 #include <cfloat> 00030 #include <float.h> 00031 00032 /* SVN $Revision: 35500 $ on $Date: 2011-03-12 21:34:17 +0100 (Sat, 12 Mar 2011) $ from http://bullet.googlecode.com*/ 00033 #define BT_BULLET_VERSION 278 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 //#define BT_HAS_ALIGNED_ALLOCATOR 00055 #pragma warning(disable : 4324) // disable padding warning 00056 // #pragma warning(disable:4530) // Disable the exception disable but used in MSCV Stl warning. 00057 // #pragma warning(disable:4996) //Turn off warnings about deprecated C routines 00058 // #pragma warning(disable:4786) // Disable the "debug name too long" warning 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 //btFullAssert is optional, slows down a lot 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 __attribute__((always_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 #ifdef __SPU__ 00105 #include <spu_printf.h> 00106 #define printf spu_printf 00107 #define btAssert(x) {if(!(x)){printf("Assert "__FILE__ ":%u ("#x")\n", __LINE__);spu_hcmpeq(0,0);}} 00108 #else 00109 #define btAssert assert 00110 #endif 00111 00112 #else 00113 #define btAssert(x) 00114 #endif 00115 //btFullAssert is optional, slows down a lot 00116 #define btFullAssert(x) 00117 00118 #define btLikely(_c) _c 00119 #define btUnlikely(_c) _c 00120 00121 #else 00122 00123 #ifdef USE_LIBSPE2 00124 00125 #define SIMD_FORCE_INLINE __inline 00126 #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16))) 00127 #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64))) 00128 #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128))) 00129 #ifndef assert 00130 #include <assert.h> 00131 #endif 00132 #ifdef BT_DEBUG 00133 #define btAssert assert 00134 #else 00135 #define btAssert(x) 00136 #endif 00137 //btFullAssert is optional, slows down a lot 00138 #define btFullAssert(x) 00139 00140 00141 #define btLikely(_c) __builtin_expect((_c), 1) 00142 #define btUnlikely(_c) __builtin_expect((_c), 0) 00143 00144 00145 #else 00146 //non-windows systems 00147 00148 #if (defined (__APPLE__) && defined (__i386__) && (!defined (BT_USE_DOUBLE_PRECISION))) 00149 #define BT_USE_SSE 00150 #include <emmintrin.h> 00151 00152 #define SIMD_FORCE_INLINE inline 00153 00154 #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16))) 00155 #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64))) 00156 #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128))) 00157 #ifndef assert 00158 #include <assert.h> 00159 #endif 00160 00161 #if defined(DEBUG) || defined (_DEBUG) 00162 #define btAssert assert 00163 #else 00164 #define btAssert(x) 00165 #endif 00166 00167 //btFullAssert is optional, slows down a lot 00168 #define btFullAssert(x) 00169 #define btLikely(_c) _c 00170 #define btUnlikely(_c) _c 00171 00172 #else 00173 00174 #define SIMD_FORCE_INLINE inline 00175 00176 00177 00178 00179 #define ATTRIBUTE_ALIGNED16(a) a 00180 #define ATTRIBUTE_ALIGNED64(a) a 00181 #define ATTRIBUTE_ALIGNED128(a) a 00182 #ifndef assert 00183 #include <assert.h> 00184 #endif 00185 00186 #if defined(DEBUG) || defined (_DEBUG) 00187 #define btAssert assert 00188 #else 00189 #define btAssert(x) 00190 #endif 00191 00192 //btFullAssert is optional, slows down a lot 00193 #define btFullAssert(x) 00194 #define btLikely(_c) _c 00195 #define btUnlikely(_c) _c 00196 #endif //__APPLE__ 00197 00198 #endif // LIBSPE2 00199 00200 #endif //__CELLOS_LV2__ 00201 #endif 00202 00203 00205 #if defined(BT_USE_DOUBLE_PRECISION) 00206 typedef double btScalar; 00207 //this number could be bigger in double precision 00208 #define BT_LARGE_FLOAT 1e30 00209 #else 00210 typedef float btScalar; 00211 //keep BT_LARGE_FLOAT*BT_LARGE_FLOAT < FLT_MAX 00212 #define BT_LARGE_FLOAT 1e18f 00213 #endif 00214 00215 00216 00217 #define BT_DECLARE_ALIGNED_ALLOCATOR() \ 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 SIMD_FORCE_INLINE void* operator new[](size_t sizeInBytes) { return btAlignedAlloc(sizeInBytes,16); } \ 00223 SIMD_FORCE_INLINE void operator delete[](void* ptr) { btAlignedFree(ptr); } \ 00224 SIMD_FORCE_INLINE void* operator new[](size_t, void* ptr) { return ptr; } \ 00225 SIMD_FORCE_INLINE void operator delete[](void*, void*) { } \ 00226 00227 00228 00229 #if defined(BT_USE_DOUBLE_PRECISION) || defined(BT_FORCE_DOUBLE_FUNCTIONS) 00230 00231 SIMD_FORCE_INLINE btScalar btSqrt(btScalar x) { return sqrt(x); } 00232 SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabs(x); } 00233 SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cos(x); } 00234 SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sin(x); } 00235 SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tan(x); } 00236 SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { if (x<btScalar(-1)) x=btScalar(-1); if (x>btScalar(1)) x=btScalar(1); return acos(x); } 00237 SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { if (x<btScalar(-1)) x=btScalar(-1); if (x>btScalar(1)) x=btScalar(1); return asin(x); } 00238 SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atan(x); } 00239 SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2(x, y); } 00240 SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return exp(x); } 00241 SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return log(x); } 00242 SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return pow(x,y); } 00243 SIMD_FORCE_INLINE btScalar btFmod(btScalar x,btScalar y) { return fmod(x,y); } 00244 00245 #else 00246 00247 SIMD_FORCE_INLINE btScalar btSqrt(btScalar y) 00248 { 00249 #ifdef USE_APPROXIMATION 00250 double x, z, tempf; 00251 unsigned long *tfptr = ((unsigned long *)&tempf) + 1; 00252 00253 tempf = y; 00254 *tfptr = (0xbfcdd90a - *tfptr)>>1; /* estimate of 1/sqrt(y) */ 00255 x = tempf; 00256 z = y*btScalar(0.5); 00257 x = (btScalar(1.5)*x)-(x*x)*(x*z); /* iteration formula */ 00258 x = (btScalar(1.5)*x)-(x*x)*(x*z); 00259 x = (btScalar(1.5)*x)-(x*x)*(x*z); 00260 x = (btScalar(1.5)*x)-(x*x)*(x*z); 00261 x = (btScalar(1.5)*x)-(x*x)*(x*z); 00262 return x*y; 00263 #else 00264 return sqrtf(y); 00265 #endif 00266 } 00267 SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabsf(x); } 00268 SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cosf(x); } 00269 SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); } 00270 SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); } 00271 SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { 00272 if (x<btScalar(-1)) 00273 x=btScalar(-1); 00274 if (x>btScalar(1)) 00275 x=btScalar(1); 00276 return acosf(x); 00277 } 00278 SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { 00279 if (x<btScalar(-1)) 00280 x=btScalar(-1); 00281 if (x>btScalar(1)) 00282 x=btScalar(1); 00283 return asinf(x); 00284 } 00285 SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); } 00286 SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); } 00287 SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return expf(x); } 00288 SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return logf(x); } 00289 SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return powf(x,y); } 00290 SIMD_FORCE_INLINE btScalar btFmod(btScalar x,btScalar y) { return fmodf(x,y); } 00291 00292 #endif 00293 00294 #define SIMD_2_PI btScalar(6.283185307179586232) 00295 #define SIMD_PI (SIMD_2_PI * btScalar(0.5)) 00296 #define SIMD_HALF_PI (SIMD_2_PI * btScalar(0.25)) 00297 #define SIMD_RADS_PER_DEG (SIMD_2_PI / btScalar(360.0)) 00298 #define SIMD_DEGS_PER_RAD (btScalar(360.0) / SIMD_2_PI) 00299 #define SIMDSQRT12 btScalar(0.7071067811865475244008443621048490) 00300 00301 #define btRecipSqrt(x) ((btScalar)(btScalar(1.0)/btSqrt(btScalar(x)))) /* reciprocal square root */ 00302 00303 00304 #ifdef BT_USE_DOUBLE_PRECISION 00305 #define SIMD_EPSILON DBL_EPSILON 00306 #define SIMD_INFINITY DBL_MAX 00307 #else 00308 #define SIMD_EPSILON FLT_EPSILON 00309 #define SIMD_INFINITY FLT_MAX 00310 #endif 00311 00312 SIMD_FORCE_INLINE btScalar btAtan2Fast(btScalar y, btScalar x) 00313 { 00314 btScalar coeff_1 = SIMD_PI / 4.0f; 00315 btScalar coeff_2 = 3.0f * coeff_1; 00316 btScalar abs_y = btFabs(y); 00317 btScalar angle; 00318 if (x >= 0.0f) { 00319 btScalar r = (x - abs_y) / (x + abs_y); 00320 angle = coeff_1 - coeff_1 * r; 00321 } else { 00322 btScalar r = (x + abs_y) / (abs_y - x); 00323 angle = coeff_2 - coeff_1 * r; 00324 } 00325 return (y < 0.0f) ? -angle : angle; 00326 } 00327 00328 SIMD_FORCE_INLINE bool btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; } 00329 00330 SIMD_FORCE_INLINE bool btEqual(btScalar a, btScalar eps) { 00331 return (((a) <= eps) && !((a) < -eps)); 00332 } 00333 SIMD_FORCE_INLINE bool btGreaterEqual (btScalar a, btScalar eps) { 00334 return (!((a) <= eps)); 00335 } 00336 00337 00338 SIMD_FORCE_INLINE int btIsNegative(btScalar x) { 00339 return x < btScalar(0.0) ? 1 : 0; 00340 } 00341 00342 SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; } 00343 SIMD_FORCE_INLINE btScalar btDegrees(btScalar x) { return x * SIMD_DEGS_PER_RAD; } 00344 00345 #define BT_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name 00346 00347 #ifndef btFsel 00348 SIMD_FORCE_INLINE btScalar btFsel(btScalar a, btScalar b, btScalar c) 00349 { 00350 return a >= 0 ? b : c; 00351 } 00352 #endif 00353 #define btFsels(a,b,c) (btScalar)btFsel(a,b,c) 00354 00355 00356 SIMD_FORCE_INLINE bool btMachineIsLittleEndian() 00357 { 00358 long int i = 1; 00359 const char *p = (const char *) &i; 00360 if (p[0] == 1) // Lowest address contains the least significant byte 00361 return true; 00362 else 00363 return false; 00364 } 00365 00366 00367 00370 SIMD_FORCE_INLINE unsigned btSelect(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero) 00371 { 00372 // Set testNz to 0xFFFFFFFF if condition is nonzero, 0x00000000 if condition is zero 00373 // Rely on positive value or'ed with its negative having sign bit on 00374 // and zero value or'ed with its negative (which is still zero) having sign bit off 00375 // Use arithmetic shift right, shifting the sign bit through all 32 bits 00376 unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31); 00377 unsigned testEqz = ~testNz; 00378 return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); 00379 } 00380 SIMD_FORCE_INLINE int btSelect(unsigned condition, int valueIfConditionNonZero, int valueIfConditionZero) 00381 { 00382 unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31); 00383 unsigned testEqz = ~testNz; 00384 return static_cast<int>((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); 00385 } 00386 SIMD_FORCE_INLINE float btSelect(unsigned condition, float valueIfConditionNonZero, float valueIfConditionZero) 00387 { 00388 #ifdef BT_HAVE_NATIVE_FSEL 00389 return (float)btFsel((btScalar)condition - btScalar(1.0f), valueIfConditionNonZero, valueIfConditionZero); 00390 #else 00391 return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero; 00392 #endif 00393 } 00394 00395 template<typename T> SIMD_FORCE_INLINE void btSwap(T& a, T& b) 00396 { 00397 T tmp = a; 00398 a = b; 00399 b = tmp; 00400 } 00401 00402 00403 //PCK: endian swapping functions 00404 SIMD_FORCE_INLINE unsigned btSwapEndian(unsigned val) 00405 { 00406 return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); 00407 } 00408 00409 SIMD_FORCE_INLINE unsigned short btSwapEndian(unsigned short val) 00410 { 00411 return static_cast<unsigned short>(((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)); 00412 } 00413 00414 SIMD_FORCE_INLINE unsigned btSwapEndian(int val) 00415 { 00416 return btSwapEndian((unsigned)val); 00417 } 00418 00419 SIMD_FORCE_INLINE unsigned short btSwapEndian(short val) 00420 { 00421 return btSwapEndian((unsigned short) val); 00422 } 00423 00430 SIMD_FORCE_INLINE unsigned int btSwapEndianFloat(float d) 00431 { 00432 unsigned int a = 0; 00433 unsigned char *dst = (unsigned char *)&a; 00434 unsigned char *src = (unsigned char *)&d; 00435 00436 dst[0] = src[3]; 00437 dst[1] = src[2]; 00438 dst[2] = src[1]; 00439 dst[3] = src[0]; 00440 return a; 00441 } 00442 00443 // unswap using char pointers 00444 SIMD_FORCE_INLINE float btUnswapEndianFloat(unsigned int a) 00445 { 00446 float d = 0.0f; 00447 unsigned char *src = (unsigned char *)&a; 00448 unsigned char *dst = (unsigned char *)&d; 00449 00450 dst[0] = src[3]; 00451 dst[1] = src[2]; 00452 dst[2] = src[1]; 00453 dst[3] = src[0]; 00454 00455 return d; 00456 } 00457 00458 00459 // swap using char pointers 00460 SIMD_FORCE_INLINE void btSwapEndianDouble(double d, unsigned char* dst) 00461 { 00462 unsigned char *src = (unsigned char *)&d; 00463 00464 dst[0] = src[7]; 00465 dst[1] = src[6]; 00466 dst[2] = src[5]; 00467 dst[3] = src[4]; 00468 dst[4] = src[3]; 00469 dst[5] = src[2]; 00470 dst[6] = src[1]; 00471 dst[7] = src[0]; 00472 00473 } 00474 00475 // unswap using char pointers 00476 SIMD_FORCE_INLINE double btUnswapEndianDouble(const unsigned char *src) 00477 { 00478 double d = 0.0; 00479 unsigned char *dst = (unsigned char *)&d; 00480 00481 dst[0] = src[7]; 00482 dst[1] = src[6]; 00483 dst[2] = src[5]; 00484 dst[3] = src[4]; 00485 dst[4] = src[3]; 00486 dst[5] = src[2]; 00487 dst[6] = src[1]; 00488 dst[7] = src[0]; 00489 00490 return d; 00491 } 00492 00493 // returns normalized value in range [-SIMD_PI, SIMD_PI] 00494 SIMD_FORCE_INLINE btScalar btNormalizeAngle(btScalar angleInRadians) 00495 { 00496 angleInRadians = btFmod(angleInRadians, SIMD_2_PI); 00497 if(angleInRadians < -SIMD_PI) 00498 { 00499 return angleInRadians + SIMD_2_PI; 00500 } 00501 else if(angleInRadians > SIMD_PI) 00502 { 00503 return angleInRadians - SIMD_2_PI; 00504 } 00505 else 00506 { 00507 return angleInRadians; 00508 } 00509 } 00510 00512 struct btTypedObject 00513 { 00514 btTypedObject(int objectType) 00515 :m_objectType(objectType) 00516 { 00517 } 00518 int m_objectType; 00519 inline int getObjectType() const 00520 { 00521 return m_objectType; 00522 } 00523 }; 00524 #endif //SIMD___SCALAR_H