Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //This code has been released into the public domain
- using System;
- using System.IO;
- using System.Collections.Generic;
- using OpenTK.Math;
- using System.Drawing;
- using PlatformLib;
- public class ObjMeshLoader
- {
- public static StreamReader[] LoadMeshes(string fileName) {
- StreamReader mreader = new StreamReader(PlatformLib.Platform.openFile(fileName));
- MemoryStream current = null;
- List<MemoryStream> mstreams = new List<MemoryStream>();
- StreamWriter mwriter = null;
- if(!mreader.ReadLine().Contains("#")) {
- mreader.BaseStream.Close();
- throw new Exception("Invalid header");
- }
- while(!mreader.EndOfStream) {
- string cmd = mreader.ReadLine();
- string line = cmd;
- line = line.Trim(splitCharacters);
- line = line.Replace(" ", " ");
- string[] parameters = line.Split(splitCharacters);
- if(parameters[0] == "mtllib") {
- loadMaterials(parameters[1]);
- }
- if(parameters[0] == "o") {
- if(mwriter!=null) {
- mwriter.Flush();
- current.Position = 0;
- }
- current = new MemoryStream();
- mwriter = new StreamWriter(current);
- mwriter.WriteLine(parameters[1]);
- mstreams.Add(current);
- } else {
- if(mwriter!=null) {
- mwriter.WriteLine(cmd);
- mwriter.Flush();
- }
- }
- }
- mwriter.Flush();
- current.Position = 0;
- List<StreamReader> readers = new List<StreamReader>();
- foreach(MemoryStream e in mstreams) {
- e.Position = 0;
- StreamReader sreader = new StreamReader(e);
- readers.Add(sreader);
- }
- return readers.ToArray();
- }
- public static bool Load(ObjMesh mesh, string fileName)
- {
- try
- {
- using (StreamReader streamReader = new StreamReader(Platform.openFile(fileName)))
- {
- Load(mesh, streamReader);
- streamReader.Close();
- return true;
- }
- }
- catch { return false; }
- }
- public static bool Load2(ObjMesh mesh, StreamReader streamReader, ObjMesh prevmesh)
- {
- if(prevmesh !=null) {
- //mesh.Vertices = prevmesh.Vertices;
- }
- try
- {
- //streamReader.BaseStream.Position = 0;
- Load(mesh, streamReader);
- streamReader.Close();
- #if DEBUG
- Console.WriteLine("Loaded "+mesh.Triangles.Length.ToString()+" triangles and"+mesh.Quads.Length.ToString()+" quadrilaterals parsed, with a grand total of "+mesh.Vertices.Length.ToString()+" vertices.");
- #endif
- return true;
- }
- catch(Exception er) { Console.WriteLine(er);return false; }
- }
- static char[] splitCharacters = new char[] { ' ' };
- static List<Vector3> vertices;
- static List<Vector3> normals;
- static List<Vector2> texCoords;
- static Dictionary<ObjMesh.ObjVertex, int> objVerticesIndexDictionary;
- static List<ObjMesh.ObjVertex> objVertices;
- static List<ObjMesh.ObjTriangle> objTriangles;
- static List<ObjMesh.ObjQuad> objQuads;
- static Dictionary<string,Bitmap> materials = new Dictionary<string, Bitmap>();
- static void loadMaterials(string path) {
- StreamReader mreader = new StreamReader(Platform.openFile(path));
- string current = "";
- bool isfound = false;
- while(!mreader.EndOfStream) {
- string line = mreader.ReadLine();
- line = line.Trim(splitCharacters);
- line = line.Replace(" ", " ");
- string[] parameters = line.Split(splitCharacters);
- if(parameters[0] == "newmtl") {
- if(materials.ContainsKey(parameters[1])) {
- isfound = true;
- } else {
- current = parameters[1];
- }
- }
- if(parameters[0] == "map_Kd") {
- if(!isfound) {
- string filename = "";
- for(int i = 1;i<parameters.Length;i++) {
- filename+=parameters[i];
- }
- string searcher = "\\"+"\\";
- filename.Replace(searcher,"\\");
- Bitmap mymap = new Bitmap(filename);
- materials.Add(current,mymap);
- isfound = false;
- }
- }
- }
- }
- static float parsefloat(string val) {
- return Convert.ToSingle(val);
- }
- int remaining = 0;
- static string GetLine(string text, ref int pos) {
- string retval = text.Substring(pos,text.IndexOf(Environment.NewLine,pos));
- pos = text.IndexOf(Environment.NewLine,pos);
- return retval;
- }
- static void Load(ObjMesh mesh, StreamReader textReader)
- {
- //try {
- //vertices = null;
- //objVertices = null;
- if(vertices == null) {
- vertices = new List<Vector3>();
- }
- if(normals == null) {
- normals = new List<Vector3>();
- }
- if(texCoords == null) {
- texCoords = new List<Vector2>();
- }
- if(objVerticesIndexDictionary == null) {
- objVerticesIndexDictionary = new Dictionary<ObjMesh.ObjVertex, int>();
- }
- if(objVertices == null) {
- objVertices = new List<ObjMesh.ObjVertex>();
- }
- objTriangles = new List<ObjMesh.ObjTriangle>();
- objQuads = new List<ObjMesh.ObjQuad>();
- mesh.vertexPositionOffset = vertices.Count;
- string line;
- string alltext = textReader.ReadToEnd();
- int pos = 0;
- while ((line = GetLine(alltext,pos)) != null)
- {
- if(line.Length<2) {
- break;
- }
- //line = line.Trim(splitCharacters);
- //line = line.Replace(" ", " ");
- string[] parameters = line.Split(splitCharacters);
- switch (parameters[0])
- {
- case "usemtl":
- //Material specification
- try {
- mesh.Material = materials[parameters[1]];
- }catch(KeyNotFoundException) {
- Console.WriteLine("WARNING: Texture parse failure: "+parameters[1]);
- }
- break;
- case "p": // Point
- break;
- case "v": // Vertex
- float x = parsefloat(parameters[1]);
- float y = parsefloat(parameters[2]);
- float z = parsefloat(parameters[3]);
- vertices.Add(new Vector3(x, y, z));
- break;
- case "vt": // TexCoord
- float u = parsefloat(parameters[1]);
- float v = parsefloat(parameters[2]);
- texCoords.Add(new Vector2(u, v));
- break;
- case "vn": // Normal
- float nx = parsefloat(parameters[1]);
- float ny = parsefloat(parameters[2]);
- float nz = parsefloat(parameters[3]);
- normals.Add(new Vector3(nx, ny, nz));
- break;
- case "f":
- switch (parameters.Length)
- {
- case 4:
- ObjMesh.ObjTriangle objTriangle = new ObjMesh.ObjTriangle();
- objTriangle.Index0 = ParseFaceParameter(parameters[1]);
- objTriangle.Index1 = ParseFaceParameter(parameters[2]);
- objTriangle.Index2 = ParseFaceParameter(parameters[3]);
- objTriangles.Add(objTriangle);
- break;
- case 5:
- ObjMesh.ObjQuad objQuad = new ObjMesh.ObjQuad();
- objQuad.Index0 = ParseFaceParameter(parameters[1]);
- objQuad.Index1 = ParseFaceParameter(parameters[2]);
- objQuad.Index2 = ParseFaceParameter(parameters[3]);
- objQuad.Index3 = ParseFaceParameter(parameters[4]);
- objQuads.Add(objQuad);
- break;
- }
- break;
- }
- }
- //}catch(Exception er) {
- // Console.WriteLine(er);
- // Console.WriteLine("Successfully recovered. Bounds/Collision checking may fail though");
- //}
- mesh.Vertices = objVertices.ToArray();
- mesh.Triangles = objTriangles.ToArray();
- mesh.Quads = objQuads.ToArray();
- textReader.BaseStream.Close();
- }
- public static void Clear() {
- objVerticesIndexDictionary = null;
- vertices = null;
- normals = null;
- texCoords = null;
- objVertices = null;
- objTriangles = null;
- objQuads = null;
- }
- static char[] faceParamaterSplitter = new char[] { '/' };
- static int ParseFaceParameter(string faceParameter)
- {
- Vector3 vertex = new Vector3();
- Vector2 texCoord = new Vector2();
- Vector3 normal = new Vector3();
- string[] parameters = faceParameter.Split(faceParamaterSplitter);
- int vertexIndex = Convert.ToInt32(parameters[0]);
- if( vertexIndex < 0 ) vertexIndex = vertices.Count + vertexIndex;
- else vertexIndex = vertexIndex -1;
- //Hmm. This seems to be broken.
- try {
- vertex = vertices[vertexIndex];
- }catch(Exception) {
- throw new Exception("Vertex recognition failure at "+vertexIndex.ToString());
- }
- if (parameters.Length > 1)
- {
- int texCoordIndex = Convert.ToInt32(parameters[1]);
- if (texCoordIndex < 0) texCoordIndex = texCoords.Count + texCoordIndex;
- else texCoordIndex = texCoordIndex - 1;
- try {
- texCoord = texCoords[texCoordIndex];
- }catch(Exception) {
- Console.WriteLine("ERR: Vertex "+vertexIndex+" not found. ");
- throw new DllNotFoundException(vertexIndex.ToString());
- }
- }
- if (parameters.Length > 2)
- {
- int normalIndex = Convert.ToInt32(parameters[2]);
- if (normalIndex < 0) normalIndex = normals.Count + normalIndex;
- else normalIndex = normalIndex - 1;
- normal = normals[normalIndex];
- }
- return FindOrAddObjVertex(ref vertex, ref texCoord, ref normal);
- }
- static int FindOrAddObjVertex(ref Vector3 vertex, ref Vector2 texCoord, ref Vector3 normal)
- {
- ObjMesh.ObjVertex newObjVertex = new ObjMesh.ObjVertex();
- newObjVertex.Vertex = vertex;
- newObjVertex.TexCoord = texCoord;
- newObjVertex.Normal = normal;
- int index;
- if (objVerticesIndexDictionary.TryGetValue(newObjVertex, out index))
- {
- return index;
- }
- else
- {
- objVertices.Add(newObjVertex);
- objVerticesIndexDictionary[newObjVertex] = objVertices.Count - 1;
- return objVertices.Count - 1;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement