using System.Text;\r
using System.Runtime.InteropServices;\r
using System.ComponentModel;\r
-using System.Windows.Forms;\r
using System.Windows.Forms.Design;\r
\r
namespace Tso2MqoGui\r
{\r
public abstract class TSOGenerator\r
{\r
- private string dir;\r
- private TSOGenerateConfig config;\r
- protected MqoFile mqo;\r
- protected TSOFile tsor;\r
- protected Dictionary<string, TSONode> nodes;\r
- protected List<TSOMesh> meshes;\r
- private ImportInfo ii;\r
- private BinaryWriter bw;\r
- protected Dictionary<string, MaterialInfo> materials;\r
- private Dictionary<string, TextureInfo> textures;\r
-\r
- public TSOFile LoadTSO(string file)\r
+ string dir;\r
+ TSOGeneratorConfig config;\r
+ protected MqoReader mqo;\r
+ protected MqxReader mqx;\r
+ protected TSOFile tsoref;\r
+ protected List<TSOMesh> meshes;\r
+ ImportInfo ii;\r
+ BinaryWriter bw;\r
+ Dictionary<string, MaterialInfo> materials;\r
+ protected int nummaterials { get { return materials.Count; } }\r
+ Dictionary<string, TextureInfo> textures;\r
+\r
+ public TSOGenerator(TSOGeneratorConfig config)\r
{\r
- TSOFile tso = new TSOFile(file);\r
+ this.config = config;\r
+ }\r
+\r
+ public TSOFile LoadTSO(string file)\r
+ {\r
+ TSOFile tso = new TSOFile(file);\r
tso.ReadAll();\r
return tso;\r
}\r
\r
- private bool DoSetupDir(string mqoin)\r
+ bool SetCurrentDirectory(string dir)\r
{\r
- dir = Path.GetDirectoryName(mqoin);\r
+ this.dir = dir;\r
Environment.CurrentDirectory = dir;\r
return true;\r
}\r
\r
- private bool DoLoadMQO(string mqoin)\r
+ bool DoLoadMQO(string mqo_file)\r
{\r
// MQO読み込み\r
- mqo = new MqoFile();\r
- mqo.Load(mqoin);\r
- mqo.Dump();\r
+ mqo = new MqoReader();\r
+ mqo.Load(mqo_file);\r
+ return true;\r
+ }\r
+\r
+ bool DoLoadMqx(string mqo_file)\r
+ {\r
+ // Mqx読み込み\r
+ mqx = new MqxReader();\r
+ if (mqx.Load(mqo_file))\r
+ {\r
+ mqx.CreateWeits();\r
+ mqx.CreateWeitMap();\r
+ }\r
return true;\r
}\r
\r
- private bool DoLoadXml(string importinfo_file)\r
+ bool DoLoadXml(string importinfo_file)\r
{\r
// XML読み込み\r
ii = ImportInfo.Load(importinfo_file);\r
\r
foreach (MaterialInfo i in materials.Values)\r
{\r
- string name = Path.GetFileNameWithoutExtension(i.diffuse);\r
+ string color_tex_name = Path.GetFileNameWithoutExtension(i.ColorTexture);\r
\r
- if (!textures.ContainsKey(name))\r
- textures.Add(name, new TextureInfo(name, i.diffuse));\r
+ if (color_tex_name != null && !textures.ContainsKey(color_tex_name))\r
+ textures.Add(color_tex_name, new TextureInfo(color_tex_name, i.ColorTexture));\r
\r
- name = Path.GetFileNameWithoutExtension(i.shadow);\r
+ string shade_tex_name = Path.GetFileNameWithoutExtension(i.ShadeTexture);\r
\r
- if (!textures.ContainsKey(name))\r
- textures.Add(name, new TextureInfo(name, i.shadow));\r
+ if (shade_tex_name != null && !textures.ContainsKey(shade_tex_name))\r
+ textures.Add(shade_tex_name, new TextureInfo(shade_tex_name, i.ShadeTexture));\r
}\r
\r
return true;\r
}\r
\r
- private bool DoWriteHeader()\r
+ bool DoWriteHeader()\r
{\r
bw.Write(0x314F5354);\r
return true;\r
}\r
\r
- private bool DoWriteNodeNames()\r
+ bool DoWriteNodeNames()\r
{\r
- bw.Write(tsor.nodes.Length);\r
-\r
- nodes = new Dictionary<string,TSONode>();\r
+ if (tsoref != null)\r
+ {\r
+ bw.Write(tsoref.nodes.Length);\r
\r
- foreach(TSONode i in tsor.nodes)\r
+ foreach (TSONode i in tsoref.nodes)\r
+ WriteString(bw, i.Path);\r
+ }\r
+ else if (mqx != null)\r
{\r
- WriteString(bw, i.Name);\r
- nodes.Add(i.ShortName, i);\r
+ bw.Write(mqx.bones.Length);\r
+\r
+ foreach (MqoBone i in mqx.bones)\r
+ WriteString(bw, i.path);\r
}\r
+ else\r
+ return false;\r
\r
return true;\r
}\r
\r
- private bool DoWriteNodeMatrices()\r
+ bool DoWriteNodeMatrices()\r
{\r
- bw.Write(tsor.nodes.Length);\r
+ if (tsoref != null)\r
+ {\r
+ bw.Write(tsoref.nodes.Length);\r
+\r
+ foreach (TSONode i in tsoref.nodes)\r
+ WriteMatrix(bw, i.Matrix);\r
+ }\r
+ else if (mqx != null)\r
+ {\r
+ bw.Write(mqx.bones.Length);\r
\r
- foreach(TSONode i in tsor.nodes)\r
- WriteMatrix(bw, i.Matrix);\r
+ foreach (MqoBone i in mqx.bones)\r
+ WriteMatrix(bw, i.matrix);\r
+ }\r
+ else\r
+ return false;\r
\r
return true;\r
}\r
\r
- private bool DoWriteTextures()\r
+ bool DoWriteTextures()\r
{\r
bw.Write(textures.Count);\r
\r
- foreach(TextureInfo i in textures.Values)\r
+ foreach (TextureInfo tex_info in textures.Values)\r
{\r
- string file= i.file;\r
- string name= i.name;\r
+ string file = tex_info.file;\r
+ string name = tex_info.name;\r
+\r
+ string file_directory_name = Path.GetDirectoryName(file);\r
+ string file_name = Path.GetFileName(file);\r
\r
WriteString(bw, name);\r
- WriteString(bw, "\"" + Path.GetFileName(file) + "\"");\r
+ WriteString(bw, "\"" + file_name + "\"");\r
\r
// テクスチャの読み込み\r
- TSOTex tex = LoadTex(file);\r
- tex.name = name;\r
+ TSOTex tex = LoadTex(file);\r
+ tex.name = name;\r
bw.Write(tex.Width);\r
bw.Write(tex.Height);\r
bw.Write(tex.Depth);\r
bw.Write(tex.data, 0, tex.data.Length);\r
\r
- ImportTextureInfo iti = new ImportTextureInfo(tex);\r
- ii.textures.Add(iti);\r
+ ImportTextureInfo import_tex_info = new ImportTextureInfo(tex);\r
+ ii.textures.Add(import_tex_info);\r
\r
// テクスチャが同じフォルダにない場合、コピーしておく\r
- if(Path.GetDirectoryName(file).ToUpper() != dir.ToUpper())\r
+ if (file_directory_name != "" && file_directory_name.ToUpper() != dir.ToUpper())\r
{\r
- iti.File = Path.Combine(dir, Path.GetFileName(file));\r
- File.Copy(file, iti.File, true);\r
+ import_tex_info.File = Path.Combine(dir, file_name);\r
+ File.Copy(file, import_tex_info.File, true);\r
}\r
}\r
\r
return true;\r
}\r
\r
- private bool DoWriteEffects()\r
+ bool DoWriteEffects()\r
{\r
bw.Write(ii.effects.Count);\r
\r
- foreach(ImportEffectInfo i in ii.effects)\r
+ foreach (ImportEffectInfo import_effect_info in ii.effects)\r
{\r
- string file= Path.Combine(dir, i.Name);\r
- string[] code= File.ReadAllLines(file, Encoding.Default);\r
+ string file = Path.Combine(dir, import_effect_info.Name);\r
+ string[] code = File.ReadAllLines(file, Encoding.Default);\r
\r
- WriteString(bw, i.Name);\r
+ WriteString(bw, import_effect_info.Name);\r
bw.Write(code.Length);\r
\r
- foreach(string j in code)\r
- WriteString(bw, j.Trim('\r', '\n'));\r
+ foreach (string line in code)\r
+ WriteString(bw, line.Trim('\r', '\n'));\r
}\r
\r
return true;\r
}\r
\r
- private bool DoWriteMaterials()\r
+ bool DoWriteMaterials()\r
{\r
bw.Write(mqo.Materials.Count);\r
\r
- foreach(MqoMaterial i in mqo.Materials)\r
+ foreach (MqoMaterial mat in mqo.Materials)\r
{\r
- MaterialInfo mi = materials[i.name];\r
- string[] code= mi.GetCode();\r
+ MaterialInfo mat_info = materials[mat.name];\r
+ string[] code = mat_info.GetCode();\r
\r
- WriteString(bw, i.name);\r
+ WriteString(bw, mat.name);\r
WriteString(bw, "cgfxShader");\r
bw.Write(code.Length);\r
\r
- foreach(string j in code)\r
- WriteString(bw, j.Trim('\r', '\n'));\r
+ foreach (string line in code)\r
+ WriteString(bw, line.Trim('\r', '\n'));\r
\r
- ImportMaterialInfo imi = new ImportMaterialInfo();\r
- imi.Name = i.name;\r
- imi.File = "cgfxShader";\r
- ii.materials.Add(imi);\r
+ ImportMaterialInfo import_mat_info = new ImportMaterialInfo();\r
+ import_mat_info.Name = mat.name;\r
+ import_mat_info.File = "cgfxShader";\r
+ ii.materials.Add(import_mat_info);\r
\r
// コードを保存する\r
- File.WriteAllLines(Path.Combine(dir, i.name), code);\r
+ File.WriteAllLines(Path.Combine(dir, mat.name), code);\r
}\r
\r
return true;\r
}\r
\r
- private bool DoWriteMeshes()\r
+ bool DoWriteMeshes()\r
{\r
bw.Write(meshes.Count);\r
\r
- foreach(TSOMesh i in meshes)\r
+ foreach (TSOMesh mesh in meshes)\r
{\r
- WriteString(bw, i.Name);\r
- WriteMatrix(bw, i.Matrix);\r
+ WriteString(bw, mesh.Name);\r
+ WriteMatrix(bw, mesh.Matrix);\r
bw.Write(1);\r
- bw.Write(i.numsubs);\r
+ bw.Write(mesh.numsubs);\r
\r
- foreach(TSOSubMesh j in i.sub)\r
+ foreach (TSOSubMesh sub in mesh.sub_meshes)\r
{\r
- bw.Write(j.spec);\r
- bw.Write(j.numbones);\r
+ bw.Write(sub.spec);\r
+ bw.Write(sub.numbones);\r
\r
- foreach(int k in j.bones)\r
- bw.Write(k);\r
+ foreach (int i in sub.bones)\r
+ bw.Write(i);\r
\r
- bw.Write(j.numvertices);\r
+ bw.Write(sub.numvertices);\r
\r
- foreach(Vertex k in j.vertices)\r
- WriteVertex(bw, k);\r
+ foreach (Vertex v in sub.vertices)\r
+ WriteVertex(bw, v);\r
}\r
}\r
\r
return true;\r
}\r
\r
- private bool DoOutput(string tsoex)\r
+ bool DoOutput(string path)\r
{\r
//----- 出力処理 -----------------------------------------------\r
ii.materials.Clear();\r
ii.textures.Clear();\r
\r
- using (FileStream fs = File.OpenWrite(tsoex))\r
+ using (FileStream fs = File.OpenWrite(path))\r
{\r
fs.SetLength(0);\r
bw = new BinaryWriter(fs);\r
\r
return true;\r
}\r
+\r
+ //メッシュリストを生成する。\r
+ //メッシュリストはthis.meshesに保持する。\r
protected abstract bool DoGenerateMeshes();\r
\r
- private bool DoSaveXml(string importinfo_file)\r
+ bool DoSaveXml(string importinfo_file)\r
{\r
// 結果を保存しておく\r
ImportInfo.Save(importinfo_file, ii);\r
return true;\r
}\r
\r
- private bool DoCleanup()\r
+ protected virtual bool DoCleanup()\r
{\r
- dir = null;\r
- tsor = null;\r
- nodes = null;\r
- meshes = null;\r
- config = null;\r
- mqo = null;\r
- ii = null;\r
- bw = null;\r
- materials = null;\r
- textures = null;\r
+ dir = null;\r
+ tsoref = null;\r
+ meshes = null;\r
+ mqo = null;\r
+ ii = null;\r
+ bw = null;\r
+ materials = null;\r
+ textures = null;\r
\r
System.GC.Collect();\r
return true;\r
}\r
\r
- public void Generate(string mqoin, string tsoref, string tsoex, TSOGenerateConfig config)\r
+ public void Generate(string mqo_file, string tsoref_file, string tsoout_file)\r
{\r
- this.config = config;\r
- string importinfo_file = Path.ChangeExtension(mqoin, ".xml");\r
+ string dir = Path.GetDirectoryName(mqo_file);\r
+ string importinfo_file = Path.ChangeExtension(mqo_file, ".xml");\r
\r
try\r
{\r
- if (!DoSetupDir(mqoin)) return;\r
- if (!DoLoadMQO(mqoin)) return;\r
- if (!DoLoadRefTSO(tsoref)) return;\r
+ if (!SetCurrentDirectory(dir)) return;\r
+ if (!DoLoadMQO(mqo_file)) return;\r
+ if (!DoLoadMqx(mqo_file)) return;\r
+ if (!DoLoadRefTSO(tsoref_file)) return;\r
if (!DoLoadXml(importinfo_file)) return;\r
- if (!DoOutput(tsoex)) return;\r
+ if (!DoOutput(tsoout_file)) return;\r
if (!DoSaveXml(importinfo_file)) return;\r
}\r
finally\r
DoCleanup();\r
}\r
}\r
- \r
- protected abstract bool DoLoadRefTSO(string tsoref);\r
\r
-#region ユーティリティ\r
+ // 参照tsoを読み込む。\r
+ // 参照tsoはthis.tsorefに保持する。\r
+ protected abstract bool DoLoadRefTSO(string path);\r
+\r
+ #region ユーティリティ\r
public void WriteString(BinaryWriter bw, string s)\r
{\r
- byte[] b = Encoding.Default.GetBytes(s);\r
+ byte[] b = Encoding.Default.GetBytes(s);\r
bw.Write(b);\r
bw.Write((byte)0);\r
}\r
\r
public unsafe void WriteVertex(BinaryWriter bw, Vertex v)\r
{\r
- uint idx0 = v.Idx;\r
- byte* idx = (byte*)(&idx0);\r
- List<int> idxs = new List<int>(4);\r
- List<float> wgts = new List<float>(4);\r
+ uint idx0 = v.Idx;\r
+ byte* idx = (byte*)(&idx0);\r
+ List<int> idxs = new List<int>(4);\r
+ List<float> wgts = new List<float>(4);\r
\r
- if(v.Wgt.x > 0) { idxs.Add(idx[0]); wgts.Add(v.Wgt.x); }\r
- if(v.Wgt.y > 0) { idxs.Add(idx[1]); wgts.Add(v.Wgt.y); }\r
- if(v.Wgt.z > 0) { idxs.Add(idx[2]); wgts.Add(v.Wgt.z); }\r
- if(v.Wgt.w > 0) { idxs.Add(idx[3]); wgts.Add(v.Wgt.w); }\r
+ if (v.Wgt.x > 0) { idxs.Add(idx[0]); wgts.Add(v.Wgt.x); }\r
+ if (v.Wgt.y > 0) { idxs.Add(idx[1]); wgts.Add(v.Wgt.y); }\r
+ if (v.Wgt.z > 0) { idxs.Add(idx[2]); wgts.Add(v.Wgt.z); }\r
+ if (v.Wgt.w > 0) { idxs.Add(idx[3]); wgts.Add(v.Wgt.w); }\r
\r
bw.Write(v.Pos.X); bw.Write(v.Pos.Y); bw.Write(v.Pos.Z);\r
bw.Write(v.Nrm.X); bw.Write(v.Nrm.Y); bw.Write(v.Nrm.Z);\r
\r
bw.Write(wgts.Count);\r
\r
- for(int i= 0, n= idxs.Count; i < n; ++i)\r
+ for (int i = 0, n = idxs.Count; i < n; ++i)\r
{\r
bw.Write(idxs[i]);\r
bw.Write(wgts[i]);\r
}\r
}\r
-#endregion\r
-#region テクスチャ処理\r
- public TSOTex LoadTex(string file)\r
+ #endregion\r
+ #region テクスチャ処理\r
+ public TSOTex LoadTex(string file)\r
{\r
- string ext = Path.GetExtension(file).ToUpper();\r
- TSOTex tex;\r
+ string ext = Path.GetExtension(file).ToUpper();\r
+ TSOTex tex;\r
\r
- switch(ext)\r
+ switch (ext)\r
{\r
- case ".TGA": tex= LoadTarga(file); break;\r
- case ".BMP": tex= LoadBitmap(file); break;\r
- default: throw new Exception("Unsupported texture file: " + file);\r
+ case ".TGA": tex = LoadTarga(file); break;\r
+ case ".BMP": tex = LoadBitmap(file); break;\r
+ default: throw new Exception("Unsupported texture file: " + file);\r
}\r
\r
- for(int i= 0, n= tex.data.Length; i < n; i+=tex.Depth)\r
+ for (int i = 0, n = tex.data.Length; i < n; i += tex.Depth)\r
{\r
- byte b = tex.data[i+0];\r
- tex.data[i+0] = tex.data[i+2];\r
- tex.data[i+2] = b;\r
+ byte b = tex.data[i + 0];\r
+ tex.data[i + 0] = tex.data[i + 2];\r
+ tex.data[i + 2] = b;\r
}\r
\r
return tex;\r
}\r
\r
- public unsafe TSOTex LoadTarga(string file)\r
+ public unsafe TSOTex LoadTarga(string file)\r
{\r
- using(FileStream fs= File.OpenRead(file))\r
+ using (FileStream fs = File.OpenRead(file))\r
{\r
- BinaryReader br = new BinaryReader(fs);\r
- TARGA_HEADER header;\r
+ BinaryReader br = new BinaryReader(fs);\r
+ TARGA_HEADER header;\r
\r
Marshal.Copy(br.ReadBytes(sizeof(TARGA_HEADER)), 0, (IntPtr)(&header), sizeof(TARGA_HEADER));\r
\r
- if(header.imagetype != 0x02) throw new Exception("Invalid imagetype: " + file);\r
- if(header.depth != 24\r
- && header.depth != 32) throw new Exception("Invalid depth: " + file);\r
- \r
- TSOTex tex = new TSOTex();\r
- tex.depth = header.depth / 8;\r
- tex.width = header.width;\r
- tex.height = header.height;\r
- tex.File = file;\r
- tex.data = br.ReadBytes(tex.width * tex.height * tex.depth);\r
+ if (header.imagetype != 0x02) throw new Exception("Invalid imagetype: " + file);\r
+ if (header.depth != 24\r
+ && header.depth != 32) throw new Exception("Invalid depth: " + file);\r
+\r
+ TSOTex tex = new TSOTex();\r
+ tex.depth = header.depth / 8;\r
+ tex.width = header.width;\r
+ tex.height = header.height;\r
+ tex.File = file;\r
+ tex.data = br.ReadBytes(tex.width * tex.height * tex.depth);\r
\r
return tex;\r
}\r
}\r
\r
- public unsafe TSOTex LoadBitmap(string file)\r
+ public unsafe TSOTex LoadBitmap(string file)\r
{\r
- using(FileStream fs= File.OpenRead(file))\r
+ using (FileStream fs = File.OpenRead(file))\r
{\r
- BinaryReader br = new BinaryReader(fs);\r
- BITMAPFILEHEADER bfh;\r
- BITMAPINFOHEADER bih;\r
+ BinaryReader br = new BinaryReader(fs);\r
+ BITMAPFILEHEADER bfh;\r
+ BITMAPINFOHEADER bih;\r
\r
Marshal.Copy(br.ReadBytes(sizeof(BITMAPFILEHEADER)), 0, (IntPtr)(&bfh), sizeof(BITMAPFILEHEADER));\r
Marshal.Copy(br.ReadBytes(sizeof(BITMAPINFOHEADER)), 0, (IntPtr)(&bih), sizeof(BITMAPINFOHEADER));\r
\r
- if(bfh.bfType != 0x4D42) throw new Exception("Invalid imagetype: " + file);\r
- if(bih.biBitCount != 24\r
- && bih.biBitCount != 32) throw new Exception("Invalid depth: " + file);\r
- \r
- TSOTex tex = new TSOTex();\r
- tex.depth = bih.biBitCount / 8;\r
- tex.width = bih.biWidth;\r
- tex.height = bih.biHeight;\r
- tex.File = file;\r
- tex.data = br.ReadBytes(tex.width * tex.height * tex.depth);\r
-\r
- return tex;\r
- }\r
- }\r
-#endregion\r
- }\r
-\r
- public class TSOGeneratorOneBone : TSOGenerator\r
- {\r
- public Dictionary<string, string> ObjectBoneNames = new Dictionary<string, string>();\r
-\r
- protected override bool DoLoadRefTSO(string tsoref)\r
- {\r
- // 参照TSOロード\r
- tsor = LoadTSO(tsoref);\r
- return true;\r
- }\r
-\r
- protected override bool DoGenerateMeshes()\r
- {\r
- meshes = new List<TSOMesh>();\r
-\r
- foreach(MqoObject i in mqo.Objects)\r
- {\r
- if(i.name.ToLower() == "bone")\r
- continue;\r
-\r
- Console.WriteLine("object:" + i.name);\r
-\r
- // 法線生成\r
- Point3[] nrm = new Point3[i.vertices.Count];\r
- \r
- foreach(MqoFace j in i.faces)\r
- {\r
- Point3 v1 = Point3.Normalize(i.vertices[j.b] - i.vertices[j.a]);\r
- Point3 v2 = Point3.Normalize(i.vertices[j.c] - i.vertices[j.b]);\r
- Point3 n = Point3.Normalize(Point3.Cross(v1, v2));\r
- nrm[j.a] -=n;\r
- nrm[j.b] -=n;\r
- nrm[j.c] -=n;\r
- }\r
-\r
- for(int j= 0; j < nrm.Length; ++j)\r
- nrm[j] = Point3.Normalize(nrm[j]);\r
-\r
- // ボーン情報作成\r
- uint idx = 0x00000000;\r
- Point4 wgt = new Point4(1, 0, 0, 0);\r
- int[] bones = new int[1];\r
- string bone = ObjectBoneNames[i.name];\r
- bones[0] = nodes[bone].ID;\r
-\r
- // マテリアル別に処理を実行\r
- List<ushort> indices = new List<ushort>();\r
- VertexHeap<Vertex> vh = new VertexHeap<Vertex>();\r
- List<TSOSubMesh> subs = new List<TSOSubMesh>();\r
-\r
- Console.WriteLine(" vertices bone_indices");\r
- Console.WriteLine(" -------- ------------");\r
-\r
- for(int j= 0, n= materials.Count; j < n; ++j)\r
- {\r
- int mtl = j;\r
- indices.Clear();\r
-\r
- foreach(MqoFace f in i.faces)\r
- {\r
- if(f.mtl != mtl)\r
- continue;\r
-\r
- Vertex va = new Vertex(i.vertices[f.a], wgt, idx, nrm[f.a], new Point2(f.ta.x, 1-f.ta.y));\r
- Vertex vb = new Vertex(i.vertices[f.b], wgt, idx, nrm[f.b], new Point2(f.tb.x, 1-f.tb.y));\r
- Vertex vc = new Vertex(i.vertices[f.c], wgt, idx, nrm[f.c], new Point2(f.tc.x, 1-f.tc.y));\r
-\r
- indices.Add(vh.Add(va));\r
- indices.Add(vh.Add(vc));\r
- indices.Add(vh.Add(vb));\r
- }\r
-\r
- if(indices.Count == 0)\r
- continue;\r
-\r
- // フェイス最適化\r
- ushort[] nidx = NvTriStrip.Optimize(indices.ToArray());\r
-\r
- // サブメッシュ生成\r
- Vertex[] verts= vh.verts.ToArray();\r
- TSOSubMesh sub = new TSOSubMesh();\r
- sub.spec = mtl;\r
- sub.numbones = bones.Length;\r
- sub.bones = bones;\r
- sub.numvertices = nidx.Length;\r
- sub.vertices = new Vertex[nidx.Length];\r
- \r
- for(int k= 0; k < nidx.Length; ++k)\r
- sub.vertices[k] = verts[nidx[k]];\r
-\r
- Console.WriteLine(" {0,8} {1,12}", sub.vertices.Length, sub.bones.Length);\r
-\r
- subs.Add(sub);\r
- }\r
-\r
- // メッシュ生成\r
- TSOMesh mesh = new TSOMesh();\r
- mesh.name = i.name;\r
- mesh.numsubs = subs.Count;\r
- mesh.sub = subs.ToArray();\r
- mesh.matrix = Matrix44.Identity;\r
- mesh.effect = 0;\r
- meshes.Add(mesh);\r
- }\r
-\r
- return true;\r
- }\r
-\r
- }\r
- \r
- public unsafe class TSOGeneratorRefBone : TSOGenerator\r
- {\r
- private List<Vertex> vlst;\r
- private PointCluster pc;\r
-\r
- private void CreatePointCluster(TSOFile tso)\r
- {\r
- vlst= new List<Vertex>();\r
-\r
- foreach(TSOMesh i in tso.meshes)\r
- foreach(TSOSubMesh j in i.sub)\r
- vlst.AddRange(j.vertices);\r
-\r
- pc = new PointCluster(vlst.Count);\r
-\r
- foreach(Vertex i in vlst)\r
- pc.Add(i.Pos.x, i.Pos.y, i.Pos.z);\r
-\r
- pc.Clustering();\r
- }\r
-\r
- protected override bool DoLoadRefTSO(string tsoref)\r
- {\r
- // 参照TSOロード\r
- tsor = LoadTSO(tsoref);\r
-\r
- foreach(TSOMesh i in tsor.meshes)\r
- foreach(TSOSubMesh j in i.sub)\r
- {\r
- int[] bones = j.bones;\r
-\r
- for(int k= 0, n= j.numvertices; k < n; ++k)\r
- {\r
- // ボーンをグローバルな番号に変換\r
- uint idx0= j.vertices[k].Idx;\r
- byte* idx = (byte*)(&idx0);\r
- idx[0] = (byte)bones[idx[0]];\r
- idx[1] = (byte)bones[idx[1]];\r
- idx[2] = (byte)bones[idx[2]];\r
- idx[3] = (byte)bones[idx[3]];\r
- j.vertices[k].Idx = idx0;\r
- }\r
- }\r
-\r
- CreatePointCluster(tsor);\r
- return true;\r
- }\r
-\r
- protected override bool DoGenerateMeshes()\r
- {\r
- meshes = new List<TSOMesh>();\r
-\r
- foreach(MqoObject i in mqo.Objects)\r
- {\r
- if(i.name.ToLower() == "bone")\r
- continue;\r
-\r
- Console.WriteLine("object:" + i.name);\r
-\r
- // 一番近い頂点への参照\r
- List<int> vref= new List<int>(i.vertices.Count);\r
-\r
- foreach(Point3 j in i.vertices)\r
- vref.Add(pc.NearestIndex(j.x, j.y, j.z));\r
-\r
- // 法線生成\r
- Point3[] nrm = new Point3[i.vertices.Count];\r
- \r
- foreach(MqoFace j in i.faces)\r
- {\r
- Point3 v1 = Point3.Normalize(i.vertices[j.b] - i.vertices[j.a]);\r
- Point3 v2 = Point3.Normalize(i.vertices[j.c] - i.vertices[j.b]);\r
- Point3 n = Point3.Normalize(Point3.Cross(v1, v2));\r
+ if (bfh.bfType != 0x4D42) throw new Exception("Invalid imagetype: " + file);\r
+ if (bih.biBitCount != 24\r
+ && bih.biBitCount != 32) throw new Exception("Invalid depth: " + file);\r
\r
- nrm[j.a] -=n;\r
- nrm[j.b] -=n;\r
- nrm[j.c] -=n;\r
- }\r
+ TSOTex tex = new TSOTex();\r
+ tex.depth = bih.biBitCount / 8;\r
+ tex.width = bih.biWidth;\r
+ tex.height = bih.biHeight;\r
+ tex.File = file;\r
+ tex.data = br.ReadBytes(tex.width * tex.height * tex.depth);\r
\r
- for(int j= 0; j < nrm.Length; ++j)\r
- nrm[j] = Point3.Normalize(nrm[j]);\r
-\r
- // フェイスの組成\r
- List<int> faces1 = new List<int>();\r
- List<int> faces2 = new List<int>();\r
- //int[] bonecnv = new int[tsor.nodes.Length]; // ボーン変換テーブル\r
- VertexHeap<Vertex> vh = new VertexHeap<Vertex>();\r
- Vertex[] v = new Vertex[3];\r
- List<int> bones = new List<int>(16);\r
- List<ushort> indices = new List<ushort>();\r
- Dictionary<int, int> selected= new Dictionary<int,int>();\r
- Dictionary<int, int> work = new Dictionary<int,int>();\r
- List<TSOSubMesh> subs = new List<TSOSubMesh>();\r
-\r
- for(int j= 0, n= i.faces.Count; j < n; ++j)\r
- faces1.Add(j);\r
-\r
-#region ボーンパーティション\r
- Console.WriteLine(" vertices bone_indices");\r
- Console.WriteLine(" -------- ------------");\r
-\r
- while (faces1.Count > 0)\r
- {\r
- int mtl = i.faces[faces1[0]].mtl;\r
- selected.Clear();\r
- indices .Clear();\r
- vh .Clear();\r
- bones .Clear();\r
-\r
- foreach(int j in faces1)\r
- {\r
- MqoFace f = i.faces[j];\r
-\r
- if(f.mtl != mtl)\r
- {\r
- faces2.Add(j);\r
- continue;\r
- }\r
-\r
- v[0] = vlst[vref[f.a]];\r
- v[1] = vlst[vref[f.b]];\r
- v[2] = vlst[vref[f.c]];\r
-\r
- work.Clear();\r
-\r
- for(int k= 0; k < 3; ++k)\r
- {\r
- Vertex vv = v[k];\r
- UInt32 idx0 = vv.Idx;\r
- Point4 wgt0 = vv.Wgt;\r
- byte* idx = (byte*)(&idx0);\r
- float* wgt = (float*)(&wgt0);\r
-\r
- for(int l= 0; l < 4; ++l)\r
- {\r
- if(wgt[l] <= float.Epsilon) continue;\r
- if(selected.ContainsKey(idx[l])) continue;\r
- \r
- if(!work.ContainsKey(idx[l]))\r
- work.Add(idx[l], 0);\r
- }\r
- }\r
-\r
- if (selected.Count + work.Count > 16)\r
- {\r
- faces2.Add(j);\r
- continue;\r
- }\r
-\r
- // ボーンリストに足してvalid\r
- foreach(KeyValuePair<int, int> l in work)\r
- {\r
- selected.Add(l.Key, selected.Count); // ボーンテーブルに追加\r
- bones.Add(l.Key);\r
- }\r
-\r
- // \todo 点の追加\r
- 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));\r
- 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));\r
- 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));\r
-\r
- indices.Add(vh.Add(va));\r
- indices.Add(vh.Add(vc));\r
- indices.Add(vh.Add(vb));\r
- }\r
-\r
- // フェイス最適化\r
- ushort[] nidx = NvTriStrip.Optimize(indices.ToArray());\r
-\r
- // 頂点のボーン参照ローカルに変換\r
- Vertex[] verts = vh.verts.ToArray();\r
-\r
- for(int j= 0; j < verts.Length; ++j)\r
- {\r
- uint idx0= verts[j].Idx;\r
- byte* idx = (byte*)(&idx0);\r
- Point4 wgt0= verts[j].Wgt;\r
- float* wgt = (float*)(&wgt0);\r
-\r
- for(int k= 0; k < 4; ++k)\r
- if(wgt[k] > float.Epsilon)\r
- idx[k] = (byte)selected[idx[k]];\r
-\r
- verts[j].Idx = idx0;\r
- }\r
-\r
- // サブメッシュ生成\r
- TSOSubMesh sub = new TSOSubMesh();\r
- sub.spec = mtl;\r
- sub.numbones = bones.Count;\r
- sub.bones = bones.ToArray();\r
- sub.numvertices = nidx.Length;\r
- sub.vertices = new Vertex[nidx.Length];\r
- \r
- for(int j= 0; j < nidx.Length; ++j)\r
- sub.vertices[j] = verts[nidx[j]];\r
-\r
- Console.WriteLine(" {0,8} {1,12}", sub.vertices.Length, sub.bones.Length);\r
-\r
- subs.Add(sub);\r
-\r
- // 次の周回\r
- List<int> t = faces1;\r
- faces1 = faces2;\r
- faces2 = t;\r
- t.Clear();\r
- }\r
-#endregion\r
- // \todo TSOMesh生成\r
- TSOMesh mesh = new TSOMesh();\r
- mesh.name = i.name;\r
- mesh.numsubs = subs.Count;\r
- mesh.sub = subs.ToArray();\r
- mesh.matrix = Matrix44.Identity;\r
- mesh.effect = 0;\r
- meshes.Add(mesh);\r
+ return tex;\r
}\r
-\r
- return true;\r
}\r
-\r
+ #endregion\r
}\r
\r
public class TextureInfo\r
\r
public TextureInfo(string name, string file)\r
{\r
- this.name = name;\r
- this.file = file;\r
+ this.name = name;\r
+ this.file = file;\r
}\r
}\r
\r
public class MaterialInfo\r
{\r
- public string name;\r
- public string shader;\r
- public string diffuse;\r
- public string shadow;\r
- //public Dictionary<string, string> parameters;\r
+ string name;\r
+ string shader;\r
+ string color_tex;\r
+ string shade_tex;\r
+ //public Dictionary<string, string> parameters;\r
\r
- public MaterialInfo(string path, MqoMaterial mqom, ImportMaterialInfo impm)\r
+ public MaterialInfo(string path, MqoMaterial mat, ImportMaterialInfo import_mat_info)\r
{\r
- name = mqom.name;\r
- diffuse = mqom.tex;\r
+ name = mat.name;\r
+ color_tex = mat.tex;\r
\r
- if(impm != null)\r
+ if (import_mat_info != null)\r
{\r
- string file= Path.Combine(path, impm.Name);\r
+ string file = Path.Combine(path, import_mat_info.Name);\r
\r
- if(File.Exists(file))\r
- shader = file;\r
+ if (File.Exists(file))\r
+ shader = import_mat_info.Name;\r
\r
- if(impm.shadow != null)\r
+ if (import_mat_info.ShadeTex != null)\r
{\r
- file = Path.Combine(path, impm.shadow.File);\r
+ file = Path.Combine(path, import_mat_info.ShadeTex.File);\r
\r
- if(File.Exists(file))\r
- shadow = file;\r
+ if (File.Exists(file))\r
+ shade_tex = import_mat_info.ShadeTex.File;\r
}\r
}\r
}\r
\r
- public bool Valid\r
+ public bool Valid\r
{\r
get\r
{\r
- return File.Exists(shader)\r
- && File.Exists(diffuse)\r
- && File.Exists(shadow);\r
+ return File.Exists(shader);\r
}\r
}\r
\r
public string[] GetCode()\r
{\r
- TSOMaterialCode code= TSOMaterialCode.GenerateFromFile(shader);\r
- List<string> line= new List<string>();\r
-\r
- code.SetValue("ColorTex", Path.GetFileNameWithoutExtension(diffuse));\r
- code.SetValue("ShadeTex", Path.GetFileNameWithoutExtension(shadow));\r
-\r
- foreach(KeyValuePair<string, TSOParameter> i in code)\r
+ TSOMaterialCode code = TSOMaterialCode.GenerateFromFile(shader);\r
+ if (color_tex != null)\r
+ code.SetValue("ColorTex", Path.GetFileNameWithoutExtension(color_tex));\r
+ if (shade_tex != null)\r
+ code.SetValue("ShadeTex", Path.GetFileNameWithoutExtension(shade_tex));\r
+\r
+ List<string> line = new List<string>();\r
+ foreach (KeyValuePair<string, TSOParameter> i in code)\r
line.Add(i.Value.ToString());\r
\r
return line.ToArray();\r
}\r
\r
- public string Name { get { return name; } }\r
- \r
+ public string Name { get { return name; } }\r
+\r
[Editor(typeof(FileNameEditor), typeof(UITypeEditor))]\r
[DisplayNameAttribute("シェーダー設定ファイル")]\r
- public string ShaderFile { get { return shader; } set { shader = value; } }\r
- \r
+ public string ShaderFile { get { return shader; } set { shader = value; } }\r
+\r
[Editor(typeof(FileNameEditor), typeof(UITypeEditor))]\r
[DisplayNameAttribute("テクスチャ:カラー")]\r
- public string DiffuseTexture { get { return diffuse; } set { diffuse = value; } }\r
+ public string ColorTexture { get { return color_tex; } set { color_tex = value; } }\r
\r
[Editor(typeof(FileNameEditor), typeof(UITypeEditor))]\r
[DisplayNameAttribute("テクスチャ:シェーティング")]\r
- public string ShadowTexture { get { return shadow; } set { shadow = value; } }\r
+ public string ShadeTexture { get { return shade_tex; } set { shade_tex = value; } }\r
}\r
}\r