Browse Source

even more With* APIs :)

Vicente Penades 6 years ago
parent
commit
41ee11ee0a

+ 2 - 33
src/SharpGLTF.Toolkit/Geometry/InterleavedMeshBuilder.cs

@@ -6,8 +6,6 @@ using System.Text;
 namespace SharpGLTF.Geometry
 {
     using Collections;
-    using Schema2;
-    using VertexTypes;
 
     public class InterleavedMeshBuilder<TVertex, TMaterial>
         where TVertex : struct
@@ -69,38 +67,9 @@ namespace SharpGLTF.Geometry
             }
         }
 
-        public void CopyToNode(Node dstNode, Func<TMaterial, Material> materialEvaluator)
+        public IReadOnlyList<int> GetIndices(TMaterial material)
         {
-            dstNode.Mesh = dstNode.LogicalParent.CreateMesh();
-            CopyToMesh(dstNode.Mesh, materialEvaluator);
-        }
-
-        public void CopyToMesh(Schema2.Mesh dstMesh, Func<TMaterial, Material> materialEvaluator)
-        {
-            var root = dstMesh.LogicalParent;
-
-            // create vertex accessors
-            var vertexAccessors = root.CreateInterleavedVertexAccessors(_Vertices);
-
-            foreach (var kvp in _Indices)
-            {
-                // create index buffer
-                var ibytes = new Byte[4 * kvp.Value.Count];
-                var ibuffer = root.UseBufferView(new ArraySegment<byte>(ibytes), 0, BufferMode.ELEMENT_ARRAY_BUFFER);
-
-                var indices = root
-                    .CreateAccessor("Indices");
-
-                indices.SetIndexData(ibuffer, 0, kvp.Value);
-
-                // create mesh primitive
-                var prim = dstMesh.CreatePrimitive();
-                foreach (var va in vertexAccessors) prim.SetVertexAccessor(va.Key, va.Value);
-                prim.SetIndexAccessor(indices);
-                prim.DrawPrimitiveType = PrimitiveType.TRIANGLES;
-
-                prim.Material = materialEvaluator(kvp.Key);
-            }
+            return _Indices.TryGetValue(material, out List<int> indices) ? indices : null;
         }
 
         #endregion

+ 37 - 0
src/SharpGLTF.Toolkit/Schema2/MaterialExtensions.cs

@@ -33,6 +33,24 @@ namespace SharpGLTF.Schema2
             return material;
         }
 
+        public static Material WithDoubleSide(this Material material, bool enabled)
+        {
+            material.DoubleSided = enabled;
+            return material;
+        }
+
+        public static Material WithChannelTexture(this Material material, string channelName, int textureSet, string imageFilePath)
+        {
+            material.FindChannel(channelName).SetTexture(textureSet, material.LogicalParent.UseImageWithFile(imageFilePath));
+            return material;
+        }
+
+        public static Material WithChannelTexture(this Material material, string channelName, int textureSet, Image image)
+        {
+            material.FindChannel(channelName).SetTexture(textureSet, image);
+            return material;
+        }
+
         /// <summary>
         /// Initializes this <see cref="Material"/> instance with PBR Metallic Roughness attributes.
         /// </summary>
@@ -44,6 +62,25 @@ namespace SharpGLTF.Schema2
             return material;
         }
 
+        public static Material WithPBRMetallicRoughness(this Material material,
+            Vector4 baseColorFactor, string baseColorImageFilePath,
+            float metallicFactor = 1, string metallicImageFilePath = null,
+            float roughnessFactor = 1, string roughtnessImageFilePath = null
+            )
+        {
+            material.WithPBRMetallicRoughness();
+
+            if (!string.IsNullOrWhiteSpace(baseColorImageFilePath)) material.WithChannelTexture("BaseColor", 0, baseColorImageFilePath);
+            if (!string.IsNullOrWhiteSpace(metallicImageFilePath)) material.WithChannelTexture("Metallic", 0, baseColorImageFilePath);
+            if (!string.IsNullOrWhiteSpace(roughtnessImageFilePath)) material.WithChannelTexture("Roughness", 0, baseColorImageFilePath);
+
+            material.FindChannel("BaseColor").SetFactor(baseColorFactor);
+            material.FindChannel("Metallic").SetFactor(metallicFactor);
+            material.FindChannel("Roughness").SetFactor(roughnessFactor);
+
+            return material;
+        }
+
         /// <summary>
         /// Initializes this <see cref="Material"/> instance with PBR Specular Glossiness attributes.
         /// </summary>

