Exemple #1
0
        public unsafe TSOTex   LoadTarga(string file)
        {
            using (FileStream fs = File.OpenRead(file))
            {
                BinaryReader br = new BinaryReader(fs);
                TARGA_HEADER header;

                Marshal.Copy(br.ReadBytes(sizeof(TARGA_HEADER)), 0, (IntPtr)(&header), sizeof(TARGA_HEADER));

                if (header.imagetype != 0x02)
                {
                    throw new Exception("Invalid imagetype: " + file);
                }
                if (header.depth != 24 &&
                    header.depth != 32)
                {
                    throw new Exception("Invalid depth: " + file);
                }

                TSOTex tex = new TSOTex();
                tex.depth  = header.depth / 8;
                tex.width  = header.width;
                tex.height = header.height;
                tex.File   = file;
                tex.data   = br.ReadBytes(tex.width * tex.height * tex.depth);

                return(tex);
            }
        }
Exemple #2
0
        public unsafe TSOTex   LoadBitmap(string file)
        {
            using (FileStream fs = File.OpenRead(file))
            {
                BinaryReader     br = new BinaryReader(fs);
                BITMAPFILEHEADER bfh;
                BITMAPINFOHEADER bih;

                Marshal.Copy(br.ReadBytes(sizeof(BITMAPFILEHEADER)), 0, (IntPtr)(&bfh), sizeof(BITMAPFILEHEADER));
                Marshal.Copy(br.ReadBytes(sizeof(BITMAPINFOHEADER)), 0, (IntPtr)(&bih), sizeof(BITMAPINFOHEADER));

                if (bfh.bfType != 0x4D42)
                {
                    throw new Exception("Invalid imagetype: " + file);
                }
                if (bih.biBitCount != 24 &&
                    bih.biBitCount != 32)
                {
                    throw new Exception("Invalid depth: " + file);
                }

                TSOTex tex = new TSOTex();
                tex.depth  = bih.biBitCount / 8;
                tex.width  = bih.biWidth;
                tex.height = bih.biHeight;
                tex.File   = file;
                tex.data   = br.ReadBytes(tex.width * tex.height * tex.depth);

                return(tex);
            }
        }
Exemple #3
0
        private bool DoWriteTextures()
        {
            bw.Write(textures.Count);

            foreach (TextureInfo i in textures.Values)
            {
                string file = i.file;
                string name = i.name;

                WriteString(bw, name);
                WriteString(bw, "\"" + Path.GetFileName(file) + "\"");

                // テクスチャの読み込み
                TSOTex tex = LoadTex(file);
                tex.name = name;
                bw.Write(tex.Width);
                bw.Write(tex.Height);
                bw.Write(tex.Depth);
                bw.Write(tex.data, 0, tex.data.Length);

                ImportTextureInfo iti = new ImportTextureInfo(tex);
                ii.textures.Add(iti);

                // テクスチャが同じフォルダにない場合、コピーしておく
                if (Path.GetDirectoryName(file).ToUpper() != dir.ToUpper())
                {
                    iti.File = Path.Combine(dir, Path.GetFileName(file));
                    File.Copy(file, iti.File, true);
                }
            }

            return(true);
        }
Exemple #4
0
        unsafe TSOTex LoadTGA(string file)
        {
            using (FileStream fs = File.OpenRead(file))
            {
                BinaryReader br = new BinaryReader(fs);
                TARGA_HEADER header;

                Marshal.Copy(br.ReadBytes(sizeof(TARGA_HEADER)), 0, (IntPtr)(&header), sizeof(TARGA_HEADER));

                if (header.imagetype != 0x02)
                {
                    throw new Exception("Invalid imagetype: " + file);
                }
                if (header.depth != 24 && header.depth != 32)
                {
                    throw new Exception("Invalid depth: " + file);
                }

                TSOTex tex = new TSOTex();
                tex.depth  = header.depth / 8;
                tex.width  = header.width;
                tex.height = header.height;
                tex.File   = file;
                tex.data   = br.ReadBytes(tex.width * tex.height * tex.depth);

                for (int i = 0, n = tex.data.Length; i < n; i += tex.Depth)
                {
                    byte b = tex.data[i + 0];
                    tex.data[i + 0] = tex.data[i + 2];
                    tex.data[i + 2] = b;
                }

                return(tex);
            }
        }
Exemple #5
0
 public void CreateTextureFile(TSOTex tex)
 {
     using (Bitmap bmp = CreateTextureBitmap(tex))
     {
         string file = GetTexturePath(tex);
         bmp.Save(file);
     }
 }
Exemple #6
0
 public ImportTextureInfo(TSOTex tex)
 {
     Name          = tex.Name;
     File          = tex.File.Trim('"');
     BytesPerPixel = tex.Depth;
     Width         = tex.Width;
     Height        = tex.Height;
 }
