Browse Source

Json Serialization has been refactored to use the new System.Text.Json, which will allow faster serialization with less memory footprint.
Also, dependency with Newtonsoft.Json has been removed.

Vicente Penades 6 years ago
parent
commit
b8c755435f
31 changed files with 817 additions and 671 deletions
  1. 28 10
      build/SharpGLTF.CodeGen/CodeGen/EmitCSharp.cs
  2. 17 7
      src/SharpGLTF.Core/IO/BinarySerialization.cs
  3. 17 3
      src/SharpGLTF.Core/IO/JsonCollections.cs
  4. 140 175
      src/SharpGLTF.Core/IO/JsonSerializable.cs
  5. 93 96
      src/SharpGLTF.Core/IO/ReadContext.cs
  6. 170 48
      src/SharpGLTF.Core/IO/Serialization.cs
  7. 4 4
      src/SharpGLTF.Core/IO/Unknown.cs
  8. 8 6
      src/SharpGLTF.Core/IO/WriteContext.cs
  9. 1 1
      src/SharpGLTF.Core/Memory/ColorArray.cs
  10. 5 5
      src/SharpGLTF.Core/Schema2/Generated/ext.MSFT.textureDDS.g.cs
  11. 18 18
      src/SharpGLTF.Core/Schema2/Generated/ext.ModelLightsPunctual.g.cs
  12. 5 5
      src/SharpGLTF.Core/Schema2/Generated/ext.NodeLightsPunctual.g.cs
  13. 8 8
      src/SharpGLTF.Core/Schema2/Generated/ext.TextureTransform.g.cs
  14. 4 4
      src/SharpGLTF.Core/Schema2/Generated/ext.Unlit.g.cs
  15. 9 9
      src/SharpGLTF.Core/Schema2/Generated/ext.pbrSpecularGlossiness.g.cs
  16. 5 5
      src/SharpGLTF.Core/Schema2/Generated/ext.textureWEBP.g.cs
  17. 200 200
      src/SharpGLTF.Core/Schema2/Generated/gltf.g.cs
  18. 1 1
      src/SharpGLTF.Core/Schema2/gltf.Buffer.cs
  19. 13 11
      src/SharpGLTF.Core/Schema2/gltf.ExtraProperties.cs
  20. 1 1
      src/SharpGLTF.Core/Schema2/gltf.Images.cs
  21. 30 19
      src/SharpGLTF.Core/Schema2/gltf.Serialization.Read.cs
  22. 24 19
      src/SharpGLTF.Core/Schema2/gltf.Serialization.Write.cs
  23. 2 2
      src/SharpGLTF.Core/SharpGLTF.Core.csproj
  24. 1 1
      src/SharpGLTF.Core/Validation/ModelException.cs
  25. 1 1
      src/SharpGLTF.Core/Validation/ValidationContext.cs
  26. 2 5
      src/SharpGLTF.Toolkit/IO/Zip.cs
  27. 3 1
      tests/SharpGLTF.Tests/Collections/ChildrenCollectionTests.cs
  28. 1 1
      tests/SharpGLTF.Tests/Schema2/Authoring/BasicSceneCreationTests.cs
  29. 2 2
      tests/SharpGLTF.Tests/Schema2/LoadAndSave/LoadSpecialModelsTest.cs
  30. 3 2
      tests/SharpGLTF.Tests/SharpGLTF.Tests.csproj
  31. 1 1
      tests/SharpGLTF.Tests/Utils.cs

+ 28 - 10
build/SharpGLTF.CodeGen/CodeGen/EmitCSharp.cs

@@ -1,4 +1,6 @@
-using System;
+// #define USENEWTONSOFT
+
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Reflection;
@@ -331,7 +333,12 @@ namespace SharpGLTF.CodeGen
             sb.AppendLine("using System.Linq;");
             sb.AppendLine("using System.Text;");
             sb.AppendLine("using System.Numerics;");
+
+            #if USENEWTONSOFT
             sb.AppendLine("using Newtonsoft.Json;");
+            #else
+            sb.AppendLine("using System.Text.Json;");
+            #endif
             sb.AppendLine();
 
             sb.AppendLine($"namespace {Constants.OutputNamespace}");
@@ -471,7 +478,7 @@ namespace SharpGLTF.CodeGen
             yield return string.Empty;
         }            
 
-        #endregion
+#endregion
     }
 
     /// <summary>
@@ -503,6 +510,8 @@ namespace SharpGLTF.CodeGen
 
         public bool HasBaseClass { get; set; }
 
+        private const string _READERMODIFIER = "ref ";
+
         #endregion
 
         #region API
@@ -526,7 +535,7 @@ namespace SharpGLTF.CodeGen
                     this.AddFieldSerializerCase(smethod);
 
                     // emit deserializer
-                    this.AddFieldDeserializerCase(f.PersistentName, $"{frname} = DeserializePropertyValue<{_Emitter._GetRuntimeName(etype)}>(reader);");
+                    this.AddFieldDeserializerCase(f.PersistentName, $"{frname} = DeserializePropertyValue<{_Emitter._GetRuntimeName(etype)}>({_READERMODIFIER}reader);");
 
                     continue;
                 }
@@ -565,15 +574,15 @@ namespace SharpGLTF.CodeGen
             if (f.FieldType is ArrayType atype)
             {
                 var titem = _Emitter._GetRuntimeName(atype.ItemType);
-                return $"DeserializePropertyList<{titem}>(reader, {fname});";
+                return $"DeserializePropertyList<{titem}>({_READERMODIFIER}reader, {fname});";
             }
             else if (f.FieldType is DictionaryType dtype)
             {
                 var titem = _Emitter._GetRuntimeName(dtype.ValueType);
-                return $"DeserializePropertyDictionary<{titem}>(reader, {fname});";
+                return $"DeserializePropertyDictionary<{titem}>({_READERMODIFIER}reader, {fname});";
             }
 
-            return $"{fname} = DeserializePropertyValue<{_Emitter._GetRuntimeName(f.FieldType)}>(reader);";
+            return $"{fname} = DeserializePropertyValue<{_Emitter._GetRuntimeName(f.FieldType)}>({_READERMODIFIER}reader);";
         }        
 
         public void AddFieldSerializerCase(string line) { _SerializerBody.Add(line); }
@@ -585,6 +594,15 @@ namespace SharpGLTF.CodeGen
 
         public IEnumerable<string> EmitCode()
         {
+            #if USENEWTONSOFT
+            var readerType = "JsonReader";
+            var writerType = "JsonWriter";
+            #else
+            var readerType = "ref Utf8JsonReader";
+            var writerType = "Utf8JsonWriter";
+            #endif
+
+
             foreach (var l in ClassSummary.EmitSummary(0)) yield return l;
             
             yield return ClassDeclaration;
@@ -597,7 +615,7 @@ namespace SharpGLTF.CodeGen
             yield return string.Empty;
 
             // yield return "/// <inheritdoc />".Indent(1);
-            yield return "protected override void SerializeProperties(JsonWriter writer)".Indent(1);
+            yield return $"protected override void SerializeProperties({writerType} writer)".Indent(1);
             yield return "{".Indent(1);
             if (HasBaseClass) yield return "base.SerializeProperties(writer);".Indent(2);
             foreach (var l in _SerializerBody.Indent(2)) yield return l;
@@ -606,13 +624,13 @@ namespace SharpGLTF.CodeGen
             yield return string.Empty;
 
             // 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, {readerType} reader)".Indent(1);
             yield return "{".Indent(1);
             yield return "switch (jsonPropertyName)".Indent(2);
             yield return "{".Indent(2);
 
             foreach (var l in _DeserializerSwitchBody.Indent(3)) yield return l;
-            if (HasBaseClass) yield return "default: base.DeserializeProperty(jsonPropertyName, reader); break;".Indent(3);
+            if (HasBaseClass) yield return $"default: base.DeserializeProperty(jsonPropertyName,{_READERMODIFIER}reader); break;".Indent(3);
             else yield return "default: throw new NotImplementedException();".Indent(3);
 
             yield return "}".Indent(2);
@@ -623,6 +641,6 @@ namespace SharpGLTF.CodeGen
             yield return "}";
         }
 
-        #endregion
+#endregion
     }
 }

+ 17 - 7
src/SharpGLTF.Core/IO/BinarySerialization.cs

@@ -20,6 +20,17 @@ namespace SharpGLTF.Schema2
 
         #region read
 
+        public static bool IsBinaryHeader(Byte a, Byte b, Byte c, Byte d)
+        {
+            uint magic = 0;
+            magic |= (uint)a;
+            magic |= (uint)b << 8;
+            magic |= (uint)c << 16;
+            magic |= (uint)d << 24;
+
+            return magic == GLTFHEADER;
+        }
+
         internal static bool _Identify(Stream stream)
         {
             Guard.NotNull(stream, nameof(stream));
@@ -27,15 +38,14 @@ namespace SharpGLTF.Schema2
 
             var currPos = stream.Position;
 
-            uint magic = 0;
-            magic |= (uint)stream.ReadByte();
-            magic |= (uint)stream.ReadByte() << 8;
-            magic |= (uint)stream.ReadByte() << 16;
-            magic |= (uint)stream.ReadByte() << 24;
+            var a = stream.ReadByte();
+            var b = stream.ReadByte();
+            var c = stream.ReadByte();
+            var d = stream.ReadByte();
 
             stream.Position = currPos; // restart read position
 
-            return magic == GLTFHEADER;
+            return IsBinaryHeader((Byte)a, (Byte)b, (Byte)c, (Byte)d);
         }
 
         public static IReadOnlyDictionary<UInt32, Byte[]> ReadBinaryFile(Stream stream)
