From 5a3858c0b72e6750e5d5aa947d7fbe76dc2ae8af Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Wed, 5 Aug 2020 20:51:03 +0000 Subject: [PATCH] Model Structure (#1) --- Importer.cs | 101 ++++++++++++++++++++++++++++++++++-------------- Mesh.cs | 23 ----------- MeshData.cs | 12 ++++++ MeshPart.cs | 47 ---------------------- MeshPartData.cs | 34 ++++++++++++++++ Model.cs | 36 ----------------- ModelData.cs | 15 +++++++ Smuggler.csproj | 5 ++- 8 files changed, 136 insertions(+), 137 deletions(-) delete mode 100644 Mesh.cs create mode 100644 MeshData.cs delete mode 100644 MeshPart.cs create mode 100644 MeshPartData.cs delete mode 100644 Model.cs create mode 100644 ModelData.cs diff --git a/Importer.cs b/Importer.cs index 1369802..f9d1622 100644 --- a/Importer.cs +++ b/Importer.cs @@ -7,18 +7,18 @@ namespace Smuggler { public static class Importer { - public static Model ImportGLB(GraphicsDevice graphicsDevice, Stream stream) + public static ModelData ImportGLB(GraphicsDevice graphicsDevice, Stream stream) { var sharpModel = SharpGLTF.Schema2.ModelRoot.ReadGLB(stream); var vertexType = InferVertexType(sharpModel); if (vertexType == null) { return null; } - var meshes = new List(); + var meshes = new List(); foreach (var mesh in sharpModel.LogicalMeshes) { - var meshParts = new List(); + var meshParts = new List(); foreach (var primitive in mesh.Primitives) { @@ -27,18 +27,10 @@ namespace Smuggler ); } - meshes.Add(new Mesh(meshParts.ToArray())); + meshes.Add(new MeshData(meshParts.ToArray())); } - var model = new Model(meshes.ToArray()); - - /* TODO: BasicEffect only supports one texture but GLTF supports several */ - - if (sharpModel.LogicalTextures.Count > 0) - { - var fnaTexture = Texture2D.FromStream(graphicsDevice, sharpModel.LogicalTextures[0].PrimaryImage.Content.Open()); - model.SetTexture(fnaTexture); - } + var model = new ModelData(meshes.ToArray()); return model; } @@ -106,7 +98,7 @@ namespace Smuggler return null; } - private static MeshPart ImportMeshPart(GraphicsDevice graphicsDevice, System.Type vertexType, SharpGLTF.Schema2.MeshPrimitive primitive) + private static MeshPartData ImportMeshPart(GraphicsDevice graphicsDevice, System.Type vertexType, SharpGLTF.Schema2.MeshPrimitive primitive) { var indices = Indices(primitive); var positions = Positions(primitive); @@ -145,19 +137,66 @@ namespace Smuggler ImportVertexPositionTexture(primitive, vertexBuffer, indices, positions); } - /* TODO: We need a new Effect subclass to support some GLTF features */ - - var effect = new BasicEffect(graphicsDevice); - effect.EnableDefaultLighting(); - effect.PreferPerPixelLighting = true; - - return new MeshPart( + var meshPartData = new MeshPartData( vertexBuffer, indexBuffer, positions, - triangles, - effect + triangles ); + + if (primitive.Material != null) + { + var normalChannel = primitive.Material.FindChannel("Normal"); + if (normalChannel.HasValue) + { + if (normalChannel.Value.Texture != null) + { + meshPartData.NormalTexture = Texture2D.FromStream( + graphicsDevice, + normalChannel.Value.Texture.PrimaryImage.Content.Open() + ); + } + } + + var albedoChannel = primitive.Material.FindChannel("BaseColor"); + if (albedoChannel.HasValue) + { + if (albedoChannel.Value.Texture != null) + { + meshPartData.AlbedoTexture = Texture2D.FromStream( + graphicsDevice, + albedoChannel.Value.Texture.PrimaryImage.Content.Open() + ); + } + + var parameter = albedoChannel.Value.Parameter; + + meshPartData.Albedo = new Vector3( + parameter.X, + parameter.Y, + parameter.Z + ); + } + + var metallicRoughnessChannel = primitive.Material.FindChannel("MetallicRoughness"); + if (metallicRoughnessChannel.HasValue) + { + if (metallicRoughnessChannel.Value.Texture != null) + { + meshPartData.MetallicRoughnessTexture = Texture2D.FromStream( + graphicsDevice, + metallicRoughnessChannel.Value.Texture.PrimaryImage.Content.Open() + ); + } + + var parameter = metallicRoughnessChannel.Value.Parameter; + + meshPartData.Metallic = parameter.X; + meshPartData.Roughness = parameter.Y; + } + } + + return meshPartData; } /* Attribute Getters */ @@ -198,7 +237,7 @@ namespace Smuggler for (int i = 0; i < normals.Length; i++) { var normal = normalAccessor[i]; - normals[i] = -new Vector3(normal.X, normal.Z, normal.Y); + normals[i] = new Vector3(-normal.X, -normal.Z, normal.Y); } return normals; @@ -221,7 +260,7 @@ namespace Smuggler private static Triangle[] Triangles(SharpGLTF.Schema2.MeshPrimitive primitive) { var triangles = new List(); - + foreach (var (a, b, c) in primitive.GetTriangleIndices()) { triangles.Add(new Triangle(a, b, c)); @@ -250,7 +289,8 @@ namespace Smuggler VertexBuffer vertexBuffer, uint[] indices, Vector3[] positions - ) { + ) + { var colors = Colors(primitive); var vertices = new VertexPositionColor[positions.Length]; @@ -274,7 +314,8 @@ namespace Smuggler VertexBuffer vertexBuffer, uint[] indices, Vector3[] positions - ) { + ) + { var colors = Colors(primitive); var texcoords = TexCoords(primitive); @@ -301,7 +342,8 @@ namespace Smuggler VertexBuffer vertexBuffer, uint[] indices, Vector3[] positions - ) { + ) + { var normals = Normals(primitive); var texcoords = TexCoords(primitive); @@ -328,7 +370,8 @@ namespace Smuggler VertexBuffer vertexBuffer, uint[] indices, Vector3[] positions - ) { + ) + { var texcoords = TexCoords(primitive); var vertices = new VertexPositionTexture[positions.Length]; diff --git a/Mesh.cs b/Mesh.cs deleted file mode 100644 index f8bd217..0000000 --- a/Mesh.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; - -namespace Smuggler -{ - public class Mesh - { - public MeshPart[] MeshParts { get; } - - public Mesh(MeshPart[] meshParts) - { - MeshParts = meshParts; - } - - public void Draw(GraphicsDevice graphicsDevice, Matrix world, Matrix view, Matrix projection) - { - foreach (var meshPart in MeshParts) - { - meshPart.Draw(graphicsDevice, world, view, projection); - } - } - } -} diff --git a/MeshData.cs b/MeshData.cs new file mode 100644 index 0000000..3c80670 --- /dev/null +++ b/MeshData.cs @@ -0,0 +1,12 @@ +namespace Smuggler +{ + public class MeshData + { + public MeshPartData[] MeshParts { get; } + + public MeshData(MeshPartData[] meshParts) + { + MeshParts = meshParts; + } + } +} diff --git a/MeshPart.cs b/MeshPart.cs deleted file mode 100644 index b68bfab..0000000 --- a/MeshPart.cs +++ /dev/null @@ -1,47 +0,0 @@ -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; - -namespace Smuggler -{ - public class MeshPart - { - public IndexBuffer IndexBuffer { get; } - public VertexBuffer VertexBuffer { get; } - public Triangle[] Triangles { get; } - public BasicEffect Effect { get; } - public Vector3[] Positions { get; } - - public MeshPart(VertexBuffer vertexBuffer, IndexBuffer indexBuffer, Vector3[] positions, Triangle[] triangles, BasicEffect effect) - { - VertexBuffer = vertexBuffer; - IndexBuffer = indexBuffer; - Positions = positions; - Triangles = triangles; - Effect = effect; - } - - public void Draw(GraphicsDevice graphicsDevice, Matrix world, Matrix view, Matrix projection) - { - graphicsDevice.SetVertexBuffer(VertexBuffer); - graphicsDevice.Indices = IndexBuffer; - - Effect.World = world; - Effect.View = view; - Effect.Projection = projection; - - foreach (var pass in Effect.CurrentTechnique.Passes) - { - pass.Apply(); - - graphicsDevice.DrawIndexedPrimitives( - PrimitiveType.TriangleList, - 0, - 0, - VertexBuffer.VertexCount, - 0, - Triangles.Length - ); - } - } - } -} diff --git a/MeshPartData.cs b/MeshPartData.cs new file mode 100644 index 0000000..2f935d3 --- /dev/null +++ b/MeshPartData.cs @@ -0,0 +1,34 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace Smuggler +{ + public class MeshPartData + { + public IndexBuffer IndexBuffer { get; } + public VertexBuffer VertexBuffer { get; } + public Triangle[] Triangles { get; } + public Vector3[] Positions { get; } + + public Texture2D AlbedoTexture { get; set; } = null; + public Texture2D NormalTexture { get; set; } = null; + public Texture2D MetallicRoughnessTexture { get; set; } = null; + + public Vector3 Albedo { get; set; } = Vector3.One; + public float Metallic { get; set; } = 0.5f; + public float Roughness { get; set; } = 0.5f; + + public MeshPartData( + VertexBuffer vertexBuffer, + IndexBuffer indexBuffer, + Vector3[] positions, + Triangle[] triangles + ) + { + VertexBuffer = vertexBuffer; + IndexBuffer = indexBuffer; + Positions = positions; + Triangles = triangles; + } + } +} diff --git a/Model.cs b/Model.cs deleted file mode 100644 index ed3ec25..0000000 --- a/Model.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; - -namespace Smuggler -{ - public class Model - { - public Mesh[] Meshes { get; } - public Texture2D[] Textures { get; } - - public Model(Mesh[] meshes) - { - Meshes = meshes; - } - - public void SetTexture(Texture2D texture) - { - foreach (var mesh in Meshes) - { - foreach (var meshPart in mesh.MeshParts) - { - meshPart.Effect.TextureEnabled = true; - meshPart.Effect.Texture = texture; - } - } - } - - public void Draw(GraphicsDevice graphicsDevice, Matrix world, Matrix view, Matrix projection) - { - foreach (var mesh in Meshes) - { - mesh.Draw(graphicsDevice, world, view, projection); - } - } - } -} diff --git a/ModelData.cs b/ModelData.cs new file mode 100644 index 0000000..3d1a03a --- /dev/null +++ b/ModelData.cs @@ -0,0 +1,15 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace Smuggler +{ + public class ModelData + { + public MeshData[] Meshes { get; } + + public ModelData(MeshData[] meshes) + { + Meshes = meshes; + } + } +} diff --git a/Smuggler.csproj b/Smuggler.csproj index fafb0a4..c9385e5 100644 --- a/Smuggler.csproj +++ b/Smuggler.csproj @@ -8,6 +8,7 @@ Cassandra Lugo and Evan Hemsley 2020 true Smuggler + AnyCPU;x86 @@ -15,7 +16,7 @@ - + - +