Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
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);
        }