Browse Source

Flesh out the two AGI vendor extensions.

Ed Mackey 4 years ago
parent
commit
67e0da26be

+ 4 - 2
build/SharpGLTF.CodeGen/Constants.cs

@@ -69,8 +69,10 @@ namespace SharpGLTF
             public static string TextureWebp => _Path("EXT_texture_webp", "glTF.EXT_texture_webp.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 MeshGpuInstancing => _Path("EXT_mesh_gpu_instancing", "glTF.EXT_mesh_gpu_instancing.schema.json");
 
 
-            public static string RootAgiArticulations => _Path("AGI_articulations", "glTF.AGI_articulations.schema.json");
-            public static string NodeAgiArticulations => _Path("AGI_articulations", "node.AGI_articulations.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");
         }
         }
 
 
         #endregion
         #endregion

+ 52 - 8
build/SharpGLTF.CodeGen/Program.cs

@@ -51,6 +51,7 @@ namespace SharpGLTF
             // _ProcessMicrosoftLODExtension();
             // _ProcessMicrosoftLODExtension();
 
 
             _ProcessAgiArticulationsExtension();
             _ProcessAgiArticulationsExtension();
+            _ProcessAgiStkMetadataExtension();
         }
         }
 
 
         #endregion
         #endregion
@@ -311,17 +312,37 @@ namespace SharpGLTF
 
 
         private static void _ProcessAgiArticulationsExtension()
         private static void _ProcessAgiArticulationsExtension()
         {
         {
-            var ctx1 = LoadSchemaContext(Constants.VendorExtensions.RootAgiArticulations);
+            var ctx1 = LoadSchemaContext(Constants.VendorExtensions.AgiRootArticulations);
             ctx1.IgnoredByCodeEmitter("glTF Property");
             ctx1.IgnoredByCodeEmitter("glTF Property");
             ctx1.IgnoredByCodeEmitter("glTF Child of Root Property");
             ctx1.IgnoredByCodeEmitter("glTF Child of Root Property");
 
 
-            ProcessSchema("ext.RootAgiArticulations.g", ctx1);
+            ctx1.FindClass("Articulation")
+                .GetField("pointingVector")
+                .SetDataType(typeof(System.Numerics.Vector3), true)
+                .SetItemsRange(0);
+
+            ProcessSchema("ext.AgiRootArticulations.g", ctx1);
+
+            var ctx2 = LoadSchemaContext(Constants.VendorExtensions.AgiNodeArticulations);
+            ctx2.IgnoredByCodeEmitter("glTF Property");
+            ctx2.IgnoredByCodeEmitter("glTF Child of Root Property");
+
+            ProcessSchema("ext.AgiNodeArticulations.g", ctx2);
+        }
+
+        private static void _ProcessAgiStkMetadataExtension()
+        {
+            var ctx1 = LoadSchemaContext(Constants.VendorExtensions.AgiRootStkMetadata);
+            ctx1.IgnoredByCodeEmitter("glTF Property");
+            ctx1.IgnoredByCodeEmitter("glTF Child of Root Property");
 
 
-            var ctx2 = LoadSchemaContext(Constants.VendorExtensions.NodeAgiArticulations);
+            ProcessSchema("ext.AgiRootStkMetadata.g", ctx1);
+
+            var ctx2 = LoadSchemaContext(Constants.VendorExtensions.AgiNodeStkMetadata);
             ctx2.IgnoredByCodeEmitter("glTF Property");
             ctx2.IgnoredByCodeEmitter("glTF Property");
             ctx2.IgnoredByCodeEmitter("glTF Child of Root Property");
             ctx2.IgnoredByCodeEmitter("glTF Child of Root Property");
 
 
-            ProcessSchema("ext.NodeAgiArticulations.g", ctx2);
+            ProcessSchema("ext.AgiNodeStkMetadata.g", ctx2);
         }
         }
 
 
         #endregion
         #endregion
@@ -394,9 +415,14 @@ namespace SharpGLTF
 
 
             newEmitter.SetRuntimeName("EXT_mesh_gpu_instancing glTF extension", "MeshGpuInstancing");
             newEmitter.SetRuntimeName("EXT_mesh_gpu_instancing glTF extension", "MeshGpuInstancing");
 
 
