Browse Source

more validation improvements...

Vicente Penades 6 years ago
parent
commit
5851ef6968
29 changed files with 359 additions and 230 deletions
  1. 2 2
      build/SharpGLTF.CodeGen/CodeGen/EmitCSharp.cs
  2. 1 3
      src/SharpGLTF.Core/Debug/DebugViews.cs
  3. 4 4
      src/SharpGLTF.Core/Debug/DebuggerDisplay.cs
  4. 0 2
      src/SharpGLTF.Core/Schema2/Generated/ext.MSFT.textureDDS.g.cs
  5. 0 6
      src/SharpGLTF.Core/Schema2/Generated/ext.ModelLightsPunctual.g.cs
  6. 0 2
      src/SharpGLTF.Core/Schema2/Generated/ext.NodeLightsPunctual.g.cs
  7. 0 2
      src/SharpGLTF.Core/Schema2/Generated/ext.TextureTransform.g.cs
  8. 0 2
      src/SharpGLTF.Core/Schema2/Generated/ext.Unlit.g.cs
  9. 0 2
      src/SharpGLTF.Core/Schema2/Generated/ext.pbrSpecularGlossiness.g.cs
  10. 0 2
      src/SharpGLTF.Core/Schema2/Generated/ext.textureWEBP.g.cs
  11. 0 58
      src/SharpGLTF.Core/Schema2/Generated/gltf.g.cs
  12. 104 3
      src/SharpGLTF.Core/Schema2/gltf.AccessorSparse.cs
  13. 59 80
      src/SharpGLTF.Core/Schema2/gltf.Accessors.cs
  14. 8 1
      src/SharpGLTF.Core/Schema2/gltf.Animations.cs
  15. 98 13
      src/SharpGLTF.Core/Schema2/gltf.BufferView.cs
  16. 0 1
      src/SharpGLTF.Core/Schema2/gltf.Camera.cs
  17. 14 1
      src/SharpGLTF.Core/Schema2/gltf.Images.cs
  18. 0 1
      src/SharpGLTF.Core/Schema2/gltf.Material.cs
  19. 0 2
      src/SharpGLTF.Core/Schema2/gltf.MaterialsFactory.cs
  20. 0 1
      src/SharpGLTF.Core/Schema2/gltf.Mesh.cs
  21. 8 27
      src/SharpGLTF.Core/Schema2/gltf.MeshPrimitive.cs
  22. 0 1
      src/SharpGLTF.Core/Schema2/gltf.Root.cs
  23. 0 1
      src/SharpGLTF.Core/Schema2/khr.lights.cs
  24. 14 0
      src/SharpGLTF.Core/Validation/ValidationContext.cs
  25. 3 4
      tests/SharpGLTF.Tests/Reports.cs
  26. 2 2
      tests/SharpGLTF.Tests/Schema2/Authoring/MeshBuilderCreationTests.cs
  27. 25 3
      tests/SharpGLTF.Tests/Schema2/LoadAndSave/LoadSampleTests.cs
  28. 2 2
      tests/SharpGLTF.Tests/Schema2/LoadAndSave/LoadSpecialModelsTest.cs
  29. 15 2
      tests/SharpGLTF.Tests/TestFiles.cs

+ 2 - 2
build/SharpGLTF.CodeGen/CodeGen/EmitCSharp.cs

@@ -596,7 +596,7 @@ namespace SharpGLTF.CodeGen
 
 
             yield return string.Empty;
             yield return string.Empty;
 
 
-            yield return "/// <inheritdoc />".Indent(1);
+            // yield return "/// <inheritdoc />".Indent(1);
             yield return "protected override void SerializeProperties(JsonWriter writer)".Indent(1);
             yield return "protected override void SerializeProperties(JsonWriter writer)".Indent(1);
             yield return "{".Indent(1);
             yield return "{".Indent(1);
             if (HasBaseClass) yield return "base.SerializeProperties(writer);".Indent(2);
             if (HasBaseClass) yield return "base.SerializeProperties(writer);".Indent(2);
@@ -605,7 +605,7 @@ namespace SharpGLTF.CodeGen
 
 
             yield return string.Empty;
             yield return string.Empty;
 
 
-            yield return "/// <inheritdoc />".Indent(1);
+            // yield return "/// <inheritdoc />".Indent(1);
             yield return "protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)".Indent(1);
             yield return "protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)".Indent(1);
             yield return "{".Indent(1);
             yield return "{".Indent(1);
             yield return "switch (jsonPropertyName)".Indent(2);
             yield return "switch (jsonPropertyName)".Indent(2);

+ 1 - 3
src/SharpGLTF.Core/Debug/DebugViews.cs

@@ -41,8 +41,6 @@ namespace SharpGLTF.Debug
 
 
         public int ByteLength => _Value.Content.Count;
         public int ByteLength => _Value.Content.Count;
 
 
-        public Schema2.BufferMode? DeviceBufferTarget => _Value.DeviceBufferTarget;
-
         [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)]
         [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)]
         public Schema2.Accessor[] Accessors => _Value.FindAccessors().ToArray();
         public Schema2.Accessor[] Accessors => _Value.FindAccessors().ToArray();
     }
     }
@@ -69,7 +67,7 @@ namespace SharpGLTF.Debug
                 if (_Value.Dimensions == Schema2.DimensionType.VEC4) return _Value.AsVector4Array().Cast<Object>().ToArray();
                 if (_Value.Dimensions == Schema2.DimensionType.VEC4) return _Value.AsVector4Array().Cast<Object>().ToArray();
                 if (_Value.Dimensions == Schema2.DimensionType.MAT4) return _Value.AsMatrix4x4Array().Cast<Object>().ToArray();
                 if (_Value.Dimensions == Schema2.DimensionType.MAT4) return _Value.AsMatrix4x4Array().Cast<Object>().ToArray();
 
 
-                var itemByteSz = _Value.ItemByteSize;
+                var itemByteSz = _Value.ElementByteSize;
                 var byteStride = Math.Max(_Value.SourceBufferView.ByteStride, itemByteSz);
                 var byteStride = Math.Max(_Value.SourceBufferView.ByteStride, itemByteSz);
                 var items = new ArraySegment<Byte>[_Value.Count];
                 var items = new ArraySegment<Byte>[_Value.Count];
 
 

+ 4 - 4
src/SharpGLTF.Core/Debug/DebuggerDisplay.cs

@@ -41,8 +41,8 @@ namespace SharpGLTF.Debug
         {
         {
             var path = string.Empty;
             var path = string.Empty;
 
 
-            if (bv.DeviceBufferTarget == BufferMode.ARRAY_BUFFER) path += " VertexView";
-            else if (bv.DeviceBufferTarget == BufferMode.ELEMENT_ARRAY_BUFFER) path += " IndexView";
+            if (bv.IsVertexBuffer) path += " VertexView";
+            else if (bv.IsIndexBuffer) path += " IndexView";
             else path += " BufferView";
             else path += " BufferView";
 
 
             var content = bv.Content;
             var content = bv.Content;
@@ -66,8 +66,8 @@ namespace SharpGLTF.Debug
 
 
             var bv = accessor.SourceBufferView;
             var bv = accessor.SourceBufferView;
 
 
-            if (bv.DeviceBufferTarget == BufferMode.ARRAY_BUFFER) path += "VertexBuffer";
-            else if (bv.DeviceBufferTarget == BufferMode.ELEMENT_ARRAY_BUFFER) path += "IndexBuffer";
+            if (bv.IsVertexBuffer) path += "VertexBuffer";
+            else if (bv.IsIndexBuffer) path += "IndexBuffer";
             else path += "BufferView";
             else path += "BufferView";
             path += $"[{bv.LogicalIndex}ᴵᵈˣ] ⇨";
             path += $"[{bv.LogicalIndex}ᴵᵈˣ] ⇨";
 
 

+ 0 - 2
src/SharpGLTF.Core/Schema2/Generated/ext.MSFT.textureDDS.g.cs

@@ -34,14 +34,12 @@ namespace SharpGLTF.Schema2
 		private Int32? _source;
 		private Int32? _source;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "source", _source);
 			SerializeProperty(writer, "source", _source);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)

+ 0 - 6
src/SharpGLTF.Core/Schema2/Generated/ext.ModelLightsPunctual.g.cs