@@ -132,7 +142,7 @@ namespace SharpGLTF.Schema2
         {
             var ex = IsBinaryCompatible(model); if (ex != null) throw ex;
 
-            var jsonText = model.GetJSON(Newtonsoft.Json.Formatting.None);
+            var jsonText = model.GetJSON(false);
             var jsonChunk = Encoding.UTF8.GetBytes(jsonText);
             var jsonPadding = jsonChunk.Length & 3; if (jsonPadding != 0) jsonPadding = 4 - jsonPadding;
 

+ 17 - 3
src/SharpGLTF.Core/IO/Json.cs → src/SharpGLTF.Core/IO/JsonCollections.cs

@@ -2,12 +2,26 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
+using System.Text.Json;
 
 namespace SharpGLTF.IO
 {
     static class JsonUtils
     {
-        public static bool IsSerializable(Object value)
+        public static ArraySegment<Byte> ReadBytesToEnd(this System.IO.Stream s)
+        {
+            using (var m = new System.IO.MemoryStream())
+            {
+                s.CopyTo(m);
+                if (m.TryGetBuffer(out ArraySegment<Byte> segment)) return segment;
+
+                var array = m.ToArray();
+
+                return new ArraySegment<byte>(array);
+            }
+        }
+
+        public static bool IsJsonSerializable(Object value)
         {
             if (value == null) return false;
 
@@ -23,12 +37,12 @@ namespace SharpGLTF.IO
 
             if (value is JsonList list)
             {
-                return list.All(item => IsSerializable(item));
+                return list.All(item => IsJsonSerializable(item));
             }
 
             if (value is JsonDictionary dict)
             {
-                return dict.Values.All(item => IsSerializable(item));
+                return dict.Values.All(item => IsJsonSerializable(item));
             }
 
             return false;

+ 140 - 175
src/SharpGLTF.Core/IO/JsonSerializable.cs

@@ -4,7 +4,10 @@ using System.Linq;
 using System.Numerics;
 using System.Text;
 
-using Newtonsoft.Json;
+using System.Text.Json;
+
+using JSONEXCEPTION = System.Text.Json.JsonException;
+using JSONTOKEN = System.Text.Json.JsonTokenType;
 
 namespace SharpGLTF.IO
 {
@@ -34,7 +37,7 @@ namespace SharpGLTF.IO
 
         #region serialization
 
-        internal void Serialize(JsonWriter writer)
+        internal void Serialize(Utf8JsonWriter writer)
         {
             Guard.NotNull(writer, nameof(writer));
 
@@ -43,63 +46,58 @@ namespace SharpGLTF.IO
             writer.WriteEndObject();
         }
 
-        protected abstract void SerializeProperties(JsonWriter writer);
+        protected abstract void SerializeProperties(Utf8JsonWriter writer);
 
-        protected static void SerializeProperty(JsonWriter writer, string name, Object value)
+        protected static void SerializeProperty(Utf8JsonWriter writer, string name, Object value)
         {
             if (value == null) return;
 
             Guard.NotNull(writer, nameof(writer));
 
-            writer.WritePropertyName(name);
-            _Serialize(writer, value);
+            _SerializeProperty(writer, name, value);
         }
 
-        protected static void SerializeProperty(JsonWriter writer, string name, Boolean? value, Boolean? defval = null)
+        protected static void SerializeProperty(Utf8JsonWriter writer, string name, Boolean? value, Boolean? defval = null)
         {
             if (!value.HasValue) return;
             if (defval.HasValue && defval.Value.Equals(value.Value)) return;
 
             Guard.NotNull(writer, nameof(writer));
 
-            writer.WritePropertyName(name);
-            writer.WriteValue(value.Value);
+            writer.WriteBoolean(name, value.Value);
         }
 
-        protected static void SerializeProperty(JsonWriter writer, string name, Int32? value, Int32? defval = null)
+        protected static void SerializeProperty(Utf8JsonWriter writer, string name, Int32? value, Int32? defval = null)
         {
             if (!value.HasValue) return;
             if (defval.HasValue && defval.Value.Equals(value.Value)) return;
 
             Guard.NotNull(writer, nameof(writer));
 
-            writer.WritePropertyName(name);
-            writer.WriteValue(value.Value);
+            writer.WriteNumber(name, value.Value);
         }
 
-        protected static void SerializeProperty(JsonWriter writer, string name, Single? value, Single? defval = null)
+        protected static void SerializeProperty(Utf8JsonWriter writer, string name, Single? value, Single? defval = null)
         {
             if (!value.HasValue) return;
             if (defval.HasValue && defval.Value.Equals(value.Value)) return;
 
             Guard.NotNull(writer, nameof(writer));
 
-            writer.WritePropertyName(name);
-            writer.WriteValue(value.Value);
+            writer.WriteNumber(name, value.Value);
         }
 
-        protected static void SerializeProperty(JsonWriter writer, string name, Double? value, Double? defval = null)
+        protected static void SerializeProperty(Utf8JsonWriter writer, string name, Double? value, Double? defval = null)
         {
             if (!value.HasValue) return;
             if (defval.HasValue && defval.Value.Equals(value.Value)) return;
 
             Guard.NotNull(writer, nameof(writer));
 
-            writer.WritePropertyName(name);
-            writer.WriteValue(value.Value);
+            writer.WriteNumber(name, value.Value);
         }
 
-        protected static void SerializeProperty(JsonWriter writer, string name, Vector2? value, Vector2? defval = null)
+        protected static void SerializeProperty(Utf8JsonWriter writer, string name, Vector2? value, Vector2? defval = null)
         {
             if (!value.HasValue) return;
             if (defval.HasValue && defval.Value.Equals(value.Value)) return;
@@ -107,10 +105,10 @@ namespace SharpGLTF.IO
             Guard.NotNull(writer, nameof(writer));
 
             writer.WritePropertyName(name);
-            _Serialize(writer, value.Value);
+            writer.WriteVector2(value.Value);
         }
 
-        protected static void SerializeProperty(JsonWriter writer, string name, Vector3? value, Vector3? defval = null)
+        protected static void SerializeProperty(Utf8JsonWriter writer, string name, Vector3? value, Vector3? defval = null)
         {
             if (!value.HasValue) return;
             if (defval.HasValue && defval.Value.Equals(value.Value)) return;
@@ -118,10 +116,10 @@ namespace SharpGLTF.IO
             Guard.NotNull(writer, nameof(writer));
 
             writer.WritePropertyName(name);
-            _Serialize(writer, value.Value);
+            writer.WriteVector3(value.Value);
         }
 
-        protected static void SerializeProperty(JsonWriter writer, string name, Vector4? value, Vector4? defval = null)
+        protected static void SerializeProperty(Utf8JsonWriter writer, string name, Vector4? value, Vector4? defval = null)
         {
             if (!value.HasValue) return;
             if (defval.HasValue && defval.Value.Equals(value.Value)) return;
@@ -129,10 +127,10 @@ namespace SharpGLTF.IO
             Guard.NotNull(writer, nameof(writer));
 
             writer.WritePropertyName(name);
-            _Serialize(writer, value.Value);
+            writer.WriteVector4(value.Value);
         }
 
-        protected static void SerializeProperty(JsonWriter writer, string name, Quaternion? value, Quaternion? defval = null)
+        protected static void SerializeProperty(Utf8JsonWriter writer, string name, Quaternion? value, Quaternion? defval = null)
         {
             if (!value.HasValue) return;
             if (defval.HasValue && defval.Value.Equals(value.Value)) return;
@@ -140,10 +138,10 @@ namespace SharpGLTF.IO
             Guard.NotNull(writer, nameof(writer));
 
             writer.WritePropertyName(name);
-            _Serialize(writer, value.Value);
+            writer.WriteQuaternion(value.Value);
         }
 
-        protected static void SerializeProperty(JsonWriter writer, string name, Matrix4x4? value, Matrix4x4? defval = null)
+        protected static void SerializeProperty(Utf8JsonWriter writer, string name, Matrix4x4? value, Matrix4x4? defval = null)
         {
             if (!value.HasValue) return;
             if (defval.HasValue && defval.Value.Equals(value.Value)) return;
@@ -151,10 +149,10 @@ namespace SharpGLTF.IO
             Guard.NotNull(writer, nameof(writer));
 
             writer.WritePropertyName(name);
-            _Serialize(writer, value.Value);
+            writer.WriteMatrix4x4(value.Value);
         }
 
-        protected static void SerializePropertyEnumValue<T>(JsonWriter writer, string name, T? value, T? defval = null)
+        protected static void SerializePropertyEnumValue<T>(Utf8JsonWriter writer, string name, T? value, T? defval = null)
             where T : struct
         {
             Guard.IsTrue(typeof(T).IsEnum, nameof(T));
@@ -164,10 +162,10 @@ namespace SharpGLTF.IO
 
             Guard.NotNull(writer, nameof(writer));
 
-            SerializeProperty(writer, name, (int)(Object)value);
+            writer.WriteNumber(name, (int)(Object)value);
         }
 
-        protected static void SerializePropertyEnumSymbol<T>(JsonWriter writer, string name, T? value, T? defval = null)
+        protected static void SerializePropertyEnumSymbol<T>(Utf8JsonWriter writer, string name, T? value, T? defval = null)
             where T : struct
         {
             Guard.IsTrue(typeof(T).IsEnum, nameof(T));
@@ -177,21 +175,20 @@ namespace SharpGLTF.IO
 
             Guard.NotNull(writer, nameof(writer));
 
-            SerializeProperty(writer, name, Enum.GetName(typeof(T), value));
+            writer.WriteString(name, Enum.GetName(typeof(T), value));
         }
 
-        protected static void SerializePropertyObject<T>(JsonWriter writer, string name, T value)
+        protected static void SerializePropertyObject<T>(Utf8JsonWriter writer, string name, T value)
             where T : JsonSerializable
         {
             if (value == null) return;
 
             Guard.NotNull(writer, nameof(writer));
 
-            writer.WritePropertyName(name);
-            _Serialize(writer, value);
+            _SerializeProperty(writer, name, value);
         }
 
-        protected static void SerializeProperty<T>(JsonWriter writer, string name, IReadOnlyList<T> collection, int? minItems = 1)
+        protected static void SerializeProperty<T>(Utf8JsonWriter writer, string name, IReadOnlyList<T> collection, int? minItems = 1)
         {
             if (collection == null) return;
             if (minItems.HasValue && collection.Count < minItems.Value) return;
@@ -201,15 +198,13 @@ namespace SharpGLTF.IO
             writer.WritePropertyName(name);
 
             writer.WriteStartArray();
-            foreach (var item in collection)
-            {
-                _Serialize(writer, item);
-            }
+
+            foreach (var item in collection) _SerializeValue(writer, item);
 
             writer.WriteEndArray();
         }
 
-        protected static void SerializeProperty<T>(JsonWriter writer, string name, IReadOnlyDictionary<String, T> collection)
+        protected static void SerializeProperty<T>(Utf8JsonWriter writer, string name, IReadOnlyDictionary<String, T> collection)
         {
             if (collection == null) return;
             if (collection.Count < 1) return;
@@ -219,44 +214,31 @@ namespace SharpGLTF.IO
             writer.WritePropertyName(name);
 
             writer.WriteStartObject();
-            foreach (var item in collection)
-            {
-                writer.WritePropertyName(item.Key);
-                _Serialize(writer, item.Value);
-            }
+
+            foreach (var item in collection) _SerializeProperty(writer, item.Key, item.Value);
 
             writer.WriteEndObject();
         }
 
-        private static void _Serialize(JsonWriter writer, Object value)
+        private static void _SerializeProperty(Utf8JsonWriter writer, String name, Object value)
         {
             Guard.NotNull(writer, nameof(writer));
             Guard.NotNull(value, nameof(value));
 
-            System.Diagnostics.Debug.Assert(!value.GetType().IsEnum, "gltf schema does not define a typed way of serializing enums");
+            if (writer.TryWriteProperty(name, value)) return;
 
-            if (value is String vstr) { writer.WriteValue(vstr); return; }
-            if (value is Boolean vbol) { writer.WriteValue(vbol); return; }
-
-            if (value is Byte vu8) { writer.WriteValue(vu8); return; }
-            if (value is UInt16 vu16) { writer.WriteValue(vu16); return; }
-            if (value is UInt32 vu32) { writer.WriteValue(vu32); return; }
-            if (value is UInt64 vu64) { writer.WriteValue(vu64); return; }
+            writer.WritePropertyName(name);
+            _SerializeValue(writer, value);
+        }
 
-            if (value is SByte vs8) { writer.WriteValue(vs8); return; }
-            if (value is Int16 vs16) { writer.WriteValue(vs16); return; }
-            if (value is Int32 vs32) { writer.WriteValue(vs32); return; }
-            if (value is Int64 vs64) { writer.WriteValue(vs64); return; }
+        private static void _SerializeValue(Utf8JsonWriter writer, Object value)
+        {
+            Guard.NotNull(writer, nameof(writer));
+            Guard.NotNull(value, nameof(value));
 
-            if (value is Single vf32) { writer.WriteValue(vf32); return; }
-            if (value is Double vf64) { writer.WriteValue(vf64); return; }
-            if (value is Decimal vfxx) { writer.WriteValue(vfxx); return; }
+            System.Diagnostics.Debug.Assert(!value.GetType().IsEnum, "gltf schema does not define a typed way of serializing enums");
 
-            if (value is Vector2 vvv2) { writer.WriteVector2(vvv2); return; }
-            if (value is Vector3 vvv3) { writer.WriteVector3(vvv3); return; }
-            if (value is Vector4 vvv4) { writer.WriteVector4(vvv4); return; }
-            if (value is Quaternion qqq4) { writer.WriteQuaternion(qqq4); return; }
-            if (value is Matrix4x4 mm44) { writer.WriteMatrix4x4(mm44); return; }
+            if (writer.TryWriteValue(value)) return;
 
             if (value is JsonSerializable vgltf) { vgltf.Serialize(writer); return; }
 
@@ -265,6 +247,7 @@ namespace SharpGLTF.IO
                 if (dict.Count == 0) return;
 
                 writer.WriteStartObject();
+
                 foreach (var key in dict.Keys)
                 {
                     var val = dict[key];
@@ -278,11 +261,11 @@ namespace SharpGLTF.IO
                         if (val is System.Collections.IDictionary xdict && xdict.Count == 0) continue;
                     }
 
-                    writer.WritePropertyName(key.ToString());
-                    _Serialize(writer, val);
+                    _SerializeProperty(writer, key.ToString(), val);
                 }
 
                 writer.WriteEndObject();
+
                 return;
             }
 
@@ -291,12 +274,14 @@ namespace SharpGLTF.IO
                 if (list.Count == 0) return;
 
                 writer.WriteStartArray();
+
                 foreach (var item in list)
                 {
-                    _Serialize(writer, item);
+                    _SerializeValue(writer, item);
                 }
 
                 writer.WriteEndArray();
+
                 return;
             }
 
@@ -307,21 +292,19 @@ namespace SharpGLTF.IO
 
         #region deserialization
 
-        internal void Deserialize(JsonReader reader)
+        internal void Deserialize(ref Utf8JsonReader reader)
         {
-            Guard.NotNull(reader, nameof(reader));
+            if (reader.TokenType == JSONTOKEN.PropertyName) reader.Read();
 
-            if (reader.TokenType == JsonToken.PropertyName) reader.Read();
-
-            if (reader.TokenType == JsonToken.StartObject)
+            if (reader.TokenType == JSONTOKEN.StartObject)
             {
-                while (reader.Read() && reader.TokenType != JsonToken.EndObject)
+                while (reader.Read() && reader.TokenType != JSONTOKEN.EndObject)
                 {
-                    if (reader.TokenType == JsonToken.PropertyName)
+                    if (reader.TokenType == JSONTOKEN.PropertyName)
                     {
-                        var key = reader.Value as String;
+                        var key = reader.GetString();
 
-                        DeserializeProperty(key, reader);
+                        DeserializeProperty(key, ref reader);
                     }
                     else
                     {
@@ -335,202 +318,184 @@ namespace SharpGLTF.IO
             throw new NotImplementedException();
         }
 
-        protected static Object DeserializeUnknownObject(JsonReader reader)
+        protected static Object DeserializeUnknownObject(ref Utf8JsonReader reader)
         {
-            Guard.NotNull(reader, nameof(reader));
-
-            if (reader.TokenType == JsonToken.PropertyName) reader.Read();
+            if (reader.TokenType == JSONTOKEN.PropertyName) reader.Read();
 
-            if (reader.TokenType == JsonToken.StartArray)
+            if (reader.TokenType == JSONTOKEN.StartArray)
             {
                 var list = new JsonList();
 
-                while (reader.Read() && reader.TokenType != JsonToken.EndArray)
+                while (reader.Read() && reader.TokenType != JSONTOKEN.EndArray)
                 {
-                    list.Add(DeserializeUnknownObject(reader));
+                    list.Add(DeserializeUnknownObject(ref reader));
                 }
 
                 return list;
             }
 
-            if (reader.TokenType == JsonToken.StartObject)
+            if (reader.TokenType == JSONTOKEN.StartObject)
             {
                 var dict = new JsonDictionary();
 
-                while (reader.Read() && reader.TokenType != JsonToken.EndObject)
+                while (reader.Read() && reader.TokenType != JSONTOKEN.EndObject)
                 {
-                    if (reader.TokenType == JsonToken.PropertyName)
+                    if (reader.TokenType == JSONTOKEN.PropertyName)
                     {
-                        var key = reader.Value as String;
+                        var key = reader.GetString();
 
-                        dict[key] = DeserializeUnknownObject(reader);
+                        dict[key] = DeserializeUnknownObject(ref reader);
                     }
                     else
                     {
-                        throw new JsonReaderException();
+                        throw new JSONEXCEPTION();
                     }
                 }
 
                 return dict;
             }
 
-            System.Diagnostics.Debug.Assert(reader.TokenType != JsonToken.None);
-            System.Diagnostics.Debug.Assert(reader.TokenType != JsonToken.EndArray);
-            System.Diagnostics.Debug.Assert(reader.TokenType != JsonToken.EndObject);
-            System.Diagnostics.Debug.Assert(reader.TokenType != JsonToken.EndConstructor);
+            System.Diagnostics.Debug.Assert(reader.TokenType != JSONTOKEN.None);
+            System.Diagnostics.Debug.Assert(reader.TokenType != JSONTOKEN.EndArray);
+            System.Diagnostics.Debug.Assert(reader.TokenType != JSONTOKEN.EndObject);
+            // System.Diagnostics.Debug.Assert(reader.TokenType != JsonToken.EndConstructor);
 
-            return reader.Value;
+            return reader.GetAnyValue();
         }
 
-        protected abstract void DeserializeProperty(string jsonPropertyName, JsonReader reader);
+        protected abstract void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader);
 
-        protected static T DeserializePropertyValue<T>(JsonReader reader)
+        protected static T DeserializePropertyValue<T>(ref Utf8JsonReader reader)
         {
-            Guard.NotNull(reader, nameof(reader));
+            _TryCastValue(ref reader, typeof(T), out Object v);
 
-            _TryCastValue(reader, typeof(T), out Object v);
-
-            System.Diagnostics.Debug.Assert(reader.TokenType != JsonToken.StartArray);
-            System.Diagnostics.Debug.Assert(reader.TokenType != JsonToken.StartObject);
-            System.Diagnostics.Debug.Assert(reader.TokenType != JsonToken.PropertyName);
-            System.Diagnostics.Debug.Assert(reader.TokenType != JsonToken.StartConstructor);
+            System.Diagnostics.Debug.Assert(reader.TokenType != JSONTOKEN.StartArray);
+            System.Diagnostics.Debug.Assert(reader.TokenType != JSONTOKEN.StartObject);
+            System.Diagnostics.Debug.Assert(reader.TokenType != JSONTOKEN.PropertyName);
+            // System.Diagnostics.Debug.Assert(reader.TokenType != JsonToken.StartConstructor);
 
             return (T)v;
         }
 
-        protected static void DeserializePropertyList<T>(JsonReader reader, IList<T> list)
+        protected static void DeserializePropertyList<T>(ref Utf8JsonReader reader, IList<T> list)
         {
-            Guard.NotNull(reader, nameof(reader));
+            // Guard.NotNull(reader, nameof(reader));
             Guard.NotNull(list, nameof(list));
 
-            if (reader.TokenType == JsonToken.PropertyName) reader.Read();
-
-            if (reader.TokenType != JsonToken.StartArray) throw new JsonReaderException();
-            if (reader.TokenType == JsonToken.StartObject) throw new JsonReaderException();
+            if (reader.TokenType == JSONTOKEN.PropertyName) reader.Read();
 
-            var path2 = reader.Path;
+            if (reader.TokenType != JSONTOKEN.StartArray) throw new JSONEXCEPTION();
+            if (reader.TokenType == JSONTOKEN.StartObject) throw new JSONEXCEPTION();
 
-            while (reader.Read() && reader.TokenType != JsonToken.EndArray)
+            while (reader.Read() && reader.TokenType != JSONTOKEN.EndArray)
             {
-                if (_TryCastValue(reader, typeof(T), out Object item))
+                if (_TryCastValue(ref reader, typeof(T), out Object item))
                 {
                     list.Add((T)item);
                 }
 
-                System.Diagnostics.Debug.Assert(reader.TokenType != JsonToken.StartArray);
-                System.Diagnostics.Debug.Assert(reader.TokenType != JsonToken.StartObject);
-                System.Diagnostics.Debug.Assert(reader.TokenType != JsonToken.PropertyName);
-                System.Diagnostics.Debug.Assert(reader.TokenType != JsonToken.StartConstructor);
+                System.Diagnostics.Debug.Assert(reader.TokenType != JSONTOKEN.StartArray);
+                System.Diagnostics.Debug.Assert(reader.TokenType != JSONTOKEN.StartObject);
+                System.Diagnostics.Debug.Assert(reader.TokenType != JSONTOKEN.PropertyName);
+                // System.Diagnostics.Debug.Assert(reader.TokenType != JsonToken.StartConstructor);
             }
 
-            System.Diagnostics.Debug.Assert(reader.TokenType == JsonToken.EndArray);
+            System.Diagnostics.Debug.Assert(reader.TokenType == JSONTOKEN.EndArray);
         }
 
-        protected static void DeserializePropertyDictionary<T>(JsonReader reader, IDictionary<string, T> dict)
+        protected static void DeserializePropertyDictionary<T>(ref Utf8JsonReader reader, IDictionary<string, T> dict)
         {
-            Guard.NotNull(reader, nameof(reader));
             Guard.NotNull(dict, nameof(dict));
 
-            if (reader.TokenType == JsonToken.PropertyName) reader.Read();
+            if (reader.TokenType == JSONTOKEN.PropertyName) reader.Read();
 
-            if (reader.TokenType == JsonToken.StartArray) throw new JsonReaderException();
-            if (reader.TokenType != JsonToken.StartObject) throw new JsonReaderException();
+            if (reader.TokenType == JSONTOKEN.StartArray) throw new JSONEXCEPTION();
+            if (reader.TokenType != JSONTOKEN.StartObject) throw new JSONEXCEPTION();
 
-            while (reader.Read() && reader.TokenType != JsonToken.EndObject)
+            while (reader.Read() && reader.TokenType != JSONTOKEN.EndObject)
             {
-                if (reader.TokenType == JsonToken.PropertyName)
+                if (reader.TokenType == JSONTOKEN.PropertyName)
                 {
-                    var key = reader.Value as String;
+                    var key = reader.GetString();
 
-                    if (_TryCastValue(reader, typeof(T), out Object val))
+                    if (_TryCastValue(ref reader, typeof(T), out Object val))
                     {
                         dict[key] = (T)val;
                     }
 
-                    System.Diagnostics.Debug.Assert(reader.TokenType != JsonToken.StartArray);
-                    System.Diagnostics.Debug.Assert(reader.TokenType != JsonToken.StartObject);
-                    System.Diagnostics.Debug.Assert(reader.TokenType != JsonToken.PropertyName);
-                    System.Diagnostics.Debug.Assert(reader.TokenType != JsonToken.StartConstructor);
+                    System.Diagnostics.Debug.Assert(reader.TokenType != JSONTOKEN.StartArray);
+                    System.Diagnostics.Debug.Assert(reader.TokenType != JSONTOKEN.StartObject);
+                    System.Diagnostics.Debug.Assert(reader.TokenType != JSONTOKEN.PropertyName);
+                    // System.Diagnostics.Debug.Assert(reader.TokenType != JsonToken.StartConstructor);
                 }
             }
         }
 
-        private static bool _TryCastValue(JsonReader reader, Type vtype, out Object value)
+        private static bool _TryCastValue(ref Utf8JsonReader reader, Type vtype, out Object value)
         {
-            Guard.NotNull(reader, nameof(reader));
-
             value = null;
 
-            if (reader.TokenType == JsonToken.EndArray) return false;
-            if (reader.TokenType == JsonToken.EndObject) return false;
-            if (reader.TokenType == JsonToken.EndConstructor) return false;
+            if (reader.TokenType == JSONTOKEN.EndArray) return false;
+            if (reader.TokenType == JSONTOKEN.EndObject) return false;
+            // if (reader.TokenType == JsonToken.EndConstructor) return false;
 
-            if (reader.TokenType == JsonToken.PropertyName) reader.Read();
+            if (reader.TokenType == JSONTOKEN.PropertyName) reader.Read();
 
             // untangle nullable
             var ntype = Nullable.GetUnderlyingType(vtype);
             if (ntype != null) vtype = ntype;
 
-            if (vtype == typeof(String) ||
-                vtype == typeof(Boolean) ||
-                vtype == typeof(Int16) ||
-                vtype == typeof(Int32) ||
-                vtype == typeof(Int64) ||
-                vtype == typeof(UInt16) ||
-                vtype == typeof(UInt32) ||
-                vtype == typeof(UInt64) ||
-                vtype == typeof(Single) ||
-                vtype == typeof(Double))
-            {
-                value = Convert.ChangeType(reader.Value, vtype, System.Globalization.CultureInfo.InvariantCulture);
-                return true;
-            }
+            if (vtype == typeof(String)) { value = reader.AsString(); return true; }
+            if (vtype == typeof(Boolean)) { value = reader.AsBoolean(); return true; }
 
-            if (vtype.IsEnum)
-            {
-                if (reader.Value is String xstrVal) { value = Enum.Parse(vtype, xstrVal, true); return true; }
-                if (reader.Value is Int32 int32Val) { value = Enum.ToObject(vtype, int32Val); return true; }
-                if (reader.Value is Int64 int64Val) { value = Enum.ToObject(vtype, int64Val); return true; }
+            if (vtype == typeof(Int16)) { value = reader.GetInt16(); return true; }
+            if (vtype == typeof(Int32)) { value = reader.GetInt32(); return true; }
+            if (vtype == typeof(Int64)) { value = reader.GetInt64(); return true; }
+            if (vtype == typeof(UInt16)) { value = reader.GetUInt16(); return true; }
+            if (vtype == typeof(UInt32)) { value = reader.GetUInt32(); return true; }
+            if (vtype == typeof(UInt64)) { value = reader.GetUInt64(); return true; }
+            if (vtype == typeof(Single)) { value = reader.GetSingle(); return true; }
+            if (vtype == typeof(Double)) { value = reader.GetDouble(); return true; }
+            if (vtype == typeof(Decimal)) { value = reader.GetDecimal(); return true; }
 
-                throw new NotImplementedException();
-            }
+            if (vtype.IsEnum) { value = reader.AsEnum(vtype); return true; }
 
             if (vtype == typeof(Vector2))
             {
-                var l = new List<float>();
-                DeserializePropertyList<float>(reader, l);
+                var l = new List<float>(2);
+                DeserializePropertyList<float>(ref reader, l);
                 value = new Vector2(l[0], l[1]);
                 return true;
             }
 
             if (vtype == typeof(Vector3))
             {
-                var l = new List<float>();
-                DeserializePropertyList<float>(reader, l);
+                var l = new List<float>(3);
+                DeserializePropertyList<float>(ref reader, l);
                 value = new Vector3(l[0], l[1], l[2]);
                 return true;
             }
 
             if (vtype == typeof(Vector4))
             {
-                var l = new List<float>();
-                DeserializePropertyList<float>(reader, l);
+                var l = new List<float>(4);
+                DeserializePropertyList<float>(ref reader, l);
                 value = new Vector4(l[0], l[1], l[2], l[3]);
                 return true;
             }
 
             if (vtype == typeof(Quaternion))
             {
-                var l = new List<float>();
-                DeserializePropertyList<float>(reader, l);
+                var l = new List<float>(4);
+                DeserializePropertyList<float>(ref reader, l);
                 value = new System.Numerics.Quaternion(l[0], l[1], l[2], l[3]);
                 return true;
             }
 
             if (vtype == typeof(Matrix4x4))
             {
-                var l = new List<float>();
-                DeserializePropertyList<float>(reader, l);
+                var l = new List<float>(16);
+                DeserializePropertyList<float>(ref reader, l);
                 value = new Matrix4x4
                     (
                     l[0], l[1], l[2], l[3],
@@ -545,9 +510,9 @@ namespace SharpGLTF.IO
             {
                 var item = Activator.CreateInstance(vtype, true) as JsonSerializable;
 
-                System.Diagnostics.Debug.Assert(reader.TokenType == JsonToken.StartObject);
-                item.Deserialize(reader);
-                System.Diagnostics.Debug.Assert(reader.TokenType == JsonToken.EndObject);
+                System.Diagnostics.Debug.Assert(reader.TokenType == JSONTOKEN.StartObject);
+                item.Deserialize(ref reader);
+                System.Diagnostics.Debug.Assert(reader.TokenType == JSONTOKEN.EndObject);
 
                 value = item;
 
@@ -563,7 +528,7 @@ namespace SharpGLTF.IO
                     if (valType == typeof(Int32))
                     {
                         var dict = new Dictionary<string, Int32>();
-                        DeserializePropertyDictionary(reader, dict);
+                        DeserializePropertyDictionary(ref reader, dict);
                         value = dict;
                         return true;
                     }

+ 93 - 96
src/SharpGLTF.Core/IO/ReadContext.cs

@@ -4,7 +4,8 @@ using System.IO;
 using System.Linq;
 using System.Text;
 
-using Newtonsoft.Json;
+// using Newtonsoft.Json;
+using System.Text.Json;
 using SharpGLTF.Schema2;
 
 using BYTES = System.ArraySegment<byte>;
@@ -78,7 +79,7 @@ namespace SharpGLTF.IO
 
         #endregion
 
-        #region API
+        #region API - File System
 
         public BYTES ReadAllBytesToEnd(string fileName)
         {
@@ -102,22 +103,21 @@ namespace SharpGLTF.IO
             return new MemoryStream(content.Array, content.Offset, content.Count);
         }
 
-        public String ReadJson(Stream stream)
-        {
-            Guard.NotNull(stream, nameof(stream));
+        #endregion
 
-            bool binaryFile = BinarySerialization._Identify(stream);
+        #region API
 
-            if (binaryFile)
+        public Validation.ValidationResult Validate(string filePath)
+        {
+            using (var stream = File.OpenRead(filePath))
             {
-                var chunks = BinarySerialization.ReadBinaryFile(stream);
+                bool isBinary = BinarySerialization._Identify(stream);
 
-                return Encoding.UTF8.GetString(chunks[BinarySerialization.CHUNKJSON]);
-            }
+                if (isBinary) return _ReadGLB(stream).Validation;
 
-            using (var streamReader = new StreamReader(stream))
-            {
-                return streamReader.ReadToEnd();
+                var json = stream.ReadBytesToEnd();
+
+                return _Read(json).Validation;
             }
         }
 
@@ -129,41 +129,37 @@ namespace SharpGLTF.IO
         public SCHEMA2 ReadSchema2(Stream stream)
         {
             Guard.NotNull(stream, nameof(stream));
+            Guard.IsTrue(stream.CanRead, nameof(stream));
 
             bool binaryFile = BinarySerialization._Identify(stream);
 
             return binaryFile ? ReadBinarySchema2(stream) : ReadTextSchema2(stream);
         }
 
-        /// <summary>
-        /// Reads a <see cref="SCHEMA2"/> instance from a <see cref="Stream"/> containing a GLTF file.
-        /// </summary>
-        /// <param name="stream">A <see cref="Stream"/> to read from.</param>
-        /// <returns>A <see cref="SCHEMA2"/> instance.</returns>
-        public SCHEMA2 ReadTextSchema2(Stream stream)
+        internal SCHEMA2 _ReadFromDictionary(string fileName)
         {
-            Guard.NotNull(stream, nameof(stream));
+            var json = this.ReadAllBytesToEnd(fileName);
 
-            string content = null;
+            var mv = this._Read(json);
 
-            using (var streamReader = new StreamReader(stream))
-            {
-                content = streamReader.ReadToEnd();
-            }
+            if (mv.Validation.HasErrors) throw mv.Validation.Errors.FirstOrDefault();
 
-            return ParseJson(content);
+            return mv.Model;
         }
 
         /// <summary>
-        /// Reads a <see cref="SCHEMA2"/> instance from a <see cref="Stream"/> containing a GLB file.
+        /// Reads a <see cref="SCHEMA2"/> instance from a <see cref="Stream"/> containing a GLTF file.
         /// </summary>
         /// <param name="stream">A <see cref="Stream"/> to read from.</param>
         /// <returns>A <see cref="SCHEMA2"/> instance.</returns>
-        public SCHEMA2 ReadBinarySchema2(Stream stream)
+        public SCHEMA2 ReadTextSchema2(Stream stream)
         {
             Guard.NotNull(stream, nameof(stream));
+            Guard.IsTrue(stream.CanRead, nameof(stream));
+
+            var json = stream.ReadBytesToEnd();
 
-            var mv = _ReadGLB(stream);
+            var mv = this._Read(json);
 
             if (mv.Validation.HasErrors) throw mv.Validation.Errors.FirstOrDefault();
 
@@ -171,53 +167,22 @@ namespace SharpGLTF.IO
         }
 
         /// <summary>
-        /// Parses a <see cref="SCHEMA2"/> instance from a <see cref="String"/> JSON content representing a GLTF file.
+        /// Reads a <see cref="SCHEMA2"/> instance from a <see cref="Stream"/> containing a GLB file.
         /// </summary>
-        /// <param name="jsonContent">A <see cref="String"/> JSON content representing a GLTF file.</param>
+        /// <param name="stream">A <see cref="Stream"/> to read from.</param>
         /// <returns>A <see cref="SCHEMA2"/> instance.</returns>
-        public SCHEMA2 ParseJson(String jsonContent)
+        public SCHEMA2 ReadBinarySchema2(Stream stream)
         {
-            var mv = _ParseGLTF(jsonContent);
+            Guard.NotNull(stream, nameof(stream));
+            Guard.IsTrue(stream.CanRead, nameof(stream));
+
+            var mv = this._ReadGLB(stream);
 
             if (mv.Validation.HasErrors) throw mv.Validation.Errors.FirstOrDefault();
 
             return mv.Model;
         }
 
-        public Validation.ValidationResult Validate(string filePath)
-        {
-            using (var stream = File.OpenRead(filePath))
-            {
-                bool isBinary = BinarySerialization._Identify(stream);
-
-                if (isBinary) return _ReadGLB(stream).Validation;
-
-                string content = null;
-
-                using (var streamReader = new StreamReader(stream))
-                {
-                    content = streamReader.ReadToEnd();
-                }
-
-                return _ParseGLTF(content).Validation;
-            }
-        }
-
-        internal SCHEMA2 _ReadFromDictionary(string fileName)
-        {
-            using (var s = this.OpenFile(fileName))
-            {
-                using (var tr = new StreamReader(s))
-                {
-                    var mv = this._Read(tr);
-
-                    if (mv.Validation.HasErrors) throw mv.Validation.Errors.FirstOrDefault();
-
-                    return mv.Model;
-                }
-            }
-        }
-
         #endregion
 
         #region core
@@ -228,8 +193,6 @@ namespace SharpGLTF.IO
 
             var chunks = BinarySerialization.ReadBinaryFile(stream);
 
-            var dom = Encoding.UTF8.GetString(chunks[BinarySerialization.CHUNKJSON]);
-
             var context = this;
 
             if (chunks.ContainsKey(BinarySerialization.CHUNKBIN))
@@ -238,42 +201,35 @@ namespace SharpGLTF.IO
                 context._BinaryChunk = chunks[BinarySerialization.CHUNKBIN];
             }
 
-            return context._ParseGLTF(dom);
-        }
+            var jsonChunk = chunks[BinarySerialization.CHUNKJSON];
 
-        private (SCHEMA2 Model, Validation.ValidationResult Validation) _ParseGLTF(String jsonContent)
-        {
-            Guard.NotNullOrEmpty(jsonContent, nameof(jsonContent));
-            using (var tr = new StringReader(jsonContent))
-            {
-                return _Read(tr);
-            }
+            return context._Read(new BYTES(jsonChunk));
         }
 
-        private (SCHEMA2 Model, Validation.ValidationResult Validation) _Read(TextReader textReader)
+        private (SCHEMA2 Model, Validation.ValidationResult Validation) _Read(BYTES jsonUtf8Bytes)
         {
-            Guard.NotNull(textReader, nameof(textReader));
+            Guard.NotNull(jsonUtf8Bytes, nameof(jsonUtf8Bytes));
 
             var root = new SCHEMA2();
+
             var vcontext = new Validation.ValidationResult(root, this.Validation);
 
-            using (var reader = new JsonTextReader(textReader))
+            var reader = new Utf8JsonReader(jsonUtf8Bytes);
+
+            if (!reader.Read())
             {
-                if (!reader.Read())
-                {
-                    vcontext.AddError(new Validation.ModelException(root, "Json is empty"));
-                    return (null, vcontext);
-                }
-
-                try
-                {
-                    root.Deserialize(reader);
-                }
-                catch (JsonReaderException rex)
-                {
-                    vcontext.AddError(new Validation.SchemaException(root, rex));
-                    return (null, vcontext);
-                }
+                vcontext.AddError(new Validation.ModelException(root, "Json is empty"));
+                return (null, vcontext);
+            }
+
+            try
+            {
+                root.Deserialize(ref reader);
+            }
+            catch (JsonException rex)
+            {
+                vcontext.AddError(new Validation.SchemaException(root, rex));
+                return (null, vcontext);
             }
 
             // schema validation
@@ -299,5 +255,46 @@ namespace SharpGLTF.IO
         }
 
         #endregion
+
+        #region extras
+
+        public static String ReadJson(Stream stream)
+        {
+            Guard.NotNull(stream, nameof(stream));
+
+            bool binaryFile = BinarySerialization._Identify(stream);
+
+            if (binaryFile)
+            {
+                var chunks = BinarySerialization.ReadBinaryFile(stream);
+
+                return Encoding.UTF8.GetString(chunks[BinarySerialization.CHUNKJSON]);
+            }
+
+            using (var streamReader = new StreamReader(stream))
+            {
+                return streamReader.ReadToEnd();
+            }
+        }
+
+        public static BYTES ReadJsonBytes(Stream stream)
+        {
+            Guard.NotNull(stream, nameof(stream));
+
+            bool binaryFile = BinarySerialization._Identify(stream);
+
+            if (binaryFile)
+            {
+                var chunks = BinarySerialization.ReadBinaryFile(stream);
+
+                var jsonChunk = chunks[BinarySerialization.CHUNKJSON];
+
+                return new BYTES(jsonChunk);
+            }
+
+            return stream.ReadBytesToEnd();
+        }
+
+        #endregion
     }
 }

+ 170 - 48
src/SharpGLTF.Core/IO/Serialization.cs

@@ -1,89 +1,211 @@
 using System;
 using System.Collections.Generic;
+using System.Numerics;
 using System.Text;
-
-using Newtonsoft.Json;
+using System.Text.Json;
 
 namespace SharpGLTF.IO
 {
     static class _JSonSerializationExtensions
     {
-        public static Object GetValueAs(this JsonReader reader, Type vtype)
+        public static Boolean AsBoolean(this in Utf8JsonReader reader)
         {
-            System.Diagnostics.Debug.Assert
-                (
-                reader.TokenType == JsonToken.Boolean ||
-                reader.TokenType == JsonToken.String ||
-                reader.TokenType == JsonToken.Integer ||
-                reader.TokenType == JsonToken.Float,
-                $"invalid JSON token {reader.TokenType}"
-                );
-
-            return Convert.ChangeType(reader.Value, vtype, System.Globalization.CultureInfo.InvariantCulture);
+            switch (reader.TokenType)
+            {
+                case JsonTokenType.Null: return false;
+                case JsonTokenType.True: return true;
+                case JsonTokenType.False: return false;
+                case JsonTokenType.Number: return reader.GetInt32() != 0;
+                default: throw new NotImplementedException();
+            }
+        }
+
+        public static String AsString(this in Utf8JsonReader reader)
+        {
+            switch (reader.TokenType)
+            {
+                case JsonTokenType.Null: return null;
+                case JsonTokenType.String: return reader.GetString();
+                case JsonTokenType.PropertyName: return reader.GetString();
+                case JsonTokenType.True: return "true";
+                case JsonTokenType.False: return "false";
+                case JsonTokenType.Number: return reader.GetDecimal().ToString(System.Globalization.CultureInfo.InvariantCulture);
+                default: throw new NotImplementedException();
+            }
+        }
+
+        public static Object AsEnum(this in Utf8JsonReader reader, Type enumType)
+        {
+            if (reader.TokenType == JsonTokenType.String)
+            {
+                return Enum.Parse(enumType, reader.GetString(), true);
+            }
+
+            if (reader.TokenType == JsonTokenType.Number)
+            {
+                if (reader.TryGetInt32(out Int32 int32Val)) return Enum.ToObject(enumType, int32Val);
+                if (reader.TryGetInt64(out Int64 int64Val)) return Enum.ToObject(enumType, int64Val);
+            }
+
+            throw new NotImplementedException();
+        }
+
+        public static Object GetAnyValue(this in Utf8JsonReader reader)
+        {
+            switch (reader.TokenType)
+            {
+                case JsonTokenType.Null: return null;
+                case JsonTokenType.True: return true;
+                case JsonTokenType.False: return false;
+                case JsonTokenType.String: return reader.GetString();
+                case JsonTokenType.Number: return reader.GetDecimal();
+                case JsonTokenType.PropertyName: return reader.GetString();
+                default: throw new NotImplementedException();
+            }
+        }
+
+        public static Object GetValueAs(this in Utf8JsonReader reader, Type vtype)
+        {
+            System.Diagnostics.Debug.Assert(reader.TokenType != JsonTokenType.StartArray);
+            System.Diagnostics.Debug.Assert(reader.TokenType != JsonTokenType.EndArray);
+            System.Diagnostics.Debug.Assert(reader.TokenType != JsonTokenType.StartObject);
+            System.Diagnostics.Debug.Assert(reader.TokenType != JsonTokenType.EndObject);
+
+            if (reader.TokenType == JsonTokenType.Null) return null;
+
+            if (vtype == typeof(String)) { return reader.AsString(); }
+            if (vtype == typeof(Boolean)) { return reader.AsBoolean(); }
+            if (vtype == typeof(Int16)) { return reader.GetInt16(); }
+            if (vtype == typeof(Int32)) { return reader.GetInt32(); }
+            if (vtype == typeof(Int64)) { return reader.GetInt64(); }
+            if (vtype == typeof(UInt16)) { return reader.GetUInt16(); }
+            if (vtype == typeof(UInt32)) { return reader.GetUInt32(); }
+            if (vtype == typeof(UInt64)) { return reader.GetUInt64(); }
+            if (vtype == typeof(Single)) { return reader.GetSingle(); }
+            if (vtype == typeof(Double)) { return reader.GetDouble(); }
+            if (vtype == typeof(Decimal)) { return reader.GetDecimal(); }
+
+            return Convert.ChangeType(reader.GetString(), vtype, System.Globalization.CultureInfo.InvariantCulture);
         }
 
-        public static T GetValueAs<T>(this JsonReader reader)
+        public static T GetValueAs<T>(this in Utf8JsonReader reader)
             where T : struct
         {
             return (T)reader.GetValueAs(typeof(T));
         }
 
-        public static void WriteVector2(this JsonWriter writer, System.Numerics.Vector2 v)
+        public static bool TryWriteProperty(this Utf8JsonWriter writer, string property, Object value)
+        {
+            if (value is String vstr) { writer.WriteString(property, vstr); return true; }
+            if (value is Boolean vbol) { writer.WriteBoolean(property, vbol); return true; }
+
+            if (value is Byte vu8) { writer.WriteNumber(property, vu8); return true; }
+            if (value is UInt16 vu16) { writer.WriteNumber(property, vu16); return true; }
+            if (value is UInt32 vu32) { writer.WriteNumber(property, vu32); return true; }
+            if (value is UInt64 vu64) { writer.WriteNumber(property, vu64); return true; }
+
+            if (value is SByte vs8) { writer.WriteNumber(property, vs8); return true; }
+            if (value is Int16 vs16) { writer.WriteNumber(property, vs16); return true; }
+            if (value is Int32 vs32) { writer.WriteNumber(property, vs32); return true; }
+            if (value is Int64 vs64) { writer.WriteNumber(property, vs64); return true; }
+
+            if (value is Single vf32) { writer.WriteNumber(property, vf32); return true; }
+            if (value is Double vf64) { writer.WriteNumber(property, vf64); return true; }
+            if (value is Decimal vfxx) { writer.WriteNumber(property, vfxx); return true; }
+
+            if (value is Vector2 vvv2) { writer.WritePropertyName(property); writer.WriteVector2(vvv2); return true; }
+            if (value is Vector3 vvv3) { writer.WritePropertyName(property); writer.WriteVector3(vvv3); return true; }
+            if (value is Vector4 vvv4) { writer.WritePropertyName(property); writer.WriteVector4(vvv4); return true; }
+            if (value is Quaternion qqq4) { writer.WritePropertyName(property); writer.WriteQuaternion(qqq4); return true; }
+            if (value is Matrix4x4 mm44) { writer.WritePropertyName(property); writer.WriteMatrix4x4(mm44); return true; }
+
+            return false;
+        }
+
+        public static bool TryWriteValue(this Utf8JsonWriter writer, Object value)
+        {
+            if (value is String vstr) { writer.WriteStringValue(vstr); return true; }
+            if (value is Boolean vbol) { writer.WriteBooleanValue(vbol); return true; }
+
+            if (value is Byte vu8) { writer.WriteNumberValue(vu8); return true; }
+            if (value is UInt16 vu16) { writer.WriteNumberValue(vu16); return true; }
+            if (value is UInt32 vu32) { writer.WriteNumberValue(vu32); return true; }
+            if (value is UInt64 vu64) { writer.WriteNumberValue(vu64); return true; }
+
+            if (value is SByte vs8) { writer.WriteNumberValue(vs8); return true; }
+            if (value is Int16 vs16) { writer.WriteNumberValue(vs16); return true; }
+            if (value is Int32 vs32) { writer.WriteNumberValue(vs32); return true; }
+            if (value is Int64 vs64) { writer.WriteNumberValue(vs64); return true; }
+
+            if (value is Single vf32) { writer.WriteNumberValue(vf32); return true; }
+            if (value is Double vf64) { writer.WriteNumberValue(vf64); return true; }
+            if (value is Decimal vfxx) { writer.WriteNumberValue(vfxx); return true; }
+
+            if (value is Vector2 vvv2) { writer.WriteVector2(vvv2); return true; }
+            if (value is Vector3 vvv3) { writer.WriteVector3(vvv3); return true; }
+            if (value is Vector4 vvv4) { writer.WriteVector4(vvv4); return true; }
+            if (value is Quaternion qqq4) { writer.WriteQuaternion(qqq4); return true; }
+            if (value is Matrix4x4 mm44) { writer.WriteMatrix4x4(mm44); return true; }
+
+            return false;
+        }
+
+        public static void WriteVector2(this Utf8JsonWriter writer, Vector2 v)
         {
             writer.WriteStartArray();
-            writer.WriteValue(v.X);
-            writer.WriteValue(v.Y);
+            writer.WriteNumberValue(v.X);
+            writer.WriteNumberValue(v.Y);
             writer.WriteEndArray();
         }
 
-        public static void WriteVector3(this JsonWriter writer, System.Numerics.Vector3 v)
+        public static void WriteVector3(this Utf8JsonWriter writer, Vector3 v)
         {
             writer.WriteStartArray();
-            writer.WriteValue(v.X);
-            writer.WriteValue(v.Y);
-            writer.WriteValue(v.Z);
+            writer.WriteNumberValue(v.X);
+            writer.WriteNumberValue(v.Y);
+            writer.WriteNumberValue(v.Z);
             writer.WriteEndArray();
         }
 
-        public static void WriteVector4(this JsonWriter writer, System.Numerics.Vector4 v)
+        public static void WriteVector4(this Utf8JsonWriter writer, Vector4 v)
         {
             writer.WriteStartArray();
-            writer.WriteValue(v.X);
-            writer.WriteValue(v.Y);
-            writer.WriteValue(v.Z);
-            writer.WriteValue(v.W);
+            writer.WriteNumberValue(v.X);
+            writer.WriteNumberValue(v.Y);
+            writer.WriteNumberValue(v.Z);
+            writer.WriteNumberValue(v.W);
             writer.WriteEndArray();
         }
 
-        public static void WriteQuaternion(this JsonWriter writer, System.Numerics.Quaternion q)
+        public static void WriteQuaternion(this Utf8JsonWriter writer, Quaternion q)
         {
             writer.WriteStartArray();
-            writer.WriteValue(q.X);
-            writer.WriteValue(q.Y);
-            writer.WriteValue(q.Z);
-            writer.WriteValue(q.W);
+            writer.WriteNumberValue(q.X);
+            writer.WriteNumberValue(q.Y);
+            writer.WriteNumberValue(q.Z);
+            writer.WriteNumberValue(q.W);
             writer.WriteEndArray();
         }
 
-        public static void WriteMatrix4x4(this JsonWriter writer, System.Numerics.Matrix4x4 m)
+        public static void WriteMatrix4x4(this Utf8JsonWriter writer, Matrix4x4 m)
         {
             writer.WriteStartArray();
-            writer.WriteValue(m.M11);
-            writer.WriteValue(m.M12);
-            writer.WriteValue(m.M13);
-            writer.WriteValue(m.M14);
-            writer.WriteValue(m.M21);
-            writer.WriteValue(m.M22);
-            writer.WriteValue(m.M23);
-            writer.WriteValue(m.M24);
-            writer.WriteValue(m.M31);
-            writer.WriteValue(m.M32);
-            writer.WriteValue(m.M33);
-            writer.WriteValue(m.M34);
-            writer.WriteValue(m.M41);
-            writer.WriteValue(m.M42);
-            writer.WriteValue(m.M43);
-            writer.WriteValue(m.M44);
+            writer.WriteNumberValue(m.M11);
+            writer.WriteNumberValue(m.M12);
+            writer.WriteNumberValue(m.M13);
+            writer.WriteNumberValue(m.M14);
+            writer.WriteNumberValue(m.M21);
+            writer.WriteNumberValue(m.M22);
+            writer.WriteNumberValue(m.M23);
+            writer.WriteNumberValue(m.M24);
+            writer.WriteNumberValue(m.M31);
+            writer.WriteNumberValue(m.M32);
+            writer.WriteNumberValue(m.M33);
+            writer.WriteNumberValue(m.M34);
+            writer.WriteNumberValue(m.M41);
+            writer.WriteNumberValue(m.M42);
+            writer.WriteNumberValue(m.M43);
+            writer.WriteNumberValue(m.M44);
             writer.WriteEndArray();
         }
     }

+ 4 - 4
src/SharpGLTF.Core/IO/Unknown.cs

@@ -2,7 +2,7 @@
 using System.Collections.Generic;
 using System.Text;
 
-using Newtonsoft.Json;
+using System.Text.Json;
 
 namespace SharpGLTF.IO
 {
@@ -19,13 +19,13 @@ namespace SharpGLTF.IO
 
         public JsonDictionary Properties => _Properties;
 
-        protected override void DeserializeProperty(string property, JsonReader reader)
+        protected override void DeserializeProperty(string property, ref Utf8JsonReader reader)
         {
             reader.Read();
-            _Properties[property] = DeserializeUnknownObject(reader);
+            _Properties[property] = DeserializeUnknownObject(ref reader);
         }
 
-        protected override void SerializeProperties(JsonWriter writer)
+        protected override void SerializeProperties(Utf8JsonWriter writer)
         {
             foreach (var kvp in _Properties)
             {

+ 8 - 6
src/SharpGLTF.Core/IO/WriteContext.cs

@@ -4,7 +4,6 @@ using System.IO;
 using System.Linq;
 using System.Text;
 
-using Newtonsoft.Json;
 using SharpGLTF.Schema2;
 
 using BYTES = System.ArraySegment<byte>;
@@ -53,7 +52,7 @@ namespace SharpGLTF.IO
 
             var context = Create((fn, d) => File.WriteAllBytes(Path.Combine(dirPath, fn), d.ToArray()));
             context.ImageWriting = ResourceWriteMode.SatelliteFile;
-            context.JsonFormatting = Formatting.Indented;
+            context.JsonIndented = true;
             return context;
         }
 
@@ -64,7 +63,7 @@ namespace SharpGLTF.IO
             var context = Create((fn, buff) => dict[fn] = buff);
             context.ImageWriting = ResourceWriteMode.SatelliteFile;
             context.MergeBuffers = false;
-            context.JsonFormatting = Formatting.None;
+            context.JsonIndented = false;
 
             return context;
         }
@@ -77,7 +76,7 @@ namespace SharpGLTF.IO
             var context = Create((fn, d) => stream.Write(d.Array, d.Offset, d.Count));
             context.ImageWriting = ResourceWriteMode.Embedded;
             context.MergeBuffers = true;
-            context.JsonFormatting = Formatting.None;
+            context.JsonIndented = false;
 
             return context.WithBinarySettings();
         }
@@ -86,7 +85,7 @@ namespace SharpGLTF.IO
         {
             ImageWriting = ResourceWriteMode.BufferView;
             MergeBuffers = true;
-            JsonFormatting = Formatting.None;
+            JsonIndented = false;
 
             return this;
         }
@@ -157,10 +156,13 @@ namespace SharpGLTF.IO
 
             using (var m = new MemoryStream())
             {
+                model._WriteJSON(m, this.JsonIndented);
+
+                /*
                 using (var w = new StreamWriter(m))
                 {
                     model._WriteJSON(w, this.JsonFormatting);
-                }
+                }*/
 
                 WriteAllBytesToEnd($"{baseName}.gltf", m.ToArraySegment());
             }

+ 1 - 1
src/SharpGLTF.Core/Memory/ColorArray.cs

@@ -33,7 +33,7 @@ namespace SharpGLTF.Memory
         /// <param name="normalized">True if values are normalized.</param>
         /// <param name="defaultW">If <paramref name="dimensions"/> is 3, the W values are filled with this value</param>
         public ColorArray(Byte[] source, int byteOffset, int itemsCount, int byteStride, int dimensions = 4, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false, Single defaultW = 1)
-            : this(new BYTES(source), byteOffset, itemsCount, byteStride, dimensions, encoding, normalized)
+            : this(new BYTES(source), byteOffset, itemsCount, byteStride, dimensions, encoding, normalized, defaultW)
         { }
 
         /// <summary>

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

@@ -19,7 +19,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Numerics;
-using Newtonsoft.Json;
+using System.Text.Json;
 
 namespace SharpGLTF.Schema2
 {
@@ -34,18 +34,18 @@ namespace SharpGLTF.Schema2
 		private Int32? _source;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "source", _source);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "source": _source = DeserializePropertyValue<Int32?>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "source": _source = DeserializePropertyValue<Int32?>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	

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

@@ -19,7 +19,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Numerics;
-using Newtonsoft.Json;
+using System.Text.Json;
 
 namespace SharpGLTF.Schema2
 {
@@ -39,20 +39,20 @@ namespace SharpGLTF.Schema2
 		private Double? _outerConeAngle = _outerConeAngleDefault;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "innerConeAngle", _innerConeAngle, _innerConeAngleDefault);
 			SerializeProperty(writer, "outerConeAngle", _outerConeAngle, _outerConeAngleDefault);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "innerConeAngle": _innerConeAngle = DeserializePropertyValue<Double?>(reader); break;
-				case "outerConeAngle": _outerConeAngle = DeserializePropertyValue<Double?>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "innerConeAngle": _innerConeAngle = DeserializePropertyValue<Double?>(ref reader); break;
+				case "outerConeAngle": _outerConeAngle = DeserializePropertyValue<Double?>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -79,7 +79,7 @@ namespace SharpGLTF.Schema2
 		private String _type;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "color", _color, _colorDefault);
@@ -89,16 +89,16 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "type", _type);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "color": _color = DeserializePropertyValue<Vector3?>(reader); break;
-				case "intensity": _intensity = DeserializePropertyValue<Double?>(reader); break;
-				case "range": _range = DeserializePropertyValue<Double?>(reader); break;
-				case "spot": _spot = DeserializePropertyValue<PunctualLightSpot>(reader); break;
-				case "type": _type = DeserializePropertyValue<String>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "color": _color = DeserializePropertyValue<Vector3?>(ref reader); break;
+				case "intensity": _intensity = DeserializePropertyValue<Double?>(ref reader); break;
+				case "range": _range = DeserializePropertyValue<Double?>(ref reader); break;
+				case "spot": _spot = DeserializePropertyValue<PunctualLightSpot>(ref reader); break;
+				case "type": _type = DeserializePropertyValue<String>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -111,18 +111,18 @@ namespace SharpGLTF.Schema2
 		private ChildrenCollection<PunctualLight,ModelRoot> _lights;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "lights", _lights, _lightsMinItems);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "lights": DeserializePropertyList<PunctualLight>(reader, _lights); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "lights": DeserializePropertyList<PunctualLight>(ref reader, _lights); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	

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

@@ -19,7 +19,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Numerics;
-using Newtonsoft.Json;
+using System.Text.Json;
 
 namespace SharpGLTF.Schema2
 {
@@ -31,18 +31,18 @@ namespace SharpGLTF.Schema2
 		private Int32 _light;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "light", _light);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "light": _light = DeserializePropertyValue<Int32>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "light": _light = DeserializePropertyValue<Int32>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	

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

@@ -19,7 +19,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Numerics;
-using Newtonsoft.Json;
+using System.Text.Json;
 
 namespace SharpGLTF.Schema2
 {
@@ -44,7 +44,7 @@ namespace SharpGLTF.Schema2
 		private Int32? _texCoord;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "offset", _offset, _offsetDefault);
@@ -53,15 +53,15 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "texCoord", _texCoord);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "offset": _offset = DeserializePropertyValue<Vector2?>(reader); break;
-				case "rotation": _rotation = DeserializePropertyValue<Double?>(reader); break;
-				case "scale": _scale = DeserializePropertyValue<Vector2?>(reader); break;
-				case "texCoord": _texCoord = DeserializePropertyValue<Int32?>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "offset": _offset = DeserializePropertyValue<Vector2?>(ref reader); break;
+				case "rotation": _rotation = DeserializePropertyValue<Double?>(ref reader); break;
+				case "scale": _scale = DeserializePropertyValue<Vector2?>(ref reader); break;
+				case "texCoord": _texCoord = DeserializePropertyValue<Int32?>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	

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

@@ -19,7 +19,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Numerics;
-using Newtonsoft.Json;
+using System.Text.Json;
 
 namespace SharpGLTF.Schema2
 {
@@ -32,16 +32,16 @@ namespace SharpGLTF.Schema2
 	{
 	
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	

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

@@ -19,7 +19,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Numerics;
-using Newtonsoft.Json;
+using System.Text.Json;
 
 namespace SharpGLTF.Schema2
 {
@@ -47,7 +47,7 @@ namespace SharpGLTF.Schema2
 		private TextureInfo _specularGlossinessTexture;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "diffuseFactor", _diffuseFactor, _diffuseFactorDefault);
@@ -57,16 +57,16 @@ namespace SharpGLTF.Schema2
 			SerializePropertyObject(writer, "specularGlossinessTexture", _specularGlossinessTexture);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "diffuseFactor": _diffuseFactor = DeserializePropertyValue<Vector4?>(reader); break;
-				case "diffuseTexture": _diffuseTexture = DeserializePropertyValue<TextureInfo>(reader); break;
-				case "glossinessFactor": _glossinessFactor = DeserializePropertyValue<Double?>(reader); break;
-				case "specularFactor": _specularFactor = DeserializePropertyValue<Vector3?>(reader); break;
-				case "specularGlossinessTexture": _specularGlossinessTexture = DeserializePropertyValue<TextureInfo>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "diffuseFactor": _diffuseFactor = DeserializePropertyValue<Vector4?>(ref reader); break;
+				case "diffuseTexture": _diffuseTexture = DeserializePropertyValue<TextureInfo>(ref reader); break;
+				case "glossinessFactor": _glossinessFactor = DeserializePropertyValue<Double?>(ref reader); break;
+				case "specularFactor": _specularFactor = DeserializePropertyValue<Vector3?>(ref reader); break;
+				case "specularGlossinessTexture": _specularGlossinessTexture = DeserializePropertyValue<TextureInfo>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	

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

@@ -19,7 +19,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Numerics;
-using Newtonsoft.Json;
+using System.Text.Json;
 
 namespace SharpGLTF.Schema2
 {
@@ -34,18 +34,18 @@ namespace SharpGLTF.Schema2
 		private Int32? _source;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "source", _source);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "source": _source = DeserializePropertyValue<Int32?>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "source": _source = DeserializePropertyValue<Int32?>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	

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

@@ -19,7 +19,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Numerics;
-using Newtonsoft.Json;
+using System.Text.Json;
 
 namespace SharpGLTF.Schema2
 {
@@ -177,18 +177,18 @@ namespace SharpGLTF.Schema2
 		private String _name;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "name", _name);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "name": _name = DeserializePropertyValue<String>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "name": _name = DeserializePropertyValue<String>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -209,7 +209,7 @@ namespace SharpGLTF.Schema2
 		private IndexEncodingType _componentType;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "bufferView", _bufferView);
@@ -217,14 +217,14 @@ namespace SharpGLTF.Schema2
 			SerializePropertyEnumValue<IndexEncodingType>(writer, "componentType", _componentType);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "bufferView": _bufferView = DeserializePropertyValue<Int32>(reader); break;
-				case "byteOffset": _byteOffset = DeserializePropertyValue<Int32?>(reader); break;
-				case "componentType": _componentType = DeserializePropertyValue<IndexEncodingType>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "bufferView": _bufferView = DeserializePropertyValue<Int32>(ref reader); break;
+				case "byteOffset": _byteOffset = DeserializePropertyValue<Int32?>(ref reader); break;
+				case "componentType": _componentType = DeserializePropertyValue<IndexEncodingType>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -243,20 +243,20 @@ namespace SharpGLTF.Schema2
 		private Int32? _byteOffset = _byteOffsetDefault;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "bufferView", _bufferView);
 			SerializeProperty(writer, "byteOffset", _byteOffset, _byteOffsetDefault);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "bufferView": _bufferView = DeserializePropertyValue<Int32>(reader); break;
-				case "byteOffset": _byteOffset = DeserializePropertyValue<Int32?>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "bufferView": _bufferView = DeserializePropertyValue<Int32>(ref reader); break;
+				case "byteOffset": _byteOffset = DeserializePropertyValue<Int32?>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -276,7 +276,7 @@ namespace SharpGLTF.Schema2
 		private AccessorSparseValues _values;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "count", _count);
@@ -284,14 +284,14 @@ namespace SharpGLTF.Schema2
 			SerializePropertyObject(writer, "values", _values);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "count": _count = DeserializePropertyValue<Int32>(reader); break;
-				case "indices": _indices = DeserializePropertyValue<AccessorSparseIndices>(reader); break;
-				case "values": _values = DeserializePropertyValue<AccessorSparseValues>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "count": _count = DeserializePropertyValue<Int32>(ref reader); break;
+				case "indices": _indices = DeserializePropertyValue<AccessorSparseIndices>(ref reader); break;
+				case "values": _values = DeserializePropertyValue<AccessorSparseValues>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -332,7 +332,7 @@ namespace SharpGLTF.Schema2
 		private DimensionType _type;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "bufferView", _bufferView);
@@ -346,20 +346,20 @@ namespace SharpGLTF.Schema2
 			SerializePropertyEnumSymbol<DimensionType>(writer, "type", _type);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "bufferView": _bufferView = DeserializePropertyValue<Int32?>(reader); break;
-				case "byteOffset": _byteOffset = DeserializePropertyValue<Int32?>(reader); break;
-				case "componentType": _componentType = DeserializePropertyValue<EncodingType>(reader); break;
-				case "count": _count = DeserializePropertyValue<Int32>(reader); break;
-				case "max": DeserializePropertyList<Double>(reader, _max); break;
-				case "min": DeserializePropertyList<Double>(reader, _min); break;
-				case "normalized": _normalized = DeserializePropertyValue<Boolean?>(reader); break;
-				case "sparse": _sparse = DeserializePropertyValue<AccessorSparse>(reader); break;
-				case "type": _type = DeserializePropertyValue<DimensionType>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "bufferView": _bufferView = DeserializePropertyValue<Int32?>(ref reader); break;
+				case "byteOffset": _byteOffset = DeserializePropertyValue<Int32?>(ref reader); break;
+				case "componentType": _componentType = DeserializePropertyValue<EncodingType>(ref reader); break;
+				case "count": _count = DeserializePropertyValue<Int32>(ref reader); break;
+				case "max": DeserializePropertyList<Double>(ref reader, _max); break;
+				case "min": DeserializePropertyList<Double>(ref reader, _min); break;
+				case "normalized": _normalized = DeserializePropertyValue<Boolean?>(ref reader); break;
+				case "sparse": _sparse = DeserializePropertyValue<AccessorSparse>(ref reader); break;
+				case "type": _type = DeserializePropertyValue<DimensionType>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -376,20 +376,20 @@ namespace SharpGLTF.Schema2
 		private PropertyPath _path;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "node", _node);
 			SerializePropertyEnumSymbol<PropertyPath>(writer, "path", _path);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "node": _node = DeserializePropertyValue<Int32?>(reader); break;