Exemple #7
0
 public ImportTextureInfo(TSOTex tex)
 {
     Name          = tex.Name;
     File          = tex.GetFileName();
     BytesPerPixel = tex.Depth;
     Width         = tex.Width;
     Height        = tex.Height;
 }
Exemple #8
0
 public static void Write(BinaryWriter bw, TSOTex item)
 {
     Write(bw, item.name);
     Write(bw, item.File);
     bw.Write(item.Width);
     bw.Write(item.Height);
     bw.Write(item.Depth);
     bw.Write(item.data, 0, item.data.Length);
 }
Exemple #9
0
        string GetTexturePath(TSOTex tex)
        {
            string filename = Path.GetFileName(tex.File.Trim('"'));

            if (filename == "")
            {
                filename = "none";
            }
            return(Path.Combine(OutPath, filename));
        }
Exemple #10
0
        public void CreateTextureFile(TSOTex tex)
        {
            string file = GetTexturePath(tex);

            byte[] data = tex.data;


            using (FileStream fs = File.OpenWrite(file))
            {
                BinaryWriter bw = new BinaryWriter(fs);

                switch (Path.GetExtension(file).ToUpper())
                {
                case ".TGA":
                    bw.Write((byte)0);               // id
                    bw.Write((byte)0);               // colormap
                    bw.Write((byte)2);               // imagetype
                    bw.Write((byte)0);               // unknown0
                    bw.Write((byte)0);               // unknown1
                    bw.Write((byte)0);               // unknown2
                    bw.Write((byte)0);               // unknown3
                    bw.Write((byte)0);               // unknown4
                    bw.Write((short)0);              // width
                    bw.Write((short)0);              // height
                    bw.Write((short)tex.Width);      // width
                    bw.Write((short)tex.Height);     // height
                    bw.Write((byte)(tex.depth * 8)); // depth
                    bw.Write((byte)0);               // depth
                    break;

                case ".BMP":
                    bw.Write((byte)'B');
                    bw.Write((byte)'M');
                    bw.Write((int)(54 + data.Length));
                    bw.Write((int)0);
                    bw.Write((int)54);
                    bw.Write((int)40);
                    bw.Write((int)tex.Width);
                    bw.Write((int)tex.Height);
                    bw.Write((short)1);
                    bw.Write((short)(tex.Depth * 8));
                    bw.Write((int)0);
                    bw.Write((int)data.Length);
                    bw.Write((int)0);
                    bw.Write((int)0);
                    bw.Write((int)0);
                    bw.Write((int)0);
                    break;
                }

                bw.Write(data, 0, data.Length);
                bw.Flush();
            }
        }
Exemple #11
0
        public Bitmap CreateTextureBitmap(TSOTex tex)
        {
            GCHandle handle = GCHandle.Alloc(tex.data, GCHandleType.Pinned);
            //NOTE: no exception
            IntPtr ptr = handle.AddrOfPinnedObject();
            //NOTE: no exception
            Bitmap bmp = new Bitmap(tex.Width, tex.Height, tex.Depth * tex.Width, PixelFormat.Format32bppArgb, ptr);

            //NOTE: no exception
            handle.Free();
            bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
            return(bmp);
        }
Exemple #12
0
        TSOTex LoadPNG(string file)
        {
            TSOTex tex = new TSOTex();

            using (Bitmap bmp = new Bitmap(file))
            {
                bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
                BitmapData bmp_data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat);

                IntPtr ptr    = bmp_data.Scan0;
                int    stride = bmp_data.Stride;
                //bool bottom_up = (stride < 0);
                if (stride < 0)
                {
                    stride = -stride;
                }
                int    bytes = stride * bmp_data.Height;
                byte[] data  = new byte[bytes];
                //NOTE: no exception
                Marshal.Copy(ptr, data, 0, bytes);

                bmp.UnlockBits(bmp_data);

                tex.depth  = stride / bmp_data.Width;
                tex.width  = bmp_data.Width;
                tex.height = bmp_data.Height;
                tex.File   = file;
                tex.data   = data;
            }

            for (int i = 0, n = tex.data.Length; i < n; i += tex.Depth)
            {
                byte b = tex.data[i + 0];
                tex.data[i + 0] = tex.data[i + 2];
                tex.data[i + 2] = b;
            }

            return(tex);
        }
