Browse Source

Schema Code Generator: Huge code cleanup

Vicente Penades 4 years ago
parent
commit
6564480f07

+ 8 - 40
build/SharpGLTF.CodeGen/Constants.cs

@@ -32,49 +32,17 @@ namespace SharpGLTF
         #endregion
 
         #region extension paths        
-        public static class KhronosExtensions
-        {
-            private static string KhronosSchemaDir => System.IO.Path.Combine(Constants.LocalRepoDirectory, "extensions", "2.0", "Khronos");
-
-            private static string _Path(string ext, string json)
-            {
-                return System.IO.Path.Combine(KhronosSchemaDir, ext, "schema", json);
-            }
-
-            // public static string Draco => _Path("KHR_draco_mesh_compression", "schema");
-
-            public static string XMP_Model => _Path("KHR_xmp", "glTF.KHR_xmp.schema.json");
-            public static string XMP_Node => _Path("KHR_xmp", "node.KHR_xmp.schema.json");
-            public static string PbrSpecularGlossiness => _Path("KHR_materials_pbrSpecularGlossiness", "glTF.KHR_materials_pbrSpecularGlossiness.schema.json");
-            public static string PbrClearCoat => _Path("KHR_materials_clearcoat", "glTF.KHR_materials_clearcoat.schema.json");
-            public static string PbrTransmission => _Path("KHR_materials_transmission", "glTF.KHR_materials_transmission.schema.json");
-            public static string PbrSheen => _Path("KHR_materials_sheen", "glTF.KHR_materials_sheen.schema.json");
-            public static string PbrSpecular => _Path("KHR_materials_specular", "glTF.KHR_materials_specular.schema.json");
-            public static string MaterialIor => _Path("KHR_materials_ior", "glTF.KHR_materials_ior.schema.json");
-            public static string Unlit => _Path("KHR_materials_unlit", "glTF.KHR_materials_unlit.schema.json");
-            public static string LightsPunctual_Model => _Path("KHR_lights_punctual", "glTF.KHR_lights_punctual.schema.json");
-            public static string LightsPunctual_Node => _Path("KHR_lights_punctual", "node.KHR_lights_punctual.schema.json");
-            public static string TextureTransform => _Path("KHR_texture_transform", "KHR_texture_transform.textureInfo.schema.json");
-            public static string Ktx2 => _Path("KHR_texture_basisu", "texture.KHR_texture_basisu.schema.json");
-        }
+        private static string KhronosSchemaDir => System.IO.Path.Combine(LocalRepoDirectory, "extensions", "2.0", "Khronos");
+        private static string VendorSchemaDir => System.IO.Path.Combine(LocalRepoDirectory, "extensions", "2.0", "Vendor");
 
-        public static class VendorExtensions
+        internal static string KhronosExtensionPath(string ext, string json)
         {
-            private static string VendorSchemaDir => System.IO.Path.Combine(Constants.LocalRepoDirectory, "extensions", "2.0", "Vendor");
-
-            private static string _Path(string ext, string json)
-            {
-                return System.IO.Path.Combine(VendorSchemaDir, ext, "schema", json);
-            }
+            return System.IO.Path.Combine(KhronosSchemaDir, ext, "schema", json);
+        }        
 
-            public static string TextureDDS => _Path("MSFT_texture_dds", "glTF.MSFT_texture_dds.schema.json");
-            public static string TextureWebp => _Path("EXT_texture_webp", "glTF.EXT_texture_webp.schema.json");
-            public static string MeshGpuInstancing => _Path("EXT_mesh_gpu_instancing", "glTF.EXT_mesh_gpu_instancing.schema.json");
-
-            public static string AgiRootArticulations => _Path("AGI_articulations", "glTF.AGI_articulations.schema.json");
-            public static string AgiNodeArticulations => _Path("AGI_articulations", "node.AGI_articulations.schema.json");
-            public static string AgiRootStkMetadata => _Path("AGI_stk_metadata", "glTF.AGI_stk_metadata.schema.json");
-            public static string AgiNodeStkMetadata => _Path("AGI_stk_metadata", "node.AGI_stk_metadata.schema.json");
+        internal static string VendorExtensionPath(string ext, string json)
+        {
+            return System.IO.Path.Combine(VendorSchemaDir, ext, "schema", json);
         }
 
         #endregion

+ 70 - 0
build/SharpGLTF.CodeGen/Ext.AGI_Articulations.cs

@@ -0,0 +1,70 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using SharpGLTF.SchemaReflection;
+
+namespace SharpGLTF
+{
+    class AgiArticulationsExtension : SchemaProcessor
+    {
+        private static string RootSchemaUri => Constants.VendorExtensionPath("AGI_articulations", "glTF.AGI_articulations.schema.json");
+        private static string NodeSchemaUri => Constants.VendorExtensionPath("AGI_articulations", "node.AGI_articulations.schema.json");
+
+        public override IEnumerable<(string, SchemaType.Context)> Process()
+        {
+            yield return ("ext.AgiRootArticulations.g", ProcessRoot());
+            yield return ("ext.AgiNodeArticulations.g", ProcessNode());
+        }        
+
+        private static SchemaType.Context ProcessRoot()
+        {
+            var ctx = SchemaProcessing.LoadSchemaContext(RootSchemaUri);
+            ctx.IgnoredByCodeEmitter("glTF Property");
+            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
+
+            ctx.FindClass("Articulation")
+                .GetField("pointingVector")
+                .SetDataType(typeof(System.Numerics.Vector3), true)
+                .SetItemsRange(0);            
+
+            return ctx;
+        }
+
+        private static SchemaType.Context ProcessNode()
+        {
+            var ctx = SchemaProcessing.LoadSchemaContext(NodeSchemaUri);
+            ctx.IgnoredByCodeEmitter("glTF Property");
+            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
+
+            return ctx;
+        }
+
+        public override void PrepareTypes(CodeGen.CSharpEmitter newEmitter, SchemaType.Context ctx)
+        {
+            newEmitter.SetRuntimeName("AGI_articulations glTF extension", "AgiRootArticulations");
+            newEmitter.SetRuntimeName("AGI_articulations glTF Node extension", "AgiNodeArticulations");
+            newEmitter.SetRuntimeName("Articulation", "AgiArticulation");
+            newEmitter.SetRuntimeName("Articulation Stage", "AgiArticulationStage");
+            newEmitter.SetRuntimeName("uniformScale-xRotate-xScale-xTranslate-yRotate-yScale-yTranslate-zRotate-zScale-zTranslate", "AgiArticulationTransformType");            
+
+            var agiArticulationRootClass = ctx.FindClass("AGI_articulations glTF extension");
+            if (agiArticulationRootClass != null)
+            {
+                newEmitter.SetCollectionContainer(agiArticulationRootClass.UseField("articulations"), "ChildrenCollection<TItem,AgiRootArticulations>");
+            }
+
+            var agiArticulationClass = ctx.FindClass("Articulation");
+            if (agiArticulationClass != null)
+            {
+                newEmitter.SetCollectionContainer(agiArticulationClass.UseField("stages"), "ChildrenCollection<TItem,AgiArticulation>");
+            }
+
+            var agiStkMetadataRootClass = ctx.FindClass("AGI_stk_metadata glTF extension");
+            if (agiStkMetadataRootClass != null)
+            {
+                newEmitter.SetCollectionContainer(agiStkMetadataRootClass.UseField("solarPanelGroups"), "ChildrenCollection<TItem,AgiRootStkMetadata>");
+            }
+        }
+    }
+}

