ConvexSupport.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #pragma once
  4. #include <Jolt/Math/Mat44.h>
  5. JPH_NAMESPACE_BEGIN
  6. /// Helper functions to get the support point for a convex object
  7. /// Structure that transforms a convex object (supports only uniform scaling)
  8. template <typename ConvexObject>
  9. struct TransformedConvexObject
  10. {
  11. /// Create transformed convex object.
  12. TransformedConvexObject(Mat44Arg inTransform, const ConvexObject &inObject) :
  13. mTransform(inTransform),
  14. mObject(inObject)
  15. {
  16. }
  17. /// Calculate the support vector for this convex shape.
  18. Vec3 GetSupport(Vec3Arg inDirection) const
  19. {
  20. return mTransform * mObject.GetSupport(mTransform.Multiply3x3Transposed(inDirection));
  21. }
  22. /// Get the vertices of the face that faces inDirection the most
  23. template <class VERTEX_ARRAY>
  24. void GetSupportingFace(Vec3Arg inDirection, VERTEX_ARRAY &outVertices) const
  25. {
  26. mObject.GetSupportingFace(mTransform.Multiply3x3Transposed(inDirection), outVertices);
  27. for (Vec3 &v : outVertices)
  28. v = mTransform * v;
  29. }
  30. Mat44 mTransform;
  31. const ConvexObject & mObject;
  32. };
  33. /// Structure that adds a convex radius
  34. template <typename ConvexObject>
  35. struct AddConvexRadius
  36. {
  37. AddConvexRadius(const ConvexObject &inObject, float inRadius) :
  38. mObject(inObject),
  39. mRadius(inRadius)
  40. {
  41. }
  42. /// Calculate the support vector for this convex shape.
  43. Vec3 GetSupport(Vec3Arg inDirection) const
  44. {
  45. float length = inDirection.Length();
  46. return length > 0.0f ? mObject.GetSupport(inDirection) + (mRadius / length) * inDirection : mObject.GetSupport(inDirection);
  47. }
  48. const ConvexObject & mObject;
  49. float mRadius;
  50. };
  51. /// Structure that performs a Minkowski difference A - B
  52. template <typename ConvexObjectA, typename ConvexObjectB>
  53. struct MinkowskiDifference
  54. {
  55. MinkowskiDifference(const ConvexObjectA &inObjectA, const ConvexObjectB &inObjectB) :
  56. mObjectA(inObjectA),
  57. mObjectB(inObjectB)
  58. {
  59. }
  60. /// Calculate the support vector for this convex shape.
  61. Vec3 GetSupport(Vec3Arg inDirection) const
  62. {
  63. return mObjectA.GetSupport(inDirection) - mObjectB.GetSupport(-inDirection);
  64. }
  65. const ConvexObjectA & mObjectA;
  66. const ConvexObjectB & mObjectB;
  67. };
  68. /// Class that wraps a point so that it can be used with convex collision detection
  69. struct PointConvexSupport
  70. {
  71. /// Calculate the support vector for this convex shape.
  72. Vec3 GetSupport([[maybe_unused]] Vec3Arg inDirection) const
  73. {
  74. return mPoint;
  75. }
  76. Vec3 mPoint;
  77. };
  78. /// Class that wraps a triangle so that it can used with convex collision detection
  79. struct TriangleConvexSupport
  80. {
  81. /// Constructor
  82. TriangleConvexSupport(Vec3Arg inV1, Vec3Arg inV2, Vec3Arg inV3) :
  83. mV1(inV1),
  84. mV2(inV2),
  85. mV3(inV3)
  86. {
  87. }
  88. /// Calculate the support vector for this convex shape.
  89. Vec3 GetSupport(Vec3Arg inDirection) const
  90. {
  91. // Project vertices on inDirection
  92. float d1 = mV1.Dot(inDirection);
  93. float d2 = mV2.Dot(inDirection);
  94. float d3 = mV3.Dot(inDirection);
  95. // Return vertex with biggest projection
  96. if (d1 > d2)
  97. {
  98. if (d1 > d3)
  99. return mV1;
  100. else
  101. return mV3;
  102. }
  103. else
  104. {
  105. if (d2 > d3)
  106. return mV2;
  107. else
  108. return mV3;
  109. }
  110. }
  111. /// Get the vertices of the face that faces inDirection the most
  112. template <class VERTEX_ARRAY>
  113. void GetSupportingFace([[maybe_unused]] Vec3Arg inDirection, VERTEX_ARRAY &outVertices) const
  114. {
  115. outVertices.push_back(mV1);
  116. outVertices.push_back(mV2);
  117. outVertices.push_back(mV3);
  118. }
  119. /// The three vertices of the triangle
  120. Vec3 mV1;
  121. Vec3 mV2;
  122. Vec3 mV3;
  123. };
  124. /// Class that wraps a polygon so that it can used with convex collision detection
  125. template <class VERTEX_ARRAY>
  126. struct PolygonConvexSupport
  127. {
  128. /// Constructor
  129. explicit PolygonConvexSupport(const VERTEX_ARRAY &inVertices) :
  130. mVertices(inVertices)
  131. {
  132. }
  133. /// Calculate the support vector for this convex shape.
  134. Vec3 GetSupport(Vec3Arg inDirection) const
  135. {
  136. Vec3 support_point = mVertices[0];
  137. float best_dot = mVertices[0].Dot(inDirection);
  138. for (typename VERTEX_ARRAY::const_iterator v = mVertices.begin() + 1; v < mVertices.end(); ++v)
  139. {
  140. float dot = v->Dot(inDirection);
  141. if (dot > best_dot)
  142. {
  143. best_dot = dot;
  144. support_point = *v;
  145. }
  146. }
  147. return support_point;
  148. }
  149. /// Get the vertices of the face that faces inDirection the most
  150. template <class VERTEX_ARRAY_ARG>
  151. void GetSupportingFace([[maybe_unused]] Vec3Arg inDirection, VERTEX_ARRAY_ARG &outVertices) const
  152. {
  153. for (Vec3 v : mVertices)
  154. outVertices.push_back(v);
  155. }
  156. /// The vertices of the polygon
  157. const VERTEX_ARRAY & mVertices;
  158. };
  159. JPH_NAMESPACE_END