Example #1
0
        private bool SectionFace(string[] tokens)
        {
            if (tokens[0] == "}")
            {
                return(false);
            }

            if (3 != int.Parse(tokens[0]))
            {
                return(true);
            }

            StringBuilder sb = new StringBuilder();

            foreach (string i in tokens)
            {
                sb.Append(' ').Append(i);
            }

            string  line = sb.ToString().Trim();
            MqoFace f    = new MqoFace();

            tokens = SplitString(line);
            current.faces.Add(f);

            for (int i = 1; i < tokens.Length; ++i)
            {
                string t  = tokens[i];
                string t2 = t.ToLower();

                if (t2.StartsWith("v("))
                {
                    string[] t3 = SplitParam(t);
                    f.a = ushort.Parse(t3[1]);
                    f.b = ushort.Parse(t3[2]);
                    f.c = ushort.Parse(t3[3]);
                }
                else
                if (t2.StartsWith("m("))
                {
                    string[] t3 = SplitParam(t);
                    f.mtl = ushort.Parse(t3[1]);
                }
                else
                if (t2.StartsWith("uv("))
                {
                    string[] t3 = SplitParam(t);
                    f.ta = Point2.Parse(t3, 1);
                    f.tb = Point2.Parse(t3, 3);
                    f.tc = Point2.Parse(t3, 5);
                }
            }

            return(true);
        }
Example #2
0
        public void Update(TSOMesh mesh)
        {
            vh.Clear();
            faces.Clear();

            foreach (TSOSubMesh sub_mesh in mesh.sub_meshes)
            {
                int    cnt = 0;
                ushort a = 0, b = 0, c = 0;
                Vertex va = new Vertex(), vb = new Vertex(), vc = new Vertex();

                foreach (Vertex v in sub_mesh.vertices)
                {
                    ++cnt;
                    va = vb; a = b;
                    vb = vc; b = c;
                    vc = v; c = vh.Add(new UVertex(v.Pos, v.Wgt, v.Idx, v.Nrm));

                    if (cnt < 3)
                    {
                        continue;
                    }
                    if (a == b || b == c || c == a)
                    {
                        continue;
                    }

                    if ((cnt & 1) == 0)
                    {
                        MqoFace f = new MqoFace(a, b, c, (ushort)sub_mesh.spec,
                                                new Point2(va.Tex.x, 1 - va.Tex.y),
                                                new Point2(vb.Tex.x, 1 - vb.Tex.y),
                                                new Point2(vc.Tex.x, 1 - vc.Tex.y));
                        faces.Add(f);
                    }
                    else
                    {
                        MqoFace f = new MqoFace(a, c, b, (ushort)sub_mesh.spec,
                                                new Point2(va.Tex.x, 1 - va.Tex.y),
                                                new Point2(vc.Tex.x, 1 - vc.Tex.y),
                                                new Point2(vb.Tex.x, 1 - vb.Tex.y));
                        faces.Add(f);
                    }
                }
            }
        }