@@ -39,7 +39,6 @@ namespace SharpGLTF.Schema2
 		private Double? _outerConeAngle = _outerConeAngleDefault;
 		private Double? _outerConeAngle = _outerConeAngleDefault;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -47,7 +46,6 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "outerConeAngle", _outerConeAngle, _outerConeAngleDefault);
 			SerializeProperty(writer, "outerConeAngle", _outerConeAngle, _outerConeAngleDefault);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -81,7 +79,6 @@ namespace SharpGLTF.Schema2
 		private String _type;
 		private String _type;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -92,7 +89,6 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "type", _type);
 			SerializeProperty(writer, "type", _type);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -115,14 +111,12 @@ namespace SharpGLTF.Schema2
 		private ChildrenCollection<PunctualLight,ModelRoot> _lights;
 		private ChildrenCollection<PunctualLight,ModelRoot> _lights;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "lights", _lights, _lightsMinItems);
 			SerializeProperty(writer, "lights", _lights, _lightsMinItems);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)

+ 0 - 2
src/SharpGLTF.Core/Schema2/Generated/ext.NodeLightsPunctual.g.cs

@@ -31,14 +31,12 @@ namespace SharpGLTF.Schema2
 		private Int32 _light;
 		private Int32 _light;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "light", _light);
 			SerializeProperty(writer, "light", _light);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)

+ 0 - 2
src/SharpGLTF.Core/Schema2/Generated/ext.TextureTransform.g.cs

@@ -44,7 +44,6 @@ namespace SharpGLTF.Schema2
 		private Int32? _texCoord;
 		private Int32? _texCoord;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -54,7 +53,6 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "texCoord", _texCoord);
 			SerializeProperty(writer, "texCoord", _texCoord);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)

+ 0 - 2
src/SharpGLTF.Core/Schema2/Generated/ext.Unlit.g.cs

@@ -32,13 +32,11 @@ namespace SharpGLTF.Schema2
 	{
 	{
 	
 	
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)

+ 0 - 2
src/SharpGLTF.Core/Schema2/Generated/ext.pbrSpecularGlossiness.g.cs

@@ -47,7 +47,6 @@ namespace SharpGLTF.Schema2
 		private TextureInfo _specularGlossinessTexture;
 		private TextureInfo _specularGlossinessTexture;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -58,7 +57,6 @@ namespace SharpGLTF.Schema2
 			SerializePropertyObject(writer, "specularGlossinessTexture", _specularGlossinessTexture);
 			SerializePropertyObject(writer, "specularGlossinessTexture", _specularGlossinessTexture);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)

+ 0 - 2
src/SharpGLTF.Core/Schema2/Generated/ext.textureWEBP.g.cs

@@ -34,14 +34,12 @@ namespace SharpGLTF.Schema2
 		private Int32? _source;
 		private Int32? _source;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "source", _source);
 			SerializeProperty(writer, "source", _source);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)

+ 0 - 58
src/SharpGLTF.Core/Schema2/Generated/gltf.g.cs

@@ -177,14 +177,12 @@ namespace SharpGLTF.Schema2
 		private String _name;
 		private String _name;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "name", _name);
 			SerializeProperty(writer, "name", _name);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -211,7 +209,6 @@ namespace SharpGLTF.Schema2
 		private IndexEncodingType _componentType;
 		private IndexEncodingType _componentType;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -220,7 +217,6 @@ namespace SharpGLTF.Schema2
 			SerializePropertyEnumValue<IndexEncodingType>(writer, "componentType", _componentType);
 			SerializePropertyEnumValue<IndexEncodingType>(writer, "componentType", _componentType);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -247,7 +243,6 @@ namespace SharpGLTF.Schema2
 		private Int32? _byteOffset = _byteOffsetDefault;
 		private Int32? _byteOffset = _byteOffsetDefault;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -255,7 +250,6 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "byteOffset", _byteOffset, _byteOffsetDefault);
 			SerializeProperty(writer, "byteOffset", _byteOffset, _byteOffsetDefault);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -282,7 +276,6 @@ namespace SharpGLTF.Schema2
 		private AccessorSparseValues _values;
 		private AccessorSparseValues _values;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -291,7 +284,6 @@ namespace SharpGLTF.Schema2
 			SerializePropertyObject(writer, "values", _values);
 			SerializePropertyObject(writer, "values", _values);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -340,7 +332,6 @@ namespace SharpGLTF.Schema2
 		private DimensionType _type;
 		private DimensionType _type;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -355,7 +346,6 @@ namespace SharpGLTF.Schema2
 			SerializePropertyEnumSymbol<DimensionType>(writer, "type", _type);
 			SerializePropertyEnumSymbol<DimensionType>(writer, "type", _type);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -386,7 +376,6 @@ namespace SharpGLTF.Schema2
 		private PropertyPath _path;
 		private PropertyPath _path;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -394,7 +383,6 @@ namespace SharpGLTF.Schema2
 			SerializePropertyEnumSymbol<PropertyPath>(writer, "path", _path);
 			SerializePropertyEnumSymbol<PropertyPath>(writer, "path", _path);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -418,7 +406,6 @@ namespace SharpGLTF.Schema2
 		private AnimationChannelTarget _target;
 		private AnimationChannelTarget _target;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -426,7 +413,6 @@ namespace SharpGLTF.Schema2
 			SerializePropertyObject(writer, "target", _target);
 			SerializePropertyObject(writer, "target", _target);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -453,7 +439,6 @@ namespace SharpGLTF.Schema2
 		private Int32 _output;
 		private Int32 _output;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -462,7 +447,6 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "output", _output);
 			SerializeProperty(writer, "output", _output);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -489,7 +473,6 @@ namespace SharpGLTF.Schema2
 		private ChildrenCollection<AnimationSampler,Animation> _samplers;
 		private ChildrenCollection<AnimationSampler,Animation> _samplers;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -497,7 +480,6 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "samplers", _samplers, _samplersMinItems);
 			SerializeProperty(writer, "samplers", _samplers, _samplersMinItems);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -525,7 +507,6 @@ namespace SharpGLTF.Schema2
 		private String _version;
 		private String _version;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -535,7 +516,6 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "version", _version);
 			SerializeProperty(writer, "version", _version);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -562,7 +542,6 @@ namespace SharpGLTF.Schema2
 		private String _uri;
 		private String _uri;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -570,7 +549,6 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "uri", _uri);
 			SerializeProperty(writer, "uri", _uri);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -605,7 +583,6 @@ namespace SharpGLTF.Schema2
 		private BufferMode? _target;
 		private BufferMode? _target;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -616,7 +593,6 @@ namespace SharpGLTF.Schema2
 			SerializePropertyEnumValue<BufferMode>(writer, "target", _target);
 			SerializePropertyEnumValue<BufferMode>(writer, "target", _target);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -649,7 +625,6 @@ namespace SharpGLTF.Schema2
 		private Double _znear;
 		private Double _znear;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -659,7 +634,6 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "znear", _znear);
 			SerializeProperty(writer, "znear", _znear);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -693,7 +667,6 @@ namespace SharpGLTF.Schema2
 		private Double _znear;
 		private Double _znear;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -703,7 +676,6 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "znear", _znear);
 			SerializeProperty(writer, "znear", _znear);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -732,7 +704,6 @@ namespace SharpGLTF.Schema2
 		private CameraType _type;
 		private CameraType _type;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -741,7 +712,6 @@ namespace SharpGLTF.Schema2
 			SerializePropertyEnumSymbol<CameraType>(writer, "type", _type);
 			SerializePropertyEnumSymbol<CameraType>(writer, "type", _type);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -768,7 +738,6 @@ namespace SharpGLTF.Schema2
 		private Int32? _texCoord = _texCoordDefault;
 		private Int32? _texCoord = _texCoordDefault;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -776,7 +745,6 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "texCoord", _texCoord, _texCoordDefault);
 			SerializeProperty(writer, "texCoord", _texCoord, _texCoordDefault);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -813,7 +781,6 @@ namespace SharpGLTF.Schema2
 		private Double? _roughnessFactor = _roughnessFactorDefault;
 		private Double? _roughnessFactor = _roughnessFactorDefault;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -824,7 +791,6 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "roughnessFactor", _roughnessFactor, _roughnessFactorDefault);
 			SerializeProperty(writer, "roughnessFactor", _roughnessFactor, _roughnessFactorDefault);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -847,14 +813,12 @@ namespace SharpGLTF.Schema2
 		private Double? _scale = _scaleDefault;
 		private Double? _scale = _scaleDefault;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "scale", _scale, _scaleDefault);
 			SerializeProperty(writer, "scale", _scale, _scaleDefault);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -875,14 +839,12 @@ namespace SharpGLTF.Schema2
 		private Double? _strength = _strengthDefault;
 		private Double? _strength = _strengthDefault;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "strength", _strength, _strengthDefault);
 			SerializeProperty(writer, "strength", _strength, _strengthDefault);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -922,7 +884,6 @@ namespace SharpGLTF.Schema2
 		private MaterialPBRMetallicRoughness _pbrMetallicRoughness;
 		private MaterialPBRMetallicRoughness _pbrMetallicRoughness;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -936,7 +897,6 @@ namespace SharpGLTF.Schema2
 			SerializePropertyObject(writer, "pbrMetallicRoughness", _pbrMetallicRoughness);
 			SerializePropertyObject(writer, "pbrMetallicRoughness", _pbrMetallicRoughness);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -974,7 +934,6 @@ namespace SharpGLTF.Schema2
 		private List<Dictionary<String,Int32>> _targets;
 		private List<Dictionary<String,Int32>> _targets;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -985,7 +944,6 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "targets", _targets, _targetsMinItems);
 			SerializeProperty(writer, "targets", _targets, _targetsMinItems);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -1016,7 +974,6 @@ namespace SharpGLTF.Schema2
 		private List<Double> _weights;
 		private List<Double> _weights;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -1024,7 +981,6 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "weights", _weights, _weightsMinItems);
 			SerializeProperty(writer, "weights", _weights, _weightsMinItems);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -1066,7 +1022,6 @@ namespace SharpGLTF.Schema2
 		private List<Double> _weights;
 		private List<Double> _weights;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -1081,7 +1036,6 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "weights", _weights, _weightsMinItems);
 			SerializeProperty(writer, "weights", _weights, _weightsMinItems);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -1118,7 +1072,6 @@ namespace SharpGLTF.Schema2
 		private TextureWrapMode? _wrapT = _wrapTDefault;
 		private TextureWrapMode? _wrapT = _wrapTDefault;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -1128,7 +1081,6 @@ namespace SharpGLTF.Schema2
 			SerializePropertyEnumValue<TextureWrapMode>(writer, "wrapT", _wrapT, _wrapTDefault);
 			SerializePropertyEnumValue<TextureWrapMode>(writer, "wrapT", _wrapT, _wrapTDefault);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -1153,14 +1105,12 @@ namespace SharpGLTF.Schema2
 		private List<Int32> _nodes;
 		private List<Int32> _nodes;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "nodes", _nodes, _nodesMinItems);
 			SerializeProperty(writer, "nodes", _nodes, _nodesMinItems);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -1186,7 +1136,6 @@ namespace SharpGLTF.Schema2
 		private Int32? _skeleton;
 		private Int32? _skeleton;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -1195,7 +1144,6 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "skeleton", _skeleton);
 			SerializeProperty(writer, "skeleton", _skeleton);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -1220,7 +1168,6 @@ namespace SharpGLTF.Schema2
 		private Int32? _source;
 		private Int32? _source;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -1228,7 +1175,6 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "source", _source);
 			SerializeProperty(writer, "source", _source);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -1297,7 +1243,6 @@ namespace SharpGLTF.Schema2
 		private ChildrenCollection<Texture,ModelRoot> _textures;
 		private ChildrenCollection<Texture,ModelRoot> _textures;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -1320,7 +1265,6 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "textures", _textures, _texturesMinItems);
 			SerializeProperty(writer, "textures", _textures, _texturesMinItems);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
