Functions.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. // Copyright (C) 2009-2021, 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. namespace anki
  11. {
  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. Bool testCollision(const Cone& a, const Ray& b);
  164. // Extra testCollision functions
  165. Bool testCollision(const Plane& plane, const Ray& ray, Vec4& intersection);
  166. Bool testCollision(const Plane& plane, const Vec4& vector, Vec4& intersection);
  167. Bool testCollision(const Sphere& sphere, const Ray& ray, Array<Vec4, 2>& intersectionPoints, U& intersectionPointCount);
  168. // Intersect a ray against an AABB. The ray is inside the AABB. The function returns the distance 'a' where the
  169. // intersection point is rayOrigin + rayDir * a
  170. // https://community.arm.com/graphics/b/blog/posts/reflections-based-on-local-cubemaps-in-unity
  171. inline F32 testCollisionInside(const Aabb& aabb, const Ray& ray)
  172. {
  173. const Vec4 reciprocal = ray.getDirection().reciprocal();
  174. const Vec4 intersectMaxPointPlanes = ((aabb.getMax() - ray.getOrigin()) * reciprocal).xyz0();
  175. const Vec4 intersectMinPointPlanes = ((aabb.getMin() - ray.getOrigin()) * reciprocal).xyz0();
  176. const Vec4 largestParams = intersectMaxPointPlanes.max(intersectMinPointPlanes);
  177. const F32 distToIntersect = min(min(largestParams.x(), largestParams.y()), largestParams.z());
  178. return distToIntersect;
  179. }
  180. #undef ANKI_DEF_TEST_COLLISION_FUNC
  181. #undef ANKI_DEF_TEST_COLLISION_FUNC_PLANE
  182. /// Get the min distance of a point to a plane.
  183. inline F32 getPlanePointDistance(const Plane& plane, const Vec4& point)
  184. {
  185. return absolute(testPlane(plane, point));
  186. }
  187. /// Returns the perpedicular point of a given point in a plane. Plane's normal and returned-point are perpedicular.
  188. inline Vec4 projectPointToPlane(const Plane& plane, const Vec4& point)
  189. {
  190. return point - plane.getNormal() * testPlane(plane, point);
  191. }
  192. /// Extract the clip planes using an MVP matrix.
  193. void extractClipPlanes(const Mat4& mvp, Array<Plane, 6>& planes);
  194. /// See extractClipPlanes.
  195. void extractClipPlane(const Mat4& mvp, FrustumPlaneType id, Plane& plane);
  196. /// Compute the edges of the far plane of a frustum
  197. void computeEdgesOfFrustum(F32 far, F32 fovX, F32 fovY, Vec4 points[4]);
  198. /// @}
  199. } // end namespace anki