Example #3
0
        protected override bool DoGenerateMeshes()
        {
            meshes = new List <TSOMesh>();

            foreach (MqoObject i in mqo.Objects)
            {
                if (i.name.ToLower() == "bone")
                {
                    continue;
                }

                Console.WriteLine("object:" + i.name);

                // 一番近い頂点への参照
                List <int> vref = new List <int>(i.vertices.Count);

                foreach (Point3 j in i.vertices)
                {
                    vref.Add(pc.NearestIndex(j.x, j.y, j.z));
                }

                // 法線生成
                Point3[] nrm = new Point3[i.vertices.Count];

                foreach (MqoFace j in i.faces)
                {
                    Point3 v1 = Point3.Normalize(i.vertices[j.b] - i.vertices[j.a]);
                    Point3 v2 = Point3.Normalize(i.vertices[j.c] - i.vertices[j.b]);
                    Point3 n  = Point3.Normalize(Point3.Cross(v1, v2));

                    nrm[j.a] -= n;
                    nrm[j.b] -= n;
                    nrm[j.c] -= n;
                }

                for (int j = 0; j < nrm.Length; ++j)
                {
                    nrm[j] = Point3.Normalize(nrm[j]);
                }

                // フェイスの組成
                List <int> faces1 = new List <int>();
                List <int> faces2 = new List <int>();
                //int[]                   bonecnv = new int[tsor.nodes.Length];   // ボーン変換テーブル
                VertexHeap <Vertex>   vh       = new VertexHeap <Vertex>();
                Vertex[]              v        = new Vertex[3];
                List <int>            bones    = new List <int>(16);
                List <ushort>         indices  = new List <ushort>();
                Dictionary <int, int> selected = new Dictionary <int, int>();
                Dictionary <int, int> work     = new Dictionary <int, int>();
                List <TSOSubMesh>     subs     = new List <TSOSubMesh>();

                for (int j = 0, n = i.faces.Count; j < n; ++j)
                {
                    faces1.Add(j);
                }

                #region ボーンパーティション
                Console.WriteLine("  vertices bone_indices");
                Console.WriteLine("  -------- ------------");

                while (faces1.Count > 0)
                {
                    int mtl = i.faces[faces1[0]].mtl;
                    selected.Clear();
                    indices.Clear();
                    vh.Clear();
                    bones.Clear();

                    foreach (int j in faces1)
                    {
                        MqoFace f = i.faces[j];

                        if (f.mtl != mtl)
                        {
                            faces2.Add(j);
                            continue;
                        }

                        v[0] = vlst[vref[f.a]];
                        v[1] = vlst[vref[f.b]];
                        v[2] = vlst[vref[f.c]];

                        work.Clear();

                        for (int k = 0; k < 3; ++k)
                        {
                            Vertex vv   = v[k];
                            UInt32 idx0 = vv.Idx;
                            Point4 wgt0 = vv.Wgt;
                            byte * idx  = (byte *)(&idx0);
                            float *wgt  = (float *)(&wgt0);

                            for (int l = 0; l < 4; ++l)
                            {
                                if (wgt[l] <= float.Epsilon)
                                {
                                    continue;
                                }
                                if (selected.ContainsKey(idx[l]))
                                {
                                    continue;
                                }

                                if (!work.ContainsKey(idx[l]))
                                {
                                    work.Add(idx[l], 0);
                                }
                            }
                        }

                        if (selected.Count + work.Count > 16)
                        {
                            faces2.Add(j);
                            continue;
                        }

                        // ボーンリストに足してvalid
                        foreach (KeyValuePair <int, int> l in work)
                        {
                            selected.Add(l.Key, selected.Count);    // ボーンテーブルに追加
                            bones.Add(l.Key);
                        }

                        // \todo 点の追加
                        Vertex va = new Vertex(i.vertices[f.a], v[0].Wgt, v[0].Idx, nrm[f.a], new Point2(f.ta.x, 1 - f.ta.y));
                        Vertex vb = new Vertex(i.vertices[f.b], v[1].Wgt, v[1].Idx, nrm[f.b], new Point2(f.tb.x, 1 - f.tb.y));
                        Vertex vc = new Vertex(i.vertices[f.c], v[2].Wgt, v[2].Idx, nrm[f.c], new Point2(f.tc.x, 1 - f.tc.y));

                        indices.Add(vh.Add(va));
                        indices.Add(vh.Add(vc));
                        indices.Add(vh.Add(vb));
                    }

                    // フェイス最適化
                    ushort[] nidx = NvTriStrip.Optimize(indices.ToArray());

                    // 頂点のボーン参照ローカルに変換
                    Vertex[] verts = vh.verts.ToArray();

                    for (int j = 0; j < verts.Length; ++j)
                    {
                        uint   idx0 = verts[j].Idx;
                        byte * idx  = (byte *)(&idx0);
                        Point4 wgt0 = verts[j].Wgt;
                        float *wgt  = (float *)(&wgt0);

                        for (int k = 0; k < 4; ++k)
                        {
                            if (wgt[k] > float.Epsilon)
                            {
                                idx[k] = (byte)selected[idx[k]];
                            }
                        }

                        verts[j].Idx = idx0;
                    }

                    // サブメッシュ生成
                    TSOSubMesh sub = new TSOSubMesh();
                    sub.spec        = mtl;
                    sub.numbones    = bones.Count;
                    sub.bones       = bones.ToArray();
                    sub.numvertices = nidx.Length;
                    sub.vertices    = new Vertex[nidx.Length];

                    for (int j = 0; j < nidx.Length; ++j)
                    {
                        sub.vertices[j] = verts[nidx[j]];
                    }

                    Console.WriteLine("  {0,8} {1,12}", sub.vertices.Length, sub.bones.Length);

                    subs.Add(sub);

                    // 次の周回
                    List <int> t = faces1;
                    faces1 = faces2;
                    faces2 = t;
                    t.Clear();
                }
                #endregion
                // \todo TSOMesh生成
                TSOMesh mesh = new TSOMesh();
                mesh.name    = i.name;
                mesh.numsubs = subs.Count;
                mesh.sub     = subs.ToArray();
                mesh.matrix  = Matrix44.Identity;
                mesh.effect  = 0;
                meshes.Add(mesh);
            }

            return(true);
        }