-				case "path": _path = DeserializePropertyValue<PropertyPath>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "node": _node = DeserializePropertyValue<Int32?>(ref reader); break;
+				case "path": _path = DeserializePropertyValue<PropertyPath>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -406,20 +406,20 @@ namespace SharpGLTF.Schema2
 		private AnimationChannelTarget _target;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "sampler", _sampler);
 			SerializePropertyObject(writer, "target", _target);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "sampler": _sampler = DeserializePropertyValue<Int32>(reader); break;
-				case "target": _target = DeserializePropertyValue<AnimationChannelTarget>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "sampler": _sampler = DeserializePropertyValue<Int32>(ref reader); break;
+				case "target": _target = DeserializePropertyValue<AnimationChannelTarget>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -439,7 +439,7 @@ namespace SharpGLTF.Schema2
 		private Int32 _output;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "input", _input);
@@ -447,14 +447,14 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "output", _output);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "input": _input = DeserializePropertyValue<Int32>(reader); break;
-				case "interpolation": _interpolation = DeserializePropertyValue<AnimationInterpolationMode>(reader); break;
-				case "output": _output = DeserializePropertyValue<Int32>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "input": _input = DeserializePropertyValue<Int32>(ref reader); break;
+				case "interpolation": _interpolation = DeserializePropertyValue<AnimationInterpolationMode>(ref reader); break;
+				case "output": _output = DeserializePropertyValue<Int32>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -473,20 +473,20 @@ namespace SharpGLTF.Schema2
 		private ChildrenCollection<AnimationSampler,Animation> _samplers;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "channels", _channels, _channelsMinItems);
 			SerializeProperty(writer, "samplers", _samplers, _samplersMinItems);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "channels": DeserializePropertyList<AnimationChannel>(reader, _channels); break;
