private static MashTrigle GetMashTrigle(string fname) { MashTrigle result = new MashTrigle(); using (FileStream fs = new FileStream(fname, FileMode.Open)) { using (BinaryReader reader = new BinaryReader(fs)) { long flen = fs.Length; if (flen % 108 != 0) { throw new Exception("不是正确的文件"); } int facecount = (int)(flen / 108); TrigleFace[] trigles = new TrigleFace[facecount]; for (int i = 0; i < facecount; i++) { Vector3f v0, v1, v2, vt0, vt1, vt2, vn0, vn1, vn2; v0 = ReadAVector(reader); vt0 = ReadAVector(reader); vn0 = ReadAVector(reader); v1 = ReadAVector(reader); vt1 = ReadAVector(reader); vn1 = ReadAVector(reader); v2 = ReadAVector(reader); vt2 = ReadAVector(reader); vn2 = ReadAVector(reader); TrigleFace face = new TrigleFace(v0, v1, v2) { sp0 = new Vector2f(vt0.X, vt0.Y), sp1 = new Vector2f(vt1.X, vt1.Y), sp2 = new Vector2f(vt2.X, vt2.Y), n0 = vn0, n1 = vn1, n2 = vn2 }; trigles[i] = face; } result.SetTrigles(trigles); } } return(result); }
private static void SaveObject(MashTrigle mashTrigle, string fpath) { using (FileStream fs = new FileStream(fpath, FileMode.Create)) { using (BinaryWriter writer = new BinaryWriter(fs)) { foreach (TrigleFace trigle in mashTrigle.trigles) { WriteVector(writer, trigle.v0); WriteVector(writer, trigle.sp0); WriteVector(writer, trigle.n0); WriteVector(writer, trigle.v1); WriteVector(writer, trigle.sp1); WriteVector(writer, trigle.n1); WriteVector(writer, trigle.v2); WriteVector(writer, trigle.sp2); WriteVector(writer, trigle.n2); } } } }
public static void Save(Scene scene, string basePath, string proName) { basePath = Path.Combine(basePath, proName); string profile = Path.Combine(basePath, proName + ".mrirpro"); Directory.CreateDirectory(basePath); using (FileStream fs = new FileStream(profile, FileMode.Create)) { using (StreamWriter sw = new StreamWriter(fs)) { sw.AutoFlush = true; int objcount = -1; foreach (RenderObject obj in scene.Objects) { objcount++; string fpath = Path.Combine(basePath, objcount + ".mrimtl"); SaveMaterial(obj.Material, fpath); Type type = obj.GetType(); if (type == typeof(MashTrigle)) { MashTrigle mash = obj as MashTrigle; string mtlpath = Path.Combine(basePath, objcount + ".mritri"); SaveObject(mash, mtlpath); sw.WriteLine($"mt {objcount} {objcount}"); continue; } if (type == typeof(PointLight)) { PointLight pl = obj as PointLight; sw.WriteLine($"l.p {pl.Position.X},{pl.Position.Y},{pl.Position.Z},{pl.R} {objcount}"); continue; } } } } }
public static MashTrigle[] LoadModel(string filePath, bool negativeZ = false) { string[] lines = File.ReadAllLines(filePath); List <MashTrigle> mashes = new List <MashTrigle>(); List <Vector3f> v = new List <Vector3f>() { new Vector3f() }; Dictionary <int, List <PW_Trigle> > faceList = new Dictionary <int, List <PW_Trigle> >(); List <Vector2f> vt = new List <Vector2f>() { new Vector2f() }; List <Vector3f> vn = new List <Vector3f>() { new Vector3f() }; MashTrigle nobj = null; List <PW_Trigle> trigles = new List <PW_Trigle>(); for (int linecount = 0; linecount < lines.Length; linecount++) { string line = lines[linecount]; if (string.IsNullOrWhiteSpace(line) || line.StartsWith('#')) { continue; } float p0 = 0.0f, p1 = 0.0f, p2 = 0.0f; string[] parts = line.Split(LineSplitChars, StringSplitOptions.RemoveEmptyEntries); switch (parts[0].ToLower()) { case "v": #region v if (parts.Length != 4) { throw new Exception($"line {linecount} : 缺少参数的行,请求3个,实际为{parts.Length - 1}个"); } if (!Float.TryParse(parts[1], out p0)) { throw new Exception($"line {linecount} : 不能转换的数据 {parts[1]}"); } if (!Float.TryParse(parts[2], out p1)) { throw new Exception($"line {linecount} : 不能转换的数据 {parts[2]}"); } if (!Float.TryParse(parts[3], out p2)) { throw new Exception($"line {linecount} : 不能转换的数据 {parts[3]}"); } if (negativeZ) { v.Add(new Vector3f(p0, p1, -p2)); } else { v.Add(new Vector3f(p0, p1, p2)); } #endregion break; case "vt": #region vt if (parts.Length != 3 && parts.Length != 4) { throw new Exception($"line {linecount} : 缺少参数的行,请求2或3个,实际为{parts.Length - 1}个"); } if (!Float.TryParse(parts[1], out p0)) { throw new Exception($"line {linecount} : 不能转换的数据 {parts[1]}"); } if (!Float.TryParse(parts[2], out p1)) { throw new Exception($"line {linecount} : 不能转换的数据 {parts[2]}"); } vt.Add(new Vector2f(p0, p1)); #endregion break; case "vn": #region vn if (parts.Length != 4) { throw new Exception($"line {linecount} : 缺少参数的行,请求3个,实际为{parts.Length - 1}个"); } if (!Float.TryParse(parts[1], out p0)) { throw new Exception($"line {linecount} : 不能转换的数据 {parts[1]}"); } if (!Float.TryParse(parts[2], out p1)) { throw new Exception($"line {linecount} : 不能转换的数据 {parts[2]}"); } if (!Float.TryParse(parts[3], out p2)) { throw new Exception($"line {linecount} : 不能转换的数据 {parts[3]}"); } if (negativeZ) { vn.Add(Vector3f.Normalize(new Vector3f(p0, p1, -p2))); } else { vn.Add(Vector3f.Normalize(new Vector3f(p0, p1, p2))); } #endregion break; case "vp": break; case "g": #region g if (trigles != null && trigles.Count > 0) { if (nobj == null) { nobj = new MashTrigle(); } nobj.SetTrigles(Smooth(trigles, v, vt, faceList)); mashes.Add(nobj); } nobj = new MashTrigle(); trigles = new List <PW_Trigle>(); #endregion break; case "f": #region f if (parts.Length < 4) { throw new Exception($"line {linecount} : 缺少参数的行,请求至少为3个,实际为{parts.Length - 1}个"); } int pointcount = parts.Length - 1; int[] vidx = new int[pointcount], vtidx = new int[pointcount], vnidx = new int[pointcount]; // 分割顶点信息 for (int i = 0; i < pointcount; i++) { string pinfo = parts[i + 1]; string[] infos = pinfo.Split(PInfoSplitChars); vidx[i] = int.Parse(infos[0]); int tmp; if (infos.Length > 1 && int.TryParse(infos[1], out tmp)) { vtidx[i] = tmp; } else { vtidx[i] = 0; //-1; } if (infos.Length > 2 && int.TryParse(infos[1], out tmp)) { vnidx[i] = tmp; } else { vnidx[i] = 0; //-1; } } // 生成三角形面 for (int i = 2; i < pointcount; i++) { PW_Trigle face = new PW_Trigle(); face.v0 = vidx[0]; face.v1 = vidx[i - 1]; face.v2 = vidx[i]; { //normal Vector3f e1 = v[face.v1] - v[face.v0], e2 = v[face.v2] - v[face.v0]; face.Normal = Vector3f.Normalize(Vector3f.Cross(e1, e2)); } { //sp //if (vtidx[0] != -1) { face.vt0 = vtidx[0]; //} //if (vtidx[i - 1] != -1) { face.vt1 = vtidx[i - 1]; //} //if (vtidx[i] != -1) { face.vt2 = vtidx[i]; //} } trigles.Add(face); if (!faceList.ContainsKey(face.v0)) { faceList[face.v0] = new List <PW_Trigle>(); } faceList[face.v0].Add(face); if (!faceList.ContainsKey(face.v1)) { faceList[face.v1] = new List <PW_Trigle>(); } faceList[face.v1].Add(face); if (!faceList.ContainsKey(face.v2)) { faceList[face.v2] = new List <PW_Trigle>(); } faceList[face.v2].Add(face); } #endregion break; } } if (trigles != null && trigles.Count > 0) { if (nobj == null) { nobj = new MashTrigle(); } nobj.SetTrigles(Smooth(trigles, v, vt, faceList)); mashes.Add(nobj); } return(mashes.ToArray()); }