Exemple #13
0
        bool DoWriteTextures()
        {
            bw.Write(textures.Count);

            foreach (TextureInfo tex_info in textures.Values)
            {
                string file = tex_info.file;
                string name = tex_info.name;

                string file_directory_name = Path.GetDirectoryName(file);
                string file_name           = Path.GetFileName(file);

                WriteString(bw, name);
                WriteString(bw, "\"" + file_name + "\"");

                // テクスチャの読み込み
                TSOTex tex = LoadTex(file);
                tex.name = name;
                bw.Write(tex.Width);
                bw.Write(tex.Height);
                bw.Write(tex.Depth);
                bw.Write(tex.data, 0, tex.data.Length);

                ImportTextureInfo import_tex_info = new ImportTextureInfo(tex);
                ii.textures.Add(import_tex_info);

                // テクスチャが同じフォルダにない場合、コピーしておく
                if (file_directory_name != "" && file_directory_name.ToUpper() != dir.ToUpper())
                {
                    import_tex_info.File = Path.Combine(dir, file_name);
                    File.Copy(file, import_tex_info.File, true);
                }
            }

            return(true);
        }
Exemple #14
0
 string GetTexturePath(TSOTex tex)
 {
     return(Path.Combine(OutPath, tex.GetFileName()));
 }
Exemple #15
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]);
                    }
                }
            }
        }
Exemple #16
0
        TSOTex LoadBMP(string file)
        {
            using (FileStream fs = File.OpenRead(file))
            {
                BinaryReader     br = new BinaryReader(fs);
                BITMAPFILEHEADER bfh;
                BITMAPINFOHEADER bih;

                byte[] buf;

                bfh.bfType = br.ReadUInt16();

                if (bfh.bfType != 0x4D42)
                {
                    throw new Exception("Invalid imagetype: " + file);
                }

                buf             = br.ReadBytes(12);
                bfh.bfSize      = BitConverter.ToUInt32(buf, 0x00);
                bfh.bfReserved1 = BitConverter.ToUInt16(buf, 0x04);
                bfh.bfReserved2 = BitConverter.ToUInt16(buf, 0x06);
                bfh.bfOffBits   = BitConverter.ToUInt16(buf, 0x08);

                uint biSize = br.ReadUInt32();

                buf                 = br.ReadBytes((int)biSize - 4);
                bih.biWidth         = BitConverter.ToInt32(buf, 0x00);
                bih.biHeight        = BitConverter.ToInt32(buf, 0x04);
                bih.biPlanes        = BitConverter.ToUInt16(buf, 0x08);
                bih.biBitCount      = BitConverter.ToUInt16(buf, 0x0A);
                bih.biCompression   = BitConverter.ToUInt32(buf, 0x0C);
                bih.biSizeImage     = BitConverter.ToUInt32(buf, 0x10);
                bih.biXPelsPerMeter = BitConverter.ToInt32(buf, 0x14);
                bih.biYPelsPerMeter = BitConverter.ToInt32(buf, 0x18);
                bih.biClrUsed       = BitConverter.ToUInt32(buf, 0x1C);
                bih.biClrImportant  = BitConverter.ToUInt32(buf, 0x20);
                if (biSize == 40)
                {
                    bih.bV5RedMask   = 0x00ff0000;
                    bih.bV5GreenMask = 0x0000ff00;
                    bih.bV5BlueMask  = 0x000000ff;
                    bih.bV5AlphaMask = 0;
                }
                else if (biSize >= 56)
                {
                    bih.bV5RedMask   = BitConverter.ToUInt32(buf, 0x24);
                    bih.bV5GreenMask = BitConverter.ToUInt32(buf, 0x28);
                    bih.bV5BlueMask  = BitConverter.ToUInt32(buf, 0x2C);
                    bih.bV5AlphaMask = BitConverter.ToUInt32(buf, 0x30);
                }

                if (bih.biBitCount != 24 && bih.biBitCount != 32)
                {
                    throw new Exception("Invalid depth: " + file);
                }

                TSOTex tex = new TSOTex();
                tex.depth  = bih.biBitCount / 8;
                tex.width  = bih.biWidth;
                tex.height = bih.biHeight;
                tex.File   = file;
                tex.data   = br.ReadBytes(tex.width * tex.height * tex.depth);

                if (biSize == 40)
                {
                    for (int i = 0, n = tex.data.Length; i < n; i += tex.Depth)
                    {
                        byte b = tex.data[i + 0];
                        tex.data[i + 0] = tex.data[i + 2];
                        tex.data[i + 2] = b;
                    }
                }
                else if (biSize >= 56)
                {
                    for (int i = 0, n = tex.data.Length; i < n; i += tex.Depth)
                    {
                        byte b0 = tex.data[i + 0];
                        byte b1 = tex.data[i + 1];
                        byte b2 = tex.data[i + 2];
                        byte b3 = tex.data[i + 3];
                        tex.data[i + 0] = b3;
                        tex.data[i + 1] = b2;
                        tex.data[i + 2] = b1;
                        tex.data[i + 3] = b0;
                    }
                }

                return(tex);
            }
        }
Exemple #17
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");
        }
Exemple #18
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();
        }