-				case "samplers": DeserializePropertyList<AnimationSampler>(reader, _samplers); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "channels": DeserializePropertyList<AnimationChannel>(ref reader, _channels); break;
+				case "samplers": DeserializePropertyList<AnimationSampler>(ref reader, _samplers); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -507,7 +507,7 @@ namespace SharpGLTF.Schema2
 		private String _version;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "copyright", _copyright);
@@ -516,15 +516,15 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "version", _version);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "copyright": _copyright = DeserializePropertyValue<String>(reader); break;
-				case "generator": _generator = DeserializePropertyValue<String>(reader); break;
-				case "minVersion": _minVersion = DeserializePropertyValue<String>(reader); break;
-				case "version": _version = DeserializePropertyValue<String>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "copyright": _copyright = DeserializePropertyValue<String>(ref reader); break;
+				case "generator": _generator = DeserializePropertyValue<String>(ref reader); break;
+				case "minVersion": _minVersion = DeserializePropertyValue<String>(ref reader); break;
+				case "version": _version = DeserializePropertyValue<String>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -542,20 +542,20 @@ namespace SharpGLTF.Schema2
 		private String _uri;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "byteLength", _byteLength);
 			SerializeProperty(writer, "uri", _uri);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "byteLength": _byteLength = DeserializePropertyValue<Int32>(reader); break;
