示例#1
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);
        }
示例#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);
        }
示例#3
0
        public void Write(TSOFile file)
        {
            tw.WriteLine("Metasequoia Document");
            tw.WriteLine("Format Text Ver 1.0");
            tw.WriteLine("");
            tw.WriteLine("Scene {");
            tw.WriteLine("\tpos -7.0446 4.1793 1541.1764");
            tw.WriteLine("\tlookat 11.8726 193.8590 0.4676");
            tw.WriteLine("\thead 0.8564");
            tw.WriteLine("\tpich 0.1708");
            tw.WriteLine("\tortho 0");
            tw.WriteLine("\tzoom2 31.8925");
            tw.WriteLine("\tamb 0.250 0.250 0.250");
            tw.WriteLine("}");

            VertexHeap <UVertex> vh   = new VertexHeap <UVertex>();
            List <ushort>        face = new List <ushort>(2048 * 3);
            List <float>         uv   = new List <float>(2048 * 3 * 2);
            List <int>           mtl  = new List <int>(2048);

            foreach (TSOTex tex in file.textures)
            {
                CreateTextureFile(tex);
            }

            tw.WriteLine("Material {0} {{", file.materials.Length);

            foreach (TSOMaterial mat in file.materials)
            {
                if (mat.ColorTex != null)
                {
                    TSOTex tex = file.texturemap[mat.ColorTex];
                    tw.WriteLine(
                        "\t\"{0}\" col(1.000 1.000 1.000 1.000) dif(0.800) amb(0.600) emi(0.000) spc(0.000) power(5.00) tex(\"{1}\")",
                        mat.name, GetTexturePath(tex));
                }
                else
                {
                    tw.WriteLine(
                        "\t\"{0}\" col(1.000 1.000 1.000 1.000) dif(0.800) amb(0.600) emi(0.000) spc(0.000) power(5.00))",
                        mat.name);
                }
            }

            tw.WriteLine("}");

            foreach (TSOMesh i in file.meshes)
            {
                vh.Clear();
                face.Clear();
                uv.Clear();
                mtl.Clear();

                foreach (TSOSubMesh j in i.sub)
                {
                    int    cnt = 0;
                    ushort a = 0, b = 0, c = 0;
                    Vertex va = new Vertex(), vb = new Vertex(), vc = new Vertex();

                    foreach (Vertex k in j.vertices)
                    {
                        ++cnt;
                        va = vb; a = b;
                        vb = vc; b = c;
                        vc = k;  c = vh.Add(new UVertex(k.Pos, k.Nrm, k.Tex, j.spec));

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

                        if ((cnt & 1) == 0)
                        {
                            face.Add(a); uv.Add(va.Tex.x); uv.Add(1 - va.Tex.y);
                            face.Add(b); uv.Add(vb.Tex.x); uv.Add(1 - vb.Tex.y);
                            face.Add(c); uv.Add(vc.Tex.x); uv.Add(1 - vc.Tex.y);
                            mtl.Add(j.spec);
                        }
                        else
                        {
                            face.Add(a); uv.Add(va.Tex.x); uv.Add(1 - va.Tex.y);
                            face.Add(c); uv.Add(vc.Tex.x); uv.Add(1 - vc.Tex.y);
                            face.Add(b); uv.Add(vb.Tex.x); uv.Add(1 - vb.Tex.y);
                            mtl.Add(j.spec);
                        }
                    }
                }

                tw.WriteLine("Object \"{0}\" {{", i.Name);
                tw.WriteLine("\tvisible {0}", 15);
                tw.WriteLine("\tlocking {0}", 0);
                tw.WriteLine("\tshading {0}", 1);
                tw.WriteLine("\tfacet {0}", 59.5);
                tw.WriteLine("\tcolor {0:F3} {1:F3} {2:F3}", 0.898f, 0.498f, 0.698f);
                tw.WriteLine("\tcolor_type {0}", 0);

                //
                tw.WriteLine("\tvertex {0} {{", vh.Count);

                foreach (UVertex j in vh.verts)
                {
                    WriteVertex(j.Pos.x, j.Pos.y, j.Pos.z);
                }

                tw.WriteLine("\t}");

                //
                tw.WriteLine("\tface {0} {{", face.Count / 3);

                System.Diagnostics.Debug.Assert(face.Count * 2 == uv.Count);
                System.Diagnostics.Debug.Assert(face.Count == mtl.Count * 3);

                for (int j = 0, n = face.Count; j < n; j += 3)
                {
                    WriteFace(face[j + 0], face[j + 1], face[j + 2],
                              uv[j * 2 + 0], uv[j * 2 + 1],
                              uv[j * 2 + 2], uv[j * 2 + 3],
                              uv[j * 2 + 4], uv[j * 2 + 5],
                              mtl[j / 3]);
                }
                tw.WriteLine("\t}");
                tw.WriteLine("}");
            }

            // ボーンを出す
            switch (BoneMode)
            {
            case MqoBoneMode.None:      break;

            case MqoBoneMode.RokDeBone:
            {
                // マトリクス計算
                foreach (TSONode i in file.nodes)
                {
                    if (i.parent == null)
                    {
                        i.world = i.Matrix;
                    }
                    else
                    {
                        i.world = Matrix44.Mul(i.Matrix, i.parent.World);
                    }
                }

                List <Point3> points = new List <Point3>();
                List <int>    bones  = new List <int>();

                tw.WriteLine("Object \"{0}\" {{", "Bone");
                tw.WriteLine("\tvisible {0}", 15);
                tw.WriteLine("\tlocking {0}", 0);
                tw.WriteLine("\tshading {0}", 1);
                tw.WriteLine("\tfacet {0}", 59.5);
                tw.WriteLine("\tcolor {0} {1} {2}", 1, 0, 0);
                tw.WriteLine("\tcolor_type {0}", 0);

                foreach (TSONode i in file.nodes)
                {
                    if (i.children.Count == 0)
                    {
                        continue;
                    }

                    Point3 q = new Point3(i.world.M41, i.world.M42, i.world.M43);
                    Point3 p = new Point3();

                    foreach (TSONode j in i.children)
                    {
                        p.x += j.world.M41;
                        p.y += j.world.M42;
                        p.z += j.world.M43;
                    }

                    p.x /= i.children.Count;
                    p.y /= i.children.Count;
                    p.z /= i.children.Count;

                    bones.Add(points.Count); points.Add(q);
                    bones.Add(points.Count); points.Add(p);
                }

                tw.WriteLine("\tvertex {0} {{", points.Count);

                foreach (Point3 j in points)
                {
                    WriteVertex(j.x, j.y, j.z);
                }

                tw.WriteLine("\t}");

                //
                tw.WriteLine("\tface {0} {{", bones.Count / 2);

                for (int j = 0, n = bones.Count; j < n; j += 2)
                {
                    tw.WriteLine(string.Format("\t\t2 V({0} {1})", bones[j + 0], bones[j + 1]));
                }

                tw.WriteLine("\t}");
                tw.WriteLine("}");
            }
            break;

            case MqoBoneMode.Mikoto:
            {
            }
            break;
            }

            tw.WriteLine("Eof");
        }