Esempio n. 1
0
 public static void Write(BinaryWriter bw, TSOMesh item)
 {
     Write(bw, item.Name);
     Write(bw, item.Matrix);
     bw.Write(1);
     Write(bw, item.sub);
 }
Esempio n. 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);
                    }
                }
            }
        }
Esempio n. 3
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);
        }
Esempio n. 4
0
        void ReadAll()
        {
            byte[] magic = r.ReadBytes(4);

            if (magic[0] != (byte)'T' ||
                magic[1] != (byte)'S' ||
                magic[2] != (byte)'O' ||
                magic[3] != (byte)'1')
            {
                throw new Exception("File is not TSO");
            }

            //----- ノード -------------------------------------------------
            nodemap = new Dictionary <string, TSONode>();
            int count = r.ReadInt32();

            nodes = new TSONode[count];

            for (int i = 0; i < count; ++i)
            {
                nodes[i]      = new TSONode();
                nodes[i].id   = i;
                nodes[i].path = ReadString();
                nodes[i].name = nodes[i].path.Substring(nodes[i].path.LastIndexOf('|') + 1);
                nodemap.Add(nodes[i].path, nodes[i]);
            }

            for (int i = 0; i < count; ++i)
            {
                int index = nodes[i].path.LastIndexOf('|');

                if (index <= 0)
                {
                    continue;
                }

                string pname = nodes[i].path.Substring(0, index);
                nodes[i].parent = nodemap[pname];
                nodes[i].parent.children.Add(nodes[i]);
            }

            count = r.ReadInt32();

            // Node Matrix
            for (int i = 0; i < count; ++i)
            {
                nodes[i].matrix = ReadMatrix();
            }

            //----- テクスチャ ---------------------------------------------
            count      = r.ReadInt32();
            textures   = new TSOTex[count];
            texturemap = new Dictionary <string, TSOTex>();

            for (int i = 0; i < count; ++i)
            {
                textures[i]        = new TSOTex();
                textures[i].id     = i;
                textures[i].name   = ReadString();
                textures[i].File   = ReadString();
                textures[i].width  = r.ReadInt32();
                textures[i].height = r.ReadInt32();
                textures[i].depth  = r.ReadInt32();
                textures[i].data   = r.ReadBytes(textures[i].width * textures[i].height * textures[i].depth);
                texturemap.Add(textures[i].name, textures[i]);

                ExchangeChannel(textures[i].data, textures[i].depth);
            }

            //----- エフェクト ---------------------------------------------
            count   = r.ReadInt32();
            effects = new TSOEffect[count];

            for (int i = 0; i < count; ++i)
            {
                StringBuilder sb = new StringBuilder();
                effects[i]      = new TSOEffect();
                effects[i].name = ReadString();
                effects[i].line = r.ReadInt32();

                for (int j = 0; j < effects[i].line; ++j)
                {
                    sb.Append(ReadString()).Append('\n');
                }

                effects[i].code = sb.ToString();
            }

            //----- マテリアル ---------------------------------------------
            count     = r.ReadInt32();
            materials = new TSOMaterial[count];

            for (int i = 0; i < count; ++i)
            {
                StringBuilder sb = new StringBuilder();
                materials[i]      = new TSOMaterial();
                materials[i].id   = i;
                materials[i].name = ReadString();
                materials[i].file = ReadString();
                materials[i].line = r.ReadInt32();

                for (int j = 0; j < materials[i].line; ++j)
                {
                    sb.Append(ReadString()).Append('\n');
                }

                materials[i].code = sb.ToString();
                materials[i].ParseParameters();
            }

            //----- メッシュ -----------------------------------------------
            count  = r.ReadInt32();
            meshes = new TSOMesh[count];

            for (int i = 0; i < count; ++i)
            {
                meshes[i]            = new TSOMesh();
                meshes[i].file       = this;
                meshes[i].name       = ReadString();
                meshes[i].matrix     = ReadMatrix();
                meshes[i].effect     = r.ReadInt32();
                meshes[i].numsubs    = r.ReadInt32();
                meshes[i].sub_meshes = new TSOSubMesh[meshes[i].numsubs];

                for (int j = 0; j < meshes[i].numsubs; ++j)
                {
                    meshes[i].sub_meshes[j]          = new TSOSubMesh();
                    meshes[i].sub_meshes[j].owner    = meshes[i];
                    meshes[i].sub_meshes[j].spec     = r.ReadInt32();
                    meshes[i].sub_meshes[j].numbones = r.ReadInt32();
                    meshes[i].sub_meshes[j].bones    = new int[meshes[i].sub_meshes[j].numbones];

                    for (int k = 0; k < meshes[i].sub_meshes[j].numbones; ++k)
                    {
                        meshes[i].sub_meshes[j].bones[k] = r.ReadInt32();
                    }

                    meshes[i].sub_meshes[j].numvertices = r.ReadInt32();
                    Vertex[] v = new Vertex[meshes[i].sub_meshes[j].numvertices];
                    meshes[i].sub_meshes[j].vertices = v;

                    for (int k = 0; k < meshes[i].sub_meshes[j].numvertices; ++k)
                    {
                        ReadVertex(ref v[k]);
                    }
                }
            }
        }