-				case "uri": _uri = DeserializePropertyValue<String>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "byteLength": _byteLength = DeserializePropertyValue<Int32>(ref reader); break;
+				case "uri": _uri = DeserializePropertyValue<String>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -583,7 +583,7 @@ namespace SharpGLTF.Schema2
 		private BufferMode? _target;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "buffer", _buffer);
@@ -593,16 +593,16 @@ namespace SharpGLTF.Schema2
 			SerializePropertyEnumValue<BufferMode>(writer, "target", _target);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "buffer": _buffer = DeserializePropertyValue<Int32>(reader); break;
-				case "byteLength": _byteLength = DeserializePropertyValue<Int32>(reader); break;
-				case "byteOffset": _byteOffset = DeserializePropertyValue<Int32?>(reader); break;
-				case "byteStride": _byteStride = DeserializePropertyValue<Int32?>(reader); break;
-				case "target": _target = DeserializePropertyValue<BufferMode>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "buffer": _buffer = DeserializePropertyValue<Int32>(ref reader); break;
+				case "byteLength": _byteLength = DeserializePropertyValue<Int32>(ref reader); break;
+				case "byteOffset": _byteOffset = DeserializePropertyValue<Int32?>(ref reader); break;
+				case "byteStride": _byteStride = DeserializePropertyValue<Int32?>(ref reader); break;
+				case "target": _target = DeserializePropertyValue<BufferMode>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -625,7 +625,7 @@ namespace SharpGLTF.Schema2
 		private Double _znear;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "xmag", _xmag);
