Browse Source

Switched code generation to 2020-12

Vicente Penades 4 years ago
parent
commit
326bdb54c4

+ 24 - 0
build/SharpGLTF.CodeGen/CodeGen/CodeEmitUtils.cs

@@ -55,6 +55,8 @@ namespace SharpGLTF.CodeGen
         {
             if (string.IsNullOrWhiteSpace(description)) yield break;
 
+            description = _ReplaceDescriptionKeywords(description);
+
             var lines = description
                 .Split("  ")
                 .Select(item => item.Trim())
@@ -64,5 +66,27 @@ namespace SharpGLTF.CodeGen
             foreach(var l in lines) yield return $"/// {l}";
             yield return "/// </summary>".Indent(indent);
         }
+
+        private static string _ReplaceDescriptionKeywords(string description)
+        {
+            while(true)
+            {
+                var indices = _FindDescriptionKeyword(description);
+                if (indices.start < 0) return description;
+
+                var block = description.Substring(indices.start , indices.len);
+                var name = block.Substring(2, block.Length - 4);
+
+                description = description.Replace(block, $"<see cref=\"{name}\"/>");
+            }
+        }
+
+        private static (int start,int len) _FindDescriptionKeyword(string description)
+        {
+            int start = description.IndexOf("`\"");
+            var end = description.IndexOf("\"`");
+            if (start < 0 || end < 0 || start >= end) return (-1, -1);
+            return (start, end - start + 2);
+        }
     }
 }

+ 18 - 4
build/SharpGLTF.CodeGen/CodeGen/EmitCSharp.cs

@@ -450,20 +450,34 @@ namespace SharpGLTF.CodeGen
                 yield return Invariant($"private {tconst} {defval} = {vconst};");
             }
 
-            if (f.MinimumValue != null)
+            if (f.ExclusiveMinimumValue != null)
             {
                 var tconst = _GetConstantRuntimeName(f.FieldType);
-                var vconst = _GetConstantRuntimeValue(f.FieldType, f.MinimumValue);
+                var vconst = _GetConstantRuntimeValue(f.FieldType, f.ExclusiveMinimumValue);
+                yield return Invariant($"private {tconst} {fname}ExclusiveMinimum = {vconst};");
+            }
+
+            if (f.InclusiveMinimumValue != null)
+            {
+                var tconst = _GetConstantRuntimeName(f.FieldType);
+                var vconst = _GetConstantRuntimeValue(f.FieldType, f.InclusiveMinimumValue);
                 yield return Invariant($"private {tconst} {fname}Minimum = {vconst};");
             }
 
-            if (f.MaximumValue != null)
+            if (f.InclusiveMaximumValue != null)
             {
                 var tconst = _GetConstantRuntimeName(f.FieldType);
-                var vconst = _GetConstantRuntimeValue(f.FieldType, f.MaximumValue);
+                var vconst = _GetConstantRuntimeValue(f.FieldType, f.InclusiveMaximumValue);
                 yield return Invariant($"private {tconst} {fname}Maximum = {vconst};");
             }
 
+            if (f.ExclusiveMaximumValue != null)
+            {
+                var tconst = _GetConstantRuntimeName(f.FieldType);
+                var vconst = _GetConstantRuntimeValue(f.FieldType, f.ExclusiveMaximumValue);
+                yield return Invariant($"private {tconst} {fname}ExclusiveMaximum = {vconst};");
+            }
+
             if (f.MinItems > 0)
             {                    
                 yield return $"private const int {fname}MinItems = {f.MinItems};";

+ 1 - 1
build/SharpGLTF.CodeGen/Constants.cs

@@ -22,7 +22,7 @@ namespace SharpGLTF
         /// <summary>
         /// Directory of the main schema within the download repo directory
         /// </summary>
-        public static string MainSchemaDir => System.IO.Path.Combine(LocalRepoDirectory, "specification", "2.0", "schema");
+        public static string MainSchemaDir => System.IO.Path.Combine(LocalRepoDirectory, "specification", "2.0", "schema", "2020-12");
 
         /// <summary>
         /// schema source code file path

+ 21 - 6
build/SharpGLTF.CodeGen/SchemaReflection/SchemaTypes.cs

@@ -40,6 +40,9 @@ namespace SharpGLTF.SchemaReflection
         #endregion
     }
 
