Browse Source

Adding KHR_Volume extension (WIP)

Vicente Penades 4 years ago
parent
commit
9ca62b9114

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

@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+
+using SharpGLTF.SchemaReflection;
+
+namespace SharpGLTF
+{
+    class VolumeExtension : SchemaProcessor
+    {
+        private static string SchemaUri => Constants.KhronosExtensionPath("KHR_materials_volume", "glTF.KHR_materials_volume.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");
+
+            var cls = ctx.FindClass("KHR_materials_volume glTF extension");
+
+            cls.GetField("attenuationColor")
+                .SetDataType(typeof(System.Numerics.Vector3), true)
+                .SetDefaultValue("Vector3.One")
+                .SetItemsRange(0);
+
+            yield return ("ext.MaterialsVolume.g", ctx);
+        }
+
+        public override void PrepareTypes(CodeGen.CSharpEmitter newEmitter, SchemaType.Context ctx)
+        {
+            newEmitter.SetRuntimeName("KHR_materials_volume glTF extension", "MaterialVolume");
+        }
+    }
+}

+ 1 - 0
build/SharpGLTF.CodeGen/Program.cs

@@ -37,6 +37,7 @@ namespace SharpGLTF
             processors.Add(new UnlitExtension());
             processors.Add(new IorExtension());
             processors.Add(new SheenExtension());
+            processors.Add(new VolumeExtension());
             processors.Add(new SpecularExtension());
             processors.Add(new ClearCoatExtension());
             processors.Add(new TransmissionExtension());

+ 72 - 0
src/SharpGLTF.Core/Schema2/Generated/ext.MaterialsVolume.g.cs

@@ -0,0 +1,72 @@
+// <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 that defines the parameters for the volume of a material.
+	/// </summary>
+	partial class MaterialVolume : ExtraProperties
+	{
+	
+		private static readonly Vector3 _attenuationColorDefault = Vector3.One;
+		private Vector3? _attenuationColor = _attenuationColorDefault;
+		
+		private const Double _attenuationDistanceExclusiveMinimum = 0;
+		private Double? _attenuationDistance;
+		
+		private const Double _thicknessFactorDefault = 0;
+		private const Double _thicknessFactorMinimum = 0;
+		private Double? _thicknessFactor = _thicknessFactorDefault;
+		
+		private TextureInfo _thicknessTexture;
+		
+	
+		protected override void SerializeProperties(Utf8JsonWriter writer)
+		{
+			base.SerializeProperties(writer);
+			SerializeProperty(writer, "attenuationColor", _attenuationColor, _attenuationColorDefault);
+			SerializeProperty(writer, "attenuationDistance", _attenuationDistance);
+			SerializeProperty(writer, "thicknessFactor", _thicknessFactor, _thicknessFactorDefault);
+			SerializePropertyObject(writer, "thicknessTexture", _thicknessTexture);
+		}
+	
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
+		{
+			switch (jsonPropertyName)
+			{
+				case "attenuationColor": _attenuationColor = DeserializePropertyValue<Vector3?>(ref reader); break;
+				case "attenuationDistance": _attenuationDistance = DeserializePropertyValue<Double?>(ref reader); break;
+				case "thicknessFactor": _thicknessFactor = DeserializePropertyValue<Double?>(ref reader); break;
+				case "thicknessTexture": _thicknessTexture = DeserializePropertyValue<TextureInfo>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
+			}
+		}
+	
+	}
+
+}

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

@@ -116,9 +116,9 @@ namespace SharpGLTF.Schema2
         /// <summary>
         /// Gets the index of texture's TEXCOORD_[index] attribute used for texture coordinate mapping.
         /// </summary>
-        public int TextureCoordinate => _TextureInfo(false)?.TextureCoordinate ?? 0;
+        public int TextureCoordinate => _TextureInfo?.Invoke(false)?.TextureCoordinate ?? 0;
 
-        public TextureTransform TextureTransform => _TextureInfo(false)?.Transform;
+        public TextureTransform TextureTransform => _TextureInfo?.Invoke(false)?.Transform;
 
         public TextureSampler TextureSampler => Texture?.Sampler;
 
@@ -147,6 +147,8 @@ namespace SharpGLTF.Schema2
 
             Guard.NotNull(_Material, nameof(_Material));
 
