using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using VGltf.Glb; using VGltf.Types; using VJson; using VJson.Schema; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("yutopp")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright 2019")] [assembly: AssemblyDescription("A glTF and GLB serializer/deserializer library written in pure C#.")] [assembly: AssemblyFileVersion("0.0.0.0")] [assembly: AssemblyInformationalVersion("0.0.0")] [assembly: AssemblyProduct("VGltf")] [assembly: AssemblyTitle("VGltf")] [assembly: AssemblyVersion("0.0.0.0")] namespace VGltf { public sealed class BufferBuilder { private sealed class AsView { public ArraySegment Payload; public int? ByteStride; public BufferView.TargetEnum? Target; } private readonly List _asViews = new List(); public int AddView(ArraySegment payload, int? byteStride = null, BufferView.TargetEnum? target = null) { int count = _asViews.Count; _asViews.Add(new AsView { Payload = payload, ByteStride = byteStride, Target = target }); return count; } public byte[] BuildBytes(out List views) { views = new List(); using MemoryStream memoryStream = new MemoryStream(); uint num = 0u; foreach (AsView asView in _asViews) { uint num2 = Align.WritePadding(memoryStream, num, 4u, 0); num += num2; uint byteOffset = num; memoryStream.Write(asView.Payload.Array, asView.Payload.Offset, asView.Payload.Count); num += (uint)asView.Payload.Count; uint num3 = Align.WritePadding(memoryStream, num, 4u, 0); num += num3; views.Add(new BufferView { Buffer = 0, ByteOffset = (int)byteOffset, ByteLength = asView.Payload.Count, ByteStride = asView.ByteStride, Target = asView.Target }); } return memoryStream.ToArray(); } } public sealed class GltfContainer { public Gltf Gltf { get; } public StoredBuffer Buffer { get; } public JsonSchemaRegistry JsonSchemas { get; } public GltfContainer(Gltf gltf, StoredBuffer buffer = null, JsonSchemaRegistry reg = null) { Gltf = gltf; Buffer = buffer; JsonSchemas = reg; } public static GltfContainer FromGltf(Stream s, StoredBuffer buffer = null) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown JsonSchemaRegistry reg = new JsonSchemaRegistry(); return new GltfContainer(GltfReader.Read(s, reg), buffer, reg); } public static void FromGltf(Stream s, GltfContainer container) { GltfWriter.Write(s, container.Gltf, container.JsonSchemas); } public static GltfContainer FromGlb(Stream s) { return Reader.ReadAsContainer(s); } public static void ToGlb(Stream s, GltfContainer container) { Writer.WriteFromContainer(s, container); } } public static class GltfReader { public static Gltf Read(Stream s, JsonSchemaRegistry reg, bool withRepairment = true) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) JsonReader val = new JsonReader(s); try { INode val2 = val.Read(); if (withRepairment) { RepairKnownInvalidFormat(val2); } Gltf gltf = (Gltf)new JsonDeserializer(typeof(Gltf)).DeserializeFromNode(val2); if (reg != null) { ConstraintsViolationException val3 = JsonSchemaExtensions.Validate(JsonSchema.CreateFromType(reg, false), (object)gltf, reg); if (val3 != null) { throw val3; } } return gltf; } finally { ((IDisposable)val)?.Dispose(); } } public static Gltf ReadWithoutValidation(Stream s, bool withRepairment = true) { return Read(s, null, withRepairment); } public static void RepairKnownInvalidFormat(INode node) { RepairUniGLTFInvalidNamesForImages(node); RepairUniGLTFInvalidTargets(node); RepairUniGLTFInvalidTargets2(node); RepairUniGLTFInvalidIndexValues(node); RepairUniGLTFInvalidScene(node); } public static void RepairUniGLTFInvalidNamesForImages(INode node) { INode obj = node["images"]; ArrayNode val = (ArrayNode)(object)((obj is ArrayNode) ? obj : null); if (val == null) { return; } foreach (INode item in val) { ObjectNode val2 = (ObjectNode)(object)((item is ObjectNode) ? item : null); if (val2 != null) { INode obj2 = item["extra"]["name"]; StringNode val3 = (StringNode)(object)((obj2 is StringNode) ? obj2 : null); if (val3 != null && item["name"] is UndefinedNode) { val2.AddElement("name", (INode)(object)val3); } } } } public static void RepairUniGLTFInvalidTargets(INode node) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Expected O, but got Unknown //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Expected O, but got Unknown INode obj = node["meshes"]; ArrayNode val = (ArrayNode)(object)((obj is ArrayNode) ? obj : null); if (val == null) { return; } foreach (INode item in val) { INode val2 = item["extras"]; if (val2 is UndefinedNode) { val2 = (INode)new ObjectNode(); ((ObjectNode)item).AddElement("extras", val2); } INode obj2 = item["primitives"]; ArrayNode val3 = (ArrayNode)(object)((obj2 is ArrayNode) ? obj2 : null); if (val3 == null) { continue; } List list = null; foreach (INode item2 in val3) { INode obj3 = item2["targets"]; ArrayNode val4 = (ArrayNode)(object)((obj3 is ArrayNode) ? obj3 : null); if (val4 == null) { continue; } List list2 = new List(); foreach (INode item3 in val4) { ObjectNode val5 = (ObjectNode)(object)((item3 is ObjectNode) ? item3 : null); if (val5 == null) { continue; } List list3 = new List(); foreach (KeyValuePair item4 in val5) { string key = item4.Key; if (key == "extra") { list3.Add(key); INode obj4 = item3[key]["name"]; StringNode val6 = (StringNode)(object)((obj4 is StringNode) ? obj4 : null); if (val6 == null) { continue; } list2.Add(val6.Value); } if (!IsValidMorphTargetProperty(key)) { list3.Add(key); } } foreach (string item5 in list3) { val5.RemoveElement(item5); } } if (list == null || list.Count == list2.Count) { list = list2; } } if (list == null) { continue; } ArrayNode val7 = null; ObjectNode val8 = (ObjectNode)(object)((val2 is ObjectNode) ? val2 : null); if (val8 != null) { INode val9 = val8["targetNames"]; if (val9 is UndefinedNode) { val9 = (INode)new ArrayNode(); val8.AddElement("targetNames", val9); } val7 = (ArrayNode)(object)((val9 is ArrayNode) ? val9 : null); } if (val7 == null) { continue; } foreach (string item6 in list) { val7.AddElement((INode)new StringNode(item6)); } } } public static void RepairUniGLTFInvalidTargets2(INode node) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Expected O, but got Unknown //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Expected O, but got Unknown INode obj = node["meshes"]; ArrayNode val = (ArrayNode)(object)((obj is ArrayNode) ? obj : null); if (val == null) { return; } foreach (INode item in val) { INode val2 = item["extras"]; if (val2 is UndefinedNode) { val2 = (INode)new ObjectNode(); ((ObjectNode)item).AddElement("extras", val2); } INode obj2 = item["primitives"]; ArrayNode val3 = (ArrayNode)(object)((obj2 is ArrayNode) ? obj2 : null); if (val3 == null) { continue; } List list = null; foreach (INode item2 in val3) { INode val4 = item2["extras"]; if (val4 is UndefinedNode) { continue; } INode val5 = val4["targetNames"]; if (val5 is UndefinedNode) { continue; } ArrayNode val6 = (ArrayNode)(object)((val5 is ArrayNode) ? val5 : null); if (val6 == null) { continue; } List list2 = new List(); foreach (INode elem in val6.Elems) { StringNode val7 = (StringNode)(object)((elem is StringNode) ? elem : null); if (val7 != null) { list2.Add(val7.Value); } } if (list == null || list.Count == list2.Count) { list = list2; } } if (list == null) { continue; } ArrayNode val8 = null; ObjectNode val9 = (ObjectNode)(object)((val2 is ObjectNode) ? val2 : null); if (val9 != null) { INode val10 = val9["targetNames"]; if (val10 is UndefinedNode) { val10 = (INode)new ArrayNode(); val9.AddElement("targetNames", val10); } val8 = (ArrayNode)(object)((val10 is ArrayNode) ? val10 : null); } if (val8 == null) { continue; } foreach (string item3 in list) { val8.AddElement((INode)new StringNode(item3)); } } } public static void RepairUniGLTFInvalidIndexValues(INode node) { RepairUniGLTFInvalidIndexValuesForMeshes(node); } public static void RepairUniGLTFInvalidIndexValuesForMeshes(INode node) { INode obj = node["meshes"]; ArrayNode val = (ArrayNode)(object)((obj is ArrayNode) ? obj : null); if (val == null) { return; } foreach (INode item in val) { INode obj2 = item["primitives"]; ArrayNode val2 = (ArrayNode)(object)((obj2 is ArrayNode) ? obj2 : null); if (val2 == null) { continue; } foreach (INode item2 in val2) { ObjectNode val3 = (ObjectNode)(object)((item2 is ObjectNode) ? item2 : null); if (val3 == null) { continue; } INode obj3 = item2["indices"]; IntegerNode val4 = (IntegerNode)(object)((obj3 is IntegerNode) ? obj3 : null); if (val4 != null && val4.Value == -1) { val3.RemoveElement("indices"); } INode obj4 = item2["material"]; IntegerNode val5 = (IntegerNode)(object)((obj4 is IntegerNode) ? obj4 : null); if (val5 != null && val5.Value == -1) { val3.RemoveElement("material"); } INode obj5 = item2["mode"]; IntegerNode val6 = (IntegerNode)(object)((obj5 is IntegerNode) ? obj5 : null); if (val6 != null && val6.Value == -1) { val3.RemoveElement("mode"); } INode obj6 = item2["targets"]; ArrayNode val7 = (ArrayNode)(object)((obj6 is ArrayNode) ? obj6 : null); if (val7 == null) { continue; } foreach (INode item3 in val7) { ObjectNode val8 = (ObjectNode)(object)((item3 is ObjectNode) ? item3 : null); if (val8 == null) { continue; } List list = new List(); foreach (KeyValuePair item4 in val8) { INode value = item4.Value; IntegerNode val9 = (IntegerNode)(object)((value is IntegerNode) ? value : null); if (val9 != null && val9.Value == -1) { list.Add(item4.Key); } } foreach (string item5 in list) { val8.RemoveElement(item5); } } } } } public static void RepairUniGLTFInvalidScene(INode node) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown ObjectNode val = (ObjectNode)(object)((node is ObjectNode) ? node : null); if (val != null) { INode obj = node["asset"]["generator"]; StringNode val2 = (StringNode)(object)((obj is StringNode) ? obj : null); if (val2 != null && !(val2.Value != "UniGLTF") && node["scene"] is UndefinedNode) { val.AddElement("scene", (INode)new IntegerNode(0L)); } } } private static bool IsValidMorphTargetProperty(string name) { if (name.StartsWith("_")) { return true; } switch (name) { case "POSITION": case "NORMAL": case "TANGENT": return true; default: return false; } } } public class GltfWriter { public static void Write(Stream s, Gltf gltf, JsonSchemaRegistry reg) { ConstraintsViolationException val = JsonSchemaExtensions.Validate(JsonSchema.CreateFromType(reg, false), (object)gltf, reg); if (val != null) { throw val; } WriteWithoutValidation(s, gltf); } public static void WriteWithoutValidation(Stream s, Gltf gltf) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) new JsonSerializer(typeof(Gltf)).Serialize(s, gltf, 0); } } public sealed class Resource { public ArraySegment Data; } public interface IResourceLoader { Resource Load(string uri); string FullPathOf(string uri); } public sealed class ResourceLoaderFromFileStorage : IResourceLoader { private readonly string _baseDir; public ResourceLoaderFromFileStorage(string baseDir) { _baseDir = baseDir; } public Resource Load(string uri) { if (DataUriUtil.IsData(uri)) { return DataUriUtil.Extract(uri); } return LoadFromFile(_baseDir, uri); } public string FullPathOf(string uri) { if (DataUriUtil.IsData(uri)) { throw new InvalidOperationException("uri is data form"); } return EnsureCleanedPath(_baseDir, uri); } public static string EnsureCleanedPath(string baseDir, string uri) { string fullPath = Path.GetFullPath(baseDir); string fullPath2 = Path.GetFullPath(Path.Combine(baseDir, uri)); if (!fullPath2.StartsWith(fullPath)) { throw new ArgumentException($"Path must be a child of baseDir: Uri = {uri}, BaseDir = {baseDir}, FullPath = {fullPath2}"); } return fullPath2; } public static Resource LoadFromFile(string baseDir, string uri) { byte[] array = File.ReadAllBytes(EnsureCleanedPath(baseDir, uri)); return new Resource { Data = new ArraySegment(array) }; } } public sealed class ResourceLoaderFromEmbedOnly : IResourceLoader { public Resource Load(string uri) { if (!DataUriUtil.IsData(uri)) { throw new InvalidOperationException("uri is not data form"); } return DataUriUtil.Extract(uri); } public string FullPathOf(string uri) { throw new NotImplementedException(uri); } } public static class DataUriUtil { public static bool IsData(string uri) { return uri.StartsWith("data:"); } public static Resource Extract(string uri) { int num = uri.IndexOf(','); if (num == -1) { throw new ArgumentException("Invalid DataURI format (',' is missing)"); } return new Resource { Data = new ArraySegment(Convert.FromBase64String(uri.Substring(num + 1))) }; } } public sealed class ResourcesStore { private readonly Dictionary _bufferResources = new Dictionary(); private readonly Dictionary _imageResources = new Dictionary(); public GltfContainer Container { get; } public IResourceLoader Loader { get; } public Gltf Gltf => Container.Gltf; public StoredBuffer Buffer => Container.Buffer; public ResourcesStore(GltfContainer container, IResourceLoader loader) { Container = container; Loader = loader; } public Resource GetOrLoadBufferResourceAt(int index) { if (GetBufferResourceAt(index, out var resource)) { return resource; } VGltf.Types.Buffer buffer = Gltf.Buffers[index]; if (buffer.Uri != null) { resource = Loader.Load(buffer.Uri); resource.Data = new ArraySegment(resource.Data.Array, resource.Data.Offset, buffer.ByteLength); } else { if (index != 0) { throw new InvalidOperationException("When referencing binaryBuffer, index must be 0"); } if (Buffer == null) { throw new InvalidOperationException("GLB stored buffer is null"); } resource = new Resource { Data = new ArraySegment(Buffer.Payload.Array, Buffer.Payload.Offset, buffer.ByteLength) }; } _bufferResources.Add(index, resource); return resource; } public bool GetBufferResourceAt(int index, out Resource resource) { return _bufferResources.TryGetValue(index, out resource); } public Resource GetOrLoadBufferViewResourceAt(int index) { BufferView bufferView = Gltf.BufferViews[index]; Resource orLoadBufferResourceAt = GetOrLoadBufferResourceAt(bufferView.Buffer); ArraySegment data = new ArraySegment(orLoadBufferResourceAt.Data.Array, orLoadBufferResourceAt.Data.Offset + bufferView.ByteOffset, bufferView.ByteLength); return new Resource { Data = data }; } public Resource GetOrLoadImageResourceAt(int index) { if (GetImageResourceAt(index, out var resource)) { return resource; } Image image = Gltf.Images[index]; resource = ((image.Uri == null) ? GetOrLoadBufferViewResourceAt(image.BufferView.Value) : Loader.Load(image.Uri)); _imageResources.Add(index, resource); return resource; } public bool GetImageResourceAt(int index, out Resource resource) { return _imageResources.TryGetValue(index, out resource); } public TypedBuffer GetOrLoadTypedBufferByAccessorIndex(int index) { Accessor accessor = Gltf.Accessors[index]; return new TypedBuffer(this, accessor); } } public interface ITypedView where T : struct { } public delegate Out Mapper(Elem[] xs, int i) where Elem : struct where Out : struct; public sealed class TypedArrayView where T : struct { public readonly T[] TypedBuffer; private TypedArrayView(T[] typedBuffer) { TypedBuffer = typedBuffer; } public static TypedArrayView CreateFromPrimitive(ArraySegment buffer, int stride, int componentSize, int componentNum, int count, Mapper mapper) where Prim : struct { T[] array = new T[count]; if (componentSize * componentNum == stride) { Prim[] array2 = new Prim[componentNum * count]; byte[]? array3 = buffer.Array; int offset = buffer.Offset; System.Buffer.BlockCopy(array3, offset, array2, 0, componentSize * componentNum * count); for (int i = 0; i < array2.Length / componentNum; i++) { array[i] = mapper(array2, i * componentNum); } } else { Prim[] array4 = new Prim[componentNum]; byte[] array5 = buffer.Array; int offset2 = buffer.Offset; for (int j = 0; j < count; j++) { int num = j * stride; System.Buffer.BlockCopy(array5, offset2 + num, array4, 0, componentSize * componentNum); array[j] = mapper(array4, 0); } } return new TypedArrayView(array); } } public static class TypedArrayStorageFromBufferView { public static TypedArrayView CreateFrom(ResourcesStore store, int bufferViewIndex, int byteOffset, int componentSize, int componentNum, int count, Mapper mapper) where Prim : struct where T : struct { BufferView bufferView = store.Gltf.BufferViews[bufferViewIndex]; Resource orLoadBufferViewResourceAt = store.GetOrLoadBufferViewResourceAt(bufferViewIndex); int num = componentSize * componentNum; int num2 = (bufferView.ByteStride.HasValue ? bufferView.ByteStride.Value : num); return TypedArrayView.CreateFromPrimitive(new ArraySegment(orLoadBufferViewResourceAt.Data.Array, orLoadBufferViewResourceAt.Data.Offset + byteOffset, count * num2), num2, componentSize, componentNum, count, mapper); } } public sealed class TypedArrayEntity where T : struct where U : struct { public readonly TypedArrayView DenseView; public readonly TypedArrayView SparseIndices; public readonly TypedArrayView SparseValues; public readonly int Length; private readonly int _componentNum; public TypedArrayEntity(ResourcesStore store, Accessor accessor, Mapper mapper) { Length = accessor.Count; _componentNum = accessor.Type.NumOfComponents(); if (accessor.BufferView.HasValue) { DenseView = TypedArrayStorageFromBufferView.CreateFrom(store, accessor.BufferView.Value, accessor.ByteOffset, accessor.ComponentType.SizeInBytes(), accessor.Type.NumOfComponents(), accessor.Count, mapper); } if (accessor.Sparse == null) { return; } Accessor.SparseType sparse = accessor.Sparse; Accessor.SparseType.IndicesType indices = sparse.Indices; switch (indices.ComponentType) { case Accessor.SparseType.IndicesType.ComponentTypeEnum.UNSIGNED_BYTE: SparseIndices = TypedArrayStorageFromBufferView.CreateFrom(store, indices.BufferView, indices.ByteOffset, indices.ComponentType.SizeInBytes(), 1, sparse.Count, (Mapper)((byte[] xs, int i) => xs[i])); break; case Accessor.SparseType.IndicesType.ComponentTypeEnum.UNSIGNED_SHORT: SparseIndices = TypedArrayStorageFromBufferView.CreateFrom(store, indices.BufferView, indices.ByteOffset, indices.ComponentType.SizeInBytes(), 1, sparse.Count, (Mapper)((ushort[] xs, int i) => xs[i])); break; case Accessor.SparseType.IndicesType.ComponentTypeEnum.UNSIGNED_INT: SparseIndices = TypedArrayStorageFromBufferView.CreateFrom(store, indices.BufferView, indices.ByteOffset, indices.ComponentType.SizeInBytes(), 1, sparse.Count, (uint[] xs, int i) => xs[i]); break; default: throw new NotSupportedException(); } Accessor.SparseType.ValuesType values = sparse.Values; SparseValues = TypedArrayStorageFromBufferView.CreateFrom(store, values.BufferView, values.ByteOffset, accessor.ComponentType.SizeInBytes(), accessor.Type.NumOfComponents(), sparse.Count, mapper); } public U[] AsArray() { U[] array = ((DenseView != null) ? DenseView.TypedBuffer : null); if (SparseValues == null) { return array; } U[] typedBuffer = SparseValues.TypedBuffer; uint num = SparseIndices.TypedBuffer[0]; U[] array2 = new U[Length]; int num2 = 0; for (int i = 0; i < array2.Length; i++) { U val = default(U); if (array != null) { val = array[i]; } if (i == num) { val = typedBuffer[num2]; num2++; num = ((num2 < SparseIndices.TypedBuffer.Length) ? SparseIndices.TypedBuffer[num2] : uint.MaxValue); } array2[i] = val; } return array2; } } public sealed class TypedBuffer { public readonly ResourcesStore Store; public readonly Accessor Accessor; public TypedBuffer(ResourcesStore store, Accessor accessor) { Store = store; Accessor = accessor; } public TypedArrayEntity GetEntity(Mapper mapper) where T : struct where U : struct { return new TypedArrayEntity(Store, Accessor, mapper); } public int[] GetPrimitivesAsInt() { if (Accessor.Type != 0) { throw new InvalidOperationException("Type must be Scalar: Actual = " + Accessor.Type); } return Accessor.ComponentType switch { Accessor.ComponentTypeEnum.BYTE => GetEntity((Mapper)((sbyte[] xs, int i) => xs[i])).AsArray(), Accessor.ComponentTypeEnum.UNSIGNED_BYTE => GetEntity((Mapper)((byte[] xs, int i) => xs[i])).AsArray(), Accessor.ComponentTypeEnum.SHORT => GetEntity((Mapper)((short[] xs, int i) => xs[i])).AsArray(), Accessor.ComponentTypeEnum.UNSIGNED_SHORT => GetEntity((Mapper)((ushort[] xs, int i) => xs[i])).AsArray(), Accessor.ComponentTypeEnum.UNSIGNED_INT => GetEntity((uint[] xs, int i) => (int)xs[i]).AsArray(), Accessor.ComponentTypeEnum.FLOAT => throw new InvalidOperationException("Cannot convert from float to int"), _ => throw new InvalidOperationException("Unexpected ComponentType: Actual = " + Accessor.ComponentType), }; } } } namespace VGltf.Types { [JsonSchema(Id = "accessor.schema.json")] public sealed class Accessor : GltfChildOfRootProperty { [Json] public enum ComponentTypeEnum { [JsonField] BYTE = 5120, [JsonField] UNSIGNED_BYTE = 5121, [JsonField] SHORT = 5122, [JsonField] UNSIGNED_SHORT = 5123, [JsonField] UNSIGNED_INT = 5125, [JsonField] FLOAT = 5126 } [Json(/*Could not decode attribute arguments.*/)] public enum TypeEnum { [JsonField(Name = "SCALAR")] Scalar, [JsonField(Name = "VEC2")] Vec2, [JsonField(Name = "VEC3")] Vec3, [JsonField(Name = "VEC4")] Vec4, [JsonField(Name = "MAT2")] Mat2, [JsonField(Name = "MAT3")] Mat3, [JsonField(Name = "MAT4")] Mat4 } [JsonSchema(Id = "accessor.sparse.schema.json")] public sealed class SparseType : GltfProperty { [JsonSchema(Id = "accessor.sparse.indices.schema.json")] public class IndicesType : GltfProperty { [Json] public enum ComponentTypeEnum { [JsonField] UNSIGNED_BYTE = 5121, [JsonField] UNSIGNED_SHORT = 5123, [JsonField] UNSIGNED_INT = 5125 } [JsonField(Name = "bufferView")] [JsonSchemaRequired] [JsonSchemaRef(/*Could not decode attribute arguments.*/)] public int BufferView; [JsonField(Name = "byteOffset")] [JsonSchema(Minimum = 0.0)] public int ByteOffset; [JsonField(Name = "componentType")] [JsonSchemaRequired] public ComponentTypeEnum ComponentType; } [JsonSchema(Id = "accessor.sparse.values.schema.json")] public sealed class ValuesType : GltfProperty { [JsonField(Name = "bufferView")] [JsonSchemaRequired] [JsonSchemaRef(/*Could not decode attribute arguments.*/)] public int BufferView; [JsonField(Name = "byteOffset")] [JsonSchema(Minimum = 0.0)] public int ByteOffset; } [JsonField(Name = "count")] [JsonSchema(Minimum = 0.0)] [JsonSchemaRequired] public int Count; [JsonField(Name = "indices")] [JsonSchemaRequired] public IndicesType Indices; [JsonField(Name = "values")] [JsonSchemaRequired] public ValuesType Values; } [JsonField(Name = "bufferView")] [JsonFieldIgnorable] [JsonSchemaRef(/*Could not decode attribute arguments.*/)] public int? BufferView; [JsonField(Name = "byteOffset")] [JsonSchema(Minimum = 0.0)] [JsonSchemaDependencies(new string[] { "bufferView" })] public int ByteOffset; [JsonField(Name = "componentType")] [JsonSchemaRequired] public ComponentTypeEnum ComponentType; [JsonField(Name = "normalized")] public bool Normalized; [JsonField(Name = "count")] [JsonSchema(Minimum = 1.0)] [JsonSchemaRequired] public int Count; [JsonField(Name = "type")] [JsonSchemaRequired] public TypeEnum Type; [JsonField(Name = "max")] [JsonFieldIgnorable] [JsonSchema(MinItems = 1, MaxItems = 16)] public float[] Max; [JsonField(Name = "min")] [JsonFieldIgnorable] [JsonSchema(MinItems = 1, MaxItems = 16)] public float[] Min; [JsonField(Name = "sparse")] [JsonFieldIgnorable] public SparseType Sparse; } public static class AccessorComponentTypeEnumExtensions { public static int SizeInBytes(this Accessor.ComponentTypeEnum e) { return e switch { Accessor.ComponentTypeEnum.BYTE => 1, Accessor.ComponentTypeEnum.UNSIGNED_BYTE => 1, Accessor.ComponentTypeEnum.SHORT => 2, Accessor.ComponentTypeEnum.UNSIGNED_SHORT => 2, Accessor.ComponentTypeEnum.UNSIGNED_INT => 4, Accessor.ComponentTypeEnum.FLOAT => 4, _ => throw new NotImplementedException(), }; } public static Type TypeOf(this Accessor.ComponentTypeEnum e) { return e switch { Accessor.ComponentTypeEnum.BYTE => typeof(sbyte), Accessor.ComponentTypeEnum.UNSIGNED_BYTE => typeof(byte), Accessor.ComponentTypeEnum.SHORT => typeof(short), Accessor.ComponentTypeEnum.UNSIGNED_SHORT => typeof(ushort), Accessor.ComponentTypeEnum.UNSIGNED_INT => typeof(uint), Accessor.ComponentTypeEnum.FLOAT => typeof(float), _ => throw new NotImplementedException(), }; } } public static class AccessorTypeEnumExtensions { public static int NumOfComponents(this Accessor.TypeEnum t) { return t switch { Accessor.TypeEnum.Scalar => 1, Accessor.TypeEnum.Vec2 => 2, Accessor.TypeEnum.Vec3 => 3, Accessor.TypeEnum.Vec4 => 4, Accessor.TypeEnum.Mat2 => 4, Accessor.TypeEnum.Mat3 => 9, Accessor.TypeEnum.Mat4 => 16, _ => throw new NotImplementedException(), }; } } public static class AccessorSparseIndicesComponentTypeEnumExtensions { public static Accessor.ComponentTypeEnum CommonType(this Accessor.SparseType.IndicesType.ComponentTypeEnum e) { return e switch { Accessor.SparseType.IndicesType.ComponentTypeEnum.UNSIGNED_BYTE => Accessor.ComponentTypeEnum.UNSIGNED_BYTE, Accessor.SparseType.IndicesType.ComponentTypeEnum.UNSIGNED_SHORT => Accessor.ComponentTypeEnum.UNSIGNED_SHORT, Accessor.SparseType.IndicesType.ComponentTypeEnum.UNSIGNED_INT => Accessor.ComponentTypeEnum.UNSIGNED_INT, _ => throw new NotImplementedException(), }; } public static int SizeInBytes(this Accessor.SparseType.IndicesType.ComponentTypeEnum e) { return e.CommonType().SizeInBytes(); } public static Type TypeOf(this Accessor.SparseType.IndicesType.ComponentTypeEnum e) { return e.CommonType().TypeOf(); } } [JsonSchema(Id = "animation.schema.json")] public sealed class Animation : GltfChildOfRootProperty { [JsonSchema(Id = "animation.channel.schema.json")] public class ChannelType : GltfProperty { [JsonSchema(Id = "animation.channel.target.schema.json")] public class TargetType : GltfProperty { [Json(/*Could not decode attribute arguments.*/)] public enum PathEnum { [JsonField(Name = "translation")] Translation, [JsonField(Name = "rotation")] Rotation, [JsonField(Name = "scale")] Scale, [JsonField(Name = "weights")] Weights } [JsonField(Name = "node")] [JsonSchemaRef(/*Could not decode attribute arguments.*/)] public int Node; [JsonField(Name = "path")] [JsonSchemaRequired] public PathEnum Path; } [JsonField(Name = "sampler")] [JsonSchemaRequired] [JsonSchemaRef(/*Could not decode attribute arguments.*/)] public int Sampler; [JsonField(Name = "target")] [JsonSchemaRequired] public TargetType Target; } [JsonSchema(Id = "animation.sampler.schema.json")] public class SamplerType { [Json(/*Could not decode attribute arguments.*/)] public enum InterpolationEnum { [JsonField(Name = "LINEAR")] LINEAR, [JsonField(Name = "STEP")] STEP, [JsonField(Name = "CUBICSPLINE")] CUBICSPLINE } [JsonField(Name = "input")] [JsonSchemaRequired] [JsonSchemaRef(/*Could not decode attribute arguments.*/)] public int Input; [JsonField(Name = "interpolation")] public InterpolationEnum Interpolation; [JsonField(Name = "output")] [JsonSchemaRequired] [JsonSchemaRef(/*Could not decode attribute arguments.*/)] public int Output; } [JsonField(Name = "channels")] [JsonSchema(MinItems = 1)] [JsonSchemaRequired] public List Channels; [JsonField(Name = "samplers")] [JsonSchema(MinItems = 1)] [JsonSchemaRequired] public List Samplers; } [JsonSchema(Id = "asset.schema.json")] public sealed class Asset : GltfProperty { [JsonField(Name = "copyright")] [JsonFieldIgnorable] public string Copyright; [JsonField(Name = "generator")] [JsonFieldIgnorable] public string Generator; [JsonField(Name = "version")] [JsonSchema(Pattern = "^[0-9]+\\.[0-9]+$")] [JsonSchemaRequired] public string Version; [JsonField(Name = "minVersion")] [JsonFieldIgnorable] [JsonSchema(Pattern = "^[0-9]+\\.[0-9]+$")] public string MinVersion; } [JsonSchema(Id = "buffer.schema.json")] public sealed class Buffer : GltfChildOfRootProperty { [JsonField(Name = "uri")] [JsonFieldIgnorable] public string Uri; [JsonField(Name = "byteLength")] [JsonSchema(Minimum = 1.0)] [JsonSchemaRequired] public int ByteLength; } [JsonSchema(Id = "bufferView.schema.json")] public sealed class BufferView : GltfChildOfRootProperty { [Json] public enum TargetEnum { [JsonField] ARRAY_BUFFER = 34962, [JsonField] ELEMENT_ARRAY_BUFFER } [JsonField(Name = "buffer")] [JsonSchemaRequired] [JsonSchemaRef(/*Could not decode attribute arguments.*/)] public int Buffer; [JsonField(Name = "byteOffset")] [JsonFieldIgnorable] [JsonSchema(Minimum = 0.0)] public int ByteOffset; [JsonField(Name = "byteLength")] [JsonSchema(Minimum = 1.0)] [JsonSchemaRequired] public int ByteLength; [JsonField(Name = "byteStride")] [JsonFieldIgnorable] [JsonSchema(Minimum = 4.0, Maximum = 252.0, MultipleOf = 4.0)] public int? ByteStride; [JsonField(Name = "target")] [JsonFieldIgnorable] public TargetEnum? Target; } [JsonSchema(Id = "camera.schema.json")] public sealed class Camera : GltfChildOfRootProperty { [JsonSchema(Id = "camera.orthographic.schema.json")] public sealed class OrthographicType : GltfProperty { [JsonField(Name = "xmag")] [JsonSchemaRequired] public float Xmag; [JsonField(Name = "ymag")] [JsonSchemaRequired] public float Ymag; [JsonField(Name = "zfar")] [JsonSchema(ExclusiveMinimum = 0.0)] [JsonSchemaRequired] public float Zfar; [JsonField(Name = "znear")] [JsonSchema(Minimum = 0.0)] [JsonSchemaRequired] public float Znear; } [JsonSchema(Id = "camera.perspective.schema.json")] public sealed class PerspectiveType { [JsonField(Name = "aspectRatio")] [JsonFieldIgnorable] [JsonSchema(ExclusiveMinimum = 0.0)] public float? AspectRatio; [JsonField(Name = "yfov")] [JsonSchema(ExclusiveMinimum = 0.0)] [JsonSchemaRequired] public float Yfov; [JsonField(Name = "zfar")] [JsonFieldIgnorable] [JsonSchema(ExclusiveMinimum = 0.0)] public float? Zfar; [JsonField(Name = "znear")] [JsonSchema(ExclusiveMinimum = 0.0)] [JsonSchemaRequired] public float Znear; } [Json(/*Could not decode attribute arguments.*/)] public enum TypeEnum { [JsonField(Name = "perspective")] Perspective, [JsonField(Name = "orthographic")] Orthographic } [JsonField(Name = "orthographic")] [JsonFieldIgnorable] public OrthographicType Orthographic; [JsonField(Name = "perspective")] [JsonFieldIgnorable] public PerspectiveType Perspective; [JsonField(Name = "type")] [JsonSchemaRequired] public TypeEnum Type; } [JsonSchema(Id = "glTF.schema.json")] public sealed class Gltf : GltfProperty { [JsonField(Name = "extensionsUsed")] [JsonFieldIgnorable] [JsonSchema(UniqueItems = true, MinItems = 1)] public List ExtensionsUsed; [JsonField(Name = "extensionsRequired")] [JsonFieldIgnorable] [JsonSchema(UniqueItems = true, MinItems = 1)] public List ExtensionsRequired; [JsonField(Name = "accessors")] [JsonFieldIgnorable] [JsonSchema(MinItems = 1)] public List Accessors; [JsonField(Name = "animations")] [JsonFieldIgnorable] [JsonSchema(MinItems = 1)] public List Animations; [JsonField(Name = "asset")] [JsonSchemaRequired] public Asset Asset; [JsonField(Name = "buffers")] [JsonFieldIgnorable] [JsonSchema(MinItems = 1)] public List Buffers; [JsonField(Name = "bufferViews")] [JsonFieldIgnorable] [JsonSchema(MinItems = 1)] public List BufferViews; [JsonField(Name = "cameras")] [JsonFieldIgnorable] [JsonSchema(MinItems = 1)] public List Cameras; [JsonField(Name = "images")] [JsonFieldIgnorable] [JsonSchema(MinItems = 1)] public List Images; [JsonField(Name = "materials")] [JsonFieldIgnorable] [JsonSchema(MinItems = 1)] public List Materials; [JsonField(Name = "meshes")] [JsonFieldIgnorable] [JsonSchema(MinItems = 1)] public List Meshes; [JsonField(Name = "nodes")] [JsonFieldIgnorable] [JsonSchema(MinItems = 1)] public List Nodes; [JsonField(Name = "samplers")] [JsonFieldIgnorable] [JsonSchema(MinItems = 1)] public List Samplers; [JsonField(Name = "scene")] [JsonFieldIgnorable] [JsonSchemaDependencies(new string[] { "scenes" })] [JsonSchemaRef(/*Could not decode attribute arguments.*/)] public int? Scene; [JsonField(Name = "scenes")] [JsonFieldIgnorable] [JsonSchema(MinItems = 1)] public List Scenes; [JsonField(Name = "skins")] [JsonFieldIgnorable] [JsonSchema(MinItems = 1)] public List Skins; [JsonField(Name = "textures")] [JsonFieldIgnorable] [JsonSchema(MinItems = 1)] public List Textures; public IEnumerable RootNodesIndices { get { if (!Scene.HasValue) { return Enumerable.Empty(); } Scene scene = Scenes[Scene.Value]; if (scene.Nodes == null) { return Enumerable.Empty(); } return scene.Nodes; } } public IEnumerable RootNodes => RootNodesIndices.Select((int i) => Nodes[i]); } [Json] public abstract class GltfChildOfRootProperty : GltfProperty { [JsonField(Name = "name")] [JsonFieldIgnorable] public string Name; } [JsonSchema(Minimum = 0.0)] public sealed class GltfID : RefTag { } [Json] public abstract class GltfProperty { [JsonField(Name = "extensions")] [JsonFieldIgnorable] public Dictionary Extensions; [JsonField(Name = "extras")] [JsonFieldIgnorable] public Dictionary Extras; public void AddExtension(string name, T value) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (Extensions == null) { Extensions = new Dictionary(); } INode value2 = new JsonSerializer(typeof(T)).SerializeToNode(value); Extensions.Add(name, value2); } public bool TryGetExtension(string name, JsonSchemaRegistry reg, out T value) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) if (Extensions == null) { value = default(T); return false; } if (!Extensions.TryGetValue(name, out var value2)) { value = default(T); return false; } ConstraintsViolationException val = JsonSchemaExtensions.Validate(JsonSchema.CreateFromType(reg, false), (object)value2, reg); if (val != null) { throw val; } object obj = new JsonDeserializer(typeof(T)).DeserializeFromNode(value2); value = (T)obj; return true; } public void AddExtra(string name, T value) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (Extras == null) { Extras = new Dictionary(); } INode value2 = new JsonSerializer(typeof(T)).SerializeToNode(value); Extras.Add(name, value2); } public bool TryGetExtra(string name, JsonSchemaRegistry reg, out T value) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) if (Extras == null) { value = default(T); return false; } if (!Extras.TryGetValue(name, out var value2)) { value = default(T); return false; } ConstraintsViolationException val = JsonSchemaExtensions.Validate(JsonSchema.CreateFromType(reg, false), (object)value2, reg); if (val != null) { throw val; } object obj = new JsonDeserializer(typeof(T)).DeserializeFromNode(value2); value = (T)obj; return true; } } [JsonSchema(Id = "image.schema.json")] public sealed class Image : GltfChildOfRootProperty { public const string MimeTypeImageJpeg = "image/jpeg"; public const string MimeTypeImagePng = "image/png"; [JsonField(Name = "uri")] [JsonFieldIgnorable] public string Uri; [JsonField(Name = "mimeType")] [JsonFieldIgnorable(WhenValueIs = "")] public string MimeType = ""; [JsonField(Name = "bufferView")] [JsonFieldIgnorable] [JsonSchemaDependencies(new string[] { "mimeType" })] [JsonSchemaRef(/*Could not decode attribute arguments.*/)] public int? BufferView; } public static class ImageExtensions { public static string GetExtension(this Image img) { string mimeType = img.MimeType; if (!(mimeType == "image/jpeg")) { if (mimeType == "image/png") { return ".png"; } if (img.Uri.StartsWith("data:image/jpeg;")) { return ".jpg"; } if (img.Uri.StartsWith("data:image/png;")) { return ".png"; } return Path.GetExtension(img.Uri).ToLower(); } return ".jpg"; } } [JsonSchema(Id = "material.schema.json")] public sealed class Material : GltfChildOfRootProperty { [JsonSchema(Id = "material.pbrMetallicRoughness.schema.json")] public sealed class PbrMetallicRoughnessType : GltfProperty { [JsonField(Name = "baseColorFactor")] [JsonSchema(MinItems = 4, MaxItems = 4)] [ItemsJsonSchema(Minimum = 0.0, Maximum = 1.0)] public float[] BaseColorFactor = new float[4] { 1f, 1f, 1f, 1f }; [JsonField(Name = "baseColorTexture")] [JsonFieldIgnorable] public BaseColorTextureInfoType BaseColorTexture; [JsonField(Name = "metallicFactor")] [JsonSchema(Minimum = 0.0, Maximum = 1.0)] public float MetallicFactor = 1f; [JsonField(Name = "roughnessFactor")] [JsonSchema(Minimum = 0.0, Maximum = 1.0)] public float RoughnessFactor = 1f; [JsonField(Name = "metallicRoughnessTexture")] [JsonFieldIgnorable] public MetallicRoughnessTextureInfoType MetallicRoughnessTexture; } [Json] public sealed class BaseColorTextureInfoType : TextureInfo { public override TextureInfoKind Kind => TextureInfoKind.BaseColor; } [Json] public sealed class MetallicRoughnessTextureInfoType : TextureInfo { public override TextureInfoKind Kind => TextureInfoKind.MetallicRoughness; } [JsonSchema(Id = "material.normalTextureInfo.schema.json")] public sealed class NormalTextureInfoType : TextureInfo { [JsonField(Name = "scale")] public float Scale = 1f; public override TextureInfoKind Kind => TextureInfoKind.Normal; } [JsonSchema(Id = "material.occlusionTextureInfo.schema.json")] public sealed class OcclusionTextureInfoType : TextureInfo { [JsonField(Name = "strength")] [JsonSchema(Minimum = 0.0, Maximum = 1.0)] public float Strength = 1f; public override TextureInfoKind Kind => TextureInfoKind.Occlusion; } [Json] public sealed class EmissiveTextureInfoType : TextureInfo { public override TextureInfoKind Kind => TextureInfoKind.Emissive; } [Json(/*Could not decode attribute arguments.*/)] public enum AlphaModeEnum { [JsonField(Name = "OPAQUE")] Opaque, [JsonField(Name = "MASK")] Mask, [JsonField(Name = "BLEND")] Blend } [JsonField(Name = "pbrMetallicRoughness")] [JsonFieldIgnorable] public PbrMetallicRoughnessType PbrMetallicRoughness; [JsonField(Name = "normalTexture")] [JsonFieldIgnorable] public NormalTextureInfoType NormalTexture; [JsonField(Name = "occlusionTexture")] [JsonFieldIgnorable] public OcclusionTextureInfoType OcclusionTexture; [JsonField(Name = "emissiveTexture")] [JsonFieldIgnorable] public EmissiveTextureInfoType EmissiveTexture; [JsonField(Name = "emissiveFactor")] [JsonFieldIgnorable] [JsonSchema(MinItems = 3, MaxItems = 3)] [ItemsJsonSchema(Minimum = 0.0, Maximum = 1.0)] public float[] EmissiveFactor = new float[3]; [JsonField(Name = "alphaMode")] public AlphaModeEnum AlphaMode; [JsonField(Name = "alphaCutoff")] [JsonSchema(Minimum = 0.0)] [JsonFieldIgnorable(WhenValueIs = 0f)] [JsonSchemaDependencies(new string[] { "alphaMode" })] public float AlphaCutoff = 0.5f; [JsonField(Name = "doubleSided")] public bool DoubleSided; } public static class MaterialExtensions { public static IEnumerable GetTextures(this Material mat) { if (mat.PbrMetallicRoughness != null) { yield return mat.PbrMetallicRoughness.BaseColorTexture; yield return mat.PbrMetallicRoughness.MetallicRoughnessTexture; } yield return mat.NormalTexture; yield return mat.OcclusionTexture; yield return mat.EmissiveTexture; } } [JsonSchema(Id = "mesh.schema.json")] public sealed class Mesh : GltfChildOfRootProperty { [JsonSchema(Id = "mesh.primitive.schema.json")] public sealed class PrimitiveType : GltfProperty { [Json] public enum ModeEnum { [JsonField] POINTS, [JsonField] LINES, [JsonField] LINE_LOOP, [JsonField] LINE_STRIP, [JsonField] TRIANGLES, [JsonField] TRIANGLE_STRIP, [JsonField] TRIANGLE_FAN } public static class AttributeName { public static readonly string POSITION = "POSITION"; public static readonly string NORMAL = "NORMAL"; public static readonly string TANGENT = "TANGENT"; public static readonly string TEXCOORD_0 = "TEXCOORD_0"; public static readonly string TEXCOORD_1 = "TEXCOORD_1"; public static readonly string COLOR_0 = "COLOR_0"; public static readonly string JOINTS_0 = "JOINTS_0"; public static readonly string WEIGHTS_0 = "WEIGHTS_0"; } [JsonField(Name = "attributes")] [JsonSchema(MinProperties = 1)] [JsonSchemaRequired] [JsonSchemaRef(/*Could not decode attribute arguments.*/)] public Dictionary Attributes; [JsonField(Name = "indices")] [JsonFieldIgnorable] [JsonSchemaRef(/*Could not decode attribute arguments.*/)] public int? Indices; [JsonField(Name = "material")] [JsonFieldIgnorable] [JsonSchemaRef(/*Could not decode attribute arguments.*/)] public int? Material; [JsonField(Name = "mode")] [JsonFieldIgnorable] public ModeEnum? Mode = ModeEnum.TRIANGLES; [JsonField(Name = "targets")] [JsonFieldIgnorable] [JsonSchema(MinItems = 1)] [ItemsJsonSchema(MinProperties = 1)] [ItemsJsonSchemaRef(/*Could not decode attribute arguments.*/)] public List> Targets; } [JsonField(Name = "primitives")] [JsonSchema(MinItems = 1)] [JsonSchemaRequired] public List Primitives; [JsonField(Name = "weights")] [JsonFieldIgnorable] [JsonSchema(MinItems = 1)] public float[] Weights; } [JsonSchema(Id = "node.schema.json")] public sealed class Node : GltfChildOfRootProperty { [JsonField(Name = "camera")] [JsonFieldIgnorable] [JsonSchemaRef(/*Could not decode attribute arguments.*/)] public int? Camera; [JsonField(Name = "children")] [JsonFieldIgnorable] [JsonSchema(UniqueItems = true, MinItems = 1)] [ItemsJsonSchemaRef(/*Could not decode attribute arguments.*/)] public int[] Children; [JsonField(Name = "skin")] [JsonFieldIgnorable] [JsonSchemaDependencies(new string[] { "mesh" })] [JsonSchemaRef(/*Could not decode attribute arguments.*/)] public int? Skin; [JsonField(Name = "matrix")] [JsonFieldIgnorable] [JsonSchema(MinItems = 16, MaxItems = 16)] public float[] Matrix = new float[16] { 1f, 0f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 0f, 1f }; [JsonField(Name = "mesh")] [JsonFieldIgnorable] [JsonSchemaRef(/*Could not decode attribute arguments.*/)] public int? Mesh; [JsonField(Name = "rotation")] [JsonFieldIgnorable] [JsonSchema(MinItems = 4, MaxItems = 4)] [ItemsJsonSchema(Minimum = -1.0, Maximum = 1.0)] public float[] Rotation = new float[4] { 0f, 0f, 0f, 1f }; [JsonField(Name = "scale")] [JsonFieldIgnorable] [JsonSchema(MinItems = 3, MaxItems = 3)] public float[] Scale = new float[3] { 1f, 1f, 1f }; [JsonField(Name = "translation")] [JsonFieldIgnorable] [JsonSchema(MinItems = 3, MaxItems = 3)] public float[] Translation = new float[3]; [JsonField(Name = "weights")] [JsonFieldIgnorable] [JsonSchema(MinItems = 1)] [JsonSchemaDependencies(new string[] { "mesh" })] public float[] Weights; } [JsonSchema(Id = "sampler.schema.json")] public sealed class Sampler : GltfChildOfRootProperty { [Json] public enum MagFilterEnum { [JsonField] NEAREST = 9728, [JsonField] LINEAR } [Json] public enum MinFilterEnum { [JsonField] NEAREST = 9728, [JsonField] LINEAR = 9729, [JsonField] NEAREST_MIPMAP_NEAREST = 9984, [JsonField] LINEAR_MIPMAP_NEAREST = 9985, [JsonField] NEAREST_MIPMAP_LINEAR = 9986, [JsonField] LINEAR_MIPMAP_LINEAR = 9987 } [Json] public enum WrapEnum { [JsonField] ClampToEdge = 33071, [JsonField] MirroredRepeat = 33648, [JsonField] Repeat = 10497 } [JsonField(Name = "magFilter")] [JsonFieldIgnorable] public MagFilterEnum? MagFilter; [JsonField(Name = "minFilter")] [JsonFieldIgnorable] public MinFilterEnum? MinFilter; [JsonField(Name = "wrapS")] [JsonFieldIgnorable(WhenValueIs = WrapEnum.Repeat)] public WrapEnum WrapS = WrapEnum.Repeat; [JsonField(Name = "wrapT")] [JsonFieldIgnorable(WhenValueIs = WrapEnum.Repeat)] public WrapEnum WrapT = WrapEnum.Repeat; } [JsonSchema(Id = "scene.schema.json")] public sealed class Scene : GltfChildOfRootProperty { [JsonField(Name = "nodes")] [JsonSchema(UniqueItems = true, MinItems = 1)] [ItemsJsonSchemaRef(/*Could not decode attribute arguments.*/)] public int[] Nodes; } [JsonSchema(Id = "skin.schema.json")] public sealed class Skin : GltfChildOfRootProperty { [JsonField(Name = "inverseBindMatrices")] [JsonFieldIgnorable] [JsonSchemaRef(/*Could not decode attribute arguments.*/)] public int? InverseBindMatrices; [JsonField(Name = "skeleton")] [JsonFieldIgnorable] [JsonSchemaRef(/*Could not decode attribute arguments.*/)] public int? Skeleton; [JsonField(Name = "joints")] [JsonSchema(UniqueItems = true, MinItems = 1)] [JsonSchemaRequired] [ItemsJsonSchemaRef(/*Could not decode attribute arguments.*/)] public int[] Joints; } [JsonSchema(Id = "texture.schema.json")] public sealed class Texture : GltfChildOfRootProperty { [JsonField(Name = "sampler")] [JsonFieldIgnorable] [JsonSchemaRef(/*Could not decode attribute arguments.*/)] public int? Sampler; [JsonField(Name = "source")] [JsonFieldIgnorable] [JsonSchemaRef(/*Could not decode attribute arguments.*/)] public int? Source; } public enum TextureInfoKind { BaseColor, MetallicRoughness, Normal, Occlusion, Emissive } [Json] public abstract class TextureInfo : GltfProperty { [JsonField(Name = "index")] [JsonSchemaRequired] [JsonSchemaRef(/*Could not decode attribute arguments.*/)] public int Index; [JsonField(Name = "texCoord")] [JsonSchema(Minimum = 0.0)] [JsonSchemaRequired] public int TexCoord; public abstract TextureInfoKind Kind { get; } } } namespace VGltf.Types.Extensions { public static class GltfExtensions { public static Scene GetSceneObject(this Gltf gltf) { if (!gltf.Scene.HasValue) { throw new Exception("Scene is null"); } return gltf.Scenes[gltf.Scene.Value]; } public static Image GetImageByTextureIndex(this Gltf gltf, int index, out int? imageIndex) { Texture texture = gltf.Textures[index]; imageIndex = texture.Source; return gltf.Images[imageIndex.Value]; } public static Image GetImageByTextureIndex(this Gltf gltf, int index) { int? imageIndex; return gltf.GetImageByTextureIndex(index, out imageIndex); } public static Sampler GetSamplerByTextureIndex(this Gltf gltf, int index, out int? samplerIndex) { Texture texture = gltf.Textures[index]; samplerIndex = texture.Sampler; return gltf.Samplers[samplerIndex.Value]; } public static Sampler GetSamplerByTextureIndex(this Gltf gltf, int index) { int? samplerIndex; return gltf.GetSamplerByTextureIndex(index, out samplerIndex); } public static int AddImage(this Gltf gltf, Image item) { if (gltf.Images == null) { gltf.Images = new List(); } int count = gltf.Images.Count; gltf.Images.Add(item); return count; } public static int AddAccessor(this Gltf gltf, Accessor item) { if (gltf.Accessors == null) { gltf.Accessors = new List(); } int count = gltf.Accessors.Count; gltf.Accessors.Add(item); return count; } public static int AddMesh(this Gltf gltf, Mesh item) { if (gltf.Meshes == null) { gltf.Meshes = new List(); } int count = gltf.Meshes.Count; gltf.Meshes.Add(item); return count; } public static int AddNode(this Gltf gltf, Node item) { if (gltf.Nodes == null) { gltf.Nodes = new List(); } int count = gltf.Nodes.Count; gltf.Nodes.Add(item); return count; } public static int AddScene(this Gltf gltf, Scene item) { if (gltf.Scenes == null) { gltf.Scenes = new List(); } int count = gltf.Scenes.Count; gltf.Scenes.Add(item); return count; } public static int AddMaterial(this Gltf gltf, Material item) { if (gltf.Materials == null) { gltf.Materials = new List(); } int count = gltf.Materials.Count; gltf.Materials.Add(item); return count; } public static int AddSampler(this Gltf gltf, Sampler item) { if (gltf.Samplers == null) { gltf.Samplers = new List(); } int count = gltf.Samplers.Count; gltf.Samplers.Add(item); return count; } public static int AddTexture(this Gltf gltf, Texture item) { if (gltf.Textures == null) { gltf.Textures = new List(); } int count = gltf.Textures.Count; gltf.Textures.Add(item); return count; } public static int AddSkin(this Gltf gltf, Skin item) { if (gltf.Skins == null) { gltf.Skins = new List(); } int count = gltf.Skins.Count; gltf.Skins.Add(item); return count; } public static void AddExtensionUsed(this Gltf gltf, string name) { if (gltf.ExtensionsUsed == null) { gltf.ExtensionsUsed = new List(); } if (!gltf.ContainsExtensionUsed(name)) { gltf.ExtensionsUsed.Add(name); } } public static bool ContainsExtensionUsed(this Gltf gltf, string name) { if (gltf.ExtensionsUsed == null) { return false; } return gltf.ExtensionsUsed.Contains(name); } public static void AddExtensionRequired(this Gltf gltf, string name) { if (gltf.ExtensionsRequired == null) { gltf.ExtensionsRequired = new List(); } if (!gltf.ContainsExtensionRequired(name)) { gltf.ExtensionsRequired.Add(name); } } public static bool ContainsExtensionRequired(this Gltf gltf, string name) { if (gltf.ExtensionsRequired == null) { return false; } return gltf.ExtensionsRequired.Contains(name); } } } namespace VGltf.Glb { public static class Align { public static uint CalcPadding(uint offset, uint alignment) { return (alignment - offset % alignment) % alignment; } public static uint WritePadding(Stream s, uint offset, uint alignment, byte pad = 0) { uint num = CalcPadding(offset, alignment); for (int i = 0; i < num; i++) { s.WriteByte(pad); } return num; } } public sealed class Header { public uint Magic; public uint Version; public uint Length; } public sealed class Chunk { public uint ChunkLength; public uint ChunkType; public byte[] ChunkData; } public sealed class StoredBuffer { public ArraySegment Payload; } public sealed class Reader : IDisposable { private readonly BinaryReader _r; public Reader(Stream s) { _r = new BinaryReader(s); } public void Dispose() { if (_r != null) { ((IDisposable)_r).Dispose(); } } public Header ReadHeader() { return new Header { Magic = _r.ReadUInt32(), Version = _r.ReadUInt32(), Length = _r.ReadUInt32() }; } public Chunk ReadChunk() { try { Chunk chunk = new Chunk(); chunk.ChunkLength = _r.ReadUInt32(); chunk.ChunkType = _r.ReadUInt32(); chunk.ChunkData = _r.ReadBytes((int)chunk.ChunkLength); return chunk; } catch (EndOfStreamException) { return null; } } public static GltfContainer ReadAsContainer(Stream s) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown using Reader reader = new Reader(s); Header header = reader.ReadHeader(); if (header.Magic != 1179937895) { throw new NotImplementedException(); } if (header.Version != 2) { throw new NotImplementedException(); } Gltf gltf = null; StoredBuffer storedBuffer = null; JsonSchemaRegistry reg = new JsonSchemaRegistry(); int num = 0; while (true) { Chunk chunk = reader.ReadChunk(); if (chunk == null) { break; } switch (chunk.ChunkType) { case 1313821514u: { if (num != 0) { throw new NotImplementedException("Json"); } if (gltf != null) { throw new NotImplementedException("Json"); } using (MemoryStream s2 = new MemoryStream(chunk.ChunkData)) { gltf = GltfReader.Read(s2, reg); } break; } case 5130562u: if (num != 1) { throw new NotImplementedException("BinaryBuffer"); } if (storedBuffer != null) { throw new NotImplementedException("BinaryBuffer"); } storedBuffer = new StoredBuffer { Payload = new ArraySegment(chunk.ChunkData) }; break; } num++; } if (gltf == null) { throw new NotImplementedException("Json is empty"); } return new GltfContainer(gltf, storedBuffer, reg); } } public sealed class Writer : IDisposable { private readonly BinaryWriter _w; public Writer(Stream s) { _w = new BinaryWriter(s); } public void Dispose() { if (_w != null) { ((IDisposable)_w).Dispose(); } } public void WriteHeader(Header h) { _w.Write(h.Magic); _w.Write(h.Version); _w.Write(h.Length); } public void WriteChunk(Chunk c) { _w.Write(c.ChunkLength); _w.Write(c.ChunkType); _w.Write(c.ChunkData); } public static void WriteFromContainer(Stream s, GltfContainer container) { using Writer writer = new Writer(s); uint num = 0u; byte[] array = null; if (container.Gltf == null) { throw new NotImplementedException("Json is empty"); } using (MemoryStream memoryStream = new MemoryStream()) { GltfWriter.Write(memoryStream, container.Gltf, container.JsonSchemas); array = memoryStream.ToArray(); } num += (uint)(8 + array.Length); uint num2 = Align.CalcPadding(num, 4u); num += num2; byte[] array2 = null; if (container.Buffer != null) { using (MemoryStream memoryStream2 = new MemoryStream()) { ArraySegment payload = container.Buffer.Payload; memoryStream2.Write(payload.Array, payload.Offset, payload.Count); array2 = memoryStream2.ToArray(); } num += (uint)(8 + array2.Length); } writer.WriteHeader(new Header { Magic = 1179937895u, Version = 2u, Length = 12 + num }); writer.WriteChunk(new Chunk { ChunkLength = (uint)array.Length + num2, ChunkType = 1313821514u, ChunkData = array }); writer._w.Write(new byte[4] { 32, 32, 32, 32 }, 0, (int)num2); if (array2 != null) { writer.WriteChunk(new Chunk { ChunkLength = (uint)array2.Length, ChunkType = 5130562u, ChunkData = array2 }); } } } } namespace VGltf.Ext.KhrMaterialsUnlit.Types { [JsonSchema(Title = "KHR_materials_unlit glTF extension", Description = "glTF extension that defines the unlit material model.", Id = "glTF.KHR_materials_unlit.schema.json")] public sealed class KhrMaterialsUnlit { public static readonly string ExtensionName = "KHR_materials_unlit"; } } namespace VGltf.Ext.KhrMaterialsEmissiveStrength.Types { [JsonSchema(Title = "KHR_materials_emissive_strength glTF extension", Description = "glTF extension that adjusts the strength of emissive material properties.", Id = "glTF.KHR_materials_emissive_strength.schema.json")] public sealed class KhrMaterialsEmissiveStrength { public static readonly string ExtensionName = "KHR_materials_emissive_strength"; [JsonField(Name = "emissiveStrength")] [JsonFieldIgnorable(WhenValueIs = 1f)] [JsonSchema(Minimum = 0.0)] public float EmissiveStrength = 1f; } }