Example #4
0
        protected override bool DoGenerateMeshes()
        {
            meshes = new List <TSOMesh>();

            foreach (MqoObject obj in mqo.Objects)
            {
                if (obj.name.ToLower() == "bone")
                {
                    continue;
                }

                Console.WriteLine("object:" + obj.name);

                // 一番近い頂点への参照
                List <int> vref = new List <int>(obj.vertices.Count);

                foreach (UVertex i in obj.vertices)
                {
                    vref.Add(pc.NearestIndex(i.Pos.x, i.Pos.y, i.Pos.z));
                }

                obj.CreateNormal();

                List <int>             faces_1             = new List <int>();
                List <int>             faces_2             = new List <int>();
                Heap <int>             bh                  = new Heap <int>();
                Heap <Vertex>          vh                  = new Heap <Vertex>();
                Vertex[]               refvs               = new Vertex[3];
                List <ushort>          vert_indices        = new List <ushort>();
                Dictionary <int, bool> adding_bone_indices = new Dictionary <int, bool>();
                List <TSOSubMesh>      subs                = new List <TSOSubMesh>();

                for (int i = 0, n = obj.faces.Count; i < n; ++i)
                {
                    faces_1.Add(i);
                }

                #region ボーンパーティション
                Console.WriteLine("  vertices bone_indices");
                Console.WriteLine("  -------- ------------");

                while (faces_1.Count != 0)
                {
                    int spec = obj.faces[faces_1[0]].spec;
                    bh.Clear();
                    vh.Clear();
                    vert_indices.Clear();

                    foreach (int f in faces_1)
                    {
                        MqoFace face = obj.faces[f];

                        if (face.spec != spec)
                        {
                            faces_2.Add(f);
                            continue;
                        }

                        for (int k = 0; k < 3; ++k)
                        {
                            refvs[k] = refverts[vref[face.vert_indices[k]]];
                        }

                        adding_bone_indices.Clear();

                        for (int k = 0; k < 3; ++k)
                        {
                            UInt32 idx0 = refvs[k].Idx;
                            Point4 wgt0 = refvs[k].Wgt;
                            byte * idx  = (byte *)(&idx0);
                            float *wgt  = (float *)(&wgt0);

                            for (int l = 0; l < 4; ++l)
                            {
                                if (wgt[l] <= float.Epsilon)
                                {
                                    continue;
                                }
                                if (bh.map.ContainsKey(idx[l]))
                                {
                                    continue;
                                }

                                adding_bone_indices[idx[l]] = true;
                            }
                        }

                        if (bh.Count + adding_bone_indices.Count > 16)
                        {
                            faces_2.Add(f);
                            continue;
                        }

                        foreach (int i in adding_bone_indices.Keys)
                        {
                            bh.Add(i);
                        }

                        for (int k = 0; k < 3; ++k)
                        {
                            UInt32 idx0 = refvs[k].Idx;
                            Point4 wgt0 = refvs[k].Wgt;
                            byte * idx  = (byte *)(&idx0);
                            float *wgt  = (float *)(&wgt0);

                            for (int l = 0; l < 4; ++l)
                            {
                                if (wgt[l] <= float.Epsilon)
                                {
                                    continue;
                                }

                                idx[l] = (byte)bh[idx[l]];
                            }

                            refvs[k].Idx = idx0;
                        }

                        Vertex va = new Vertex(obj.vertices[face.a].Pos, refvs[0].Wgt, refvs[0].Idx, obj.vertices[face.a].Nrm, new Point2(face.ta.x, 1 - face.ta.y));
                        Vertex vb = new Vertex(obj.vertices[face.b].Pos, refvs[1].Wgt, refvs[1].Idx, obj.vertices[face.b].Nrm, new Point2(face.tb.x, 1 - face.tb.y));
                        Vertex vc = new Vertex(obj.vertices[face.c].Pos, refvs[2].Wgt, refvs[2].Idx, obj.vertices[face.c].Nrm, new Point2(face.tc.x, 1 - face.tc.y));

                        vert_indices.Add(vh.Add(va));
                        vert_indices.Add(vh.Add(vc));
                        vert_indices.Add(vh.Add(vb));
                    }

                    ushort[] optimized_indices = NvTriStrip.Optimize(vert_indices.ToArray());

                    TSOSubMesh sub = new TSOSubMesh();
                    sub.spec     = spec;
                    sub.numbones = bh.Count;
                    sub.bones    = bh.ary.ToArray();

                    sub.numvertices = optimized_indices.Length;
                    Vertex[] vertices = new Vertex[optimized_indices.Length];
                    for (int i = 0; i < optimized_indices.Length; ++i)
                    {
                        vertices[i] = vh.ary[optimized_indices[i]];
                    }
                    sub.vertices = vertices;

                    Console.WriteLine("  {0,8} {1,12}", sub.vertices.Length, sub.bones.Length);

                    subs.Add(sub);

                    List <int> faces_tmp = faces_1;
                    faces_1 = faces_2;
                    faces_2 = faces_tmp;
                    faces_tmp.Clear();
                }
                #endregion
                TSOMesh mesh = new TSOMesh();
                mesh.name       = obj.name;
                mesh.numsubs    = subs.Count;
                mesh.sub_meshes = subs.ToArray();
                mesh.matrix     = Matrix44.Identity;
                mesh.effect     = 0;
                meshes.Add(mesh);
            }

            return(true);
        }
