Advertisement
Guest User

Untitled

a guest
Apr 23rd, 2011
309
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.98 KB | None | 0 0
  1. //This code has been released into the public domain
  2.  
  3. using System;
  4.  
  5. using System.IO;
  6.  
  7. using System.Collections.Generic;
  8.  
  9. using OpenTK.Math;
  10.  
  11. using System.Drawing;
  12.  
  13. using PlatformLib;
  14.  
  15.  
  16.  
  17. public class ObjMeshLoader
  18.  
  19. {
  20.  
  21.     public static StreamReader[] LoadMeshes(string fileName) {
  22.  
  23.         StreamReader mreader = new StreamReader(PlatformLib.Platform.openFile(fileName));
  24.  
  25.         MemoryStream current = null;
  26.  
  27.         List<MemoryStream> mstreams = new List<MemoryStream>();
  28.  
  29.         StreamWriter mwriter = null;
  30.  
  31.         if(!mreader.ReadLine().Contains("#")) {
  32.  
  33.             mreader.BaseStream.Close();
  34.  
  35.         throw new Exception("Invalid header");
  36.  
  37.         }
  38.  
  39.         while(!mreader.EndOfStream) {
  40.  
  41.         string cmd = mreader.ReadLine();
  42.  
  43.                 string line = cmd;
  44.  
  45.         line = line.Trim(splitCharacters);
  46.  
  47.             line = line.Replace("  ", " ");
  48.  
  49.  
  50.  
  51.             string[] parameters = line.Split(splitCharacters);
  52.  
  53.             if(parameters[0] == "mtllib") {
  54.  
  55.             loadMaterials(parameters[1]);
  56.  
  57.             }
  58.  
  59.             if(parameters[0] == "o") {
  60.  
  61.             if(mwriter!=null) {
  62.  
  63.                 mwriter.Flush();
  64.  
  65.                     current.Position = 0;
  66.  
  67.                 }
  68.  
  69.                 current = new MemoryStream();
  70.  
  71.                 mwriter = new StreamWriter(current);
  72.  
  73.                 mwriter.WriteLine(parameters[1]);
  74.  
  75.                 mstreams.Add(current);
  76.  
  77.             } else {
  78.  
  79.                 if(mwriter!=null) {
  80.  
  81.             mwriter.WriteLine(cmd);
  82.  
  83.                     mwriter.Flush();
  84.  
  85.                 }
  86.  
  87.             }
  88.  
  89.         }
  90.  
  91.         mwriter.Flush();
  92.  
  93.         current.Position = 0;
  94.  
  95.         List<StreamReader> readers = new List<StreamReader>();
  96.  
  97.         foreach(MemoryStream e in mstreams) {
  98.  
  99.             e.Position = 0;
  100.  
  101.         StreamReader sreader = new StreamReader(e);
  102.  
  103.             readers.Add(sreader);
  104.  
  105.         }
  106.  
  107.         return readers.ToArray();
  108.  
  109.     }
  110.  
  111.     public static bool Load(ObjMesh mesh, string fileName)
  112.  
  113.     {
  114.  
  115.         try
  116.  
  117.         {
  118.  
  119.             using (StreamReader streamReader = new StreamReader(Platform.openFile(fileName)))
  120.  
  121.             {
  122.  
  123.                 Load(mesh, streamReader);
  124.  
  125.                 streamReader.Close();
  126.  
  127.                 return true;
  128.  
  129.             }
  130.  
  131.         }
  132.  
  133.         catch { return false; }
  134.  
  135.     }
  136.  
  137.     public static bool Load2(ObjMesh mesh, StreamReader streamReader, ObjMesh prevmesh)
  138.  
  139.     {
  140.  
  141.         if(prevmesh !=null) {
  142.  
  143.         //mesh.Vertices = prevmesh.Vertices;
  144.  
  145.            
  146.  
  147.         }
  148.  
  149.         try
  150.  
  151.         {
  152.  
  153.         //streamReader.BaseStream.Position = 0;
  154.  
  155.                 Load(mesh, streamReader);
  156.  
  157.                 streamReader.Close();
  158.  
  159. #if DEBUG
  160.  
  161.             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.");
  162.  
  163. #endif
  164.  
  165.                 return true;
  166.  
  167.            
  168.  
  169.         }
  170.  
  171.         catch(Exception er) { Console.WriteLine(er);return false; }
  172.  
  173.     }
  174.  
  175.     static char[] splitCharacters = new char[] { ' ' };
  176.  
  177.  
  178.  
  179.     static List<Vector3> vertices;
  180.  
  181.     static List<Vector3> normals;
  182.  
  183.     static List<Vector2> texCoords;
  184.  
  185.     static Dictionary<ObjMesh.ObjVertex, int> objVerticesIndexDictionary;
  186.  
  187.     static List<ObjMesh.ObjVertex> objVertices;
  188.  
  189.     static List<ObjMesh.ObjTriangle> objTriangles;
  190.  
  191.     static List<ObjMesh.ObjQuad> objQuads;
  192.  
  193.  
  194.  
  195.     static Dictionary<string,Bitmap> materials = new Dictionary<string, Bitmap>();
  196.  
  197.     static void loadMaterials(string path) {
  198.  
  199.     StreamReader mreader = new StreamReader(Platform.openFile(path));
  200.  
  201.         string current = "";
  202.  
  203.         bool isfound = false;
  204.  
  205.         while(!mreader.EndOfStream) {
  206.  
  207.             string line = mreader.ReadLine();
  208.  
  209.         line = line.Trim(splitCharacters);
  210.  
  211.             line = line.Replace("  ", " ");
  212.  
  213.  
  214.  
  215.             string[] parameters = line.Split(splitCharacters);
  216.  
  217.             if(parameters[0] == "newmtl") {
  218.  
  219.             if(materials.ContainsKey(parameters[1])) {
  220.  
  221.                 isfound = true;
  222.  
  223.                 } else {
  224.  
  225.                 current = parameters[1];
  226.  
  227.                 }
  228.  
  229.             }
  230.  
  231.             if(parameters[0] == "map_Kd") {
  232.  
  233.             if(!isfound) {
  234.  
  235.                     string filename = "";
  236.  
  237.                     for(int i = 1;i<parameters.Length;i++) {
  238.  
  239.                     filename+=parameters[i];
  240.  
  241.                     }
  242.  
  243.                     string searcher = "\\"+"\\";
  244.  
  245.                     filename.Replace(searcher,"\\");
  246.  
  247.                 Bitmap mymap = new Bitmap(filename);
  248.  
  249.                 materials.Add(current,mymap);
  250.  
  251.                     isfound = false;
  252.  
  253.                 }
  254.  
  255.             }
  256.  
  257.         }
  258.  
  259.     }
  260.  
  261.     static float parsefloat(string val) {
  262.  
  263.     return Convert.ToSingle(val);
  264.  
  265.    
  266.  
  267.          
  268.  
  269.  
  270.  
  271.     }
  272.  
  273.    
  274.  
  275.     int remaining = 0;
  276.  
  277.    
  278.  
  279.     static string GetLine(string text, ref int pos) {
  280.  
  281.     string retval =  text.Substring(pos,text.IndexOf(Environment.NewLine,pos));
  282.  
  283.     pos = text.IndexOf(Environment.NewLine,pos);
  284.  
  285.         return retval;
  286.  
  287.     }
  288.  
  289.     static void Load(ObjMesh mesh, StreamReader textReader)
  290.  
  291.     {
  292.  
  293.        
  294.  
  295.         //try {
  296.  
  297.         //vertices = null;
  298.  
  299.             //objVertices = null;
  300.  
  301.             if(vertices == null) {
  302.  
  303.         vertices = new List<Vector3>();
  304.  
  305.             }
  306.  
  307.             if(normals == null) {
  308.  
  309.         normals = new List<Vector3>();
  310.  
  311.             }
  312.  
  313.             if(texCoords == null) {
  314.  
  315.         texCoords = new List<Vector2>();
  316.  
  317.             }
  318.  
  319.             if(objVerticesIndexDictionary == null) {
  320.  
  321.         objVerticesIndexDictionary = new Dictionary<ObjMesh.ObjVertex, int>();
  322.  
  323.             }
  324.  
  325.             if(objVertices == null) {
  326.  
  327.         objVertices = new List<ObjMesh.ObjVertex>();
  328.  
  329.             }
  330.  
  331.         objTriangles = new List<ObjMesh.ObjTriangle>();
  332.  
  333.         objQuads = new List<ObjMesh.ObjQuad>();
  334.  
  335.             mesh.vertexPositionOffset = vertices.Count;
  336.  
  337.         string line;
  338.  
  339.         string alltext = textReader.ReadToEnd();
  340.  
  341.         int pos = 0;
  342.  
  343.        
  344.  
  345.         while ((line = GetLine(alltext,pos)) != null)
  346.  
  347.         {
  348.  
  349.             if(line.Length<2) {
  350.  
  351.             break;
  352.  
  353.             }
  354.  
  355.             //line = line.Trim(splitCharacters);
  356.  
  357.             //line = line.Replace("  ", " ");
  358.  
  359.  
  360.  
  361.             string[] parameters = line.Split(splitCharacters);
  362.  
  363.  
  364.  
  365.             switch (parameters[0])
  366.  
  367.             {
  368.  
  369.                 case "usemtl":
  370.  
  371.                     //Material specification
  372.  
  373.                     try {
  374.  
  375.                     mesh.Material = materials[parameters[1]];
  376.  
  377.                     }catch(KeyNotFoundException) {
  378.  
  379.                     Console.WriteLine("WARNING: Texture parse failure: "+parameters[1]);
  380.  
  381.                     }
  382.  
  383.                     break;
  384.  
  385.                 case "p": // Point
  386.  
  387.                     break;
  388.  
  389.  
  390.  
  391.                 case "v": // Vertex
  392.  
  393.                     float x = parsefloat(parameters[1]);
  394.  
  395.                     float y = parsefloat(parameters[2]);
  396.  
  397.                     float z = parsefloat(parameters[3]);
  398.  
  399.                     vertices.Add(new Vector3(x, y, z));
  400.  
  401.                     break;
  402.  
  403.  
  404.  
  405.                 case "vt": // TexCoord
  406.  
  407.                     float u = parsefloat(parameters[1]);
  408.  
  409.                     float v = parsefloat(parameters[2]);
  410.  
  411.                     texCoords.Add(new Vector2(u, v));
  412.  
  413.                     break;
  414.  
  415.  
  416.  
  417.                 case "vn": // Normal
  418.  
  419.                     float nx = parsefloat(parameters[1]);
  420.  
  421.                     float ny = parsefloat(parameters[2]);
  422.  
  423.                     float nz = parsefloat(parameters[3]);
  424.  
  425.                     normals.Add(new Vector3(nx, ny, nz));
  426.  
  427.                     break;
  428.  
  429.  
  430.  
  431.                 case "f":
  432.  
  433.                     switch (parameters.Length)
  434.  
  435.                     {
  436.  
  437.                         case 4:
  438.  
  439.                             ObjMesh.ObjTriangle objTriangle = new ObjMesh.ObjTriangle();
  440.  
  441.                             objTriangle.Index0 = ParseFaceParameter(parameters[1]);
  442.  
  443.                             objTriangle.Index1 = ParseFaceParameter(parameters[2]);
  444.  
  445.                             objTriangle.Index2 = ParseFaceParameter(parameters[3]);
  446.  
  447.                             objTriangles.Add(objTriangle);
  448.  
  449.                             break;
  450.  
  451.  
  452.  
  453.                         case 5:
  454.  
  455.                             ObjMesh.ObjQuad objQuad = new ObjMesh.ObjQuad();
  456.  
  457.                             objQuad.Index0 = ParseFaceParameter(parameters[1]);
  458.  
  459.                             objQuad.Index1 = ParseFaceParameter(parameters[2]);
  460.  
  461.                             objQuad.Index2 = ParseFaceParameter(parameters[3]);
  462.  
  463.                             objQuad.Index3 = ParseFaceParameter(parameters[4]);
  464.  
  465.                             objQuads.Add(objQuad);
  466.  
  467.                             break;
  468.  
  469.                     }
  470.  
  471.                     break;
  472.  
  473.             }
  474.  
  475.            
  476.  
  477.             }
  478.  
  479.         //}catch(Exception er) {
  480.  
  481.         //  Console.WriteLine(er);
  482.  
  483.         //  Console.WriteLine("Successfully recovered. Bounds/Collision checking may fail though");
  484.  
  485.         //}
  486.  
  487.  
  488.  
  489.         mesh.Vertices = objVertices.ToArray();
  490.  
  491.         mesh.Triangles = objTriangles.ToArray();
  492.  
  493.         mesh.Quads = objQuads.ToArray();
  494.  
  495.         textReader.BaseStream.Close();
  496.  
  497.      
  498.  
  499.     }
  500.  
  501.     public static void Clear() {
  502.  
  503.           objVerticesIndexDictionary = null;
  504.  
  505.         vertices = null;
  506.  
  507.         normals = null;
  508.  
  509.         texCoords = null;
  510.  
  511.         objVertices = null;
  512.  
  513.         objTriangles = null;
  514.  
  515.         objQuads = null;
  516.  
  517.     }
  518.  
  519.     static char[] faceParamaterSplitter = new char[] { '/' };
  520.  
  521.     static int ParseFaceParameter(string faceParameter)
  522.  
  523.     {
  524.  
  525.         Vector3 vertex = new Vector3();
  526.  
  527.         Vector2 texCoord = new Vector2();
  528.  
  529.         Vector3 normal = new Vector3();
  530.  
  531.  
  532.  
  533.         string[] parameters = faceParameter.Split(faceParamaterSplitter);
  534.  
  535.  
  536.  
  537.         int vertexIndex = Convert.ToInt32(parameters[0]);
  538.  
  539.        
  540.  
  541.         if( vertexIndex < 0 ) vertexIndex = vertices.Count + vertexIndex;
  542.  
  543.         else vertexIndex = vertexIndex -1;
  544.  
  545.         //Hmm. This seems to be broken.
  546.  
  547.         try {
  548.  
  549.         vertex = vertices[vertexIndex];
  550.  
  551.         }catch(Exception) {
  552.  
  553.         throw new Exception("Vertex recognition failure at "+vertexIndex.ToString());
  554.  
  555.         }
  556.  
  557.         if (parameters.Length > 1)
  558.  
  559.         {
  560.  
  561.             int texCoordIndex = Convert.ToInt32(parameters[1]);
  562.  
  563.        
  564.  
  565.             if (texCoordIndex < 0) texCoordIndex = texCoords.Count + texCoordIndex;
  566.  
  567.             else texCoordIndex = texCoordIndex - 1;
  568.  
  569.         try {
  570.  
  571.             texCoord = texCoords[texCoordIndex];
  572.  
  573.                 }catch(Exception) {
  574.  
  575.         Console.WriteLine("ERR: Vertex "+vertexIndex+" not found. ");
  576.  
  577.             throw new DllNotFoundException(vertexIndex.ToString());
  578.  
  579.         }
  580.  
  581.            
  582.  
  583.         }
  584.  
  585.  
  586.  
  587.         if (parameters.Length > 2)
  588.  
  589.         {
  590.  
  591.             int normalIndex = Convert.ToInt32(parameters[2]);
  592.  
  593.        
  594.  
  595.             if (normalIndex < 0) normalIndex = normals.Count + normalIndex;
  596.  
  597.             else normalIndex = normalIndex - 1;
  598.  
  599.             normal = normals[normalIndex];
  600.  
  601.         }
  602.  
  603.  
  604.  
  605.         return FindOrAddObjVertex(ref vertex, ref texCoord, ref normal);
  606.  
  607.     }
  608.  
  609.     static int FindOrAddObjVertex(ref Vector3 vertex, ref Vector2 texCoord, ref Vector3 normal)
  610.  
  611.     {
  612.  
  613.         ObjMesh.ObjVertex newObjVertex = new ObjMesh.ObjVertex();
  614.  
  615.         newObjVertex.Vertex = vertex;
  616.  
  617.         newObjVertex.TexCoord = texCoord;
  618.  
  619.         newObjVertex.Normal = normal;
  620.  
  621.  
  622.  
  623.         int index;
  624.  
  625.         if (objVerticesIndexDictionary.TryGetValue(newObjVertex, out index))
  626.  
  627.         {
  628.  
  629.             return index;
  630.  
  631.         }
  632.  
  633.         else
  634.  
  635.         {
  636.  
  637.             objVertices.Add(newObjVertex);
  638.  
  639.             objVerticesIndexDictionary[newObjVertex] = objVertices.Count - 1;
  640.  
  641.             return objVertices.Count - 1;
  642.  
  643.         }
  644.  
  645.     }
  646.  
  647. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement