| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using SharpGLTF.CodeGen;
- using SharpGLTF.SchemaReflection;
- namespace SharpGLTF
- {
- public class MainSchemaProcessor : SchemaProcessor
- {
- public override IEnumerable<(string TargetFileName, SchemaType.Context Schema)> ReadSchema()
- {
- // load and process schema
- var ctx = SchemaProcessing.LoadSchemaContext(Constants.MainSchemaFile);
- // Ignore "glTF Property" because it is completely hand coded.
- ctx.IgnoredByCodeEmitter("glTF Property");
- // We will mimeType "anyof" as a plain string.
- ctx.Remove("image/jpeg-image/png");
- // replace Image.mimeType type from an Enum to String, so we can serialize it with more formats if required
- ctx.FindClass("Image")
- .GetField("mimeType")
- .FieldType = ctx.UseString();
- // replace Node.Matrix, Node.Rotation, Node.Scale and Node.Translation with System.Numerics.Vectors types
- var node = ctx.FindClass("Node");
- // the default values of the transform properties is both a "known value" and null, so
- // we preffer to set here the "known value" since it's also used to check whether
- // the value should be serialized.
- // But then, we need to set the values to null in the Node Constructor,
- // because Matrix and SRT are mutually exclusive.
- node.GetField("matrix").SetDataType(typeof(System.Numerics.Matrix4x4), true).SetDefaultValue("System.Numerics.Matrix4x4.Identity").SetItemsRange(0);
- node.GetField("scale").SetDataType(typeof(System.Numerics.Vector3), true).SetDefaultValue("Vector3.One").SetItemsRange(0);
- node.GetField("rotation").SetDataType(typeof(System.Numerics.Quaternion), true).SetDefaultValue("Quaternion.Identity").SetItemsRange(0);
- node.GetField("translation").SetDataType(typeof(System.Numerics.Vector3), true).SetDefaultValue("Vector3.Zero").SetItemsRange(0);
- // replace Material.emissiveFactor with System.Numerics.Vectors types
- ctx.FindClass("Material")
- .GetField("emissiveFactor")
- .SetDataType(typeof(System.Numerics.Vector3), true)
- .SetDefaultValue("Vector3.Zero")
- .SetItemsRange(0);
- // replace Material.baseColorFactor with System.Numerics.Vectors types
- ctx.FindClass("Material PBR Metallic Roughness")
- .GetField("baseColorFactor")
- .SetDataType(typeof(System.Numerics.Vector4), true)
- .SetDefaultValue("Vector4.One")
- .SetItemsRange(0);
- ctx.FindEnum("LINEAR-NEAREST")
- .SetValue("DEFAULT", 0);
- ctx.FindEnum("LINEAR-LINEAR_MIPMAP_LINEAR-LINEAR_MIPMAP_NEAREST-NEAREST-NEAREST_MIPMAP_LINEAR-NEAREST_MIPMAP_NEAREST")
- .SetValue("DEFAULT", 0);
- // Accessor.type is declared as AnyOfEnum, but also as a STRING,
- // which can be used by extensions to store non standard values like MAT4x3
- ctx.FindClass("Accessor")
- .GetField("type").SetDataType(typeof(string), true);
- // Since DimensionType can have additional values other than the ones defined by the schema
- // we need a "special" value to define it
- ctx.FindEnum("MAT2-MAT3-MAT4-SCALAR-VEC2-VEC3-VEC4")
- .SetValue("CUSTOM", 0);
- yield return ("gltf.g", ctx);
- }
- public override void PrepareTypes(CSharpEmitter newEmitter, SchemaType.Context ctx)
- {
- newEmitter.SetCollectionContainer("List<TItem>");
- const string rootName = "ModelRoot";
- newEmitter.SetRuntimeName("glTF", rootName);
- newEmitter.SetRuntimeName("glTF Property", "ExtraProperties");
- newEmitter.SetRuntimeName("glTF Child of Root Property", "LogicalChildOfRoot");
- newEmitter.SetRuntimeName("Sampler", "TextureSampler");
- newEmitter.SetRuntimeName("UNSIGNED_BYTE-UNSIGNED_INT-UNSIGNED_SHORT", "IndexEncodingType");
- newEmitter.SetRuntimeName("BYTE-FLOAT-SHORT-UNSIGNED_BYTE-UNSIGNED_INT-UNSIGNED_SHORT", "EncodingType");
- newEmitter.SetRuntimeName("MAT2-MAT3-MAT4-SCALAR-VEC2-VEC3-VEC4", "DimensionType");
- newEmitter.SetRuntimeName("rotation-scale-translation-weights", "PropertyPath");
- newEmitter.SetRuntimeName("ARRAY_BUFFER-ELEMENT_ARRAY_BUFFER", "BufferMode");
- newEmitter.SetRuntimeName("orthographic-perspective", "CameraType");
- newEmitter.SetRuntimeName("BLEND-MASK-OPAQUE", "AlphaMode");
- newEmitter.SetRuntimeName("LINE_LOOP-LINE_STRIP-LINES-POINTS-TRIANGLE_FAN-TRIANGLE_STRIP-TRIANGLES", "PrimitiveType");
- newEmitter.SetRuntimeName("CUBICSPLINE-LINEAR-STEP", "AnimationInterpolationMode");
- newEmitter.SetRuntimeName("LINEAR-NEAREST", "TextureInterpolationFilter");
- newEmitter.SetRuntimeName("CLAMP_TO_EDGE-MIRRORED_REPEAT-REPEAT", "TextureWrapMode");
- newEmitter.SetRuntimeName("LINEAR-LINEAR_MIPMAP_LINEAR-LINEAR_MIPMAP_NEAREST-NEAREST-NEAREST_MIPMAP_LINEAR-NEAREST_MIPMAP_NEAREST", "TextureMipMapFilter");
- // add "pointer" enum value to PropertyPath, which is required by KHR_animation_pointer
- var propertyPathEnum = ctx.FindEnum("rotation-scale-translation-weights");
- propertyPathEnum?.SetValue("pointer", 0);
- var meshClass = ctx.FindClass("Mesh");
- if (meshClass != null)
- {
- newEmitter.SetCollectionContainer(meshClass.UseField("primitives"), "ChildrenList<TItem,Mesh>");
- }
- var animationClass = ctx.FindClass("Animation");
- if (animationClass != null)
- {
- newEmitter.SetCollectionContainer(animationClass.UseField("channels"), "ChildrenList<TItem,Animation>");
- newEmitter.SetCollectionContainer(animationClass.UseField("samplers"), "ChildrenList<TItem,Animation>");
- }
- var classes = ctx.Classes.ToArray();
- var fields = classes
- .SelectMany(item => item.Fields)
- .ToArray();
- foreach (var f in fields)
- {
- if (f.FieldType is ArrayType atype)
- {
- if (atype.ItemType is ClassType ctype)
- {
- if (ctype.BaseClass != null && ctype.BaseClass.PersistentName == "glTF Child of Root Property")
- {
- newEmitter.SetCollectionContainer(f, $"ChildrenList<TItem,{rootName}>");
- }
- }
- }
- }
- }
- }
- }
|