+ 39 - 0
src/SharpGLTF.Toolkit/Schema2/MeshExtensions.cs

@@ -9,6 +9,45 @@ namespace SharpGLTF.Schema2
 
     public static partial class Toolkit
     {
+        public static Mesh CreateMesh<TVertex>(this ModelRoot root, string name, Geometry.InterleavedMeshBuilder<TVertex, Material> meshBuilder)
+            where TVertex : struct
+        {
+            return root.CreateMesh<TVertex, Material>(name, meshBuilder, k => k);
+        }
+
+        public static Mesh CreateMesh<TVertex, TMaterial>(this ModelRoot root, string name, Geometry.InterleavedMeshBuilder<TVertex, TMaterial> meshBuilder, Func<TMaterial,Material> materialEvaluator)
+            where TVertex : struct
+        {
+            var dstMesh = root.CreateMesh(name);
+
+            // create vertex accessors
+            var vertexAccessors = root.CreateInterleavedVertexAccessors(meshBuilder.Vertices);
+
+            foreach (var mkey in meshBuilder.Materials)
+            {
+                var indices = meshBuilder.GetIndices(mkey);
+
+                // create index buffer
+                var ibytes = new Byte[4 * indices.Count];
+                var ibuffer = root.UseBufferView(new ArraySegment<byte>(ibytes), 0, BufferMode.ELEMENT_ARRAY_BUFFER);
+
+                var indicesAccessor = root
+                    .CreateAccessor("Indices");
+
+                indicesAccessor.SetIndexData(ibuffer, 0, indices);
+
+                // create mesh primitive
+                var prim = dstMesh.CreatePrimitive();
+                foreach (var va in vertexAccessors) prim.SetVertexAccessor(va.Key, va.Value);
+                prim.SetIndexAccessor(indicesAccessor);
+                prim.DrawPrimitiveType = PrimitiveType.TRIANGLES;
+
+                prim.Material = materialEvaluator(mkey);
+            }
+
+            return dstMesh;
+        }
+
         public static MeshPrimitive WithVertexAccessors<TVertex>(this MeshPrimitive primitive, IReadOnlyList<TVertex> vertices)
         {
             var accessors = primitive.LogicalParent.LogicalParent.CreateInterleavedVertexAccessors(vertices);

+ 5 - 0
src/SharpGLTF/Schema2/gltf.Materials.cs

@@ -150,6 +150,11 @@ namespace SharpGLTF.Schema2
 
         public void SetFactor(Vector4 value) { _FactorSetter?.Invoke(value); }
 
+        public void SetFactor(float value)
+        {
+            SetFactor(new Vector4(1, 1, 1, value));
+        }
+
         public void SetTexture(
             int texSet,
             Image texImg,

+ 2 - 2
tests/SharpGLTF.Tests/Geometry/CreateMeshTests.cs

@@ -61,8 +61,8 @@ namespace SharpGLTF.Geometry
             var rnode = scene.CreateNode("main scene");
 
             var material = model.CreateMaterial("DefaultMaterial")
-                .WithDefault(new Vector4(1, 0, 0, 1));
-            material.DoubleSided = true;            
+                .WithDefault(new Vector4(1, 0, 0, 1))
+                .WithDoubleSide(true);
 
             rnode.Mesh = model.CreateMesh();
 

+ 23 - 33
tests/SharpGLTF.Tests/Schema2/Authoring/CreateModelTests.cs

@@ -104,8 +104,9 @@ namespace SharpGLTF.Schema2.Authoring
             // create node
             var rnode = scene.CreateNode("Triangle Node");            
             // create material
-            var material = model.CreateMaterial("Default").WithDefault(new Vector4(0, 1, 0, 1));
-            material.DoubleSided = true;
+            var material = model.CreateMaterial("Default")
+                .WithDefault(new Vector4(0, 1, 0, 1))
+                .WithDoubleSide(true);
 
             // create mesh
             var rmesh = rnode.Mesh = model.CreateMesh("Triangle Mesh");
@@ -147,10 +148,8 @@ namespace SharpGLTF.Schema2.Authoring
             var rmesh = rnode.Mesh = model.CreateMesh("Triangle Mesh");
 
             var material = model.CreateMaterial("Default")
-                .WithPBRMetallicRoughness();
-
-            material.DoubleSided = true;
-            material.FindChannel("BaseColor").SetTexture(0, model.UseImageWithFile(imagePath));
+                .WithPBRMetallicRoughness(Vector4.One, imagePath)
+                .WithDoubleSide(true);                
 
             // define the triangle positions
             var positions = new[]
@@ -197,9 +196,7 @@ namespace SharpGLTF.Schema2.Authoring
             // setup a lambda function that creates a material for a given color
             Material createMaterialForColor(Vector4 color)
             {
-                var material = model.CreateMaterial().WithDefault(color);
-                material.DoubleSided = true;
-                return material;
+                return model.CreateMaterial().WithDefault(color).WithDoubleSide(true);
             };
 
             // fill our node with the mesh
@@ -255,19 +252,16 @@ namespace SharpGLTF.Schema2.Authoring
             meshBuilder.AddPolygon(new Vector4(1, 1, 1, 1), v1, v2, v3, v4);
 
             var model = ModelRoot.CreateModel();
-            var scene = model.UseScene("Default");
-            var rnode = scene.CreateNode("RootNode");
 
             // setup a lambda function that creates a material for a given color
             Material createMaterialForColor(Vector4 color)
             {
-                var material = model.CreateMaterial().WithDefault(color);
-                material.DoubleSided = true;
-                return material;
+                return model.CreateMaterial().WithDefault(color).WithDoubleSide(true);
             };
 
-            // fill our node with the mesh
-            meshBuilder.CopyToNode(rnode, createMaterialForColor);
+            model
+                .UseScene("Default")
+                .CreateNode("RootNode").WithMesh( model.CreateMesh("mesh",meshBuilder, createMaterialForColor));
 
             model.AttachToCurrentTest("result.glb");
             model.AttachToCurrentTest("result.gltf");
@@ -277,7 +271,7 @@ namespace SharpGLTF.Schema2.Authoring
         public void CreateAnimatedMeshBuilderScene()
         {
             TestContext.CurrentContext.AttachShowDirLink();
-            TestContext.CurrentContext.AttachGltfValidatorLink();           
+            TestContext.CurrentContext.AttachGltfValidatorLink();
 
             // create animation sequence with 4 frames
             var keyframes = new Dictionary<Single, Vector3>()
@@ -288,11 +282,7 @@ namespace SharpGLTF.Schema2.Authoring
                 [4] = new Vector3(0, 0, 0),
             };
 
-            var model = ModelRoot.CreateModel();
-            var scene = model.UseScene("Default");
-            var rnode = scene.CreateNode("RootNode").WithTranslationAnimation("track1", keyframes);            
-
-            // create mesh
+            // create a mesh
             var meshBuilder = new InterleavedMeshBuilder<STATICVERTEX, Vector4>();
 
             var v1 = new STATICVERTEX(-10, 10, 0, -10, 10, 15);
@@ -301,16 +291,19 @@ namespace SharpGLTF.Schema2.Authoring
             var v4 = new STATICVERTEX(-10, -10, 0, -10, -10, 15);
             meshBuilder.AddPolygon(new Vector4(1, 1, 1, 1), v1, v2, v3, v4);
 
+            // create the gltf model
+            var model = ModelRoot.CreateModel();
+
             // setup a lambda function that creates a material for a given color
             Material createMaterialForColor(Vector4 color)
             {
-                var material = model.CreateMaterial().WithDefault(color);
-                material.DoubleSided = true;
-                return material;
-            };
+                return model.CreateMaterial().WithDefault(color).WithDoubleSide(true);
+            };            
 
-            // fill our node with the mesh
-            meshBuilder.CopyToNode(rnode, createMaterialForColor);
+            model.UseScene("Default")
+                .CreateNode("RootNode")
+                .WithTranslationAnimation("track1", keyframes)
+                .WithMesh(model.CreateMesh("mesh", meshBuilder, createMaterialForColor));
 
             model.AttachToCurrentTest("result.glb");
             model.AttachToCurrentTest("result.gltf");
@@ -380,13 +373,10 @@ namespace SharpGLTF.Schema2.Authoring
             // setup a lambda function that creates a material for a given color
             Material createMaterialForColor(Vector4 color)
             {
-                var material = model.CreateMaterial().WithDefault(color);
-                material.DoubleSided = true;
-                return material;
+                return model.CreateMaterial().WithDefault(color).WithDoubleSide(true);
             };
 
-            // fill our node with the mesh
-            meshBuilder.CopyToNode(snode, createMaterialForColor);
+            snode.WithMesh(model.CreateMesh("mesh", meshBuilder, createMaterialForColor));
 
             model.AttachToCurrentTest("result.glb");
             model.AttachToCurrentTest("result.gltf");