+ 43 - 0
build/SharpGLTF.CodeGen/Ext.AGI_RootStkMetadata.cs

@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using SharpGLTF.SchemaReflection;
+
+namespace SharpGLTF
+{
+    class AgiStkMetadataExtension : SchemaProcessor
+    {
+        private static string RootSchemaUri => Constants.VendorExtensionPath("AGI_stk_metadata", "glTF.AGI_stk_metadata.schema.json");
+        private static string NodeSchemaUri => Constants.VendorExtensionPath("AGI_stk_metadata", "node.AGI_stk_metadata.schema.json");
+
+        public override IEnumerable<(string, SchemaType.Context)> Process()
+        {
+            yield return ("ext.AgiRootStkMetadata.g", ProcessRoot());
+            yield return ("ext.AgiNodeStkMetadata.g", ProcessNode());
+        }        
+
+        private static SchemaType.Context ProcessRoot()
+        {
+            var ctx = SchemaProcessing.LoadSchemaContext(RootSchemaUri);
+            ctx.IgnoredByCodeEmitter("glTF Property");
+            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
+            return ctx;
+        }
+
+        private static SchemaType.Context ProcessNode()
+        {
+            var ctx = SchemaProcessing.LoadSchemaContext(NodeSchemaUri);
+            ctx.IgnoredByCodeEmitter("glTF Property");
+            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
+            return ctx;
+        }
+
+        public override void PrepareTypes(CodeGen.CSharpEmitter newEmitter, SchemaType.Context ctx)
+        {
+            newEmitter.SetRuntimeName("AGI_stk_metadata glTF extension", "AgiRootStkMetadata");
+            newEmitter.SetRuntimeName("AGI_stk_metadata glTF Node extension", "AgiNodeStkMetadata");
+            newEmitter.SetRuntimeName("Solar Panel Group", "AgiStkSolarPanelGroup");
+        }        
+    }
+}

+ 26 - 0
build/SharpGLTF.CodeGen/Ext.EXT_MeshGpuInstancing.cs

@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using SharpGLTF.SchemaReflection;
+
+namespace SharpGLTF
+{
+    class MeshGpuInstancingExtension : SchemaProcessor
+    {
+        private static string SchemaUri => Constants.VendorExtensionPath("EXT_mesh_gpu_instancing", "glTF.EXT_mesh_gpu_instancing.schema.json");
+        public override IEnumerable<(string, SchemaType.Context)> Process()
+        {
+            var ctx = SchemaProcessing.LoadSchemaContext(SchemaUri);
+            ctx.IgnoredByCodeEmitter("glTF Property");
+            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
+
+            yield return ("ext.MeshGpuInstancing.g", ctx);
+        }
+
+        public override void PrepareTypes(CodeGen.CSharpEmitter newEmitter, SchemaType.Context ctx)
+        {
+            newEmitter.SetRuntimeName("EXT_mesh_gpu_instancing glTF extension", "MeshGpuInstancing");
+        }
+    }
+}

+ 25 - 0
build/SharpGLTF.CodeGen/Ext.EXT_Webp.cs

@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using SharpGLTF.SchemaReflection;
+
+namespace SharpGLTF
+{
+    class TextureWebpExtension : SchemaProcessor
+    {
+        private static string SchemaUri => Constants.VendorExtensionPath("EXT_texture_webp", "glTF.EXT_texture_webp.schema.json");
+        public override IEnumerable<(string, SchemaType.Context)> Process()
+        {
+            var ctx = SchemaProcessing.LoadSchemaContext(SchemaUri);
+            ctx.IgnoredByCodeEmitter("glTF Property");
+
+            yield return ("ext.TextureWEBP.g", ctx);
+        }
+
+        public override void PrepareTypes(CodeGen.CSharpEmitter newEmitter, SchemaType.Context ctx)
+        {
+            newEmitter.SetRuntimeName("EXT_texture_webp glTF extension", "TextureWEBP");
+        }        
+    }
+}

+ 29 - 0
build/SharpGLTF.CodeGen/Ext.KHR_ClearCoat.cs

@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using SharpGLTF.SchemaReflection;
+
+namespace SharpGLTF
+{
+    class ClearCoatExtension : SchemaProcessor
+    {
+        private static string SchemaUri => Constants.KhronosExtensionPath("KHR_materials_clearcoat", "glTF.KHR_materials_clearcoat.schema.json");
+
+        public override IEnumerable<(string, SchemaType.Context)> Process()
+        {
+            var ctx = SchemaProcessing.LoadSchemaContext(SchemaUri);
+            ctx.IgnoredByCodeEmitter("glTF Property");
+            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
+            ctx.IgnoredByCodeEmitter("Texture Info");
+            ctx.IgnoredByCodeEmitter("Material Normal Texture Info");
+
+            yield return("ext.ClearCoat.g", ctx);
+        }
+
+        public override void PrepareTypes(CodeGen.CSharpEmitter newEmitter, SchemaType.Context ctx)
+        {
+            newEmitter.SetRuntimeName("KHR_materials_clearcoat glTF extension", "MaterialClearCoat");
+        }        
+    }
+}

+ 28 - 0
build/SharpGLTF.CodeGen/Ext.KHR_IOR.cs

@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using SharpGLTF.SchemaReflection;
+
+namespace SharpGLTF
+{
+    class IorExtension : SchemaProcessor
+    {
+        private static string SchemaUri => Constants.KhronosExtensionPath("KHR_materials_ior", "glTF.KHR_materials_ior.schema.json");
+        public override IEnumerable<(string, SchemaType.Context)> Process()
+        {
+            var ctx = SchemaProcessing.LoadSchemaContext(SchemaUri);
+            ctx.IgnoredByCodeEmitter("glTF Property");
+            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
+            // ctx.IgnoredByCodeEmitter("Texture Info");
+            // ctx.IgnoredByCodeEmitter("Material Normal Texture Info");
+
+            yield return ("ext.Ior.g", ctx);
+        }
+
+        public override void PrepareTypes(CodeGen.CSharpEmitter newEmitter, SchemaType.Context ctx)
+        {
+            newEmitter.SetRuntimeName("KHR_materials_ior glTF extension", "MaterialIOR");
+        }
+    }
+}

+ 49 - 0
build/SharpGLTF.CodeGen/Ext.KHR_LightsPunctual.cs