Exemple #19
0
        public void Write(TSOFile tso)
        {
            tw.WriteLine("Metasequoia Document");
            tw.WriteLine("Format Text Ver 1.0");
            tw.WriteLine("");
            if (MqxEnabled)
            {
                tw.WriteLine("IncludeXml \"{0}\"", Path.ChangeExtension(Path.GetFileName(OutFile), ".mqx"));
                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("}");

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

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

            foreach (TSOMaterial mat in tso.materials)
            {
                TSOTex tex = null;
                if (tso.texturemap.TryGetValue(mat.ColorTex, out tex))
                {
                    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, tex.GetFileName());
                }
                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("}");

            MqoBone[] bones = null;

            if (MqxEnabled)
            {
                bones = CreateBones(tso);
            }

            MqoObjectGen.uid_enabled = MqxEnabled;
            MqoObjectGen obj = new MqoObjectGen();

            ushort object_id = 0;

            foreach (TSOMesh mesh in tso.meshes)
            {
                obj.id   = ++object_id;
                obj.name = mesh.Name;
                obj.Update(mesh);
                obj.Write(tw);

                if (MqxEnabled)
                {
                    obj.AddWeits(bones);
                }
            }

            if (MqxEnabled)
            {
                MqxWriter writer = new MqxWriter();
                writer.MqoFile = OutFile;
                writer.Write(bones, object_id /* eq numobjects */);
            }

            tw.WriteLine("Eof");
        }
Exemple #20
0
        private void btnMerge_Click(object sender, EventArgs e)
        {
            Color c = tabPage2.BackColor;

            try
            {
                tabPage2.BackColor = Color.Tomato;
                List <TSOMesh> meshes = new List <TSOMesh>();
                Dictionary <string, KeyValuePair <TSOMaterial, int> > materialmap = new Dictionary <string, KeyValuePair <TSOMaterial, int> >();
                Dictionary <string, TSOTex> textures = new Dictionary <string, TSOTex>();
                TSOFile last = null;

                foreach (TreeNode node in tvMerge.Nodes)
                {
                    TSOFile tso = new TSOFile();
                    last = tso;
                    ulong mtls = 0;
                    ulong mask = 1;
                    tso.Load(node.Text);

                    foreach (TSOMesh mesh in tso.meshes)
                    {
                        TreeNode[] found = node.Nodes.Find(mesh.Name, false);

                        if (found.Length == 0 || !found[0].Checked)
                        {
                            continue;
                        }

                        foreach (TSOSubMesh k in mesh.sub_meshes)
                        {
                            mtls |= 1ul << k.spec;
                        }

                        meshes.Add(mesh);
                    }

                    foreach (TSOMaterial mat in tso.materials)
                    {
                        if ((mask & mtls) != 0)
                        {
                            if (!materialmap.ContainsKey(mat.Name))
                            {
                                materialmap.Add(mat.Name, new KeyValuePair <TSOMaterial, int>(mat, materialmap.Count));

                                if (!textures.ContainsKey(mat.ColorTex))
                                {
                                    TSOTex tex = tso.texturemap[mat.ColorTex];
                                    textures.Add(tex.Name, tex);
                                }

                                if (!textures.ContainsKey(mat.ShadeTex))
                                {
                                    TSOTex tex = tso.texturemap[mat.ShadeTex];
                                    textures.Add(tex.Name, tex);
                                }
                            }
                        }

                        mask <<= 1;
                    }
                }

                using (FileStream fs = File.OpenWrite(tbMergeTso.Text))
                {
                    fs.SetLength(0);

                    List <TSOTex> texlist = new List <TSOTex>(textures.Values);
                    TSOMaterial[] mtllist = new TSOMaterial[materialmap.Count];

                    foreach (var i in materialmap.Values)
                    {
                        mtllist[i.Value] = i.Key;
                    }

                    foreach (TSOMesh mesh in meshes)
                    {
                        foreach (TSOSubMesh sub in mesh.sub_meshes)
                        {
                            TSOMaterial spec = mesh.file.materials[sub.spec];
                            sub.spec = materialmap[spec.Name].Value;
                        }
                    }

                    foreach (TSOTex tex in texlist)
                    {
                        TSOFile.ExchangeChannel(tex.data, tex.depth);
                    }

                    BinaryWriter bw = new BinaryWriter(fs);
                    TSOWriter.WriteHeader(bw);
                    TSOWriter.Write(bw, last.nodes);
                    TSOWriter.Write(bw, texlist.ToArray());
                    TSOWriter.Write(bw, last.effects);
                    TSOWriter.Write(bw, mtllist);
                    TSOWriter.Write(bw, meshes.ToArray());
                }
            }
            catch (Exception exception)
            {
                Util.ProcessError(exception);
            }
            finally
            {
                tabPage2.BackColor = c;
            }
        }