Model Structure #1
101
Importer.cs
101
Importer.cs
|
@ -7,18 +7,18 @@ namespace Smuggler
|
||||||
{
|
{
|
||||||
public static class Importer
|
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 sharpModel = SharpGLTF.Schema2.ModelRoot.ReadGLB(stream);
|
||||||
var vertexType = InferVertexType(sharpModel);
|
var vertexType = InferVertexType(sharpModel);
|
||||||
|
|
||||||
if (vertexType == null) { return null; }
|
if (vertexType == null) { return null; }
|
||||||
|
|
||||||
var meshes = new List<Mesh>();
|
var meshes = new List<MeshData>();
|
||||||
|
|
||||||
foreach (var mesh in sharpModel.LogicalMeshes)
|
foreach (var mesh in sharpModel.LogicalMeshes)
|
||||||
{
|
{
|
||||||
var meshParts = new List<MeshPart>();
|
var meshParts = new List<MeshPartData>();
|
||||||
|
|
||||||
foreach (var primitive in mesh.Primitives)
|
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());
|
var model = new ModelData(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +98,7 @@ namespace Smuggler
|
||||||
return null;
|
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 indices = Indices(primitive);
|
||||||
var positions = Positions(primitive);
|
var positions = Positions(primitive);
|
||||||
|
@ -145,19 +137,66 @@ namespace Smuggler
|
||||||
ImportVertexPositionTexture(primitive, vertexBuffer, indices, positions);
|
ImportVertexPositionTexture(primitive, vertexBuffer, indices, positions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: We need a new Effect subclass to support some GLTF features */
|
var meshPartData = new MeshPartData(
|
||||||
|
|
||||||
var effect = new BasicEffect(graphicsDevice);
|
|
||||||
effect.EnableDefaultLighting();
|
|
||||||
effect.PreferPerPixelLighting = true;
|
|
||||||
|
|
||||||
return new MeshPart(
|
|
||||||
vertexBuffer,
|
vertexBuffer,
|
||||||
indexBuffer,
|
indexBuffer,
|
||||||
positions,
|
positions,
|
||||||
triangles,
|
triangles
|
||||||
effect
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
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 */
|
/* Attribute Getters */
|
||||||
|
@ -198,7 +237,7 @@ namespace Smuggler
|
||||||
for (int i = 0; i < normals.Length; i++)
|
for (int i = 0; i < normals.Length; i++)
|
||||||
{
|
{
|
||||||
var normal = normalAccessor[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;
|
return normals;
|
||||||
|
@ -221,7 +260,7 @@ namespace Smuggler
|
||||||
private static Triangle[] Triangles(SharpGLTF.Schema2.MeshPrimitive primitive)
|
private static Triangle[] Triangles(SharpGLTF.Schema2.MeshPrimitive primitive)
|
||||||
{
|
{
|
||||||
var triangles = new List<Triangle>();
|
var triangles = new List<Triangle>();
|
||||||
|
|
||||||
foreach (var (a, b, c) in primitive.GetTriangleIndices())
|
foreach (var (a, b, c) in primitive.GetTriangleIndices())
|
||||||
{
|
{
|
||||||
triangles.Add(new Triangle(a, b, c));
|
triangles.Add(new Triangle(a, b, c));
|
||||||
|
@ -250,7 +289,8 @@ namespace Smuggler
|
||||||
VertexBuffer vertexBuffer,
|
VertexBuffer vertexBuffer,
|
||||||
uint[] indices,
|
uint[] indices,
|
||||||
Vector3[] positions
|
Vector3[] positions
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
var colors = Colors(primitive);
|
var colors = Colors(primitive);
|
||||||
|
|
||||||
var vertices = new VertexPositionColor[positions.Length];
|
var vertices = new VertexPositionColor[positions.Length];
|
||||||
|
@ -274,7 +314,8 @@ namespace Smuggler
|
||||||
VertexBuffer vertexBuffer,
|
VertexBuffer vertexBuffer,
|
||||||
uint[] indices,
|
uint[] indices,
|
||||||
Vector3[] positions
|
Vector3[] positions
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
var colors = Colors(primitive);
|
var colors = Colors(primitive);
|
||||||
var texcoords = TexCoords(primitive);
|
var texcoords = TexCoords(primitive);
|
||||||
|
|
||||||
|
@ -301,7 +342,8 @@ namespace Smuggler
|
||||||
VertexBuffer vertexBuffer,
|
VertexBuffer vertexBuffer,
|
||||||
uint[] indices,
|
uint[] indices,
|
||||||
Vector3[] positions
|
Vector3[] positions
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
var normals = Normals(primitive);
|
var normals = Normals(primitive);
|
||||||
var texcoords = TexCoords(primitive);
|
var texcoords = TexCoords(primitive);
|
||||||
|
|
||||||
|
@ -328,7 +370,8 @@ namespace Smuggler
|
||||||
VertexBuffer vertexBuffer,
|
VertexBuffer vertexBuffer,
|
||||||
uint[] indices,
|
uint[] indices,
|
||||||
Vector3[] positions
|
Vector3[] positions
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
var texcoords = TexCoords(primitive);
|
var texcoords = TexCoords(primitive);
|
||||||
|
|
||||||
var vertices = new VertexPositionTexture[positions.Length];
|
var vertices = new VertexPositionTexture[positions.Length];
|
||||||
|
|
23
Mesh.cs
23
Mesh.cs
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
namespace Smuggler
|
||||||
|
{
|
||||||
|
public class MeshData
|
||||||
|
{
|
||||||
|
public MeshPartData[] MeshParts { get; }
|
||||||
|
|
||||||
|
public MeshData(MeshPartData[] meshParts)
|
||||||
|
{
|
||||||
|
MeshParts = meshParts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
47
MeshPart.cs
47
MeshPart.cs
|
@ -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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
Model.cs
36
Model.cs
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,7 @@
|
||||||
<Copyright>Cassandra Lugo and Evan Hemsley 2020</Copyright>
|
<Copyright>Cassandra Lugo and Evan Hemsley 2020</Copyright>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<AssemblyName>Smuggler</AssemblyName>
|
<AssemblyName>Smuggler</AssemblyName>
|
||||||
|
<Platforms>AnyCPU;x86</Platforms>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -15,7 +16,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\FNA\FNA.Core.csproj"/>
|
<ProjectReference Include="..\FNA\FNA.Core.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
Loading…
Reference in New Issue