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); } }
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); } }
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); }
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); } }
public void CreateTextureFile(TSOTex tex) { using (Bitmap bmp = CreateTextureBitmap(tex)) { string file = GetTexturePath(tex); bmp.Save(file); } }
public ImportTextureInfo(TSOTex tex) { Name = tex.Name; File = tex.File.Trim('"'); BytesPerPixel = tex.Depth; Width = tex.Width; Height = tex.Height; }
public ImportTextureInfo(TSOTex tex) { Name = tex.Name; File = tex.GetFileName(); BytesPerPixel = tex.Depth; Width = tex.Width; Height = tex.Height; }
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); }
string GetTexturePath(TSOTex tex) { string filename = Path.GetFileName(tex.File.Trim('"')); if (filename == "") { filename = "none"; } return(Path.Combine(OutPath, filename)); }
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(); } }
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); }
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); }
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); }
string GetTexturePath(TSOTex tex) { return(Path.Combine(OutPath, tex.GetFileName())); }
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]); } } } }
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); } }
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"); }
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(); }
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"); }
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; } }