From 10d037e44c3f6954769e67c32e082e65c40b4050 Mon Sep 17 00:00:00 2001 From: Ross Nordby Date: Sat, 16 Nov 2024 19:23:51 -0600 Subject: [PATCH] More aggressive filtering. --- BepuPhysics/Collidables/ConvexHullHelper.cs | 26 ++++++++++++++------ Demos/SpecializedTests/ConvexHullTestDemo.cs | 2 +- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/BepuPhysics/Collidables/ConvexHullHelper.cs b/BepuPhysics/Collidables/ConvexHullHelper.cs index e5f8267d..54d570c1 100644 --- a/BepuPhysics/Collidables/ConvexHullHelper.cs +++ b/BepuPhysics/Collidables/ConvexHullHelper.cs @@ -497,7 +497,7 @@ static void AddFace(ref QuickList faces, BufferPool pool, Vector3 nor static void AddFaceEdgesToTestList(BufferPool pool, ref QuickList reducedFaceIndices, ref QuickList edgesToTest, - ref QuickSet submittedEdgeTests, + ref QuickDictionary edgeFaceCounts, Vector3 faceNormal, int newFaceIndex) { var previousIndex = reducedFaceIndices[reducedFaceIndices.Count - 1]; @@ -507,14 +507,19 @@ static void AddFaceEdgesToTestList(BufferPool pool, endpoints.A = previousIndex; endpoints.B = reducedFaceIndices[i]; previousIndex = endpoints.B; - if (!submittedEdgeTests.Contains(endpoints)) + if (!edgeFaceCounts.FindOrAllocateSlot(ref endpoints, pool, out var slotIndex)) { EdgeToTest nextEdgeToTest; nextEdgeToTest.Endpoints = endpoints; nextEdgeToTest.FaceNormal = faceNormal; nextEdgeToTest.FaceIndex = newFaceIndex; edgesToTest.Allocate(pool) = nextEdgeToTest; - submittedEdgeTests.Add(endpoints, pool); + edgeFaceCounts.Values[slotIndex] = 1; + } + else + { + //No need to test this edge; it's already been submitted by a different face. + edgeFaceCounts.Values[slotIndex]++; } } } @@ -549,7 +554,7 @@ internal DebugStep(EdgeEndpoints sourceEdge, QuickList rawVertexIndices, Ve BasisY = basisY; Raw = ((Span)rawVertexIndices).ToArray(); Reduced = ((Span)reducedVertexIndices).ToArray(); - OverwrittenOriginal = null; + OverwrittenOriginal = null; FaceIndex = faceIndex; } @@ -566,7 +571,7 @@ internal DebugStep FillHistory(Buffer allowVertex, QuickList fac FaceIndices.Add(face.VertexIndices[j]); FaceNormals[i] = face.Normal; } - AllowVertex = new bool[allowVertex.Length]; + AllowVertex = new bool[allowVertex.Length]; for (int i = 0; i < allowVertex.Length; ++i) { AllowVertex[i] = allowVertex[i] != 0; @@ -729,7 +734,7 @@ public static void ComputeHull(Span points, BufferPool pool, out HullDa var faces = new QuickList(points.Length, pool); var edgesToTest = new QuickList(points.Length, pool); - var submittedEdgeTests = new QuickSet(points.Length, pool); + var edgeFaceCounts = new QuickDictionary(points.Length, pool); if (reducedFaceIndices.Count >= 3) { //The initial face search found an actual face! That's a bit surprising since we didn't start from an edge offset, but rather an arbitrary direction. @@ -768,6 +773,11 @@ public static void ComputeHull(Span points, BufferPool pool, out HullDa while (edgesToTest.Count > 0) { edgesToTest.Pop(out var edgeToTest); + if (edgeFaceCounts.TryGetValue(ref edgeToTest.Endpoints, out var edgeFaceCount) && edgeFaceCount >= 2) + { + //This edge is already part of two faces; no need to test it further. + continue; + } ref var edgeA = ref points[edgeToTest.Endpoints.A]; ref var edgeB = ref points[edgeToTest.Endpoints.B]; @@ -827,7 +837,7 @@ public static void ComputeHull(Span points, BufferPool pool, out HullDa ReduceFace(ref rawFaceVertexIndices, faceNormal, points, planeEpsilonNarrow, ref facePoints, ref allowVertices, ref face.VertexIndices); step.UpdateForFaceMerge(rawFaceVertexIndices, face.VertexIndices, allowVertices, i); mergedFace = true; - + // It's possible for the merged face to have invalidated a previous face that wouldn't necessarily be detected as something to merge. break; } @@ -836,7 +846,7 @@ public static void ComputeHull(Span points, BufferPool pool, out HullDa { var faceCountPriorToAdd = faces.Count; AddFace(ref faces, pool, faceNormal, reducedFaceIndices); - AddFaceEdgesToTestList(pool, ref reducedFaceIndices, ref edgesToTest, ref submittedEdgeTests, faceNormal, faceCountPriorToAdd); + AddFaceEdgesToTestList(pool, ref reducedFaceIndices, ref edgesToTest, ref edgeFaceCounts, faceNormal, faceCountPriorToAdd); } step.FillHistory(allowVertices, faces); steps.Add(step); diff --git a/Demos/SpecializedTests/ConvexHullTestDemo.cs b/Demos/SpecializedTests/ConvexHullTestDemo.cs index 3e7d2572..2d73d9db 100644 --- a/Demos/SpecializedTests/ConvexHullTestDemo.cs +++ b/Demos/SpecializedTests/ConvexHullTestDemo.cs @@ -790,7 +790,7 @@ void DrawFace(DebugStep step, int[] reduced, bool deleted, int i) { var localStep = debugSteps[i]; DrawFace(localStep, localStep.Reduced, false, i); - if (localStep.OverwrittenOriginal != null) + if (showDeleted && localStep.OverwrittenOriginal != null) { DrawFace(localStep, localStep.OverwrittenOriginal, true, i); }