private void ParseObjToken(string line, string[] tokens) { string token = tokens[0].ToLower(); try { switch (token) { case "v": { float x = float.Parse(tokens[1], System.Globalization.CultureInfo.InvariantCulture); float y = float.Parse(tokens[2], System.Globalization.CultureInfo.InvariantCulture); float z = float.Parse(tokens[3], System.Globalization.CultureInfo.InvariantCulture); Vector3 p = new Vector3(x * Scale, y * Scale, z * Scale); //BBox.AddFloat3(ref p); Positions.Add(p); break; } case "vn": { if (ParseNormals) { float x = float.Parse(tokens[1], System.Globalization.CultureInfo.InvariantCulture); float y = float.Parse(tokens[2], System.Globalization.CultureInfo.InvariantCulture); float z = float.Parse(tokens[3], System.Globalization.CultureInfo.InvariantCulture); float modifier = -1.0f; Normals.Add(new Vector3(x, y, z) * modifier); } break; } case "vt": { float x = float.Parse(tokens[1], System.Globalization.CultureInfo.InvariantCulture); float y = float.Parse(tokens[2], System.Globalization.CultureInfo.InvariantCulture); Texcoords.Add(new Vector(x, y, 0f)); break; } case "f": { int v0 = 0, v1 = 0, v2 = 0; if (tokens.Length >= 10) { //full v, vn, vt indices v0 = int.Parse(tokens[1], System.Globalization.CultureInfo.InvariantCulture); v1 = int.Parse(tokens[4], System.Globalization.CultureInfo.InvariantCulture); v2 = int.Parse(tokens[7], System.Globalization.CultureInfo.InvariantCulture); mCurrentGroup.VIndices.Add(new Int3(v0 - 1, v1 - 1, v2 - 1)); v0 = int.Parse(tokens[2], System.Globalization.CultureInfo.InvariantCulture); v1 = int.Parse(tokens[5], System.Globalization.CultureInfo.InvariantCulture); v2 = int.Parse(tokens[8], System.Globalization.CultureInfo.InvariantCulture); mCurrentGroup.TIndices.Add(new Int3(v0 - 1, v1 - 1, v2 - 1)); if (ParseNormals) { v0 = int.Parse(tokens[3], System.Globalization.CultureInfo.InvariantCulture); v1 = int.Parse(tokens[6], System.Globalization.CultureInfo.InvariantCulture); v2 = int.Parse(tokens[9], System.Globalization.CultureInfo.InvariantCulture); mCurrentGroup.NIndices.Add(new Int3(v0 - 1, v1 - 1, v2 - 1)); } } else if (tokens.Length == 7) { //v, ( vn | vt ) indices v0 = int.Parse(tokens[1], System.Globalization.CultureInfo.InvariantCulture); v1 = int.Parse(tokens[3], System.Globalization.CultureInfo.InvariantCulture); v2 = int.Parse(tokens[5], System.Globalization.CultureInfo.InvariantCulture); mCurrentGroup.VIndices.Add(new Int3(v0 - 1, v1 - 1, v2 - 1)); v0 = int.Parse(tokens[2], System.Globalization.CultureInfo.InvariantCulture); v1 = int.Parse(tokens[4], System.Globalization.CultureInfo.InvariantCulture); v2 = int.Parse(tokens[6], System.Globalization.CultureInfo.InvariantCulture); if (line.Contains("//")) { if (ParseNormals) mCurrentGroup.NIndices.Add(new Int3(v0 - 1, v1 - 1, v2 - 1)); } else { mCurrentGroup.TIndices.Add(new Int3(v0 - 1, v1 - 1, v2 - 1)); } } else if (tokens.Length == 4) { //v indices v0 = int.Parse(tokens[1], System.Globalization.CultureInfo.InvariantCulture); v1 = int.Parse(tokens[2], System.Globalization.CultureInfo.InvariantCulture); v2 = int.Parse(tokens[3], System.Globalization.CultureInfo.InvariantCulture); mCurrentGroup.VIndices.Add(new Int3(v0 - 1, v1 - 1, v2 - 1)); } else { throw new Exception("Error parsing obj file"); } break; } case "g": { string name = tokens[1].ToLowerInvariant(); mCurrentGroupName = name; mCurrentGroup = new ObjGroupInfo(name) { mtrl = mCurrentMtrlName }; Groups.Add(mCurrentGroup); break; } case "usemtl": { string name = tokens[1].ToLowerInvariant(); string groupname = mCurrentGroupName.ToLowerInvariant(); mCurrentGroup = new ObjGroupInfo(groupname); Groups.Add(mCurrentGroup); mCurrentGroup.mtrl = name; mCurrentMtrlName = name; break; } case "mtllib": { mCurrentMtrl = default(ObjFileMaterial); string name = mDirectory + tokens[1]; ParseFile(ParseMtrlToken, name); if (mCurrentMtrlName != null) { mMtrls.Add(mCurrentMtrlName, mCurrentMtrl); } mCurrentMtrlName = null; break; } default: break; } } catch (Exception ex) { Console.WriteLine("Error parsing obj token: " + ex.Message); } }
private void ParseMtrlToken(string line, string[] tokens) { string token = tokens[0].ToLower(); try { switch (token) { case "newmtl": { if (mCurrentMtrlName != null) { mMtrls.Add(mCurrentMtrlName, mCurrentMtrl); } mCurrentMtrlName = tokens[1]; mCurrentMtrl = new ObjFileMaterial(); break; } case "ns": { mCurrentMtrl.Ns = float.Parse(tokens[1], CultureInfo.InvariantCulture); break; } case "ni": { mCurrentMtrl.Ni = float.Parse(tokens[1], CultureInfo.InvariantCulture); break; } case "d": { mCurrentMtrl.d = float.Parse(tokens[1], CultureInfo.InvariantCulture); break; } case "tr": { mCurrentMtrl.Tr = float.Parse(tokens[1], CultureInfo.InvariantCulture); break; } case "illum": { mCurrentMtrl.illum = float.Parse(tokens[1], CultureInfo.InvariantCulture); break; } case "tf": { float x = float.Parse(tokens[1], CultureInfo.InvariantCulture); float y = float.Parse(tokens[2], CultureInfo.InvariantCulture); float z = float.Parse(tokens[3], CultureInfo.InvariantCulture); mCurrentMtrl.Tf = new Vector(x, y, z); break; } case "ka": { float x = float.Parse(tokens[1], CultureInfo.InvariantCulture); float y = float.Parse(tokens[2], CultureInfo.InvariantCulture); float z = float.Parse(tokens[3], CultureInfo.InvariantCulture); mCurrentMtrl.Ka = new Vector(x, y, z); break; } case "kd": { float x = float.Parse(tokens[1], CultureInfo.InvariantCulture); float y = float.Parse(tokens[2], CultureInfo.InvariantCulture); float z = float.Parse(tokens[3], CultureInfo.InvariantCulture); mCurrentMtrl.Kd = new Vector(x, y, z); break; } case "ks": { float x = float.Parse(tokens[1], CultureInfo.InvariantCulture); float y = float.Parse(tokens[2], CultureInfo.InvariantCulture); float z = float.Parse(tokens[3], CultureInfo.InvariantCulture); mCurrentMtrl.Ks = new Vector(x, y, z); break; } case "ke": { float x = float.Parse(tokens[1], CultureInfo.InvariantCulture); float y = float.Parse(tokens[2], CultureInfo.InvariantCulture); float z = float.Parse(tokens[3], CultureInfo.InvariantCulture); mCurrentMtrl.Ke = new Vector(x, y, z); break; } case "map_ka": { //mCurrentMtrl.Map_Ka = tokens.Length < 2 ? tokens.Last() : line.Substring(line.IndexOf(tokens[1])); mCurrentMtrl.SetMaps(ka: tokens.Length < 2 ? tokens.Last() : line.Substring(line.IndexOf(tokens[1]))); break; } case "map_kd": { //mCurrentMtrl.Map_Kd = tokens.Length < 2 ? tokens.Last() : line.Substring(line.IndexOf(tokens[1])); mCurrentMtrl.SetMaps(kd: tokens.Length < 2 ? tokens.Last() : line.Substring(line.IndexOf(tokens[1]))); break; } case "map_ks": { mCurrentMtrl.SetMaps(ks: tokens.Length < 2 ? tokens.Last() : line.Substring(line.IndexOf(tokens[1]))); //Map_Ks = line.Substring(line.IndexOf(tokens[1])); break; } case "map_refl": { mCurrentMtrl.SetMaps(ks: tokens.Length < 2 ? tokens.Last() : line.Substring(line.IndexOf(tokens[1]))); //Map_Ks = line.Substring(line.IndexOf(tokens[1])); break; } case "bump": { mCurrentMtrl.SetMaps(mapd: tokens.Length < 2 ? tokens.Last() : line.Substring(line.IndexOf(tokens[1]))); //mCurrentMtrl.Map_d = line.Substring(line.IndexOf(tokens[1])); break; } default: break; } } catch (Exception ex) { Console.WriteLine("Error parsing mtrl token: " + ex.Message); } }
public SceneGeometryInfo Load(string filename, bool invertNormals = false, params string[] additionalFiles) { var FileName = filename; if (!File.Exists(filename)) { throw new FileNotFoundException("OBJLoader Error: File not found", filename); } Positions = new List<Vector>(); Normals = new List<Vector>(); Texcoords = new List<Vector>(); mMtrls = new Dictionary<string, ObjFileMaterial>(); Groups = new List<ObjGroupInfo>(); mCurrentGroup = null; mCurrentMtrlName = null; mCurrentMtrl = default(ObjFileMaterial); Console.Write("Loading: " + Path.GetFileName(FileName) + "... "); //float start = Time.GetTimeInSecs(); mDirectory = Path.GetDirectoryName(FileName) + "\\"; mCurrentGroup = new ObjGroupInfo("default"); Groups.Add(mCurrentGroup); ParseFile(ParseObjToken, FileName); CreateNormals(); SceneGeometryInfo result = new SceneGeometryInfo(); result.Vertices = this.Positions.Select(i => (Point) i).ToArray(); result.Normals = this.Normals.ToArray(); result.TexCoords = this.Texcoords.ToArray(); var geo = new List<GeometryInfo>(); foreach (var objGroup in this.Groups) { if (!objGroup.VIndices.Any()) { Console.WriteLine("No inidexz-"); continue; } if (string.IsNullOrWhiteSpace(objGroup.mtrl)) { Debugger.Break(); } geo.Add(new GeometryInfo() { IndexData = new IntStore(objGroup.VIndices.SelectMany(i=> new[] {i.v0, i.v1, i.v2})), NormalIndexData = new IntStore(objGroup.NIndices.SelectMany(i=> new[] {i.v0, i.v1, i.v2})), TextureIndexData = new IntStore(objGroup.TIndices.SelectMany(i => new[] { i.v0, i.v1, i.v2 })), Name = objGroup.name, MaterialName = objGroup.mtrl, }); } result.Geometry = geo.ToArray(); return result; }