/// <summary> /// The load from obj. /// </summary> /// <param name="FilePath">The file path.</param> /// <remarks></remarks> public virtual 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]); // } } } if (MaterialNames.Count > this.Shaders.Shader.Length) { List<ShaderInfo> newlist = new List<ShaderInfo>(); for (int x = 0; x < this.Shaders.Shader.Length; x++) { newlist.Add(this.Shaders.Shader[x]); } int diff = MaterialNames.Count - this.Shaders.Shader.Length; for (int x = 0; x < diff; x++) { newlist.Add(this.Shaders.Shader[0]); } this.Shaders.Shader = newlist.ToArray(); } 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.RawDataMetaChunks.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<short>> faces = new List<List<short>>(); List<List<short>> facesuv = new List<List<short>>(); List<List<short>> facesnormal = new List<List<short>>(); 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": List<short> templist = new List<short>(); List<short> templist2 = new List<short>(); List<short> templist3 = new List<short>(); 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('/'); short temp1 = short.Parse(split1[0]); short temp2 = short.Parse(split2[0]); short temp3 = short.Parse(split3[0]); temp1--; temp2--; temp3--; faces[groupcount - 1].Add(temp1); faces[groupcount - 1].Add(temp2); faces[groupcount - 1].Add(temp3); temp1 = short.Parse(split1[1]); temp2 = short.Parse(split2[1]); temp3 = short.Parse(split3[1]); temp1--; temp2--; temp3--; facesuv[groupcount - 1].Add(temp1); facesuv[groupcount - 1].Add(temp2); facesuv[groupcount - 1].Add(temp3); temp1 = short.Parse(split1[2]); temp2 = short.Parse(split2[2]); temp3 = short.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]); // Materials.Add(Materials.Count, 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++; } 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.RawDataMetaChunks[x].SubMeshInfo = new RawDataMetaChunk.ModelSubMeshInfo[groupcount]; int totalindicecount = 0; this.RawDataMetaChunks[x].Vertices.Clear(); this.RawDataMetaChunks[x].UVs.Clear(); this.RawDataMetaChunks[x].Normals.Clear(); for (int y = 0; y < groupcount; y++) { 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]); goto gohere; } } } gohere1: this.RawDataMetaChunks[x].UVs.Add(uvs[facesuv[y][h]]); this.RawDataMetaChunks[x].Vertices.Add(vertices[faces[y][h]]); this.RawDataMetaChunks[x].Normals.Add(normals[facesnormal[y][h]]); Faces[y].Add((short)(this.RawDataMetaChunks[x].Vertices.Count - 1)); gohere: ; } #region Make Triangle Strip Mesh m = temprender.MakeMesh( this.RawDataMetaChunks[x].Vertices, Faces[y], this.RawDataMetaChunks[x].UVs); int indicecount = 0; unsafe { int[] adj = new int[m.NumberFaces * 3]; m.GenerateAdjacency(0.0f, adj); int[] test; int[] test2; GraphicsStream oi; Mesh oid = m.Optimize( MeshFlags.OptimizeIgnoreVerts | MeshFlags.OptimizeAttributeSort, adj, out test, out test2, out oi); IndexBuffer ib = oid.IndexBuffer; ib = Mesh.ConvertMeshSubsetToSingleStrip( oid, 0, MeshFlags.OptimizeIgnoreVerts | MeshFlags.OptimizeStripeReorder | MeshFlags.IbManaged, out indicecount); GraphicsStream xxxx = ib.Lock(0, 0, LockFlags.None); short* ind = (short*)xxxx.InternalData.ToPointer(); for (int z = 0; z < indicecount; z++) { newIndices.Add(ind[z]); } } #endregion #region SubmeshInfo RawDataMetaChunk.ModelSubMeshInfo submesh = new RawDataMetaChunk.ModelSubMeshInfo(); submesh.IndiceStart = totalindicecount; totalindicecount += indicecount; submesh.IndiceCount = indicecount; submesh.ShaderNumber = 0; object tempobject = Materials[y]; if (tempobject != null) { int tempint = MaterialNames.IndexOf((string)tempobject); if (tempint != -1) { submesh.ShaderNumber = tempint; } } this.RawDataMetaChunks[x].SubMeshInfo[y] = submesh; #endregion } #endregion this.RawDataMetaChunks[x].Indices = newIndices.ToArray(); this.RawDataMetaChunks[x].IndiceCount = this.RawDataMetaChunks[x].Indices.Length; this.RawDataMetaChunks[x].VerticeCount = this.RawDataMetaChunks[x].Vertices.Count; this.RawDataMetaChunks[x].FaceCount = facecount / 3; } #region Bounding Box this.BoundingBox.MinX = minx; this.BoundingBox.MaxX = maxx; this.BoundingBox.MinY = miny; this.BoundingBox.MaxY = maxy; this.BoundingBox.MinZ = minz; this.BoundingBox.MaxZ = maxz; this.BoundingBox.MinU = minu; this.BoundingBox.MaxU = maxu; this.BoundingBox.MinV = minv; this.BoundingBox.MaxV = maxv; #endregion #endregion }
/// <summary> /// The load from obj. /// </summary> /// <param name="FilePath">The file path.</param> /// <remarks></remarks> public override 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]); // } } } if (MaterialNames.Count > this.Shaders.Shader.Length) { List <ShaderInfo> newlist = new List <ShaderInfo>(); for (int x = 0; x < this.Shaders.Shader.Length; x++) { newlist.Add(this.Shaders.Shader[x]); } int diff = MaterialNames.Count - this.Shaders.Shader.Length; for (int x = 0; x < diff; x++) { newlist.Add(this.Shaders.Shader[0]); } this.Shaders.Shader = newlist.ToArray(); } 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.RawDataMetaChunks.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 <short> > faces = new List <List <short> >(); List <List <short> > facesuv = new List <List <short> >(); List <List <short> > facesnormal = new List <List <short> >(); 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": List <short> templist = new List <short>(); List <short> templist2 = new List <short>(); List <short> templist3 = new List <short>(); 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('/'); short temp1 = short.Parse(split1[0]); short temp2 = short.Parse(split2[0]); short temp3 = short.Parse(split3[0]); temp1--; temp2--; temp3--; faces[groupcount - 1].Add(temp1); faces[groupcount - 1].Add(temp2); faces[groupcount - 1].Add(temp3); temp1 = short.Parse(split1[1]); temp2 = short.Parse(split2[1]); temp3 = short.Parse(split3[1]); temp1--; temp2--; temp3--; facesuv[groupcount - 1].Add(temp1); facesuv[groupcount - 1].Add(temp2); facesuv[groupcount - 1].Add(temp3); temp1 = short.Parse(split1[2]); temp2 = short.Parse(split2[2]); temp3 = short.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++; } 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.RawDataMetaChunks[x].SubMeshInfo = new RawDataMetaChunk.ModelSubMeshInfo[groupcount]; int totalindicecount = 0; this.RawDataMetaChunks[x].Vertices.Clear(); this.RawDataMetaChunks[x].UVs.Clear(); this.RawDataMetaChunks[x].Normals.Clear(); for (int y = 0; y < groupcount; y++) { 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]); goto gohere; } } } gohere1: this.RawDataMetaChunks[x].UVs.Add(uvs[facesuv[y][h]]); this.RawDataMetaChunks[x].Vertices.Add(vertices[faces[y][h]]); this.RawDataMetaChunks[x].Normals.Add(normals[facesnormal[y][h]]); Faces[y].Add((short)(this.RawDataMetaChunks[x].Vertices.Count - 1)); gohere: ; } #region Make Triangle Strip Mesh m = temprender.MakeMesh( this.RawDataMetaChunks[x].Vertices, Faces[y], this.RawDataMetaChunks[x].UVs); //int striplength = 0; int indicecount = 0; unsafe { int[] adj = new int[m.NumberFaces * 3]; m.GenerateAdjacency(0.0f, adj); int[] test; int[] test2; GraphicsStream oi; Mesh oid = m.Optimize( MeshFlags.OptimizeIgnoreVerts | MeshFlags.OptimizeAttributeSort, adj, out test, out test2, out oi); IndexBuffer ib = oid.IndexBuffer; ib = Mesh.ConvertMeshSubsetToSingleStrip( oid, 0, MeshFlags.OptimizeIgnoreVerts | MeshFlags.OptimizeStripeReorder | MeshFlags.IbManaged, out indicecount); GraphicsStream xxxx = ib.Lock(0, 0, LockFlags.None); short * ind = (short *)xxxx.InternalData.ToPointer(); for (int z = 0; z < indicecount; z++) { newIndices.Add(ind[z]); } } #endregion #region SubmeshInfo RawDataMetaChunk.ModelSubMeshInfo submesh = new RawDataMetaChunk.ModelSubMeshInfo(); submesh.IndiceStart = totalindicecount; totalindicecount += indicecount; submesh.IndiceCount = indicecount; submesh.ShaderNumber = 0; object tempobject = Materials[y]; if (tempobject != null) { int tempint = MaterialNames.IndexOf((string)tempobject); if (tempint != -1) { submesh.ShaderNumber = tempint; } } this.RawDataMetaChunks[x].SubMeshInfo[y] = submesh; #endregion } #endregion this.RawDataMetaChunks[x].Indices = newIndices.ToArray(); this.RawDataMetaChunks[x].IndiceCount = this.RawDataMetaChunks[x].Indices.Length; this.RawDataMetaChunks[x].VerticeCount = this.RawDataMetaChunks[x].Vertices.Count; this.RawDataMetaChunks[x].FaceCount = facecount / 3; } #region Bounding Box this.BoundingBox.MinX = minx; this.BoundingBox.MaxX = maxx; this.BoundingBox.MinY = miny; this.BoundingBox.MaxY = maxy; this.BoundingBox.MinZ = minz; this.BoundingBox.MaxZ = maxz; this.BoundingBox.MinU = minu; this.BoundingBox.MaxU = maxu; this.BoundingBox.MinV = minv; this.BoundingBox.MaxV = maxv; #endregion #endregion }