+    /// <summary>
+    /// Represents a <see cref="String"/> type.
+    /// </summary>
     [System.Diagnostics.DebuggerDisplay("{PersistentName}")]
     public sealed class StringType : SchemaType
     {
@@ -72,6 +75,12 @@ namespace SharpGLTF.SchemaReflection
         #endregion
     }
 
+    /// <summary>
+    /// Represents a "by value" type <see cref="Boolean"/>, <see cref="Int32"/>, <see cref="Single"/>, etc
+    /// </summary>
+    /// <remarks>
+    /// This type can optionally be set as nullable.
+    /// </remarks>
     [System.Diagnostics.DebuggerDisplay("{PersistentName}")]
     public sealed class BlittableType : SchemaType
     {
@@ -229,9 +238,13 @@ namespace SharpGLTF.SchemaReflection
         private readonly String _PersistentName;
         private SchemaType _FieldType;
 
+        private Object _ExclusiveMinimumValue;
+        private Object _InclusiveMinimumValue;
+
         private Object _DefaultValue;
-        private Object _MinimumValue;
-        private Object _MaximumValue;
+
+        private Object _InclusiveMaximumValue;
+        private Object _ExclusiveMaximumValue;
 
         private int _MinItems;
         private int _MaxItems;
@@ -247,10 +260,12 @@ namespace SharpGLTF.SchemaReflection
         public String PersistentName => _PersistentName;
 
         public SchemaType FieldType { get => _FieldType; set => _FieldType = value; }
-
+        
+        public Object ExclusiveMinimumValue { get => _ExclusiveMinimumValue; set => _ExclusiveMinimumValue = value; }
+        public Object InclusiveMinimumValue { get => _InclusiveMinimumValue; set => _InclusiveMinimumValue = value; }
         public Object DefaultValue { get => _DefaultValue; set => _DefaultValue = value; }
-        public Object MinimumValue { get => _MinimumValue; set => _MinimumValue = value; }
-        public Object MaximumValue { get => _MaximumValue; set => _MaximumValue = value; }
+        public Object InclusiveMaximumValue { get => _InclusiveMaximumValue; set => _InclusiveMaximumValue = value; }
+        public Object ExclusiveMaximumValue { get => _ExclusiveMaximumValue; set => _ExclusiveMaximumValue = value; }
 
         public int MinItems { get => _MinItems; set => _MinItems = value; }
         public int MaxItems { get => _MaxItems; set => _MaxItems = value; }
@@ -273,7 +288,7 @@ namespace SharpGLTF.SchemaReflection
 
         public FieldInfo SetDefaultValue(string defval) { _DefaultValue = defval; return this; }
 
-        public FieldInfo SetLimits(Decimal? min, Decimal? max) { _MinimumValue = min; _MaximumValue = max; return this; }
+        public FieldInfo SetLimits(Decimal? min, Decimal? max) { _InclusiveMinimumValue = min; _InclusiveMaximumValue = max; return this; }
 
         public FieldInfo SetItemsRange(int min, int max = int.MaxValue) { _MinItems = min; _MaxItems = max; return this; }
 

+ 24 - 4
build/SharpGLTF.CodeGen/SchemaReflection/SchemaTypesReader.cs

@@ -81,10 +81,28 @@ namespace SharpGLTF.SchemaReflection
 
                     foreach (var v in property.AnyOf)
                     {
-                        var val = v.Enumeration.FirstOrDefault();
                         var key = v.Description;
+                        var val = v.Enumeration?.FirstOrDefault();
+                        var ext = v.ExtensionData?.FirstOrDefault() ?? default;                        
 
-                        if (val is String) { key = (string)val; val = (Int64)0; }                        
+                        if (val is String txt)
+                        {
+                            System.Diagnostics.Debug.Assert(v.Type == NJsonSchema.JsonObjectType.None);
+
+                            key = txt; val = (Int64)0;
+                        }
+
+                        if (v.Type == NJsonSchema.JsonObjectType.None && ext.Key == "const")
+                        {
+                            key = (string)ext.Value; val = (Int64)0;
+                        }
+
+                        if (v.Type == NJsonSchema.JsonObjectType.Integer && ext.Key == "const")
+                        {
+                            val = (Int64)ext.Value;
+                        }
+
+                        System.Diagnostics.Debug.Assert(key != null || dict.Count > 0);
 
                         if (string.IsNullOrWhiteSpace(key)) continue;
 
@@ -153,9 +171,11 @@ namespace SharpGLTF.SchemaReflection
 
                     field.FieldType = ctx._UseType(p, required.Contains(p.Name));
 
-                    field.MinimumValue = p.Minimum;
-                    field.MaximumValue = p.Maximum;
+                    field.ExclusiveMinimumValue = p.ExclusiveMinimum ?? (p.IsExclusiveMinimum ? p.Minimum : null);
+                    field.InclusiveMinimumValue = p.IsExclusiveMinimum ? null : p.Minimum;
                     field.DefaultValue = p.Default;
+                    field.InclusiveMaximumValue = p.IsExclusiveMaximum ? null : p.Maximum;
+                    field.ExclusiveMaximumValue = p.ExclusiveMaximum ?? (p.IsExclusiveMaximum ? p.Maximum : null);
 
                     field.MinItems = p.MinItems;
                     field.MaxItems = p.MaxItems;

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

@@ -32,11 +32,11 @@ namespace SharpGLTF.Schema2
 	
 		private const Double _innerConeAngleDefault = 0;
 		private const Double _innerConeAngleMinimum = 0;
-		private const Double _innerConeAngleMaximum = 1.5707963267948966;
+		private const Double _innerConeAngleExclusiveMaximum = 1.5707963267948966;
 		private Double? _innerConeAngle = _innerConeAngleDefault;
 		
 		private const Double _outerConeAngleDefault = 0.7853981633974483;
-		private const Double _outerConeAngleMinimum = 0;
+		private const Double _outerConeAngleExclusiveMinimum = 0;
 		private const Double _outerConeAngleMaximum = 1.5707963267948966;
 		private Double? _outerConeAngle = _outerConeAngleDefault;
 		
@@ -73,7 +73,7 @@ namespace SharpGLTF.Schema2
 		private const Double _intensityMinimum = 0;
 		private Double? _intensity = _intensityDefault;
 		
-		private const Double _rangeMinimum = 0;
+		private const Double _rangeExclusiveMinimum = 0;
 		private Double? _range;
 		
 		private PunctualLightSpot _spot;

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

@@ -39,7 +39,7 @@ namespace SharpGLTF.Schema2
 
 
 	/// <summary>
-	/// The datatype of components in the attribute.
+	/// The datatype of the accessor's components.
 	/// </summary>
 	public enum EncodingType
 	{
@@ -53,7 +53,7 @@ namespace SharpGLTF.Schema2
 
 
 	/// <summary>
-	/// Specifies if the attribute is a scalar, vector, or matrix.
+	/// Specifies if the accessor's elements are scalars, vectors, or matrices.
 	/// </summary>
 	public enum DimensionType
 	{
@@ -69,7 +69,7 @@ namespace SharpGLTF.Schema2
 
 
 	/// <summary>
-	/// The name of the node's TRS property to modify, or the "weights" of the Morph Targets it instantiates. For the "translation" property, the values that are provided by the sampler are the translation along the x, y, and z axes. For the "rotation" property, the values are a quaternion in the order (x, y, z, w), where w is the scalar. For the "scale" property, the values are the scaling factors along the x, y, and z axes.
+	/// 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.
 	/// </summary>
 	public enum PropertyPath
 	{
@@ -92,7 +92,7 @@ namespace SharpGLTF.Schema2
 
 
 	/// <summary>
-	/// The target that the GPU buffer should be bound to.
+	/// The hint representing the intended GPU buffer type to use with this buffer view.
 	/// </summary>
 	public enum BufferMode
 	{
@@ -123,7 +123,7 @@ namespace SharpGLTF.Schema2
 
 
 	/// <summary>
-	/// The type of primitives to render.
+	/// The topology type of primitives to render.
 	/// </summary>
 	public enum PrimitiveType
 	{
@@ -164,7 +164,7 @@ namespace SharpGLTF.Schema2
 
 
 	/// <summary>
-	/// t wrapping mode.
+	/// T (V) wrapping mode.
 	/// </summary>
 	public enum TextureWrapMode
 	{
@@ -198,7 +198,7 @@ namespace SharpGLTF.Schema2
 	}
 
 	/// <summary>
-	/// Indices of those attributes that deviate from their initialization value.
+	/// An object pointing to a buffer view containing the indices of deviating accessor values. The number of indices is equal to `accessor.sparse.count`. Indices **MUST** strictly increase.
 	/// </summary>
 	partial class AccessorSparseIndices : ExtraProperties
 	{
@@ -234,7 +234,7 @@ namespace SharpGLTF.Schema2
 	}
 
 	/// <summary>
-	/// Array of size `accessor.sparse.count` times number of components storing the displaced accessor attributes pointed by `accessor.sparse.indices`.
+	/// An object pointing to a buffer view containing the deviating accessor values. The number of elements is equal to `accessor.sparse.count` times number of components. The elements have the same component type as the base accessor. The elements are tightly packed. Data **MUST** be aligned following the same rules as the base accessor.
 	/// </summary>
 	partial class AccessorSparseValues : ExtraProperties
 	{
@@ -266,7 +266,7 @@ namespace SharpGLTF.Schema2
 	}
 
 	/// <summary>
-	/// Sparse storage of attributes that deviate from their initialization value.
+	/// Sparse storage of accessor values that deviate from their initialization value.
 	/// </summary>
 	partial class AccessorSparse : ExtraProperties
 	{
@@ -301,9 +301,7 @@ namespace SharpGLTF.Schema2
 	}
 
 	/// <summary>
-	/// A typed view into a bufferView.
-	/// A bufferView contains raw binary data.
-	/// An accessor provides a typed view into a bufferView or a subset of a bufferView similar to how WebGL's `vertexAttribPointer()` defines an attribute in a buffer.
+	/// A typed view into a buffer view that contains raw binary data.
 	/// </summary>
 	partial class Accessor : LogicalChildOfRoot
 	{
@@ -621,7 +619,7 @@ namespace SharpGLTF.Schema2
 		
 		private Double _ymag;
 		
-		private const Double _zfarMinimum = 0;
+		private const Double _zfarExclusiveMinimum = 0;
 		private Double _zfar;
 		
 		private const Double _znearMinimum = 0;
@@ -657,16 +655,16 @@ namespace SharpGLTF.Schema2
 	partial class CameraPerspective : ExtraProperties
 	{
 	
-		private const Double _aspectRatioMinimum = 0;
+		private const Double _aspectRatioExclusiveMinimum = 0;
 		private Double? _aspectRatio;
 		
-		private const Double _yfovMinimum = 0;
+		private const Double _yfovExclusiveMinimum = 0;
 		private Double _yfov;
 		
-		private const Double _zfarMinimum = 0;
+		private const Double _zfarExclusiveMinimum = 0;
 		private Double? _zfar;
 		
-		private const Double _znearMinimum = 0;
+		private const Double _znearExclusiveMinimum = 0;
 		private Double _znear;
 		
 	
@@ -695,7 +693,7 @@ namespace SharpGLTF.Schema2
 
 	/// <summary>
 	/// A camera's projection.
-	/// A node can reference a camera to apply a transform to place the camera in the scene.
+	/// A node **MAY** reference a camera to apply a transform to place the camera in the scene.
 	/// </summary>
 	partial class Camera : LogicalChildOfRoot
 	{
@@ -964,8 +962,7 @@ namespace SharpGLTF.Schema2
 
 	/// <summary>
 	/// A set of primitives to be rendered.
-	/// A node can contain one mesh.
-	/// A node's transform places the mesh in the scene.
+	/// Its global transform is defined by a node that references it.
 	/// </summary>
 	partial class Mesh : LogicalChildOfRoot
 	{
@@ -998,8 +995,8 @@ namespace SharpGLTF.Schema2
 
 	/// <summary>
 	/// A node in the node hierarchy.
-	/// When the node contains `skin`, all `mesh.primitives` must contain `JOINTS_0` and `WEIGHTS_0` attributes.
-	/// A node can have either a `matrix` or any combination of `translation`/`rotation`/`scale` (TRS) properties. TRS properties are converted to matrices and postmultiplied in the `T * R * S` order to compose the transformation matrix; first the scale is applied to the vertices, then the rotation, and then the translation. If none are provided, the transform is the identity. When a node is targeted for animation (referenced by an animation.channel.target), only TRS properties may be present; `matrix` will not be present.
+	/// When the node contains `skin`, all `mesh.primitives` **MUST** contain `JOINTS_0` and `WEIGHTS_0` attributes.
+	/// A node **MAY** have either a `matrix` or any combination of `translation`/`rotation`/`scale` (TRS) properties. TRS properties are converted to matrices and postmultiplied in the `T * R * S` order to compose the transformation matrix; first the scale is applied to the vertices, then the rotation, and then the translation. If none are provided, the transform is the identity. When a node is targeted for animation (referenced by an animation.channel.target), `matrix` **MUST NOT** be present.
 	/// </summary>
 	partial class Node : LogicalChildOfRoot
 	{
@@ -1296,7 +1293,7 @@ namespace SharpGLTF.Schema2
 	}
 
 	/// <summary>
-	/// Image data used to create a texture. Image can be referenced by URI or `bufferView` index. `mimeType` is required in the latter case.
+	/// Image data used to create a texture. Image **MAY** be referenced by an URI (or IRI) or a buffer view index.
 	/// </summary>
 	partial class Image : LogicalChildOfRoot
 	{

+ 5 - 5
src/SharpGLTF.Core/Schema2/gltf.Camera.cs

@@ -172,7 +172,7 @@ namespace SharpGLTF.Schema2
         public static void VerifyParameters(float xmag, float ymag, float znear, float zfar)
         {
             Guard.MustBeGreaterThanOrEqualTo(znear, (float)_znearMinimum, nameof(znear));
-            Guard.MustBeGreaterThanOrEqualTo(zfar, (float)_zfarMinimum, nameof(zfar));
+            Guard.MustBeGreaterThan(zfar, (float)_zfarExclusiveMinimum, nameof(zfar));
             Guard.MustBeGreaterThan(zfar, znear, nameof(zfar));
             Guard.MustBeLessThan(zfar, float.PositiveInfinity, nameof(zfar));
 
@@ -254,12 +254,12 @@ namespace SharpGLTF.Schema2
 
         public static void VerifyParameters(float? aspectRatio, float yfov, float znear, float zfar = float.PositiveInfinity)
         {
-            Guard.MustBeGreaterThanOrEqualTo(aspectRatio.AsValue(1), (float)_aspectRatioMinimum, nameof(aspectRatio));
-            Guard.MustBeGreaterThan(yfov, (float)_yfovMinimum, nameof(yfov));
+            Guard.MustBeGreaterThan(aspectRatio.AsValue(1), (float)_aspectRatioExclusiveMinimum, nameof(aspectRatio));
+            Guard.MustBeGreaterThan(yfov, (float)_yfovExclusiveMinimum, nameof(yfov));
             // Guard.MustBeLessThan(yfov, (float)Math.PI, nameof(yfov));
 
-            Guard.MustBeGreaterThanOrEqualTo(znear, (float)_znearMinimum, nameof(znear));
-            Guard.MustBeGreaterThanOrEqualTo(zfar, (float)_zfarMinimum, nameof(zfar));
+            Guard.MustBeGreaterThan(znear, (float)_znearExclusiveMinimum, nameof(znear));
+            Guard.MustBeGreaterThan(zfar, (float)_zfarExclusiveMinimum, nameof(zfar));
             Guard.MustBeGreaterThan(zfar, znear, nameof(zfar));
         }
 

+ 16 - 6
src/SharpGLTF.Core/Schema2/gltf.PunctualLight.cs

@@ -133,7 +133,7 @@ namespace SharpGLTF.Schema2
 
         /// <summary>
         /// Gets or sets a Hint defining a distance cutoff at which the light's intensity may be considered
-        /// to have reached zero. Supported only for point and spot lights. Must be > 0.
+        /// to have reached zero. Supported only for point and spot lights.
         /// When undefined, range is assumed to be infinite.
         /// </summary>
         public Single Range
@@ -143,7 +143,9 @@ namespace SharpGLTF.Schema2
             {
                 if (LightType == PunctualLightType.Directional) { _range = null; return; }
 
-                _range = ((double)value).AsNullable(_rangeDefault, _rangeMinimum + 2e-07, float.MaxValue);
+                if (value <= _rangeExclusiveMinimum) throw new ArgumentOutOfRangeException(nameof(value));
+
+                _range = ((double)value).AsNullable(_rangeDefault, _rangeExclusiveMinimum, float.MaxValue);
             }
         }
 
@@ -188,20 +190,28 @@ namespace SharpGLTF.Schema2
         public Single InnerConeAngle
         {
             get => (Single)_innerConeAngle.AsValue(_innerConeAngleDefault);
-            set => _innerConeAngle = value.AsNullable((Single)_innerConeAngleDefault, (Single)_innerConeAngleMinimum, (Single)_innerConeAngleMaximum);
+            set
+            {
+                Guard.MustBeLessThan(value, _innerConeAngleExclusiveMaximum, nameof(value));
+                _innerConeAngle = value.AsNullable((Single)_innerConeAngleDefault, (Single)_innerConeAngleMinimum, (Single)_innerConeAngleExclusiveMaximum);
+            }
         }
 
         public Single OuterConeAngle
         {
             get => (Single)_outerConeAngle.AsValue(_outerConeAngleDefault);
-            set => _outerConeAngle = value.AsNullable((Single)_outerConeAngleDefault, (Single)_outerConeAngleMinimum, (Single)_outerConeAngleMaximum);
+            set
+            {
+                Guard.MustBeGreaterThan(value, _outerConeAngleExclusiveMinimum, nameof(value));
+                _outerConeAngle = value.AsNullable((Single)_outerConeAngleDefault, (Single)_outerConeAngleExclusiveMinimum, (Single)_outerConeAngleMaximum);
+            }
         }
 
         protected override void OnValidateContent(Validation.ValidationContext validate)
         {
             validate
-                .IsDefaultOrWithin(nameof(InnerConeAngle), InnerConeAngle, (Single)_innerConeAngleMinimum, (Single)_innerConeAngleMaximum)
-                .IsDefaultOrWithin(nameof(OuterConeAngle), OuterConeAngle, (Single)_outerConeAngleMinimum, (Single)_outerConeAngleMaximum)
+                .IsDefaultOrWithin(nameof(InnerConeAngle), InnerConeAngle, (Single)_innerConeAngleMinimum, (Single)_innerConeAngleExclusiveMaximum)
+                .IsDefaultOrWithin(nameof(OuterConeAngle), OuterConeAngle, (Single)_outerConeAngleExclusiveMinimum, (Single)_outerConeAngleMaximum)
                 .IsLess(nameof(InnerConeAngle), InnerConeAngle, OuterConeAngle);
 
             base.OnValidateContent(validate);