@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using SharpGLTF.SchemaReflection;
+
+namespace SharpGLTF
+{
+    class LightsPunctualExtension : SchemaProcessor
+    {
+        private static string RootSchemaUri => Constants.KhronosExtensionPath("KHR_lights_punctual", "glTF.KHR_lights_punctual.schema.json");
+        private static string NodeSchemaUri => Constants.KhronosExtensionPath("KHR_lights_punctual", "node.KHR_lights_punctual.schema.json");
+
+        public override IEnumerable<(string, SchemaType.Context)> Process()
+        {            
+            yield return ("ext.ModelLightsPunctual.g", ProcessModel());
+            yield return ("ext.NodeLightsPunctual.g", ProcessNode());
+        }
+        private static SchemaType.Context ProcessModel()
+        {
+            var ctx = SchemaProcessing.LoadSchemaContext(RootSchemaUri);
+            ctx.IgnoredByCodeEmitter("glTF Property");
+            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
+
+            ctx.FindClass("light")
+                .GetField("color")
+                .SetDataType(typeof(System.Numerics.Vector3), true)
+                .SetDefaultValue("Vector3.One")
+                .SetItemsRange(0);
+            return ctx;
+        }
+
+        private static SchemaType.Context ProcessNode()
+        {
+            var ctx = SchemaProcessing.LoadSchemaContext(NodeSchemaUri);
+            ctx.IgnoredByCodeEmitter("glTF Property");
+            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
+            return ctx;
+        }
+
+        public override void PrepareTypes(CodeGen.CSharpEmitter newEmitter, SchemaType.Context ctx)
+        {
+            newEmitter.SetRuntimeName("light", "PunctualLight");
+            newEmitter.SetRuntimeName("light/spot", "PunctualLightSpot");
+            newEmitter.SetRuntimeName("KHR_lights_punctual glTF extension", "_ModelPunctualLights");
+            newEmitter.SetRuntimeName("KHR_lights_punctual node extension", "_NodePunctualLight");
+        }
+    }
+}

+ 40 - 0
build/SharpGLTF.CodeGen/Ext.KHR_Sheen.cs

@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using SharpGLTF.SchemaReflection;
+
+namespace SharpGLTF
+{
+    class SheenExtension : SchemaProcessor
+    {
+        private static string SchemaUri => Constants.KhronosExtensionPath("KHR_materials_sheen", "glTF.KHR_materials_sheen.schema.json");
+        public override IEnumerable<(string, SchemaType.Context)> Process()
+        {
+            var ctx = SchemaProcessing.LoadSchemaContext(SchemaUri);
+            ctx.IgnoredByCodeEmitter("glTF Property");
+            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
+            ctx.IgnoredByCodeEmitter("Texture Info");
+            ctx.IgnoredByCodeEmitter("Material Normal Texture Info");
+
+
+            ctx.FindClass("KHR_materials_sheen glTF extension")
+                .GetField("sheenColorFactor")
+                .SetDataType(typeof(System.Numerics.Vector3), true)
+                .SetDefaultValue("Vector3.Zero")
+                .SetItemsRange(0);
+
+            ctx.FindClass("KHR_materials_sheen glTF extension")
+                .GetField("sheenRoughnessFactor")
+                .SetDataType(typeof(float), true)
+                .SetItemsRange(0);
+
+            yield return ("ext.Sheen.g", ctx);
+        }
+
+        public override void PrepareTypes(CodeGen.CSharpEmitter newEmitter, SchemaType.Context ctx)
+        {
+            newEmitter.SetRuntimeName("KHR_materials_sheen glTF extension", "MaterialSheen");
+        }
+    }
+}

+ 34 - 0
build/SharpGLTF.CodeGen/Ext.KHR_Specular.cs

@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using SharpGLTF.SchemaReflection;
+
+namespace SharpGLTF
+{
+    class SpecularExtension : SchemaProcessor
+    {
+        private static string SchemaUri => Constants.KhronosExtensionPath("KHR_materials_specular", "glTF.KHR_materials_specular.schema.json");
+        public override IEnumerable<(string, SchemaType.Context)> Process()
+        {
+            var ctx = SchemaProcessing.LoadSchemaContext(SchemaUri);
+            ctx.IgnoredByCodeEmitter("glTF Property");
+            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
+            ctx.IgnoredByCodeEmitter("Texture Info");
+            ctx.IgnoredByCodeEmitter("Material Normal Texture Info");
+
+            ctx.FindClass("KHR_materials_specular glTF extension")
+                .GetField("specularColorFactor")
+                .SetDataType(typeof(System.Numerics.Vector3), true)
+                .SetDefaultValue("Vector3.One")
+                .SetItemsRange(0);
+
+            yield return ("ext.pbrSpecular.g", ctx);
+        }
+
+        public override void PrepareTypes(CodeGen.CSharpEmitter newEmitter, SchemaType.Context ctx)
+        {
+            newEmitter.SetRuntimeName("KHR_materials_specular glTF extension", "MaterialSpecular");
+        }
+    }
+}

+ 39 - 0
build/SharpGLTF.CodeGen/Ext.KHR_SpecularGlossiness.cs

@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using SharpGLTF.SchemaReflection;
+
+namespace SharpGLTF
+{
+    class SpecularGlossinessExtension : SchemaProcessor
+    {
+        private static string SchemaUri => Constants.KhronosExtensionPath("KHR_materials_pbrSpecularGlossiness", "glTF.KHR_materials_pbrSpecularGlossiness.schema.json");
+        public override IEnumerable<(string, SchemaType.Context)> Process()
+        {
+            var ctx = SchemaProcessing.LoadSchemaContext(SchemaUri);
+            ctx.IgnoredByCodeEmitter("glTF Property");
+            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
+            ctx.IgnoredByCodeEmitter("Texture Info");
+
+            ctx.FindClass("KHR_materials_pbrSpecularGlossiness glTF extension")
+                .GetField("diffuseFactor")
+                .SetDataType(typeof(System.Numerics.Vector4), true)
+                .SetDefaultValue("Vector4.One")
+                .SetItemsRange(0);
+
+            ctx.FindClass("KHR_materials_pbrSpecularGlossiness glTF extension")
+                .GetField("specularFactor")
+                .SetDataType(typeof(System.Numerics.Vector3), true)
+                .SetDefaultValue("Vector3.One")
+                .SetItemsRange(0);
+
+            yield return ("ext.pbrSpecularGlossiness.g", ctx);
+        }
+
+        public override void PrepareTypes(CodeGen.CSharpEmitter newEmitter, SchemaType.Context ctx)
+        {
+            newEmitter.SetRuntimeName("KHR_materials_pbrSpecularGlossiness glTF extension", "MaterialPBRSpecularGlossiness");
+        }
+    }
+}

+ 26 - 0
build/SharpGLTF.CodeGen/Ext.KHR_TextureBasisU.cs

