103 lines
4.0 KiB
C#
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());
|
||
|
}
|
||
|
}
|
||
|
}
|