@@ -1361,7 +1305,6 @@ namespace SharpGLTF.Schema2
 		private String _uri;
 		private String _uri;
 		
 		
 	
 	
-		/// <inheritdoc />
 		protected override void SerializeProperties(JsonWriter writer)
 		protected override void SerializeProperties(JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
@@ -1370,7 +1313,6 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "uri", _uri);
 			SerializeProperty(writer, "uri", _uri);
 		}
 		}
 	
 	
-		/// <inheritdoc />
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)

+ 104 - 3
src/SharpGLTF.Core/Schema2/gltf.AccessorSparse.cs

@@ -2,13 +2,25 @@
 
 
 namespace SharpGLTF.Schema2
 namespace SharpGLTF.Schema2
 {
 {
+    using SharpGLTF.Validation;
     using ROOT = ModelRoot;
     using ROOT = ModelRoot;
 
 
     public sealed partial class AccessorSparse
     public sealed partial class AccessorSparse
     {
     {
+        #region lifecycle
+
         internal AccessorSparse() { }
         internal AccessorSparse() { }
 
 
-        /// <inheritdoc />
+        #endregion
+
+        #region properties
+
+        public int Count => _count;
+
+        #endregion
+
+        #region API
+
         protected override IEnumerable<ExtraProperties> GetLogicalChildren()
         protected override IEnumerable<ExtraProperties> GetLogicalChildren()
         {
         {
             return base.GetLogicalChildren().ConcatItems(_indices, _values);
             return base.GetLogicalChildren().ConcatItems(_indices, _values);
@@ -25,8 +37,6 @@ namespace SharpGLTF.Schema2
             this._values = new AccessorSparseValues(values, valuesOffset);
             this._values = new AccessorSparseValues(values, valuesOffset);
         }
         }
 
 
-        public int Count => _count;
-
         internal KeyValuePair<Memory.IntegerArray, Memory.MemoryAccessor> _CreateMemoryAccessors(Accessor baseAccessor)
         internal KeyValuePair<Memory.IntegerArray, Memory.MemoryAccessor> _CreateMemoryAccessors(Accessor baseAccessor)
         {
         {
             var key = this._indices._GetIndicesArray(baseAccessor.LogicalParent, _count);
             var key = this._indices._GetIndicesArray(baseAccessor.LogicalParent, _count);
@@ -34,10 +44,42 @@ namespace SharpGLTF.Schema2
 
 
             return new KeyValuePair<Memory.IntegerArray, Memory.MemoryAccessor>(key, val);
             return new KeyValuePair<Memory.IntegerArray, Memory.MemoryAccessor>(key, val);
         }
         }
+
+        #endregion
+
+        #region validation
+
+        protected override void OnValidateReferences(ValidationContext result)
+        {
+            result = result.GetContext(this);
+
+            base.OnValidateReferences(result);
+
+            result.CheckIsInRange(nameof(Count), _count, _countMinimum, int.MaxValue);
+            result.CheckSchemaIsDefined("Indices", _indices);
+            result.CheckSchemaIsDefined("Values", _values);
+
+            _indices?.ValidateReferences(result);
+            _values?.ValidateReferences(result);
+        }
+
+        protected override void OnValidate(ValidationContext result)
+        {
+            result = result.GetContext(this);
+
+            base.OnValidate(result);
+
+            _indices.Validate(result, _count);
+            _values.Validate(result, _count);
+        }
+
+        #endregion
     }
     }
 
 
     public sealed partial class AccessorSparseIndices
     public sealed partial class AccessorSparseIndices
     {
     {
+        #region lifecycle
+
         internal AccessorSparseIndices() { }
         internal AccessorSparseIndices() { }
 
 
         internal AccessorSparseIndices(BufferView bv, int byteOffset, IndexEncodingType encoding)
         internal AccessorSparseIndices(BufferView bv, int byteOffset, IndexEncodingType encoding)
@@ -50,15 +92,46 @@ namespace SharpGLTF.Schema2
             this._componentType = encoding;
             this._componentType = encoding;
         }
         }
 
 
+        #endregion
+
+        #region API
+
         internal Memory.IntegerArray _GetIndicesArray(ROOT root, int count)
         internal Memory.IntegerArray _GetIndicesArray(ROOT root, int count)
         {
         {
             var srcBuffer = root.LogicalBufferViews[this._bufferView];
             var srcBuffer = root.LogicalBufferViews[this._bufferView];
             return new Memory.IntegerArray(srcBuffer.Content, this._byteOffset ?? 0, count, this._componentType);
             return new Memory.IntegerArray(srcBuffer.Content, this._byteOffset ?? 0, count, this._componentType);
         }
         }
+
+        #endregion
+
+        #region validation
+
+        protected override void OnValidateReferences(ValidationContext result)
+        {
+            result = result.GetContext(this);
+
+            base.OnValidateReferences(result);
+
+            result.CheckSchemaNonNegative("ByteOffset", _byteOffset);
+            result.CheckArrayIndexAccess("BufferView", _bufferView, result.Root.LogicalBufferViews);
+        }
+
+        internal void Validate(ValidationContext result, int count)
+        {
+            result = result.GetContext(this);
+
+            var bv = result.Root.LogicalBufferViews[_bufferView];
+
+            BufferView.CheckAccess(result, bv, _byteOffset ?? _byteOffsetDefault, DimensionType.SCALAR, _componentType.ToComponent(), false, count);
+        }
+
+        #endregion
     }
     }
 
 
     public sealed partial class AccessorSparseValues
     public sealed partial class AccessorSparseValues
     {
     {
+        #region lifecycle
+
         internal AccessorSparseValues() { }
         internal AccessorSparseValues() { }
 
 
         internal AccessorSparseValues(BufferView bv, int byteOffset)
         internal AccessorSparseValues(BufferView bv, int byteOffset)
@@ -70,11 +143,39 @@ namespace SharpGLTF.Schema2
             this._byteOffset = byteOffset.AsNullable(_byteOffsetDefault);
             this._byteOffset = byteOffset.AsNullable(_byteOffsetDefault);
         }
         }
 
 
