Browse Source

trying alternate method for vertex sanitization

Vicente Penades 6 years ago
parent
commit
5f349d43be

+ 10 - 3
src/SharpGLTF.Toolkit/Geometry/PrimitiveBuilder.cs

@@ -145,7 +145,14 @@ namespace SharpGLTF.Geometry
         /// <returns>The index of the vertex.</returns>
         /// <returns>The index of the vertex.</returns>
         public int UseVertex(VertexBuilder<TvG, TvM, TvS> vertex)
         public int UseVertex(VertexBuilder<TvG, TvM, TvS> vertex)
         {
         {
-            if (_Scrict) vertex.Validate();
+            if (_Scrict)
+            {
+                vertex.Validate();
+            }
+            else
+            {
+                if (!vertex.Geometry.SanitizeVertex(out vertex.Geometry)) return -1;
+            }
 
 
             return _Vertices.Use(vertex);
             return _Vertices.Use(vertex);
         }
         }
@@ -174,7 +181,7 @@ namespace SharpGLTF.Geometry
             var bb = UseVertex(b);
             var bb = UseVertex(b);
 
 
             // check for degenerated triangles:
             // check for degenerated triangles:
-            if (aa == bb)
+            if (aa < 0 || bb < 0 || aa == bb)
             {
             {
                 if (_Scrict) throw new ArgumentException($"Invalid triangle indices {aa} {bb}");
                 if (_Scrict) throw new ArgumentException($"Invalid triangle indices {aa} {bb}");
                 return;
                 return;
@@ -201,7 +208,7 @@ namespace SharpGLTF.Geometry
             var cc = UseVertex(c);
             var cc = UseVertex(c);
 
 
             // check for degenerated triangles:
             // check for degenerated triangles:
-            if (aa == bb || aa == cc || bb == cc)
+            if (aa < 0 || bb < 0 || cc < 0 || aa == bb || aa == cc || bb == cc)
             {
             {
                 if (_Scrict) throw new ArgumentException($"Invalid triangle indices {aa} {bb} {cc}");
                 if (_Scrict) throw new ArgumentException($"Invalid triangle indices {aa} {bb} {cc}");
                 return;
                 return;

+ 3 - 3
src/SharpGLTF.Toolkit/Geometry/VertexTypes/VertexGeometry.cs

@@ -95,13 +95,13 @@ namespace SharpGLTF.Geometry.VertexTypes
         public VertexPositionNormal(Vector3 p, Vector3 n)
         public VertexPositionNormal(Vector3 p, Vector3 n)
         {
         {
             this.Position = p;
             this.Position = p;
-            this.Normal = Vector3.Normalize(n);
+            this.Normal = n;
         }
         }
 
 
         public VertexPositionNormal(float px, float py, float pz, float nx, float ny, float nz)
         public VertexPositionNormal(float px, float py, float pz, float nx, float ny, float nz)
         {
         {
             this.Position = new Vector3(px, py, pz);
             this.Position = new Vector3(px, py, pz);
-            this.Normal = Vector3.Normalize(new Vector3(nx, ny, nz));
+            this.Normal = new Vector3(nx, ny, nz);
         }
         }
 
 
         public VertexPositionNormal(IVertexGeometry src)
         public VertexPositionNormal(IVertexGeometry src)
@@ -162,7 +162,7 @@ namespace SharpGLTF.Geometry.VertexTypes
         public VertexPositionNormalTangent(Vector3 p, Vector3 n, Vector4 t)
         public VertexPositionNormalTangent(Vector3 p, Vector3 n, Vector4 t)
         {
         {
             this.Position = p;
             this.Position = p;
-            this.Normal = Vector3.Normalize(n);
+            this.Normal = n;
             this.Tangent = t;
             this.Tangent = t;
         }
         }
 
 

+ 38 - 0
src/SharpGLTF.Toolkit/Geometry/VertexTypes/VertexUtils.cs

@@ -11,6 +11,44 @@ namespace SharpGLTF.Geometry.VertexTypes
 {
 {
     static class VertexUtils
     static class VertexUtils
     {
     {
+        public static bool SanitizeVertex<TvG>(this TvG inVertex, out TvG outVertex)
+            where TvG : struct, IVertexGeometry
+        {
+            outVertex = inVertex;
+
+            var p = inVertex.GetPosition();
+
+            if (!p._IsReal()) return false;
+
+            if (inVertex.TryGetNormal(out Vector3 n))
+            {
+                if (!n._IsReal()) return false;
+                if (n == Vector3.Zero) n = p;
+                if (n == Vector3.Zero) return false;
+
+                var l = n.Length();
+                if (l < 0.99f || l > 0.01f) outVertex.SetNormal(Vector3.Normalize(n));
+            }
+
+            if (inVertex.TryGetTangent(out Vector4 tw))
+            {
+                if (!tw._IsReal()) return false;
+
+                var t = new Vector3(tw.X, tw.Y, tw.Z);
+                if (t == Vector3.Zero) return false;
+
+                if (tw.W > 0) tw.W = 1;
+                if (tw.W < 0) tw.W = -1;
+
+                var l = t.Length();
+                if (l < 0.99f || l > 0.01f) t = Vector3.Normalize(t);
+
+                outVertex.SetTangent(new Vector4(t, tw.W));
+            }
+
+            return true;
+        }
+
         public static IEnumerable<MemoryAccessor[]> CreateVertexMemoryAccessors<TvG, TvM, TvS>(this IEnumerable<IReadOnlyList<VertexBuilder<TvG, TvM, TvS>>> vertexBlocks)
         public static IEnumerable<MemoryAccessor[]> CreateVertexMemoryAccessors<TvG, TvM, TvS>(this IEnumerable<IReadOnlyList<VertexBuilder<TvG, TvM, TvS>>> vertexBlocks)
             where TvG : struct, IVertexGeometry
             where TvG : struct, IVertexGeometry
             where TvM : struct, IVertexMaterial
             where TvM : struct, IVertexMaterial