15#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
26#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
28 static constexpr Real cDrawScale = 10;
65 inline Triangle(
int inIdx0,
int inIdx1,
int inIdx2,
const Vec3 *inPositions);
84 return mEdge[(inIndex + 1) % 3];
96#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
106 union alignas(Triangle) Block
113 Block mTriangles[cMaxTriangles];
114 Block * mNextFree =
nullptr;
115 int mHighWatermark = 0;
129 if (mNextFree !=
nullptr)
132 t =
reinterpret_cast<Triangle *
>(&mNextFree->mTriangle);
133 mNextFree = mNextFree->mNextFree;
138 if (mHighWatermark >= cMaxTriangles)
140 t =
reinterpret_cast<Triangle *
>(&mTriangles[mHighWatermark].mTriangle);
145 new (t)
Triangle(inIdx0, inIdx1, inIdx2, inPositions);
156 memset(inT, 0xcd,
sizeof(
Triangle));
160 Block *tu =
reinterpret_cast<Block *
>(inT);
161 tu->mNextFree = mNextFree;
194 Triangles::push_back(inT);
200 std::push_heap(begin(), end(), sTriangleSorter);
213 std::pop_heap(begin(), end(), sTriangleSorter);
224 mPositions(inPositions)
226#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
243 sLinkTriangle(t1, 0, t2, 2);
244 sLinkTriangle(t1, 1, t2, 1);
245 sLinkTriangle(t1, 2, t2, 0);
248 mTriangleQueue.push_back(t1);
249 mTriangleQueue.push_back(t2);
251#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
263 return !mTriangleQueue.empty();
269 return mTriangleQueue.PeekClosest();
275 return mTriangleQueue.PopClosest();
283 float best_dist_sq = 0.0f;
288 float dot = t->
mNormal.
Dot(inPosition - t->mCentroid);
291 float dist_sq = dot * dot / t->mNormal.LengthSq();
292 if (dist_sq > best_dist_sq)
295 best_dist_sq = dist_sq;
300 outBestDistSq = best_dist_sq;
308 Vec3 pos = mPositions[inIdx];
310#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
315#ifdef JPH_EPA_CONVEX_BUILDER_VALIDATE
322 if (!FindEdge(inFacingTriangle, pos, edges))
326 int num_edges = edges.
size();
327 for (
int i = 0; i < num_edges; ++i)
338 mTriangleQueue.push_back(nt);
342 for (
int i = 0; i < num_edges; ++i)
344 sLinkTriangle(outTriangles[i], 0, edges[i].mNeighbourTriangle, edges[i].mNeighbourEdge);
345 sLinkTriangle(outTriangles[i], 1, outTriangles[(i + 1) % num_edges], 2);
348#ifdef JPH_EPA_CONVEX_BUILDER_VALIDATE
353#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
367#ifdef JPH_ENABLE_ASSERTS
374#if defined(JPH_EPA_CONVEX_BUILDER_VALIDATE) || defined(JPH_EPA_CONVEX_BUILDER_DRAW)
381 mFactory.FreeTriangle(inT);
389 Triangle *t = mFactory.CreateTriangle(inIdx1, inIdx2, inIdx3, mPositions.data());
393#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
395 t->mIteration = mIteration;
398#if defined(JPH_EPA_CONVEX_BUILDER_VALIDATE) || defined(JPH_EPA_CONVEX_BUILDER_DRAW)
400 mTriangles.push_back(t);
407 static void sLinkTriangle(
Triangle *inT1,
int inEdge1,
Triangle *inT2,
int inEdge2)
411 Edge &e1 = inT1->mEdge[inEdge1];
412 Edge &e2 = inT2->mEdge[inEdge2];
419 JPH_ASSERT(e1.mStartIdx == inT2->GetNextEdge(inEdge2).mStartIdx);
420 JPH_ASSERT(e2.mStartIdx == inT1->GetNextEdge(inEdge1).mStartIdx);
423 e1.mNeighbourTriangle = inT2;
424 e1.mNeighbourEdge = inEdge2;
425 e2.mNeighbourTriangle = inT1;
426 e2.mNeighbourEdge = inEdge1;
433 for (
int i = 0; i < 3; ++i)
435 Edge &edge = inT->mEdge[i];
436 if (edge.mNeighbourTriangle !=
nullptr)
438 Edge &neighbour_edge = edge.mNeighbourTriangle->mEdge[edge.mNeighbourEdge];
441 JPH_ASSERT(neighbour_edge.mNeighbourTriangle == inT);
442 JPH_ASSERT(neighbour_edge.mNeighbourEdge == i);
445 neighbour_edge.mNeighbourTriangle =
nullptr;
446 edge.mNeighbourTriangle =
nullptr;
463 JPH_ASSERT(inFacingTriangle->IsFacing(inVertex));
466 inFacingTriangle->mRemoved =
true;
476 int cur_stack_pos = 0;
479 stack[0].mTriangle = inFacingTriangle;
484 int next_expected_start_idx = -1;
488 StackEntry &cur_entry = stack[cur_stack_pos];
491 if (++cur_entry.mIter >= 3)
494 UnlinkTriangle(cur_entry.mTriangle);
497 if (--cur_stack_pos < 0)
503 Edge &e = cur_entry.mTriangle->mEdge[(cur_entry.mEdge + cur_entry.mIter) % 3];
505 if (n !=
nullptr && !n->mRemoved)
508 if (n->IsFacing(inVertex))
516 StackEntry &new_entry = stack[cur_stack_pos];
517 new_entry.mTriangle = n;
518 new_entry.mEdge = e.mNeighbourEdge;
529 if (e.mStartIdx != next_expected_start_idx && next_expected_start_idx != -1)
533 next_expected_start_idx = n->mEdge[e.mNeighbourEdge].mStartIdx;
536 outEdges.push_back(e);
543 JPH_ASSERT(outEdges.empty() || outEdges[0].mStartIdx == next_expected_start_idx);
545#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
547 for (
int i = 0; i < (int)outEdges.size(); ++i)
549 RVec3 edge_start = cDrawScale * (mOffset + mPositions[outEdges[i].mStartIdx]);
561 return outEdges.size() >= 3;
564#ifdef JPH_EPA_CONVEX_BUILDER_VALIDATE
566 void ValidateTriangle(
const Triangle *inT)
const
571 for (
const Edge &my_edge : inT->mEdge)
572 JPH_ASSERT(my_edge.mNeighbourTriangle ==
nullptr);
576 for (
int i = 0; i < 3; ++i)
578 const Edge &my_edge = inT->mEdge[i];
581 const Triangle *nb = my_edge.mNeighbourTriangle;
587 const Edge &nb_edge = nb->mEdge[my_edge.mNeighbourEdge];
588 JPH_ASSERT(nb_edge.mNeighbourTriangle == inT);
592 const Edge &nb_next_edge = nb->GetNextEdge(my_edge.mNeighbourEdge);
593 JPH_ASSERT(nb_next_edge.mStartIdx == my_edge.mStartIdx);
596 const Edge &my_next_edge = inT->GetNextEdge(i);
597 JPH_ASSERT(my_next_edge.mStartIdx == nb_edge.mStartIdx);
604 void ValidateTriangles()
const
606 for (
const Triangle *t : mTriangles)
611#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
620 for (
const Triangle *t : mTriangles)
624 RVec3 p1 = cDrawScale * (mOffset + mPositions[t->mEdge[0].mStartIdx]);
625 RVec3 p2 = cDrawScale * (mOffset + mPositions[t->mEdge[1].mStartIdx]);
626 RVec3 p3 = cDrawScale * (mOffset + mPositions[t->mEdge[2].mStartIdx]);
633 RVec3 centroid = cDrawScale * (mOffset + t->mCentroid);
634 float len = t->mNormal.Length();
640 float min_x = FLT_MAX;
641 float max_x = -FLT_MAX;
642 for (
Vec3 p : mPositions)
644 min_x = min(min_x, p.GetX());
645 max_x = max(max_x, p.GetX());
649 mOffset +=
Vec3(max_x - min_x + 0.5f, 0.0f, 0.0f);
653 void DrawLabel(
const string_view &inText)
657 mOffset +=
Vec3(5.0f, 0.0f, 0.0f);
666 mOffset +=
Vec3(inGeometry->mBounds.GetSize().GetX(), 0, 0);
672 RVec3 prev = cDrawScale * (mOffset + mPositions[inTriangle.mEdge[2].mStartIdx]);
673 for (
const Edge &edge : inTriangle.mEdge)
675 RVec3 cur = cDrawScale * (mOffset + mPositions[edge.mStartIdx]);
695 TriangleFactory mFactory;
696 const Points & mPositions;
697 TriangleQueue mTriangleQueue;
699#if defined(JPH_EPA_CONVEX_BUILDER_VALIDATE) || defined(JPH_EPA_CONVEX_BUILDER_DRAW)
703#ifdef JPH_EPA_CONVEX_BUILDER_DRAW
716 JPH_ASSERT(inIdx0 != inIdx1 && inIdx0 != inIdx2 && inIdx1 != inIdx2);
717 mEdge[0].mStartIdx = inIdx0;
718 mEdge[1].mStartIdx = inIdx1;
719 mEdge[2].mStartIdx = inIdx2;
722 mEdge[0].mNeighbourTriangle =
nullptr;
723 mEdge[1].mNeighbourTriangle =
nullptr;
724 mEdge[2].mNeighbourTriangle =
nullptr;
727 Vec3 y0 = inPositions[inIdx0];
728 Vec3 y1 = inPositions[inIdx1];
729 Vec3 y2 = inPositions[inIdx2];
732 mCentroid = (y0 + y1 + y2) / 3.0f;
744 float y20_dot_y20 = y20.
Dot(y20);
745 float y21_dot_y21 = y21.
Dot(y21);
746 if (y20_dot_y20 < y21_dot_y21)
749 mNormal = y10.
Cross(y20);
752 float normal_len_sq = mNormal.
LengthSq();
758 float c_dot_n = mCentroid.Dot(mNormal);
759 mClosestLenSq = abs(c_dot_n) * c_dot_n / normal_len_sq;
776 float y10_dot_y20 = y10.
Dot(y20);
777 float determinant = y10_dot_y10 * y20_dot_y20 - y10_dot_y20 * y10_dot_y20;
778 if (determinant > 0.0f)
780 float y0_dot_y10 = y0.
Dot(y10);
781 float y0_dot_y20 = y0.
Dot(y20);
782 float l0 = (y10_dot_y20 * y0_dot_y20 - y20_dot_y20 * y0_dot_y10) / determinant;
783 float l1 = (y10_dot_y20 * y0_dot_y10 - y10_dot_y10 * y0_dot_y20) / determinant;
786 mLambdaRelativeTo0 =
true;
792 mClosestPointInterior =
true;
799 mNormal = y10.
Cross(y21);
802 float normal_len_sq = mNormal.
LengthSq();
806 float c_dot_n = mCentroid.Dot(mNormal);
807 mClosestLenSq = abs(c_dot_n) * c_dot_n / normal_len_sq;
822 float y10_dot_y21 = y10.
Dot(y21);
823 float determinant = y10_dot_y10 * y21_dot_y21 - y10_dot_y21 * y10_dot_y21;
824 if (determinant > 0.0f)
826 float y1_dot_y10 = y1.
Dot(y10);
827 float y1_dot_y21 = y1.
Dot(y21);
828 float l0 = (y21_dot_y21 * y1_dot_y10 - y10_dot_y21 * y1_dot_y21) / determinant;
829 float l1 = (y10_dot_y21 * y1_dot_y10 - y10_dot_y10 * y1_dot_y21) / determinant;
832 mLambdaRelativeTo0 =
false;
836 mClosestPointInterior =
true;
std::uint8_t uint8
Definition: Core.h:453
#define JPH_NAMESPACE_END
Definition: Core.h:378
#define JPH_NAMESPACE_BEGIN
Definition: Core.h:372
#define JPH_ASSERT(...)
Definition: IssueReporting.h:33
float Real
Definition: Real.h:27
Class that holds an RGBA color with 8-bits per component.
Definition: Color.h:16
static const Color sWhite
Definition: Color.h:67
static Color sGetDistinctColor(int inIndex)
Get a visually distinct color.
Definition: Color.cpp:31
static const Color sDarkGreen
Definition: Color.h:56
static const Color sGrey
Definition: Color.h:65
static const Color sYellow
Definition: Color.h:60
virtual void DrawText3D(RVec3Arg inPosition, const string_view &inString, ColorArg inColor=Color::sWhite, float inHeight=0.5f)=0
Draw text.
void DrawMarker(RVec3Arg inPosition, ColorArg inColor, float inSize)
Draw a marker on a position.
Definition: DebugRenderer.cpp:172
void DrawWireTriangle(RVec3Arg inV1, RVec3Arg inV2, RVec3Arg inV3, ColorArg inColor)
Draw wireframe triangle.
Definition: DebugRenderer.cpp:242
void DrawCoordinateSystem(RMat44Arg inTransform, float inSize=1.0f)
Draw coordinate system (3 arrows, x = red, y = green, z = blue)
Definition: DebugRenderer.cpp:206
virtual void DrawGeometry(RMat44Arg inModelMatrix, const AABox &inWorldSpaceBounds, float inLODScaleSq, ColorArg inModelColor, const GeometryRef &inGeometry, ECullMode inCullMode=ECullMode::CullBackFace, ECastShadow inCastShadow=ECastShadow::On, EDrawMode inDrawMode=EDrawMode::Solid)=0
static DebugRenderer * sInstance
Singleton instance.
Definition: DebugRenderer.h:168
void DrawArrow(RVec3Arg inFrom, RVec3Arg inTo, ColorArg inColor, float inSize)
Draw an arrow.
Definition: DebugRenderer.cpp:184
virtual void DrawTriangle(RVec3Arg inV1, RVec3Arg inV2, RVec3Arg inV3, ColorArg inColor, ECastShadow inCastShadow=ECastShadow::Off)=0
Draw a single back face culled triangle.
Class that holds the information of an edge.
Definition: EPAConvexHullBuilder.h:48
int mStartIdx
Vertex index in mPositions that indicates the start vertex of this edge.
Definition: EPAConvexHullBuilder.h:54
Triangle * mNeighbourTriangle
Information about neighbouring triangle.
Definition: EPAConvexHullBuilder.h:51
int mNeighbourEdge
Index in mEdge that specifies edge that this Edge is connected to.
Definition: EPAConvexHullBuilder.h:52
Specialized points list that allows direct access to the size.
Definition: EPAConvexHullBuilder.h:172
size_type & GetSizeRef()
Definition: EPAConvexHullBuilder.h:174
Factory that creates triangles in a fixed size buffer.
Definition: EPAConvexHullBuilder.h:103
Triangle * CreateTriangle(int inIdx0, int inIdx1, int inIdx2, const Vec3 *inPositions)
Allocate a new triangle with 3 indexes.
Definition: EPAConvexHullBuilder.h:126
void FreeTriangle(Triangle *inT)
Free a triangle.
Definition: EPAConvexHullBuilder.h:151
void Clear()
Return all triangles to the free pool.
Definition: EPAConvexHullBuilder.h:119
Class that holds the information of one triangle.
Definition: EPAConvexHullBuilder.h:62
Vec3 mCentroid
Center of the triangle.
Definition: EPAConvexHullBuilder.h:89
bool mClosestPointInterior
Flag that indicates that the closest point from this triangle to the origin is an interior point.
Definition: EPAConvexHullBuilder.h:93
bool IsFacing(Vec3Arg inPosition) const
Check if triangle is facing inPosition.
Definition: EPAConvexHullBuilder.h:68
const Edge & GetNextEdge(int inIndex) const
Get the next edge of edge inIndex.
Definition: EPAConvexHullBuilder.h:82
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
bool IsFacingOrigin() const
Check if triangle is facing the origin.
Definition: EPAConvexHullBuilder.h:75
float mClosestLenSq
Closest distance^2 from origin to triangle.
Definition: EPAConvexHullBuilder.h:90
Triangle(int inIdx0, int inIdx1, int inIdx2, const Vec3 *inPositions)
Constructor.
Definition: EPAConvexHullBuilder.h:713
bool mInQueue
Flag that indicates that this triangle was placed in the sorted heap (stays true after it is popped b...
Definition: EPAConvexHullBuilder.h:95
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
Specialized triangles list that keeps them sorted on closest distance to origin.
Definition: EPAConvexHullBuilder.h:182
void push_back(Triangle *inT)
Add triangle to the list.
Definition: EPAConvexHullBuilder.h:191
Triangle * PeekClosest()
Peek the next closest triangle without removing it.
Definition: EPAConvexHullBuilder.h:204
Triangle * PopClosest()
Get next closest triangle.
Definition: EPAConvexHullBuilder.h:210
static bool sTriangleSorter(const Triangle *inT1, const Triangle *inT2)
Function to sort triangles on closest distance to origin.
Definition: EPAConvexHullBuilder.h:185
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 cMaxTriangles
Max triangles in hull.
Definition: EPAConvexHullBuilder.h:35
StaticArray< Edge, cMaxEdgeLength > Edges
Definition: EPAConvexHullBuilder.h:57
static constexpr float cMinTriangleArea
Minimum area of a triangle before, if smaller than this it will not be added to the priority queue.
Definition: EPAConvexHullBuilder.h:40
static constexpr float cBarycentricEpsilon
Epsilon value used to determine if a point is in the interior of a triangle.
Definition: EPAConvexHullBuilder.h:41
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
static constexpr int cMaxEdgeLength
Max number of edges in FindEdge.
Definition: EPAConvexHullBuilder.h:39
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
EPAConvexHullBuilder(const Points &inPositions)
Constructor.
Definition: EPAConvexHullBuilder.h:223
StaticArray< Triangle *, cMaxTriangles > Triangles
Definition: EPAConvexHullBuilder.h:168
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 sScale(float inScale)
Get matrix that scales uniformly.
Definition: Mat44.inl:163
static JPH_INLINE Mat44 sTranslation(Vec3Arg inV)
Get matrix that translates.
Definition: Mat44.inl:144
Class that makes another class non-copyable. Usage: Inherit from NonCopyable.
Definition: NonCopyable.h:11
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
T * iterator
Definition: StaticArray.h:126
uint size_type
Definition: StaticArray.h:18
size_type size() const
Returns amount of elements in the array.
Definition: StaticArray.h:89
A simple triangle and its material.
Definition: Triangle.h:11
JPH_INLINE float Dot(Vec3Arg inV2) const
Dot product.
Definition: Vec3.inl:645
JPH_INLINE Vec3 Cross(Vec3Arg inV2) const
Cross product.
Definition: Vec3.inl:590
JPH_INLINE float LengthSq() const
Squared length of vector.
Definition: Vec3.inl:661
static JPH_INLINE Vec3 sZero()
Vector with all zeros.
Definition: Vec3.inl:107
static JPH_INLINE Vec3 sReplicate(float inV)
Replicate inV across all components.
Definition: Vec3.inl:118