+        #endregion
+
+        #region API
+
         internal Memory.MemoryAccessor _GetMemoryAccessor(ROOT root, int count, Accessor baseAccessor)
         internal Memory.MemoryAccessor _GetMemoryAccessor(ROOT root, int count, Accessor baseAccessor)
         {
         {
             var view = root.LogicalBufferViews[this._bufferView];
             var view = root.LogicalBufferViews[this._bufferView];
             var info = new Memory.MemoryAccessInfo(null, this._byteOffset ?? 0, count, view.ByteStride, baseAccessor.Dimensions, baseAccessor.Encoding, baseAccessor.Normalized);
             var info = new Memory.MemoryAccessInfo(null, this._byteOffset ?? 0, count, view.ByteStride, baseAccessor.Dimensions, baseAccessor.Encoding, baseAccessor.Normalized);
             return new Memory.MemoryAccessor(view.Content, info);
             return new Memory.MemoryAccessor(view.Content, info);
         }
         }
+
+        #endregion
+
+        #region validation
+
+        protected override void OnValidateReferences(ValidationContext result)
+        {
+            result = result.GetContext(this);
+
+            base.OnValidateReferences(result);
+
+            result.CheckSchemaNonNegative("ByteOffset", _byteOffset);
+            result.CheckArrayIndexAccess("BufferView", _bufferView, result.Root.LogicalBufferViews);
+        }
+
+        internal void Validate(ValidationContext result, int count)
+        {
+            var bv = result.Root.LogicalBufferViews[_bufferView];
+
+            // we need the accessor's settings to properly check this.
+            // result.CheckAccess(bv, _byteOffset, DimensionType.SCALAR, _componentType, count);
+        }
+
+        #endregion
     }
     }
 }
 }

+ 59 - 80
src/SharpGLTF.Core/Schema2/gltf.Accessors.cs

@@ -38,7 +38,7 @@ namespace SharpGLTF.Schema2
         /// </summary>
         /// </summary>
         public int LogicalIndex                 => this.LogicalParent.LogicalAccessors.IndexOfReference(this);
         public int LogicalIndex                 => this.LogicalParent.LogicalAccessors.IndexOfReference(this);
 
 
-        internal int _LogicalBufferViewIndex    => this._bufferView.AsValue(-1);
+        internal int _SourceBufferViewIndex => this._bufferView.AsValue(-1);
 
 
         /// <summary>
         /// <summary>
         /// Gets the <see cref="BufferView"/> buffer that contains the items as an encoded byte array.
         /// Gets the <see cref="BufferView"/> buffer that contains the items as an encoded byte array.
@@ -55,6 +55,11 @@ namespace SharpGLTF.Schema2
         /// </summary>
         /// </summary>
         public int ByteOffset                   => this._byteOffset.AsValue(0);
         public int ByteOffset                   => this._byteOffset.AsValue(0);
 
 
+        /// <summary>
+        /// Gets the number of bytes, starting at <see cref="ByteOffset"/> use by this <see cref="Accessor"/>
+        /// </summary>
+        public int ByteLength                   => SourceBufferView.GetAccessorByteLength(Dimensions, Encoding, Count);
+
         /// <summary>
         /// <summary>
         /// Gets the <see cref="DimensionType"/> of an item.
         /// Gets the <see cref="DimensionType"/> of an item.
         /// </summary>
         /// </summary>
@@ -79,7 +84,7 @@ namespace SharpGLTF.Schema2
         /// Gets the number of bytes required to encode a single item in <see cref="SourceBufferView"/>
         /// Gets the number of bytes required to encode a single item in <see cref="SourceBufferView"/>
         /// Given the current <see cref="Dimensions"/> and <see cref="Encoding"/> states.
         /// Given the current <see cref="Dimensions"/> and <see cref="Encoding"/> states.
         /// </summary>
         /// </summary>
-        public int ItemByteSize                 => Encoding.ByteLength() * Dimensions.DimCount();
+        public int ElementByteSize                 => Encoding.ByteLength() * Dimensions.DimCount();
 
 
         #endregion
         #endregion
 
 
@@ -101,6 +106,47 @@ namespace SharpGLTF.Schema2
                 this._sparse._CreateMemoryAccessors(this);
                 this._sparse._CreateMemoryAccessors(this);
         }
         }
 
 
+        protected override IEnumerable<ExtraProperties> GetLogicalChildren()
+        {
+            return base.GetLogicalChildren().ConcatItems(_sparse);
+        }
+
+        public void UpdateBounds()
+        {
+            this._min.Clear();
+            this._max.Clear();
+
+            if (this.Count == 0) return;
+
+            // With the current limitations of the serializer, we can only handle floating point values.
+            if (this.Encoding != EncodingType.FLOAT) return;
+
+            // https://github.com/KhronosGroup/glTF-Validator/issues/79
+
+            var dimensions = this.Dimensions.DimCount();
+
+            for (int i = 0; i < dimensions; ++i)
+            {
+                this._min.Add(double.MaxValue);
+                this._max.Add(double.MinValue);
+            }
+
+            var array = new MultiArray(this.SourceBufferView.Content, this.ByteOffset, this.Count, this.SourceBufferView.ByteStride, dimensions, this.Encoding, false);
+
+            var current = new float[dimensions];
+
+            for (int i = 0; i < array.Count; ++i)
+            {
+                array.CopyItemTo(i, current);
+
+                for (int j = 0; j < current.Length; ++j)
+                {
+                    this._min[j] = Math.Min(this._min[j], current[j]);
+                    this._max[j] = Math.Max(this._max[j], current[j]);
+                }
+            }
+        }
+
         #endregion
         #endregion
 
 
         #region Data Buffer API
         #region Data Buffer API
@@ -160,8 +206,7 @@ namespace SharpGLTF.Schema2
         {
         {
             Guard.NotNull(buffer, nameof(buffer));
             Guard.NotNull(buffer, nameof(buffer));
             Guard.MustShareLogicalParent(this, buffer, nameof(buffer));
             Guard.MustShareLogicalParent(this, buffer, nameof(buffer));
-
-            if (buffer.DeviceBufferTarget.HasValue) Guard.IsTrue(buffer.DeviceBufferTarget.Value == BufferMode.ELEMENT_ARRAY_BUFFER, nameof(buffer));
+            Guard.IsFalse(buffer.IsVertexBuffer, nameof(buffer));
 
 
             SetData(buffer, bufferByteOffset, itemCount, DimensionType.SCALAR, encoding.ToComponent(), false);
             SetData(buffer, bufferByteOffset, itemCount, DimensionType.SCALAR, encoding.ToComponent(), false);
         }
         }
@@ -201,8 +246,7 @@ namespace SharpGLTF.Schema2
             Guard.NotNull(buffer, nameof(buffer));
             Guard.NotNull(buffer, nameof(buffer));
             Guard.MustShareLogicalParent(this, buffer, nameof(buffer));
             Guard.MustShareLogicalParent(this, buffer, nameof(buffer));
             Guard.MustBePositiveAndMultipleOf(dimensions.DimCount() * encoding.ByteLength(), 4, nameof(encoding));
             Guard.MustBePositiveAndMultipleOf(dimensions.DimCount() * encoding.ByteLength(), 4, nameof(encoding));
-
-            if (buffer.DeviceBufferTarget.HasValue) Guard.IsTrue(buffer.DeviceBufferTarget.Value == BufferMode.ARRAY_BUFFER, nameof(buffer));
+            Guard.IsFalse(buffer.IsIndexBuffer, nameof(buffer));
 
 
             SetData(buffer, bufferByteOffset, itemCount, dimensions, encoding, normalized);
             SetData(buffer, bufferByteOffset, itemCount, dimensions, encoding, normalized);
         }
         }
