public void LoadFromOBJ(string FilePath)
{
if (FilePath[FilePath.Length - 1] != '\\')
{
FilePath += "\\";
}
FileStream FS = new FileStream(FilePath + this.Name + ".mtl", FileMode.Open);
StreamReader SR = new StreamReader(FS);
List<string> MaterialNames = new List<string>();
string temps = string.Empty;
while (temps != null)
{
temps = SR.ReadLine();
if (temps == null)
{
break;
}
string[] split = temps.Split(' ');
if (split[0] == "newmtl")
{
if (MaterialNames.IndexOf(split[1]) == -1)
{
MaterialNames.Add(split[1]);
}
}
}
SR.Close();
FS.Close();
#region Bounding Box Fields
float minx = 0;
float maxx = 0;
float miny = 0;
float maxy = 0;
float minz = 0;
float maxz = 0;
float minu = 0;
float maxu = 0;
float minv = 0;
float maxv = 0;
#endregion
#region Read OBJ Files
for (int x = 0; x < this.BSPRawDataMetaChunks.Length; x++)
{
#region Fields
int verticecount = 0;
int facecount = 0;
List<Vector3> vertices = new List<Vector3>();
List<Vector3> normals = new List<Vector3>();
List<Vector2> uvs = new List<Vector2>();
List<List<int>> faces = new List<List<int>>();
List<List<int>> facesuv = new List<List<int>>();
List<List<int>> facesnormal = new List<List<int>>();
Hashtable Materials = new Hashtable();
int groupcount = 0;
#endregion
FS = new FileStream(FilePath + this.Name + "[" + x + "].obj", FileMode.Open);
SR = new StreamReader(FS);
#region ParseFile
do
{
temps = SR.ReadLine();
if (temps == null)
{
continue;
}
temps = temps.Replace(" ", " ");
string[] tempstrings = temps.Split(',', ' ');
switch (tempstrings[0])
{
#region Vertices
case "v":
Vector3 tempv = new Vector3();
tempv.X = float.Parse(tempstrings[1]);
tempv.Y = float.Parse(tempstrings[2]);
tempv.Z = float.Parse(tempstrings[3]);
if (tempv.X < minx)
{
minx = tempv.X;
}
if (tempv.X > maxx)
{
maxx = tempv.X;
}
if (tempv.Y < miny)
{
miny = tempv.Y;
}
if (tempv.Y > maxy)
{
maxy = tempv.Y;
}
if (tempv.Z < minz)
{
minz = tempv.Z;
}
if (tempv.Z > maxz)
{
maxz = tempv.Z;
}
vertices.Add(tempv);
verticecount++;
break;
#endregion
#region Normals
case "vn":
Vector3 tempvn = new Vector3();
tempvn.X = float.Parse(tempstrings[1]);
tempvn.Y = float.Parse(tempstrings[2]);
tempvn.Z = float.Parse(tempstrings[3]);
normals.Add(tempvn);
break;
#endregion
#region UVs
case "vt":
Vector2 tempv2 = new Vector2();
tempv2.X = float.Parse(tempstrings[1]);
tempv2.Y = float.Parse(tempstrings[2]);
if (tempv2.X < minu)
{
minu = tempv2.X;
}
if (tempv2.X > maxu)
{
maxu = tempv2.X;
}
if (tempv2.Y < minv)
{
minv = tempv2.Y;
}
if (tempv2.Y > maxv)
{
maxv = tempv2.Y;
}
uvs.Add(tempv2);
verticecount++;
break;
#endregion
#region Group
case "g":
if ((faces.Count == 0) || (faces[faces.Count - 1].Count > 0) ||
(facesuv[facesuv.Count - 1].Count > 0) || (facesnormal[facesnormal.Count - 1].Count > 0))
{
List<int> templist = new List<int>();
List<int> templist2 = new List<int>();
List<int> templist3 = new List<int>();
faces.Add(templist);
facesuv.Add(templist2);
facesnormal.Add(templist3);
groupcount++;
}
break;
#endregion
#region Faces
case "f":
string[] split1 = tempstrings[1].Split('/');
string[] split2 = tempstrings[2].Split('/');
string[] split3 = tempstrings[3].Split('/');
int temp1 = int.Parse(split1[0]);
int temp2 = int.Parse(split2[0]);
int temp3 = int.Parse(split3[0]);
temp1--;
temp2--;
temp3--;
faces[groupcount - 1].Add(temp1);
faces[groupcount - 1].Add(temp2);
faces[groupcount - 1].Add(temp3);
temp1 = int.Parse(split1[1]);
temp2 = int.Parse(split2[1]);
temp3 = int.Parse(split3[1]);
temp1--;
temp2--;
temp3--;
facesuv[groupcount - 1].Add(temp1);
facesuv[groupcount - 1].Add(temp2);
facesuv[groupcount - 1].Add(temp3);
temp1 = int.Parse(split1[2]);
temp2 = int.Parse(split2[2]);
temp3 = int.Parse(split3[2]);
temp1--;
temp2--;
temp3--;
facesnormal[groupcount - 1].Add(temp1);
facesnormal[groupcount - 1].Add(temp2);
facesnormal[groupcount - 1].Add(temp3);
facecount += 3;
break;
#endregion
#region Materials
case "usemtl":
Materials.Add(groupcount - 1, tempstrings[1]);
break;
#endregion
}
}
while (temps != null);
#endregion
SR.Close();
FS.Close();
int count = 0;
while (count < faces.Count)
{
start:
if (faces[count].Count == 0)
{
faces.RemoveAt(count);
facesuv.RemoveAt(count);
facesnormal.RemoveAt(count);
count = 0;
groupcount--;
goto start;
}
count++;
}
// Here we have all the vertices/textures/normals loaded into groups
/// vertices / uvs / normals as Vector3
/// faces / facesuv / facesnormal as pointers to the above
///
///
/// we need to output to (Vetcor3):
/// this.BSPRawDataMetaChunks[x].Vertices
/// this.BSPRawDataMetaChunks[x].UVs
/// this.BSPRawDataMetaChunks[x].Normals
///
Renderer temprender = new Renderer();
Panel fakepanel = new Panel();
temprender.CreateDevice(fakepanel);
List<List<short>> Faces = new List<List<short>>();
List<List<short>> Facesuv = new List<List<short>>();
List<List<short>> Facesnormal = new List<List<short>>();
List<short> newIndices = new List<short>();
#region Submeshes
this.BSPRawDataMetaChunks[x].SubMeshInfo = new ParsedModel.RawDataMetaChunk.ModelSubMeshInfo[groupcount];
int totalindicecount = 0;
this.BSPRawDataMetaChunks[x].Vertices.Clear();
this.BSPRawDataMetaChunks[x].UVs.Clear();
this.BSPRawDataMetaChunks[x].Normals.Clear();
for (int y = 0; y < groupcount; y++)
{
Application.DoEvents();
Faces.Add(new List<short>());
for (int h = 0; h < faces[y].Count; h++)
{
int tempvert = faces[y][h];
int tempuv = facesuv[y][h];
int tempnorm = facesnormal[y][h];
for (int i = 0; i < y + 1; i++)
{
for (int j = 0; j < faces[i].Count; j++)
{
if (i == y && j == h)
{
goto gohere1;
}
int tempvert2 = faces[i][j];
int tempuv2 = facesuv[i][j];
int tempnorm2 = facesnormal[i][j];
if (tempvert == tempvert2 && tempuv == tempuv2 && tempnorm == tempnorm2)
{
Faces[y].Add(Faces[i][j]);
newIndices.Add(Faces[i][j]);
goto gohere;
}
}
}
gohere1:
this.BSPRawDataMetaChunks[x].Vertices.Add(vertices[faces[y][h]]);
this.BSPRawDataMetaChunks[x].UVs.Add(uvs[facesuv[y][h]]);
this.BSPRawDataMetaChunks[x].Normals.Add(normals[facesnormal[y][h]]);
newIndices.Add((short)(this.BSPRawDataMetaChunks[x].Vertices.Count - 1));
Faces[y].Add((short)(this.BSPRawDataMetaChunks[x].Vertices.Count - 1));
gohere:
;
}
#region SubmeshInfo
ParsedModel.RawDataMetaChunk.ModelSubMeshInfo submesh =
new ParsedModel.RawDataMetaChunk.ModelSubMeshInfo();
submesh.IndiceStart = totalindicecount;
totalindicecount += faces[y].Count;
submesh.IndiceCount = faces[y].Count;
submesh.ShaderNumber = 0;
object tempobject = Materials[y];
if (tempobject != null)
{
int tempint = MaterialNames.IndexOf((string)tempobject);
if (tempint != -1)
{
submesh.ShaderNumber = tempint;
}
}
this.BSPRawDataMetaChunks[x].SubMeshInfo[y] = submesh;
#endregion
}
#endregion
this.BSPRawDataMetaChunks[x].FaceCount = facecount / 3;
int temp = 0;
for (int i = 0; i < faces.Count; i++)
{
this.BSPRawDataMetaChunks[x].SubMeshInfo[i].IndiceCount = faces[i].Count;
this.BSPRawDataMetaChunks[x].SubMeshInfo[i].IndiceStart = temp;
temp += faces[i].Count;
}
this.BSPRawDataMetaChunks[x].Indices = newIndices.ToArray();
this.BSPRawDataMetaChunks[x].IndiceCount = this.BSPRawDataMetaChunks[x].Indices.Length;
this.BSPRawDataMetaChunks[x].VerticeCount = this.BSPRawDataMetaChunks[x].Vertices.Count;
#region Displays each mesh in a window. Debugging ONLY!
/*****************************************
Form tForm = new Form();
temprender = new entity.Renderer.Renderer();
fakepanel = new Panel();
temprender.CreateDevice(fakepanel);
fakepanel.Size = tForm.Size;
tForm.Controls.Add(fakepanel);
tForm.Show();
temprender.device.VertexFormat = HaloBSPVertex.FVF;
temprender.device.RenderState.CullMode = Cull.None;
temprender.device.Transform.World = Matrix.Identity;
temprender.device.SamplerState[0].AddressU = TextureAddress.Wrap;
temprender.device.SamplerState[0].AddressV = TextureAddress.Wrap;
temprender.device.RenderState.Lighting = true;
temprender.device.RenderState.ZBufferEnable = true;
temprender.device.RenderState.ZBufferWriteEnable = true;
temprender.device.SetTexture(0, null);
temprender.device.SetTexture(1, null);
temprender.device.RenderState.AlphaBlendEnable = false;
temprender.device.RenderState.AlphaTestEnable = false;
// cam.Position = new Vector3(this.BSPRawDataMetaChunks[x].Vertices[0].X - 10, this.BSPRawDataMetaChunks[x].Vertices[0].Y - 10, this.BSPRawDataMetaChunks[x].Vertices[0].Z);
// cam.LookAt = this.BSPRawDataMetaChunks[x].Vertices[0];
Material WhiteMaterial = new Material();
WhiteMaterial.Diffuse = System.Drawing.Color.White;
WhiteMaterial.Ambient = System.Drawing.Color.White;
Material BlackMaterial = new Material();
BlackMaterial.Diffuse = System.Drawing.Color.Black;
BlackMaterial.Ambient = System.Drawing.Color.Black;
//Mesh m2 = Mesh.Box(temprender.device, 5, 5, 5);
temprender.device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, tForm.Width / tForm.Height, 1f, 250f);
//temprender.device.Transform.View = Matrix.LookAtLH(new Vector3(20, 20, 20), new Vector3(0, 0, 0), new Vector3(0, 0, 1));
temprender.device.Transform.View = Matrix.LookAtLH(
new Vector3(this.BSPRawDataMetaChunks[x].Vertices[0].X - 5, this.BSPRawDataMetaChunks[x].Vertices[0].Y + 20, this.BSPRawDataMetaChunks[x].Vertices[0].Z - 5),
this.BSPRawDataMetaChunks[x].Vertices[0],
new Vector3(0, 0, 1));
List<short> tInd = new List<short>(this.BSPPermutationRawDataMetaChunks[x].Indices);
Mesh mesh = temprender.MakeMesh(this.BSPPermutationRawDataMetaChunks[x].Vertices, tInd, this.BSPPermutationRawDataMetaChunks[x].UVs);
// While the form is still valid, render and process messages
while (tForm.Created)
{
temprender.device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, System.Drawing.Color.Black, 1.0f, 0);
temprender.BeginScene(System.Drawing.Color.Blue);
temprender.device.Transform.World = Matrix.Translation(0, 0, 0);
for (int ll = 0; ll < 1; ll++)
{
temprender.device.Material = WhiteMaterial;
temprender.device.RenderState.FillMode = FillMode.Solid;
mesh.DrawSubset(ll);
temprender.device.Material = BlackMaterial;
temprender.device.RenderState.FillMode = FillMode.WireFrame;
mesh.DrawSubset(ll);
}
//m2.DrawSubset(0);
temprender.EndScene();
Application.DoEvents();
GC.Collect(0);
GC.WaitForPendingFinalizers();
GC.Collect(0);
}
/********************************************/
#endregion
}
#endregion
}