90 lines
3.3 KiB
C#
90 lines
3.3 KiB
C#
using System.Globalization;
|
|
using OpenTK.Mathematics;
|
|
|
|
namespace Engine.Asset.Mesh.Loader;
|
|
|
|
public class ObjMeshLoader : IMeshLoader
|
|
{
|
|
private static readonly ObjMeshLoader Instance = new();
|
|
|
|
public static Mesh Load(string path, MeshLoaderParameters parameters = MeshLoaderParameters.Default)
|
|
=> Instance.LoadMesh(path, parameters);
|
|
|
|
public Mesh LoadMesh(string path, MeshLoaderParameters parameters = MeshLoaderParameters.Default)
|
|
{
|
|
var mesh = new Mesh();
|
|
|
|
var tempVertices = new List<Vector3>();
|
|
var tempNormals = new List<Vector3>();
|
|
var tempUVs = new List<Vector2>();
|
|
var index = 0u;
|
|
|
|
var loadNormals = parameters.HasFlag(MeshLoaderParameters.LoadNormals);
|
|
var loadUVs = parameters.HasFlag(MeshLoaderParameters.LoadUVs);
|
|
|
|
using var reader = new StreamReader(path);
|
|
while (reader.ReadLine() is { } line)
|
|
{
|
|
var parts = line.Split(' ', StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
if (parts.Length == 0 || parts[0].StartsWith('#'))
|
|
continue;
|
|
|
|
switch (parts[0])
|
|
{
|
|
case "v":
|
|
tempVertices.Add(new Vector3(
|
|
float.Parse(parts[1], CultureInfo.InvariantCulture),
|
|
float.Parse(parts[2], CultureInfo.InvariantCulture),
|
|
float.Parse(parts[3], CultureInfo.InvariantCulture)
|
|
));
|
|
break;
|
|
|
|
case "vt" when loadUVs:
|
|
tempUVs.Add(new Vector2(
|
|
float.Parse(parts[1], CultureInfo.InvariantCulture),
|
|
float.Parse(parts[2], CultureInfo.InvariantCulture)
|
|
));
|
|
break;
|
|
|
|
case "vn" when loadNormals:
|
|
tempNormals.Add(new Vector3(
|
|
float.Parse(parts[1], CultureInfo.InvariantCulture),
|
|
float.Parse(parts[2], CultureInfo.InvariantCulture),
|
|
float.Parse(parts[3], CultureInfo.InvariantCulture)
|
|
));
|
|
break;
|
|
|
|
case "f":
|
|
for (var i = 1; i <= 3; i++)
|
|
{
|
|
var faceComponents = parts[i].Split('/');
|
|
var meshVertex = new Mesh.Vertex
|
|
{
|
|
Position = tempVertices[int.Parse(faceComponents[0]) - 1]
|
|
};
|
|
|
|
if (loadUVs && faceComponents.Length > 1 && faceComponents[1] != "")
|
|
{
|
|
meshVertex.Uv = tempUVs[int.Parse(faceComponents[1]) - 1];
|
|
}
|
|
|
|
if (loadNormals && faceComponents.Length > 2 && faceComponents[2] != "")
|
|
{
|
|
meshVertex.Normal = tempNormals[int.Parse(faceComponents[2]) - 1];
|
|
}
|
|
|
|
mesh.VerticesInternal.Add(meshVertex);
|
|
mesh.IndicesInternal.Add(index++);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (parameters.HasFlag(MeshLoaderParameters.Optimize))
|
|
mesh = IMeshLoader.Optimize(mesh);
|
|
|
|
return mesh;
|
|
}
|
|
} |