Bladeren bron

+documentation

Vicente Penades 6 jaren geleden
bovenliggende
commit
59148dd002

+ 11 - 0
src/SharpGLTF.Toolkit/Geometry/PrimitiveBuilder.cs

@@ -70,6 +70,7 @@ namespace SharpGLTF.Geometry
     /// <see cref="VertexJoints16x4"/>,
     /// <see cref="VertexJoints16x8"/>.
     /// </typeparam>
+    [System.Diagnostics.DebuggerDisplay("Primitive {_Material}")]
     public class PrimitiveBuilder<TMaterial, TvP, TvM, TvS> : IPrimitiveBuilder, IPrimitive<TMaterial>
         where TvP : struct, IVertexPosition
         where TvM : struct, IVertexMaterial
@@ -128,6 +129,16 @@ namespace SharpGLTF.Geometry
 
         #region API
 
+        /// <summary>
+        /// Adds or reuses a vertex.
+        /// </summary>
+        /// <param name="vertex">
+        /// A vertex formed by
+        /// <typeparamref name="TvP"/>,
+        /// <typeparamref name="TvM"/> and
+        /// <typeparamref name="TvS"/> fragments.
+        /// </param>
+        /// <returns>The index of the vertex.</returns>
         public int UseVertex((TvP, TvM, TvS) vertex)
         {
             if (_Scrict)

+ 3 - 0
src/SharpGLTF.Toolkit/Geometry/VertexTypes/VertexColumns.cs

@@ -5,6 +5,9 @@ using System.Text;
 
 namespace SharpGLTF.Geometry.VertexTypes
 {
+    /// <summary>
+    /// Represents a vertex buffer, where every vertex attribute is represented as a vector column.
+    /// </summary>
     public class VertexColumns
     {
         #region columns

+ 1 - 0
src/SharpGLTF.Toolkit/Geometry/VertexTypes/VertexEmpty.cs

@@ -5,6 +5,7 @@ using System.Text;
 
 namespace SharpGLTF.Geometry.VertexTypes
 {
+    [System.Diagnostics.DebuggerDisplay("Empty")]
     public struct VertexEmpty : IVertexMaterial, IVertexSkinning
     {
         public void Validate() { }

+ 5 - 0
src/SharpGLTF.Toolkit/Geometry/VertexTypes/VertexMaterial.cs

@@ -22,6 +22,7 @@ namespace SharpGLTF.Geometry.VertexTypes
     /// <summary>
     /// Defines a Vertex attribute with a Color material.
     /// </summary>
+    [System.Diagnostics.DebuggerDisplay("{Color}")]
     public struct VertexColor1 : IVertexMaterial
     {
         #region constructors
@@ -78,6 +79,7 @@ namespace SharpGLTF.Geometry.VertexTypes
     /// <summary>
     /// Defines a Vertex attribute with a Texture Coordinate.
     /// </summary>
+    [System.Diagnostics.DebuggerDisplay("{TexCoord}")]
     public struct VertexTexture1 : IVertexMaterial
     {
         #region constructors
@@ -133,6 +135,7 @@ namespace SharpGLTF.Geometry.VertexTypes
     /// <summary>
     /// Defines a Vertex attribute with a Color material and a Texture Coordinate.
     /// </summary>
+    [System.Diagnostics.DebuggerDisplay("{Color} {TexCoord}")]
     public struct VertexColor1Texture1 : IVertexMaterial
     {
         #region constructors
@@ -191,6 +194,7 @@ namespace SharpGLTF.Geometry.VertexTypes
     /// <summary>
     /// Defines a Vertex attribute with a Color material and two Texture Coordinates.
     /// </summary>
+    [System.Diagnostics.DebuggerDisplay("{Color} {TexCoord0} {TexCoord1}")]
     public struct VertexColor1Texture2 : IVertexMaterial
     {
         #region constructors
@@ -262,6 +266,7 @@ namespace SharpGLTF.Geometry.VertexTypes
     /// <summary>
     /// Defines a Vertex attribute with a Color material and two Texture Coordinates.
     /// </summary>
+    [System.Diagnostics.DebuggerDisplay("{Color0} {Color1} {TexCoord0} {TexCoord1}")]
     public struct VertexColor2Texture2 : IVertexMaterial
     {
         #region constructors

+ 3 - 0
src/SharpGLTF.Toolkit/Geometry/VertexTypes/VertexPosition.cs

@@ -23,6 +23,7 @@ namespace SharpGLTF.Geometry.VertexTypes
     /// <summary>
     /// Defines a Vertex attribute with a Position.
     /// </summary>
+    [System.Diagnostics.DebuggerDisplay("{Position}")]
     public struct VertexPosition : IVertexPosition
     {
         #region constructors
@@ -81,6 +82,7 @@ namespace SharpGLTF.Geometry.VertexTypes
     /// <summary>
     /// Defines a Vertex attribute with a Position and a Normal.
     /// </summary>
+    [System.Diagnostics.DebuggerDisplay("{Position} {Normal}")]
     public struct VertexPositionNormal : IVertexPosition
     {
         #region constructors
@@ -141,6 +143,7 @@ namespace SharpGLTF.Geometry.VertexTypes
     /// <summary>
     /// Defines a Vertex attribute with a Position, a Normal and a Tangent.
     /// </summary>
+    [System.Diagnostics.DebuggerDisplay("{Position} {Normal} {Tangent}")]
     public struct VertexPositionNormalTangent : IVertexPosition
     {
         #region constructors

+ 83 - 8
src/SharpGLTF.Toolkit/Materials/Material.cs

@@ -60,15 +60,38 @@ namespace SharpGLTF.Materials
 
         #region API
 
-        public MaterialBuilder WithUnlitShader() { return WithShade(SHADERUNLIT); }
-
-        public MaterialBuilder WithMetallicRoughnessShader() { return WithShade(SHADERPBRMETALLICROUGHNESS); }
-
-        public MaterialBuilder WithSpecularGlossinessShader() { return WithShade(SHADERPBRSPECULARGLOSSINESS); }
-
-        public MaterialBuilder WithShade(string shader)
+        /// <summary>
+        /// Sets <see cref="MaterialBuilder.ShaderStyle"/> to use <see cref="SHADERUNLIT"/>.
+        /// </summary>
+        /// <returns>This <see cref="MaterialBuilder"/>.</returns>
+        public MaterialBuilder WithUnlitShader() { return WithShader(SHADERUNLIT); }
+
+        /// <summary>
+        /// Sets <see cref="MaterialBuilder.ShaderStyle"/> to use <see cref="SHADERPBRMETALLICROUGHNESS"/>.
+        /// </summary>
+        /// <returns>This <see cref="MaterialBuilder"/>.</returns>
+        public MaterialBuilder WithMetallicRoughnessShader() { return WithShader(SHADERPBRMETALLICROUGHNESS); }
+
+        /// <summary>
+        /// Sets <see cref="MaterialBuilder.ShaderStyle"/> to use <see cref="SHADERPBRSPECULARGLOSSINESS"/>.
+        /// </summary>
+        /// <returns>This <see cref="MaterialBuilder"/>.</returns>
+        public MaterialBuilder WithSpecularGlossinessShader() { return WithShader(SHADERPBRSPECULARGLOSSINESS); }
+
+        /// <summary>
+        /// Sets <see cref="MaterialBuilder.ShaderStyle"/>.
+        /// </summary>
+        /// <param name="shader">
+        /// A valid shader style, which can be one of these values:
+        /// <see cref="SHADERUNLIT"/>,
+        /// <see cref="SHADERPBRMETALLICROUGHNESS"/>,
+        /// <see cref="SHADERPBRSPECULARGLOSSINESS"/>
+        /// </param>
+        /// <returns>This <see cref="MaterialBuilder"/>.</returns>
+        public MaterialBuilder WithShader(string shader)
         {
             Guard.NotNullOrEmpty(shader, nameof(shader));
+            Guard.IsTrue(shader == SHADERUNLIT || shader == SHADERPBRMETALLICROUGHNESS || shader == SHADERPBRSPECULARGLOSSINESS, nameof(shader));
             ShaderStyle = shader;
             return this;
         }
@@ -95,7 +118,6 @@ namespace SharpGLTF.Materials
         public MaterialChannelBuilder UseChannel(string channelKey)
         {
             var ch = GetChannel(channelKey);
-
             if (ch != null) return ch;
 
             ch = new MaterialChannelBuilder(this, channelKey);
@@ -147,12 +169,65 @@ namespace SharpGLTF.Materials
             return this;
         }
 
+        /// <summary>
+        /// Defines a fallback <see cref="MaterialBuilder"/> instance for the current <see cref="MaterialBuilder"/>.
+        /// </summary>
+        /// <param name="fallback">
+        /// A <see cref="MaterialBuilder"/> instance
+        /// that must have a <see cref="MaterialBuilder.ShaderStyle"/>
+        /// of type <see cref="SHADERPBRMETALLICROUGHNESS"/></param>
+        /// <returns>This <see cref="MaterialBuilder"/>.</returns>
         public MaterialBuilder WithFallback(MaterialBuilder fallback)
         {
             this.CompatibilityFallback = fallback;
             return this;
         }
 
+        internal void ValidateForSchema2()
+        {
+            if (this.ShaderStyle == SHADERPBRSPECULARGLOSSINESS)
+            {
+                if (this.CompatibilityFallback != null)
+                {
+                    Guard.MustBeNull(this.CompatibilityFallback.CompatibilityFallback, nameof(this.CompatibilityFallback.CompatibilityFallback));
+
+                    Guard.IsTrue(this.CompatibilityFallback.ShaderStyle == SHADERPBRMETALLICROUGHNESS, nameof(CompatibilityFallback.ShaderStyle));
+                }
+            }
+            else
+            {
+                Guard.MustBeNull(this.CompatibilityFallback, nameof(CompatibilityFallback));
+            }
+        }
+
+        public MaterialBuilder WithNormal(string imageFilePath, float scale = 1)
+        {
+            WithChannelImage("Normal", imageFilePath);
+            WithChannelParam("Normal", new Vector4(scale, 0, 0, 0));
+
+            return this;
+        }
+
+        public MaterialBuilder WithOcclusion(string imageFilePath, float strength = 1)
+        {
+            WithChannelImage("Occlusion", imageFilePath);
+            WithChannelParam("Occlusion", new Vector4(strength, 0, 0, 0));
+
+            return this;
+        }
+
+        public MaterialBuilder WithEmissive(string imageFilePath, Vector3 emissiveFactor)
+        {
+            WithChannelImage("Emissive", imageFilePath);
+            WithChannelParam("Emissive", new Vector4(emissiveFactor, 0));
+
+            return this;
+        }
+
+        public MaterialBuilder WithEmissive(string imageFilePath) { return WithChannelImage("Emissive", imageFilePath); }
+
+        public MaterialBuilder WithEmissive(Vector3 emissiveFactor) { return WithChannelParam("Emissive", new Vector4(emissiveFactor, 0)); }
+
         #endregion
     }
 }

+ 23 - 1
src/SharpGLTF.Toolkit/Materials/readme.md

@@ -27,4 +27,26 @@ element has a different meaning, depending on the kind of channel:
 
 #### Implementation
 
-TODO
+To create new materials, there's two ways of doing it; accessing directly to the glTF
+materials namespace, or using the MaterialBuilder class.
+
+The advantage of MaterialBuilder is that it allows to create stand alone materials
+that can be easily edited and used to create glTF materials at any time.
+
+Creating a standard material can be done like this:
+
+```c#
+var material = new Materials.MaterialBuilder("material1")
+                .WithDoubleSide(true)
+                .WithMetallicRoughnessShader()
+                .WithChannelImage("Normal", "WaterBottle_normal.png")
+                .WithChannelImage("Emissive", "WaterBottle_emissive.png")
+                .WithChannelImage("Occlusion", "WaterBottle_occlusion.png")
+                .WithChannelImage("BaseColor", "WaterBottle_baseColor.png")
+                .WithChannelImage("MetallicRoughness", "WaterBottle_roughnessMetallic.png");
+```
+
+MaterialBuilder also supports a fallback material that will be used in case the main material is not
+supported by the rendering engine. But due to glTF limitations, this feature is restricted only to
+a main material using SpecularGlossiness shader, and the fallback material using MatellicRoughness
+shader.

+ 21 - 2
src/SharpGLTF.Toolkit/Schema2/MaterialExtensions.cs

@@ -159,6 +159,9 @@ namespace SharpGLTF.Schema2
 
         public static Material CreateMaterial(this ModelRoot root, Materials.MaterialBuilder mb)
         {
+            Guard.NotNull(root, nameof(root));
+            Guard.NotNull(mb, nameof(mb));
+
             var m = root.CreateMaterial(mb.Name);
 
             mb.CopyTo(m);
@@ -172,6 +175,9 @@ namespace SharpGLTF.Schema2
 
         public static void CopyTo(this Material srcMaterial, Materials.MaterialBuilder dstMaterial)
         {
+            Guard.NotNull(srcMaterial, nameof(srcMaterial));
+            Guard.NotNull(dstMaterial, nameof(dstMaterial));
+
             dstMaterial.Name = srcMaterial.Name;
             dstMaterial.AlphaMode = srcMaterial.Alpha;
             dstMaterial.AlphaCutoff = srcMaterial.AlphaCutoff;
@@ -205,6 +211,9 @@ namespace SharpGLTF.Schema2
 
         public static void CopyChannelsTo(this Material srcMaterial, Materials.MaterialBuilder dstMaterial, params string[] channelKeys)
         {
+            Guard.NotNull(srcMaterial, nameof(srcMaterial));
+            Guard.NotNull(dstMaterial, nameof(dstMaterial));
+
             foreach (var k in channelKeys)
             {
                 var src = srcMaterial.FindChannel(k);
@@ -218,6 +227,9 @@ namespace SharpGLTF.Schema2
 
         public static void CopyTo(this MaterialChannel srcChannel, Materials.MaterialChannelBuilder dstChannel)
         {
+            Guard.NotNull(srcChannel, nameof(srcChannel));
+            Guard.NotNull(dstChannel, nameof(dstChannel));
+
             dstChannel.Parameter = srcChannel.Parameter;
 
             if (srcChannel.Texture == null) { return; }
@@ -241,7 +253,10 @@ namespace SharpGLTF.Schema2
 
         public static void CopyTo(this Materials.MaterialBuilder srcMaterial, Material dstMaterial)
         {
-            // dstMaterial.Name = srcMaterial.Name;
+            Guard.NotNull(srcMaterial, nameof(srcMaterial));
+            Guard.NotNull(dstMaterial, nameof(dstMaterial));
+
+            srcMaterial.ValidateForSchema2();
 
             dstMaterial.Alpha = srcMaterial.AlphaMode;
             dstMaterial.AlphaCutoff = srcMaterial.AlphaCutoff;
@@ -280,6 +295,9 @@ namespace SharpGLTF.Schema2
 
         public static void CopyChannelsTo(this Materials.MaterialBuilder srcMaterial, Material dstMaterial, params string[] channelKeys)
         {
+            Guard.NotNull(srcMaterial, nameof(srcMaterial));
+            Guard.NotNull(dstMaterial, nameof(dstMaterial));
+
             foreach (var k in channelKeys)
             {
                 var src = srcMaterial.GetChannel(k);
@@ -294,7 +312,8 @@ namespace SharpGLTF.Schema2
 
         public static void CopyTo(this Materials.MaterialChannelBuilder srcChannel, MaterialChannel dstChannel)
         {
-            if (srcChannel == null) return;
+            Guard.NotNull(srcChannel, nameof(srcChannel));
+            Guard.NotNull(dstChannel, nameof(dstChannel));
 
             dstChannel.Parameter = srcChannel.Parameter;
 

+ 2 - 1
tests/SharpGLTF.Tests/Schema2/LoadAndSave/LoadGeneratedTests.cs

@@ -28,7 +28,8 @@ namespace SharpGLTF.Schema2.LoadAndSave
         {
             TestContext.CurrentContext.AttachShowDirLink();
 
-            var files = TestFiles.GetReferenceModelPaths();
+            var files = TestFiles.GetReferenceModelPaths()
+                .Where(item => item.Contains("\\Positive\\"));
 
             foreach (var f in files)
             {

+ 2 - 2
tests/SharpGLTF.Tests/TestFiles.cs

@@ -30,8 +30,8 @@ namespace SharpGLTF
             
             TestContext.Progress.WriteLine("Downloading reference files... It might take a while, please, wait...");            
 
-            var dstPath = System.IO.Path.Combine(TestContext.CurrentContext.WorkDirectory, "GeneratedReferenceModels", "v_0_6_0.zip");
-            _GeneratedModelsDir = DownloadUtils.DownloadFile("https://github.com/KhronosGroup/glTF-Asset-Generator/releases/download/v0.6.0/GeneratedAssets-0.6.0.zip", dstPath);
+            var dstPath = System.IO.Path.Combine(TestContext.CurrentContext.WorkDirectory, "GeneratedReferenceModels", "v_0_6_1.zip");
+            _GeneratedModelsDir = DownloadUtils.DownloadFile("https://github.com/KhronosGroup/glTF-Asset-Generator/releases/download/v0.6.1/GeneratedAssets-0.6.1.zip", dstPath);
             
             TestContext.Progress.WriteLine("Checking out test files... It might take a while, please, wait...");