public void AddFace(OBJFace face) { List <OBJFace> faces; if (!Faces.TryGetValue(face.Material, out faces)) { Faces[face.Material] = faces = new List <OBJFace>(); } faces.Add(face); }
public static void ParseLineStandard(OBJParserStatus s, string line) { OBJObject o; string[] data = line.Split(' '); switch (data[0]) { case "mtllib": // Currently ignore material libraries. return; case "o": o = new OBJObject(line.Substring(2), s.Current); s.Data.Objects.Add(o); s.Current = o.Groups[0]; s.CurrentMaterial = ""; return; case "g": if (s.Data.Objects.Count == 0) { o = new OBJObject("", s.Current); s.Data.Objects.Add(o); s.Current = o.Groups[0]; s.Current.Name = line.Substring(2); } else { s.Current = new OBJGroup(line.Substring(2), s.Current); if (s.Current.PrevObj.Groups.Count == 2 && s.Current.PrevObj.Groups[0].Name == "") { s.Current.PrevObj.Groups.RemoveAt(0); } } s.CurrentMaterial = ""; return; case "v": s.Current.Vertices.Add(_ParseV3(data, 1)); return; case "vt": s.Current.UVs.Add(_ParseV2(data, 1)); return; case "vn": s.Current.Normals.Add(_ParseV3(data, 1)); return; case "usemtl": // Currently ignore material usages. s.Current.Materials.Add(line.Substring(7)); return; case "s": if (data[1] == "off") { // Currently ignore smoothing group disabling. } else { // Currently ignore smoothing group 1 - 32. } return; case "f": OBJGroup current = s.Current; if (4 <= data.Length && data.Length < 6) { int[] indices = new int[data.Length - 1]; for (int i = 0; i < indices.Length; i++) { string elem = data[i + 1]; int iV = 0; int iN = 0; int iUV = 0; if (elem.Contains("//")) { string[] parts = elem.Split('/'); iV = int.Parse(parts[0]); iN = int.Parse(parts[2]); } else if (_Count(elem, '/', 2)) { string[] parts = elem.Split('/'); iV = int.Parse(parts[0]); iUV = int.Parse(parts[1]); iN = int.Parse(parts[2]); } else if (!elem.Contains("/")) { iV = int.Parse(elem); } else { string[] parts = elem.Split('/'); iV = int.Parse(parts[0]); iUV = int.Parse(parts[1]); } string cacheKey = $"{iV}; {iN}; {iUV}"; int cacheValue; if (current.IndexCache.TryGetValue(cacheKey, out cacheValue)) { indices[i] = cacheValue; } else { cacheValue = current.IndexCache.Count; indices[i] = cacheValue; current.IndexCache[cacheKey] = cacheValue; if ((1 <= iV && iV <= current.Vertices.Count) || (iV < 0 && 1 <= (iV = iV + current.Vertices.Count + 1) && iV <= current.Vertices.Count)) { current.UVertices.Add(current.Vertices[iV - 1]); } else { current.UVertices.Add(Vector3.zero); } if ((1 <= iN && iN <= current.Normals.Count) || (iN < 0 && 1 <= (iN = iN + current.Normals.Count + 1) && iN <= current.Normals.Count)) { current.ContainsNormals = true; current.UNormals.Add(current.Normals[iN - 1]); } else { current.UNormals.Add(Vector3.zero); } if ((1 <= iUV && iUV <= current.UVs.Count) || (iUV < 0 && 1 <= (iUV = iUV + current.UVs.Count + 1) && iUV <= current.UVs.Count)) { current.UUVs.Add(current.UVs[iUV - 1]); } else { current.UUVs.Add(Vector2.zero); } } } OBJFace face = new OBJFace(); face.IndexMap = OBJFace.DefaultIndexMap; face.RawIndices = indices; face.Material = s.CurrentMaterial; s.Current.AddFace(face); if (indices.Length > 3) { face = new OBJFace(); face.IndexMap = OBJFace.SecondaryIndexMap; face.RawIndices = indices; face.Material = s.CurrentMaterial; s.Current.AddFace(face); } } return; } }
public virtual Mesh ToMesh() { Mesh mesh = new Mesh(); mesh.name = Name; List <Vector3> pVertices = new List <Vector3>(); List <Vector3> pNormals = new List <Vector3>(); List <Vector2> pUVs = new List <Vector2>(); List <List <int> > pIndices = new List <List <int> >(); IDictionary <int, int> map = new IntDictionary <int>(); HashSet <string> materials = new HashSet <string>(); foreach (KeyValuePair <string, List <OBJFace> > facesPerMat in Faces) { string mat = facesPerMat.Key; List <OBJFace> faces = facesPerMat.Value; if (faces.Count == 0) { continue; } List <int> indices = new List <int>(); for (int fi = 0; fi < faces.Count; fi++) { OBJFace face = faces[fi]; indices.Add(face[0]); indices.Add(face[1]); indices.Add(face[2]); } if (!materials.Contains(mat)) { materials.Add(mat); mesh.subMeshCount++; } for (int ii = 0; ii < indices.Count; ii++) { int index = indices[ii]; if (map.ContainsKey(index)) { indices[ii] = map[index]; } else { indices[ii] = map[index] = pVertices.Count; pVertices.Add(UVertices[index]); pNormals.Add(UNormals[index]); pUVs.Add(UUVs[index]); } } pIndices.Add(indices); } mesh.SetVertices(pVertices); mesh.SetNormals(pNormals); mesh.SetUVs(0, pUVs); for (int i = 0; i < pIndices.Count; i++) { mesh.SetTriangles(pIndices[i], i); } if (!ContainsNormals) { mesh.RecalculateNormals(); } mesh.RecalculateBounds(); mesh.Optimize(); return(mesh); }