//================needed classes or structs =================
public struct Vertex
{
private Vector3 position;
private Vector3 normal;
private Vector2 textureCoords;
public Vertex(Vector3 position, Vector3 normal, Vector2 textureCoords )
{
this.normal = normal;
this.position = position;
this.textureCoords = textureCoords;
}
public static int Size => (3 + 3 + 2) * 4;
}
public class OBJLoader
{
public static RawModel LoadObjModel(String name)
{
string path = @"Models\" + name + ".obj";
List<Vertex> Vertices = new List<Vertex>();
List<string> VertexString = new List<string>();
List<int> Indices = new List<int>();
List<Vector3> Positions = new List<Vector3>();
List<Vector2> TextureCoordinates = new List<Vector2>();
List<Vector3> Normals = new List<Vector3>();
List<string> Lines = new List<string>();
string Line;
System.IO.StreamReader file = new System.IO.StreamReader(path);
while ((Line = file.ReadLine()) != null)
{
Lines.Add(Line);
}
file.Close();
string FacePattern = "^f .*$";
string PositionPattern = "^v .*$";
string TextureCorrdinatesPattern = "^vt .*$";
string NormalPattern = "^vn .*$";
string FloatingPointPattern = @"[-+]?[0-9]*\.?[0-9]+";
string VertexFacePattern = @"[0-9]*/[0-9]*/[0-9]*";
string NumberPatten = @"\d+";
MatchCollection FloatingPoints = null;
MatchCollection FaceVertices = null;
Lines.Where(L => Regex.IsMatch(L, PositionPattern)).ToList().ForEach(L =>
{
FloatingPoints = Regex.Matches(L, FloatingPointPattern);
Positions.Add(new Vector3(float.Parse(FloatingPoints[0].ToString()), float.Parse(FloatingPoints[1].ToString()), float.Parse(FloatingPoints[2].ToString())));
});
Lines.Where(L => Regex.IsMatch(L, NormalPattern)).ToList().ForEach(L =>
{
FloatingPoints = Regex.Matches(L, FloatingPointPattern);
Normals.Add(new Vector3(float.Parse(FloatingPoints[0].ToString()), float.Parse(FloatingPoints[1].ToString()), float.Parse(FloatingPoints[2].ToString())));
});
Lines.Where(L => Regex.IsMatch(L, TextureCorrdinatesPattern)).ToList().ForEach(L =>
{
FloatingPoints = Regex.Matches(L, FloatingPointPattern);
TextureCoordinates.Add(new Vector2(float.Parse(FloatingPoints[0].ToString()), float.Parse(FloatingPoints[1].ToString())));
});
Lines.Where(L => Regex.IsMatch(L, FacePattern)).ToList().ForEach(L =>
{
FaceVertices = Regex.Matches(L, VertexFacePattern);
VertexString.Add(FaceVertices[0].ToString());
VertexString.Add(FaceVertices[1].ToString());
VertexString.Add(FaceVertices[2].ToString());
});
List<string> AllVerticesStrings = new List<string>();
AllVerticesStrings = VertexString;
VertexString = VertexString.Distinct().ToList();
MatchCollection indices = null;
VertexString.ForEach(Vertex =>
{
indices = Regex.Matches(Vertex, NumberPatten);
Vertices.Add(new VertexData.Vertex(Positions[int.Parse(indices[0].ToString()) - 1], Normals[int.Parse(indices[2].ToString()) - 1], TextureCoordinates[int.Parse(indices[1].ToString()) - 1]));
});
Dictionary<string, int> IndexKeyDictionary = new Dictionary<string, int>();
for (int i = 0; i < VertexString.Count; i++)
{
IndexKeyDictionary.Add(VertexString[i], i);
}
AllVerticesStrings.ToList().ForEach(Key => Indices.Add(IndexKeyDictionary[Key]));
return new RawModel(Vertices.ToArray(), Indices.ToArray());
}
}