Functions.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <AnKi/Collision/Common.h>
  7. #include <AnKi/Collision/Plane.h>
  8. #include <AnKi/Collision/Ray.h>
  9. #include <AnKi/Collision/Aabb.h>
  10. #include <AnKi/Util/WeakArray.h>
  11. namespace anki {
  12. /// @addtogroup collision
  13. /// @{
  14. /// It gives the distance between a point and a plane. It returns >0 if the primitive lies in front of the plane, <0
  15. /// if it's behind and ==0 when it collides the plane.
  16. F32 testPlane(const Plane& plane, const Aabb& aabb);
  17. /// @copydoc testPlane(const Plane&, const Aabb&)
  18. F32 testPlane(const Plane& plane, const Sphere& sphere);
  19. /// @copydoc testPlane(const Plane&, const Aabb&)
  20. F32 testPlane(const Plane& plane, const Obb& obb);
  21. /// @copydoc testPlane(const Plane&, const Aabb&)
  22. F32 testPlane(const Plane& plane, const ConvexHullShape& hull);
  23. /// @copydoc testPlane(const Plane&, const Aabb&)
  24. F32 testPlane(const Plane& plane, const LineSegment& ls);
  25. /// @copydoc testPlane(const Plane&, const Aabb&)
  26. F32 testPlane(const Plane& plane, const Cone& cone);
  27. /// @copydoc testPlane(const Plane&, const Aabb&)
  28. F32 testPlane(const Plane& plane, const Ray& ray);
  29. /// @copydoc testPlane(const Plane&, const Aabb&)
  30. inline F32 testPlane(const Plane& plane, const Vec4& point)
  31. {
  32. ANKI_ASSERT(isZero(point.w));
  33. return plane.getNormal().dot(point) - plane.getOffset();
  34. }
  35. /// @copydoc computeAabb(const ConvexHullShape&)
  36. Aabb computeAabb(const Sphere& sphere);
  37. /// @copydoc computeAabb(const ConvexHullShape&)
  38. Aabb computeAabb(const Obb& obb);
  39. /// Compute a bounding box of a shape.
  40. Aabb computeAabb(const ConvexHullShape& hull);
  41. /// @copydoc computeAabb(const ConvexHullShape&)
  42. Aabb computeAabb(const LineSegment& ls);
  43. /// @copydoc computeAabb(const ConvexHullShape&)
  44. Aabb computeAabb(const Cone& cone);
  45. // Aabb
  46. Bool testCollision(const Aabb& a, const Aabb& b);
  47. Bool testCollision(const Aabb& a, const Sphere& b);
  48. Bool testCollision(const Aabb& a, const Obb& b);
  49. Bool testCollision(const Aabb& a, const ConvexHullShape& b);
  50. Bool testCollision(const Aabb& a, const LineSegment& b);
  51. Bool testCollision(const Aabb& a, const Cone& b);
  52. Bool testCollision(const Aabb& a, const Ray& b);
  53. // Sphere
  54. inline Bool testCollision(const Sphere& a, const Aabb& b)
  55. {
  56. return testCollision(b, a);
  57. }
  58. Bool testCollision(const Sphere& a, const Sphere& b);
  59. Bool testCollision(const Sphere& a, const Obb& b);
  60. Bool testCollision(const Sphere& a, const ConvexHullShape& b);
  61. Bool testCollision(const Sphere& a, const LineSegment& b);
  62. Bool testCollision(const Sphere& a, const Cone& b);
  63. Bool testCollision(const Sphere& a, const Ray& b);
  64. // Obb
  65. inline Bool testCollision(const Obb& a, const Aabb& b)
  66. {
  67. return testCollision(b, a);
  68. }
  69. inline Bool testCollision(const Obb& a, const Sphere& b)
  70. {
  71. return testCollision(b, a);
  72. }
  73. Bool testCollision(const Obb& a, const Obb& b);
  74. Bool testCollision(const Obb& a, const ConvexHullShape& b);
  75. Bool testCollision(const Obb& a, const LineSegment& b);
  76. Bool testCollision(const Obb& a, const Cone& b);
  77. Bool testCollision(const Obb& a, const Ray& b);
  78. // ConvexHullShape
  79. inline Bool testCollision(const ConvexHullShape& a, const Aabb& b)
  80. {
  81. return testCollision(b, a);
  82. }
  83. inline Bool testCollision(const ConvexHullShape& a, const Sphere& b)
  84. {
  85. return testCollision(b, a);
  86. }
  87. inline Bool testCollision(const ConvexHullShape& a, const Obb& b)
  88. {
  89. return testCollision(b, a);
  90. }
  91. Bool testCollision(const ConvexHullShape& a, const ConvexHullShape& b);
  92. Bool testCollision(const ConvexHullShape& a, const LineSegment& b);
  93. Bool testCollision(const ConvexHullShape& a, const Cone& b);
  94. Bool testCollision(const ConvexHullShape& a, const Ray& b);
  95. // LineSegment
  96. inline Bool testCollision(const LineSegment& a, const Aabb& b)
  97. {
  98. return testCollision(b, a);
  99. }
  100. inline Bool testCollision(const LineSegment& a, const Sphere& b)
  101. {
  102. return testCollision(b, a);
  103. }
  104. inline Bool testCollision(const LineSegment& a, const Obb& b)
  105. {
  106. return testCollision(b, a);
  107. }
  108. inline Bool testCollision(const LineSegment& a, const ConvexHullShape& b)
  109. {
  110. return testCollision(b, a);
  111. }
  112. Bool testCollision(const LineSegment& a, const LineSegment& b);
  113. Bool testCollision(const LineSegment& a, const Cone& b);
  114. Bool testCollision(const LineSegment& a, const Ray& b);
  115. // Cone
  116. inline Bool testCollision(const Cone& a, const Aabb& b)
  117. {
  118. return testCollision(b, a);
  119. }
  120. inline Bool testCollision(const Cone& a, const Sphere& b)
  121. {
  122. return testCollision(b, a);
  123. }
  124. inline Bool testCollision(const Cone& a, const Obb& b)
  125. {
  126. return testCollision(b, a);
  127. }
  128. inline Bool testCollision(const Cone& a, const ConvexHullShape& b)
  129. {
  130. return testCollision(b, a);
  131. }
  132. inline Bool testCollision(const Cone& a, const LineSegment& b)
  133. {
  134. return testCollision(b, a);
  135. }
  136. Bool testCollision(const Cone& a, const Cone& b);
  137. Bool testCollision(const Cone& a, const Ray& b);
  138. // Ray
  139. inline Bool testCollision(const Ray& a, const Aabb& b)
  140. {
  141. return testCollision(b, a);
  142. }
  143. inline Bool testCollision(const Ray& a, const Sphere& b)
  144. {
  145. return testCollision(b, a);
  146. }
  147. inline Bool testCollision(const Ray& a, const Obb& b)
  148. {
  149. return testCollision(b, a);
  150. }
  151. inline Bool testCollision(const Ray& a, const ConvexHullShape& b)
  152. {
  153. return testCollision(b, a);
  154. }
  155. inline Bool testCollision(const Ray& a, const LineSegment& b)
  156. {
  157. return testCollision(b, a);
  158. }
  159. inline Bool testCollision(const Ray& a, const Cone& b)
  160. {
  161. return testCollision(b, a);
  162. }
  163. // Extra testCollision functions
  164. Bool testCollision(const Plane& plane, const Ray& ray, Vec4& intersection);
  165. Bool testCollision(const Plane& plane, const Vec4& vector, Vec4& intersection);
  166. Bool testCollision(const Sphere& sphere, const Ray& ray, Array<Vec4, 2>& intersectionPoints, U& intersectionPointCount);
  167. // Intersect a ray against an AABB. The ray is inside the AABB. The function returns the distance 'a' where the
  168. // intersection point is rayOrigin + rayDir * a
  169. // https://community.arm.com/graphics/b/blog/posts/reflections-based-on-local-cubemaps-in-unity
  170. inline F32 testCollisionInside(const Aabb& aabb, const Ray& ray)
  171. {
  172. const Vec4 reciprocal = ray.getDirection().reciprocal();
  173. const Vec4 intersectMaxPointPlanes = ((aabb.getMax() - ray.getOrigin()) * reciprocal).xyz0;
  174. const Vec4 intersectMinPointPlanes = ((aabb.getMin() - ray.getOrigin()) * reciprocal).xyz0;
  175. const Vec4 largestParams = intersectMaxPointPlanes.max(intersectMinPointPlanes);
  176. const F32 distToIntersect = min(min(largestParams.x, largestParams.y), largestParams.z);
  177. return distToIntersect;
  178. }
  179. #undef ANKI_DEF_TEST_COLLISION_FUNC
  180. #undef ANKI_DEF_TEST_COLLISION_FUNC_PLANE
  181. /// Get the min distance of a point to a plane.
  182. inline F32 getPlanePointDistance(const Plane& plane, const Vec4& point)
  183. {
  184. return absolute(testPlane(plane, point));
  185. }
  186. /// Returns the perpedicular point of a given point in a plane. Plane's normal and returned-point are perpedicular.
  187. inline Vec4 projectPointToPlane(const Plane& plane, const Vec4& point)
  188. {
  189. return point - plane.getNormal() * testPlane(plane, point);
  190. }
  191. /// Extract the clip planes using an MVP matrix.
  192. void extractClipPlanes(const Mat4& mvp, Array<Plane, 6>& planes);
  193. /// See extractClipPlanes.
  194. void extractClipPlane(const Mat4& mvp, FrustumPlaneType id, Plane& plane);
  195. /// Compute the edges of the far plane of a frustum
  196. void computeEdgesOfFrustum(F32 far, F32 fovX, F32 fovY, Vec3 points[4]);
  197. /// Welzl's algorithm that computes a compact bounding sphere given a point cloud.
  198. ANKI_PURE Sphere computeBoundingSphere(const Vec3* firstPoint, U32 pointCount, PtrSize stride);
  199. /// Computes an AABB given a point cloud.
  200. ANKI_PURE Aabb computeBoundingAabb(const Vec3* firstPoint, U32 pointCount, PtrSize stride);
  201. /// @}
  202. } // end namespace anki