Scalar.h
Go to the documentation of this file.
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 
16 
17 #ifndef TF_SCALAR_H
18 #define TF_SCALAR_H
19 
20 #ifdef TF_MANAGED_CODE
21 //Aligned data types not supported in managed code
22 #pragma unmanaged
23 #endif
24 
25 
26 #include <math.h>
27 #include <stdlib.h>//size_t for MSVC 6.0
28 #include <cstdlib>
29 #include <cfloat>
30 #include <float.h>
31 
32 #if defined(DEBUG) || defined (_DEBUG)
33 #define TF_DEBUG
34 #endif
35 
36 
37 #ifdef _WIN32
38 
39  #if defined(__MINGW32__) || defined(__CYGWIN__) || (defined (_MSC_VER) && _MSC_VER < 1300)
40 
41  #define TFSIMD_FORCE_INLINE inline
42  #define ATTRIBUTE_ALIGNED16(a) a
43  #define ATTRIBUTE_ALIGNED64(a) a
44  #define ATTRIBUTE_ALIGNED128(a) a
45  #else
46  //#define TF_HAS_ALIGNED_ALLOCATOR
47  #pragma warning(disable : 4324) // disable padding warning
48 // #pragma warning(disable:4530) // Disable the exception disable but used in MSCV Stl warning.
49 // #pragma warning(disable:4996) //Turn off warnings about deprecated C routines
50 // #pragma warning(disable:4786) // Disable the "debug name too long" warning
51 
52  #define TFSIMD_FORCE_INLINE __forceinline
53  #define ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a
54  #define ATTRIBUTE_ALIGNED64(a) __declspec(align(64)) a
55  #define ATTRIBUTE_ALIGNED128(a) __declspec (align(128)) a
56  #ifdef _XBOX
57  #define TF_USE_VMX128
58 
59  #include <ppcintrinsics.h>
60  #define TF_HAVE_NATIVE_FSEL
61  #define tfFsel(a,b,c) __fsel((a),(b),(c))
62  #else
63 
64 
65  #endif//_XBOX
66 
67  #endif //__MINGW32__
68 
69  #include <assert.h>
70 #ifdef TF_DEBUG
71  #define tfAssert assert
72 #else
73  #define tfAssert(x)
74 #endif
75  //tfFullAssert is optional, slows down a lot
76  #define tfFullAssert(x)
77 
78  #define tfLikely(_c) _c
79  #define tfUnlikely(_c) _c
80 
81 #else
82 
83 #if defined (__CELLOS_LV2__)
84  #define TFSIMD_FORCE_INLINE inline
85  #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
86  #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
87  #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
88  #ifndef assert
89  #include <assert.h>
90  #endif
91 #ifdef TF_DEBUG
92  #define tfAssert assert
93 #else
94  #define tfAssert(x)
95 #endif
96  //tfFullAssert is optional, slows down a lot
97  #define tfFullAssert(x)
98 
99  #define tfLikely(_c) _c
100  #define tfUnlikely(_c) _c
101 
102 #else
103 
104 #ifdef USE_LIBSPE2
105 
106  #define TFSIMD_FORCE_INLINE __inline
107  #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
108  #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
109  #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
110  #ifndef assert
111  #include <assert.h>
112  #endif
113 #ifdef TF_DEBUG
114  #define tfAssert assert
115 #else
116  #define tfAssert(x)
117 #endif
118  //tfFullAssert is optional, slows down a lot
119  #define tfFullAssert(x)
120 
121 
122  #define tfLikely(_c) __builtin_expect((_c), 1)
123  #define tfUnlikely(_c) __builtin_expect((_c), 0)
124 
125 
126 #else
127  //non-windows systems
128 
129 
130  #define TFSIMD_FORCE_INLINE inline
131  #define ATTRIBUTE_ALIGNED16(a) a
136  #define ATTRIBUTE_ALIGNED64(a) a
137  #define ATTRIBUTE_ALIGNED128(a) a
138  #ifndef assert
139  #include <assert.h>
140  #endif
141 
142 #if defined(DEBUG) || defined (_DEBUG)
143  #define tfAssert assert
144 #else
145  #define tfAssert(x)
146 #endif
147 
148  //tfFullAssert is optional, slows down a lot
149  #define tfFullAssert(x)
150  #define tfLikely(_c) _c
151  #define tfUnlikely(_c) _c
152 
153 #endif // LIBSPE2
154 
155 #endif //__CELLOS_LV2__
156 #endif
157 
158 
160 typedef double tfScalar;
161 //this number could be bigger in double precision
162 #define TF_LARGE_FLOAT 1e30
163 
164 
165 
166 #define TF_DECLARE_ALIGNED_ALLOCATOR() \
167  TFSIMD_FORCE_INLINE void* operator new(size_t sizeInBytes) { return tfAlignedAlloc(sizeInBytes,16); } \
168  TFSIMD_FORCE_INLINE void operator delete(void* ptr) { tfAlignedFree(ptr); } \
169  TFSIMD_FORCE_INLINE void* operator new(size_t, void* ptr) { return ptr; } \
170  TFSIMD_FORCE_INLINE void operator delete(void*, void*) { } \
171  TFSIMD_FORCE_INLINE void* operator new[](size_t sizeInBytes) { return tfAlignedAlloc(sizeInBytes,16); } \
172  TFSIMD_FORCE_INLINE void operator delete[](void* ptr) { tfAlignedFree(ptr); } \
173  TFSIMD_FORCE_INLINE void* operator new[](size_t, void* ptr) { return ptr; } \
174  TFSIMD_FORCE_INLINE void operator delete[](void*, void*) { } \
175 
176 
177 
178 
184 TFSIMD_FORCE_INLINE tfScalar tfAcos(tfScalar x) { if (x<tfScalar(-1)) x=tfScalar(-1); if (x>tfScalar(1)) x=tfScalar(1); return acos(x); }
185 TFSIMD_FORCE_INLINE tfScalar tfAsin(tfScalar x) { if (x<tfScalar(-1)) x=tfScalar(-1); if (x>tfScalar(1)) x=tfScalar(1); return asin(x); }
187 TFSIMD_FORCE_INLINE tfScalar tfAtan2(tfScalar x, tfScalar y) { return atan2(x, y); }
192 
193 
194 #define TFSIMD_2_PI tfScalar(6.283185307179586232)
195 #define TFSIMD_PI (TFSIMD_2_PI * tfScalar(0.5))
196 #define TFSIMD_HALF_PI (TFSIMD_2_PI * tfScalar(0.25))
197 #define TFSIMD_RADS_PER_DEG (TFSIMD_2_PI / tfScalar(360.0))
198 #define TFSIMD_DEGS_PER_RAD (tfScalar(360.0) / TFSIMD_2_PI)
199 #define TFSIMDSQRT12 tfScalar(0.7071067811865475244008443621048490)
200 
201 #define tfRecipSqrt(x) ((tfScalar)(tfScalar(1.0)/tfSqrt(tfScalar(x)))) /* reciprocal square root */
202 
203 
204 #define TFSIMD_EPSILON DBL_EPSILON
205 #define TFSIMD_INFINITY DBL_MAX
206 
208 {
209  tfScalar coeff_1 = TFSIMD_PI / 4.0f;
210  tfScalar coeff_2 = 3.0f * coeff_1;
211  tfScalar abs_y = tfFabs(y);
212  tfScalar angle;
213  if (x >= 0.0f) {
214  tfScalar r = (x - abs_y) / (x + abs_y);
215  angle = coeff_1 - coeff_1 * r;
216  } else {
217  tfScalar r = (x + abs_y) / (abs_y - x);
218  angle = coeff_2 - coeff_1 * r;
219  }
220  return (y < 0.0f) ? -angle : angle;
221 }
222 
224 
226  return (((a) <= eps) && !((a) < -eps));
227 }
229  return (!((a) <= eps));
230 }
231 
232 
234  return x < tfScalar(0.0) ? 1 : 0;
235 }
236 
239 
240 #define TF_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
241 
242 #ifndef tfFsel
244 {
245  return a >= 0 ? b : c;
246 }
247 #endif
248 #define tfFsels(a,b,c) (tfScalar)tfFsel(a,b,c)
249 
250 
252 {
253  long int i = 1;
254  const char *p = (const char *) &i;
255  if (p[0] == 1) // Lowest address contains the least significant byte
256  return true;
257  else
258  return false;
259 }
260 
261 
262 
265 TFSIMD_FORCE_INLINE unsigned tfSelect(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero)
266 {
267  // Set testNz to 0xFFFFFFFF if condition is nonzero, 0x00000000 if condition is zero
268  // Rely on positive value or'ed with its negative having sign bit on
269  // and zero value or'ed with its negative (which is still zero) having sign bit off
270  // Use arithmetic shift right, shifting the sign bit through all 32 bits
271  unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
272  unsigned testEqz = ~testNz;
273  return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz));
274 }
275 TFSIMD_FORCE_INLINE int tfSelect(unsigned condition, int valueIfConditionNonZero, int valueIfConditionZero)
276 {
277  unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
278  unsigned testEqz = ~testNz;
279  return static_cast<int>((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz));
280 }
281 TFSIMD_FORCE_INLINE float tfSelect(unsigned condition, float valueIfConditionNonZero, float valueIfConditionZero)
282 {
283 #ifdef TF_HAVE_NATIVE_FSEL
284  return (float)tfFsel((tfScalar)condition - tfScalar(1.0f), valueIfConditionNonZero, valueIfConditionZero);
285 #else
286  return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero;
287 #endif
288 }
289 
290 template<typename T> TFSIMD_FORCE_INLINE void tfSwap(T& a, T& b)
291 {
292  T tmp = a;
293  a = b;
294  b = tmp;
295 }
296 
297 
298 //PCK: endian swapping functions
299 TFSIMD_FORCE_INLINE unsigned tfSwapEndian(unsigned val)
300 {
301  return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
302 }
303 
304 TFSIMD_FORCE_INLINE unsigned short tfSwapEndian(unsigned short val)
305 {
306  return static_cast<unsigned short>(((val & 0xff00) >> 8) | ((val & 0x00ff) << 8));
307 }
308 
310 {
311  return tfSwapEndian((unsigned)val);
312 }
313 
314 TFSIMD_FORCE_INLINE unsigned short tfSwapEndian(short val)
315 {
316  return tfSwapEndian((unsigned short) val);
317 }
318 
326 {
327  unsigned int a = 0;
328  unsigned char *dst = (unsigned char *)&a;
329  unsigned char *src = (unsigned char *)&d;
330 
331  dst[0] = src[3];
332  dst[1] = src[2];
333  dst[2] = src[1];
334  dst[3] = src[0];
335  return a;
336 }
337 
338 // unswap using char pointers
340 {
341  float d = 0.0f;
342  unsigned char *src = (unsigned char *)&a;
343  unsigned char *dst = (unsigned char *)&d;
344 
345  dst[0] = src[3];
346  dst[1] = src[2];
347  dst[2] = src[1];
348  dst[3] = src[0];
349 
350  return d;
351 }
352 
353 
354 // swap using char pointers
355 TFSIMD_FORCE_INLINE void tfSwapEndianDouble(double d, unsigned char* dst)
356 {
357  unsigned char *src = (unsigned char *)&d;
358 
359  dst[0] = src[7];
360  dst[1] = src[6];
361  dst[2] = src[5];
362  dst[3] = src[4];
363  dst[4] = src[3];
364  dst[5] = src[2];
365  dst[6] = src[1];
366  dst[7] = src[0];
367 
368 }
369 
370 // unswap using char pointers
371 TFSIMD_FORCE_INLINE double tfUnswapEndianDouble(const unsigned char *src)
372 {
373  double d = 0.0;
374  unsigned char *dst = (unsigned char *)&d;
375 
376  dst[0] = src[7];
377  dst[1] = src[6];
378  dst[2] = src[5];
379  dst[3] = src[4];
380  dst[4] = src[3];
381  dst[5] = src[2];
382  dst[6] = src[1];
383  dst[7] = src[0];
384 
385  return d;
386 }
387 
388 // returns normalized value in range [-TFSIMD_PI, TFSIMD_PI]
390 {
391  angleInRadians = tfFmod(angleInRadians, TFSIMD_2_PI);
392  if(angleInRadians < -TFSIMD_PI)
393  {
394  return angleInRadians + TFSIMD_2_PI;
395  }
396  else if(angleInRadians > TFSIMD_PI)
397  {
398  return angleInRadians - TFSIMD_2_PI;
399  }
400  else
401  {
402  return angleInRadians;
403  }
404 }
405 
408 {
409  tfTypedObject(int objectType)
410  :m_objectType(objectType)
411  {
412  }
414  inline int getObjectType() const
415  {
416  return m_objectType;
417  }
418 };
419 #endif //TFSIMD___SCALAR_H
tfTan
TFSIMD_FORCE_INLINE tfScalar tfTan(tfScalar x)
Definition: Scalar.h:183
tfTypedObject::getObjectType
int getObjectType() const
Definition: Scalar.h:414
tfAtan2Fast
TFSIMD_FORCE_INLINE tfScalar tfAtan2Fast(tfScalar y, tfScalar x)
Definition: Scalar.h:207
tfAcos
TFSIMD_FORCE_INLINE tfScalar tfAcos(tfScalar x)
Definition: Scalar.h:184
TFSIMD_RADS_PER_DEG
#define TFSIMD_RADS_PER_DEG
Definition: Scalar.h:197
tfFmod
TFSIMD_FORCE_INLINE tfScalar tfFmod(tfScalar x, tfScalar y)
Definition: Scalar.h:191
tfTypedObject
rudimentary class to provide type info
Definition: Scalar.h:407
tfUnswapEndianFloat
TFSIMD_FORCE_INLINE float tfUnswapEndianFloat(unsigned int a)
Definition: Scalar.h:339
TFSIMD_FORCE_INLINE
#define TFSIMD_FORCE_INLINE
Definition: Scalar.h:130
tfFabs
TFSIMD_FORCE_INLINE tfScalar tfFabs(tfScalar x)
Definition: Scalar.h:180
tfSqrt
TFSIMD_FORCE_INLINE tfScalar tfSqrt(tfScalar x)
Definition: Scalar.h:179
TFSIMD_PI
#define TFSIMD_PI
Definition: Scalar.h:195
tfSin
TFSIMD_FORCE_INLINE tfScalar tfSin(tfScalar x)
Definition: Scalar.h:182
tfIsNegative
TFSIMD_FORCE_INLINE int tfIsNegative(tfScalar x)
Definition: Scalar.h:233
tfAsin
TFSIMD_FORCE_INLINE tfScalar tfAsin(tfScalar x)
Definition: Scalar.h:185
f
f
tfExp
TFSIMD_FORCE_INLINE tfScalar tfExp(tfScalar x)
Definition: Scalar.h:188
TFSIMD_2_PI
#define TFSIMD_2_PI
Definition: Scalar.h:194
tfPow
TFSIMD_FORCE_INLINE tfScalar tfPow(tfScalar x, tfScalar y)
Definition: Scalar.h:190
tfEqual
TFSIMD_FORCE_INLINE bool tfEqual(tfScalar a, tfScalar eps)
Definition: Scalar.h:225
tfUnswapEndianDouble
TFSIMD_FORCE_INLINE double tfUnswapEndianDouble(const unsigned char *src)
Definition: Scalar.h:371
tfMachineIsLittleEndian
TFSIMD_FORCE_INLINE bool tfMachineIsLittleEndian()
Definition: Scalar.h:251
tfDegrees
TFSIMD_FORCE_INLINE tfScalar tfDegrees(tfScalar x)
Definition: Scalar.h:238
d
d
tfLog
TFSIMD_FORCE_INLINE tfScalar tfLog(tfScalar x)
Definition: Scalar.h:189
TFSIMD_EPSILON
#define TFSIMD_EPSILON
Definition: Scalar.h:204
tfRadians
TFSIMD_FORCE_INLINE tfScalar tfRadians(tfScalar x)
Definition: Scalar.h:237
tfSwapEndian
TFSIMD_FORCE_INLINE unsigned tfSwapEndian(unsigned val)
Definition: Scalar.h:299
tfTypedObject::m_objectType
int m_objectType
Definition: Scalar.h:413
tfSelect
TFSIMD_FORCE_INLINE unsigned tfSelect(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero)
Definition: Scalar.h:265
tfNormalizeAngle
TFSIMD_FORCE_INLINE tfScalar tfNormalizeAngle(tfScalar angleInRadians)
Definition: Scalar.h:389
tfSwap
TFSIMD_FORCE_INLINE void tfSwap(T &a, T &b)
Definition: Scalar.h:290
tfScalar
double tfScalar
The tfScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: Scalar.h:160
tfAtan
TFSIMD_FORCE_INLINE tfScalar tfAtan(tfScalar x)
Definition: Scalar.h:186
angle
TF2SIMD_FORCE_INLINE tf2Scalar angle(const Quaternion &q1, const Quaternion &q2)
tfFsel
TFSIMD_FORCE_INLINE tfScalar tfFsel(tfScalar a, tfScalar b, tfScalar c)
Definition: Scalar.h:243
TFSIMD_DEGS_PER_RAD
#define TFSIMD_DEGS_PER_RAD
Definition: Scalar.h:198
tfTypedObject::tfTypedObject
tfTypedObject(int objectType)
Definition: Scalar.h:409
tfSwapEndianFloat
TFSIMD_FORCE_INLINE unsigned int tfSwapEndianFloat(float d)
tfSwapFloat uses using char pointers to swap the endianness
Definition: Scalar.h:325
assert.h
tfCos
TFSIMD_FORCE_INLINE tfScalar tfCos(tfScalar x)
Definition: Scalar.h:181
tfFuzzyZero
TFSIMD_FORCE_INLINE bool tfFuzzyZero(tfScalar x)
Definition: Scalar.h:223
tfSwapEndianDouble
TFSIMD_FORCE_INLINE void tfSwapEndianDouble(double d, unsigned char *dst)
Definition: Scalar.h:355
tfGreaterEqual
TFSIMD_FORCE_INLINE bool tfGreaterEqual(tfScalar a, tfScalar eps)
Definition: Scalar.h:228
tfAtan2
TFSIMD_FORCE_INLINE tfScalar tfAtan2(tfScalar x, tfScalar y)
Definition: Scalar.h:187


tf
Author(s): Tully Foote, Eitan Marder-Eppstein, Wim Meeussen
autogenerated on Sat Aug 19 2023 02:38:07