Cry_Geo.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. // Description : Common structures for geometry computations
  9. #pragma once
  10. #include "Cry_Math.h"
  11. ///////////////////////////////////////////////////////////////////////////////
  12. // Forward declarations //
  13. ///////////////////////////////////////////////////////////////////////////////
  14. struct Ray;
  15. template <typename F>
  16. struct Lineseg_tpl;
  17. template <typename F>
  18. struct Triangle_tpl;
  19. struct AABB;
  20. template <typename F>
  21. struct OBB_tpl;
  22. //-----------------------------------------------------
  23. ///////////////////////////////////////////////////////////////////////////////
  24. // Definitions //
  25. ///////////////////////////////////////////////////////////////////////////////
  26. struct PosNorm
  27. {
  28. Vec3 vPos;
  29. Vec3 vNorm;
  30. };
  31. ///////////////////////////////////////////////////////////////////////////////
  32. ///////////////////////////////////////////////////////////////////////////////
  33. ///////////////////////////////////////////////////////////////////////////////
  34. // struct Ray
  35. ///////////////////////////////////////////////////////////////////////////////
  36. ///////////////////////////////////////////////////////////////////////////////
  37. ///////////////////////////////////////////////////////////////////////////////
  38. struct Ray
  39. {
  40. Vec3 origin;
  41. Vec3 direction;
  42. //default Ray constructor (without initialisation)
  43. inline Ray(void) {}
  44. inline Ray(const Vec3& o, const Vec3& d) { origin = o; direction = d; }
  45. inline void operator () (const Vec3& o, const Vec3& d) { origin = o; direction = d; }
  46. ~Ray(void) {};
  47. };
  48. ///////////////////////////////////////////////////////////////////////////////
  49. ///////////////////////////////////////////////////////////////////////////////
  50. ///////////////////////////////////////////////////////////////////////////////
  51. // struct Lineseg
  52. ///////////////////////////////////////////////////////////////////////////////
  53. ///////////////////////////////////////////////////////////////////////////////
  54. ///////////////////////////////////////////////////////////////////////////////
  55. struct Lineseg
  56. {
  57. Vec3_tpl<float> start;
  58. Vec3_tpl<float> end;
  59. //default Lineseg constructor (without initialisation)
  60. inline Lineseg(void) {}
  61. inline Lineseg(const Vec3_tpl<float>& s, const Vec3_tpl<float>& e) { start = s; end = e; }
  62. ~Lineseg(void) {};
  63. };
  64. ///////////////////////////////////////////////////////////////////////////////
  65. ///////////////////////////////////////////////////////////////////////////////
  66. ///////////////////////////////////////////////////////////////////////////////
  67. // struct Triangle
  68. ///////////////////////////////////////////////////////////////////////////////
  69. ///////////////////////////////////////////////////////////////////////////////
  70. ///////////////////////////////////////////////////////////////////////////////
  71. template <typename F>
  72. struct Triangle_tpl
  73. {
  74. Vec3_tpl<F> v0, v1, v2;
  75. //default Lineseg constructor (without initialisation)
  76. ILINE Triangle_tpl(void) {}
  77. ILINE Triangle_tpl(const Vec3_tpl<F>& a, const Vec3_tpl<F>& b, const Vec3_tpl<F>& c) { v0 = a; v1 = b; v2 = c; }
  78. ILINE void operator () (const Vec3_tpl<F>& a, const Vec3_tpl<F>& b, const Vec3_tpl<F>& c) { v0 = a; v1 = b; v2 = c; }
  79. ~Triangle_tpl(void) {};
  80. Vec3_tpl<F> GetNormal() const
  81. {
  82. return ((v1 - v0) ^ (v2 - v0)).GetNormalized();
  83. }
  84. F GetArea() const
  85. {
  86. return 0.5f * (v1 - v0).Cross(v2 - v0).GetLength();
  87. }
  88. };
  89. ///////////////////////////////////////////////////////////////////////////////
  90. ///////////////////////////////////////////////////////////////////////////////
  91. ///////////////////////////////////////////////////////////////////////////////
  92. // struct AABB
  93. ///////////////////////////////////////////////////////////////////////////////
  94. ///////////////////////////////////////////////////////////////////////////////
  95. ///////////////////////////////////////////////////////////////////////////////
  96. struct AABB
  97. {
  98. Vec3 min;
  99. Vec3 max;
  100. /// default AABB constructor (without initialisation)
  101. ILINE AABB()
  102. {}
  103. enum type_reset
  104. {
  105. RESET
  106. };
  107. // AABB aabb(RESET) generates a reset aabb
  108. ILINE AABB(type_reset)
  109. { Reset(); }
  110. ILINE explicit AABB(float radius)
  111. { max = Vec3(radius); min = -max; }
  112. ILINE explicit AABB(const Vec3& v)
  113. { min = max = v; }
  114. ILINE AABB(const Vec3& v, float radius)
  115. { Vec3 ext(radius); min = v - ext; max = v + ext; }
  116. ILINE AABB(const Vec3& vmin, const Vec3& vmax)
  117. { min = vmin; max = vmax; }
  118. ILINE AABB(const AABB& aabb)
  119. {
  120. min.x = aabb.min.x;
  121. min.y = aabb.min.y;
  122. min.z = aabb.min.z;
  123. max.x = aabb.max.x;
  124. max.y = aabb.max.y;
  125. max.z = aabb.max.z;
  126. }
  127. inline AABB(const Vec3* points, int num)
  128. {
  129. Reset();
  130. for (int i = 0; i < num; i++)
  131. {
  132. Add(points[i]);
  133. }
  134. }
  135. //! Reset Bounding box before calculating bounds.
  136. //! These values ensure that Add() functions work correctly for Reset bbs, without additional comparisons.
  137. ILINE void Reset()
  138. { min = Vec3(1e15f); max = Vec3(-1e15f); }
  139. ILINE bool IsReset() const
  140. { return min.x > max.x; }
  141. ILINE float IsResetSel(float ifReset, float ifNotReset) const
  142. { return (float)fsel(max.x - min.x, ifNotReset, ifReset); }
  143. //! Check if bounding box is empty (Zero volume).
  144. ILINE bool IsEmpty() const
  145. { return min == max; }
  146. //! Check if bounding box has valid, non zero volume
  147. ILINE bool IsNonZero() const
  148. { return min.x < max.x && min.y < max.y && min.z < max.z; }
  149. ILINE Vec3 GetCenter() const
  150. { return (min + max) * 0.5f; }
  151. ILINE Vec3 GetSize() const
  152. { return (max - min) * IsResetSel(0.0f, 1.0f); }
  153. ILINE float GetRadius() const
  154. { return IsResetSel(0.0f, (max - min).GetLengthFloat() * 0.5f); }
  155. ILINE void Add(const Vec3& v)
  156. {
  157. min.CheckMin(v);
  158. max.CheckMax(v);
  159. }
  160. inline void Add(const Vec3& v, float radius)
  161. {
  162. Vec3 ext(radius);
  163. min.CheckMin(v - ext);
  164. max.CheckMax(v + ext);
  165. }
  166. ILINE void Add(const AABB& bb)
  167. {
  168. min.CheckMin(bb.min);
  169. max.CheckMax(bb.max);
  170. }
  171. //! Check if this bounding box contains a point within itself.
  172. bool IsContainPoint(const Vec3& pos) const
  173. {
  174. assert(min.IsValid());
  175. assert(max.IsValid());
  176. assert(pos.IsValid());
  177. if (pos.x < min.x)
  178. {
  179. return false;
  180. }
  181. if (pos.y < min.y)
  182. {
  183. return false;
  184. }
  185. if (pos.z < min.z)
  186. {
  187. return false;
  188. }
  189. if (pos.x > max.x)
  190. {
  191. return false;
  192. }
  193. if (pos.y > max.y)
  194. {
  195. return false;
  196. }
  197. if (pos.z > max.z)
  198. {
  199. return false;
  200. }
  201. return true;
  202. }
  203. float GetDistanceSqr(Vec3 const& v) const
  204. {
  205. Vec3 vNear = v;
  206. vNear.CheckMax(min);
  207. vNear.CheckMin(max);
  208. return vNear.GetSquaredDistance(v);
  209. }
  210. float GetDistance(Vec3 const& v) const
  211. {
  212. return sqrt(GetDistanceSqr(v));
  213. }
  214. // Check two bounding boxes for intersection.
  215. inline bool IsIntersectBox(const AABB& b) const
  216. {
  217. assert(min.IsValid());
  218. assert(max.IsValid());
  219. assert(b.min.IsValid());
  220. assert(b.max.IsValid());
  221. // Check for intersection on X axis.
  222. if ((min.x > b.max.x) || (b.min.x > max.x))
  223. {
  224. return false;
  225. }
  226. // Check for intersection on Y axis.
  227. if ((min.y > b.max.y) || (b.min.y > max.y))
  228. {
  229. return false;
  230. }
  231. // Check for intersection on Z axis.
  232. if ((min.z > b.max.z) || (b.min.z > max.z))
  233. {
  234. return false;
  235. }
  236. // Boxes overlap in all 3 axises.
  237. return true;
  238. }
  239. /*!
  240. * calculate the new bounds of a transformed AABB
  241. *
  242. * Example:
  243. * AABB aabb = AABB::CreateAABBfromOBB(m34,aabb);
  244. *
  245. * return values:
  246. * expanded AABB in world-space
  247. */
  248. ILINE void SetTransformedAABB(const Matrix34& m34, const AABB& aabb)
  249. {
  250. if (aabb.IsReset())
  251. {
  252. Reset();
  253. }
  254. else
  255. {
  256. Matrix33 m33;
  257. m33.m00 = fabs_tpl(m34.m00);
  258. m33.m01 = fabs_tpl(m34.m01);
  259. m33.m02 = fabs_tpl(m34.m02);
  260. m33.m10 = fabs_tpl(m34.m10);
  261. m33.m11 = fabs_tpl(m34.m11);
  262. m33.m12 = fabs_tpl(m34.m12);
  263. m33.m20 = fabs_tpl(m34.m20);
  264. m33.m21 = fabs_tpl(m34.m21);
  265. m33.m22 = fabs_tpl(m34.m22);
  266. Vec3 sz = m33 * ((aabb.max - aabb.min) * 0.5f);
  267. Vec3 pos = m34 * ((aabb.max + aabb.min) * 0.5f);
  268. min = pos - sz;
  269. max = pos + sz;
  270. }
  271. }
  272. };
  273. ILINE bool IsEquivalent(const AABB& a, const AABB& b, float epsilon = VEC_EPSILON)
  274. {
  275. return IsEquivalent(a.min, b.min, epsilon) && IsEquivalent(a.max, b.max, epsilon);
  276. }
  277. ///////////////////////////////////////////////////////////////////////////////
  278. ///////////////////////////////////////////////////////////////////////////////
  279. ///////////////////////////////////////////////////////////////////////////////
  280. // struct OBB
  281. ///////////////////////////////////////////////////////////////////////////////
  282. ///////////////////////////////////////////////////////////////////////////////
  283. ///////////////////////////////////////////////////////////////////////////////
  284. template <typename F>
  285. struct OBB_tpl
  286. {
  287. Matrix33 m33; //orientation vectors
  288. Vec3 h; //half-length-vector
  289. Vec3 c; //center of obb
  290. //default OBB constructor (without initialisation)
  291. inline OBB_tpl() {}
  292. ILINE void SetOBB(const Matrix33& matrix, const Vec3& hlv, const Vec3& center) { m33 = matrix; h = hlv; c = center; }
  293. ILINE static OBB_tpl<F> CreateOBB(const Matrix33& m33, const Vec3& hlv, const Vec3& center) { OBB_tpl<f32> obb; obb.m33 = m33; obb.h = hlv; obb.c = center; return obb; }
  294. ILINE void SetOBBfromAABB(const Matrix33& mat33, const AABB& aabb)
  295. {
  296. m33 = mat33;
  297. h = (aabb.max - aabb.min) * 0.5f; //calculate the half-length-vectors
  298. c = (aabb.max + aabb.min) * 0.5f; //the center is relative to the PIVOT
  299. }
  300. ILINE void SetOBBfromAABB(const Quat& q, const AABB& aabb)
  301. {
  302. m33 = Matrix33(q);
  303. h = (aabb.max - aabb.min) * 0.5f; //calculate the half-length-vectors
  304. c = (aabb.max + aabb.min) * 0.5f; //the center is relative to the PIVOT
  305. }
  306. ILINE static OBB_tpl<F> CreateOBBfromAABB(const Matrix33& m33, const AABB& aabb) { OBB_tpl<f32> obb; obb.SetOBBfromAABB(m33, aabb); return obb; }
  307. ILINE static OBB_tpl<F> CreateOBBfromAABB(const Quat& q, const AABB& aabb) { OBB_tpl<f32> obb; obb.SetOBBfromAABB(q, aabb); return obb; }
  308. ~OBB_tpl(void) {};
  309. };
  310. typedef OBB_tpl<f32> OBB;
  311. ///////////////////////////////////////////////////////////////////////////////
  312. ///////////////////////////////////////////////////////////////////////////////
  313. ///////////////////////////////////////////////////////////////////////////////
  314. // struct Sphere
  315. ///////////////////////////////////////////////////////////////////////////////
  316. ///////////////////////////////////////////////////////////////////////////////
  317. ///////////////////////////////////////////////////////////////////////////////
  318. struct Sphere
  319. {
  320. Vec3 center;
  321. float radius;
  322. Sphere() {}
  323. Sphere(const Vec3& c, float r)
  324. : center(c)
  325. , radius(r) {}
  326. void operator()(const Vec3& c, float r) { center = c; radius = r; }
  327. };
  328. typedef Triangle_tpl<f32> Triangle;