@@ -634,15 +634,15 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "znear", _znear);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "xmag": _xmag = DeserializePropertyValue<Double>(reader); break;
-				case "ymag": _ymag = DeserializePropertyValue<Double>(reader); break;
-				case "zfar": _zfar = DeserializePropertyValue<Double>(reader); break;
-				case "znear": _znear = DeserializePropertyValue<Double>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "xmag": _xmag = DeserializePropertyValue<Double>(ref reader); break;
+				case "ymag": _ymag = DeserializePropertyValue<Double>(ref reader); break;
+				case "zfar": _zfar = DeserializePropertyValue<Double>(ref reader); break;
+				case "znear": _znear = DeserializePropertyValue<Double>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -667,7 +667,7 @@ namespace SharpGLTF.Schema2
 		private Double _znear;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "aspectRatio", _aspectRatio);
@@ -676,15 +676,15 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "znear", _znear);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "aspectRatio": _aspectRatio = DeserializePropertyValue<Double?>(reader); break;
-				case "yfov": _yfov = DeserializePropertyValue<Double>(reader); break;
-				case "zfar": _zfar = DeserializePropertyValue<Double?>(reader); break;
-				case "znear": _znear = DeserializePropertyValue<Double>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "aspectRatio": _aspectRatio = DeserializePropertyValue<Double?>(ref reader); break;
+				case "yfov": _yfov = DeserializePropertyValue<Double>(ref reader); break;
+				case "zfar": _zfar = DeserializePropertyValue<Double?>(ref reader); break;
+				case "znear": _znear = DeserializePropertyValue<Double>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -704,7 +704,7 @@ namespace SharpGLTF.Schema2
 		private CameraType _type;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializePropertyObject(writer, "orthographic", _orthographic);
@@ -712,14 +712,14 @@ namespace SharpGLTF.Schema2
 			SerializePropertyEnumSymbol<CameraType>(writer, "type", _type);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "orthographic": _orthographic = DeserializePropertyValue<CameraOrthographic>(reader); break;
-				case "perspective": _perspective = DeserializePropertyValue<CameraPerspective>(reader); break;
-				case "type": _type = DeserializePropertyValue<CameraType>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "orthographic": _orthographic = DeserializePropertyValue<CameraOrthographic>(ref reader); break;
+				case "perspective": _perspective = DeserializePropertyValue<CameraPerspective>(ref reader); break;
+				case "type": _type = DeserializePropertyValue<CameraType>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -738,20 +738,20 @@ namespace SharpGLTF.Schema2
 		private Int32? _texCoord = _texCoordDefault;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "index", _index);
 			SerializeProperty(writer, "texCoord", _texCoord, _texCoordDefault);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "index": _index = DeserializePropertyValue<Int32>(reader); break;
-				case "texCoord": _texCoord = DeserializePropertyValue<Int32?>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "index": _index = DeserializePropertyValue<Int32>(ref reader); break;
+				case "texCoord": _texCoord = DeserializePropertyValue<Int32?>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -781,7 +781,7 @@ namespace SharpGLTF.Schema2
 		private Double? _roughnessFactor = _roughnessFactorDefault;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "baseColorFactor", _baseColorFactor, _baseColorFactorDefault);
@@ -791,16 +791,16 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "roughnessFactor", _roughnessFactor, _roughnessFactorDefault);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "baseColorFactor": _baseColorFactor = DeserializePropertyValue<Vector4?>(reader); break;
-				case "baseColorTexture": _baseColorTexture = DeserializePropertyValue<TextureInfo>(reader); break;
-				case "metallicFactor": _metallicFactor = DeserializePropertyValue<Double?>(reader); break;
-				case "metallicRoughnessTexture": _metallicRoughnessTexture = DeserializePropertyValue<TextureInfo>(reader); break;
-				case "roughnessFactor": _roughnessFactor = DeserializePropertyValue<Double?>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "baseColorFactor": _baseColorFactor = DeserializePropertyValue<Vector4?>(ref reader); break;
+				case "baseColorTexture": _baseColorTexture = DeserializePropertyValue<TextureInfo>(ref reader); break;
+				case "metallicFactor": _metallicFactor = DeserializePropertyValue<Double?>(ref reader); break;
+				case "metallicRoughnessTexture": _metallicRoughnessTexture = DeserializePropertyValue<TextureInfo>(ref reader); break;
+				case "roughnessFactor": _roughnessFactor = DeserializePropertyValue<Double?>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -813,18 +813,18 @@ namespace SharpGLTF.Schema2
 		private Double? _scale = _scaleDefault;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "scale", _scale, _scaleDefault);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "scale": _scale = DeserializePropertyValue<Double?>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "scale": _scale = DeserializePropertyValue<Double?>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -839,18 +839,18 @@ namespace SharpGLTF.Schema2
 		private Double? _strength = _strengthDefault;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "strength", _strength, _strengthDefault);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "strength": _strength = DeserializePropertyValue<Double?>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "strength": _strength = DeserializePropertyValue<Double?>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -884,7 +884,7 @@ namespace SharpGLTF.Schema2
 		private MaterialPBRMetallicRoughness _pbrMetallicRoughness;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "alphaCutoff", _alphaCutoff, _alphaCutoffDefault);
