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
        static TrigleFace[] Smooth(List <PW_Trigle> faces, List <Vector3f> v, List <Vector2f> vt, Dictionary <int, List <PW_Trigle> > faceList)
        {
            if (faces == null || faces.Count == 0)
            {
                return(null);
            }
            Dictionary <int, Vector3f> pointNormal = new Dictionary <int, Vector3f>();

            TrigleFace[] re = new TrigleFace[faces.Count];
            foreach (KeyValuePair <int, List <PW_Trigle> > kv in faceList)
            {
                Vector3f n = new Vector3f();
                foreach (PW_Trigle trigle in kv.Value)
                {
                    n += trigle.Normal;
                }
                n = Vector3f.Normalize(n);
                pointNormal[kv.Key] = n;
            }

            int idx = 0;

            foreach (PW_Trigle trigle in faces)
            {
                TrigleFace t = new TrigleFace(v[trigle.v0], v[trigle.v1], v[trigle.v2]);
                t.sp0 = vt[trigle.vt0];
                t.sp1 = vt[trigle.vt1];
                t.sp2 = vt[trigle.vt2];
                t.n0  = pointNormal[trigle.v0];
                t.n1  = pointNormal[trigle.v1];
                t.n2  = pointNormal[trigle.v2];

                re[idx] = t;
                idx++;
            }
            return(re);
        }
Beispiel #3
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()
            };
            List <Vector2f> vt = new List <Vector2f>()
            {
                new Vector2f()
            };
            List <Vector3f> vn = new List <Vector3f>()
            {
                new Vector3f()
            };

            MashTrigle        nobj    = null;
            List <TrigleFace> trigles = new List <TrigleFace>();

            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(trigles.ToArray());
                        mashes.Add(nobj);
                    }
                    nobj    = new MashTrigle();
                    trigles = new List <TrigleFace>();
                    #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] = -1;
                        }
                        if (infos.Length > 2 && int.TryParse(infos[1], out tmp))
                        {
                            vnidx[i] = tmp;
                        }
                        else
                        {
                            vnidx[i] = -1;
                        }
                    }

                    // 生成三角形面
                    for (int i = 2; i < pointcount; i++)
                    {
                        TrigleFace face = new TrigleFace(v[vidx[0]], v[vidx[i - 1]], v[vidx[i]]);
                        {                                 //normal
                            Vector3f facenormal = new Vector3f();
                            if (vnidx[0] == -1 || vnidx[i - 1] == -1 || vnidx[i] == -1)
                            {
                                facenormal = Vector3f.Normalize(Vector3f.Cross(face.e1, face.e2));
                            }

                            if (vnidx[0] == -1)
                            {
                                face.n0 = facenormal;
                            }
                            else
                            {
                                face.n0 = vn[vnidx[0]];
                            }
                            if (vnidx[i - 1] == -1)
                            {
                                face.n1 = facenormal;
                            }
                            else
                            {
                                face.n1 = vn[vnidx[i - 1]];
                            }
                            if (vnidx[i] == -1)
                            {
                                face.n2 = facenormal;
                            }
                            else
                            {
                                face.n2 = vn[vnidx[i]];
                            }
                        }
                        {                                 //sp
                            if (vtidx[0] != -1)
                            {
                                face.sp0 = vt[vtidx[0]];
                            }
                            if (vtidx[i - 1] != -1)
                            {
                                face.sp1 = vt[vtidx[i - 1]];
                            }
                            if (vtidx[i] != -1)
                            {
                                face.sp2 = vt[vtidx[i]];
                            }
                        }

                        trigles.Add(face);
                    }

                    #endregion
                    break;
                }
            }

            if (trigles != null && trigles.Count > 0)
            {
                if (nobj == null)
                {
                    nobj = new MashTrigle();
                }
                nobj.SetTrigles(trigles.ToArray());
                mashes.Add(nobj);
            }

            return(mashes.ToArray());
        }