Smuggler/Importer.cs

103 lines
4.0 KiB
C#

using System.Collections.Generic;
using System.IO;
using System.Numerics;
using Microsoft.Xna.Framework.Graphics;
namespace Smuggler
{
public static class Importer
{
public static Model ImportGLTF(GraphicsDevice graphicsDevice, Stream stream)
{
var sharpModel = SharpGLTF.Schema2.ModelRoot.ReadGLB(stream);
var meshes = new List<Mesh>();
foreach (var mesh in sharpModel.LogicalMeshes)
{
var meshParts = new List<MeshPart>();
foreach (var primitive in mesh.Primitives)
{
var positionAccessor = primitive.GetVertexAccessor("POSITION").AsVector3Array();
var normalAccessor = primitive.GetVertexAccessor("NORMAL").AsVector3Array();
var texcoordAccessor = primitive.GetVertexAccessor("TEXCOORD_0").AsVector2Array();
var indexAccessor = primitive.GetIndexAccessor().AsIndicesArray();
var positions = new Vector3[positionAccessor.Count];
var normals = new Vector3[normalAccessor.Count];
var texcoords = new Vector2[texcoordAccessor.Count];
var triangles = new List<Triangle>();
for (int i = 0; i < positions.Length; i++)
{
var position = positionAccessor[i];
positions[i] = new Vector3(-position.X, -position.Z, position.Y);
}
for (int i = 0; i < normals.Length; i++)
{
var normal = normalAccessor[i];
normals[i] = -new Vector3(normal.X, normal.Z, normal.Y);
}
foreach (var (a, b, c) in primitive.GetTriangleIndices())
{
triangles.Add(new Triangle(a, b, c));
}
var vertexBuffer = new VertexBuffer(
graphicsDevice,
typeof(VertexPositionNormalTexture),
positions.Length,
BufferUsage.WriteOnly
);
var indexBuffer = new IndexBuffer(
graphicsDevice,
IndexElementSize.ThirtyTwoBits,
indexAccessor.Count,
BufferUsage.WriteOnly
);
var vertices = new VertexPositionNormalTexture[primitive.IndexAccessor.Count];
var indices = new uint[primitive.IndexAccessor.Count];
var indexCounter = 0;
foreach (var index in primitive.GetIndices())
{
var position = positions[index];
var normal = normals[index];
var texcoord = texcoords[index];
indices[indexCounter] = index;
vertices[index] = new VertexPositionNormalTexture(
new Microsoft.Xna.Framework.Vector3(position.X, position.Y, position.Z),
new Microsoft.Xna.Framework.Vector3(normal.X, normal.Y, normal.Z),
new Microsoft.Xna.Framework.Vector2(texcoord.X, texcoord.Y)
);
indexCounter++;
}
indexBuffer.SetData(indices);
vertexBuffer.SetData(vertices);
meshParts.Add(
new MeshPart(
vertexBuffer,
indexBuffer,
triangles.ToArray(),
new BasicEffect(graphicsDevice)
)
);
}
meshes.Add(new Mesh(meshParts.ToArray()));
}
return new Model(meshes.ToArray());
}
}
}