-            newEmitter.SetRuntimeName("AGI_articulations glTF extension", "RootAgiArticulations");
-            newEmitter.SetRuntimeName("AGI_articulations glTF Node extension", "NodeAgiArticulations");
-            newEmitter.SetRuntimeName("uniformScale-xRotate-xScale-xTranslate-yRotate-yScale-yTranslate-zRotate-zScale-zTranslate", "ArticulationTransformType");
+            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 classes = ctx.Classes.ToArray();
             var fields = classes.SelectMany(item => item.Fields).ToArray();
             var fields = classes.SelectMany(item => item.Fields).ToArray();
@@ -413,7 +439,25 @@ namespace SharpGLTF
                 newEmitter.SetCollectionContainer(animationClass.UseField("channels"), "ChildrenCollection<TItem,Animation>");
                 newEmitter.SetCollectionContainer(animationClass.UseField("channels"), "ChildrenCollection<TItem,Animation>");
                 newEmitter.SetCollectionContainer(animationClass.UseField("samplers"), "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>");
+            }
+
             foreach (var f in fields)
             foreach (var f in fields)
             {
             {
                 if (f.FieldType is ArrayType atype)
                 if (f.FieldType is ArrayType atype)

+ 1 - 1
src/SharpGLTF.Core/Schema2/Generated/ext.NodeAgiArticulations.g.cs → src/SharpGLTF.Core/Schema2/Generated/ext.AgiNodeArticulations.g.cs

@@ -30,7 +30,7 @@ namespace SharpGLTF.Schema2
 	/// <summary>
 	/// <summary>
 	/// glTF Extension for an individual node in a glTF model, to associate it with the model's root AGI_articulations object.
 	/// glTF Extension for an individual node in a glTF model, to associate it with the model's root AGI_articulations object.
 	/// </summary>
 	/// </summary>
-	partial class NodeAgiArticulations : ExtraProperties
+	partial class AgiNodeArticulations : ExtraProperties
 	{
 	{
 	
 	
 		private String _articulationName;
 		private String _articulationName;

+ 60 - 0
src/SharpGLTF.Core/Schema2/Generated/ext.AgiNodeStkMetadata.g.cs

@@ -0,0 +1,60 @@
+// <auto-generated/>
+
+//------------------------------------------------------------------------------------------------
+//      This file has been programatically generated; DON´T EDIT!
+//------------------------------------------------------------------------------------------------
+
+#pragma warning disable SA1001
+#pragma warning disable SA1027
+#pragma warning disable SA1028
+#pragma warning disable SA1121
+#pragma warning disable SA1205
+#pragma warning disable SA1309
+#pragma warning disable SA1402
+#pragma warning disable SA1505
+#pragma warning disable SA1507
+#pragma warning disable SA1508
+#pragma warning disable SA1652
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Numerics;
+using System.Text.Json;
+
+namespace SharpGLTF.Schema2
+{
+	using Collections;
+
+	/// <summary>
+	/// glTF Extension for an individual node in a glTF model, to associate it with the model's root AGI_stk_metadata object.
+	/// </summary>
+	partial class AgiNodeStkMetadata : ExtraProperties
+	{
+	
+		private Boolean? _noObscuration;
+		
+		private String _solarPanelGroupName;
+		
+	
+		protected override void SerializeProperties(Utf8JsonWriter writer)
+		{
+			base.SerializeProperties(writer);
+			SerializeProperty(writer, "noObscuration", _noObscuration);
+			SerializeProperty(writer, "solarPanelGroupName", _solarPanelGroupName);
+		}
+	
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
+		{
+			switch (jsonPropertyName)
+			{
+				case "noObscuration": _noObscuration = DeserializePropertyValue<Boolean?>(ref reader); break;
+				case "solarPanelGroupName": _solarPanelGroupName = DeserializePropertyValue<String>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
+			}
+		}
+	
+	}
+
+}

+ 14 - 16
src/SharpGLTF.Core/Schema2/Generated/ext.RootAgiArticulations.g.cs → src/SharpGLTF.Core/Schema2/Generated/ext.AgiRootArticulations.g.cs

@@ -30,7 +30,7 @@ namespace SharpGLTF.Schema2
 	/// <summary>
 	/// <summary>
 	/// The type of motion applied by this articulation stage.
 	/// The type of motion applied by this articulation stage.
 	/// </summary>
 	/// </summary>
-	public enum ArticulationTransformType
+	public enum AgiArticulationTransformType
 	{
 	{
 		xTranslate,
 		xTranslate,
 		yTranslate,
 		yTranslate,
@@ -48,7 +48,7 @@ namespace SharpGLTF.Schema2
 	/// <summary>
 	/// <summary>
 	/// One stage of a model articulation definition.
 	/// One stage of a model articulation definition.
 	/// </summary>
 	/// </summary>
-	partial class ArticulationStage : ExtraProperties
+	partial class AgiArticulationStage : ExtraProperties
 	{
 	{
 	
 	
 		private Double _initialValue;
 		private Double _initialValue;
@@ -59,7 +59,7 @@ namespace SharpGLTF.Schema2
 		
 		
 		private String _name;
 		private String _name;
 		
 		
-		private ArticulationTransformType _type;
+		private AgiArticulationTransformType _type;
 		
 		
 	
 	
 		protected override void SerializeProperties(Utf8JsonWriter writer)
 		protected override void SerializeProperties(Utf8JsonWriter writer)
@@ -69,7 +69,7 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "maximumValue", _maximumValue);
 			SerializeProperty(writer, "maximumValue", _maximumValue);
 			SerializeProperty(writer, "minimumValue", _minimumValue);
 			SerializeProperty(writer, "minimumValue", _minimumValue);
 			SerializeProperty(writer, "name", _name);
 			SerializeProperty(writer, "name", _name);
-			SerializePropertyEnumSymbol<ArticulationTransformType>(writer, "type", _type);
+			SerializePropertyEnumSymbol<AgiArticulationTransformType>(writer, "type", _type);
 		}
 		}
 	
 	
 		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
@@ -80,7 +80,7 @@ namespace SharpGLTF.Schema2
 				case "maximumValue": _maximumValue = DeserializePropertyValue<Double>(ref reader); break;
 				case "maximumValue": _maximumValue = DeserializePropertyValue<Double>(ref reader); break;
 				case "minimumValue": _minimumValue = DeserializePropertyValue<Double>(ref reader); break;
 				case "minimumValue": _minimumValue = DeserializePropertyValue<Double>(ref reader); break;
 				case "name": _name = DeserializePropertyValue<String>(ref reader); break;
 				case "name": _name = DeserializePropertyValue<String>(ref reader); break;
-				case "type": _type = DeserializePropertyValue<ArticulationTransformType>(ref reader); break;
+				case "type": _type = DeserializePropertyValue<AgiArticulationTransformType>(ref reader); break;
 				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 			}
 		}
 		}
@@ -90,24 +90,22 @@ namespace SharpGLTF.Schema2
 	/// <summary>
 	/// <summary>
 	/// A model articulation definition.
 	/// A model articulation definition.
 	/// </summary>
 	/// </summary>
-	partial class Articulation : ExtraProperties
+	partial class AgiArticulation : ExtraProperties
 	{
 	{
 	
 	
 		private String _name;
 		private String _name;
 		
 		
-		private const int _pointingVectorMinItems = 3;
-		private const int _pointingVectorMaxItems = 3;
-		private List<Double> _pointingVector;
+		private Vector3? _pointingVector;
 		
 		
 		private const int _stagesMinItems = 1;
 		private const int _stagesMinItems = 1;
-		private List<ArticulationStage> _stages;
+		private ChildrenCollection<AgiArticulationStage,AgiArticulation> _stages;
 		
 		
 	
 	
 		protected override void SerializeProperties(Utf8JsonWriter writer)
 		protected override void SerializeProperties(Utf8JsonWriter writer)
 		{
 		{
 			base.SerializeProperties(writer);
 			base.SerializeProperties(writer);
 			SerializeProperty(writer, "name", _name);
 			SerializeProperty(writer, "name", _name);
-			SerializeProperty(writer, "pointingVector", _pointingVector, _pointingVectorMinItems);
+			SerializeProperty(writer, "pointingVector", _pointingVector);
 			SerializeProperty(writer, "stages", _stages, _stagesMinItems);
 			SerializeProperty(writer, "stages", _stages, _stagesMinItems);
 		}
 		}
 	
 	
@@ -116,8 +114,8 @@ namespace SharpGLTF.Schema2
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
 			{
 			{
 				case "name": _name = DeserializePropertyValue<String>(ref reader); break;
 				case "name": _name = DeserializePropertyValue<String>(ref reader); break;
-				case "pointingVector": DeserializePropertyList<Double>(ref reader, _pointingVector); break;
-				case "stages": DeserializePropertyList<ArticulationStage>(ref reader, _stages); break;
+				case "pointingVector": _pointingVector = DeserializePropertyValue<Vector3?>(ref reader); break;
+				case "stages": DeserializePropertyList<AgiArticulationStage>(ref reader, _stages); break;
 				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 			}
 		}
 		}
@@ -127,11 +125,11 @@ namespace SharpGLTF.Schema2
 	/// <summary>
 	/// <summary>
 	/// glTF Extension that defines metadata for applying external analysis or effects to a model.
 	/// glTF Extension that defines metadata for applying external analysis or effects to a model.
 	/// </summary>
 	/// </summary>
-	partial class RootAgiArticulations : ExtraProperties
+	partial class AgiRootArticulations : ExtraProperties
 	{
 	{
 	
 	
 		private const int _articulationsMinItems = 1;
 		private const int _articulationsMinItems = 1;
-		private List<Articulation> _articulations;
+		private ChildrenCollection<AgiArticulation,AgiRootArticulations> _articulations;
 		
 		
 	
 	
 		protected override void SerializeProperties(Utf8JsonWriter writer)
 		protected override void SerializeProperties(Utf8JsonWriter writer)
@@ -144,7 +142,7 @@ namespace SharpGLTF.Schema2
 		{
 		{
 			switch (jsonPropertyName)
 			switch (jsonPropertyName)
 			{
 			{
-				case "articulations": DeserializePropertyList<Articulation>(ref reader, _articulations); break;
+				case "articulations": DeserializePropertyList<AgiArticulation>(ref reader, _articulations); break;
 				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 			}
 		}
 		}

+ 89 - 0
src/SharpGLTF.Core/Schema2/Generated/ext.AgiRootStkMetadata.g.cs

@@ -0,0 +1,89 @@
+// <auto-generated/>
+
+//------------------------------------------------------------------------------------------------
+//      This file has been programatically generated; DON´T EDIT!
+//------------------------------------------------------------------------------------------------
+
+#pragma warning disable SA1001
+#pragma warning disable SA1027
+#pragma warning disable SA1028
+#pragma warning disable SA1121
+#pragma warning disable SA1205
+#pragma warning disable SA1309
+#pragma warning disable SA1402
+#pragma warning disable SA1505
+#pragma warning disable SA1507
+#pragma warning disable SA1508
+#pragma warning disable SA1652
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Numerics;
+using System.Text.Json;
+
+namespace SharpGLTF.Schema2
+{
+	using Collections;
+
+	/// <summary>
+	/// A solar panel group definition.
+	/// </summary>
+	partial class AgiStkSolarPanelGroup : ExtraProperties
+	{
+	
+		private const Double _efficiencyMinimum = 0;
+		private const Double _efficiencyMaximum = 100;
+		private Double _efficiency;
+		
+		private String _name;
+		
+	
+		protected override void SerializeProperties(Utf8JsonWriter writer)
+		{
+			base.SerializeProperties(writer);
+			SerializeProperty(writer, "efficiency", _efficiency);
+			SerializeProperty(writer, "name", _name);
+		}
+	
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
+		{
+			switch (jsonPropertyName)
+			{
+				case "efficiency": _efficiency = DeserializePropertyValue<Double>(ref reader); break;
+				case "name": _name = DeserializePropertyValue<String>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
+			}
+		}
+	
+	}
+
+	/// <summary>
+	/// glTF Extension that defines metadata for use with STK (Systems Tool Kit).
+	/// </summary>
+	partial class AgiRootStkMetadata : ExtraProperties
+	{
+	
+		private const int _solarPanelGroupsMinItems = 1;
+		private ChildrenCollection<AgiStkSolarPanelGroup,AgiRootStkMetadata> _solarPanelGroups;
+		
+	
+		protected override void SerializeProperties(Utf8JsonWriter writer)
+		{
+			base.SerializeProperties(writer);
+			SerializeProperty(writer, "solarPanelGroups", _solarPanelGroups, _solarPanelGroupsMinItems);
+		}
+	
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
+		{
+			switch (jsonPropertyName)
+			{
+				case "solarPanelGroups": DeserializePropertyList<AgiStkSolarPanelGroup>(ref reader, _solarPanelGroups); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
+			}
+		}
+	
+	}
+
+}

+ 115 - 10
src/SharpGLTF.Core/Schema2/agi.Articulations.cs

@@ -1,24 +1,39 @@
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
-using System.Text;
+using System.Numerics;
+using System.Linq;
+using SharpGLTF.Collections;
 
 
 namespace SharpGLTF.Schema2
 namespace SharpGLTF.Schema2
 {
 {
-    public sealed partial class ArticulationStage
+    public sealed partial class AgiRootArticulations
     {
     {
-    }
+        internal AgiRootArticulations(ModelRoot root)
+        {
+            _articulations = new ChildrenCollection<AgiArticulation, AgiRootArticulations>(this);
+        }
 
 
-    public sealed partial class Articulation
-    {
-    }
+        protected override IEnumerable<ExtraProperties> GetLogicalChildren()
+        {
+            return base.GetLogicalChildren().Concat(_articulations);
+        }
 
 
-    public sealed partial class RootAgiArticulations
-    {
+        public IReadOnlyList<AgiArticulation> Articulations => _articulations;
+
+        public AgiArticulation CreateArticulation(string name)
+        {
+            var articulation = new AgiArticulation();
+            articulation.Name = name;
+
+            _articulations.Add(articulation);
+
+            return articulation;
+        }
     }
     }
 
 
-    public sealed partial class NodeAgiArticulations
+    public sealed partial class AgiNodeArticulations
     {
     {
-        internal NodeAgiArticulations(Node node) { }
+        internal AgiNodeArticulations(Node node) { }
 
 
         public String ArticulationName
         public String ArticulationName
         {
         {
@@ -32,4 +47,94 @@ namespace SharpGLTF.Schema2
             set => _isAttachPoint = value;
             set => _isAttachPoint = value;
         }
         }
     }
     }
+
+    public sealed partial class AgiArticulation : IChildOf<AgiRootArticulations>
+    {
+        internal AgiArticulation()
+        {
+            _stages = new ChildrenCollection<AgiArticulationStage, AgiArticulation>(this);
+        }
+
+        protected override IEnumerable<ExtraProperties> GetLogicalChildren()
+        {
+            return base.GetLogicalChildren().Concat(_stages);
+        }
+
+        public IReadOnlyList<AgiArticulationStage> Stages => _stages;
+
+        public AgiArticulationStage CreateArticulationStage(string name)
+        {
+            var stage = new AgiArticulationStage();
+            stage.Name = name;
+
+            _stages.Add(stage);
+
+            return stage;
+        }
+
+        public String Name
+        {
+            get => _name;
+            set => _name = value;
+        }
+
+        public Vector3? PointingVector
+        {
+            get => _pointingVector;
+            set => _pointingVector = value;
+        }
+
+        public int LogicalIndex { get; private set; } = -1;
+
+        public AgiRootArticulations LogicalParent { get; private set; }
+
+        public void _SetLogicalParent(AgiRootArticulations parent, int index)
+        {
+            LogicalParent = parent;
+            LogicalIndex = index;
+        }
+    }
+
+    public sealed partial class AgiArticulationStage : IChildOf<AgiArticulation>
+    {
+        public int LogicalIndex { get; private set; } = -1;
+
+        public AgiArticulation LogicalParent { get; private set; }
+
+        public void _SetLogicalParent(AgiArticulation parent, int index)
+        {
+            LogicalParent = parent;
+            LogicalIndex = index;
+        }
+
+        public String Name
+        {
+            get => _name;
+            set => _name = value;
+        }
+
+        public AgiArticulationTransformType TransformType
+        {
+            get => _type;
+            set => _type = value;
+        }
+
+        public Double MinimumValue
+        {
+            get => _minimumValue;
+            set => _minimumValue = value;
+        }
+
+        public Double InitialValue
+        {
+            get => _initialValue;
+            set => _initialValue = value;
+        }
+
+        public Double MaximumValue
+        {
+            get => _maximumValue;
+            set => _maximumValue = value;
+        }
+    }
 }
 }

+ 74 - 0
src/SharpGLTF.Core/Schema2/agi.StkMetadata.cs

@@ -0,0 +1,74 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using SharpGLTF.Collections;
+
+namespace SharpGLTF.Schema2
+{
+    public sealed partial class AgiRootStkMetadata
+    {
+        internal AgiRootStkMetadata(ModelRoot root)
+        {
+            _solarPanelGroups = new ChildrenCollection<AgiStkSolarPanelGroup, AgiRootStkMetadata>(this);
+        }
+
+        protected override IEnumerable<ExtraProperties> GetLogicalChildren()
+        {
+            return base.GetLogicalChildren().Concat(_solarPanelGroups);
+        }
+
+        public IReadOnlyList<AgiStkSolarPanelGroup> SolarPanelGroups => _solarPanelGroups;
+
+        public AgiStkSolarPanelGroup CreateSolarPanelGroup(string name)
+        {
+            var group = new AgiStkSolarPanelGroup();
+            group.Name = name;
+
+            _solarPanelGroups.Add(group);
+
+            return group;
+        }
+    }
+
+    public sealed partial class AgiNodeStkMetadata
+    {
+        internal AgiNodeStkMetadata(Node node) { }
+
+        public String SolarPanelGroupName
+        {
+            get => _solarPanelGroupName;
+            set => _solarPanelGroupName = value;
+        }
+
+        public Boolean? NoObscuration
+        {
+            get => _noObscuration;
+            set => _noObscuration = value;
+        }
+    }
+
+    public sealed partial class AgiStkSolarPanelGroup : IChildOf<AgiRootStkMetadata>
+    {
+        public int LogicalIndex { get; private set; } = -1;
+
+        public AgiRootStkMetadata LogicalParent { get; private set; }
+
+        public void _SetLogicalParent(AgiRootStkMetadata parent, int index)
+        {
+            LogicalParent = parent;
+            LogicalIndex = index;
+        }
+
+        public String Name
+        {
+            get => _name;
+            set => _name = value;
+        }
+
+        public Double Efficiency
+        {
+            get => _efficiency;
+            set => _efficiency = value;
+        }
+    }
+}

+ 4 - 2
src/SharpGLTF.Core/Schema2/gltf.ExtensionsFactory.cs

@@ -39,8 +39,10 @@ namespace SharpGLTF.Schema2
             RegisterExtension<Texture, TextureWEBP>("EXT_texture_webp");
             RegisterExtension<Texture, TextureWEBP>("EXT_texture_webp");
             RegisterExtension<Texture, TextureKTX2>("KHR_texture_basisu");
             RegisterExtension<Texture, TextureKTX2>("KHR_texture_basisu");
 
 
-            RegisterExtension<ModelRoot, RootAgiArticulations>("AGI_articulations");
-            RegisterExtension<Node, NodeAgiArticulations>("AGI_articulations");
+            RegisterExtension<ModelRoot, AgiRootArticulations>("AGI_articulations");
+            RegisterExtension<ModelRoot, AgiRootStkMetadata>("AGI_stk_metadata");
+            RegisterExtension<Node, AgiNodeArticulations>("AGI_articulations");
+            RegisterExtension<Node, AgiNodeStkMetadata>("AGI_stk_metadata");
         }
         }
 
 
         #endregion
         #endregion