@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using SharpGLTF.SchemaReflection;
+
+namespace SharpGLTF
+{
+    class TextureKtx2Extension : SchemaProcessor
+    {
+        private static string SchemaUri => Constants.KhronosExtensionPath("KHR_texture_basisu", "texture.KHR_texture_basisu.schema.json");
+
+        public override IEnumerable<(string, SchemaType.Context)> Process()
+        {
+            var ctx = SchemaProcessing.LoadSchemaContext(SchemaUri);
+            ctx.IgnoredByCodeEmitter("glTF Property");
+
+            yield return ("ext.TextureKTX2.g", ctx);
+        }
+
+        public override void PrepareTypes(CodeGen.CSharpEmitter newEmitter, SchemaType.Context ctx)
+        {
+            newEmitter.SetRuntimeName("KHR_texture_basisu glTF extension", "TextureKTX2");
+        }
+    }
+}

+ 39 - 0
build/SharpGLTF.CodeGen/Ext.KHR_TextureTransform.cs

@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using SharpGLTF.SchemaReflection;
+
+namespace SharpGLTF
+{
+    class TextureTransformExtension : SchemaProcessor
+    {
+        private static string SchemaUri => Constants.KhronosExtensionPath("KHR_texture_transform", "KHR_texture_transform.textureInfo.schema.json");
+
+        public override IEnumerable<(string, SchemaType.Context)> Process()
+        {
+            var ctx = SchemaProcessing.LoadSchemaContext(SchemaUri);
+            ctx.IgnoredByCodeEmitter("glTF Property");
+            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
+
+            var tex = ctx.FindClass("KHR_texture_transform textureInfo extension");
+
+            tex.GetField("offset")
+                .SetDataType(typeof(System.Numerics.Vector2), true)
+                .SetDefaultValue("Vector2.Zero")
+                .SetItemsRange(0);
+
+            tex.GetField("scale")
+                .SetDataType(typeof(System.Numerics.Vector2), true)
+                .SetDefaultValue("Vector2.One")
+                .SetItemsRange(0);
+
+            yield return ("ext.TextureTransform.g", ctx);
+        }
+
+        public override void PrepareTypes(CodeGen.CSharpEmitter newEmitter, SchemaType.Context ctx)
+        {
+            newEmitter.SetRuntimeName("KHR_texture_transform textureInfo extension", "TextureTransform");
+        }
+    }
+}

+ 28 - 0
build/SharpGLTF.CodeGen/Ext.KHR_Transmission.cs

@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using SharpGLTF.SchemaReflection;
+
+namespace SharpGLTF
+{
+    class TransmissionExtension : SchemaProcessor
+    {
+        private static string SchemaUri => Constants.KhronosExtensionPath("KHR_materials_transmission", "glTF.KHR_materials_transmission.schema.json");
+        public override IEnumerable<(string, SchemaType.Context)> Process()
+        {
+            var ctx = SchemaProcessing.LoadSchemaContext(SchemaUri);
+            ctx.IgnoredByCodeEmitter("glTF Property");
+            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
+            ctx.IgnoredByCodeEmitter("Texture Info");
+            ctx.IgnoredByCodeEmitter("Material Normal Texture Info");
+
+            yield return("ext.Transmission.g", ctx);
+        }
+
+        public override void PrepareTypes(CodeGen.CSharpEmitter newEmitter, SchemaType.Context ctx)
+        {
+            newEmitter.SetRuntimeName("KHR_materials_transmission glTF extension", "MaterialTransmission");
+        }
+    }
+}

+ 27 - 0
build/SharpGLTF.CodeGen/Ext.KHR_Unlit.cs

@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using SharpGLTF.SchemaReflection;
+
+namespace SharpGLTF
+{
+    class UnlitExtension : SchemaProcessor
+    {
+        private static string SchemaUri => Constants.KhronosExtensionPath("KHR_materials_unlit", "glTF.KHR_materials_unlit.schema.json");
+
+        public override IEnumerable<(string, SchemaType.Context)> Process()
+        {
+            var ctx = SchemaProcessing.LoadSchemaContext(SchemaUri);
+            ctx.IgnoredByCodeEmitter("glTF Property");
+            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
+
+            yield return("ext.Unlit.g", ctx);
+        }
+
+        public override void PrepareTypes(CodeGen.CSharpEmitter newEmitter, SchemaType.Context ctx)
+        {
+            newEmitter.SetRuntimeName("KHR_materials_unlit glTF extension", "MaterialUnlit");
+        }
+    }
+}

+ 57 - 0
build/SharpGLTF.CodeGen/Ext.KHR_Xmp.cs

@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using SharpGLTF.SchemaReflection;
+
+namespace SharpGLTF
+{
+    class XMPExtension : SchemaProcessor
+    {
+        private static string RootSchemaUri => Constants.KhronosExtensionPath("KHR_xmp", "glTF.KHR_xmp.schema.json");
+        private static string NodeSchemaUri => Constants.KhronosExtensionPath("KHR_xmp", "node.KHR_xmp.schema.json");
+
+        public override IEnumerable<(string, SchemaType.Context)> Process()
+        {
+            // Model extension
+
+            var ctx = SchemaProcessing.LoadSchemaContext(RootSchemaUri);
+            ctx.IgnoredByCodeEmitter("glTF Property");
+            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
+
+            /*
+            var jdict = ctx.UseClass("JsonDictionary");
+            var jlist = ctx.UseClass("JsonList");
+
+            ctx.FindClass("KHR_xmp glTF extension")
+                .GetField("@context")
+                .SetDataType(jdict);
+
+            ctx.FindClass("KHR_xmp glTF extension")
+                .GetField("packets")
+                .SetDataType(jlist);*/
+
+            /*
+            ctx.FindClass("KHR_xmp glTF extension")
+                .GetField("@context")
+                .SetDataType(typeof(Dictionary<string,Object>), true);
+            */
+
+            yield return ("ext.XMP.Model.g", ctx);
+
+            // Node extension
+
+            ctx = SchemaProcessing.LoadSchemaContext(NodeSchemaUri);
+            ctx.IgnoredByCodeEmitter("glTF Property");
+            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
+
+            yield return ("ext.XMP.Node.g", ctx);
+        }
+
+        public override void PrepareTypes(CodeGen.CSharpEmitter newEmitter, SchemaType.Context ctx)
+        {
+            newEmitter.SetRuntimeName("KHR_xmp glTF extension", "XMPPacketsCollection");
+            newEmitter.SetRuntimeName("KHR_xmp node extension", "XMPPacketReference");
+        }
+    }
+}

+ 25 - 0
build/SharpGLTF.CodeGen/Ext.MSFT_TextureDDS.cs