@@ -897,19 +897,19 @@ namespace SharpGLTF.Schema2
 			SerializePropertyObject(writer, "pbrMetallicRoughness", _pbrMetallicRoughness);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "alphaCutoff": _alphaCutoff = DeserializePropertyValue<Double?>(reader); break;
-				case "alphaMode": _alphaMode = DeserializePropertyValue<AlphaMode>(reader); break;
-				case "doubleSided": _doubleSided = DeserializePropertyValue<Boolean?>(reader); break;
-				case "emissiveFactor": _emissiveFactor = DeserializePropertyValue<Vector3?>(reader); break;
-				case "emissiveTexture": _emissiveTexture = DeserializePropertyValue<TextureInfo>(reader); break;
-				case "normalTexture": _normalTexture = DeserializePropertyValue<MaterialNormalTextureInfo>(reader); break;
-				case "occlusionTexture": _occlusionTexture = DeserializePropertyValue<MaterialOcclusionTextureInfo>(reader); break;
-				case "pbrMetallicRoughness": _pbrMetallicRoughness = DeserializePropertyValue<MaterialPBRMetallicRoughness>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "alphaCutoff": _alphaCutoff = DeserializePropertyValue<Double?>(ref reader); break;
+				case "alphaMode": _alphaMode = DeserializePropertyValue<AlphaMode>(ref reader); break;
+				case "doubleSided": _doubleSided = DeserializePropertyValue<Boolean?>(ref reader); break;
+				case "emissiveFactor": _emissiveFactor = DeserializePropertyValue<Vector3?>(ref reader); break;
+				case "emissiveTexture": _emissiveTexture = DeserializePropertyValue<TextureInfo>(ref reader); break;
+				case "normalTexture": _normalTexture = DeserializePropertyValue<MaterialNormalTextureInfo>(ref reader); break;
+				case "occlusionTexture": _occlusionTexture = DeserializePropertyValue<MaterialOcclusionTextureInfo>(ref reader); break;
+				case "pbrMetallicRoughness": _pbrMetallicRoughness = DeserializePropertyValue<MaterialPBRMetallicRoughness>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -934,7 +934,7 @@ namespace SharpGLTF.Schema2
 		private List<Dictionary<String,Int32>> _targets;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "attributes", _attributes);
@@ -944,16 +944,16 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "targets", _targets, _targetsMinItems);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "attributes": DeserializePropertyDictionary<Int32>(reader, _attributes); break;
-				case "indices": _indices = DeserializePropertyValue<Int32?>(reader); break;
-				case "material": _material = DeserializePropertyValue<Int32?>(reader); break;
-				case "mode": _mode = DeserializePropertyValue<PrimitiveType>(reader); break;
-				case "targets": DeserializePropertyList<Dictionary<String,Int32>>(reader, _targets); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "attributes": DeserializePropertyDictionary<Int32>(ref reader, _attributes); break;
+				case "indices": _indices = DeserializePropertyValue<Int32?>(ref reader); break;
+				case "material": _material = DeserializePropertyValue<Int32?>(ref reader); break;
+				case "mode": _mode = DeserializePropertyValue<PrimitiveType>(ref reader); break;
+				case "targets": DeserializePropertyList<Dictionary<String,Int32>>(ref reader, _targets); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -974,20 +974,20 @@ namespace SharpGLTF.Schema2
 		private List<Double> _weights;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "primitives", _primitives, _primitivesMinItems);
 			SerializeProperty(writer, "weights", _weights, _weightsMinItems);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "primitives": DeserializePropertyList<MeshPrimitive>(reader, _primitives); break;
-				case "weights": DeserializePropertyList<Double>(reader, _weights); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "primitives": DeserializePropertyList<MeshPrimitive>(ref reader, _primitives); break;
+				case "weights": DeserializePropertyList<Double>(ref reader, _weights); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -1022,7 +1022,7 @@ namespace SharpGLTF.Schema2
 		private List<Double> _weights;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "camera", _camera);
@@ -1036,20 +1036,20 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "weights", _weights, _weightsMinItems);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "camera": _camera = DeserializePropertyValue<Int32?>(reader); break;
-				case "children": DeserializePropertyList<Int32>(reader, _children); break;
-				case "matrix": _matrix = DeserializePropertyValue<Matrix4x4?>(reader); break;
-				case "mesh": _mesh = DeserializePropertyValue<Int32?>(reader); break;
-				case "rotation": _rotation = DeserializePropertyValue<Quaternion?>(reader); break;
-				case "scale": _scale = DeserializePropertyValue<Vector3?>(reader); break;
-				case "skin": _skin = DeserializePropertyValue<Int32?>(reader); break;
-				case "translation": _translation = DeserializePropertyValue<Vector3?>(reader); break;
-				case "weights": DeserializePropertyList<Double>(reader, _weights); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "camera": _camera = DeserializePropertyValue<Int32?>(ref reader); break;
+				case "children": DeserializePropertyList<Int32>(ref reader, _children); break;
+				case "matrix": _matrix = DeserializePropertyValue<Matrix4x4?>(ref reader); break;
+				case "mesh": _mesh = DeserializePropertyValue<Int32?>(ref reader); break;
+				case "rotation": _rotation = DeserializePropertyValue<Quaternion?>(ref reader); break;
+				case "scale": _scale = DeserializePropertyValue<Vector3?>(ref reader); break;
+				case "skin": _skin = DeserializePropertyValue<Int32?>(ref reader); break;
+				case "translation": _translation = DeserializePropertyValue<Vector3?>(ref reader); break;
+				case "weights": DeserializePropertyList<Double>(ref reader, _weights); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -1072,7 +1072,7 @@ namespace SharpGLTF.Schema2
 		private TextureWrapMode? _wrapT = _wrapTDefault;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializePropertyEnumValue<TextureInterpolationFilter>(writer, "magFilter", _magFilter);
@@ -1081,15 +1081,15 @@ namespace SharpGLTF.Schema2
 			SerializePropertyEnumValue<TextureWrapMode>(writer, "wrapT", _wrapT, _wrapTDefault);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "magFilter": _magFilter = DeserializePropertyValue<TextureInterpolationFilter>(reader); break;
-				case "minFilter": _minFilter = DeserializePropertyValue<TextureMipMapFilter>(reader); break;
-				case "wrapS": _wrapS = DeserializePropertyValue<TextureWrapMode>(reader); break;
-				case "wrapT": _wrapT = DeserializePropertyValue<TextureWrapMode>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "magFilter": _magFilter = DeserializePropertyValue<TextureInterpolationFilter>(ref reader); break;
+				case "minFilter": _minFilter = DeserializePropertyValue<TextureMipMapFilter>(ref reader); break;
+				case "wrapS": _wrapS = DeserializePropertyValue<TextureWrapMode>(ref reader); break;
+				case "wrapT": _wrapT = DeserializePropertyValue<TextureWrapMode>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -1105,18 +1105,18 @@ namespace SharpGLTF.Schema2
 		private List<Int32> _nodes;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "nodes", _nodes, _nodesMinItems);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "nodes": DeserializePropertyList<Int32>(reader, _nodes); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "nodes": DeserializePropertyList<Int32>(ref reader, _nodes); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -1136,7 +1136,7 @@ namespace SharpGLTF.Schema2
 		private Int32? _skeleton;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "inverseBindMatrices", _inverseBindMatrices);
@@ -1144,14 +1144,14 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "skeleton", _skeleton);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "inverseBindMatrices": _inverseBindMatrices = DeserializePropertyValue<Int32?>(reader); break;
-				case "joints": DeserializePropertyList<Int32>(reader, _joints); break;
-				case "skeleton": _skeleton = DeserializePropertyValue<Int32?>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "inverseBindMatrices": _inverseBindMatrices = DeserializePropertyValue<Int32?>(ref reader); break;
+				case "joints": DeserializePropertyList<Int32>(ref reader, _joints); break;
+				case "skeleton": _skeleton = DeserializePropertyValue<Int32?>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -1168,20 +1168,20 @@ namespace SharpGLTF.Schema2
 		private Int32? _source;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "sampler", _sampler);
 			SerializeProperty(writer, "source", _source);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "sampler": _sampler = DeserializePropertyValue<Int32?>(reader); break;
-				case "source": _source = DeserializePropertyValue<Int32?>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "sampler": _sampler = DeserializePropertyValue<Int32?>(ref reader); break;
+				case "source": _source = DeserializePropertyValue<Int32?>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -1243,7 +1243,7 @@ namespace SharpGLTF.Schema2
 		private ChildrenCollection<Texture,ModelRoot> _textures;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializePropertyObject(writer, "asset", _asset);
@@ -1265,28 +1265,28 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "textures", _textures, _texturesMinItems);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "asset": _asset = DeserializePropertyValue<Asset>(reader); break;
-				case "extensionsRequired": DeserializePropertyList<String>(reader, _extensionsRequired); break;
-				case "extensionsUsed": DeserializePropertyList<String>(reader, _extensionsUsed); break;
-				case "accessors": DeserializePropertyList<Accessor>(reader, _accessors); break;
-				case "animations": DeserializePropertyList<Animation>(reader, _animations); break;
-				case "bufferViews": DeserializePropertyList<BufferView>(reader, _bufferViews); break;
-				case "buffers": DeserializePropertyList<Buffer>(reader, _buffers); break;
-				case "cameras": DeserializePropertyList<Camera>(reader, _cameras); break;
-				case "images": DeserializePropertyList<Image>(reader, _images); break;
-				case "materials": DeserializePropertyList<Material>(reader, _materials); break;
-				case "meshes": DeserializePropertyList<Mesh>(reader, _meshes); break;
-				case "nodes": DeserializePropertyList<Node>(reader, _nodes); break;
-				case "samplers": DeserializePropertyList<TextureSampler>(reader, _samplers); break;
-				case "scene": _scene = DeserializePropertyValue<Int32?>(reader); break;
-				case "scenes": DeserializePropertyList<Scene>(reader, _scenes); break;
-				case "skins": DeserializePropertyList<Skin>(reader, _skins); break;
-				case "textures": DeserializePropertyList<Texture>(reader, _textures); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "asset": _asset = DeserializePropertyValue<Asset>(ref reader); break;
+				case "extensionsRequired": DeserializePropertyList<String>(ref reader, _extensionsRequired); break;
+				case "extensionsUsed": DeserializePropertyList<String>(ref reader, _extensionsUsed); break;
+				case "accessors": DeserializePropertyList<Accessor>(ref reader, _accessors); break;
+				case "animations": DeserializePropertyList<Animation>(ref reader, _animations); break;
+				case "bufferViews": DeserializePropertyList<BufferView>(ref reader, _bufferViews); break;
+				case "buffers": DeserializePropertyList<Buffer>(ref reader, _buffers); break;
+				case "cameras": DeserializePropertyList<Camera>(ref reader, _cameras); break;
+				case "images": DeserializePropertyList<Image>(ref reader, _images); break;
+				case "materials": DeserializePropertyList<Material>(ref reader, _materials); break;
+				case "meshes": DeserializePropertyList<Mesh>(ref reader, _meshes); break;
+				case "nodes": DeserializePropertyList<Node>(ref reader, _nodes); break;
+				case "samplers": DeserializePropertyList<TextureSampler>(ref reader, _samplers); break;
+				case "scene": _scene = DeserializePropertyValue<Int32?>(ref reader); break;
+				case "scenes": DeserializePropertyList<Scene>(ref reader, _scenes); break;
+				case "skins": DeserializePropertyList<Skin>(ref reader, _skins); break;
+				case "textures": DeserializePropertyList<Texture>(ref reader, _textures); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	
@@ -1305,7 +1305,7 @@ namespace SharpGLTF.Schema2
 		private String _uri;
 		
 	
-		protected override void SerializeProperties(JsonWriter writer)
+		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "bufferView", _bufferView);
@@ -1313,14 +1313,14 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "uri", _uri);
 		}
 	