Example #5
0
        bool SectionFace(string[] tokens)
        {
            if (tokens[0] == "}")
            {
                return(false);
            }

            int nface = int.Parse(tokens[0]);

            {
                StringBuilder sb = new StringBuilder();
                foreach (string i in tokens)
                {
                    sb.Append(' ').Append(i);
                }
                string line = sb.ToString().Trim();
                tokens = SplitString(line);
            }
            switch (nface)
            {
            case 3:
            {
                MqoFace f = new MqoFace();

                for (int i = 1; i < tokens.Length; ++i)
                {
                    string t = tokens[i];

                    if (t.StartsWith("V("))
                    {
                        string[] t3 = SplitParam(t);
                        f.a = ushort.Parse(t3[1]);
                        f.b = ushort.Parse(t3[2]);
                        f.c = ushort.Parse(t3[3]);
                    }
                    else if (t.StartsWith("M("))
                    {
                        string[] t3 = SplitParam(t);
                        f.spec = ushort.Parse(t3[1]);
                    }
                    else if (t.StartsWith("UV("))
                    {
                        string[] t3 = SplitParam(t);
                        f.ta = Point2.Parse(t3, 1);
                        f.tb = Point2.Parse(t3, 3);
                        f.tc = Point2.Parse(t3, 5);
                    }
                }
                obj.faces.Add(f);
            }
            break;

            case 4:
            {
                MqoFace f  = new MqoFace();
                MqoFace f2 = new MqoFace();

                for (int i = 1; i < tokens.Length; ++i)
                {
                    string t = tokens[i];

                    if (t.StartsWith("V("))
                    {
                        string[] t3 = SplitParam(t);
                        f.a  = ushort.Parse(t3[1]);
                        f.b  = ushort.Parse(t3[2]);
                        f.c  = ushort.Parse(t3[3]);
                        f2.a = f.a;
                        f2.b = f.c;
                        f2.c = ushort.Parse(t3[4]);
                    }
                    else if (t.StartsWith("M("))
                    {
                        string[] t3 = SplitParam(t);
                        f.spec  = ushort.Parse(t3[1]);
                        f2.spec = f.spec;
                    }
                    else if (t.StartsWith("UV("))
                    {
                        string[] t3 = SplitParam(t);
                        f.ta  = Point2.Parse(t3, 1);
                        f.tb  = Point2.Parse(t3, 3);
                        f.tc  = Point2.Parse(t3, 5);
                        f2.ta = f.ta;
                        f2.tb = f.tc;
                        f2.tc = Point2.Parse(t3, 7);
                    }
                }
                obj.faces.Add(f);
                obj.faces.Add(f2);
            }
            break;

            default:
                Console.WriteLine("unsupported: nface {0}", nface);
                break;
            }
            return(true);
        }