+            if (_TextureInfo == null) throw new InvalidOperationException();
+
             var sampler = _Material.LogicalParent.UseTextureSampler(ws, wt, min, mag);
             var texture = _Material.LogicalParent.UseTexture(primaryImg, fallbackImg, sampler);
 
@@ -170,9 +172,7 @@ namespace SharpGLTF.Schema2
 
         private Texture TryGetTexture()
         {
-            if (_TextureInfo == null) throw new InvalidOperationException();
-
-            var texInfo = _TextureInfo(false);
+            var texInfo = _TextureInfo?.Invoke(false);
             if (texInfo == null) return null;
             if (texInfo._LogicalTextureIndex < 0) return null;
             return _Material.LogicalParent.LogicalTextures[texInfo._LogicalTextureIndex];

+ 95 - 0
src/SharpGLTF.Core/Schema2/gltf.MaterialsFactory.cs

@@ -629,4 +629,99 @@ namespace SharpGLTF.Schema2
             }
         }
     }
+
+    internal sealed partial class MaterialVolume
+    {
+#pragma warning disable CA1801 // Review unused parameters
+        internal MaterialVolume(Material material) { }
+#pragma warning restore CA1801 // Review unused parameters
+
+        protected override IEnumerable<ExtraProperties> GetLogicalChildren()
+        {
+            return base.GetLogicalChildren().ConcatElements(_thicknessTexture);
+        }
+
+        private TextureInfo _GetThicknessTexture(bool create)
+        {
+            if (create && _thicknessTexture == null) _thicknessTexture = new TextureInfo();
+            return _thicknessTexture;
+        }
+
+        public float ThicknessFactor
+        {
+            get => (float)_thicknessFactor.AsValue(_thicknessFactorDefault);
+            set => _thicknessFactor = ((double)value).AsNullable(_thicknessFactorDefault);
+        }
+
+        public Vector3 AttenuationColor
+        {
+            get => _attenuationColor.AsValue(_attenuationColorDefault);
+            set => _attenuationColor = value.AsNullable(_attenuationColorDefault);
+        }
+
+        public float AttenuationDistance
+        {
+            get => (float)_attenuationDistance;
+            set => _attenuationDistance = value > _attenuationDistanceExclusiveMinimum ? value : throw new ArgumentOutOfRangeException();
+        }
+
+        private static Vector4 _AttenuationDefault => new Vector4(_attenuationColorDefault, float.MaxValue);
+
+        private Vector4 _Attenuation
+        {
+            get
+            {
+                return new Vector4
+                    (
+                    _attenuationColor.AsValue(_attenuationColorDefault),
+                    (float)_attenuationDistance.AsValue(float.MaxValue)
+                    );
+            }
+            set
+            {
+                _attenuationColor = new Vector3(value.X, value.Y, value.Z).AsNullable(_attenuationColorDefault);
+                _attenuationDistance = ((double)value.W).AsNullable(float.MaxValue, _attenuationDistanceExclusiveMinimum, float.PositiveInfinity);
+            }
+        }
+
+        public IEnumerable<MaterialChannel> GetChannels(Material material)
+        {
+            yield return new MaterialChannel
+                (
+                material,
+                "VolumeThickness",
+                _GetThicknessTexture,
+                (float)_thicknessFactorDefault,
+                () => ThicknessFactor,
+                value => ThicknessFactor = value
+                );
+
+            yield return new MaterialChannel
+                (
+                material,
+                "VolumeAttenuation",
+                null,
+                _AttenuationDefault,
+                () => _Attenuation,
+                value => _Attenuation = value
+                );
+        }
+
+        protected override void OnValidateContent(ValidationContext validate)
+        {
+            base.OnValidateContent(validate);
+
+            if (_attenuationColor.HasValue)
+            {
+                Guard.MustBeBetweenOrEqualTo(_attenuationColor.Value.X, 0, float.MaxValue, nameof(_attenuationColor));
+                Guard.MustBeBetweenOrEqualTo(_attenuationColor.Value.Y, 0, float.MaxValue, nameof(_attenuationColor));
+                Guard.MustBeBetweenOrEqualTo(_attenuationColor.Value.Z, 0, float.MaxValue, nameof(_attenuationColor));
+            }
+
+            if (_thicknessFactor.HasValue)
+            {
+                Guard.MustBeBetweenOrEqualTo(_thicknessFactor.Value, _thicknessFactorMinimum, float.MaxValue, nameof(_thicknessFactor));
+            }
+        }
+    }
 }