restructure importer to import different vertex types
parent
742c38ec7e
commit
e670bba1a6
377
Importer.cs
377
Importer.cs
|
@ -7,9 +7,306 @@ namespace Smuggler
|
||||||
{
|
{
|
||||||
public static class Importer
|
public static class Importer
|
||||||
{
|
{
|
||||||
public static Model ImportGLTF(GraphicsDevice graphicsDevice, Stream stream)
|
private static System.Type InferVertexType(SharpGLTF.Schema2.ModelRoot model)
|
||||||
|
{
|
||||||
|
bool hasColor = false;
|
||||||
|
bool hasNormal = false;
|
||||||
|
bool hasTexture = false;
|
||||||
|
|
||||||
|
if (model.LogicalMeshes.Count == 0) { return null; }
|
||||||
|
if (model.LogicalMeshes[0].Primitives.Count == 0) { return null; }
|
||||||
|
|
||||||
|
var samplePrimitive = model.LogicalMeshes[0].Primitives[0];
|
||||||
|
|
||||||
|
if (samplePrimitive.GetVertexAccessor("POSITION") == null)
|
||||||
|
{
|
||||||
|
System.Console.WriteLine("There is no Position attribute on this model's vertices. That seems weird!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (samplePrimitive.GetVertexAccessor("COLOR") != null)
|
||||||
|
{
|
||||||
|
hasColor = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (samplePrimitive.GetVertexAccessor("NORMAL") != null)
|
||||||
|
{
|
||||||
|
hasNormal = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (samplePrimitive.GetVertexAccessor("TEXCOORD_0") != null)
|
||||||
|
{
|
||||||
|
hasTexture = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasColor && hasNormal && hasTexture)
|
||||||
|
{
|
||||||
|
// FIXME: Implement VertexPositionColorNormalTexture
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasColor && hasTexture)
|
||||||
|
{
|
||||||
|
return typeof(VertexPositionColorTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasNormal && hasTexture)
|
||||||
|
{
|
||||||
|
return typeof(VertexPositionNormalTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasColor)
|
||||||
|
{
|
||||||
|
return typeof(VertexPositionColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasTexture)
|
||||||
|
{
|
||||||
|
return typeof(VertexPositionTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.Console.WriteLine("Could not infer vertex type");
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Vector3[] Positions(SharpGLTF.Schema2.MeshPrimitive primitive)
|
||||||
|
{
|
||||||
|
var positionAccessor = primitive.GetVertexAccessor("POSITION").AsVector3Array();
|
||||||
|
var positions = new Vector3[positionAccessor.Count];
|
||||||
|
|
||||||
|
for (int i = 0; i < positions.Length; i++)
|
||||||
|
{
|
||||||
|
var position = positionAccessor[i];
|
||||||
|
positions[i] = new Vector3(-position.X, -position.Z, position.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
return positions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Color[] Colors(SharpGLTF.Schema2.MeshPrimitive primitive)
|
||||||
|
{
|
||||||
|
var colorAccessor = primitive.GetVertexAccessor("COLOR").AsColorArray();
|
||||||
|
var colors = new Color[colorAccessor.Count];
|
||||||
|
|
||||||
|
for (int i = 0; i < colors.Length; i++)
|
||||||
|
{
|
||||||
|
var color = colorAccessor[i];
|
||||||
|
colors[i] = new Color(color.X, color.Y, color.Z, color.W);
|
||||||
|
}
|
||||||
|
|
||||||
|
return colors;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Vector3[] Normals(SharpGLTF.Schema2.MeshPrimitive primitive)
|
||||||
|
{
|
||||||
|
var normalAccessor = primitive.GetVertexAccessor("NORMAL").AsVector3Array();
|
||||||
|
var normals = new Vector3[normalAccessor.Count];
|
||||||
|
|
||||||
|
for (int i = 0; i < normals.Length; i++)
|
||||||
|
{
|
||||||
|
var normal = normalAccessor[i];
|
||||||
|
normals[i] = -new Vector3(normal.X, normal.Z, normal.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
return normals;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Vector2[] TexCoords(SharpGLTF.Schema2.MeshPrimitive primitive)
|
||||||
|
{
|
||||||
|
var texcoordAccessor = primitive.GetVertexAccessor("TEXCOORD_0").AsVector2Array();
|
||||||
|
var texcoords = new Vector2[texcoordAccessor.Count];
|
||||||
|
|
||||||
|
for (int i = 0; i < texcoords.Length; i++)
|
||||||
|
{
|
||||||
|
var texcoord = texcoordAccessor[i];
|
||||||
|
texcoords[i] = new Vector2(texcoord.X, texcoord.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
return texcoords;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Triangle[] Triangles(SharpGLTF.Schema2.MeshPrimitive primitive)
|
||||||
|
{
|
||||||
|
var triangles = new List<Triangle>();
|
||||||
|
|
||||||
|
foreach (var (a, b, c) in primitive.GetTriangleIndices())
|
||||||
|
{
|
||||||
|
triangles.Add(new Triangle(a, b, c));
|
||||||
|
}
|
||||||
|
|
||||||
|
return triangles.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint[] Indices(SharpGLTF.Schema2.MeshPrimitive primitive)
|
||||||
|
{
|
||||||
|
var indexAccessor = primitive.GetIndexAccessor().AsIndicesArray();
|
||||||
|
var indices = new uint[indexAccessor.Count];
|
||||||
|
|
||||||
|
for (int i = 0; i < indices.Length; i++)
|
||||||
|
{
|
||||||
|
indices[i] = indexAccessor[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return indices;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ImportVertexPositionColor(
|
||||||
|
SharpGLTF.Schema2.MeshPrimitive primitive,
|
||||||
|
VertexBuffer vertexBuffer,
|
||||||
|
uint[] indices,
|
||||||
|
Vector3[] positions
|
||||||
|
) {
|
||||||
|
var colors = Colors(primitive);
|
||||||
|
|
||||||
|
var vertices = new VertexPositionColor[positions.Length];
|
||||||
|
|
||||||
|
foreach (var index in indices)
|
||||||
|
{
|
||||||
|
var position = positions[index];
|
||||||
|
var color = colors[index];
|
||||||
|
|
||||||
|
vertices[index] = new VertexPositionColor(
|
||||||
|
position,
|
||||||
|
color
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
vertexBuffer.SetData(vertices);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ImportVertexPositionColorTexture(
|
||||||
|
SharpGLTF.Schema2.MeshPrimitive primitive,
|
||||||
|
VertexBuffer vertexBuffer,
|
||||||
|
uint[] indices,
|
||||||
|
Vector3[] positions
|
||||||
|
) {
|
||||||
|
var colors = Colors(primitive);
|
||||||
|
var texcoords = TexCoords(primitive);
|
||||||
|
|
||||||
|
var vertices = new VertexPositionColorTexture[positions.Length];
|
||||||
|
|
||||||
|
foreach (var index in indices)
|
||||||
|
{
|
||||||
|
var position = positions[index];
|
||||||
|
var color = colors[index];
|
||||||
|
var texcoord = texcoords[index];
|
||||||
|
|
||||||
|
vertices[index] = new VertexPositionColorTexture(
|
||||||
|
position,
|
||||||
|
color,
|
||||||
|
texcoord
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
vertexBuffer.SetData(vertices);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ImportVertexPositionNormalTexture(
|
||||||
|
SharpGLTF.Schema2.MeshPrimitive primitive,
|
||||||
|
VertexBuffer vertexBuffer,
|
||||||
|
uint[] indices,
|
||||||
|
Vector3[] positions
|
||||||
|
) {
|
||||||
|
var normals = Normals(primitive);
|
||||||
|
var texcoords = TexCoords(primitive);
|
||||||
|
|
||||||
|
var vertices = new VertexPositionNormalTexture[positions.Length];
|
||||||
|
|
||||||
|
foreach (var index in indices)
|
||||||
|
{
|
||||||
|
var position = positions[index];
|
||||||
|
var normal = normals[index];
|
||||||
|
var texcoord = texcoords[index];
|
||||||
|
|
||||||
|
vertices[index] = new VertexPositionNormalTexture(
|
||||||
|
position,
|
||||||
|
normal,
|
||||||
|
texcoord
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
vertexBuffer.SetData(vertices);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ImportVertexPositionTexture(
|
||||||
|
SharpGLTF.Schema2.MeshPrimitive primitive,
|
||||||
|
VertexBuffer vertexBuffer,
|
||||||
|
uint[] indices,
|
||||||
|
Vector3[] positions
|
||||||
|
) {
|
||||||
|
var texcoords = TexCoords(primitive);
|
||||||
|
|
||||||
|
var vertices = new VertexPositionTexture[positions.Length];
|
||||||
|
|
||||||
|
foreach (var index in indices)
|
||||||
|
{
|
||||||
|
var position = positions[index];
|
||||||
|
var texcoord = texcoords[index];
|
||||||
|
|
||||||
|
vertices[index] = new VertexPositionTexture(
|
||||||
|
position,
|
||||||
|
texcoord
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
vertexBuffer.SetData(vertices);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MeshPart ImportMeshPart(GraphicsDevice graphicsDevice, System.Type vertexType, SharpGLTF.Schema2.MeshPrimitive primitive)
|
||||||
|
{
|
||||||
|
var indices = Indices(primitive);
|
||||||
|
var positions = Positions(primitive);
|
||||||
|
var triangles = Triangles(primitive);
|
||||||
|
|
||||||
|
var vertexBuffer = new VertexBuffer(
|
||||||
|
graphicsDevice,
|
||||||
|
vertexType,
|
||||||
|
positions.Length,
|
||||||
|
BufferUsage.None
|
||||||
|
);
|
||||||
|
|
||||||
|
var indexBuffer = new IndexBuffer(
|
||||||
|
graphicsDevice,
|
||||||
|
IndexElementSize.ThirtyTwoBits,
|
||||||
|
indices.Length,
|
||||||
|
BufferUsage.None
|
||||||
|
);
|
||||||
|
|
||||||
|
indexBuffer.SetData(indices);
|
||||||
|
|
||||||
|
if (vertexType == typeof(VertexPositionColor))
|
||||||
|
{
|
||||||
|
ImportVertexPositionColor(primitive, vertexBuffer, indices, positions);
|
||||||
|
}
|
||||||
|
else if (vertexType == typeof(VertexPositionColorTexture))
|
||||||
|
{
|
||||||
|
ImportVertexPositionColorTexture(primitive, vertexBuffer, indices, positions);
|
||||||
|
}
|
||||||
|
else if (vertexType == typeof(VertexPositionNormalTexture))
|
||||||
|
{
|
||||||
|
ImportVertexPositionNormalTexture(primitive, vertexBuffer, indices, positions);
|
||||||
|
}
|
||||||
|
else if (vertexType == typeof(VertexPositionTexture))
|
||||||
|
{
|
||||||
|
ImportVertexPositionTexture(primitive, vertexBuffer, indices, positions);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MeshPart(
|
||||||
|
vertexBuffer,
|
||||||
|
indexBuffer,
|
||||||
|
positions,
|
||||||
|
triangles,
|
||||||
|
new BasicEffect(graphicsDevice)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Model ImportGLB(GraphicsDevice graphicsDevice, Stream stream)
|
||||||
{
|
{
|
||||||
var sharpModel = SharpGLTF.Schema2.ModelRoot.ReadGLB(stream);
|
var sharpModel = SharpGLTF.Schema2.ModelRoot.ReadGLB(stream);
|
||||||
|
var vertexType = InferVertexType(sharpModel);
|
||||||
|
|
||||||
|
if (vertexType == null) { return null; }
|
||||||
|
|
||||||
var meshes = new List<Mesh>();
|
var meshes = new List<Mesh>();
|
||||||
|
|
||||||
|
@ -19,84 +316,8 @@ namespace Smuggler
|
||||||
|
|
||||||
foreach (var primitive in mesh.Primitives)
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < texcoords.Length; i++)
|
|
||||||
{
|
|
||||||
var texcoord = texcoordAccessor[i];
|
|
||||||
texcoords[i] = new Vector2(texcoord.X, texcoord.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[positions.Length];
|
|
||||||
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(
|
meshParts.Add(
|
||||||
new MeshPart(
|
ImportMeshPart(graphicsDevice, vertexType, primitive)
|
||||||
vertexBuffer,
|
|
||||||
indexBuffer,
|
|
||||||
vertices,
|
|
||||||
triangles.ToArray(),
|
|
||||||
new BasicEffect(graphicsDevice)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,15 +7,15 @@ namespace Smuggler
|
||||||
{
|
{
|
||||||
public IndexBuffer IndexBuffer { get; }
|
public IndexBuffer IndexBuffer { get; }
|
||||||
public VertexBuffer VertexBuffer { get; }
|
public VertexBuffer VertexBuffer { get; }
|
||||||
public VertexPositionNormalTexture[] Vertices { get; } /* should we parameterize this by vertex type? */
|
|
||||||
public Triangle[] Triangles { get; }
|
public Triangle[] Triangles { get; }
|
||||||
public BasicEffect Effect { get; }
|
public BasicEffect Effect { get; }
|
||||||
|
public Vector3[] Positions { get; }
|
||||||
|
|
||||||
public MeshPart(VertexBuffer vertexBuffer, IndexBuffer indexBuffer, VertexPositionNormalTexture[] vertices, Triangle[] triangles, BasicEffect effect)
|
public MeshPart(VertexBuffer vertexBuffer, IndexBuffer indexBuffer, Vector3[] positions, Triangle[] triangles, BasicEffect effect)
|
||||||
{
|
{
|
||||||
VertexBuffer = vertexBuffer;
|
VertexBuffer = vertexBuffer;
|
||||||
IndexBuffer = indexBuffer;
|
IndexBuffer = indexBuffer;
|
||||||
Vertices = vertices;
|
Positions = positions;
|
||||||
Triangles = triangles;
|
Triangles = triangles;
|
||||||
Effect = effect;
|
Effect = effect;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue