- Main Page
- Packages
- Classes
- Files

- File List
- File Members

# D:/guillaume/guillara/3D/DXGfx/Backup/DXGfxLib/ObjectFromObj.cs

Go to the documentation of this file.

    00001 //BSD License
    00002 //DXGfx® - http://www.eteractions.com
    00003 //Copyright (c) 2005
    00004 //by Guillaume Randon
    00005 //Permission is hereby granted, free of charge, to any person obtaining a copy of this software
    00006 //and associated documentation files (the "Software"), to deal in the Software without restriction,
    00007 //including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
    00008 //and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
    00009 //subject to the following conditions:
    00010 //The above copyright notice and this permission notice shall be included in all copies or substantial
    00011 //portions of the Software.
    00012 //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
    00013 //INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
    00014 //AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    00015 //DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    00016 //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    00017 using System;
    00018 using System.Collections;
    00019 using System.Collections.Generic;
    00020 using System.Text;
    00021 using Microsoft.DirectX;
    00022 using Microsoft.DirectX.Direct3D;
    00023 using Microsoft.Samples.DirectX.UtilityToolkit;
    00024 using System.Drawing;
    00025 using System.IO;
    00026
    00027 namespace DXGfxLib
    00028 {
    00032     public struct MaterialFromObj
    00033     {
    00034         public string name;
    00035
    00036         public Vector3 vAmbient;
    00037         public Vector3 vDiffuse;
    00038         public Vector3 vSpecular;
    00039
    00040         public int nShininess;
    00041         public float fAlpha;
    00042
    00043         public bool bSpecular;
    00044
    00045         public string strTexture;
    00046         public Texture texture;
    00047     }
    00048
    00054     public class ObjectFromObj : MeshObject
    00055     {
    00059         private int numFaces = 0;
    00063         private int numIndices = 0;
    00067         private bool weHaveNormals = false;
    00071         private Material defaultMat;
    00072
    00076         private List<MaterialFromObj> materials = null;
    00077
    00081         public ObjectFromObj()
    00082         {
    00083             materials = new List<MaterialFromObj>();
    00084             // Default material
    00085             defaultMat = new Material();
    00086             defaultMat.Ambient = Color.Aqua;
    00087             defaultMat.Diffuse = Color.Azure;
    00088             defaultMat.Emissive = Color.Blue;
    00089             defaultMat.Specular = Color.Brown;
    00090         }
    00091
    00097         public void Load(Device d3ddevice, string wavefrontObjFile)
    00098         {
    00099             // Load our file
    00100             string meshFile = Utility.FindMediaFile(wavefrontObjFile);
    00101             string mtlFile = "";
    00102
    00103             // Store the current folder, then switch to the folder where the media was found
    00104             string currentFolder = System.IO.Directory.GetCurrentDirectory();
    00105             System.IO.Directory.SetCurrentDirectory(new System.IO.FileInfo(meshFile).Directory.FullName);
    00106
    00107             List<Int16> indices = new List<Int16>();
    00108             List<Vector2> texCoords = new List<Vector2>();
    00109             List<Vector3> normals = new List<Vector3>();
    00110             List<int> attributes = new List<int>();
    00111             List<CustomVertex.PositionNormalTextured> vertices = new List<CustomVertex.PositionNormalTextured>();
    00112
    00113             int currSubset = 0;
    00114
    00115             string line;
    00116
    00117             //Pass the file path and file name to the StreamReader constructor
    00118             StreamReader sr = new StreamReader(meshFile);
    00119
    00120                         //Read the first line of text
    00121                         line = sr.ReadLine();
    00122
    00123                         //Continue to read until you reach end of file
    00124                         while (line != null)
    00125                         {
    00126                 if(line.StartsWith("#"))
    00127                 {
    00128                     // Nothing to read, these are comments.
    00129                 }
    00130                 else if(line.StartsWith("vt"))
    00131                 {
    00132                     // Vertext texcoord.
    00133                     string tmp = line.Substring(3);
    00134
    00135                     string[] values = FilteredSplit(tmp, null);
    00136
    00137                     texCoords.Add(new Vector2(float.Parse(values[0]),
    00138                                                 float.Parse(values[1])));
    00139                 }
    00140                 else if(line.StartsWith("vn"))
    00141                 {
    00142                     // Normals
    00143                     string tmp = line.Substring(3);
    00144
    00145                     string[] values = FilteredSplit(tmp, null);
    00146
    00147                     normals.Add(new Vector3(float.Parse(values[0]),
    00148                                                 float.Parse(values[1]),
    00149                                                 float.Parse(values[2])));
    00150                 }
    00151                 else if (line.StartsWith("v"))
    00152                 {
    00153                     // Positions.
    00154                     string tmp = line.Substring(2);
    00155
    00156                     string[] values = FilteredSplit(tmp, null);
    00157
    00158                     CustomVertex.PositionNormalTextured vertex = new CustomVertex.PositionNormalTextured();
    00159                     vertex.Position = new Vector3(float.Parse(values[0]),
    00160                                                 float.Parse(values[1]),
    00161                                                 float.Parse(values[2]));
    00162                     vertices.Add(vertex);
    00163                 }
    00164                 else if(line.StartsWith("f"))
    00165                 {
    00166                     // Face
    00167                     int iPosition, iTexCoord, iNormal;
    00168                     iPosition = iTexCoord = iNormal = 0;
    00169                     CustomVertex.PositionNormalTextured vertex;
    00170
    00171                     string tmp = line.Substring(2);
    00172                     string[] values = FilteredSplit(tmp, null);
    00173                     if (values.Length == 3)
    00174                     {
    00175                         for (int i = 0; i < 3; i++)
    00176                         {
    00177                             string[] indexes = values[i].Split('/');
    00178
    00179                             iPosition = int.Parse(indexes[0]);
    00180                             vertex = vertices[iPosition - 1];
    00181
    00182                             indices.Add((Int16)(iPosition - 1));
    00183                             numIndices++;
    00184
    00185                             if (indexes.Length > 1)
    00186                             {
    00187                                 iTexCoord = int.Parse(indexes[1]);
    00188                                 vertex.Tu = texCoords[iTexCoord - 1].X;
    00189                                 vertex.Tv = texCoords[iTexCoord - 1].Y;
    00190
    00191                                 if (indexes.Length > 2)
    00192                                 {
    00193                                     weHaveNormals = true;
    00194                                     iNormal = int.Parse(indexes[2]);
    00195                                     vertex.Nx = normals[iNormal - 1].X;
    00196                                     vertex.Ny = normals[iNormal - 1].Y;
    00197                                     vertex.Nz = normals[iNormal - 1].Z;
    00198                                 }
    00199                             }
    00200                         }
    00201                         numFaces++;
    00202
    00203                         attributes.Add(currSubset);
    00204                     }
    00205                     if (values.Length == 4)
    00206                     {
    00207                         for (int i = 0; i < 4; i++)
    00208                         {
    00209                             string[] indexes = values[i].Split('/');
    00210
    00211                             iPosition = int.Parse(indexes[0]);
    00212                             vertex = vertices[iPosition - 1];
    00213
    00214                             if (i == 3)
    00215                             {
    00216                                 indices.Add(indices[indices.Count - 3]);
    00217                                 indices.Add(indices[indices.Count - 1]);
    00218                                 indices.Add((Int16)(iPosition - 1));
    00219                                 numIndices = +3;
    00220                                 numFaces++;
    00221                                 attributes.Add(currSubset);
    00222                             }
    00223                             else
    00224                             {
    00225                                 indices.Add((Int16)(iPosition - 1));
    00226                                 numIndices++;
    00227                             }
    00228                             if (indexes.Length > 1)
    00229                             {
    00230                                 iTexCoord = int.Parse(indexes[1]);
    00231                                 vertex.Tu = texCoords[iTexCoord - 1].X;
    00232                                 vertex.Tv = texCoords[iTexCoord - 1].Y;
    00233
    00234                                 if (indexes.Length > 2)
    00235                                 {
    00236                                     weHaveNormals = true;
    00237                                     iNormal = int.Parse(indexes[2]);
    00238                                     vertex.Nx = normals[iNormal - 1].X;
    00239                                     vertex.Ny = normals[iNormal - 1].Y;
    00240                                     vertex.Nz = normals[iNormal - 1].Z;
    00241                                 }
    00242                             }
    00243                         }
    00244                         numFaces++;
    00245
    00246                         attributes.Add(currSubset);
    00247                     }
    00248                 }
    00249                 else if(line.StartsWith("mtllib"))
    00250                 {
    00251                     mtlFile = line.Substring(7);
    00252
    00253                     // Then load it now so that we have our materials ready
    00254                     LoadMtl(d3ddevice, mtlFile);
    00255                 }
    00256                 else if(line.StartsWith("usemtl"))
    00257                 {
    00258                     bool found = false;
    00259
    00260                     string matName = line.Substring(7);
    00261
    00262                     for (int i = 0; i < materials.Count; i++)
    00263                     {
    00264                         if (matName.Equals(materials[i].name))
    00265                         {
    00266                             found = true;
    00267                             currSubset = i;
    00268                         }
    00269                     }
    00270
    00271                     if (!found)
    00272                     {
    00273                         throw new Exception("Materials are already loaded so we should have it!");
    00274                     }
    00275                 }
    00276
    00277                                 //Read the next line
    00278                                 line = sr.ReadLine();
    00279                         }
    00280
    00281                         //close the file
    00282                         sr.Close();
    00283
    00284             Mesh ourMesh = new Mesh(numFaces, vertices.Count, MeshFlags.Managed, CustomVertex.PositionNormalTextured.Format,
    00285                 d3ddevice);
    00286
    00287             GraphicsStream dstVertices = ourMesh.LockVertexBuffer(LockFlags.NoSystemLock);
    00288             dstVertices.Write(vertices.ToArray());
    00289             ourMesh.UnlockVertexBuffer();
    00290
    00291             GraphicsStream dstIndices = ourMesh.LockIndexBuffer(LockFlags.NoSystemLock);
    00292             dstIndices.Write(indices.ToArray());
    00293             ourMesh.UnlockIndexBuffer();
    00294
    00295             int[] dstAttributes = ourMesh.LockAttributeBufferArray(LockFlags.NoSystemLock);
    00296             attributes.CopyTo(dstAttributes);
    00297             ourMesh.UnlockAttributeBuffer();
    00298
    00299             if (!weHaveNormals)
    00300             {
    00301                 ourMesh.ComputeNormals();
    00302             }
    00303
    00304
    00305             base.Attach(ourMesh);
    00306
    00307             // Now revert to the folder we were in initially
    00308             System.IO.Directory.SetCurrentDirectory(currentFolder);
    00309         }
    00310
    00316         public void LoadMtl(Device d3ddevice, string file)
    00317         {
    00318             MaterialFromObj currentMaterial = new MaterialFromObj();
    00319             bool first = true;
    00320
    00321             //Pass the file path and file name to the StreamReader constructor
    00322             StreamReader sr = new StreamReader(file);
    00323
    00324             //Read the first line of text
    00325             string line = sr.ReadLine();
    00326
    00327             //Continue to read until you reach end of file
    00328             while (line != null)
    00329             {
    00330                 if (line.StartsWith("#"))
    00331                 {
    00332                     // Nothing to read, these are comments.
    00333                 }
    00334                 else if (line.StartsWith("newmtl"))
    00335                 {
    00336                     if (!first)
    00337                     {
    00338                         materials.Add(currentMaterial);
    00339                         currentMaterial = new MaterialFromObj();
    00340                     }
    00341                     first = false;
    00342                     currentMaterial.name = line.Substring(7);
    00343                 }
    00344                 else if (line.StartsWith("Ka"))
    00345                 {
    00346                     string tmp = line.Substring(3);
    00347
    00348                     string[] values = FilteredSplit(tmp, null);
    00349
    00350
    00351                     currentMaterial.vAmbient = new Vector3(float.Parse(values[0]),
    00352                                                 float.Parse(values[1]),
    00353                                                 float.Parse(values[2]));
    00354                 }
    00355                 else if (line.StartsWith("Kd"))
    00356                 {
    00357                     string tmp = line.Substring(3);
    00358
    00359                     string[] values = FilteredSplit(tmp, null);
    00360
    00361                     currentMaterial.vDiffuse = new Vector3(float.Parse(values[0]),
    00362                             float.Parse(values[1]),
    00363                             float.Parse(values[2]));
    00364                 }
    00365
    00366                 else if (line.StartsWith("Ks"))
    00367                 {
    00368                     string tmp = line.Substring(3);
    00369
    00370                     string[] values = FilteredSplit(tmp, null);
    00371
    00372                     currentMaterial.vSpecular = new Vector3(float.Parse(values[0]),
    00373                             float.Parse(values[1]),
    00374                             float.Parse(values[2]));
    00375                 }
    00376                 else if (line.StartsWith("map_Kd"))
    00377                 {
    00378                     string tmp = line.Substring(7);
    00379
    00380                     //currentMaterial.texture = ResourceCache.GetGlobalInstance().CreateTextureFromFile(d3ddevice, tmp);
    00381
    00382                 }
    00383
    00384                 //Read the next line
    00385                 line = sr.ReadLine();
    00386             }
    00387             materials.Add(currentMaterial);
    00388
    00389             //close the file
    00390             sr.Close();
    00391         }
    00392
    00397         public override void Draw(Device d3ddevice)
    00398         {
    00399             d3ddevice.SetTransform(TransformType.World, worldMat);
    00400             d3ddevice.Material = defaultMat;
    00401             for (int i = 0; i < materials.Count; i++)
    00402             {
    00403                 d3ddevice.SetTexture(0, materials[i].texture);
    00404                 originalMesh.DrawSubset(i);
    00405             }
    00406         }
    00407
    00414         public string[] FilteredSplit(string strIn, char[] separator)
    00415         {
    00416             string[] valuesUnfiltered = strIn.Split(separator);
    00417
    00418             // Sometime if we have a white space at the beginning of the string, split
    00419             // will remove an empty string. Let's remove that.
    00420             List<string> listOfValues = new List<string>();
    00421             foreach (string str in valuesUnfiltered)
    00422             {
    00423                 if (str != "")
    00424                 {
    00425                     listOfValues.Add(str);
    00426                 }
    00427             }
    00428             string[] values = listOfValues.ToArray();
    00429
    00430             return values;
    00431         }
    00432     }
    00433 }