2
0
Эх сурвалжийг харах

Supporting smaller convex hulls in the ConvexHullBuilder

Jorrit Rouwe 3 жил өмнө
parent
commit
ccc2d9a287

+ 4 - 4
Jolt/Geometry/ConvexHullBuilder.cpp

@@ -304,7 +304,7 @@ ConvexHullBuilder::EResult ConvexHullBuilder::Initialize(int inMaxVertices, floa
 			}
 		}
 	JPH_ASSERT(idx3 >= 0);
-	if (best_triangle_area_sq < FLT_EPSILON)
+	if (best_triangle_area_sq < cMinTriangleAreaSq)
 	{
 		outError = "Could not find a suitable initial triangle because its area was too small";
 		return EResult::Degenerate;
@@ -554,7 +554,7 @@ void ConvexHullBuilder::AddPoint(Face *inFacingFace, int inIdx, float inCoplanar
 		if (!face->mRemoved)
 		{
 			// Merge with neighbour if this is a degenerate face
-			MergeDegenerateFace(face, 1.0e-12f, affected_faces);
+			MergeDegenerateFace(face, affected_faces);
 
 			// Merge with coplanar neighbours (or when the neighbour forms a concave edge)
 			if (!face->mRemoved)
@@ -827,10 +827,10 @@ void ConvexHullBuilder::MergeFaces(Edge *inEdge)
 #endif
 }
 
-void ConvexHullBuilder::MergeDegenerateFace(Face *inFace, float inMinAreaSq, Faces &ioAffectedFaces)
+void ConvexHullBuilder::MergeDegenerateFace(Face *inFace, Faces &ioAffectedFaces)
 {
 	// Check area of face
-	if (inFace->mNormal.LengthSq() < inMinAreaSq)
+	if (inFace->mNormal.LengthSq() < cMinTriangleAreaSq)
 	{
 		// Find longest edge, since this face is a sliver this should keep the face convex
 		float max_length_sq = 0.0f;

+ 4 - 1
Jolt/Geometry/ConvexHullBuilder.h

@@ -124,6 +124,9 @@ public:
 	const Faces &		GetFaces() const					{ return mFaces; }
 
 private:
+	/// Minimal square area of a triangle (used for merging and checking if a triangle is degenerate)
+	static constexpr float cMinTriangleAreaSq = 1.0e-12f;
+
 #ifdef JPH_CONVEX_BUILDER_DEBUG
 	/// Factor to scale convex hull when debug drawing the construction process
 	static constexpr float cDrawScale = 10.0f;
@@ -181,7 +184,7 @@ private:
 	void				MergeFaces(Edge *inEdge);
 
 	/// Merges inFace with a neighbour if it is degenerate (a sliver)
-	void				MergeDegenerateFace(Face *inFace, float inMinAreaSq, Faces &ioAffectedFaces);
+	void				MergeDegenerateFace(Face *inFace, Faces &ioAffectedFaces);
 
 	/// Merges any coplanar as well as neighbours that form a non-convex edge into inFace. 
 	/// Faces are considered coplanar if the distance^2 of the other face's centroid is smaller than inToleranceSq.

+ 19 - 0
Samples/Tests/ConvexCollision/ConvexHullTest.cpp

@@ -357,6 +357,25 @@ void ConvexHullTest::Initialize()
 			Vec3(-0.30392047f, -0.17969127f, 0.22713920f),
 			Vec3(-0.30392047f, -0.17969127f, 0.22713920f),
 			Vec3(-0.30392047f, -0.17969127f, 0.22713920f)
+		},
+		{
+			// A really small hull
+			Vec3(-0.00707678869f, 0.00559568405f, -0.0239779726f),
+			Vec3(0.0136205591f, 0.00541752577f, -0.0225500446f),
+			Vec3(0.0135576781f, 0.00559568405f, -0.0224227905f),
+			Vec3(-0.0108219199f, 0.00559568405f, -0.0223935191f),
+			Vec3(0.0137226451f, 0.00559568405f, -0.0220940933f),
+			Vec3(0.00301175844f, -0.0232942104f, -0.0214947499f),
+			Vec3(0.017349612f, 0.00559568405f, 0.0241708681f),
+			Vec3(0.00390899926f, -0.0368074179f, 0.0541367307f),
+			Vec3(-0.0164459459f, 0.00559568405f, 0.0607497096f),
+			Vec3(-0.0169881769f, 0.00559568405f, 0.0608173609f),
+			Vec3(-0.0168782212f, 0.0052883029f, 0.0613293499f),
+			Vec3(-0.00663783913f, 0.00559568405f, -0.024154868f),
+			Vec3(-0.00507298298f, 0.00559568405f, -0.0242112875f),
+			Vec3(-0.00565947127f, 0.00477081537f, -0.0243848339f),
+			Vec3(0.0118075963f, 0.00124305487f, -0.0258472487f),
+			Vec3(0.00860248506f, -0.00697988272f, -0.0276725553f),
 		}
 	};