Browse Source

triangulation tests not good...

Vicente Penades 6 years ago
parent
commit
68620a4871

+ 23 - 12
src/SharpGLTF.Toolkit/Geometry/Triangulation.cs

@@ -156,10 +156,6 @@ namespace SharpGLTF.Geometry
         {
             System.Diagnostics.Debug.Assert(outIndices.Length == (inVertices.Length - 2) * 3, $"{nameof(outIndices)} has invalid length");
 
-            // setup source Indices
-            Span<int> tmpIndices = stackalloc int[inIndices.Length];
-            inIndices.CopyTo(tmpIndices);
-
             // define master direction
             var masterDirection = Vector3.Zero;
             for (int i = 2; i < inVertices.Length; ++i)
@@ -169,11 +165,21 @@ namespace SharpGLTF.Geometry
                 masterDirection += Vector3.Cross(ab, ac);
             }
 
+            // setup source Indices
+            Span<int> tmpIndices = stackalloc int[inIndices.Length];
+            inIndices.CopyTo(tmpIndices);
+
             int triIdx = 0;
 
             // begin clipping ears
-            while (tmpIndices.Length > 3)
+            while (true)
             {
+                if (tmpIndices.Length < 3) break;
+
+                PolygonToolkit.SanitizeIndices(inVertices, ref tmpIndices);
+
+                if (tmpIndices.Length < 3) break;
+
                 var tri = _FindEarTriangle(inVertices, tmpIndices, masterDirection);
                 if (tri.Item1 < 0) throw new ArgumentException("failed to triangulate", nameof(inVertices));
 
@@ -187,10 +193,13 @@ namespace SharpGLTF.Geometry
                 PolygonToolkit.RemoveElementAt(ref tmpIndices, tri.Item2);
             }
 
-            // add last triangle.
-            outIndices[triIdx++] = tmpIndices[0];
-            outIndices[triIdx++] = tmpIndices[1];
-            outIndices[triIdx++] = tmpIndices[2];
+            if (tmpIndices.Length >= 3)
+            {
+                // add last triangle.
+                outIndices[triIdx++] = tmpIndices[0];
+                outIndices[triIdx++] = tmpIndices[1];
+                outIndices[triIdx++] = tmpIndices[2];
+            }
 
             System.Diagnostics.Debug.Assert(outIndices.Length == triIdx, $"{nameof(outIndices)} has invalid length");
         }
@@ -209,9 +218,11 @@ namespace SharpGLTF.Geometry
                 var bb = inIndices[b];
                 var cc = inIndices[c];
 
-                var ab = inVertices[bb] - inVertices[aa];
-                var ac = inVertices[cc] - inVertices[aa];
-                var dir = Vector3.Cross(ab, ac);
+                var aaa = inVertices[aa];
+                var bbb = inVertices[bb];
+                var ccc = inVertices[cc];
+
+                var dir = Vector3.Cross(bbb - aaa, ccc - aaa);
 
                 // determine the winding of the ear, and skip it if it's reversed.
                 if (Vector3.Dot(masterDirection, dir) <= 0) continue;

+ 18 - 1
tests/SharpGLTF.Tests/Geometry/TriangulationTests.cs

@@ -66,6 +66,23 @@ namespace SharpGLTF.Geometry
             new Vector2(-4,0),
         };
 
+        
+        private static readonly Vector2[] _SnakePolygon = new[]
+        {
+            new Vector2(0,1),
+            new Vector2(2,3),
+            new Vector2(4,1),
+
+            new Vector2(4,0),
+            new Vector2(2,2),
+            new Vector2(0,0),
+            new Vector2(-2,2),
+            new Vector2(-4,0),
+
+            new Vector2(-4,1),
+            new Vector2(-2,3),
+        };
+
         // this is a pretty messy polygon with lots of degenerated triangles, and holes
         private static readonly Vector2[] _SahaquielPolygon = new[]
         {
@@ -109,7 +126,7 @@ namespace SharpGLTF.Geometry
             var mesh = VERTEX.CreateCompatibleMesh();
             mesh.Triangulator = BasicEarClippingTriangulation.Default;
 
-            var polygon = _PoygonWithHole
+            var polygon = _SnakePolygon
                 .Select(item => new Vector3(item, 0))
                 .ToArray();