Jolt Physics
A multi core friendly Game Physics Engine
Loading...
Searching...
No Matches
EPAPenetrationDepth.h
Go to the documentation of this file.
1// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
11
12//#define JPH_EPA_PENETRATION_DEPTH_DEBUG
13
15
37{
38private:
39 // Typedefs
40 static constexpr int cMaxPoints = EPAConvexHullBuilder::cMaxPoints;
41 static constexpr int cMaxPointsToIncludeOriginInHull = 32;
42 static_assert(cMaxPointsToIncludeOriginInHull < cMaxPoints);
43
46
48 GJKClosestPoint mGJK;
49
51 class SupportPoints
52 {
53 public:
55 Points mY;
56 Vec3 mP[cMaxPoints];
57 Vec3 mQ[cMaxPoints];
58
60 template <typename A, typename B>
61 Vec3 Add(const A &inA, const B &inB, Vec3Arg inDirection, int &outIndex)
62 {
63 // Get support point of the minkowski sum A - B
64 Vec3 p = inA.GetSupport(inDirection);
65 Vec3 q = inB.GetSupport(-inDirection);
66 Vec3 w = p - q;
67
68 // Store new point
69 outIndex = mY.size();
70 mY.push_back(w);
71 mP[outIndex] = p;
72 mQ[outIndex] = q;
73
74 return w;
75 }
76 };
77
78public:
80 enum class EStatus
81 {
83 Colliding,
85 };
86
98 template <typename AE, typename BE>
99 EStatus GetPenetrationDepthStepGJK(const AE &inAExcludingConvexRadius, float inConvexRadiusA, const BE &inBExcludingConvexRadius, float inConvexRadiusB, float inTolerance, Vec3 &ioV, Vec3 &outPointA, Vec3 &outPointB)
100 {
102
103 // Don't supply a zero ioV, we only want to get points on the hull of the Minkowsky sum and not internal points
104 JPH_ASSERT(!ioV.IsNearZero());
105
106 // Get closest points
107 float combined_radius = inConvexRadiusA + inConvexRadiusB;
108 float combined_radius_sq = combined_radius * combined_radius;
109 float closest_points_dist_sq = mGJK.GetClosestPoints(inAExcludingConvexRadius, inBExcludingConvexRadius, inTolerance, combined_radius_sq, ioV, outPointA, outPointB);
110 if (closest_points_dist_sq > combined_radius_sq)
111 {
112 // No collision
114 }
115 if (closest_points_dist_sq > 0.0f)
116 {
117 // Collision within convex radius, adjust points for convex radius
118 float v_len = sqrt(closest_points_dist_sq); // GetClosestPoints function returns |ioV|^2 when return value < FLT_MAX
119 outPointA += ioV * (inConvexRadiusA / v_len);
120 outPointB -= ioV * (inConvexRadiusB / v_len);
121 return EStatus::Colliding;
122 }
123
125 }
126
139 template <typename AI, typename BI>
140 bool GetPenetrationDepthStepEPA(const AI &inAIncludingConvexRadius, const BI &inBIncludingConvexRadius, float inTolerance, Vec3 &outV, Vec3 &outPointA, Vec3 &outPointB)
141 {
143
144 // Check that the tolerance makes sense (smaller value than this will just result in needless iterations)
145 JPH_ASSERT(inTolerance >= FLT_EPSILON);
146
147 // Fetch the simplex from GJK algorithm
148 SupportPoints support_points;
149 mGJK.GetClosestPointsSimplex(support_points.mY.data(), support_points.mP, support_points.mQ, support_points.mY.GetSizeRef());
150
151 // Fill up the amount of support points to 4
152 switch (support_points.mY.size())
153 {
154 case 1:
155 {
156 // 1 vertex, which must be at the origin, which is useless for our purpose
157 JPH_ASSERT(support_points.mY[0].IsNearZero(1.0e-8f));
158 support_points.mY.pop_back();
159
160 // Add support points in 4 directions to form a tetrahedron around the origin
161 int p1, p2, p3, p4;
162 (void)support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, Vec3(0, 1, 0), p1);
163 (void)support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, Vec3(-1, -1, -1), p2);
164 (void)support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, Vec3(1, -1, -1), p3);
165 (void)support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, Vec3(0, -1, 1), p4);
166 JPH_ASSERT(p1 == 0);
167 JPH_ASSERT(p2 == 1);
168 JPH_ASSERT(p3 == 2);
169 JPH_ASSERT(p4 == 3);
170 break;
171 }
172
173 case 2:
174 {
175 // Two vertices, create 3 extra by taking perpendicular axis and rotating it around in 120 degree increments
176 Vec3 axis = (support_points.mY[1] - support_points.mY[0]).Normalized();
177 Mat44 rotation = Mat44::sRotation(axis, DegreesToRadians(120.0f));
178 Vec3 dir1 = axis.GetNormalizedPerpendicular();
179 Vec3 dir2 = rotation * dir1;
180 Vec3 dir3 = rotation * dir2;
181 int p1, p2, p3;
182 (void)support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, dir1, p1);
183 (void)support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, dir2, p2);
184 (void)support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, dir3, p3);
185 JPH_ASSERT(p1 == 2);
186 JPH_ASSERT(p2 == 3);
187 JPH_ASSERT(p3 == 4);
188 break;
189 }
190
191 case 3:
192 case 4:
193 // We already have enough points
194 break;
195 }
196
197 // Create hull out of the initial points
198 JPH_ASSERT(support_points.mY.size() >= 3);
199 EPAConvexHullBuilder hull(support_points.mY);
200#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
201 hull.DrawLabel("Build initial hull");
202#endif
203#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
204 Trace("Init: num_points = %u", (uint)support_points.mY.size());
205#endif
206 hull.Initialize(0, 1, 2);
207 for (typename Points::size_type i = 3; i < support_points.mY.size(); ++i)
208 {
209 float dist_sq;
210 Triangle *t = hull.FindFacingTriangle(support_points.mY[i], dist_sq);
211 if (t != nullptr)
212 {
214 if (!hull.AddPoint(t, i, FLT_MAX, new_triangles))
215 {
216 // We can't recover from a failure to add a point to the hull because the old triangles have been unlinked already.
217 // Assume no collision. This can happen if the shapes touch in 1 point (or plane) in which case the hull is degenerate.
218 return false;
219 }
220 }
221 }
222
223#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
224 hull.DrawLabel("Complete hull");
225
226 // Generate the hull of the Minkowski difference for visualization
227 MinkowskiDifference diff(inAIncludingConvexRadius, inBIncludingConvexRadius);
228 DebugRenderer::GeometryRef geometry = DebugRenderer::sInstance->CreateTriangleGeometryForConvex([&diff](Vec3Arg inDirection) { return diff.GetSupport(inDirection); });
229 hull.DrawGeometry(geometry, Color::sYellow);
230
231 hull.DrawLabel("Ensure origin in hull");
232#endif
233
234 // Loop until we are sure that the origin is inside the hull
235 for (;;)
236 {
237 // Get the next closest triangle
239
240 // Don't process removed triangles, just free them (because they're in a heap we don't remove them earlier since we would have to rebuild the sorted heap)
241 if (t->mRemoved)
242 {
244
245 // If we run out of triangles, we couldn't include the origin in the hull so there must be very little penetration and we report no collision.
246 if (!hull.HasNextTriangle())
247 return false;
248
249 hull.FreeTriangle(t);
250 continue;
251 }
252
253 // If the closest to the triangle is zero or positive, the origin is in the hull and we can proceed to the main algorithm
254 if (t->mClosestLenSq >= 0.0f)
255 break;
256
257#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
258 hull.DrawLabel("Next iteration");
259#endif
260#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
261 Trace("EncapsulateOrigin: verts = (%d, %d, %d), closest_dist_sq = %g, centroid = (%g, %g, %g), normal = (%g, %g, %g)",
262 t->mEdge[0].mStartIdx, t->mEdge[1].mStartIdx, t->mEdge[2].mStartIdx,
263 t->mClosestLenSq,
264 t->mCentroid.GetX(), t->mCentroid.GetY(), t->mCentroid.GetZ(),
265 t->mNormal.GetX(), t->mNormal.GetY(), t->mNormal.GetZ());
266#endif
267
268 // Remove the triangle from the queue before we start adding new ones (which may result in a new closest triangle at the front of the queue)
270
271 // Add a support point to get the origin inside the hull
272 int new_index;
273 Vec3 w = support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, t->mNormal, new_index);
274
275#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
276 // Draw the point that we're adding
277 hull.DrawMarker(w, Color::sRed, 1.0f);
278 hull.DrawWireTriangle(*t, Color::sRed);
279 hull.DrawState();
280#endif
281
282 // Add the point to the hull, if we fail we terminate and report no collision
284 if (!t->IsFacing(w) || !hull.AddPoint(t, new_index, FLT_MAX, new_triangles))
285 return false;
286
287 // The triangle is facing the support point "w" and can now be safely removed
289 hull.FreeTriangle(t);
290
291 // If we run out of triangles or points, we couldn't include the origin in the hull so there must be very little penetration and we report no collision.
292 if (!hull.HasNextTriangle() || support_points.mY.size() >= cMaxPointsToIncludeOriginInHull)
293 return false;
294 }
295
296#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
297 hull.DrawLabel("Main algorithm");
298#endif
299
300 // Current closest distance to origin
301 float closest_dist_sq = FLT_MAX;
302
303 // Remember last good triangle
304 Triangle *last = nullptr;
305
306 // If we want to flip the penetration depth
307 bool flip_v_sign = false;
308
309 // Loop until closest point found
310 do
311 {
312 // Get closest triangle to the origin
314
315 // Don't process removed triangles, just free them (because they're in a heap we don't remove them earlier since we would have to rebuild the sorted heap)
316 if (t->mRemoved)
317 {
318 hull.FreeTriangle(t);
319 continue;
320 }
321
322#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
323 hull.DrawLabel("Next iteration");
324#endif
325#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
326 Trace("FindClosest: verts = (%d, %d, %d), closest_len_sq = %g, centroid = (%g, %g, %g), normal = (%g, %g, %g)",
327 t->mEdge[0].mStartIdx, t->mEdge[1].mStartIdx, t->mEdge[2].mStartIdx,
328 t->mClosestLenSq,
329 t->mCentroid.GetX(), t->mCentroid.GetY(), t->mCentroid.GetZ(),
330 t->mNormal.GetX(), t->mNormal.GetY(), t->mNormal.GetZ());
331#endif
332 // Check if next triangle is further away than closest point, we've found the closest point
333 if (t->mClosestLenSq >= closest_dist_sq)
334 break;
335
336 // Replace last good with this triangle
337 if (last != nullptr)
338 hull.FreeTriangle(last);
339 last = t;
340
341 // Add support point in direction of normal of the plane
342 // Note that the article uses the closest point between the origin and plane, but this always has the exact same direction as the normal (if the origin is behind the plane)
343 // and this way we do less calculations and lose less precision
344 int new_index;
345 Vec3 w = support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, t->mNormal, new_index);
346
347 // Project w onto the triangle normal
348 float dot = t->mNormal.Dot(w);
349
350 // Check if we just found a separating axis. This can happen if the shape shrunk by convex radius and then expanded by
351 // convex radius is bigger then the original shape due to inaccuracies in the shrinking process.
352 if (dot < 0.0f)
353 return false;
354
355 // Get the distance squared (along normal) to the support point
356 float dist_sq = Square(dot) / t->mNormal.LengthSq();
357
358#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
359 Trace("FindClosest: w = (%g, %g, %g), dot = %g, dist_sq = %g",
360 w.GetX(), w.GetY(), w.GetZ(),
361 dot, dist_sq);
362#endif
363#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
364 // Draw the point that we're adding
365 hull.DrawMarker(w, Color::sPurple, 1.0f);
366 hull.DrawWireTriangle(*t, Color::sPurple);
367 hull.DrawState();
368#endif
369
370 // If the error became small enough, we've converged
371 if (dist_sq - t->mClosestLenSq < t->mClosestLenSq * inTolerance)
372 {
373#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
374 Trace("Converged");
375#endif // JPH_EPA_PENETRATION_DEPTH_DEBUG
376 break;
377 }
378
379 // Keep track of the minimum distance
380 closest_dist_sq = min(closest_dist_sq, dist_sq);
381
382 // If the triangle thinks this point is not front facing, we've reached numerical precision and we're done
383 if (!t->IsFacing(w))
384 {
385#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
386 Trace("Not facing triangle");
387#endif // JPH_EPA_PENETRATION_DEPTH_DEBUG
388 break;
389 }
390
391 // Add point to hull
393 if (!hull.AddPoint(t, new_index, closest_dist_sq, new_triangles))
394 {
395#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
396 Trace("Could not add point");
397#endif // JPH_EPA_PENETRATION_DEPTH_DEBUG
398 break;
399 }
400
401 // If the hull is starting to form defects then we're reaching numerical precision and we have to stop
402 bool has_defect = false;
403 for (const Triangle *nt : new_triangles)
404 if (nt->IsFacingOrigin())
405 {
406 has_defect = true;
407 break;
408 }
409 if (has_defect)
410 {
411#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
412 Trace("Has defect");
413#endif // JPH_EPA_PENETRATION_DEPTH_DEBUG
414 // When the hull has defects it is possible that the origin has been classified on the wrong side of the triangle
415 // so we do an additional check to see if the penetration in the -triangle normal direction is smaller than
416 // the penetration in the triangle normal direction. If so we must flip the sign of the penetration depth.
417 Vec3 w2 = inAIncludingConvexRadius.GetSupport(-t->mNormal) - inBIncludingConvexRadius.GetSupport(t->mNormal);
418 float dot2 = -t->mNormal.Dot(w2);
419 if (dot2 < dot)
420 flip_v_sign = true;
421 break;
422 }
423 }
424 while (hull.HasNextTriangle() && support_points.mY.size() < cMaxPoints);
425
426 // Determine closest points, if last == null it means the hull was a plane so there's no penetration
427 if (last == nullptr)
428 return false;
429
430#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
431 hull.DrawLabel("Closest found");
432 hull.DrawWireTriangle(*last, Color::sWhite);
433 hull.DrawArrow(last->mCentroid, last->mCentroid + last->mNormal.NormalizedOr(Vec3::sZero()), Color::sWhite, 0.1f);
434 hull.DrawState();
435#endif
436
437 // Calculate penetration by getting the vector from the origin to the closest point on the triangle:
438 // distance = (centroid - origin) . normal / |normal|, closest = origin + distance * normal / |normal|
439 outV = (last->mCentroid.Dot(last->mNormal) / last->mNormal.LengthSq()) * last->mNormal;
440
441 // If penetration is near zero, treat this as a non collision since we cannot find a good normal
442 if (outV.IsNearZero())
443 return false;
444
445 // Check if we have to flip the sign of the penetration depth
446 if (flip_v_sign)
447 outV = -outV;
448
449 // Use the barycentric coordinates for the closest point to the origin to find the contact points on A and B
450 Vec3 p0 = support_points.mP[last->mEdge[0].mStartIdx];
451 Vec3 p1 = support_points.mP[last->mEdge[1].mStartIdx];
452 Vec3 p2 = support_points.mP[last->mEdge[2].mStartIdx];
453
454 Vec3 q0 = support_points.mQ[last->mEdge[0].mStartIdx];
455 Vec3 q1 = support_points.mQ[last->mEdge[1].mStartIdx];
456 Vec3 q2 = support_points.mQ[last->mEdge[2].mStartIdx];
457
458 if (last->mLambdaRelativeTo0)
459 {
460 // y0 was the reference vertex
461 outPointA = p0 + last->mLambda[0] * (p1 - p0) + last->mLambda[1] * (p2 - p0);
462 outPointB = q0 + last->mLambda[0] * (q1 - q0) + last->mLambda[1] * (q2 - q0);
463 }
464 else
465 {
466 // y1 was the reference vertex
467 outPointA = p1 + last->mLambda[0] * (p0 - p1) + last->mLambda[1] * (p2 - p1);
468 outPointB = q1 + last->mLambda[0] * (q0 - q1) + last->mLambda[1] * (q2 - q1);
469 }
470
471 return true;
472 }
473
477 template <typename AE, typename AI, typename BE, typename BI>
478 bool GetPenetrationDepth(const AE &inAExcludingConvexRadius, const AI &inAIncludingConvexRadius, float inConvexRadiusA, const BE &inBExcludingConvexRadius, const BI &inBIncludingConvexRadius, float inConvexRadiusB, float inCollisionToleranceSq, float inPenetrationTolerance, Vec3 &ioV, Vec3 &outPointA, Vec3 &outPointB)
479 {
480 // Check result of collision detection
481 switch (GetPenetrationDepthStepGJK(inAExcludingConvexRadius, inConvexRadiusA, inBExcludingConvexRadius, inConvexRadiusB, inCollisionToleranceSq, ioV, outPointA, outPointB))
482 {
484 return true;
485
487 return false;
488
490 return GetPenetrationDepthStepEPA(inAIncludingConvexRadius, inBIncludingConvexRadius, inPenetrationTolerance, ioV, outPointA, outPointB);
491 }
492
493 JPH_ASSERT(false);
494 return false;
495 }
496
514 template <typename A, typename B>
515 bool CastShape(Mat44Arg inStart, Vec3Arg inDirection, float inCollisionTolerance, float inPenetrationTolerance, const A &inA, const B &inB, float inConvexRadiusA, float inConvexRadiusB, bool inReturnDeepestPoint, float &ioLambda, Vec3 &outPointA, Vec3 &outPointB, Vec3 &outContactNormal)
516 {
517 // First determine if there's a collision at all
518 if (!mGJK.CastShape(inStart, inDirection, inCollisionTolerance, inA, inB, inConvexRadiusA, inConvexRadiusB, ioLambda, outPointA, outPointB, outContactNormal))
519 return false;
520
521 // When our contact normal is too small, we don't have an accurate result
522 bool contact_normal_invalid = outContactNormal.IsNearZero(Square(inCollisionTolerance));
523
524 if (inReturnDeepestPoint
525 && ioLambda == 0.0f // Only when lambda = 0 we can have the bodies overlap
526 && (inConvexRadiusA + inConvexRadiusB == 0.0f // When no convex radius was provided we can never trust contact points at lambda = 0
527 || contact_normal_invalid))
528 {
529 // If we're initially intersecting, we need to run the EPA algorithm in order to find the deepest contact point
530 AddConvexRadius<A> add_convex_a(inA, inConvexRadiusA);
531 AddConvexRadius<B> add_convex_b(inB, inConvexRadiusB);
532 TransformedConvexObject<AddConvexRadius<A>> transformed_a(inStart, add_convex_a);
533 if (!GetPenetrationDepthStepEPA(transformed_a, add_convex_b, inPenetrationTolerance, outContactNormal, outPointA, outPointB))
534 return false;
535 }
536 else if (contact_normal_invalid)
537 {
538 // If we weren't able to calculate a contact normal, use the cast direction instead
539 outContactNormal = inDirection;
540 }
541
542 return true;
543 }
544};
545
unsigned int uint
Definition: Core.h:426
#define JPH_NAMESPACE_END
Definition: Core.h:354
#define JPH_NAMESPACE_BEGIN
Definition: Core.h:348
TraceFunction Trace
Definition: IssueReporting.cpp:18
#define JPH_ASSERT(...)
Definition: IssueReporting.h:33
constexpr T Square(T inV)
Square a value.
Definition: Math.h:52
constexpr float DegreesToRadians(float inV)
Convert a value from degrees to radians.
Definition: Math.h:13
#define JPH_PROFILE_FUNCTION()
Scope profiling for function.
Definition: Profiler.h:254
static const Color sPurple
Definition: Color.h:55
static const Color sWhite
Definition: Color.h:61
static const Color sRed
Definition: Color.h:49
static const Color sYellow
Definition: Color.h:54
GeometryRef CreateTriangleGeometryForConvex(SupportFunction inGetSupport)
Definition: DebugRenderer.cpp:688
static DebugRenderer * sInstance
Singleton instance.
Definition: DebugRenderer.h:136
int mStartIdx
Vertex index in mPositions that indicates the start vertex of this edge.
Definition: EPAConvexHullBuilder.h:54
Specialized points list that allows direct access to the size.
Definition: EPAConvexHullBuilder.h:172
Class that holds the information of one triangle.
Definition: EPAConvexHullBuilder.h:62
Vec3 mCentroid
Center of the triangle.
Definition: EPAConvexHullBuilder.h:89
bool IsFacing(Vec3Arg inPosition) const
Check if triangle is facing inPosition.
Definition: EPAConvexHullBuilder.h:68
Vec3 mNormal
Normal of this triangle, length is 2 times area of triangle.
Definition: EPAConvexHullBuilder.h:88
Edge mEdge[3]
3 edges of this triangle
Definition: EPAConvexHullBuilder.h:87
float mClosestLenSq
Closest distance^2 from origin to triangle.
Definition: EPAConvexHullBuilder.h:90
float mLambda[2]
Barycentric coordinates of closest point to origin on triangle.
Definition: EPAConvexHullBuilder.h:91
bool mLambdaRelativeTo0
How to calculate the closest point, true: y0 + l0 * (y1 - y0) + l1 * (y2 - y0), false: y1 + l0 * (y0 ...
Definition: EPAConvexHullBuilder.h:92
bool mRemoved
Flag that indicates that triangle has been removed.
Definition: EPAConvexHullBuilder.h:94
A convex hull builder specifically made for the EPA penetration depth calculation....
Definition: EPAConvexHullBuilder.h:24
Triangle * PeekClosestTriangleInQueue()
Access to the next closest triangle to the origin (won't remove it from the queue).
Definition: EPAConvexHullBuilder.h:267
bool HasNextTriangle() const
Check if there's another triangle to process from the queue.
Definition: EPAConvexHullBuilder.h:261
static constexpr int cMaxPoints
Max number of points in hull.
Definition: EPAConvexHullBuilder.h:36
Triangle * PopClosestTriangleFromQueue()
Access to the next closest triangle to the origin and remove it from the queue.
Definition: EPAConvexHullBuilder.h:273
void FreeTriangle(Triangle *inT)
Free a triangle.
Definition: EPAConvexHullBuilder.h:365
Triangle * FindFacingTriangle(Vec3Arg inPosition, float &outBestDistSq)
Definition: EPAConvexHullBuilder.h:280
void Initialize(int inIdx1, int inIdx2, int inIdx3)
Initialize the hull with 3 points.
Definition: EPAConvexHullBuilder.h:233
bool AddPoint(Triangle *inFacingTriangle, int inIdx, float inClosestDistSq, NewTriangles &outTriangles)
Add a new point to the convex hull.
Definition: EPAConvexHullBuilder.h:305
Definition: EPAPenetrationDepth.h:37
bool CastShape(Mat44Arg inStart, Vec3Arg inDirection, float inCollisionTolerance, float inPenetrationTolerance, const A &inA, const B &inB, float inConvexRadiusA, float inConvexRadiusB, bool inReturnDeepestPoint, float &ioLambda, Vec3 &outPointA, Vec3 &outPointB, Vec3 &outContactNormal)
Definition: EPAPenetrationDepth.h:515
bool GetPenetrationDepth(const AE &inAExcludingConvexRadius, const AI &inAIncludingConvexRadius, float inConvexRadiusA, const BE &inBExcludingConvexRadius, const BI &inBIncludingConvexRadius, float inConvexRadiusB, float inCollisionToleranceSq, float inPenetrationTolerance, Vec3 &ioV, Vec3 &outPointA, Vec3 &outPointB)
Definition: EPAPenetrationDepth.h:478
EStatus GetPenetrationDepthStepGJK(const AE &inAExcludingConvexRadius, float inConvexRadiusA, const BE &inBExcludingConvexRadius, float inConvexRadiusB, float inTolerance, Vec3 &ioV, Vec3 &outPointA, Vec3 &outPointB)
Definition: EPAPenetrationDepth.h:99
EStatus
Return code for GetPenetrationDepthStepGJK.
Definition: EPAPenetrationDepth.h:81
@ NotColliding
Returned if the objects don't collide, in this case outPointA/outPointB are invalid.
@ Indeterminate
Returned if the objects penetrate further than the convex radius. In this case you need to call GetPe...
@ Colliding
Returned if the objects penetrate.
bool GetPenetrationDepthStepEPA(const AI &inAIncludingConvexRadius, const BI &inBIncludingConvexRadius, float inTolerance, Vec3 &outV, Vec3 &outPointA, Vec3 &outPointB)
Definition: EPAPenetrationDepth.h:140
Definition: GJKClosestPoint.h:23
bool CastShape(Mat44Arg inStart, Vec3Arg inDirection, float inTolerance, const A &inA, const B &inB, float &ioLambda)
Definition: GJKClosestPoint.h:665
void GetClosestPointsSimplex(Vec3 *outY, Vec3 *outP, Vec3 *outQ, uint &outNumPoints) const
Definition: GJKClosestPoint.h:502
float GetClosestPoints(const A &inA, const B &inB, float inTolerance, float inMaxDistSq, Vec3 &ioV, Vec3 &outPointA, Vec3 &outPointB)
Definition: GJKClosestPoint.h:334
Holds a 4x4 matrix of floats, but supports also operations on the 3x3 upper left part of the matrix.
Definition: Mat44.h:13
static JPH_INLINE Mat44 sRotation(Vec3Arg inAxis, float inAngle)
Rotate around arbitrary axis.
Definition: Mat44.inl:139
Simple variable length array backed by a fixed size buffer.
Definition: StaticArray.h:12
void push_back(const T &inElement)
Add element to the back of the array.
Definition: StaticArray.h:59
uint size_type
Definition: StaticArray.h:16
size_type size() const
Returns amount of elements in the array.
Definition: StaticArray.h:87
Definition: Vec3.h:16
JPH_INLINE float Dot(Vec3Arg inV2) const
Dot product.
Definition: Vec3.inl:637
JPH_INLINE Vec3 GetNormalizedPerpendicular() const
Get normalized vector that is perpendicular to this vector.
Definition: Vec3.inl:812
JPH_INLINE float GetX() const
Get individual components.
Definition: Vec3.h:123
JPH_INLINE Vec3 NormalizedOr(Vec3Arg inZeroValue) const
Normalize vector or return inZeroValue if the length of the vector is zero.
Definition: Vec3.inl:708
JPH_INLINE float GetY() const
Definition: Vec3.h:124
JPH_INLINE float LengthSq() const
Squared length of vector.
Definition: Vec3.inl:653
JPH_INLINE bool IsNearZero(float inMaxDistSq=1.0e-12f) const
Test if vector is near zero.
Definition: Vec3.inl:347
static JPH_INLINE Vec3 sZero()
Vector with all zeros.
Definition: Vec3.inl:107
JPH_INLINE float GetZ() const
Definition: Vec3.h:125
Structure that adds a convex radius.
Definition: ConvexSupport.h:46
Structure that performs a Minkowski difference A - B.
Definition: ConvexSupport.h:67
Vec3 GetSupport(Vec3Arg inDirection) const
Calculate the support vector for this convex shape.
Definition: ConvexSupport.h:75
Definition: ConvexSupport.h:15