HaloMap.RawData.BSPModel.LoadFromOBJ C# (CSharp) Method

LoadFromOBJ() public method

The load from obj.
public LoadFromOBJ ( string FilePath ) : void
FilePath string The file path.
return void
        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
        }