-		protected override void DeserializeProperty(string jsonPropertyName, JsonReader reader)
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		{
 			switch (jsonPropertyName)
 			{
-				case "bufferView": _bufferView = DeserializePropertyValue<Int32?>(reader); break;
-				case "mimeType": _mimeType = DeserializePropertyValue<String>(reader); break;
-				case "uri": _uri = DeserializePropertyValue<String>(reader); break;
-				default: base.DeserializeProperty(jsonPropertyName, reader); break;
+				case "bufferView": _bufferView = DeserializePropertyValue<Int32?>(ref reader); break;
+				case "mimeType": _mimeType = DeserializePropertyValue<String>(ref reader); break;
+				case "uri": _uri = DeserializePropertyValue<String>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 		}
 	

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

@@ -86,7 +86,7 @@ namespace SharpGLTF.Schema2
 
         /// <summary>
         /// Called by the serializer immediatelly after
-        /// calling <see cref="_WriteToSatellite(WriteContext, string)"/>
+        /// calling <see cref="_WriteToSatellite(IO.WriteContext, string)"/>
         /// or <see cref="_WriteToInternal"/>
         /// </summary>
         internal void _ClearAfterWrite()

+ 13 - 11
src/SharpGLTF.Core/Schema2/gltf.ExtraProperties.cs

@@ -2,10 +2,13 @@
 using System.Collections.Generic;
 using System.Linq;
 
-using Newtonsoft.Json;
+// using Newtonsoft.Json;
+using System.Text.Json;
 
 using SharpGLTF.IO;
 
+using JsonToken = System.Text.Json.JsonTokenType;
+
 namespace SharpGLTF.Schema2
 {
     public abstract class ExtraProperties : JsonSerializable
@@ -147,10 +150,10 @@ namespace SharpGLTF.Schema2
         #region serialization API
 
         /// <summary>
-        /// Writes the properties of the current instance to a <see cref="JsonWriter"/>.
+        /// Writes the properties of the current instance to a <see cref="Utf8JsonWriter"/>.
         /// </summary>
         /// <param name="writer">The target writer.</param>
-        protected override void SerializeProperties(JsonWriter writer)
+        protected override void SerializeProperties(Utf8JsonWriter writer)
         {
             if (_extensions.Count > 0)
             {
@@ -191,26 +194,25 @@ namespace SharpGLTF.Schema2
         }
 
         /// <summary>
-        /// Reads the properties of the current instance from a <see cref="JsonReader"/>.
+        /// Reads the properties of the current instance from a <see cref="Utf8JsonReader"/>.
         /// </summary>
         /// <param name="property">The name of the property.</param>
         /// <param name="reader">The source reader.</param>
-        protected override void DeserializeProperty(string property, JsonReader reader)
+        protected override void DeserializeProperty(string property, ref Utf8JsonReader reader)
         {
             Guard.NotNullOrEmpty(property, nameof(property));
-            Guard.NotNull(reader, nameof(reader));
 
             switch (property)
             {
-                case "extensions": _DeserializeExtensions(this, reader, _extensions); break;
+                case "extensions": _DeserializeExtensions(this, ref reader, _extensions); break;
 
-                case "extras": _extras = DeserializeUnknownObject(reader); break;
+                case "extras": _extras = DeserializeUnknownObject(ref reader); break;
 
                 default: reader.Skip(); break;
             }
         }
 
-        private static void _DeserializeExtensions(JsonSerializable parent, JsonReader reader, IList<JsonSerializable> extensions)
+        private static void _DeserializeExtensions(JsonSerializable parent, ref Utf8JsonReader reader, IList<JsonSerializable> extensions)
         {
             reader.Read();
 
@@ -218,13 +220,13 @@ namespace SharpGLTF.Schema2
             {
                 while (reader.Read() && reader.TokenType != JsonToken.EndObject)
                 {
-                    var key = reader.Value as String;
+                    var key = reader.GetString();
 
                     var val = ExtensionsFactory.Create(parent, key);
 
                     if (val == null) val = new UnknownNode(key);
 
-                    val.Deserialize(reader);
+                    val.Deserialize(ref reader);
                     extensions.Add(val);
                     continue;
                 }

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

@@ -343,7 +343,7 @@ namespace SharpGLTF.Schema2
 
         /// <summary>
         /// Called by the serializer immediatelly after
-        /// calling <see cref="_WriteToSatellite(FileWriterCallback, string)"/>
+        /// calling <see cref="_WriteToSatellite(IO.WriteContext, string)"/>
         /// or <see cref="_WriteToInternal"/>
         /// </summary>
         internal void _ClearAfterWrite()

+ 30 - 19
src/SharpGLTF.Core/Schema2/gltf.Serialization.Read.cs

@@ -4,14 +4,13 @@ using System.IO;
 using System.Linq;
 using System.Text;
 
-using Newtonsoft.Json;
-
 using BYTES = System.ArraySegment<byte>;
 
+using VALIDATIONMODE = SharpGLTF.Validation.ValidationMode;
+
 namespace SharpGLTF.Schema2
 {
     using MODEL = ModelRoot;
-    using VALIDATIONMODE = Validation.ValidationMode;
 
     public delegate Boolean ImageReaderCallback(Image image);
 
@@ -149,36 +148,48 @@ namespace SharpGLTF.Schema2
         {
             Guard.FilePathMustExist(filePath, nameof(filePath));
 
-            var context = IO.ReadContext.CreateFromFile(filePath);
-
-            string json = null;
+            BYTES json = default;
 
             using (var s = File.OpenRead(filePath))
             {
-                json = context.ReadJson(s);
+                json = IO.ReadContext.ReadJsonBytes(s);
             }
 
             return ParseSatellitePaths(json);
         }
 
-        private static string[] ParseSatellitePaths(string json)
+        private static string[] ParseSatellitePaths(BYTES json)
         {
-            var rss = Newtonsoft.Json.Linq.JObject.Parse(json);
+            var uris = new HashSet<string>();
 
-            var buffers = rss["buffers"]?.Select(item => (String)item["uri"]);
-            var images = rss["images"]?.Select(item => (String)item["uri"]);
+            void _addUri(System.Text.Json.JsonElement property)
+            {
+                var newUri = property.GetString();
 
-            IEnumerable<string> uris = buffers;
+                if (string.IsNullOrWhiteSpace(newUri)) return;
+                if (newUri.StartsWith("data:", StringComparison.OrdinalIgnoreCase)) return;
 
-            if (images != null)
-            {
-                uris = uris == null ? images : uris.Concat(images);
+                uris.Add(newUri);
             }
 
-            uris = uris
-                .Where(uri => !string.IsNullOrWhiteSpace(uri))
-                .Where(uri => !uri.StartsWith("data:", StringComparison.Ordinal))
-                .Distinct();
+            using (var dom = System.Text.Json.JsonDocument.Parse(json))
+            {
+                if (dom.RootElement.TryGetProperty("buffers", out System.Text.Json.JsonElement buffers))
+                {
+                    foreach (var buffer in buffers.EnumerateArray())
+                    {
+                        if (buffer.TryGetProperty("uri", out System.Text.Json.JsonElement uri)) _addUri(uri);
+                    }
+                }
+
+                if (dom.RootElement.TryGetProperty("images", out System.Text.Json.JsonElement images))
+                {
+                    foreach (var image in images.EnumerateArray())
+                    {
+                        if (image.TryGetProperty("uri", out System.Text.Json.JsonElement uri)) _addUri(uri);
+                    }
+                }
+            }
 
             return uris.ToArray();
         }

+ 24 - 19
src/SharpGLTF.Core/Schema2/gltf.Serialization.Write.cs

@@ -4,8 +4,6 @@ using System.IO;
 using System.Linq;
 using System.Text;
 
-using Newtonsoft.Json;
-
 using BYTES = System.ArraySegment<byte>;
 
 namespace SharpGLTF.Schema2
@@ -42,14 +40,6 @@ namespace SharpGLTF.Schema2
     {
         #region lifecycle
 
-        public static implicit operator WriteSettings(Formatting jsonfmt)
-        {
-            return new WriteSettings
-            {
-                JsonFormatting = jsonfmt
-            };
-        }
-
         public WriteSettings() { }
 
         public WriteSettings(WriteSettings other)
@@ -75,7 +65,7 @@ namespace SharpGLTF.Schema2
         /// <summary>
         /// Gets or sets a value indicating how to format the JSON document of the glTF.
         /// </summary>
-        public Formatting JsonFormatting { get; set; } = Formatting.None;
+        public Boolean JsonIndented { get; set; } = false;
 
         #endregion
 
@@ -86,7 +76,7 @@ namespace SharpGLTF.Schema2
             Guard.NotNull(other, nameof(other));
             this.ImageWriting = other.ImageWriting;
             this.MergeBuffers = other.MergeBuffers;
-            this.JsonFormatting = other.JsonFormatting;
+            this.JsonIndented = other.JsonIndented;
         }
 
         #endregion
@@ -158,15 +148,28 @@ namespace SharpGLTF.Schema2
         /// <summary>
         /// Gets the JSON document of this <see cref="MODEL"/>.
         /// </summary>
-        /// <param name="fmt">The formatting of the JSON document.</param>
+        /// <param name="indented">The formatting of the JSON document.</param>
         /// <returns>A JSON content.</returns>
-        public string GetJSON(Formatting fmt)
+        public string GetJSON(bool indented)
         {
+            using (var mm = new System.IO.MemoryStream())
+            {
+                _WriteJSON(mm, indented);
+
+                mm.Position = 0;
+
+                using (var ss = new System.IO.StreamReader(mm))
+                {
+                    return ss.ReadToEnd();
+                }
+            }
+
+            /*
             using (var ss = new StringWriter())
             {
                 _WriteJSON(ss, fmt);
                 return ss.ToString();
-            }
+            }*/
         }
 
         /// <summary>
@@ -210,12 +213,14 @@ namespace SharpGLTF.Schema2
 
         #region core
 
-        internal void _WriteJSON(TextWriter sw, Formatting fmt)
+        internal void _WriteJSON(System.IO.Stream sw, bool indented)
         {
-            using (var writer = new JsonTextWriter(sw))
-            {
-                writer.Formatting = fmt;
+            System.Text.Json.JsonWriterOptions options = default;
 
+            options.Indented = indented;
+
+            using (var writer = new System.Text.Json.Utf8JsonWriter(sw, options))
+            {
                 this.Serialize(writer);
             }
         }

+ 2 - 2
src/SharpGLTF.Core/SharpGLTF.Core.csproj

@@ -23,9 +23,9 @@
     </AssemblyAttribute>    
   </ItemGroup>  
   
-  <ItemGroup>    
-    <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
+  <ItemGroup>        
     <PackageReference Include="System.Memory" Version="4.5.3" />
+    <PackageReference Include="System.Text.Json" Version="4.7.0" />
   </ItemGroup>
 
   <ItemGroup>

+ 1 - 1
src/SharpGLTF.Core/Validation/ModelException.cs

@@ -58,7 +58,7 @@ namespace SharpGLTF.Validation
         internal SchemaException(TARGET target, String message)
             : base(target, message) { }
 
-        internal SchemaException(TARGET target, Newtonsoft.Json.JsonReaderException rex)
+        internal SchemaException(TARGET target, System.Text.Json.JsonException rex)
             : base(target, rex) { }
     }
 

+ 1 - 1
src/SharpGLTF.Core/Validation/ValidationContext.cs

@@ -168,7 +168,7 @@ namespace SharpGLTF.Validation
 
         public void CheckSchemaIsJsonSerializable(ValueLocation location, Object value)
         {
-            if (IO.JsonUtils.IsSerializable(value)) return;
+            if (IO.JsonUtils.IsJsonSerializable(value)) return;
 
             AddSchemaError(location, "Invalid JSON data.");
         }

+ 2 - 5
src/SharpGLTF.Toolkit/IO/Zip.cs

@@ -50,7 +50,7 @@ namespace SharpGLTF.IO
         {
             return _Archive
                 .Entries
-                .Where(item => item.FullName.ToLower().EndsWith(".gltf") || item.FullName.ToLower().EndsWith(".glb"))
+                .Where(item => item.FullName.EndsWith(".gltf", StringComparison.OrdinalIgnoreCase) || item.FullName.EndsWith(".glb", StringComparison.OrdinalIgnoreCase))
                 .OrderBy(item => item.FullName);
         }
 
@@ -93,14 +93,11 @@ namespace SharpGLTF.IO
                     else return new ArraySegment<byte>(m.ToArray());
                 }
             }
-
         }
 
         private System.IO.Compression.ZipArchiveEntry _FindEntry(string filePath)
         {
-            filePath = filePath.ToLower();
-
-            var entry = _Archive.Entries.FirstOrDefault(item => item.FullName.ToLower() == filePath);
+            var entry = _Archive.Entries.FirstOrDefault(item => item.FullName.Equals(filePath, StringComparison.OrdinalIgnoreCase) );
             if (entry == null) throw new System.IO.FileNotFoundException(filePath);
             return entry;
         }

+ 3 - 1
tests/SharpGLTF.Tests/Collections/ChildrenCollectionTests.cs

@@ -23,8 +23,10 @@ namespace SharpGLTF.Collections
         [Test]
         public void TestChildCollectionList1()
         {
-            var list = new ChildrenCollection<TestChild, ChildrenCollectionTests>(this);
+            if (System.Diagnostics.Debugger.IsAttached) return;
 
+            var list = new ChildrenCollection<TestChild, ChildrenCollectionTests>(this);
+            
             Assert.Throws<ArgumentNullException>(() => list.Add(null));
 
             var item = new TestChild();

+ 1 - 1
tests/SharpGLTF.Tests/Schema2/Authoring/BasicSceneCreationTests.cs

@@ -44,7 +44,7 @@ namespace SharpGLTF.Schema2.Authoring
                 ["D"] = new IO.JsonDictionary { ["S"]= 1, ["T"] = 2 }
             };
 
-            var json = root.GetJSON(Newtonsoft.Json.Formatting.Indented);
+            var json = root.GetJSON(true);
 
             var bytes = root.WriteGLB();
             var rootBis = ModelRoot.ParseGLB(bytes);

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

@@ -113,8 +113,8 @@ namespace SharpGLTF.Schema2.LoadAndSave
             // which is causing some problems to the interpolator.
 
             TestContext.CurrentContext.AttachShowDirLink();
-
-            var path = "Assets\\SpecialCases\\mouse.glb";
+            
+            var path = System.IO.Path.Combine(TestContext.CurrentContext.TestDirectory, "Assets\\SpecialCases\\mouse.glb");
 
             var model = ModelRoot.Load(path);
 

+ 3 - 2
tests/SharpGLTF.Tests/SharpGLTF.Tests.csproj

@@ -1,13 +1,13 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFrameworks>netcoreapp2.2;net471</TargetFrameworks>
+    <TargetFrameworks>netcoreapp3.0;net471</TargetFrameworks>
 
     <IsPackable>false</IsPackable>
 
     <RootNamespace>SharpGLTF</RootNamespace>
 
-    <LangVersion>7.1</LangVersion>
+    <LangVersion>latest</LangVersion>
   </PropertyGroup>
 
   <ItemGroup>
@@ -21,6 +21,7 @@
   </ItemGroup>
 
   <ItemGroup>    
+    <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />    
     <PackageReference Include="nunit" Version="3.12.0" />
     <PackageReference Include="NUnit3TestAdapter" Version="3.16.0">
       <PrivateAssets>all</PrivateAssets>

+ 1 - 1
tests/SharpGLTF.Tests/Utils.cs

@@ -124,7 +124,7 @@ namespace SharpGLTF
             }
             else if (fileName.ToLower().EndsWith(".gltf"))
             {
-                model.Save(fileName, Newtonsoft.Json.Formatting.Indented);
+                model.Save(fileName, new Schema2.WriteSettings { JsonIndented=true } );
             }
             else if (fileName.ToLower().EndsWith(".obj"))
             {