Beispiel #1
0
        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);
        }
Beispiel #2
0
 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);
             }
         }
     }
 }
Beispiel #3
0
        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;
                        }
                    }
                }
            }
        }
Beispiel #4
0
        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());
        }