Esempio n. 5
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);
        }
Esempio n. 6
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);
        }
Esempio n. 7
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);

                obj.CreateNormal();

                // ボーン情報作成
                uint   idx   = 0x00000000;
                Point4 wgt   = new Point4(1, 0, 0, 0);
                int[]  bones = CreateBones(obj);

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

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

                for (int spec = 0; spec < nummaterials; ++spec)
                {
                    vert_indices.Clear();

                    foreach (MqoFace face in obj.faces)
                    {
                        if (face.spec != spec)
                        {
                            continue;
                        }

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

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

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

                    TSOSubMesh sub = new TSOSubMesh();
                    sub.spec     = spec;
                    sub.numbones = bones.Length;
                    sub.bones    = bones;

                    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);
                }

                // メッシュ生成
                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);
        }
Esempio n. 8
0
        public void ReadAll()
        {
            byte[] magic = r.ReadBytes(4);

            if (magic[0] != (byte)'T' ||
                magic[1] != (byte)'S' ||
                magic[2] != (byte)'O' ||
                magic[3] != (byte)'1')
            {
                throw new Exception("File is not TSO");
            }

            //----- ノード -------------------------------------------------
            nodemap = new Dictionary <string, TSONode>();
            int count = r.ReadInt32();

            nodes = new TSONode[count];

            for (int i = 0; i < count; ++i)
            {
                nodes[i]       = new TSONode();
                nodes[i].id    = i;
                nodes[i].name  = ReadString();
                nodes[i].sname = nodes[i].name.Substring(nodes[i].name.LastIndexOf('|') + 1);
                nodemap.Add(nodes[i].name, nodes[i]);

                WriteLine(i + ": " + nodes[i].name);
            }

            for (int i = 0; i < count; ++i)
            {
                int index = nodes[i].name.LastIndexOf('|');

                if (index <= 0)
                {
                    continue;
                }

                string pname = nodes[i].name.Substring(0, index);
                WriteLine(pname);
                nodes[i].parent = nodemap[pname];
                nodes[i].parent.children.Add(nodes[i]);
            }

            WriteLine(r.BaseStream.Position.ToString("X"));

            count = r.ReadInt32();

            // Node Matrix
            for (int i = 0; i < count; ++i)
            {
                nodes[i].matrix = ReadMatrix();
            }

            WriteLine(r.BaseStream.Position.ToString("X"));

            //----- テクスチャ ---------------------------------------------
            count      = r.ReadInt32();
            textures   = new TSOTex[count];
            texturemap = new Dictionary <string, TSOTex>();

            for (int i = 0; i < count; ++i)
            {
                textures[i]        = new TSOTex();
                textures[i].id     = i;
                textures[i].name   = ReadString();
                textures[i].File   = ReadString();
                textures[i].width  = r.ReadInt32();
                textures[i].height = r.ReadInt32();
                textures[i].depth  = r.ReadInt32();
                textures[i].data   = r.ReadBytes(textures[i].width * textures[i].height * textures[i].depth);
                texturemap.Add(textures[i].name, textures[i]);

                ExchangeChannel(textures[i].data, textures[i].depth);

                WriteLine(r.BaseStream.Position.ToString("X"));
            }

            //----- エフェクト ---------------------------------------------
            count   = r.ReadInt32();
            effects = new TSOEffect[count];

            for (int i = 0; i < count; ++i)
            {
                StringBuilder sb = new StringBuilder();
                effects[i]      = new TSOEffect();
                effects[i].name = ReadString();
                effects[i].line = r.ReadInt32();

                for (int j = 0; j < effects[i].line; ++j)
                {
                    sb.Append(ReadString()).Append('\n');
                }

                effects[i].code = sb.ToString();

                WriteLine(r.BaseStream.Position.ToString("X"));
            }

            //----- マテリアル ---------------------------------------------
            count     = r.ReadInt32();
            materials = new TSOMaterial[count];

            for (int i = 0; i < count; ++i)
            {
                StringBuilder sb = new StringBuilder();
                materials[i]      = new TSOMaterial();
                materials[i].id   = i;
                materials[i].name = ReadString();
                materials[i].file = ReadString();
                materials[i].line = r.ReadInt32();

                for (int j = 0; j < materials[i].line; ++j)
                {
                    sb.Append(ReadString()).Append('\n');
                }

                materials[i].code = sb.ToString();
                materials[i].ParseParameters();

                WriteLine(r.BaseStream.Position.ToString("X"));
            }

            //----- メッシュ -----------------------------------------------
            count  = r.ReadInt32();
            meshes = new TSOMesh[count];
            int check = 0;

            for (int i = 0; i < count; ++i)
            {
                meshes[i]         = new TSOMesh();
                meshes[i].file    = this;
                meshes[i].name    = ReadString();
                meshes[i].matrix  = ReadMatrix();
                meshes[i].effect  = r.ReadInt32();
                meshes[i].numsubs = r.ReadInt32();
                meshes[i].sub     = new TSOSubMesh[meshes[i].numsubs];

                for (int j = 0; j < meshes[i].numsubs; ++j)
                {
                    meshes[i].sub[j]          = new TSOSubMesh();
                    meshes[i].sub[j].owner    = meshes[i];
                    meshes[i].sub[j].spec     = r.ReadInt32();
                    meshes[i].sub[j].numbones = r.ReadInt32();
                    meshes[i].sub[j].bones    = new int[meshes[i].sub[j].numbones];

                    meshes[i].sub[j].ink = materials[meshes[i].sub[j].spec].technique.ToUpper().IndexOf("INKOFF") < 0;
                    //meshes[i].sub[j].shadow     = specs[meshes[i].sub[j].spec].technique.ToUpper().IndexOf(Shadow

                    for (int k = 0; k < meshes[i].sub[j].numbones; ++k)
                    {
                        meshes[i].sub[j].bones[k] = r.ReadInt32();
                    }

                    meshes[i].sub[j].numvertices = r.ReadInt32();
                    Vertex[] v = new Vertex[meshes[i].sub[j].numvertices];
                    meshes[i].sub[j].vertices = v;

                    for (int k = 0; k < meshes[i].sub[j].numvertices; ++k)
                    {
                        ReadVertex(ref v[k]);
                    }

                    WriteLine(r.BaseStream.Position.ToString("X"));
                    System.Diagnostics.Debug.WriteLine(r.BaseStream.Position.ToString("X"));
                }
            }

            WriteLine(r.BaseStream.Position.ToString("X"));
            WriteLine(check.ToString("X"));

            r.BaseStream.Dispose();
        }