@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using SharpGLTF.SchemaReflection;
+
+namespace SharpGLTF
+{
+    class TextureDDSExtension : SchemaProcessor
+    {
+        private static string SchemaUri => Constants.VendorExtensionPath("MSFT_texture_dds", "glTF.MSFT_texture_dds.schema.json");
+        public override IEnumerable<(string, SchemaType.Context)> Process()
+        {
+            var ctx = SchemaProcessing.LoadSchemaContext(SchemaUri);
+            ctx.IgnoredByCodeEmitter("glTF Property");
+
+            yield return ("ext.MSFT.TextureDDS.g", ctx);
+        }
+
+        public override void PrepareTypes(CodeGen.CSharpEmitter newEmitter, SchemaType.Context ctx)
+        {
+            newEmitter.SetRuntimeName("MSFT_texture_dds extension", "TextureDDS");
+        }
+    }
+}

+ 127 - 0
build/SharpGLTF.CodeGen/MainSchemaProcessor.cs

@@ -0,0 +1,127 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using SharpGLTF.CodeGen;
+using SharpGLTF.SchemaReflection;
+
+namespace SharpGLTF
+{
+    class MainSchemaProcessor : SchemaProcessor
+    {
+        public override IEnumerable<(string TargetFileName, SchemaType.Context Schema)> Process()
+        {
+            // 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");
+            node.GetField("matrix").SetDataType(typeof(System.Numerics.Matrix4x4), true).RemoveDefaultValue().SetItemsRange(0);
+            node.GetField("rotation").SetDataType(typeof(System.Numerics.Quaternion), true).RemoveDefaultValue().SetItemsRange(0);
+            node.GetField("scale").SetDataType(typeof(System.Numerics.Vector3), true).RemoveDefaultValue().SetItemsRange(0);
+            node.GetField("translation").SetDataType(typeof(System.Numerics.Vector3), true).RemoveDefaultValue().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");                        
+
+            var meshClass = ctx.FindClass("Mesh");
+            if (meshClass != null)
+            {
+                newEmitter.SetCollectionContainer(meshClass.UseField("primitives"), "ChildrenCollection<TItem,Mesh>");
+            }
+
+            var animationClass = ctx.FindClass("Animation");
+            if (animationClass != null)
+            {
+                newEmitter.SetCollectionContainer(animationClass.UseField("channels"), "ChildrenCollection<TItem,Animation>");
+                newEmitter.SetCollectionContainer(animationClass.UseField("samplers"), "ChildrenCollection<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, $"ChildrenCollection<TItem,{rootName}>");
+                        }
+                    }
+                }
+            }
+        }        
+    }
+}

+ 33 - 339
build/SharpGLTF.CodeGen/Program.cs

@@ -14,7 +14,7 @@ namespace SharpGLTF
     using CodeGen;
     using SchemaReflection;    
 
