Atoms Crowd  7.0.0
AtomsMath.h
1 #pragma once
2 // ===========================================================================
3 // Copyright (c) 2015 Toolchefs Ltd. All rights reserved.
4 //
5 // Use of this software is subject to the terms of the Toolchefs license
6 // agreement provided at the time of installation or download, or which
7 // otherwise accompanies this software in either electronic or hard copy form.
8 // ===========================================================================
9 #ifndef ATOMS_UNREAL
10 #ifndef CA_SUPPRESS
11 #define CA_SUPPRESS(x)
12 #endif
13 #endif
14 
15 #include <AtomsUtils/Globals.h>
16 #include <AtomsMath/ImathExport.h>
17 #include <AtomsMath/ImathConfig.h>
18 #include <AtomsMath/ImathVec.h>
19 #include <AtomsMath/ImathVecAlgo.h>
20 #include <AtomsMath/ImathMatrix.h>
21 #include <AtomsMath/ImathMatrixAlgo.h>
22 #include <AtomsMath/ImathQuat.h>
23 #include <AtomsMath/ImathEuler.h>
24 #include <AtomsMath/ImathBox.h>
25 #include <AtomsMath/ImathColor.h>
26 #include <AtomsMath/ImathLine.h>
27 #include <AtomsMath/ImathSphere.h>
28 #include <AtomsMath/ImathRandom.h>
29 #include <AtomsMath/ImathBoxAlgo.h>
30 #include <vector>
31 #include <limits>
32 
33 #ifndef M_PI
34 #include <math.h>
35 #endif
36 
37 namespace AtomsMath
38 {
39 #ifdef C11
40  using Vector2 = ATOMSMATH_NAMESPACE::V2d;
41  using Vector2f = ATOMSMATH_NAMESPACE::V2f;
42  using Vector2i = ATOMSMATH_NAMESPACE::V2i;
43  using Vector3 = ATOMSMATH_NAMESPACE::V3d;
44  using Vector3f = ATOMSMATH_NAMESPACE::V3f;
45  using Vector3i = ATOMSMATH_NAMESPACE::V3i;
46  using Vector4 = ATOMSMATH_NAMESPACE::V4d;
47  using Vector4f = ATOMSMATH_NAMESPACE::V4f;
48  using Vector4i = ATOMSMATH_NAMESPACE::V4i;
49  using Matrix = ATOMSMATH_NAMESPACE::M44d;
50  using Matrixf = ATOMSMATH_NAMESPACE::M44f;
51  using Matrix33 = ATOMSMATH_NAMESPACE::M33d;
52  using Matrix33f = ATOMSMATH_NAMESPACE::M33f;
53  using Quaternion = ATOMSMATH_NAMESPACE::Quatd;
54  using Quaternionf = ATOMSMATH_NAMESPACE::Quatf;
55  using Euler = ATOMSMATH_NAMESPACE::Eulerd;
56  using Eulerf = ATOMSMATH_NAMESPACE::Eulerf;
57  using Box2 = ATOMSMATH_NAMESPACE::Box2d;
58  using Box2f = ATOMSMATH_NAMESPACE::Box2f;
59  using Box2i = ATOMSMATH_NAMESPACE::Box2i;
60  using Box3 = ATOMSMATH_NAMESPACE::Box3d;
61  using Box3f = ATOMSMATH_NAMESPACE::Box3f;
62  using Box3i = ATOMSMATH_NAMESPACE::Box3i;
63  using Color3c = ATOMSMATH_NAMESPACE::Color3c;
64  using Color3f = ATOMSMATH_NAMESPACE::Color3f;
65  using Color4c = ATOMSMATH_NAMESPACE::Color4c;
66  using Color4f = ATOMSMATH_NAMESPACE::Color4f;
67  using Line3 = ATOMSMATH_NAMESPACE::Line3d ;
68  using Line3f = ATOMSMATH_NAMESPACE::Line3f;
69  using Line2 = ATOMSMATH_NAMESPACE::Line2d;
70  using Line2f = ATOMSMATH_NAMESPACE::Line2f;
71  using Sphere3 = ATOMSMATH_NAMESPACE::Sphere3d;
72  using Sphere3f = ATOMSMATH_NAMESPACE::Sphere3f;
73 #else
74  typedef ATOMSMATH_NAMESPACE::V2d Vector2;
75  typedef ATOMSMATH_NAMESPACE::V2f Vector2f;
76  typedef ATOMSMATH_NAMESPACE::V2i Vector2i;
77  typedef ATOMSMATH_NAMESPACE::V3d Vector3;
78  typedef ATOMSMATH_NAMESPACE::V3f Vector3f;
79  typedef ATOMSMATH_NAMESPACE::V3i Vector3i;
80  typedef ATOMSMATH_NAMESPACE::V4d Vector4;
81  typedef ATOMSMATH_NAMESPACE::V4f Vector4f;
82  typedef ATOMSMATH_NAMESPACE::V4i Vector4i;
83  typedef ATOMSMATH_NAMESPACE::M44d Matrix;
84  typedef ATOMSMATH_NAMESPACE::M44f Matrixf;
85  typedef ATOMSMATH_NAMESPACE::M33d Matrix33;
86  typedef ATOMSMATH_NAMESPACE::M33f Matrix33f;
87  typedef ATOMSMATH_NAMESPACE::Quatd Quaternion;
88  typedef ATOMSMATH_NAMESPACE::Quatf Quaternionf;
89  typedef ATOMSMATH_NAMESPACE::Eulerd Euler;
90  //typedef ATOMSMATH_NAMESPACE::Eulerf Eulerf; //!< Euler class
91  typedef ATOMSMATH_NAMESPACE::Box2d Box2;
92  //typedef ATOMSMATH_NAMESPACE::Box2f Box2f; //!< Bounding box class
93  //typedef ATOMSMATH_NAMESPACE::Box2i Box2i; //!< Bounding box class
94  typedef ATOMSMATH_NAMESPACE::Box3d Box3;
95  //typedef ATOMSMATH_NAMESPACE::Box3f Box3f; //!< Bounding box class
96  //typedef ATOMSMATH_NAMESPACE::Box3i Box3i; //!< Bounding box class
97  typedef ATOMSMATH_NAMESPACE::Color3c Color3c;
98  //typedef ATOMSMATH_NAMESPACE::Color3f Color3f; //!< Color class
99  typedef ATOMSMATH_NAMESPACE::Color4c Color4c;
100  //typedef ATOMSMATH_NAMESPACE::Color4f Color4f; //!< Color class
101 
102  typedef ATOMSMATH_NAMESPACE::Line3d Line3;
103  //typedef ATOMSMATH_NAMESPACE::Line3f Line3f; //!< Line class
104 
105  typedef ATOMSMATH_NAMESPACE::Line2d Line2;
106  typedef ATOMSMATH_NAMESPACE::Line2f Line2f;
107 
108  typedef ATOMSMATH_NAMESPACE::Sphere3d Sphere3;
109  //typedef ATOMSMATH_NAMESPACE::Sphere3f Sphere3f; //!< Sphere class
110 
111  //typedef ATOMSMATH_NAMESPACE::Rand32 Rand32;
112  //typedef ATOMSMATH_NAMESPACE::Rand48 Rand48;
113 #endif
114 
115 #ifndef ATOMS_UNREAL
116  template <class T>
117  inline T
118  clamp(T a, T l, T h)
119  {
120  return (a < l) ? l : ((a > h) ? h : a);
121  }
122 
123 
124  template <class T, class W>
125  inline T
126  clip(const T& p, const W& box)
127  {
128  //
129  // Clip the coordinates of a point, p, against a box.
130  // The result, q, is the closest point to p that is inside the box.
131  //
132 
133  T q;
134 
135  for (int i = 0; i < int(box.min.dimensions()); i++)
136  {
137  if (p[i] < box.min[i])
138  q[i] = box.min[i];
139  else if (p[i] > box.max[i])
140  q[i] = box.max[i];
141  else
142  q[i] = p[i];
143  }
144 
145  return q;
146  }
147 
148 
149  template <class T, class W>
150  inline T
151  closestPointInBox(const T& p, const W& box)
152  {
153  return clip(p, box);
154  }
155 
156  template<typename T, typename W>
157  inline typename T::BaseType distanceSq(const T& point, const W& box)
158  {
159  auto p = closestPointInBox(point, box);
160  return (p - point).length2();
161  }
162 #else
163  template<typename T, typename W>
164  inline typename T::BaseType distanceSq(const T& point, const W& box)
165  {
166  auto p = closestPointInBox(point, box);
167  return (p - point).length2();
168  }
169 #endif
170 
171  ATOMSUTILS_EXPORT double getConvexPolyCross(const AtomsMath::Vector2f &O, const AtomsMath::Vector2f &A, const AtomsMath::Vector2f &B);
172 
173  ATOMSUTILS_EXPORT std::vector<AtomsMath::Vector2f> getConvexPoly(std::vector<AtomsMath::Vector2f> P);
174 
175  template<typename T>
176  T closestPointToSegment(const T& P0, const T& P1, const T& point)
177  {
178  auto lineDir = P1 - P0;
179  auto lineLength = lineDir.length();
180  lineDir.normalize();
181  auto dotValue = (point - P0).dot(lineDir);
182  dotValue = dotValue > lineLength ? lineLength : dotValue;
183  dotValue = dotValue < 0.0f ? 0.0f : dotValue;
184  return P0 + lineDir * dotValue;
185  }
186 
187  template<typename T>
188  inline typename T::BaseType distanceToSegment(const T& P0, const T& P1, const T& point)
189  {
190  return (closestPointToSegment(P0, P1, point) - point).length();
191  }
192 
193  inline AtomsMath::Vector2f flatVector3(const AtomsMath::Vector3& in) { return AtomsMath::Vector2f(static_cast<float>(in.x), static_cast<float>(in.z)); }
194 
195  template <class _Ty>
196  class numeric_limits { // numeric limits for arbitrary type _Ty (say little or nothing)
197  public:
198  static _Ty(min)() noexcept {
199  return std::numeric_limits<_Ty>::min();
200  }
201 
202  static _Ty(max)() noexcept {
203  return std::numeric_limits<_Ty>::max();
204  }
205  };
206 
207  template <>
208  class numeric_limits<std::string>
209  {
210  public:
211  static const char* (min)() noexcept {
212  return "";
213  }
214 
215  static const char* (max)() noexcept {
216  return "";
217  }
218  };
219 
220  template <>
221  class numeric_limits<Matrix>
222  {
223  public:
224  static Matrix(min)() noexcept {
225  return Matrix();
226  }
227 
228  static Matrix(max)() noexcept {
229  return Matrix();
230  }
231  };
232 
233  template <>
234  class numeric_limits<Vector2>
235  {
236  public:
237  static Vector2(min)() noexcept {
238  return Vector2(std::numeric_limits<float>::min());
239  }
240 
241  static Vector2(max)() noexcept {
242  return Vector2(std::numeric_limits<float>::max());
243  }
244  };
245 
246  template <>
247  class numeric_limits<Vector3>
248  {
249  public:
250  static Vector3(min)() noexcept {
251  return Vector3(std::numeric_limits<float>::min());
252  }
253 
254  static Vector3(max)() noexcept {
255  return Vector3(std::numeric_limits<float>::max());
256  }
257  };
258 
259  template <>
260  class numeric_limits<Vector4>
261  {
262  public:
263  static Vector4(min)() noexcept {
264  return Vector4(std::numeric_limits<float>::min());
265  }
266 
267  static Vector4(max)() noexcept {
268  return Vector4(std::numeric_limits<float>::max());
269  }
270  };
271 
272  template <>
273  class numeric_limits<Quaternion>
274  {
275  public:
276  static Quaternion(min)() noexcept {
277  return Quaternion();
278  }
279 
280  static Quaternion(max)() noexcept {
281  return Quaternion();
282  }
283  };
284 
285  template <>
287  {
288  public:
289  static Euler(min)() noexcept {
290  return Euler();
291  }
292 
293  static Euler(max)() noexcept {
294  return Euler();
295  }
296  };
297 
298  template <>
299  class numeric_limits<Vector2f>
300  {
301  public:
302  static Vector2f(min)() noexcept {
303  return Vector2f(std::numeric_limits<float>::min());
304  }
305 
306  static Vector2f(max)() noexcept {
307  return Vector2f(std::numeric_limits<float>::max());
308  }
309  };
310 
311  template <>
312  class numeric_limits<Vector3f>
313  {
314  public:
315  static Vector3f(min)() noexcept {
316  return Vector3f(std::numeric_limits<float>::min());
317  }
318 
319  static Vector3f(max)() noexcept {
320  return Vector3f(std::numeric_limits<float>::max());
321  }
322  };
323 
324  template <>
325  class numeric_limits<Vector4f>
326  {
327  public:
328  static Vector4f(min)() noexcept {
329  return Vector4f(std::numeric_limits<float>::min());
330  }
331 
332  static Vector4f(max)() noexcept {
333  return Vector4f(std::numeric_limits<float>::max());
334  }
335  };
336 
337 
338  // random gen
339  template <class _Ty>
340  class RandomValue {
341  public:
342  static _Ty value(ATOMSMATH_NAMESPACE::Rand48& random, const _Ty& minVal, const _Ty& maxVal) noexcept {
343  return minVal;
344  }
345  };
346 
347  template <>
348  class RandomValue<int>
349  {
350  public:
351  static int(value)(ATOMSMATH_NAMESPACE::Rand48& random, const int& minValue, const int& maxValue) noexcept {
352  if (maxValue > minValue)
353  return random.nexti() % (maxValue - minValue) + minValue;
354  else if (maxValue < minValue)
355  return random.nexti() % (minValue - maxValue) + maxValue;
356  else
357  return minValue;
358  }
359  };
360 
361  template <>
362  class RandomValue<float>
363  {
364  public:
365  static float(value)(ATOMSMATH_NAMESPACE::Rand48& random, const float& minValue, const float& maxValue) noexcept {
366  return static_cast<float>(random.nextf(minValue, maxValue));
367  }
368  };
369 
370  template <>
371  class RandomValue<double>
372  {
373  public:
374  static double(value)(ATOMSMATH_NAMESPACE::Rand48& random, const double& minValue, const double& maxValue) noexcept {
375  return random.nextf(minValue, maxValue);
376  }
377  };
378 
379  template <>
380  class RandomValue<bool>
381  {
382  public:
383  static bool(value)(ATOMSMATH_NAMESPACE::Rand48& random, const bool& minValue, const bool& maxValue) noexcept {
384  return minValue != maxValue ? random.nextb() : minValue;
385  }
386  };
387 
388  template <>
389  class RandomValue<Vector2>
390  {
391  public:
392  static Vector2(value)(ATOMSMATH_NAMESPACE::Rand48& random, const Vector2& minValue, const Vector2& maxValue) noexcept {
393  return Vector2(
394  random.nextf(minValue.x, maxValue.x),
395  random.nextf(minValue.y, maxValue.y));
396  }
397  };
398 
399  template <>
400  class RandomValue<Vector3>
401  {
402  public:
403  static Vector3(value)(ATOMSMATH_NAMESPACE::Rand48& random, const Vector3& minValue, const Vector3& maxValue) noexcept {
404  return Vector3(
405  random.nextf(minValue.x, maxValue.x),
406  random.nextf(minValue.y, maxValue.y),
407  random.nextf(minValue.z, maxValue.z));
408  }
409  };
410 
411  template <>
412  class RandomValue<Vector4>
413  {
414  public:
415  static Vector4(value)(ATOMSMATH_NAMESPACE::Rand48& random, const Vector4& minValue, const Vector4& maxValue) noexcept {
416  return Vector4(
417  random.nextf(minValue.x, maxValue.x),
418  random.nextf(minValue.y, maxValue.y),
419  random.nextf(minValue.z, maxValue.z),
420  random.nextf(minValue.w, maxValue.w));
421  }
422  };
423 
424  template <>
425  class RandomValue<Vector2f>
426  {
427  public:
428  static Vector2f(value)(ATOMSMATH_NAMESPACE::Rand48& random, const Vector2f& minValue, const Vector2f& maxValue) noexcept {
429  return Vector2f(
430  static_cast<float>(random.nextf(minValue.x, maxValue.x)),
431  static_cast<float>(random.nextf(minValue.y, maxValue.y)));
432  }
433  };
434 
435  template <>
436  class RandomValue<Vector3f>
437  {
438  public:
439  static Vector3f(value)(ATOMSMATH_NAMESPACE::Rand48& random, const Vector3f& minValue, const Vector3f& maxValue) noexcept {
440  return Vector3f(
441  static_cast<float>(random.nextf(minValue.x, maxValue.x)),
442  static_cast<float>(random.nextf(minValue.y, maxValue.y)),
443  static_cast<float>(random.nextf(minValue.z, maxValue.z)));
444  }
445  };
446 
447  template <>
448  class RandomValue<Vector4f>
449  {
450  public:
451  static Vector4f(value)(ATOMSMATH_NAMESPACE::Rand48& random, const Vector4f& minValue, const Vector4f& maxValue) noexcept {
452  return Vector4f(
453  static_cast<float>(random.nextf(minValue.x, maxValue.x)),
454  static_cast<float>(random.nextf(minValue.y, maxValue.y)),
455  static_cast<float>(random.nextf(minValue.z, maxValue.z)),
456  static_cast<float>(random.nextf(minValue.w, maxValue.w)));
457  }
458  };
459 
460  template <>
461  class RandomValue<Matrix>
462  {
463  public:
464  static Matrix(value)(ATOMSMATH_NAMESPACE::Rand48& random, const Matrix& m_minValue, const Matrix& m_maxValue) noexcept {
465  return Matrix(
466  random.nextf(m_minValue[0][0], m_maxValue[0][0]), random.nextf(m_minValue[0][1], m_maxValue[0][1]), random.nextf(m_minValue[0][2], m_maxValue[0][2]), random.nextf(m_minValue[0][3], m_maxValue[0][3]),
467  random.nextf(m_minValue[1][0], m_maxValue[1][0]), random.nextf(m_minValue[1][1], m_maxValue[1][1]), random.nextf(m_minValue[1][2], m_maxValue[1][2]), random.nextf(m_minValue[1][3], m_maxValue[1][3]),
468  random.nextf(m_minValue[2][0], m_maxValue[2][0]), random.nextf(m_minValue[2][1], m_maxValue[2][1]), random.nextf(m_minValue[2][2], m_maxValue[2][2]), random.nextf(m_minValue[2][3], m_maxValue[2][3]),
469  random.nextf(m_minValue[3][0], m_maxValue[3][0]), random.nextf(m_minValue[3][1], m_maxValue[3][1]), random.nextf(m_minValue[3][2], m_maxValue[3][2]), random.nextf(m_minValue[3][3], m_maxValue[3][3]));
470  }
471  };
472 
473  template <>
474  class RandomValue<Matrixf>
475  {
476  public:
477  static Matrixf(value)(ATOMSMATH_NAMESPACE::Rand48& random, const Matrixf& m_minValue, const Matrixf& m_maxValue) noexcept {
478  return Matrixf(
479  static_cast<float>(random.nextf(m_minValue[0][0], m_maxValue[0][0])), static_cast<float>(random.nextf(m_minValue[0][1], m_maxValue[0][1])), static_cast<float>(random.nextf(m_minValue[0][2], m_maxValue[0][2])), static_cast<float>(random.nextf(m_minValue[0][3], m_maxValue[0][3])),
480  static_cast<float>(random.nextf(m_minValue[1][0], m_maxValue[1][0])), static_cast<float>(random.nextf(m_minValue[1][1], m_maxValue[1][1])), static_cast<float>(random.nextf(m_minValue[1][2], m_maxValue[1][2])), static_cast<float>(random.nextf(m_minValue[1][3], m_maxValue[1][3])),
481  static_cast<float>(random.nextf(m_minValue[2][0], m_maxValue[2][0])), static_cast<float>(random.nextf(m_minValue[2][1], m_maxValue[2][1])), static_cast<float>(random.nextf(m_minValue[2][2], m_maxValue[2][2])), static_cast<float>(random.nextf(m_minValue[2][3], m_maxValue[2][3])),
482  static_cast<float>(random.nextf(m_minValue[3][0], m_maxValue[3][0])), static_cast<float>(random.nextf(m_minValue[3][1], m_maxValue[3][1])), static_cast<float>(random.nextf(m_minValue[3][2], m_maxValue[3][2])), static_cast<float>(random.nextf(m_minValue[3][3], m_maxValue[3][3])));
483  }
484  };
485 
486  template <>
487  class RandomValue<Quaternion>
488  {
489  public:
490  static Quaternion(value)(ATOMSMATH_NAMESPACE::Rand48& random, const Quaternion& minValue, const Quaternion& maxValue) noexcept {
491  return Quaternion(
492  random.nextf(minValue.r, maxValue.r),
493  random.nextf(minValue.v.x, maxValue.v.x),
494  random.nextf(minValue.v.y, maxValue.v.y),
495  random.nextf(minValue.v.z, maxValue.v.z)
496  );
497  }
498  };
499 
500  template <>
501  class RandomValue<Quaternionf>
502  {
503  public:
504  static Quaternionf(value)(ATOMSMATH_NAMESPACE::Rand48& random, const Quaternionf& minValue, const Quaternionf& maxValue) noexcept {
505  return Quaternionf(
506  static_cast<float>(random.nextf(minValue.r, maxValue.r)),
507  static_cast<float>(random.nextf(minValue.v.x, maxValue.v.x)),
508  static_cast<float>(random.nextf(minValue.v.y, maxValue.v.y)),
509  static_cast<float>(random.nextf(minValue.v.z, maxValue.v.z))
510  );
511  }
512  };
513 
514  template <>
516  {
517  public:
518  static Euler(value)(ATOMSMATH_NAMESPACE::Rand48& random, const Euler& minValue, const Euler& maxValue) noexcept {
519  return Euler(
520  static_cast<float>(random.nextf(minValue.x, maxValue.x)),
521  static_cast<float>(random.nextf(minValue.y, maxValue.y)),
522  static_cast<float>(random.nextf(minValue.z, maxValue.z)));
523  }
524  };
525 
526  ATOMSUTILS_EXPORT bool isBoundingBoxVisible(const AtomsMath::Box3& bbox, const AtomsMath::Matrix& cameraWorldMatrix, const AtomsMath::Matrix& cameraProjectionMatrix, bool isOrtho, double overscanX = 0.0, double overscanY = 0.0, double overscanZ=0.0);
527  ATOMSUTILS_EXPORT bool isPointVisible(const AtomsMath::Vector3& point, const AtomsMath::Matrix& cameraWorldMatrix, const AtomsMath::Matrix& cameraProjectionMatrix, bool isOrtho, double overscanX = 0.0, double overscanY = 0.0, double overscanZ = 0.0);
528 }
Definition: AtomsMath.h:340
Definition: AtomsMath.h:196
Definition: ImathBox.h:36
Definition: ImathColor.h:29
Definition: ImathColor.h:115
Definition: ImathEuler.h:118
Definition: ImathLine.h:180
Definition: ImathLine.h:25
Definition: ImathMatrix.h:305
Definition: ImathSphere.h:25