ConvexSupport.h 4.6 KB

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