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
50#ifdef JPH_ENABLE_ASSERTS
52 float mGJKTolerance = 0.0f;
53#endif // JPH_ENABLE_ASSERTS
54
56 class SupportPoints
57 {
58 public:
60 Points mY;
61 Vec3 mP[cMaxPoints];
62 Vec3 mQ[cMaxPoints];
63
65 template <typename A, typename B>
66 Vec3 Add(const A &inA, const B &inB, Vec3Arg inDirection, int &outIndex)
67 {
68 // Get support point of the minkowski sum A - B
69 Vec3 p = inA.GetSupport(inDirection);
70 Vec3 q = inB.GetSupport(-inDirection);
71 Vec3 w = p - q;
72
73 // Store new point
74 outIndex = mY.size();
75 mY.push_back(w);
76 mP[outIndex] = p;
77 mQ[outIndex] = q;
78
79 return w;
80 }
81 };
82
83public:
85 enum class EStatus
86 {
88 Colliding,
90 };
91
103 template <typename AE, typename BE>
104 EStatus GetPenetrationDepthStepGJK(const AE &inAExcludingConvexRadius, float inConvexRadiusA, const BE &inBExcludingConvexRadius, float inConvexRadiusB, float inTolerance, Vec3 &ioV, Vec3 &outPointA, Vec3 &outPointB)
105 {
107
108 JPH_IF_ENABLE_ASSERTS(mGJKTolerance = inTolerance;)
109
110 // Don't supply a zero ioV, we only want to get points on the hull of the Minkowsky sum and not internal points
111 JPH_ASSERT(!ioV.IsNearZero());
112
113 // Get closest points
114 float combined_radius = inConvexRadiusA + inConvexRadiusB;
115 float combined_radius_sq = combined_radius * combined_radius;
116 float closest_points_dist_sq = mGJK.GetClosestPoints(inAExcludingConvexRadius, inBExcludingConvexRadius, inTolerance, combined_radius_sq, ioV, outPointA, outPointB);
117 if (closest_points_dist_sq > combined_radius_sq)
118 {
119 // No collision
121 }
122 if (closest_points_dist_sq > 0.0f)
123 {
124 // Collision within convex radius, adjust points for convex radius
125 float v_len = sqrt(closest_points_dist_sq); // GetClosestPoints function returns |ioV|^2 when return value < FLT_MAX
126 outPointA += ioV * (inConvexRadiusA / v_len);
127 outPointB -= ioV * (inConvexRadiusB / v_len);
128 return EStatus::Colliding;
129 }
130
132 }
133
146 template <typename AI, typename BI>
147 bool GetPenetrationDepthStepEPA(const AI &inAIncludingConvexRadius, const BI &inBIncludingConvexRadius, float inTolerance, Vec3 &outV, Vec3 &outPointA, Vec3 &outPointB)
148 {
150
151 // Check that the tolerance makes sense (smaller value than this will just result in needless iterations)
152 JPH_ASSERT(inTolerance >= FLT_EPSILON);
153
154 // Fetch the simplex from GJK algorithm
155 SupportPoints support_points;
156 mGJK.GetClosestPointsSimplex(support_points.mY.data(), support_points.mP, support_points.mQ, support_points.mY.GetSizeRef());
157
158 // Fill up the amount of support points to 4
159 switch (support_points.mY.size())
160 {
161 case 1:
162 {
163 // 1 vertex, which must be at the origin, which is useless for our purpose
164 JPH_ASSERT(support_points.mY[0].IsNearZero(Square(mGJKTolerance)));
165 support_points.mY.pop_back();
166
167 // Add support points in 4 directions to form a tetrahedron around the origin
168 int p1, p2, p3, p4;
169 (void)support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, Vec3(0, 1, 0), p1);
170 (void)support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, Vec3(-1, -1, -1), p2);
171 (void)support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, Vec3(1, -1, -1), p3);
172 (void)support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, Vec3(0, -1, 1), p4);
173 JPH_ASSERT(p1 == 0);
174 JPH_ASSERT(p2 == 1);
175 JPH_ASSERT(p3 == 2);
176 JPH_ASSERT(p4 == 3);
177 break;
178 }
179
180 case 2:
181 {
182 // Two vertices, create 3 extra by taking perpendicular axis and rotating it around in 120 degree increments
183 Vec3 axis = (support_points.mY[1] - support_points.mY[0]).Normalized();
184 Mat44 rotation = Mat44::sRotation(axis, DegreesToRadians(120.0f));
185 Vec3 dir1 = axis.GetNormalizedPerpendicular();
186 Vec3 dir2 = rotation * dir1;
187 Vec3 dir3 = rotation * dir2;
188 int p1, p2, p3;
189 (void)support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, dir1, p1);
190 (void)support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, dir2, p2);
191 (void)support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, dir3, p3);
192 JPH_ASSERT(p1 == 2);
193 JPH_ASSERT(p2 == 3);
194 JPH_ASSERT(p3 == 4);
195 break;
196 }
197
198 case 3:
199 case 4:
200 // We already have enough points
201 break;
202 }
203
204 // Create hull out of the initial points
205 JPH_ASSERT(support_points.mY.size() >= 3);
206 EPAConvexHullBuilder hull(support_points.mY);
207#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
208 hull.DrawLabel("Build initial hull");
209#endif
210#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
211 Trace("Init: num_points = %u", (uint)support_points.mY.size());
212#endif
213 hull.Initialize(0, 1, 2);
214 for (typename Points::size_type i = 3; i < support_points.mY.size(); ++i)
215 {
216 float dist_sq;
217 Triangle *t = hull.FindFacingTriangle(support_points.mY[i], dist_sq);
218 if (t != nullptr)
219 {
221 if (!hull.AddPoint(t, i, FLT_MAX, new_triangles))
222 {
223 // We can't recover from a failure to add a point to the hull because the old triangles have been unlinked already.
224 // Assume no collision. This can happen if the shapes touch in 1 point (or plane) in which case the hull is degenerate.
225 return false;
226 }
227 }
228 }
229
230#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
231 hull.DrawLabel("Complete hull");
232
233 // Generate the hull of the Minkowski difference for visualization
234 MinkowskiDifference diff(inAIncludingConvexRadius, inBIncludingConvexRadius);
235 DebugRenderer::GeometryRef geometry = DebugRenderer::sInstance->CreateTriangleGeometryForConvex([&diff](Vec3Arg inDirection) { return diff.GetSupport(inDirection); });
236 hull.DrawGeometry(geometry, Color::sYellow);
237
238 hull.DrawLabel("Ensure origin in hull");
239#endif
240
241 // Loop until we are sure that the origin is inside the hull
242 for (;;)
243 {
244 // Get the next closest triangle
246
247 // 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)
248 if (t->mRemoved)
249 {
251
252 // 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.
253 if (!hull.HasNextTriangle())
254 return false;
255
256 hull.FreeTriangle(t);
257 continue;
258 }
259
260 // If the closest to the triangle is zero or positive, the origin is in the hull and we can proceed to the main algorithm
261 if (t->mClosestLenSq >= 0.0f)
262 break;
263
264#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
265 hull.DrawLabel("Next iteration");
266#endif
267#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
268 Trace("EncapsulateOrigin: verts = (%d, %d, %d), closest_dist_sq = %g, centroid = (%g, %g, %g), normal = (%g, %g, %g)",
269 t->mEdge[0].mStartIdx, t->mEdge[1].mStartIdx, t->mEdge[2].mStartIdx,
270 t->mClosestLenSq,
271 t->mCentroid.GetX(), t->mCentroid.GetY(), t->mCentroid.GetZ(),
272 t->mNormal.GetX(), t->mNormal.GetY(), t->mNormal.GetZ());
273#endif
274
275 // 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)
277
278 // Add a support point to get the origin inside the hull
279 int new_index;
280 Vec3 w = support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, t->mNormal, new_index);
281
282#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
283 // Draw the point that we're adding
284 hull.DrawMarker(w, Color::sRed, 1.0f);
285 hull.DrawWireTriangle(*t, Color::sRed);
286 hull.DrawState();
287#endif
288
289 // Add the point to the hull, if we fail we terminate and report no collision
291 if (!t->IsFacing(w) || !hull.AddPoint(t, new_index, FLT_MAX, new_triangles))
292 return false;
293
294 // The triangle is facing the support point "w" and can now be safely removed
296 hull.FreeTriangle(t);
297
298 // 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.
299 if (!hull.HasNextTriangle() || support_points.mY.size() >= cMaxPointsToIncludeOriginInHull)
300 return false;
301 }
302
303#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
304 hull.DrawLabel("Main algorithm");
305#endif
306
307 // Current closest distance to origin
308 float closest_dist_sq = FLT_MAX;
309
310 // Remember last good triangle
311 Triangle *last = nullptr;
312
313 // If we want to flip the penetration depth
314 bool flip_v_sign = false;
315
316 // Loop until closest point found
317 do
318 {
319 // Get closest triangle to the origin
321
322 // 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)
323 if (t->mRemoved)
324 {
325 hull.FreeTriangle(t);
326 continue;
327 }
328
329#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
330 hull.DrawLabel("Next iteration");
331#endif
332#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
333 Trace("FindClosest: verts = (%d, %d, %d), closest_len_sq = %g, centroid = (%g, %g, %g), normal = (%g, %g, %g)",
334 t->mEdge[0].mStartIdx, t->mEdge[1].mStartIdx, t->mEdge[2].mStartIdx,
335 t->mClosestLenSq,
336 t->mCentroid.GetX(), t->mCentroid.GetY(), t->mCentroid.GetZ(),
337 t->mNormal.GetX(), t->mNormal.GetY(), t->mNormal.GetZ());
338#endif
339 // Check if next triangle is further away than closest point, we've found the closest point
340 if (t->mClosestLenSq >= closest_dist_sq)
341 break;
342
343 // Replace last good with this triangle
344 if (last != nullptr)
345 hull.FreeTriangle(last);
346 last = t;
347
348 // Add support point in direction of normal of the plane
349 // 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)
350 // and this way we do less calculations and lose less precision
351 int new_index;
352 Vec3 w = support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, t->mNormal, new_index);
353
354 // Project w onto the triangle normal
355 float dot = t->mNormal.Dot(w);
356
357 // Check if we just found a separating axis. This can happen if the shape shrunk by convex radius and then expanded by
358 // convex radius is bigger then the original shape due to inaccuracies in the shrinking process.
359 if (dot < 0.0f)
360 return false;
361
362 // Get the distance squared (along normal) to the support point
363 float dist_sq = Square(dot) / t->mNormal.LengthSq();
364
365#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
366 Trace("FindClosest: w = (%g, %g, %g), dot = %g, dist_sq = %g",
367 w.GetX(), w.GetY(), w.GetZ(),
368 dot, dist_sq);
369#endif
370#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
371 // Draw the point that we're adding
372 hull.DrawMarker(w, Color::sPurple, 1.0f);
373 hull.DrawWireTriangle(*t, Color::sPurple);
374 hull.DrawState();
375#endif
376
377 // If the error became small enough, we've converged
378 if (dist_sq - t->mClosestLenSq < t->mClosestLenSq * inTolerance)
379 {
380#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
381 Trace("Converged");
382#endif // JPH_EPA_PENETRATION_DEPTH_DEBUG
383 break;
384 }
385
386 // Keep track of the minimum distance
387 closest_dist_sq = min(closest_dist_sq, dist_sq);
388
389 // If the triangle thinks this point is not front facing, we've reached numerical precision and we're done
390 if (!t->IsFacing(w))
391 {
392#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
393 Trace("Not facing triangle");
394#endif // JPH_EPA_PENETRATION_DEPTH_DEBUG
395 break;
396 }
397
398 // Add point to hull
400 if (!hull.AddPoint(t, new_index, closest_dist_sq, new_triangles))
401 {
402#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
403 Trace("Could not add point");
404#endif // JPH_EPA_PENETRATION_DEPTH_DEBUG
405 break;
406 }
407
408 // If the hull is starting to form defects then we're reaching numerical precision and we have to stop
409 bool has_defect = false;
410 for (const Triangle *nt : new_triangles)
411 if (nt->IsFacingOrigin())
412 {
413 has_defect = true;
414 break;
415 }
416 if (has_defect)
417 {
418#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
419 Trace("Has defect");
420#endif // JPH_EPA_PENETRATION_DEPTH_DEBUG
421 // When the hull has defects it is possible that the origin has been classified on the wrong side of the triangle
422 // so we do an additional check to see if the penetration in the -triangle normal direction is smaller than
423 // the penetration in the triangle normal direction. If so we must flip the sign of the penetration depth.
424 Vec3 w2 = inAIncludingConvexRadius.GetSupport(-t->mNormal) - inBIncludingConvexRadius.GetSupport(t->mNormal);
425 float dot2 = -t->mNormal.Dot(w2);
426 if (dot2 < dot)
427 flip_v_sign = true;
428 break;
429 }
430 }
431 while (hull.HasNextTriangle() && support_points.mY.size() < cMaxPoints);
432
433 // Determine closest points, if last == null it means the hull was a plane so there's no penetration
434 if (last == nullptr)
435 return false;
436
437#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
438 hull.DrawLabel("Closest found");
439 hull.DrawWireTriangle(*last, Color::sWhite);
440 hull.DrawArrow(last->mCentroid, last->mCentroid + last->mNormal.NormalizedOr(Vec3::sZero()), Color::sWhite, 0.1f);
441 hull.DrawState();
442#endif
443
444 // Calculate penetration by getting the vector from the origin to the closest point on the triangle:
445 // distance = (centroid - origin) . normal / |normal|, closest = origin + distance * normal / |normal|
446 outV = (last->mCentroid.Dot(last->mNormal) / last->mNormal.LengthSq()) * last->mNormal;
447
448 // If penetration is near zero, treat this as a non collision since we cannot find a good normal
449 if (outV.IsNearZero())
450 return false;
451
452 // Check if we have to flip the sign of the penetration depth
453 if (flip_v_sign)
454 outV = -outV;
455
456 // Use the barycentric coordinates for the closest point to the origin to find the contact points on A and B
457 Vec3 p0 = support_points.mP[last->mEdge[0].mStartIdx];
458 Vec3 p1 = support_points.mP[last->mEdge[1].mStartIdx];
459 Vec3 p2 = support_points.mP[last->mEdge[2].mStartIdx];
460
461 Vec3 q0 = support_points.mQ[last->mEdge[0].mStartIdx];
462 Vec3 q1 = support_points.mQ[last->mEdge[1].mStartIdx];
463 Vec3 q2 = support_points.mQ[last->mEdge[2].mStartIdx];
464
465 if (last->mLambdaRelativeTo0)
466 {
467 // y0 was the reference vertex
468 outPointA = p0 + last->mLambda[0] * (p1 - p0) + last->mLambda[1] * (p2 - p0);
469 outPointB = q0 + last->mLambda[0] * (q1 - q0) + last->mLambda[1] * (q2 - q0);
470 }
471 else
472 {
473 // y1 was the reference vertex
474 outPointA = p1 + last->mLambda[0] * (p0 - p1) + last->mLambda[1] * (p2 - p1);
475 outPointB = q1 + last->mLambda[0] * (q0 - q1) + last->mLambda[1] * (q2 - q1);
476 }
477
478 return true;
479 }
480
484 template <typename AE, typename AI, typename BE, typename BI>
485 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)
486 {
487 // Check result of collision detection
488 switch (GetPenetrationDepthStepGJK(inAExcludingConvexRadius, inConvexRadiusA, inBExcludingConvexRadius, inConvexRadiusB, inCollisionToleranceSq, ioV, outPointA, outPointB))
489 {
491 return true;
492
494 return false;
495
497 return GetPenetrationDepthStepEPA(inAIncludingConvexRadius, inBIncludingConvexRadius, inPenetrationTolerance, ioV, outPointA, outPointB);
498 }
499
500 JPH_ASSERT(false);
501 return false;
502 }
503
521 template <typename A, typename B>
522 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)
523 {
524 JPH_IF_ENABLE_ASSERTS(mGJKTolerance = inCollisionTolerance;)
525
526 // First determine if there's a collision at all
527 if (!mGJK.CastShape(inStart, inDirection, inCollisionTolerance, inA, inB, inConvexRadiusA, inConvexRadiusB, ioLambda, outPointA, outPointB, outContactNormal))
528 return false;
529
530 // When our contact normal is too small, we don't have an accurate result
531 bool contact_normal_invalid = outContactNormal.IsNearZero(Square(inCollisionTolerance));
532
533 if (inReturnDeepestPoint
534 && ioLambda == 0.0f // Only when lambda = 0 we can have the bodies overlap
535 && (inConvexRadiusA + inConvexRadiusB == 0.0f // When no convex radius was provided we can never trust contact points at lambda = 0
536 || contact_normal_invalid))
537 {
538 // If we're initially intersecting, we need to run the EPA algorithm in order to find the deepest contact point
539 AddConvexRadius<A> add_convex_a(inA, inConvexRadiusA);
540 AddConvexRadius<B> add_convex_b(inB, inConvexRadiusB);
541 TransformedConvexObject<AddConvexRadius<A>> transformed_a(inStart, add_convex_a);
542 if (!GetPenetrationDepthStepEPA(transformed_a, add_convex_b, inPenetrationTolerance, outContactNormal, outPointA, outPointB))
543 return false;
544 }
545 else if (contact_normal_invalid)
546 {
547 // If we weren't able to calculate a contact normal, use the cast direction instead
548 outContactNormal = inDirection;
549 }
550
551 return true;
552 }
553};
554
unsigned int uint
Definition: Core.h:452
#define JPH_NAMESPACE_END
Definition: Core.h:378
#define JPH_NAMESPACE_BEGIN
Definition: Core.h:372
TraceFunction Trace
Definition: IssueReporting.cpp:18
#define JPH_IF_ENABLE_ASSERTS(...)
Definition: IssueReporting.h:35
#define JPH_ASSERT(...)
Definition: IssueReporting.h:33
JPH_INLINE constexpr T Square(T inV)
Square a value.
Definition: Math.h:52
JPH_INLINE 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:271
static const Color sPurple
Definition: Color.h:61
static const Color sWhite
Definition: Color.h:67
static const Color sRed
Definition: Color.h:55
static const Color sYellow
Definition: Color.h:60
GeometryRef CreateTriangleGeometryForConvex(SupportFunction inGetSupport)
Definition: DebugRenderer.cpp:688
static DebugRenderer * sInstance
Singleton instance.
Definition: DebugRenderer.h:168
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:522
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:485
EStatus GetPenetrationDepthStepGJK(const AE &inAExcludingConvexRadius, float inConvexRadiusA, const BE &inBExcludingConvexRadius, float inConvexRadiusB, float inTolerance, Vec3 &ioV, Vec3 &outPointA, Vec3 &outPointB)
Definition: EPAPenetrationDepth.h:104
EStatus
Return code for GetPenetrationDepthStepGJK.
Definition: EPAPenetrationDepth.h:86
@ 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:147
Definition: GJKClosestPoint.h:23
bool CastShape(Mat44Arg inStart, Vec3Arg inDirection, float inTolerance, const A &inA, const B &inB, float &ioLambda)
Definition: GJKClosestPoint.h:659
void GetClosestPointsSimplex(Vec3 *outY, Vec3 *outP, Vec3 *outQ, uint &outNumPoints) const
Definition: GJKClosestPoint.h:496
float GetClosestPoints(const A &inA, const B &inB, float inTolerance, float inMaxDistSq, Vec3 &ioV, Vec3 &outPointA, Vec3 &outPointB)
Definition: GJKClosestPoint.h:328
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:14
void push_back(const T &inElement)
Add element to the back of the array.
Definition: StaticArray.h:61
uint size_type
Definition: StaticArray.h:18
size_type size() const
Returns amount of elements in the array.
Definition: StaticArray.h:89
Definition: Vec3.h:17
JPH_INLINE float Dot(Vec3Arg inV2) const
Dot product.
Definition: Vec3.inl:645
JPH_INLINE Vec3 GetNormalizedPerpendicular() const
Get normalized vector that is perpendicular to this vector.
Definition: Vec3.inl:820
JPH_INLINE float GetX() const
Get individual components.
Definition: Vec3.h:124
JPH_INLINE Vec3 NormalizedOr(Vec3Arg inZeroValue) const
Normalize vector or return inZeroValue if the length of the vector is zero.
Definition: Vec3.inl:716
JPH_INLINE float GetY() const
Definition: Vec3.h:125
JPH_INLINE float LengthSq() const
Squared length of vector.
Definition: Vec3.inl:661
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:126
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