-    class Program
+    partial class Program
     {
         #region MAIN
 
@@ -22,359 +22,53 @@ namespace SharpGLTF
         {
             SchemaDownload.Syncronize(Constants.RemoteSchemaRepo, Constants.LocalRepoDirectory);
 
-            _ProcessMainSchema();
+            var processors = new List<SchemaProcessor>();
+
+            // ---------------------------------------------- Add Main Schema
+
+            processors.Add(new MainSchemaProcessor());
+
+            // ---------------------------------------------- Add extensions
 
             // XMP
-            _ProcessKhronosXMPExtension();
+            processors.Add(new XMPExtension());
 
-            // material extensions            
-            _ProcessKhronosUnlitExtension();
-            _ProcessKhronosIorExtension();
-            _ProcessKhronosSheenExtension();
-            _ProcessKhronosSpecularExtension();
-            _ProcessKhronosClearCoatExtension();            
-            _ProcessKhronosTransmissionExtension();
-            _ProcessKhronosSpecularGlossinessExtension();
+            // material extensions       
+            processors.Add(new UnlitExtension());
+            processors.Add(new IorExtension());
+            processors.Add(new SheenExtension());
+            processors.Add(new SpecularExtension());
+            processors.Add(new ClearCoatExtension());
+            processors.Add(new TransmissionExtension());
+            processors.Add(new SpecularGlossinessExtension());
 
             // lights
-            _ProcessKhronosLightsPunctualExtension();
+            processors.Add(new LightsPunctualExtension());
 
             // gpu mesh instancing
-            _ProcessMeshGpuInstancingExtension();
+            processors.Add(new MeshGpuInstancingExtension());
 
             // textures
-            _ProcessKhronosTextureTransformExtension();
-            _ProcessMicrosoftTextureDDSExtension();
-            _ProcessTextureWebpExtension();
-            _ProcessTextureKtx2Extension();
-
-            // these extansions are not fully supported and temporarily removed:
-            // _ProcessDracoExtension();
-            // _ProcessMicrosoftLODExtension();
-
-            _ProcessAgiArticulationsExtension();
-            _ProcessAgiStkMetadataExtension();
-        }
-
-        #endregion
-
-        #region Main Schema code generation        
-
-        private static void _ProcessMainSchema()
-        {
-            // load and process schema
-            var ctx1 = SchemaProcessing.LoadSchemaContext(Constants.MainSchemaFile);
-
-            // Ignore "glTF Property" because it is completely hand coded.
-            ctx1.IgnoredByCodeEmitter("glTF Property");
-
-            // We will mimeType "anyof" as a plain string.
-            ctx1.Remove("image/jpeg-image/png");            
-
-            // replace Image.mimeType type from an Enum to String, so we can serialize it with more formats if required
-            ctx1.FindClass("Image")
-                .GetField("mimeType")
-                .FieldType = ctx1.UseString();
-
-            // replace Node.Matrix, Node.Rotation, Node.Scale and Node.Translation with System.Numerics.Vectors types
-            var node = ctx1.FindClass("Node");
-            node.GetField("matrix").SetDataType(typeof(System.Numerics.Matrix4x4), true).RemoveDefaultValue().SetItemsRange(0);
-            node.GetField("rotation").SetDataType(typeof(System.Numerics.Quaternion), true).RemoveDefaultValue().SetItemsRange(0);
-            node.GetField("scale").SetDataType(typeof(System.Numerics.Vector3), true).RemoveDefaultValue().SetItemsRange(0);
-            node.GetField("translation").SetDataType(typeof(System.Numerics.Vector3), true).RemoveDefaultValue().SetItemsRange(0);
-
-            // replace Material.emissiveFactor with System.Numerics.Vectors types
-            ctx1.FindClass("Material")
-                .GetField("emissiveFactor")
-                .SetDataType(typeof(System.Numerics.Vector3), true)
-                .SetDefaultValue("Vector3.Zero")
-                .SetItemsRange(0);
-
-            // replace Material.baseColorFactor with System.Numerics.Vectors types
-            ctx1.FindClass("Material PBR Metallic Roughness")
-                .GetField("baseColorFactor")
-                .SetDataType(typeof(System.Numerics.Vector4), true)
-                .SetDefaultValue("Vector4.One")
-                .SetItemsRange(0);
-
-            ctx1.FindEnum("LINEAR-NEAREST")
-                .SetValue("DEFAULT",0);
-
-            ctx1.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
-            ctx1.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
-            ctx1.FindEnum("MAT2-MAT3-MAT4-SCALAR-VEC2-VEC3-VEC4")
-                .SetValue("CUSTOM", 0);
-
-            SchemaProcessing.EmitCodeFromSchema("gltf.g", ctx1);
-        }
-
-        #endregion
-
-        #region Extensions code generation
-
-        private static void _ProcessKhronosXMPExtension()
-        {
-            // Model extension
-
-            var ctx = SchemaProcessing.LoadSchemaContext(Constants.KhronosExtensions.XMP_Model);
-            ctx.IgnoredByCodeEmitter("glTF Property");
-            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
+            processors.Add(new TextureTransformExtension());
+            processors.Add(new TextureDDSExtension());
+            processors.Add(new TextureWebpExtension());
+            processors.Add(new TextureKtx2Extension());
 
-            /*
-            var jdict = ctx.UseClass("JsonDictionary");
-            var jlist = ctx.UseClass("JsonList");
+            processors.Add(new AgiArticulationsExtension());
+            processors.Add(new AgiStkMetadataExtension());
 
-            ctx.FindClass("KHR_xmp glTF extension")
-                .GetField("@context")
-                .SetDataType(jdict);
-
-            ctx.FindClass("KHR_xmp glTF extension")
-                .GetField("packets")
-                .SetDataType(jlist);*/
-
-            /*
-            ctx.FindClass("KHR_xmp glTF extension")
-                .GetField("@context")
-                .SetDataType(typeof(Dictionary<string,Object>), true);
-            */
-
-            SchemaProcessing.EmitCodeFromSchema("ext.XMP.Model.g", ctx);
-
-            // Node extension
-
-            ctx = SchemaProcessing.LoadSchemaContext(Constants.KhronosExtensions.XMP_Node);
-            ctx.IgnoredByCodeEmitter("glTF Property");
-            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
-
-            SchemaProcessing.EmitCodeFromSchema("ext.XMP.Node.g", ctx);
-        }        
-
-        private static void _ProcessKhronosSpecularGlossinessExtension()
-        {
-            var ctx = SchemaProcessing.LoadSchemaContext(Constants.KhronosExtensions.PbrSpecularGlossiness);
-            ctx.IgnoredByCodeEmitter("glTF Property");
-            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
-            ctx.IgnoredByCodeEmitter("Texture Info");
-
-            ctx.FindClass("KHR_materials_pbrSpecularGlossiness glTF extension")
-                .GetField("diffuseFactor")
-                .SetDataType(typeof(System.Numerics.Vector4), true)
-                .SetDefaultValue("Vector4.One")
-                .SetItemsRange(0);
-
-            ctx.FindClass("KHR_materials_pbrSpecularGlossiness glTF extension")
-                .GetField("specularFactor")
-                .SetDataType(typeof(System.Numerics.Vector3), true)
-                .SetDefaultValue("Vector3.One")
-                .SetItemsRange(0);
-
-            SchemaProcessing.EmitCodeFromSchema("ext.pbrSpecularGlossiness.g", ctx);
-        }
-
-        private static void _ProcessKhronosUnlitExtension()
-        {
-            var ctx = SchemaProcessing.LoadSchemaContext(Constants.KhronosExtensions.Unlit);
-            ctx.IgnoredByCodeEmitter("glTF Property");
-            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
-
-            SchemaProcessing.EmitCodeFromSchema("ext.Unlit.g", ctx);
-        }
-
-        private static void _ProcessKhronosClearCoatExtension()
-        {
-            var ctx = SchemaProcessing.LoadSchemaContext(Constants.KhronosExtensions.PbrClearCoat);
-            ctx.IgnoredByCodeEmitter("glTF Property");
-            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
-            ctx.IgnoredByCodeEmitter("Texture Info");
-            ctx.IgnoredByCodeEmitter("Material Normal Texture Info");
-
-            SchemaProcessing.EmitCodeFromSchema("ext.ClearCoat.g", ctx);
-        }
-
-        private static void _ProcessKhronosSpecularExtension()
-        {
-            var ctx = SchemaProcessing.LoadSchemaContext(Constants.KhronosExtensions.PbrSpecular);
-            ctx.IgnoredByCodeEmitter("glTF Property");
-            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
-            ctx.IgnoredByCodeEmitter("Texture Info");
-            ctx.IgnoredByCodeEmitter("Material Normal Texture Info");
-
-            ctx.FindClass("KHR_materials_specular glTF extension")
-                .GetField("specularColorFactor")
-                .SetDataType(typeof(System.Numerics.Vector3), true)
-                .SetDefaultValue("Vector3.One")
-                .SetItemsRange(0);
-
-            SchemaProcessing.EmitCodeFromSchema("ext.pbrSpecular.g", ctx);
-        }
-
-        private static void _ProcessKhronosTransmissionExtension()
-        {
-            var ctx = SchemaProcessing.LoadSchemaContext(Constants.KhronosExtensions.PbrTransmission);
-            ctx.IgnoredByCodeEmitter("glTF Property");
-            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
-            ctx.IgnoredByCodeEmitter("Texture Info");
-            ctx.IgnoredByCodeEmitter("Material Normal Texture Info");
-
-            SchemaProcessing.EmitCodeFromSchema("ext.Transmission.g", ctx);
-        }
-
-        private static void _ProcessKhronosSheenExtension()
-        {
-            var ctx = SchemaProcessing.LoadSchemaContext(Constants.KhronosExtensions.PbrSheen);
-            ctx.IgnoredByCodeEmitter("glTF Property");
-            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
-            ctx.IgnoredByCodeEmitter("Texture Info");
-            ctx.IgnoredByCodeEmitter("Material Normal Texture Info");
-
-            
-            ctx.FindClass("KHR_materials_sheen glTF extension")
-                .GetField("sheenColorFactor")
-                .SetDataType(typeof(System.Numerics.Vector3), true)
-                .SetDefaultValue("Vector3.Zero")
-                .SetItemsRange(0);
-
-            ctx.FindClass("KHR_materials_sheen glTF extension")
-                .GetField("sheenRoughnessFactor")
-                .SetDataType(typeof(float), true)                
-                .SetItemsRange(0);
-
-            SchemaProcessing.EmitCodeFromSchema("ext.Sheen.g", ctx);
-        }
-
-        private static void _ProcessKhronosIorExtension()
-        {
-            var ctx = SchemaProcessing.LoadSchemaContext(Constants.KhronosExtensions.MaterialIor);
-            ctx.IgnoredByCodeEmitter("glTF Property");
-            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
-            // ctx.IgnoredByCodeEmitter("Texture Info");
-            // ctx.IgnoredByCodeEmitter("Material Normal Texture Info");
-
-            SchemaProcessing.EmitCodeFromSchema("ext.Ior.g", ctx);
-        }
-
-        private static void _ProcessKhronosLightsPunctualExtension()
-        {
-            // Model
-
-            var ctx = SchemaProcessing.LoadSchemaContext(Constants.KhronosExtensions.LightsPunctual_Model);            
-            ctx.IgnoredByCodeEmitter("glTF Property");
-            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
-
-            ctx.FindClass("light")
-                .GetField("color")
-                .SetDataType(typeof(System.Numerics.Vector3), true)
-                .SetDefaultValue("Vector3.One")
-                .SetItemsRange(0);
-
-            SchemaProcessing.EmitCodeFromSchema("ext.ModelLightsPunctual.g", ctx);
-
-            // Node
-
-            ctx = SchemaProcessing.LoadSchemaContext(Constants.KhronosExtensions.LightsPunctual_Node);
-            ctx.IgnoredByCodeEmitter("glTF Property");
-            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
-
-            SchemaProcessing.EmitCodeFromSchema("ext.NodeLightsPunctual.g", ctx);
-        }
-
-        private static void _ProcessKhronosTextureTransformExtension()
-        {
-            var ctx = SchemaProcessing.LoadSchemaContext(Constants.KhronosExtensions.TextureTransform);
-            ctx.IgnoredByCodeEmitter("glTF Property");
-            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
-
-            var tex = ctx.FindClass("KHR_texture_transform textureInfo extension");
-
-            tex.GetField("offset")
-                .SetDataType(typeof(System.Numerics.Vector2), true)
-                .SetDefaultValue("Vector2.Zero")
-                .SetItemsRange(0);
-
-            tex.GetField("scale")
-                .SetDataType(typeof(System.Numerics.Vector2), true)
-                .SetDefaultValue("Vector2.One")
-                .SetItemsRange(0);
-
-            SchemaProcessing.EmitCodeFromSchema("ext.TextureTransform.g", ctx);
-        }
-
-        private static void _ProcessMicrosoftTextureDDSExtension()
-        {
-            var ctx = SchemaProcessing.LoadSchemaContext(Constants.VendorExtensions.TextureDDS);
-            ctx.IgnoredByCodeEmitter("glTF Property");
-
-            SchemaProcessing.EmitCodeFromSchema("ext.MSFT.TextureDDS.g", ctx);
-        }
-
-        private static void _ProcessTextureWebpExtension()
-        {
-            var ctx = SchemaProcessing.LoadSchemaContext(Constants.VendorExtensions.TextureWebp);
-            ctx.IgnoredByCodeEmitter("glTF Property");
-
-            SchemaProcessing.EmitCodeFromSchema("ext.TextureWEBP.g", ctx);
-        }
-
-        private static void _ProcessTextureKtx2Extension()
-        {
-            var ctx = SchemaProcessing.LoadSchemaContext(Constants.KhronosExtensions.Ktx2);
-            ctx.IgnoredByCodeEmitter("glTF Property");
-
-            SchemaProcessing.EmitCodeFromSchema("ext.TextureKTX2.g", ctx);
-        }
-
-        private static void _ProcessMeshGpuInstancingExtension()
-        {
-            var ctx = SchemaProcessing.LoadSchemaContext(Constants.VendorExtensions.MeshGpuInstancing);
-            ctx.IgnoredByCodeEmitter("glTF Property");
-            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
-
-            SchemaProcessing.EmitCodeFromSchema("ext.MeshGpuInstancing.g", ctx);
-        }
-
-        private static void _ProcessAgiArticulationsExtension()
-        {
-            var ctx1 = SchemaProcessing.LoadSchemaContext(Constants.VendorExtensions.AgiRootArticulations);
-            ctx1.IgnoredByCodeEmitter("glTF Property");
-            ctx1.IgnoredByCodeEmitter("glTF Child of Root Property");
-
-            ctx1.FindClass("Articulation")
-                .GetField("pointingVector")
-                .SetDataType(typeof(System.Numerics.Vector3), true)
-                .SetItemsRange(0);
-
-            SchemaProcessing.EmitCodeFromSchema("ext.AgiRootArticulations.g", ctx1);
-
-            var ctx2 = SchemaProcessing.LoadSchemaContext(Constants.VendorExtensions.AgiNodeArticulations);
-            ctx2.IgnoredByCodeEmitter("glTF Property");
-            ctx2.IgnoredByCodeEmitter("glTF Child of Root Property");
-
-            SchemaProcessing.EmitCodeFromSchema("ext.AgiNodeArticulations.g", ctx2);
-        }
-
-        private static void _ProcessAgiStkMetadataExtension()
-        {
-            var ctx1 = SchemaProcessing.LoadSchemaContext(Constants.VendorExtensions.AgiRootStkMetadata);
-            ctx1.IgnoredByCodeEmitter("glTF Property");
-            ctx1.IgnoredByCodeEmitter("glTF Child of Root Property");
+            // ----------------------------------------------  process all files
 
-            SchemaProcessing.EmitCodeFromSchema("ext.AgiRootStkMetadata.g", ctx1);
+            var processes = processors.SelectMany(item => item.Process());
 
-            var ctx2 = SchemaProcessing.LoadSchemaContext(Constants.VendorExtensions.AgiNodeStkMetadata);
-            ctx2.IgnoredByCodeEmitter("glTF Property");
-            ctx2.IgnoredByCodeEmitter("glTF Child of Root Property");
+            foreach (var (targetFileName, schema) in processes)
+            {
+                System.Console.WriteLine($"Emitting {targetFileName}...");
 
-            SchemaProcessing.EmitCodeFromSchema("ext.AgiNodeStkMetadata.g", ctx2);
+                SchemaProcessing.EmitCodeFromSchema(targetFileName, schema, processors);
+            }
         }
 
-        #endregion                
+        #endregion     
     }    
 }