@@ -288,51 +332,6 @@ namespace SharpGLTF.Schema2
 
 
         #endregion
         #endregion
 
 
-        #region API
-
-        protected override IEnumerable<ExtraProperties> GetLogicalChildren()
-        {
-            return base.GetLogicalChildren().ConcatItems(_sparse);
-        }
-
-        public void UpdateBounds()
-        {
-            this._min.Clear();
-            this._max.Clear();
-
-            if (this.Count == 0) return;
-
-            // With the current limitations of the serializer, we can only handle floating point values.
-            if (this.Encoding != EncodingType.FLOAT) return;
-
-            // https://github.com/KhronosGroup/glTF-Validator/issues/79
-
-            var dimensions = this.Dimensions.DimCount();
-
-            for (int i = 0; i < dimensions; ++i)
-            {
-                this._min.Add(double.MaxValue);
-                this._max.Add(double.MinValue);
-            }
-
-            var array = new MultiArray(this.SourceBufferView.Content, this.ByteOffset, this.Count, this.SourceBufferView.ByteStride, dimensions, this.Encoding, false);
-
-            var current = new float[dimensions];
-
-            for (int i = 0; i < array.Count; ++i)
-            {
-                array.CopyItemTo(i, current);
-
-                for (int j = 0; j < current.Length; ++j)
-                {
-                    this._min[j] = Math.Min(this._min[j], current[j]);
-                    this._max[j] = Math.Max(this._max[j], current[j]);
-                }
-            }
-        }
-
-        #endregion
-
         #region Validation
         #region Validation
 
 
         protected override void OnValidateReferences(Validation.ValidationContext result)
         protected override void OnValidateReferences(Validation.ValidationContext result)
@@ -344,42 +343,22 @@ namespace SharpGLTF.Schema2
 
 
             result.CheckSchemaNonNegative("ByteOffset", _byteOffset);
             result.CheckSchemaNonNegative("ByteOffset", _byteOffset);
             result.CheckSchemaIsInRange("Count", _count, _countMinimum, int.MaxValue);
             result.CheckSchemaIsInRange("Count", _count, _countMinimum, int.MaxValue);
+
+            _sparse?.ValidateReferences(result);
         }
         }
 
 
-        /// <see href="https://github.com/KhronosGroup/glTF-Validator/blob/master/lib/src/base/accessor.dart"/>
-        /// <seealso href="https://github.com/KhronosGroup/glTF-Validator/blob/master/lib/src/data_access/validate_accessors.dart"/>
         protected override void OnValidate(Validation.ValidationContext result)
         protected override void OnValidate(Validation.ValidationContext result)
         {
         {
             base.OnValidate(result);
             base.OnValidate(result);
 
 
-            // TODO: check BufferView access.
-            // if (_count < _countMinimum) result.AddError(this, $"Count is out of range");
-            // if (_byteOffset < 0) result.AddError(this, $"ByteOffset is out of range");
+            _sparse?.Validate(result);
 
 
-            if (this.Normalized)
-            {
-                if (this._componentType != EncodingType.UNSIGNED_BYTE && this._componentType != EncodingType.UNSIGNED_SHORT)
-                {
-                    result.AddDataError(nameof(Normalized), "Only (u)byte and (u)short accessors can be normalized.");
-                }
-            }
-
-            if (SourceBufferView.DeviceBufferTarget == BufferMode.ARRAY_BUFFER)
-            {
-                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.");
-            }
+            BufferView.CheckAccess(result, this.SourceBufferView, this.ByteOffset, this.Dimensions, this.Encoding, this.Normalized, this.Count);
 
 
             ValidateBounds(result);
             ValidateBounds(result);
+
+            // at this point we don't know which kind of data we're accessing, so it's up to the components
+            // using this accessor to validate the data.
         }
         }
 
 
         private void ValidateBounds(Validation.ValidationContext result)
         private void ValidateBounds(Validation.ValidationContext result)
@@ -392,8 +371,8 @@ namespace SharpGLTF.Schema2
 
 
             var dimensions = this.Dimensions.DimCount();
             var dimensions = this.Dimensions.DimCount();
 
 
-            // if (_min.Count != dimensions) { result.AddError($"min bounds length mismatch; expected {dimensions} but found {_min.Count}"); return; }
-            // if (_max.Count != dimensions) { result.AddError($"max bounds length mismatch; expected {dimensions} but found {_max.Count}"); return; }
+            if (_min.Count != dimensions) { result.AddLinkError("Min", $"size mismatch; expected {dimensions} but found {_min.Count}"); return; }
+            if (_max.Count != dimensions) { result.AddLinkError("Max", $"size mismatch; expected {dimensions} but found {_max.Count}"); return; }
 
 
             for (int i = 0; i < _min.Count; ++i)
             for (int i = 0; i < _min.Count; ++i)
             {
             {

+ 8 - 1
src/SharpGLTF.Core/Schema2/gltf.Animations.cs

@@ -41,7 +41,6 @@ namespace SharpGLTF.Schema2
 
 
         #region API
         #region API
 
 
-        /// <inheritdoc />
         protected override IEnumerable<ExtraProperties> GetLogicalChildren()
         protected override IEnumerable<ExtraProperties> GetLogicalChildren()
         {
         {
             return base.GetLogicalChildren().Concat(_samplers).Concat(_channels);
             return base.GetLogicalChildren().Concat(_samplers).Concat(_channels);
@@ -738,6 +737,14 @@ namespace SharpGLTF.Schema2
             result.CheckArrayIndexAccess("Output", _output, this.LogicalParent.LogicalParent.LogicalAccessors);
             result.CheckArrayIndexAccess("Output", _output, this.LogicalParent.LogicalParent.LogicalAccessors);
         }
         }
 
 
+        protected override void OnValidate(ValidationContext result)
+        {
+            base.OnValidate(result);
+
+            // Input.ValidateAnimationInput();
+            // Output.ValidateAnimationOutput();
+        }
+
         #endregion
         #endregion
     }
     }
 
 

+ 98 - 13
src/SharpGLTF.Core/Schema2/gltf.BufferView.cs

@@ -66,10 +66,29 @@ namespace SharpGLTF.Schema2
         /// </summary>
         /// </summary>
         public int LogicalIndex                 => this.LogicalParent.LogicalBufferViews.IndexOfReference(this);
         public int LogicalIndex                 => this.LogicalParent.LogicalBufferViews.IndexOfReference(this);
 
 
-        public BufferMode? DeviceBufferTarget   => this._target;
+        /// <summary>
+        /// Gets a value indicating whether this <see cref="BufferView"/> defines a GPU Ready Vertex Buffer.
+        /// </summary>
+        public bool IsVertexBuffer              => this._target == BufferMode.ARRAY_BUFFER;
+
+        /// <summary>
+        /// Gets a value indicating whether this <see cref="BufferView"/> defines a GPU Ready Index Buffer.
+        /// </summary>
+        public bool IsIndexBuffer               => this._target == BufferMode.ELEMENT_ARRAY_BUFFER;
+
+        /// <summary>
+        /// Gets a value indicating whether this <see cref="BufferView"/> defines a general purpose data buffer.
+        /// </summary>
+        public bool IsDataBuffer                => this._target == null;
 
 
+        /// <summary>
+        /// Gets the number of bytes between the beginnings of successive elements, or Zero.
+        /// </summary>
         public int ByteStride                   => this._byteStride.AsValue(0);
         public int ByteStride                   => this._byteStride.AsValue(0);
 
 
+        /// <summary>
+        /// Gets the actual bytes defined by this <see cref="BufferView"/>
+        /// </summary>
         public BYTES Content
         public BYTES Content
         {
         {
             get
             get
@@ -86,6 +105,15 @@ namespace SharpGLTF.Schema2
 
 
         #region API
         #region API
 
 
+        public IEnumerable<Image> FindImages()
+        {
+            var idx = LogicalIndex;
+
+            return this.LogicalParent
+                .LogicalImages
+                .Where(image => image._SourceBufferViewIndex == idx);
+        }
+
         /// <summary>
         /// <summary>
         /// Finds all the accessors using this BufferView
         /// Finds all the accessors using this BufferView
         /// </summary>
         /// </summary>
@@ -96,7 +124,7 @@ namespace SharpGLTF.Schema2
 
 
             return this.LogicalParent
             return this.LogicalParent
                 .LogicalAccessors
                 .LogicalAccessors
-                .Where(accessor => accessor._LogicalBufferViewIndex == idx);
+                .Where(accessor => accessor._SourceBufferViewIndex == idx);
         }
         }
 
 
         internal void _IsolateBufferMemory(_StaticBufferBuilder targetBuffer)
         internal void _IsolateBufferMemory(_StaticBufferBuilder targetBuffer)
