using System.Collections.Generic; using System.IO; using Microsoft.Xna.Framework; 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(); foreach (var mesh in sharpModel.LogicalMeshes) { var meshParts = new List(); 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(); 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 Vector3(position.X, position.Y, position.Z), new Vector3(normal.X, normal.Y, normal.Z), new Vector2(texcoord.X, texcoord.Y) ); indexCounter++; } indexBuffer.SetData(indices); vertexBuffer.SetData(vertices); meshParts.Add( new MeshPart( vertexBuffer, indexBuffer, positions, triangles.ToArray(), new BasicEffect(graphicsDevice) ) ); } meshes.Add(new Mesh(meshParts.ToArray())); } return new Model(meshes.ToArray()); } } }