66 lines
2.3 KiB
C#
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;
|
|
}
|
|
} |