Exemplo n.º 1
0
        public void CreateNormal()
        {
            Point3[] normal = new Point3[vertices.Count];

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

            for (int i = 0; i < normal.Length; ++i)
            {
                vertices[i].Nrm = Point3.Normalize(normal[i]);
            }
        }
Exemplo 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);
        }
Exemplo n.º 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);

                // 法線生成
                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]);
                }

                // ボーン情報作成
                uint   idx   = 0x00000000;
                Point4 wgt   = new Point4(1, 0, 0, 0);
                int[]  bones = new int[1];
                string bone  = ObjectBoneNames[i.name];
                bones[0] = nodes[bone].ID;

                // マテリアル別に処理を実行
                List <ushort>       indices = new List <ushort>();
                VertexHeap <Vertex> vh      = new VertexHeap <Vertex>();
                List <TSOSubMesh>   subs    = new List <TSOSubMesh>();

                Console.WriteLine("  vertices bone_indices");
                Console.WriteLine("  -------- ------------");

                for (int j = 0, n = materials.Count; j < n; ++j)
                {
                    int mtl = j;
                    indices.Clear();

                    foreach (MqoFace f in i.faces)
                    {
                        if (f.mtl != mtl)
                        {
                            continue;
                        }

                        Vertex va = new Vertex(i.vertices[f.a], wgt, idx, nrm[f.a], new Point2(f.ta.x, 1 - f.ta.y));
                        Vertex vb = new Vertex(i.vertices[f.b], wgt, idx, nrm[f.b], new Point2(f.tb.x, 1 - f.tb.y));
                        Vertex vc = new Vertex(i.vertices[f.c], wgt, 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));
                    }

                    if (indices.Count == 0)
                    {
                        continue;
                    }

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

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

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

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

                    subs.Add(sub);
                }

                // メッシュ生成
                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);
        }