@@ -127,10 +155,73 @@ namespace SharpGLTF.Schema2
                 .All(o => o < this.ByteStride);
                 .All(o => o < this.ByteStride);
         }
         }
 
 
+        internal static bool AreEqual(BufferView bv, BYTES content, int byteStride, BufferMode? target)
+        {
+            if (bv.Content.Array != content.Array) return false;
+            if (bv.Content.Offset != content.Offset) return false;
+            if (bv.Content.Count != content.Count) return false;
+            if (bv.ByteStride != byteStride) return false;
+            if (bv._target != target) return false;
+            return true;
+        }
+
+        /// <summary>
+        /// Calculates the number of bytes to which this accessors reads
+        /// taking into account if the source <see cref="BufferView"/> is strided.
+        /// </summary>
+        /// <returns>The number of bytes to access.</returns>
+        internal int GetAccessorByteLength(DimensionType dim, EncodingType enc, int count)
+        {
+            var elementByteSize = dim.DimCount() * enc.ByteLength();
+            if (this.ByteStride == 0) return elementByteSize * count;
+            return (this.ByteStride * (count - 1)) + elementByteSize;
+        }
+
         #endregion
         #endregion
 
 
         #region Validation
         #region Validation
 
 
+        internal static void CheckAccess(Validation.ValidationContext result, BufferView bv, int accessorByteOffset, DimensionType dim, EncodingType enc, bool nrm, int count)
+        {
+            if (nrm)
+            {
+                if (enc != EncodingType.UNSIGNED_BYTE && enc != EncodingType.UNSIGNED_SHORT)
+                {
+                    result.AddDataError("Normalized", "Only (u)byte and (u)short accessors can be normalized.");
+                }
+            }
+
+            var elementByteSize = dim.DimCount() * enc.ByteLength();
+
+            if (bv.IsVertexBuffer)
+            {
+                if (bv.ByteStride == 0) result.CheckSchemaIsMultipleOf("ElementByteSize", elementByteSize, 4);
+            }
+
+            if (bv.IsIndexBuffer)
+            {
+                if (dim != DimensionType.SCALAR) result.AddLinkError(("BufferView", bv.LogicalIndex), $"is an IndexBuffer, but accessor dimensions is: {dim}");
+                if (enc == EncodingType.BYTE)    result.AddLinkError(("BufferView", bv.LogicalIndex), $"is an IndexBuffer, but accessor encoding is (s)byte");
+                if (enc == EncodingType.SHORT)   result.AddLinkError(("BufferView", bv.LogicalIndex), $"is an IndexBuffer, but accessor encoding is (s)short");
+                if (enc == EncodingType.FLOAT)   result.AddLinkError(("BufferView", bv.LogicalIndex), $"is an IndexBuffer, but accessor encoding is float");
+                if (nrm)                         result.AddLinkError(("BufferView", bv.LogicalIndex), $"is an IndexBuffer, but accessor is normalized");
+            }
+
+            if (bv.ByteStride > 0)
+            {
+                if (bv.ByteStride < elementByteSize) result.AddLinkError("ElementByteSize", $"Referenced bufferView's byteStride value {bv.ByteStride} is less than accessor element's length {elementByteSize}.");
+
+                // "Accessor's total byteOffset {0} isn't a multiple of componentType length {1}.";
+
+                return;
+            }
+
+            var accessorByteLength = bv.GetAccessorByteLength(dim, enc, count);
+
+            // "Accessor(offset: {0}, length: {1}) does not fit referenced bufferView[% 3] length %4.";
+            result.CheckArrayRangeAccess(("BufferView", bv.LogicalIndex), accessorByteOffset, accessorByteLength, bv.Content);
+        }
+
         protected override void OnValidateReferences(Validation.ValidationContext result)
         protected override void OnValidateReferences(Validation.ValidationContext result)
         {
         {
             base.OnValidateReferences(result);
             base.OnValidateReferences(result);
@@ -167,10 +258,10 @@ namespace SharpGLTF.Schema2
         {
         {
             result = result.GetContext(this);
             result = result.GetContext(this);
 
 
-            if (!this.DeviceBufferTarget.HasValue) return;
-            if (usingMode == this.DeviceBufferTarget.Value) return;
+            if (!this._target.HasValue) return;
+            if (usingMode == this._target.Value) return;
 
 
-            result.AddLinkError(nameof(DeviceBufferTarget), $"is set as {this.DeviceBufferTarget.Value}. But an accessor wants to use it as '{usingMode}'.");
+            result.AddLinkError("Device Buffer Target", $"is set as {this._target.Value}. But an accessor wants to use it as '{usingMode}'.");
         }
         }
 
 
         #endregion
         #endregion
@@ -224,17 +315,11 @@ namespace SharpGLTF.Schema2
             Guard.NotNull(buffer, nameof(buffer));
             Guard.NotNull(buffer, nameof(buffer));
             Guard.MustShareLogicalParent(this, "this", buffer, nameof(buffer));
             Guard.MustShareLogicalParent(this, "this", buffer, nameof(buffer));
 
 
-            byteLength = byteLength.AsValue(buffer.Content.Length - byteOffset);
+            var content = new BYTES(buffer.Content, byteOffset, byteLength.AsValue(buffer.Content.Length - byteOffset) );
 
 
             foreach (var bv in this.LogicalBufferViews)
             foreach (var bv in this.LogicalBufferViews)
             {
             {
-                if (bv.Content.Array != buffer.Content) continue;
-                if (bv.Content.Offset != byteOffset) continue;
-                if (bv.Content.Count != byteLength.Value) continue;
-                if (bv.ByteStride != byteStride) continue;
-                if (bv.DeviceBufferTarget != target) continue;
-
-                return bv;
+                if (BufferView.AreEqual(bv, content, byteStride, target)) return bv;
             }
             }
 
 
             var newbv = new BufferView(buffer, byteOffset, byteLength, byteStride, target);
             var newbv = new BufferView(buffer, byteOffset, byteLength, byteStride, target);

+ 0 - 1
src/SharpGLTF.Core/Schema2/gltf.Camera.cs

@@ -31,7 +31,6 @@ namespace SharpGLTF.Schema2
 
 
         #region API
         #region API
 
 
-        /// <inheritdoc />
         protected override IEnumerable<ExtraProperties> GetLogicalChildren()
         protected override IEnumerable<ExtraProperties> GetLogicalChildren()
         {
         {
             return base.GetLogicalChildren().ConcatItems(_orthographic, _perspective);
             return base.GetLogicalChildren().ConcatItems(_orthographic, _perspective);

+ 14 - 1
src/SharpGLTF.Core/Schema2/gltf.Images.cs

@@ -2,7 +2,7 @@
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Text;
 using System.Text;
-
+using SharpGLTF.Validation;
 using BYTES = System.ArraySegment<byte>;
 using BYTES = System.ArraySegment<byte>;
 
 
 namespace SharpGLTF.Schema2
 namespace SharpGLTF.Schema2
@@ -99,6 +99,8 @@ namespace SharpGLTF.Schema2
             }
             }
         }
         }
 
 
+        internal int _SourceBufferViewIndex => _bufferView.AsValue(-1);
+
         #endregion
         #endregion
 
 
         #region API
         #region API
@@ -332,6 +334,17 @@ namespace SharpGLTF.Schema2
             result.CheckArrayIndexAccess("BufferView", _bufferView, this.LogicalParent.LogicalBufferViews);
             result.CheckArrayIndexAccess("BufferView", _bufferView, this.LogicalParent.LogicalBufferViews);
         }
         }
 
 
+        protected override void OnValidate(ValidationContext result)
+        {
+            base.OnValidate(result);
+
+            if (this._bufferView.HasValue)
+            {
+                var bv = result.Root.LogicalBufferViews[this._bufferView ?? 0];
+                if (!bv.IsDataBuffer) result.AddLinkError(("BufferView", this._bufferView), "is a GPU target.");
+            }
+        }
+
         #endregion
         #endregion
     }
     }
 
 

+ 0 - 1
src/SharpGLTF.Core/Schema2/gltf.Material.cs

@@ -63,7 +63,6 @@ namespace SharpGLTF.Schema2
 
 
         #region API
         #region API
 
 
