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