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 //
112 // Note that if the assert below triggers, it is very likely that you have a MeshShape that contains a degenerate triangle (e.g. a sliver).
113 // Go up a couple of levels in the call stack to see if we're indeed testing a triangle and if it is degenerate.
114 // If this is the case then fix the triangles you supply to the MeshShape.
115 JPH_ASSERT(!ioV.IsNearZero());
116
117 // Get closest points
118 float combined_radius = inConvexRadiusA + inConvexRadiusB;
119 float combined_radius_sq = combined_radius * combined_radius;
120 float closest_points_dist_sq = mGJK.GetClosestPoints(inAExcludingConvexRadius, inBExcludingConvexRadius, inTolerance, combined_radius_sq, ioV, outPointA, outPointB);
121 if (closest_points_dist_sq > combined_radius_sq)
122 {
123 // No collision
125 }
126 if (closest_points_dist_sq > 0.0f)
127 {
128 // Collision within convex radius, adjust points for convex radius
129 float v_len = sqrt(closest_points_dist_sq); // GetClosestPoints function returns |ioV|^2 when return value < FLT_MAX
130 outPointA += ioV * (inConvexRadiusA / v_len);
131 outPointB -= ioV * (inConvexRadiusB / v_len);
132 return EStatus::Colliding;
133 }
134
136 }
137
150 template <typename AI, typename BI>
151 bool GetPenetrationDepthStepEPA(const AI &inAIncludingConvexRadius, const BI &inBIncludingConvexRadius, float inTolerance, Vec3 &outV, Vec3 &outPointA, Vec3 &outPointB)
152 {
154
155 // Check that the tolerance makes sense (smaller value than this will just result in needless iterations)
156 JPH_ASSERT(inTolerance >= FLT_EPSILON);
157
158 // Fetch the simplex from GJK algorithm
159 SupportPoints support_points;
160 mGJK.GetClosestPointsSimplex(support_points.mY.data(), support_points.mP, support_points.mQ, support_points.mY.GetSizeRef());
161
162 // Fill up the amount of support points to 4
163 switch (support_points.mY.size())
164 {
165 case 1:
166 {
167 // 1 vertex, which must be at the origin, which is useless for our purpose
168 JPH_ASSERT(support_points.mY[0].IsNearZero(Square(mGJKTolerance)));
169 support_points.mY.pop_back();
170
171 // Add support points in 4 directions to form a tetrahedron around the origin
172 int p1, p2, p3, p4;
173 (void)support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, Vec3(0, 1, 0), p1);
174 (void)support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, Vec3(-1, -1, -1), p2);
175 (void)support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, Vec3(1, -1, -1), p3);
176 (void)support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, Vec3(0, -1, 1), p4);
177 JPH_ASSERT(p1 == 0);
178 JPH_ASSERT(p2 == 1);
179 JPH_ASSERT(p3 == 2);
180 JPH_ASSERT(p4 == 3);
181 break;
182 }
183
184 case 2:
185 {
186 // Two vertices, create 3 extra by taking perpendicular axis and rotating it around in 120 degree increments
187 Vec3 axis = (support_points.mY[1] - support_points.mY[0]).Normalized();
188 Mat44 rotation = Mat44::sRotation(axis, DegreesToRadians(120.0f));
189 Vec3 dir1 = axis.GetNormalizedPerpendicular();
190 Vec3 dir2 = rotation * dir1;
191 Vec3 dir3 = rotation * dir2;
192 int p1, p2, p3;
193 (void)support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, dir1, p1);
194 (void)support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, dir2, p2);
195 (void)support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, dir3, p3);
196 JPH_ASSERT(p1 == 2);
197 JPH_ASSERT(p2 == 3);
198 JPH_ASSERT(p3 == 4);
199 break;
200 }
201
202 case 3:
203 case 4:
204 // We already have enough points
205 break;
206 }
207
208 // Create hull out of the initial points
209 JPH_ASSERT(support_points.mY.size() >= 3);
210 EPAConvexHullBuilder hull(support_points.mY);
211#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
212 hull.DrawLabel("Build initial hull");
213#endif
214#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
215 Trace("Init: num_points = %u", (uint)support_points.mY.size());
216#endif
217 hull.Initialize(0, 1, 2);
218 for (typename Points::size_type i = 3; i < support_points.mY.size(); ++i)
219 {
220 float dist_sq;
221 Triangle *t = hull.FindFacingTriangle(support_points.mY[i], dist_sq);
222 if (t != nullptr)
223 {
225 if (!hull.AddPoint(t, i, FLT_MAX, new_triangles))
226 {
227 // We can't recover from a failure to add a point to the hull because the old triangles have been unlinked already.
228 // Assume no collision. This can happen if the shapes touch in 1 point (or plane) in which case the hull is degenerate.
229 return false;
230 }
231 }
232 }
233
234#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
235 hull.DrawLabel("Complete hull");
236
237 // Generate the hull of the Minkowski difference for visualization
238 MinkowskiDifference diff(inAIncludingConvexRadius, inBIncludingConvexRadius);
239 DebugRenderer::GeometryRef geometry = DebugRenderer::sInstance->CreateTriangleGeometryForConvex([&diff](Vec3Arg inDirection) { return diff.GetSupport(inDirection); });
240 hull.DrawGeometry(geometry, Color::sYellow);
241
242 hull.DrawLabel("Ensure origin in hull");
243#endif
244
245 // Loop until we are sure that the origin is inside the hull
246 for (;;)
247 {
248 // Get the next closest triangle
250
251 // 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)
252 if (t->mRemoved)
253 {
255
256 // 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.
257 if (!hull.HasNextTriangle())
258 return false;
259
260 hull.FreeTriangle(t);
261 continue;
262 }
263
264 // If the closest to the triangle is zero or positive, the origin is in the hull and we can proceed to the main algorithm
265 if (t->mClosestLenSq >= 0.0f)
266 break;
267
268#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
269 hull.DrawLabel("Next iteration");
270#endif
271#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
272 Trace("EncapsulateOrigin: verts = (%d, %d, %d), closest_dist_sq = %g, centroid = (%g, %g, %g), normal = (%g, %g, %g)",
273 t->mEdge[0].mStartIdx, t->mEdge[1].mStartIdx, t->mEdge[2].mStartIdx,
274 t->mClosestLenSq,
275 t->mCentroid.GetX(), t->mCentroid.GetY(), t->mCentroid.GetZ(),
276 t->mNormal.GetX(), t->mNormal.GetY(), t->mNormal.GetZ());
277#endif
278
279 // 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)
281
282 // Add a support point to get the origin inside the hull
283 int new_index;
284 Vec3 w = support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, t->mNormal, new_index);
285
286#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
287 // Draw the point that we're adding
288 hull.DrawMarker(w, Color::sRed, 1.0f);
289 hull.DrawWireTriangle(*t, Color::sRed);
290 hull.DrawState();
291#endif
292
293 // Add the point to the hull, if we fail we terminate and report no collision
295 if (!t->IsFacing(w) || !hull.AddPoint(t, new_index, FLT_MAX, new_triangles))
296 return false;
297
298 // The triangle is facing the support point "w" and can now be safely removed
300 hull.FreeTriangle(t);
301
302 // 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.
303 if (!hull.HasNextTriangle() || support_points.mY.size() >= cMaxPointsToIncludeOriginInHull)
304 return false;
305 }
306
307#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
308 hull.DrawLabel("Main algorithm");
309#endif
310
311 // Current closest distance to origin
312 float closest_dist_sq = FLT_MAX;
313
314 // Remember last good triangle
315 Triangle *last = nullptr;
316
317 // If we want to flip the penetration depth
318 bool flip_v_sign = false;
319
320 // Loop until closest point found
321 do
322 {
323 // Get closest triangle to the origin
325
326 // 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)
327 if (t->mRemoved)
328 {
329 hull.FreeTriangle(t);
330 continue;
331 }
332
333#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
334 hull.DrawLabel("Next iteration");
335#endif
336#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
337 Trace("FindClosest: verts = (%d, %d, %d), closest_len_sq = %g, centroid = (%g, %g, %g), normal = (%g, %g, %g)",
338 t->mEdge[0].mStartIdx, t->mEdge[1].mStartIdx, t->mEdge[2].mStartIdx,
339 t->mClosestLenSq,
340 t->mCentroid.GetX(), t->mCentroid.GetY(), t->mCentroid.GetZ(),
341 t->mNormal.GetX(), t->mNormal.GetY(), t->mNormal.GetZ());
342#endif
343 // Check if next triangle is further away than closest point, we've found the closest point
344 if (t->mClosestLenSq >= closest_dist_sq)
345 break;
346
347 // Replace last good with this triangle
348 if (last != nullptr)
349 hull.FreeTriangle(last);
350 last = t;
351
352 // Add support point in direction of normal of the plane
353 // 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)
354 // and this way we do less calculations and lose less precision
355 int new_index;
356 Vec3 w = support_points.Add(inAIncludingConvexRadius, inBIncludingConvexRadius, t->mNormal, new_index);
357
358 // Project w onto the triangle normal
359 float dot = t->mNormal.Dot(w);
360
361 // Check if we just found a separating axis. This can happen if the shape shrunk by convex radius and then expanded by
362 // convex radius is bigger then the original shape due to inaccuracies in the shrinking process.
363 if (dot < 0.0f)
364 return false;
365
366 // Get the distance squared (along normal) to the support point
367 float dist_sq = Square(dot) / t->mNormal.LengthSq();
368
369#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
370 Trace("FindClosest: w = (%g, %g, %g), dot = %g, dist_sq = %g",
371 w.GetX(), w.GetY(), w.GetZ(),
372 dot, dist_sq);
373#endif
374#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
375 // Draw the point that we're adding
376 hull.DrawMarker(w, Color::sPurple, 1.0f);
377 hull.DrawWireTriangle(*t, Color::sPurple);
378 hull.DrawState();
379#endif
380
381 // If the error became small enough, we've converged
382 if (dist_sq - t->mClosestLenSq < t->mClosestLenSq * inTolerance)
383 {
384#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
385 Trace("Converged");
386#endif // JPH_EPA_PENETRATION_DEPTH_DEBUG
387 break;
388 }
389
390 // Keep track of the minimum distance
391 closest_dist_sq = min(closest_dist_sq, dist_sq);
392
393 // If the triangle thinks this point is not front facing, we've reached numerical precision and we're done
394 if (!t->IsFacing(w))
395 {
396#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
397 Trace("Not facing triangle");
398#endif // JPH_EPA_PENETRATION_DEPTH_DEBUG
399 break;
400 }
401
402 // Add point to hull
404 if (!hull.AddPoint(t, new_index, closest_dist_sq, new_triangles))
405 {
406#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
407 Trace("Could not add point");
408#endif // JPH_EPA_PENETRATION_DEPTH_DEBUG
409 break;
410 }
411
412 // If the hull is starting to form defects then we're reaching numerical precision and we have to stop
413 bool has_defect = false;
414 for (const Triangle *nt : new_triangles)
415 if (nt->IsFacingOrigin())
416 {
417 has_defect = true;
418 break;
419 }
420 if (has_defect)
421 {
422#ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG
423 Trace("Has defect");
424#endif // JPH_EPA_PENETRATION_DEPTH_DEBUG
425 // When the hull has defects it is possible that the origin has been classified on the wrong side of the triangle
426 // so we do an additional check to see if the penetration in the -triangle normal direction is smaller than
427 // the penetration in the triangle normal direction. If so we must flip the sign of the penetration depth.
428 Vec3 w2 = inAIncludingConvexRadius.GetSupport(-t->mNormal) - inBIncludingConvexRadius.GetSupport(t->mNormal);
429 float dot2 = -t->mNormal.Dot(w2);
430 if (dot2 < dot)
431 flip_v_sign = true;
432 break;
433 }
434 }
435 while (hull.HasNextTriangle() && support_points.mY.size() < cMaxPoints);
436
437 // Determine closest points, if last == null it means the hull was a plane so there's no penetration
438 if (last == nullptr)
439 return false;
440
441#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
442 hull.DrawLabel("Closest found");
443 hull.DrawWireTriangle(*last, Color::sWhite);
444 hull.DrawArrow(last->mCentroid, last->mCentroid + last->mNormal.NormalizedOr(Vec3::sZero()), Color::sWhite, 0.1f);
445 hull.DrawState();
446#endif
447
448 // Calculate penetration by getting the vector from the origin to the closest point on the triangle:
449 // distance = (centroid - origin) . normal / |normal|, closest = origin + distance * normal / |normal|
450 outV = (last->mCentroid.Dot(last->mNormal) / last->mNormal.LengthSq()) * last->mNormal;
451
452 // If penetration is near zero, treat this as a non collision since we cannot find a good normal
453 if (outV.IsNearZero())
454 return false;
455
456 // Check if we have to flip the sign of the penetration depth
457 if (flip_v_sign)
458 outV = -outV;
459
460 // Use the barycentric coordinates for the closest point to the origin to find the contact points on A and B
461 Vec3 p0 = support_points.mP[last->mEdge[0].mStartIdx];
462 Vec3 p1 = support_points.mP[last->mEdge[1].mStartIdx];
463 Vec3 p2 = support_points.mP[last->mEdge[2].mStartIdx];
464
465 Vec3 q0 = support_points.mQ[last->mEdge[0].mStartIdx];
466 Vec3 q1 = support_points.mQ[last->mEdge[1].mStartIdx];
467 Vec3 q2 = support_points.mQ[last->mEdge[2].mStartIdx];
468
469 if (last->mLambdaRelativeTo0)
470 {
471 // y0 was the reference vertex
472 outPointA = p0 + last->mLambda[0] * (p1 - p0) + last->mLambda[1] * (p2 - p0);
473 outPointB = q0 + last->mLambda[0] * (q1 - q0) + last->mLambda[1] * (q2 - q0);
474 }
475 else
476 {
477 // y1 was the reference vertex
478 outPointA = p1 + last->mLambda[0] * (p0 - p1) + last->mLambda[1] * (p2 - p1);
479 outPointB = q1 + last->mLambda[0] * (q0 - q1) + last->mLambda[1] * (q2 - q1);
480 }
481
482 return true;
483 }
484
488 template <typename AE, typename AI, typename BE, typename BI>
489 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)
490 {
491 // Check result of collision detection
492 switch (GetPenetrationDepthStepGJK(inAExcludingConvexRadius, inConvexRadiusA, inBExcludingConvexRadius, inConvexRadiusB, inCollisionToleranceSq, ioV, outPointA, outPointB))
493 {
495 return true;
496
498 return false;
499
501 return GetPenetrationDepthStepEPA(inAIncludingConvexRadius, inBIncludingConvexRadius, inPenetrationTolerance, ioV, outPointA, outPointB);
502 }
503
504 JPH_ASSERT(false);
505 return false;
506 }
507
525 template <typename A, typename B>
526 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)
527 {
528 JPH_IF_ENABLE_ASSERTS(mGJKTolerance = inCollisionTolerance;)
529
530 // First determine if there's a collision at all
531 if (!mGJK.CastShape(inStart, inDirection, inCollisionTolerance, inA, inB, inConvexRadiusA, inConvexRadiusB, ioLambda, outPointA, outPointB, outContactNormal))
532 return false;
533
534 // When our contact normal is too small, we don't have an accurate result
535 bool contact_normal_invalid = outContactNormal.IsNearZero(Square(inCollisionTolerance));
536
537 if (inReturnDeepestPoint
538 && ioLambda == 0.0f // Only when lambda = 0 we can have the bodies overlap
539 && (inConvexRadiusA + inConvexRadiusB == 0.0f // When no convex radius was provided we can never trust contact points at lambda = 0
540 || contact_normal_invalid))
541 {
542 // If we're initially intersecting, we need to run the EPA algorithm in order to find the deepest contact point
543 AddConvexRadius<A> add_convex_a(inA, inConvexRadiusA);
544 AddConvexRadius<B> add_convex_b(inB, inConvexRadiusB);
545 TransformedConvexObject<AddConvexRadius<A>> transformed_a(inStart, add_convex_a);
546 if (!GetPenetrationDepthStepEPA(transformed_a, add_convex_b, inPenetrationTolerance, outContactNormal, outPointA, outPointB))
547 return false;
548 }
549 else if (contact_normal_invalid)
550 {
551 // If we weren't able to calculate a contact normal, use the cast direction instead
552 outContactNormal = inDirection;
553 }
554
555 return true;
556 }
557};
558
unsigned int uint
Definition Core.h:481
#define JPH_NAMESPACE_END
Definition Core.h:414
#define JPH_NAMESPACE_BEGIN
Definition Core.h:408
TraceFunction Trace
Definition IssueReporting.cpp:14
#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:55
JPH_INLINE constexpr float DegreesToRadians(float inV)
Convert a value from degrees to radians.
Definition Math.h:16
#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:698
static DebugRenderer * sInstance
Singleton instance.
Definition DebugRenderer.h:179
int mStartIdx
Vertex index in mPositions that indicates the start vertex of this edge.
Definition EPAConvexHullBuilder.h:55
Specialized points list that allows direct access to the size.
Definition EPAConvexHullBuilder.h:173
Class that holds the information of one triangle.
Definition EPAConvexHullBuilder.h:63
Vec3 mCentroid
Center of the triangle.
Definition EPAConvexHullBuilder.h:90
bool IsFacing(Vec3Arg inPosition) const
Check if triangle is facing inPosition.
Definition EPAConvexHullBuilder.h:69
Vec3 mNormal
Normal of this triangle, length is 2 times area of triangle.
Definition EPAConvexHullBuilder.h:89
Edge mEdge[3]
3 edges of this triangle
Definition EPAConvexHullBuilder.h:88
float mClosestLenSq
Closest distance^2 from origin to triangle.
Definition EPAConvexHullBuilder.h:91
float mLambda[2]
Barycentric coordinates of closest point to origin on triangle.
Definition EPAConvexHullBuilder.h:92
bool mLambdaRelativeTo0
How to calculate the closest point, true: y0 + l0 * (y1 - y0) + l1 * (y2 - y0), false: y1 + l0 * (y0 ...
Definition EPAConvexHullBuilder.h:93
bool mRemoved
Flag that indicates that triangle has been removed.
Definition EPAConvexHullBuilder.h:95
A convex hull builder specifically made for the EPA penetration depth calculation....
Definition EPAConvexHullBuilder.h:25
Triangle * PeekClosestTriangleInQueue()
Access to the next closest triangle to the origin (won't remove it from the queue).
Definition EPAConvexHullBuilder.h:268
bool HasNextTriangle() const
Check if there's another triangle to process from the queue.
Definition EPAConvexHullBuilder.h:262
static constexpr int cMaxPoints
Max number of points in hull.
Definition EPAConvexHullBuilder.h:37
Triangle * PopClosestTriangleFromQueue()
Access to the next closest triangle to the origin and remove it from the queue.
Definition EPAConvexHullBuilder.h:274
void FreeTriangle(Triangle *inT)
Free a triangle.
Definition EPAConvexHullBuilder.h:366
Triangle * FindFacingTriangle(Vec3Arg inPosition, float &outBestDistSq)
Definition EPAConvexHullBuilder.h:281
void Initialize(int inIdx1, int inIdx2, int inIdx3)
Initialize the hull with 3 points.
Definition EPAConvexHullBuilder.h:234
bool AddPoint(Triangle *inFacingTriangle, int inIdx, float inClosestDistSq, NewTriangles &outTriangles)
Add a new point to the convex hull.
Definition EPAConvexHullBuilder.h:306
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:526
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:489
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:151
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:822
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:103
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