-        /// <inheritdoc />
         protected override IEnumerable<ExtraProperties> GetLogicalChildren()
         protected override IEnumerable<ExtraProperties> GetLogicalChildren()
         {
         {
             return base.GetLogicalChildren().ConcatItems(_normalTexture, _emissiveTexture, _occlusionTexture, _pbrMetallicRoughness);
             return base.GetLogicalChildren().ConcatItems(_normalTexture, _emissiveTexture, _occlusionTexture, _pbrMetallicRoughness);

+ 0 - 2
src/SharpGLTF.Core/Schema2/gltf.MaterialsFactory.cs

@@ -141,7 +141,6 @@ namespace SharpGLTF.Schema2
 
 
     internal sealed partial class MaterialPBRMetallicRoughness
     internal sealed partial class MaterialPBRMetallicRoughness
     {
     {
-        /// <inheritdoc />
         protected override IEnumerable<ExtraProperties> GetLogicalChildren()
         protected override IEnumerable<ExtraProperties> GetLogicalChildren()
         {
         {
             return base.GetLogicalChildren().ConcatItems(_baseColorTexture, _metallicRoughnessTexture);
             return base.GetLogicalChildren().ConcatItems(_baseColorTexture, _metallicRoughnessTexture);
@@ -213,7 +212,6 @@ namespace SharpGLTF.Schema2
     {
     {
         internal MaterialPBRSpecularGlossiness(Material material) { }
         internal MaterialPBRSpecularGlossiness(Material material) { }
 
 
-        /// <inheritdoc />
         protected override IEnumerable<ExtraProperties> GetLogicalChildren()
         protected override IEnumerable<ExtraProperties> GetLogicalChildren()
         {
         {
             return base.GetLogicalChildren().ConcatItems(_diffuseTexture, _specularGlossinessTexture);
             return base.GetLogicalChildren().ConcatItems(_diffuseTexture, _specularGlossinessTexture);

+ 0 - 1
src/SharpGLTF.Core/Schema2/gltf.Mesh.cs

@@ -70,7 +70,6 @@ namespace SharpGLTF.Schema2
             }
             }
         }
         }
 
 
-        /// <inheritdoc />
         protected override IEnumerable<ExtraProperties> GetLogicalChildren()
         protected override IEnumerable<ExtraProperties> GetLogicalChildren()
         {
         {
             return base.GetLogicalChildren().Concat(_primitives);
             return base.GetLogicalChildren().Concat(_primitives);

+ 8 - 27
src/SharpGLTF.Core/Schema2/gltf.MeshPrimitive.cs

@@ -103,7 +103,7 @@ namespace SharpGLTF.Schema2
             }
             }
 
 
             var indices = accessors
             var indices = accessors
-                .Select(item => item._LogicalBufferViewIndex)
+                .Select(item => item._SourceBufferViewIndex)
                 .Where(item => item >= 0)
                 .Where(item => item >= 0)
                 .Distinct();
                 .Distinct();
 
 
@@ -265,7 +265,7 @@ namespace SharpGLTF.Schema2
                 if (incompatibleMode) result.AddLinkWarning("Indices", $"Number of vertices or indices({IndexAccessor.Count}) is not compatible with used drawing mode('{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
+            // check attributes accessors
 
 
             foreach (var group in this.VertexAccessors.Values.GroupBy(item => item.SourceBufferView))
             foreach (var group in this.VertexAccessors.Values.GroupBy(item => item.SourceBufferView))
             {
             {
@@ -280,37 +280,16 @@ namespace SharpGLTF.Schema2
                     }
                     }
 
 
                     // now, there's two possible outcomes:
                     // now, there's two possible outcomes:
-                    // - sequential accessors: accessor data comes one after another.
-                    // - strided accessors: the sum of all accessors must match bytestride
+                    // - sequential accessors: all accessors's ElementByteStride should be EQUAL to BufferView's ByteStride
+                    // - strided accessors: all accessors's ElementByteStride should SUM to BufferView's ByteStride
 
 
-                    if (group.All(item => item.ItemByteSize.WordPadded() == group.Key.ByteStride))
+                    if (group.All(item => item.ElementByteSize.WordPadded() == group.Key.ByteStride))
                     {
                     {
                         // sequential format.
                         // sequential format.
-
-                        // all accessor are laid sequentially, so they must not overlap.
-
-                        var accessors = group.OrderBy(item => item.ByteOffset);
-                        var bvByteOffset = accessors.First().ByteOffset;
-
-                        int pointer = 0;
-
-                        foreach (var accessor in accessors)
-                        {
-                            var accessorStartOffset = accessor.ByteOffset - bvByteOffset;
-                            var accessorByteCount = accessor.ItemByteSize.WordPadded() * accessor.Count;
-
-                            if (accessorStartOffset < pointer) result.AddLinkError("Attributes", "Accessors overlapping found.");
-
-                            pointer += accessorByteCount;
-                        }
                     }
                     }
-                    else if (group.Sum(item => item.ItemByteSize.WordPadded()) == group.Key.ByteStride)
+                    else if (group.Sum(item => item.ElementByteSize.WordPadded()) == group.Key.ByteStride)
                     {
                     {
                         // strided format.
                         // strided format.
-
-                        var accessors = group.OrderBy(item => item.ByteOffset);
-                        var bvByteOffset = accessors.First().ByteOffset;
-                        var bvByteCount = group.Key.ByteStride * vertexCount;
                     }
                     }
                     else
                     else
                     {
                     {
@@ -320,6 +299,8 @@ namespace SharpGLTF.Schema2
                 }
                 }
             }
             }
 
 
+            // check vertex attributes
+
             _ValidatePositions(result);
             _ValidatePositions(result);
             _ValidateNormals(result);
             _ValidateNormals(result);
             _ValidateTangents(result);
             _ValidateTangents(result);

+ 0 - 1
src/SharpGLTF.Core/Schema2/gltf.Root.cs

@@ -96,7 +96,6 @@ namespace SharpGLTF.Schema2
         public IReadOnlyList<Scene>             LogicalScenes           => _scenes;
         public IReadOnlyList<Scene>             LogicalScenes           => _scenes;
         public IReadOnlyList<Animation>         LogicalAnimations       => _animations;
         public IReadOnlyList<Animation>         LogicalAnimations       => _animations;
 
 
-        /// <inheritdoc />
         protected override IEnumerable<ExtraProperties> GetLogicalChildren()
         protected override IEnumerable<ExtraProperties> GetLogicalChildren()
         {
         {
             var containers = base.GetLogicalChildren();
             var containers = base.GetLogicalChildren();

+ 0 - 1
src/SharpGLTF.Core/Schema2/khr.lights.cs

@@ -14,7 +14,6 @@ namespace SharpGLTF.Schema2
             _lights = new ChildrenCollection<PunctualLight, ModelRoot>(root);
             _lights = new ChildrenCollection<PunctualLight, ModelRoot>(root);
         }
         }
 
 
-        /// <inheritdoc />
         protected override IEnumerable<ExtraProperties> GetLogicalChildren()
         protected override IEnumerable<ExtraProperties> GetLogicalChildren()
         {
         {
             return base.GetLogicalChildren().Concat(_lights);
             return base.GetLogicalChildren().Concat(_lights);

+ 14 - 0
src/SharpGLTF.Core/Validation/ValidationContext.cs

@@ -99,6 +99,16 @@ namespace SharpGLTF.Validation
 
 
         #region schema errors
         #region schema errors
 
 
+        public bool CheckSchemaIsDefined<T>(ValueLocation location, T value)
+            where T : class
+        {
+            if (value != null) return true;
+
+            AddSchemaError(location, "must be defined.");
+
+            return false;
+        }
+
         public bool CheckSchemaIsDefined<T>(ValueLocation location, T? value)
         public bool CheckSchemaIsDefined<T>(ValueLocation location, T? value)
             where T : struct
             where T : struct
         {
         {
@@ -353,10 +363,14 @@ namespace SharpGLTF.Validation
     {
     {
         public static implicit operator ValueLocation(int index) { return new ValueLocation(string.Empty, index); }
         public static implicit operator ValueLocation(int index) { return new ValueLocation(string.Empty, index); }
 
 
+        public static implicit operator ValueLocation(int? index) { return new ValueLocation(string.Empty, index ?? 0); }
+
         public static implicit operator ValueLocation(string name) { return new ValueLocation(name); }
         public static implicit operator ValueLocation(string name) { return new ValueLocation(name); }
 
 
         public static implicit operator ValueLocation((string, int) tuple) { return new ValueLocation(tuple.Item1, tuple.Item2); }
         public static implicit operator ValueLocation((string, int) tuple) { return new ValueLocation(tuple.Item1, tuple.Item2); }
 
 
+        public static implicit operator ValueLocation((string, int?) tuple) { return new ValueLocation(tuple.Item1, tuple.Item2 ?? 0); }
+
         public static implicit operator String(ValueLocation location) { return location.ToString(); }
         public static implicit operator String(ValueLocation location) { return location.ToString(); }
 
 
         private ValueLocation(string name, int idx1 = -1)
         private ValueLocation(string name, int idx1 = -1)

+ 3 - 4
tests/SharpGLTF.Tests/Reports.cs

@@ -140,10 +140,9 @@ namespace SharpGLTF.Reporting
         {
         {
             var rrrr = new ModelReport();
             var rrrr = new ModelReport();
 
 
-            foreach (var bv in model.LogicalBufferViews.Where(item => item.DeviceBufferTarget == BufferMode.ARRAY_BUFFER)) rrrr._VertexBuffers.Add(bv.Content.Count);
-            foreach (var iv in model.LogicalBufferViews.Where(item => item.DeviceBufferTarget == BufferMode.ELEMENT_ARRAY_BUFFER)) rrrr._IndexBuffers.Add(iv.Content.Count);
-            foreach (var dv in model.LogicalBufferViews.Where(item => item.DeviceBufferTarget == null)) rrrr._DataBuffers.Add(dv.Content.Count);
-
+            foreach (var vb in model.LogicalBufferViews.Where(item => item.IsVertexBuffer)) rrrr._VertexBuffers.Add(vb.Content.Count);
+            foreach (var ib in model.LogicalBufferViews.Where(item => item.IsIndexBuffer)) rrrr._IndexBuffers.Add(ib.Content.Count);
+            foreach (var db in model.LogicalBufferViews.Where(item => item.IsDataBuffer)) rrrr._DataBuffers.Add(db.Content.Count);
 
 
             foreach (var mesh in model.LogicalMeshes)
             foreach (var mesh in model.LogicalMeshes)
             {
             {

+ 2 - 2
tests/SharpGLTF.Tests/Schema2/Authoring/MeshBuilderCreationTests.cs

@@ -104,8 +104,8 @@ namespace SharpGLTF.Schema2.Authoring
             // checks
             // checks
             Assert.AreEqual(1, model.LogicalBuffers.Count);
             Assert.AreEqual(1, model.LogicalBuffers.Count);
             Assert.AreEqual(2, model.LogicalBufferViews.Count);
             Assert.AreEqual(2, model.LogicalBufferViews.Count);
-            Assert.AreEqual(BufferMode.ARRAY_BUFFER, model.LogicalBufferViews[0].DeviceBufferTarget);
-            Assert.AreEqual(BufferMode.ELEMENT_ARRAY_BUFFER, model.LogicalBufferViews[1].DeviceBufferTarget);
+            Assert.IsTrue(model.LogicalBufferViews[0].IsVertexBuffer);
+            Assert.IsTrue(model.LogicalBufferViews[1].IsIndexBuffer);
             Assert.AreEqual(2, model.LogicalMaterials.Count);
             Assert.AreEqual(2, model.LogicalMaterials.Count);
 
 
             model.AttachToCurrentTest("result.glb");
             model.AttachToCurrentTest("result.glb");

+ 25 - 3
tests/SharpGLTF.Tests/Schema2/LoadAndSave/LoadSampleTests.cs

@@ -44,8 +44,6 @@ namespace SharpGLTF.Schema2.LoadAndSave
                 Assert.Fail(ex.Message);
                 Assert.Fail(ex.Message);
             }
             }
 
 
-
-
             var perf_load = perf.ElapsedMilliseconds;
             var perf_load = perf.ElapsedMilliseconds;
 
 
             // do a model clone and compare it
             // do a model clone and compare it
@@ -113,12 +111,36 @@ namespace SharpGLTF.Schema2.LoadAndSave
             TestContext.CurrentContext.AttachShowDirLink();
             TestContext.CurrentContext.AttachShowDirLink();
             TestContext.CurrentContext.AttachGltfValidatorLinks();
             TestContext.CurrentContext.AttachGltfValidatorLinks();
 
 
-            foreach (var f in TestFiles.GetBabylonJSModelsPaths())
+            foreach (var f in TestFiles.GetBabylonJSValidModelsPaths())
             {
             {
+                TestContext.Progress.WriteLine(f);
+
                 _LoadModel(f);
                 _LoadModel(f);
             }
             }
         }
         }
 
 
+        [Test]
+        public void LoadInvalidModelsFromBabylonJs()
+        {
+            TestContext.CurrentContext.AttachShowDirLink();
+            TestContext.CurrentContext.AttachGltfValidatorLinks();
+
+            foreach (var f in TestFiles.GetBabylonJSInvalidModelsPaths())
+            {
+                TestContext.Progress.WriteLine(f);
+
+                try
+                {
+                    var model = ModelRoot.Load(f);
+                    Assert.Fail("Should throw");
+                }
+                catch(Exception ex)
+                {
+                    TestContext.WriteLine(ex.Message);
+                }
+            }
+        }
+
         [TestCase("SpecGlossVsMetalRough.gltf")]
         [TestCase("SpecGlossVsMetalRough.gltf")]
         [TestCase(@"TextureTransformTest.gltf")]
         [TestCase(@"TextureTransformTest.gltf")]
         [TestCase(@"UnlitTest\glTF-Binary\UnlitTest.glb")]        
         [TestCase(@"UnlitTest\glTF-Binary\UnlitTest.glb")]        

+ 2 - 2
tests/SharpGLTF.Tests/Schema2/LoadAndSave/LoadSpecialModelsTest.cs

@@ -72,7 +72,7 @@ namespace SharpGLTF.Schema2.LoadAndSave
             }
             }
         }
         }
 
 
-        [Test]
+        // [Test]
         public void LoadUniVRM()
         public void LoadUniVRM()
         {
         {
             TestContext.CurrentContext.AttachShowDirLink();
             TestContext.CurrentContext.AttachShowDirLink();
@@ -85,7 +85,7 @@ namespace SharpGLTF.Schema2.LoadAndSave
             model.AttachToCurrentTest("AliceModel.glb");
             model.AttachToCurrentTest("AliceModel.glb");
         }
         }
 
 
-        [Test]
+        // [Test]
         public void LoadShrekshaoModel()
         public void LoadShrekshaoModel()
         {
         {
             TestContext.CurrentContext.AttachShowDirLink();
             TestContext.CurrentContext.AttachShowDirLink();

+ 15 - 2
tests/SharpGLTF.Tests/TestFiles.cs

@@ -66,6 +66,8 @@ namespace SharpGLTF
         private static readonly string _BabylonJsMeshesDir;
         private static readonly string _BabylonJsMeshesDir;
         private static readonly string _BabylonJsPlaygroundDir;
         private static readonly string _BabylonJsPlaygroundDir;
 
 
+        private static readonly string[] _BabylonJsInvalidFiles = {"seagulf.glb" };
+
         private static string _GeneratedModelsDir;        
         private static string _GeneratedModelsDir;        
 
 
         #endregion
         #endregion
@@ -124,14 +126,25 @@ namespace SharpGLTF
                 .ToList();
                 .ToList();
         }
         }
 
 
-        public static IReadOnlyList<string> GetBabylonJSModelsPaths()
+        public static IReadOnlyList<string> GetBabylonJSValidModelsPaths()
+        {
+            var files = GetModelPathsInDirectory(_BabylonJsMeshesDir);
+
+            return files
+                .OrderBy(item => item)
+                .Where(item => !item.Contains("\\AssetGenerator\\0.6\\"))
+                .Where(item => !_BabylonJsInvalidFiles.Any(ff => item.EndsWith(ff)))                
+                .ToList();
+        }
+
+        public static IReadOnlyList<string> GetBabylonJSInvalidModelsPaths()
         {
         {
             var files = GetModelPathsInDirectory(_BabylonJsMeshesDir);
             var files = GetModelPathsInDirectory(_BabylonJsMeshesDir);
 
 
             return files
             return files
                 .OrderBy(item => item)
                 .OrderBy(item => item)
                 .Where(item => !item.Contains("\\AssetGenerator\\0.6\\"))
                 .Where(item => !item.Contains("\\AssetGenerator\\0.6\\"))
-                .Where(item => !item.EndsWith("shaderBall.glb")) // invalid
+                .Where(item => _BabylonJsInvalidFiles.Any(ff => item.EndsWith(ff)))
                 .ToList();
                 .ToList();
         }
         }