+ 4 - 104
build/SharpGLTF.CodeGen/SchemaProcessing.cs

@@ -75,114 +75,14 @@ namespace SharpGLTF
 
         #endregion
 
-        public static void EmitCodeFromSchema(string dstFile, SchemaType.Context ctx)
+        public static void EmitCodeFromSchema(string dstFile, SchemaType.Context ctx, IReadOnlyList<SchemaProcessor> extensions)
         {
             var newEmitter = new CSharpEmitter();
-            newEmitter.DeclareContext(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");
-
-            newEmitter.SetRuntimeName("KHR_materials_pbrSpecularGlossiness glTF extension", "MaterialPBRSpecularGlossiness");
-            newEmitter.SetRuntimeName("KHR_materials_unlit glTF extension", "MaterialUnlit");
-            newEmitter.SetRuntimeName("KHR_materials_specular glTF extension", "MaterialSpecular");
-            newEmitter.SetRuntimeName("KHR_materials_clearcoat glTF extension", "MaterialClearCoat");
-            newEmitter.SetRuntimeName("KHR_materials_transmission glTF extension", "MaterialTransmission");
-            newEmitter.SetRuntimeName("KHR_materials_sheen glTF extension", "MaterialSheen");
-            newEmitter.SetRuntimeName("KHR_materials_ior glTF extension", "MaterialIOR");
-
-            newEmitter.SetRuntimeName("KHR_xmp glTF extension", "XMPPacketsCollection");
-            newEmitter.SetRuntimeName("KHR_xmp node extension", "XMPPacketReference");
-
-
-
-            newEmitter.SetRuntimeName("light", "PunctualLight");
-            newEmitter.SetRuntimeName("light/spot", "PunctualLightSpot");
-            newEmitter.SetRuntimeName("KHR_lights_punctual glTF extension", "_ModelPunctualLights");
-            newEmitter.SetRuntimeName("KHR_lights_punctual node extension", "_NodePunctualLight");
-
-            newEmitter.SetRuntimeName("KHR_texture_transform textureInfo extension", "TextureTransform");
-
-            newEmitter.SetRuntimeName("MSFT_texture_dds extension", "TextureDDS");
-            newEmitter.SetRuntimeName("EXT_texture_webp glTF extension", "TextureWEBP");
-            newEmitter.SetRuntimeName("KHR_texture_basisu glTF extension", "TextureKTX2");
-
-            newEmitter.SetRuntimeName("EXT_mesh_gpu_instancing glTF extension", "MeshGpuInstancing");
-
-            newEmitter.SetRuntimeName("AGI_articulations glTF extension", "AgiRootArticulations");
-            newEmitter.SetRuntimeName("AGI_articulations glTF Node extension", "AgiNodeArticulations");
-            newEmitter.SetRuntimeName("Articulation", "AgiArticulation");
-            newEmitter.SetRuntimeName("Articulation Stage", "AgiArticulationStage");
-            newEmitter.SetRuntimeName("uniformScale-xRotate-xScale-xTranslate-yRotate-yScale-yTranslate-zRotate-zScale-zTranslate", "AgiArticulationTransformType");
-            newEmitter.SetRuntimeName("AGI_stk_metadata glTF extension", "AgiRootStkMetadata");
-            newEmitter.SetRuntimeName("AGI_stk_metadata glTF Node extension", "AgiNodeStkMetadata");
-            newEmitter.SetRuntimeName("Solar Panel Group", "AgiStkSolarPanelGroup");
-
-            var classes = ctx.Classes.ToArray();
-            var fields = classes.SelectMany(item => item.Fields).ToArray();
-
-            var meshClass = ctx.FindClass("Mesh");
-            if (meshClass != null)
-            {
-                newEmitter.SetCollectionContainer(meshClass.UseField("primitives"), "ChildrenCollection<TItem,Mesh>");
-            }
-
-            var animationClass = ctx.FindClass("Animation");
-            if (animationClass != null)
-            {
-                newEmitter.SetCollectionContainer(animationClass.UseField("channels"), "ChildrenCollection<TItem,Animation>");
-                newEmitter.SetCollectionContainer(animationClass.UseField("samplers"), "ChildrenCollection<TItem,Animation>");
-            }
-
-            var agiArticulationRootClass = ctx.FindClass("AGI_articulations glTF extension");
-            if (agiArticulationRootClass != null)
-            {
-                newEmitter.SetCollectionContainer(agiArticulationRootClass.UseField("articulations"), "ChildrenCollection<TItem,AgiRootArticulations>");
-            }
-
-            var agiArticulationClass = ctx.FindClass("Articulation");
-            if (agiArticulationClass != null)
-            {
-                newEmitter.SetCollectionContainer(agiArticulationClass.UseField("stages"), "ChildrenCollection<TItem,AgiArticulation>");
-            }
-
-            var agiStkMetadataRootClass = ctx.FindClass("AGI_stk_metadata glTF extension");
-            if (agiStkMetadataRootClass != null)
-            {
-                newEmitter.SetCollectionContainer(agiStkMetadataRootClass.UseField("solarPanelGroups"), "ChildrenCollection<TItem,AgiRootStkMetadata>");
-            }
+            newEmitter.DeclareContext(ctx);           
 
-            foreach (var f in fields)
+            foreach(var ext in extensions)
             {
-                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, $"ChildrenCollection<TItem,{rootName}>");
-                        }
-                    }
-                }
+                ext.PrepareTypes(newEmitter, ctx);
             }
 
             var textOut = newEmitter.EmitContext(ctx);

