Browse Source

more improvements on validation...

Vicente Penades 6 years ago
parent
commit
aa0783df63

+ 17 - 1
src/SharpGLTF.Core/Schema2/gltf.Accessors.cs

@@ -341,6 +341,9 @@ namespace SharpGLTF.Schema2
 
             result.CheckSchemaIsDefined("BufferView", _bufferView);
             result.CheckArrayIndexAccess("BufferView", _bufferView, this.LogicalParent.LogicalBufferViews);
+
+            result.CheckSchemaNonNegative("ByteOffset", _byteOffset);
+            result.CheckSchemaIsInRange("Count", _count, _countMinimum, int.MaxValue);
         }
 
         /// <see href="https://github.com/KhronosGroup/glTF-Validator/blob/master/lib/src/base/accessor.dart"/>
@@ -366,12 +369,25 @@ namespace SharpGLTF.Schema2
                 var len = Encoding.ByteLength() * Dimensions.DimCount();
                 result.CheckSchemaIsMultipleOf("Encoding", len, 4);
             }
+
+            if (this.SourceBufferView.ByteStride > 0)
+            {
+                var o = this.ByteOffset - (this.ByteOffset % this.SourceBufferView.ByteStride);
+
+                var accessorByteLen = o + this.SourceBufferView.ByteStride * this.Count;
+
+                if (accessorByteLen > this.SourceBufferView.Content.Count) result.AddLinkError("Count", "exceeds the bounds of BufferView.ByteLength.");
+            }
+
+            ValidateBounds(result);
         }
 
-        internal void ValidateBounds(Validation.ValidationContext result)
+        private void ValidateBounds(Validation.ValidationContext result)
         {
             result = result.GetContext(this);
 
+            if (_min.Count != _max.Count) result.AddDataError("Max", $"Min and Max bounds dimension mismatch Min:{_min.Count} Max:{_max.Count}");
+
             if (_min.Count == 0 && _max.Count == 0) return;
 
             var dimensions = this.Dimensions.DimCount();

+ 1 - 1
src/SharpGLTF.Core/Schema2/gltf.Buffer.cs

@@ -119,7 +119,7 @@ namespace SharpGLTF.Schema2
             result.CheckSchemaIsValidURI("Uri", this._uri);
 
             result.CheckSchemaIsInRange("ByteLength", _byteLength, _byteLengthMinimum, int.MaxValue);
-            result.CheckSchemaIsMultipleOf("ByteLength", _byteLength, 4);
+            // result.CheckSchemaIsMultipleOf("ByteLength", _byteLength, 4);
         }
 
         protected override void OnValidate(Validation.ValidationContext result)

+ 16 - 29
src/SharpGLTF.Core/Schema2/gltf.MeshPrimitive.cs

@@ -218,15 +218,15 @@ namespace SharpGLTF.Schema2
         {
             base.OnValidate(result);
 
-            // check vertex count
+            // all vertices must have the same vertex count
 
             var vertexCounts = VertexAccessors
                 .Select(item => item.Value.Count)
                 .Distinct();
 
-            if (vertexCounts.Count() != 1)
+            if (vertexCounts.Skip(1).Any())
             {
-                result.AddLinkError(Validation.ErrorCodes.MESH_PRIMITIVE_UNEQUAL_ACCESSOR_COUNT);
+                result.AddLinkError("Attributes", "All accessors of the same primitive must have the same count.");
                 return;
             }
 
@@ -262,7 +262,7 @@ namespace SharpGLTF.Schema2
                         break;
                 }
 
-                if (incompatibleMode) result.AddLinkWarning(Validation.WarnCodes.MESH_PRIMITIVE_INCOMPATIBLE_MODE, IndexAccessor.Count, this.DrawPrimitiveType);
+                if (incompatibleMode) result.AddLinkWarning("Indices", $"Number of vertices or indices({IndexAccessor.Count}) is not compatible with used drawing mode('{this.DrawPrimitiveType}').");
             }
 
             // check attributes
