Functions.h 7.2 KB

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