+ 13 - 0
build/SharpGLTF.CodeGen/SchemaProcessor.cs

@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace SharpGLTF
+{
+    abstract class SchemaProcessor
+    {
+        public abstract IEnumerable<(string TargetFileName, SchemaReflection.SchemaType.Context Schema)> Process();
+
+        public abstract void PrepareTypes(CodeGen.CSharpEmitter newEmitter, SchemaReflection.SchemaType.Context ctx);
+    }
+}

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

@@ -69,7 +69,7 @@ namespace SharpGLTF.Schema2
 
 
 	/// <summary>
-	/// The name of the node's TRS property to modify, or the <see cref="weights"/> of the Morph Targets it instantiates. For the <see cref="translation"/> property, the values that are provided by the sampler are the translation along the X, Y, and Z axes. For the <see cref="rotation"/> property, the values are a quaternion in the order (x, y, z, w), where w is the scalar. For the <see cref="scale"/> property, the values are the scaling factors along the X, Y, and Z axes.
+	/// The name of the node's TRS property to animate, or the <see cref="weights"/> of the Morph Targets it instantiates. For the <see cref="translation"/> property, the values that are provided by the sampler are the translation along the X, Y, and Z axes. For the <see cref="rotation"/> property, the values are a quaternion in the order (x, y, z, w), where w is the scalar. For the <see cref="scale"/> property, the values are the scaling factors along the X, Y, and Z axes.
 	/// </summary>
 	public enum PropertyPath
 	{
@@ -367,7 +367,7 @@ namespace SharpGLTF.Schema2
 	}
 
 	/// <summary>
-	/// The index of the node and TRS property that an animation channel targets.
+	/// The descriptor of the animated property.
 	/// </summary>
 	partial class AnimationChannelTarget : ExtraProperties
 	{
@@ -397,7 +397,7 @@ namespace SharpGLTF.Schema2
 	}
 
 	/// <summary>
-	/// Targets an animation's sampler at a node's property.
+	/// An animation channel combines an animation sampler with a target property being animated.
 	/// </summary>
 	partial class AnimationChannel : ExtraProperties
 	{
@@ -427,7 +427,7 @@ namespace SharpGLTF.Schema2
 	}
 
 	/// <summary>
-	/// Combines input and output accessors with an interpolation algorithm to define a keyframe graph (but not its target).
+	/// An animation sampler combines timestamps with a sequence of output values and defines an interpolation algorithm.
 	/// </summary>
 	partial class AnimationSampler : ExtraProperties
 	{