@@ -271,13 +271,16 @@ namespace SharpGLTF.Schema2
             {
                 if (group.Skip(1).Any())
                 {
+                    // if more than one accessor shares a BufferView, it must define a ByteStride
+
                     if (group.Key.ByteStride == 0)
                     {
-                        result.GetContext(group.Key).AddLinkError("ByteStride", " must be defined when two or more accessors use the same buffer view.");
+                        result.GetContext(group.Key).AddLinkError("ByteStride", " must be defined when two or more accessors use the same BufferView.");
+                        return;
                     }
 
                     // now, there's two possible outcomes:
-                    // - independent streaming accessors: all accessors must have ByteStride size
+                    // - sequential accessors: accessor data comes one after another.
                     // - strided accessors: the sum of all accessors must match bytestride
 
                     if (group.All(item => item.ItemByteSize.WordPadded() == group.Key.ByteStride))
@@ -287,13 +290,13 @@ namespace SharpGLTF.Schema2
                         // all accessor are laid sequentially, so they must not overlap.
 
                         var accessors = group.OrderBy(item => item.ByteOffset);
-                        var startOffset = accessors.First().ByteOffset;
+                        var bvByteOffset = accessors.First().ByteOffset;
 
                         int pointer = 0;
 
                         foreach (var accessor in accessors)
                         {
-                            var accessorStartOffset = accessor.ByteOffset - startOffset;
+                            var accessorStartOffset = accessor.ByteOffset - bvByteOffset;
                             var accessorByteCount = accessor.ItemByteSize.WordPadded() * accessor.Count;
 
                             if (accessorStartOffset < pointer) result.AddLinkError("Attributes", "Accessors overlapping found.");
@@ -306,20 +309,8 @@ namespace SharpGLTF.Schema2
                         // strided format.
 
                         var accessors = group.OrderBy(item => item.ByteOffset);
-                        var startOffset = accessors.First().ByteOffset;
-
-                        int pointer = 0;
-
-                        foreach (var accessor in accessors)
-                        {
-                            var accessorStartOffset = accessor.ByteOffset - startOffset;
-                            var accessorByteCount = accessor.ItemByteSize.WordPadded();
-
-                            if (accessorStartOffset < pointer) result.AddLinkError("Attributes", "Accessors overlapping found.");
-                            if (accessorStartOffset + accessorByteCount > group.Key.ByteStride) result.AddLinkError("Attributes", "Accessors exceed BufferView's ByteStride.");
-
-                            pointer += accessorByteCount;
-                        }
+                        var bvByteOffset = accessors.First().ByteOffset;
+                        var bvByteCount = group.Key.ByteStride * vertexCount;
                     }
                     else
                     {
@@ -394,14 +385,10 @@ namespace SharpGLTF.Schema2
                 max = Math.Max(max, (int)jjjj.W);
             }
 
-            foreach (var skin in skins)
+            foreach (var skin in skins.Where(item => item != null))
             {
-                if (skin == null) continue;
-                else
-                {
-                    var skinJoints = new int[skin.JointsCount];
-                    result.CheckArrayIndexAccess(attributeName, max, skinJoints);
-                }
+                var skinJoints = new int[skin.JointsCount];
+                result.CheckArrayIndexAccess(attributeName, max, skinJoints);
             }
         }
 

+ 19 - 10
src/SharpGLTF.Core/Schema2/gltf.Root.cs

@@ -150,17 +150,21 @@ namespace SharpGLTF.Schema2
 
             result.CheckArrayIndexAccess(nameof(DefaultScene), _scene, this.LogicalScenes);
 
-            foreach (var b in _bufferViews) b.ValidateReferences(result);
+            foreach (var b in _buffers) b.ValidateReferences(result);
+            foreach (var v in _bufferViews) v.ValidateReferences(result);
+            foreach (var a in _accessors) a.ValidateReferences(result);
 
+            foreach (var i in _images) i.ValidateReferences(result);
+            foreach (var s in _samplers) s.ValidateReferences(result);
             foreach (var t in _textures) t.ValidateReferences(result);
             foreach (var m in _materials) m.ValidateReferences(result);
 
-            foreach (var a in _accessors) a.ValidateReferences(result);
             foreach (var m in _meshes) m.ValidateReferences(result);
             foreach (var s in _skins) s.ValidateReferences(result);
+            foreach (var c in _cameras) c.ValidateReferences(result);
 
-            foreach (var s in _scenes) s.ValidateReferences(result);
             foreach (var n in _nodes) n.ValidateReferences(result);
+            foreach (var s in _scenes) s.ValidateReferences(result);
             foreach (var a in _animations) a.ValidateReferences(result);
 
             base.OnValidateReferences(result);
@@ -189,17 +193,22 @@ namespace SharpGLTF.Schema2
 
             // 4th check contents
 
-            foreach (var s in _scenes) s.Validate(result);
-            foreach (var n in _nodes) n.Validate(result);
+            foreach (var b in _buffers) b.Validate(result);
+            foreach (var v in _bufferViews) v.Validate(result);
+            foreach (var a in _accessors) a.Validate(result);
 
-            foreach (var a in _accessors)
-            {
-                a.Validate(result);
-                a.ValidateBounds(result);
-            }
+            foreach (var i in _images) i.Validate(result);
+            foreach (var s in _samplers) s.Validate(result);
+            foreach (var t in _textures) t.Validate(result);
+            foreach (var m in _materials) m.Validate(result);
 
             foreach (var m in _meshes) m.Validate(result);
             foreach (var s in _skins) s.Validate(result);
+            foreach (var c in _cameras) c.Validate(result);
+
+            foreach (var n in _nodes) n.Validate(result);
+            foreach (var s in _scenes) s.Validate(result);
+            foreach (var a in _animations) a.Validate(result);
         }
 
         #endregion