Files
doom-dm/Engine/Asset/Mesh/Loader/StlMeshLoader.cs
2024-12-04 22:35:04 +03:00

66 lines
2.3 KiB
C#

using System.Globalization;
using OpenTK.Mathematics;
namespace Engine.Asset.Mesh.Loader;
public class StlMeshLoader : IMeshLoader
{
private static readonly StlMeshLoader 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 currentNormal = new Vector3();
var index = 0u;
using var reader = new StreamReader(path);
while (reader.ReadLine() is { } line)
{
line = line.Trim();
if (string.IsNullOrWhiteSpace(line) || line.StartsWith("solid") || line.StartsWith("outer loop") ||
line.StartsWith("endloop"))
continue;
if (line.StartsWith("endsolid"))
break;
var parts = line.Split(' ', StringSplitOptions.RemoveEmptyEntries);
switch (parts[0])
{
case "facet" when parts[1] == "normal" && parameters.HasFlag(MeshLoaderParameters.LoadNormals):
currentNormal = new Vector3(
float.Parse(parts[2], CultureInfo.InvariantCulture),
float.Parse(parts[3], CultureInfo.InvariantCulture),
float.Parse(parts[4], CultureInfo.InvariantCulture)
);
break;
case "vertex":
{
var vertex = new Vector3(
float.Parse(parts[1], CultureInfo.InvariantCulture),
float.Parse(parts[2], CultureInfo.InvariantCulture),
float.Parse(parts[3], CultureInfo.InvariantCulture)
);
mesh.VerticesInternal.Add(new Mesh.Vertex
{
Position = vertex,
Normal = currentNormal
});
mesh.IndicesInternal.Add(index++);
break;
}
}
}
if (parameters.HasFlag(MeshLoaderParameters.Optimize))
mesh = IMeshLoader.Optimize(mesh);
return mesh;
}
}