Newton Dynamics  4.00
dTypes.h
1 /* Copyright (c) <2003-2019> <Julio Jerez, Newton Game Dynamics>
2 *
3 * This software is provided 'as-is', without any express or implied
4 * warranty. In no event will the authors be held liable for any damages
5 * arising from the use of this software.
6 *
7 * Permission is granted to anyone to use this software for any purpose,
8 * including commercial applications, and to alter it and redistribute it
9 * freely, subject to the following restrictions:
10 *
11 * 1. The origin of this software must not be misrepresented; you must not
12 * claim that you wrote the original software. If you use this software
13 * in a product, an acknowledgment in the product documentation would be
14 * appreciated but is not required.
15 *
16 * 2. Altered source versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software.
18 *
19 * 3. This notice may not be removed or altered from any source distribution.
20 */
21 
22 #ifndef __D_TYPES_H__
23 #define __D_TYPES_H__
24 
25 #ifdef _MSC_VER
26  #if defined (_M_ARM) || defined (_M_ARM64)
27  #ifndef _ARM_VER
28  #define _ARM_VER
29  #endif
30  #elif defined (_M_X64)
31  #ifndef _WIN_64_VER
32  #define _WIN_64_VER
33  #endif
34  #elif defined (_M_IX86)
35  #ifndef _WIN_32_VER
36  #define _WIN_32_VER
37  #endif
38  #else
39  #error target platform not defined
40  #endif
41 
42  #if _MSC_VER >= 1400
43  #define HAVE_STRUCT_TIMESPEC
44  #endif
45 #endif
46 
47 #if (defined (_WIN_32_VER) || defined (_WIN_64_VER) || (defined (_MSC_VER ) && defined (_ARM_VER)) )
48  #include <io.h>
49  #include <stdint.h>
50  #include <direct.h>
51  #include <malloc.h>
52  #include <stdarg.h>
53  #include <process.h>
54 
55  #pragma warning (push, 3)
56  #include <windows.h>
57  #include <crtdbg.h>
58  #pragma warning (pop)
59 #endif
60 
61 #include <new>
62 #include <mutex>
63 #include <atomic>
64 #include <thread>
65 #include <chrono>
66 #include <math.h>
67 #include <float.h>
68 #include <ctype.h>
69 #include <stdio.h>
70 #include <stdlib.h>
71 #include <string.h>
72 #include <stdarg.h>
73 #include <locale.h>
74 #include <tinyxml.h>
75 #include <condition_variable>
76 
77 #if (defined (__MINGW32__) || defined (__MINGW64__))
78  #include <io.h>
79  #include <direct.h>
80  #include <malloc.h>
81  #include <float.h>
82  #include <windows.h>
83  #include <process.h>
84 #endif
85 
86 #if (defined (_WIN_32_VER) || defined (_WIN_64_VER))
87  #include <intrin.h>
88  #include <emmintrin.h>
89  #include <pmmintrin.h>
90 #endif
91 
92 #if (defined (_POSIX_VER) || defined (_POSIX_VER_64) || defined (__MINGW32__) || defined (__MINGW64__))
93  // CMake defines NDEBUG for _not_ debug builds. Therefore, set
94  // Newton's _DEBUG flag only when NDEBUG is not defined.
95 
96  #ifndef NDEBUG
97  #define _DEBUG 1
98  #endif
99 
100  #include <unistd.h>
101  #include <assert.h>
102  #if (!defined(__arm__) && !defined(__aarch64__)) // it was __ARMCC_VERSION before, it should be __ARM__ or aarch64, otherwise cross compiling in gcc fails.
103  extern "C"
104  {
105  // for SSE3 and up
106  #include <pmmintrin.h>
107  #include <emmintrin.h>
108  #include <mmintrin.h>
109  }
110  #endif
111 #endif
112 
113 #ifdef _MACOSX_VER
114  #include <unistd.h>
115  #include <sys/sysctl.h>
116  #include <assert.h>
117  #if (defined __i386__ || defined __x86_64__)
118  #include <fenv.h>
119  #include <pmmintrin.h>
120  #include <emmintrin.h> //sse3
121  #include <mmintrin.h>
122  #endif
123 #endif
124 
125 //#define DG_PROFILE_PHYSICS
126 
127 // uncomment out D_PROFILER to enable profiler frame capture profiler traces
128 // alternatively the end application can use a command line option to enable this define
129 //#define D_PROFILER
130 
131 // uncomment this for Scalar floating point
132 // alternatively the end application can use a command line option to enable this define
133 //#define D_SCALAR_VECTOR_CLASS
134 
135 // uncomment this for Scalar floating point
136 // alternatively the end application can use a command line option to enable this define
137 //#define __ANDROID__
138 
139 // by default newton run on a separate thread and
140 // optionally concurrent with the calling thread,
141 // it also uses a thread job pool for multi core systems.
142 // define D_USE_THREAD_EMULATION on the command line for
143 // platform that do not support hardware multi threading or
144 // if the and application want to control threading at the application level
145 //#define D_USE_THREAD_EMULATION
146 
147 #if (defined (_WIN_32_VER) || defined (_WIN_64_VER))
148  #if _MSC_VER < 1700
149  #ifndef D_USE_THREAD_EMULATION
150  #define D_USE_THREAD_EMULATION
151  #endif
152  #endif
153 #endif
154 
155 //************************************************************
156 #ifdef D_DISABLE_ASSERT
157  #define dAssert(x)
158 #else
159  #if defined (_WIN_32_VER) || defined (_WIN_64_VER)
160  #define dAssert(x) _ASSERTE(x)
161  #elif defined (_MSC_VER ) && defined (_ARM_VER)
162  #define dAssert(x) _ASSERTE(x)
163  #else
164  #ifdef _DEBUG
165  #define dAssert(x) assert(x)
166  #else
167  #define dAssert(x)
168  #endif
169  #endif
170 #endif
171 
172 #ifdef _DEBUG
173 //#define __ENABLE_D_CONTAINERS_SANITY_CHECK
174 #endif
175 
176 #ifdef _DEBUG
177  #define D_INLINE inline
178 #else
179  #if defined(_MSC_VER)
180  #define D_INLINE __forceinline
181  #else
182  #define D_INLINE inline
183  //#define D_INLINE __attribute__((always_inline))
184  #endif
185 #endif
186 
187 #if defined (D_USE_VECTOR_AVX)
188  #if defined(_MSC_VER)
189  #define D_MSV_NEWTON_ALIGN_16 __declspec(align(16))
190  #define D_GCC_NEWTON_ALIGN_16
191 
192  #define D_MSV_NEWTON_ALIGN_32 __declspec(align(32))
193  #define D_GCC_NEWTON_ALIGN_32
194  #else
195  #define D_MSV_NEWTON_ALIGN_16
196  #define D_GCC_NEWTON_ALIGN_16 __attribute__((aligned (16)))
197 
198  #define D_MSV_NEWTON_ALIGN_32
199  #define D_GCC_NEWTON_ALIGN_32 __attribute__((aligned (32)))
200  #endif
201 #else
202  #if defined(_MSC_VER)
203  #define D_GCC_NEWTON_ALIGN_16
204  #define D_MSV_NEWTON_ALIGN_16 __declspec(align(16))
205 
206  #define D_GCC_NEWTON_ALIGN_32
207  #define D_MSV_NEWTON_ALIGN_32 __declspec(align(32))
208  #else
209  #define D_GCC_NEWTON_ALIGN_16 __attribute__((aligned (16)))
210  #define D_MSV_NEWTON_ALIGN_16
211 
212  #define D_GCC_NEWTON_ALIGN_32 __attribute__((aligned (32)))
213  #define D_MSV_NEWTON_ALIGN_32
214  #endif
215 #endif
216 
217 #if defined(_MSC_VER)
218  #define D_LIBRARY_EXPORT __declspec(dllexport)
219  #define D_LIBRARY_IMPORT __declspec(dllimport)
220 #else
221  #define D_LIBRARY_EXPORT __attribute__((visibility("default")))
222  #define D_LIBRARY_IMPORT __attribute__((visibility("default")))
223 #endif
224 
225 #ifdef _D_CORE_DLL
226  #ifdef _D_CORE_EXPORT_DLL
227  #define D_CORE_API D_LIBRARY_EXPORT
228  #else
229  #define D_CORE_API D_LIBRARY_IMPORT
230  #endif
231 #else
232  #define D_CORE_API
233 #endif
234 
235 #if ((defined (_WIN_32_VER) || defined (_WIN_64_VER)) && (_MSC_VER >= 1600))
236  typedef int8_t dInt8;
237  typedef uint8_t dUnsigned8;
238 
239  typedef int16_t dInt16;
240  typedef uint16_t dUnsigned16;
241 
242  typedef int32_t dInt32;
243  typedef uint32_t dUnsigned32;
244 
245  typedef int64_t dInt64;
246  typedef uint64_t dUnsigned64;
247 #else
248  typedef char dInt8;
249  typedef unsigned char dUnsigned8;
250 
251  typedef short dInt16;
252  typedef unsigned short dUnsigned16;
253 
254  typedef int dInt32;
255  typedef unsigned dUnsigned32;
256  typedef unsigned int dUnsigned32;
257 
258  typedef long long dInt64;
259  typedef unsigned long long dUnsigned64;
260  typedef double dFloat64;
261 #endif
262 
263 typedef double dFloat64;
264 
265 #ifdef D_NEWTON_USE_DOUBLE
266  typedef double dFloat32;
267 #else
268  typedef float dFloat32;
269 #endif
270 
271 class dTriplex
272 {
273  public:
274  dFloat32 m_x;
275  dFloat32 m_y;
276  dFloat32 m_z;
277 };
278 
279 #define dPi dFloat32 (3.141592f)
280 //#define dPi2 dFloat32 (dPi * 2.0f)
281 #define dEXP dFloat32 (2.71828f)
282 #define dEpsilon dFloat32 (1.0e-5f)
283 #define dDegreeToRad dFloat32 (dPi / 180.0f)
284 #define dRadToDegree dFloat32 (180.0f / dPi)
285 
286 #define dSqrt(x) dFloat32 (sqrt(x))
287 #define dSin(x) dFloat32 (sin(x))
288 #define dCos(x) dFloat32 (cos(x))
289 #define dAsin(x) dFloat32 (asin(x))
290 #define dAcos(x) dFloat32 (acos(x))
291 #define dLog(x) dFloat32 (log(x))
292 #define dCeil(x) dFloat32 (ceil(x))
293 #define dFloor(x) dFloat32 (floor(x))
294 #define dPow(x,y) dFloat32 (pow(x,y))
295 #define dFmod(x,y) dFloat32 (fmod(x,y))
296 #define dTan(x) dFloat32 (tan(x))
297 #define dAtan2(x,y) dFloat32 (atan2(x,y))
298 #define dRsqrt(x) (dFloat32 (1.0f) / dSqrt(x))
299 #define dClearFP() _clearfp()
300 #define dControlFP(x,y) _controlfp(x,y)
301 
302 class dMatrix;
303 class dBigVector;
304 #ifndef D_NEWTON_USE_DOUBLE
305  class dVector;
306 #endif
307 
308 #if (defined (_WIN_32_VER) || defined (_WIN_64_VER))
309  #define dCheckFloat(x) (_finite(x) && !_isnan(x))
310 // #define dCheckFloat(x) 1
311 #else
312  #define dCheckFloat(x) (isfinite(x) && !isnan(x))
313 // #define dCheckFloat(x) 1
314 #endif
315 
316 //typedef void (*dDeserialize) (void* const userData, void* buffer, dInt32 size);
317 //typedef void (*dSerialize) (void* const userData, const void* const buffer, dInt32 size);
318 //typedef bool (*dReportProgress) (dFloat32 progressNormalzedPercent, void* const userData);
319 
320 // assume this function returns memory aligned to 16 bytes
321 #define dAlloca(type, count) (type*) alloca (sizeof (type) * (count))
322 
323 D_INLINE dInt32 dExp2 (dInt32 x)
324 {
325  dInt32 exp;
326  for (exp = -1; x; x >>= 1)
327  {
328  exp ++;
329  }
330  return exp;
331 }
332 
333 D_INLINE dInt32 dBitReversal(dInt32 v, dInt32 base)
334 {
335  dInt32 x = 0;
336  dInt32 power = dExp2 (base) - 1;
337  do
338  {
339  x += (v & 1) << power;
340  v >>= 1;
341  power--;
342  } while (v);
343  dAssert(x < base);
344  return x;
345 }
346 
347 template <class T>
348 T dMod(T val, T mod)
349 {
350  return T(fmod(T(val), T(mod)));
351 }
352 
353 template <class T>
354 D_INLINE T dMin(T A, T B)
355 {
356  return (A < B) ? A : B;
357 }
358 
359 template <class T>
360 D_INLINE T dMax(T A, T B)
361 {
362  return (A > B) ? A : B;
363 }
364 
365 template <class T>
366 D_INLINE T dMin(T A, T B, T C)
367 {
368  return dMin(dMin (A, B), C);
369 }
370 
371 template <class T>
372 D_INLINE T dMax(T A, T B, T C)
373 {
374  return dMax(dMax (A, B), C);
375 }
376 
377 template <class T>
378 D_INLINE T dClamp(T val, T min, T max)
379 {
380  return dMax (min, dMin (max, val));
381 }
382 
383 template <class T>
384 D_INLINE void dSwap(T& A, T& B)
385 {
386  T tmp (A);
387  A = B;
388  B = tmp;
389 }
390 
391 template <class T>
392 D_INLINE T dAbs(T A)
393 {
394  // according to Intel this is better because is does not read after write
395  return (A >= T(0)) ? A : -A;
396 }
397 
398 template <class T>
399 D_INLINE T dSign(T A)
400 {
401  return (A >= T(0)) ? T(1) : T(-1);
402 }
403 
404 template <class T>
405 D_INLINE bool dAreEqual(T A, T B, T tol)
406 {
407  // deal with too small and de normal values.
408  if ((dAbs(A) < tol) && (dAbs(B) < tol))
409  {
410  return true;
411  }
412 
413  dInt32 exp0;
414  dFloat64 mantissa0 = frexp(dFloat64 (A), &exp0);
415 
416  dInt32 exp1;
417  dFloat64 mantissa1 = frexp(dFloat64(B), &exp1);
418  if (dAbs(exp0 - exp1) > 1)
419  {
420  return false;
421  }
422  if (exp0 != exp1)
423  {
424  if (exp0 > exp1)
425  {
426  mantissa0 *= dFloat32(2.0f);
427  }
428  else
429  {
430  mantissa1 *= dFloat32(2.0f);
431  }
432  }
433  return dAbs(mantissa0 - mantissa1) < tol;
434 }
435 
436 template <class T>
437 D_INLINE T AnglesAdd (T angleInRadiand1, T angleInRadiand0)
438 {
439  T s1 = T(dSin(angleInRadiand1));
440  T c1 = T(dCos(angleInRadiand1));
441  T s0 = T(dSin(angleInRadiand0));
442  T c0 = T(dCos(angleInRadiand0));
443 
444  T s = s1 * c0 + s0 * c1;
445  T c = c1 * c0 - s0 * s1;
446  return T(dAtan2(s, c));
447 }
448 
449 #ifdef D_NEWTON_USE_DOUBLE
450  union dFloatSign
451  {
452  struct
453  {
454  dInt32 m_dommy;
455  dInt32 m_iVal;
456  } m_integer;
457  dFloat64 m_fVal;
458  };
459 #else
461  {
462  struct
463  {
464  dInt32 m_iVal;
465  } m_integer;
466  dFloat32 m_fVal;
467  };
468 #endif
469 
471 {
472  struct
473  {
474  dInt32 m_intL;
475  dInt32 m_intH;
476  };
477  void* m_ptr;
478  dInt64 m_int;
479  dFloat64 m_float;
480 };
481 
482 #define PointerToInt(x) ((size_t)x)
483 #define IntToPointer(x) ((void*)(size_t(x)))
484 
485 #ifndef _MSC_VER
486  #define _stricmp(x,y) strcasecmp(x,y)
487 #endif
488 
490 D_CORE_API dUnsigned64 dGetCpuClock();
491 
493 D_CORE_API dUnsigned64 dGetTimeInMicrosenconds();
494 
498 D_CORE_API dFloat64 dRoundToFloat(dFloat64 val);
499 
500 #ifdef D_USE_THREAD_EMULATION
501  template<class T>
503  class dAtomic
504  {
505  public:
506  dAtomic<T>()
507  : m_val(T(val))
508  {
509  }
510 
511  dAtomic<T>(T val)
512  : m_val(val)
513  {
514  }
515 
516  T load() const
517  {
518  return m_val;
519  }
520 
521  void store(T val)
522  {
523  m_val = val;
524  }
525 
526  T exchange(T val)
527  {
528  dSwap(val, m_val);
529  return val;
530  }
531 
532  T fetch_add(T val)
533  {
534  m_val += val;
535  return m_val - val;
536  }
537 
538  T fetch_sub(T val)
539  {
540  m_val -= val;
541  return m_val + val;
542  }
543 
544  private:
545  T m_val;
546  };
547 #else
548  template<class T>
550  class dAtomic: public std::atomic<T>
551  {
552  public:
553  dAtomic<T>()
554  : std::atomic<T>(T(0))
555  {
556  }
557 
558  dAtomic<T>(T val)
559  :std::atomic<T>(val)
560  {
561  }
562  };
563 #endif
564 
567 {
568  public:
569  dSpinLock()
570 #ifndef D_USE_THREAD_EMULATION
571  :m_lock(0)
572 #endif
573  {
574  }
575 
576  void Lock()
577  {
578  #ifndef D_USE_THREAD_EMULATION
579  while (m_lock.exchange(1))
580  {
581  std::this_thread::yield();
582  }
583  #endif
584  }
585 
586  void Unlock()
587  {
588  #ifndef D_USE_THREAD_EMULATION
589  m_lock.exchange(0);
590  #endif
591  }
592 
593  #ifndef D_USE_THREAD_EMULATION
594  private:
595  dAtomic<dUnsigned32> m_lock;
596  #endif
597 };
598 
601 {
602  public:
603  dScopeSpinLock(dSpinLock& spinLock)
604  :m_spinLock(spinLock)
605  {
606  m_spinLock.Lock();
607  }
608 
609  ~dScopeSpinLock()
610  {
611  m_spinLock.Unlock();
612  }
613 
614  dSpinLock& m_spinLock;
615 };
616 
617 D_CORE_API dInt32 dVertexListToIndexList (dFloat64* const vertexList, dInt32 strideInBytes, dInt32 compareCount, dInt32 vertexCount, dInt32* const indexListOut, dFloat64 tolerance = dEpsilon);
618 D_CORE_API dInt32 dVertexListToIndexList (dFloat32* const vertexList, dInt32 strideInBytes, dInt32 floatSizeInBytes, dInt32 unsignedSizeInBytes, dInt32 vertexCount, dInt32* const indexListOut, dFloat32 tolerance = dEpsilon);
619 
622 {
623  public:
624  #ifdef _MSC_VER
625  #define D_FLOAT_EXECTIONS_MASK (EM_INVALID | EM_DENORMAL | EM_ZERODIVIDE)
626  #else
627  #define D_FLOAT_EXECTIONS_MASK 0
628  #endif
629 
630  dFloatExceptions(dUnsigned32 mask = D_FLOAT_EXECTIONS_MASK);
631  ~dFloatExceptions();
632 
633  private:
634  //#if (defined (_MSC_VER) && defined (_WIN_32_VER))
635  #if defined (_MSC_VER)
636  dUnsigned32 m_mask;
637  #endif
638 };
639 
642 {
643  public:
646  #if (defined (_MSC_VER) && defined (_WIN_32_VER))
647  dInt32 m_mask;
648  #endif
649 };
650 
651 #endif
652 
dSpinLock
Simple spin lock for synchronizing threads for very short period of time.
Definition: dTypes.h:567
dTriplex
Definition: dTypes.h:272
dFloatSign
Definition: dTypes.h:461
dSetPrecisionDouble
Set cpu floating point precision mode, the original mode is restored when the destructor is called.
Definition: dTypes.h:642
dAtomic
wrapper over standard atomic operations
Definition: dTypes.h:551
dBigVector
Definition: dVectorArmNeon.h:1521
dVector
Definition: dVectorArmNeon.h:1104
dMatrix
Definition: dMatrix.h:39
dDoubleInt
Definition: dTypes.h:471
dFloatExceptions
Set cpu floating point exceptions, the original exception state is restored when the destructor is ca...
Definition: dTypes.h:622
dScopeSpinLock
Simple scope based spin lock.
Definition: dTypes.h:601