-using System;\r
-using System.Collections.Generic;\r
-using System.ComponentModel;\r
-using System.Data;\r
-using System.Drawing;\r
-using System.IO;\r
-using System.Text;\r
-using System.Windows.Forms;\r
-using Microsoft.Win32;\r
-\r
-namespace Tso2MqoGui\r
-{\r
- public partial class Form1 : Form\r
- {\r
- public string OutPath\r
- {\r
- get { return tbPath.Text; }\r
- set { tbPath.Text= value; }\r
- }\r
-\r
- public Form1()\r
- {\r
- InitializeComponent();\r
- }\r
-\r
- private void Form1_Load(object sender, EventArgs e)\r
- {\r
- RegistryKey reg = Application.UserAppDataRegistry.CreateSubKey("Config");\r
- OutPath = (string)reg.GetValue("OutPath", Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));\r
- tabControl1.SelectedIndex = (int)reg.GetValue("TabPage", 0);\r
- tbMqoIn.Text = (string)reg.GetValue("MqoIn", "");\r
- tbTso.Text = (string)reg.GetValue("Tso", "");\r
- tbTsoEx.Text = (string)reg.GetValue("TsoEx", "");\r
- tbMergeTso.Text = (string)reg.GetValue("MergeTso", "");\r
- rbRefBone.Checked = (int)reg.GetValue("RefBone", 1) == 1;\r
- rbOneBone.Checked = (int)reg.GetValue("OneBone", 0) == 1;\r
- rbBoneNone.Checked = (int)reg.GetValue("BoneNone", 1) == 1;\r
- rbBoneRokDeBone.Checked = (int)reg.GetValue("BoneRokDeBone", 0) == 1;\r
- cbMakeSub.Checked = (int)reg.GetValue("MakeSub", 1) == 1;\r
- cbCopyTSO.Checked = (int)reg.GetValue("CopyTSO", 1) == 1;\r
- cbShowMaterials.Checked = (int)reg.GetValue("ShowMaterials", 0) == 1;\r
-\r
- reg = Application.UserAppDataRegistry.CreateSubKey("Form1");\r
- Bounds = new Rectangle(\r
- (int)reg.GetValue("Left", 0),\r
- (int)reg.GetValue("Top", 0),\r
- (int)reg.GetValue("Width", 640),\r
- (int)reg.GetValue("Height", 320));\r
-\r
- EnableControlStuff();\r
-\r
- Config config = Config.Instance;\r
- }\r
-\r
- private void Form1_FormClosed(object sender, FormClosedEventArgs e)\r
- {\r
- RegistryKey reg = Application.UserAppDataRegistry.CreateSubKey("Config");\r
- reg.SetValue("OutPath", OutPath);\r
- reg.SetValue("TabPage", tabControl1.SelectedIndex);\r
- reg.SetValue("MqoIn", tbMqoIn.Text);\r
- reg.SetValue("Tso", tbTso.Text);\r
- reg.SetValue("TsoEx", tbTsoEx.Text);\r
- reg.SetValue("MergeTso", tbMergeTso.Text);\r
- reg.SetValue("RefBone", rbRefBone.Checked ? 1 : 0);\r
- reg.SetValue("OneBone", rbOneBone.Checked ? 1 : 0);\r
- reg.SetValue("BoneNone", rbBoneNone.Checked ? 1 : 0);\r
- reg.SetValue("BoneRokDeBone", rbBoneRokDeBone.Checked ? 1 : 0);\r
- reg.SetValue("MakeSub", cbMakeSub.Checked ? 1 : 0);\r
- reg.SetValue("CopyTSO", cbCopyTSO.Checked ? 1 : 0);\r
- reg.SetValue("ShowMaterials", cbShowMaterials.Checked ? 1 : 0);\r
-\r
- reg= Application.UserAppDataRegistry.CreateSubKey("Form1");\r
-\r
- if((this.WindowState & FormWindowState.Minimized) == FormWindowState.Minimized)\r
- {\r
- reg.SetValue("Top", RestoreBounds.Top);\r
- reg.SetValue("Left", RestoreBounds.Left);\r
- reg.SetValue("Width", RestoreBounds.Width);\r
- reg.SetValue("Height", RestoreBounds.Height);\r
- } else\r
- {\r
- reg.SetValue("Top", Top);\r
- reg.SetValue("Left", Left);\r
- reg.SetValue("Width", Width);\r
- reg.SetValue("Height", Height);\r
- }\r
-\r
- Config.Save();\r
- }\r
-\r
- private void Form1_DragDrop(object sender, DragEventArgs e)\r
- {\r
- try\r
- {\r
- if(!e.Data.GetDataPresent(DataFormats.FileDrop))\r
- return;\r
-\r
- string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);\r
-\r
- if(files.Length == 0)\r
- return;\r
-\r
- switch(tabControl1.SelectedIndex)\r
- {\r
- case 0:\r
- foreach(string i in files)\r
- {\r
- if(Path.GetExtension(i).ToUpper() == ".TSO")\r
- OpenTSOFile(i);\r
- }\r
-\r
- break;\r
-\r
- case 1:\r
- switch (Path.GetExtension(files[0]).ToUpper())\r
- {\r
- case ".TSO": tbTso.Text = files[0]; break;\r
- case ".MQO": tbMqoIn.Text = files[0]; break;\r
- }\r
-\r
- break;\r
-\r
- case 2:\r
- AddMergeTso(files);\r
- break;\r
- }\r
- } catch(Exception ex)\r
- {\r
- Util.ProcessError(ex);\r
- }\r
- }\r
-\r
- private void Form1_DragEnter(object sender, DragEventArgs e)\r
- {\r
- if(!e.Data.GetDataPresent(DataFormats.FileDrop))\r
- return;\r
-\r
- e.Effect = DragDropEffects.Copy;\r
- }\r
-\r
- private void tbMergeTso_DragDrop(object sender, DragEventArgs e)\r
- {\r
- if(!e.Data.GetDataPresent(DataFormats.FileDrop))\r
- return;\r
-\r
- string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);\r
-\r
- switch(Path.GetExtension(files[0]).ToUpper())\r
- {\r
- case ".TSO": tbMergeTso.Text= files[0]; break;\r
- }\r
- }\r
-\r
- private void tbMergeTso_DragEnter(object sender, DragEventArgs e)\r
- {\r
- if(!e.Data.GetDataPresent(DataFormats.FileDrop))\r
- return;\r
-\r
- e.Effect = DragDropEffects.Copy;\r
- }\r
-\r
- private void OpenTSOFile(string f)\r
- {\r
- string dir = OutPath;\r
-\r
- if(cbMakeSub.Checked)\r
- {\r
- dir = Path.Combine(dir, Path.GetFileNameWithoutExtension(f));\r
-\r
- if(!Directory.Exists(dir))\r
- Directory.CreateDirectory(dir);\r
- }\r
-\r
- string file= Path.Combine(dir, Path.ChangeExtension(Path.GetFileName(f), ".mqo"));\r
- string info= Path.Combine(dir, Path.ChangeExtension(Path.GetFileName(f), ".xml"));\r
-\r
- try\r
- {\r
- label2.BackColor= Color.Tomato;\r
- label2.ForeColor= Color.White;\r
- label2.Text = "Processing";\r
- label2.Invalidate();\r
- label2.Update();\r
-\r
- // モデル、テクスチャの作成\r
- using(MqoWriter mqo = new MqoWriter(file))\r
- {\r
- TSOFile tso = new TSOFile(f);\r
- tso.ReadAll();\r
-\r
- if(rbBoneRokDeBone.Checked) mqo.BoneMode = MqoBoneMode.RokDeBone;\r
-\r
- mqo.Write(tso);\r
- mqo.Close();\r
-\r
- ImportInfo ii = new ImportInfo();\r
-\r
- // テクスチャ情報\r
- foreach(TSOTex i in tso.textures)\r
- ii.textures.Add(new ImportTextureInfo(i));\r
-\r
- // エフェクトの作成\r
- foreach(TSOEffect i in tso.effects)\r
- {\r
- ii.effects.Add(new ImportEffectInfo(i));\r
- File.WriteAllText(Path.Combine(dir, i.Name), i.code, Encoding.Default);\r
- }\r
-\r
- // マテリアルの作成\r
- foreach(TSOMaterial i in tso.materials)\r
- {\r
- ii.materials.Add(new ImportMaterialInfo(i));\r
- File.WriteAllText(Path.Combine(dir, i.Name), i.code, Encoding.Default);\r
- //File.WriteAllText(Path.Combine(dir, i.File), i.code, Encoding.Default);\r
- }\r
-\r
- ImportInfo.Save(info, ii);\r
- }\r
-\r
- if(cbCopyTSO.Checked)\r
- {\r
- file = Path.Combine(dir, Path.GetFileName(f));\r
-\r
- if(f != file)\r
- File.Copy(f, file, true);\r
- }\r
- } finally\r
- {\r
- label2.BackColor = SystemColors.Control;\r
- label2.BackColor = label2.Parent.BackColor;\r
- label2.ForeColor = SystemColors.ControlText;\r
- label2.Text = "Drop TSO File Here!";\r
- }\r
-\r
- //System.Diagnostics.Process.Start(file);\r
- }\r
-\r
- private void OpenMQOFile(string f)\r
- {\r
- TSOGenerator gen = new TSOGenerator();\r
- TSOGenerateConfig config = new TSOGenerateConfig();\r
- config.ShowMaterials = cbShowMaterials.Checked;\r
-\r
- if (rbRefBone.Checked)\r
- {\r
- gen.GenerateRefBone(f, tbTso.Text, tbTsoEx.Text, config);\r
- }\r
- else\r
- if (rbOneBone.Checked)\r
- {\r
- Dictionary<string, string> boneref = new Dictionary<string, string>();\r
-\r
- foreach (ListViewItem i in lvObject.Items)\r
- {\r
- if (i.SubItems[1].Text == "")\r
- {\r
- MessageBox.Show("すべてのオブジェクトにボーンを設定してください");\r
- return;\r
- }\r
-\r
- boneref.Add(i.SubItems[0].Text, i.SubItems[1].Text);\r
- }\r
-\r
- gen.GenerateOneBone(f, tbTso.Text, tbTsoEx.Text, config, boneref);\r
- }\r
- else\r
- {\r
- }\r
- }\r
-#region tso->mqo UI\r
- private void button1_Click(object sender, EventArgs e)\r
- {\r
- FolderBrowserDialog dlg = new FolderBrowserDialog();\r
- dlg.SelectedPath = OutPath;\r
-\r
- if(dlg.ShowDialog() == DialogResult.OK)\r
- OutPath = dlg.SelectedPath;\r
- }\r
-#endregion\r
-#region mqo->tso UI\r
- private void radioButton1_CheckedChanged(object sender, EventArgs e)\r
- {\r
- EnableControlStuff();\r
- }\r
-\r
- private void radioButton2_CheckedChanged(object sender, EventArgs e)\r
- {\r
- EnableControlStuff();\r
- }\r
-\r
- private void EnableControlStuff()\r
- {\r
- gbBone.Enabled = rbOneBone.Checked;\r
- }\r
-\r
- private void BuildBoneTree(TreeNodeCollection nodes, TSONode node)\r
- {\r
- TreeNode tn = nodes.Add(node.ShortName);\r
- tn.Tag = node;\r
-\r
- if(node.children != null)\r
- foreach(TSONode i in node.children)\r
- BuildBoneTree(tn.Nodes, i);\r
- }\r
-\r
- private void SaveAssign()\r
- {\r
- foreach(ListViewItem i in lvObject.Items)\r
- {\r
- string obj = i.SubItems[0].Text;\r
- string bone= i.SubItems[1].Text;\r
-\r
- if(Config.Instance.object_bone_map.ContainsKey(obj))\r
- Config.Instance.object_bone_map[obj] = bone;\r
- else Config.Instance.object_bone_map.Add(obj, bone);\r
- }\r
- }\r
-\r
- private void bRefMqoIn_Click(object sender, EventArgs e)\r
- {\r
- try\r
- {\r
- OpenFileDialog dlg = new OpenFileDialog();\r
- dlg.Filter = "Metasequoia File(*.mqo)|*.mqo";\r
- dlg.FileName= tbMqoIn.Text;\r
-\r
- if(dlg.ShowDialog() == DialogResult.OK)\r
- tbMqoIn.Text = dlg.FileName;\r
- } catch(Exception ex)\r
- {\r
- Util.ProcessError(ex);\r
- }\r
- }\r
-\r
- private void bRefTso_Click(object sender, EventArgs e)\r
- {\r
- try\r
- {\r
- OpenFileDialog dlg = new OpenFileDialog();\r
- dlg.Filter = "TSO File(*.tso)|*.tso";\r
- dlg.FileName= tbTso.Text;\r
-\r
- if(dlg.ShowDialog() == DialogResult.OK)\r
- tbTso.Text = dlg.FileName;\r
- } catch(Exception ex)\r
- {\r
- Util.ProcessError(ex);\r
- }\r
- }\r
-\r
- private void bRefTsoEx_Click(object sender, EventArgs e)\r
- {\r
- try\r
- {\r
- SaveFileDialog dlg = new SaveFileDialog();\r
- dlg.Filter = "TSO File(*.tso)|*.tso";\r
- dlg.FileName= tbTsoEx.Text;\r
-\r
- if(dlg.ShowDialog() == DialogResult.OK)\r
- tbTsoEx.Text = dlg.FileName;\r
- } catch(Exception ex)\r
- {\r
- Util.ProcessError(ex);\r
- }\r
- }\r
-\r
- private void bRefresh_Click(object sender, EventArgs e)\r
- {\r
- try\r
- {\r
- // 一旦現状を保存\r
- SaveAssign();\r
-\r
- // オブジェクト\r
- MqoFile mqo = new MqoFile();\r
- mqo.Load(tbMqoIn.Text);\r
- lvObject.Items.Clear();\r
-\r
- foreach(MqoObject i in mqo.Objects)\r
- {\r
- ListViewItem item= lvObject.Items.Add(i.name);\r
- item.Tag = i;\r
- string bone;\r
-\r
- if(Config.Instance.object_bone_map.TryGetValue(i.name, out bone))\r
- item.SubItems.Add(bone);\r
- else item.SubItems.Add("");\r
- }\r
-\r
- // ボーン構造\r
- TSOFile tso = new TSOFile(tbTso.Text);\r
- tso.ReadAll();\r
- tvBone.Visible = false;\r
- tvBone.Nodes.Clear();\r
- BuildBoneTree(tvBone.Nodes, tso.nodes[0]);\r
- tvBone.ExpandAll();\r
- tvBone.Nodes[0].EnsureVisible();\r
- } catch(Exception ex)\r
- {\r
- Util.ProcessError(ex);\r
- } finally\r
- {\r
- tvBone.Visible = true;\r
- }\r
-\r
- }\r
-\r
- private void bSelectAll_Click(object sender, EventArgs e)\r
- {\r
- foreach(ListViewItem i in lvObject.Items)\r
- i.Selected = true;\r
- }\r
-\r
- private void bDeselectAll_Click(object sender, EventArgs e)\r
- {\r
- foreach(ListViewItem i in lvObject.Items)\r
- i.Selected = false;\r
- }\r
-\r
- private void bAssign_Click(object sender, EventArgs e)\r
- {\r
- try\r
- {\r
- TreeNode n = tvBone.SelectedNode;\r
-\r
- if(n == null)\r
- {\r
- MessageBox.Show("割り当てるボーンを選択してください");\r
- return;\r
- }\r
-\r
- foreach(ListViewItem i in lvObject.SelectedItems)\r
- i.SubItems[1].Text = n.Text;\r
-\r
- SaveAssign();\r
- } catch(Exception ex)\r
- {\r
- Util.ProcessError(ex);\r
- }\r
- }\r
-\r
- private void bOk_Click(object sender, EventArgs e)\r
- {\r
- Color c = tabPage2.BackColor;\r
-\r
- try\r
- {\r
- tabPage2.BackColor = Color.Tomato;\r
- tabPage2.Update();\r
- string file = tbMqoIn.Text;\r
- OpenMQOFile(file);\r
- }\r
- catch (Exception ex)\r
- {\r
- Util.ProcessError(ex);\r
- }\r
- finally\r
- {\r
- tabPage2.BackColor = c;\r
- }\r
- }\r
-#endregion\r
-#region Merge UI\r
- private void AddMergeTso(string[] files)\r
- {\r
- foreach(string i in files)\r
- {\r
- if(Path.GetExtension(files[0]).ToUpper() != ".TSO")\r
- continue;\r
-\r
- if(tvMerge.Nodes.Find(i, false).Length == 0)\r
- {\r
- TreeNode node= tvMerge.Nodes.Add(i);\r
- node.Name = i;\r
- node.Checked = true;\r
-\r
- TSOFile tso = new TSOFile(i);\r
- tso.ReadAll();\r
-\r
- foreach(TSOMesh j in tso.meshes)\r
- {\r
- TreeNode mesh= node.Nodes.Add(j.Name);\r
- mesh.Name = j.Name;\r
- mesh.Checked = true;\r
- }\r
- }\r
- }\r
- }\r
-\r
- private void bMerge_Click(object sender, EventArgs e)\r
- {\r
- Color c = tabPage2.BackColor;\r
-\r
- try\r
- {\r
- tabPage2.BackColor = Color.Tomato;\r
- List<TSOMesh> meshes = new List<TSOMesh>();\r
- Dictionary<string, Pair<TSOMaterial, int>> materialmap = new Dictionary<string, Pair<TSOMaterial, int>>();\r
- Dictionary<string, TSOTex> textures = new Dictionary<string, TSOTex>();\r
- TSOFile last = null;\r
-\r
- foreach(TreeNode i in tvMerge.Nodes)\r
- {\r
- TSOFile tso = new TSOFile(i.Text);\r
- last = tso;\r
- ulong mtls= 0;\r
- ulong mask= 1;\r
- tso.ReadAll();\r
-\r
- foreach(TSOMesh j in tso.meshes)\r
- {\r
- TreeNode[] found = i.Nodes.Find(j.Name, false);\r
-\r
- if(found.Length == 0 || !found[0].Checked)\r
- continue;\r
-\r
- foreach(TSOSubMesh k in j.sub)\r
- mtls |=1ul << k.spec;\r
-\r
- meshes.Add(j);\r
- }\r
-\r
- foreach(TSOMaterial j in tso.materials)\r
- {\r
- if((mask & mtls) != 0)\r
- {\r
- if(!materialmap.ContainsKey(j.Name))\r
- {\r
- Pair<TSOMaterial, int> value = new Pair<TSOMaterial,int>(j, materialmap.Count);\r
- materialmap.Add(j.Name, value);\r
-\r
- if(!textures.ContainsKey(j.ColorTex))\r
- {\r
- TSOTex tex = tso.texturemap[j.ColorTex];\r
- textures.Add(tex.Name, tex);\r
- }\r
-\r
- if(!textures.ContainsKey(j.ShadeTex))\r
- {\r
- TSOTex tex = tso.texturemap[j.ShadeTex];\r
- textures.Add(tex.Name, tex);\r
- }\r
- }\r
- }\r
-\r
- mask <<=1;\r
- }\r
- }\r
-\r
- using(FileStream fs= File.OpenWrite(tbMergeTso.Text))\r
- {\r
- fs.SetLength(0);\r
-\r
- List<TSOTex> texlist = new List<TSOTex>(textures.Values);\r
- TSOMaterial[] mtllist = new TSOMaterial[materialmap.Count];\r
-\r
- foreach(var i in materialmap.Values)\r
- mtllist[i.Second] = i.First;\r
-\r
- foreach(TSOMesh i in meshes)\r
- {\r
- foreach(TSOSubMesh j in i.sub)\r
- {\r
- TSOMaterial mtl = i.file.materials[j.spec];\r
- j.spec = materialmap[mtl.Name].Second;\r
- }\r
- }\r
-\r
- foreach(TSOTex i in texlist)\r
- TSOFile.ExchangeChannel(i.data, i.depth);\r
-\r
- BinaryWriter bw = new BinaryWriter(fs);\r
- TSOWriter.WriteHeader(bw);\r
- TSOWriter.Write(bw, last.nodes);\r
- TSOWriter.Write(bw, texlist.ToArray());\r
- TSOWriter.Write(bw, last.effects);\r
- TSOWriter.Write(bw, mtllist);\r
- TSOWriter.Write(bw, meshes.ToArray());\r
- }\r
- } catch(Exception ex)\r
- {\r
- Util.ProcessError(ex);\r
- } finally\r
- {\r
- tabPage2.BackColor = c;\r
- }\r
- }\r
-\r
- private void bMergeAdd_Click(object sender, EventArgs e)\r
- {\r
- try\r
- {\r
- OpenFileDialog dlg = new OpenFileDialog();\r
- dlg.Filter = "TSO File(*.tso)|*.tso";\r
- dlg.Multiselect = true;\r
-\r
- if(dlg.ShowDialog() == DialogResult.OK)\r
- AddMergeTso(dlg.FileNames);\r
- } catch(Exception ex)\r
- {\r
- Util.ProcessError(ex);\r
- }\r
- }\r
-\r
- private void bMergeDel_Click(object sender, EventArgs e)\r
- {\r
- if(tvMerge.SelectedNode != null\r
- && tvMerge.SelectedNode.Level == 0)\r
- tvMerge.SelectedNode.Remove();\r
- }\r
-\r
- private void bMergeReset_Click(object sender, EventArgs e)\r
- {\r
- tvMerge.Nodes.Clear();\r
- }\r
-\r
- private void bRefMergeTso_Click(object sender, EventArgs e)\r
- {\r
- try\r
- {\r
- SaveFileDialog dlg = new SaveFileDialog();\r
- dlg.Filter = "TSO File(*.tso)|*.tso";\r
- dlg.FileName= tbMergeTso.Text;\r
-\r
- if(dlg.ShowDialog() == DialogResult.OK)\r
- tbMergeTso.Text = dlg.FileName;\r
- } catch(Exception ex)\r
- {\r
- Util.ProcessError(ex);\r
- }\r
- }\r
-\r
- public static bool bTvMerge_AfterCheck = false;\r
-\r
- private void tvMerge_AfterCheck(object sender, TreeViewEventArgs e)\r
- {\r
- if(bTvMerge_AfterCheck)\r
- return;\r
-\r
- bTvMerge_AfterCheck = true;\r
-\r
- try\r
- {\r
- if(e.Node.Level == 0)\r
- {\r
- foreach(TreeNode i in e.Node.Nodes)\r
- i.Checked = e.Node.Checked;\r
- } else\r
- {\r
- bool check = false;\r
- //bool uncheck = false;\r
-\r
- foreach(TreeNode i in e.Node.Parent.Nodes)\r
- if(i.Checked) check = true;\r
- //else uncheck = true;\r
-\r
- e.Node.Parent.Checked = check;\r
- }\r
- } finally\r
- {\r
- bTvMerge_AfterCheck = false;\r
- }\r
- }\r
-#endregion\r
- }\r
-\r
- public class Util\r
- {\r
- public static void ProcessError(Exception e)\r
- {\r
- MessageBox.Show(e.ToString());\r
- }\r
- }\r
-}\r
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.IO;
+using System.Text;
+using System.Windows.Forms;
+using Microsoft.Win32;
+
+namespace Tso2MqoGui
+{
+ public partial class Form1 : Form
+ {
+ public Form1()
+ {
+ InitializeComponent();
+ }
+
+ private void Form1_Load(object sender, EventArgs e)
+ {
+ RegistryKey reg = Application.UserAppDataRegistry.CreateSubKey("Config");
+ tbPath.Text = (string)reg.GetValue("OutPath", Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
+ tabControl1.SelectedIndex = (int)reg.GetValue("TabPage", 0);
+ tbMqoFile.Text = (string)reg.GetValue("MqoIn", "");
+ tbTsoFileRef.Text = (string)reg.GetValue("Tso", "");
+ tbTsoFile.Text = (string)reg.GetValue("TsoEx", "");
+ tbMergeTso.Text = (string)reg.GetValue("MergeTso", "");
+ rbRefBone.Checked = (int)reg.GetValue("RefBone", 1) == 1;
+ rbOneBone.Checked = (int)reg.GetValue("OneBone", 0) == 1;
+ rbBoneNone.Checked = (int)reg.GetValue("BoneNone", 1) == 1;
+ rbBoneRokDeBone.Checked = (int)reg.GetValue("BoneRokDeBone", 0) == 1;
+ cbMakeSub.Checked = (int)reg.GetValue("MakeSub", 1) == 1;
+ cbCopyTSO.Checked = (int)reg.GetValue("CopyTSO", 1) == 1;
+ cbShowMaterials.Checked = (int)reg.GetValue("ShowMaterials", 0) == 1;
+
+ reg = Application.UserAppDataRegistry.CreateSubKey("Form1");
+ Bounds = new Rectangle(
+ (int)reg.GetValue("Left", 0),
+ (int)reg.GetValue("Top", 0),
+ (int)reg.GetValue("Width", 640),
+ (int)reg.GetValue("Height", 320));
+
+ EnableControlStuff();
+
+ Config config = Config.Instance;
+ }
+
+ private void Form1_FormClosed(object sender, FormClosedEventArgs e)
+ {
+ RegistryKey reg = Application.UserAppDataRegistry.CreateSubKey("Config");
+ reg.SetValue("OutPath", tbPath.Text);
+ reg.SetValue("TabPage", tabControl1.SelectedIndex);
+ reg.SetValue("MqoIn", tbMqoFile.Text);
+ reg.SetValue("Tso", tbTsoFileRef.Text);
+ reg.SetValue("TsoEx", tbTsoFile.Text);
+ reg.SetValue("MergeTso", tbMergeTso.Text);
+ reg.SetValue("RefBone", rbRefBone.Checked ? 1 : 0);
+ reg.SetValue("OneBone", rbOneBone.Checked ? 1 : 0);
+ reg.SetValue("BoneNone", rbBoneNone.Checked ? 1 : 0);
+ reg.SetValue("BoneRokDeBone", rbBoneRokDeBone.Checked ? 1 : 0);
+ reg.SetValue("MakeSub", cbMakeSub.Checked ? 1 : 0);
+ reg.SetValue("CopyTSO", cbCopyTSO.Checked ? 1 : 0);
+ reg.SetValue("ShowMaterials", cbShowMaterials.Checked ? 1 : 0);
+
+ reg = Application.UserAppDataRegistry.CreateSubKey("Form1");
+
+ if ((this.WindowState & FormWindowState.Minimized) == FormWindowState.Minimized)
+ {
+ reg.SetValue("Top", RestoreBounds.Top);
+ reg.SetValue("Left", RestoreBounds.Left);
+ reg.SetValue("Width", RestoreBounds.Width);
+ reg.SetValue("Height", RestoreBounds.Height);
+ }
+ else
+ {
+ reg.SetValue("Top", Top);
+ reg.SetValue("Left", Left);
+ reg.SetValue("Width", Width);
+ reg.SetValue("Height", Height);
+ }
+
+ Config.Save();
+ }
+
+ private void Form1_DragDrop(object sender, DragEventArgs e)
+ {
+ try
+ {
+ if (!e.Data.GetDataPresent(DataFormats.FileDrop))
+ return;
+
+ string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
+
+ if (files.Length == 0)
+ return;
+
+ switch (tabControl1.SelectedIndex)
+ {
+ case 0:
+ foreach (string i in files)
+ {
+ if (Path.GetExtension(i).ToUpper() == ".TSO")
+ GenerateMqo(i);
+ }
+
+ break;
+
+ case 1:
+ switch (Path.GetExtension(files[0]).ToUpper())
+ {
+ case ".TSO": tbTsoFileRef.Text = files[0]; break;
+ case ".MQO": tbMqoFile.Text = files[0]; break;
+ }
+
+ break;
+
+ case 2:
+ AddMergeTso(files);
+ break;
+ }
+ }
+ catch (Exception exception)
+ {
+ Util.ProcessError(exception);
+ }
+ }
+
+ private void Form1_DragEnter(object sender, DragEventArgs e)
+ {
+ if (!e.Data.GetDataPresent(DataFormats.FileDrop))
+ return;
+
+ e.Effect = DragDropEffects.Copy;
+ }
+
+ private void tbMergeTso_DragDrop(object sender, DragEventArgs e)
+ {
+ if (!e.Data.GetDataPresent(DataFormats.FileDrop))
+ return;
+
+ string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
+
+ switch (Path.GetExtension(files[0]).ToUpper())
+ {
+ case ".TSO": tbMergeTso.Text = files[0]; break;
+ }
+ }
+
+ private void tbMergeTso_DragEnter(object sender, DragEventArgs e)
+ {
+ if (!e.Data.GetDataPresent(DataFormats.FileDrop))
+ return;
+
+ e.Effect = DragDropEffects.Copy;
+ }
+
+ private void GenerateMqo(string tso_file)
+ {
+ string out_path = tbPath.Text;
+
+ if (cbMakeSub.Checked)
+ {
+ out_path = Path.Combine(out_path, Path.GetFileNameWithoutExtension(tso_file));
+ Directory.CreateDirectory(out_path);
+ }
+
+ try
+ {
+ label2.BackColor = Color.Tomato;
+ label2.ForeColor = Color.White;
+ label2.Text = "Processing";
+ label2.Invalidate();
+ label2.Update();
+
+ MqoGenerator gen = new MqoGenerator();
+ gen.Generate(tso_file, out_path, rbBoneRokDeBone.Checked);
+
+ if (cbCopyTSO.Checked)
+ {
+ string tso_path = Path.Combine(out_path, Path.GetFileName(tso_file));
+
+ if (tso_file != tso_path)
+ File.Copy(tso_file, tso_path, true);
+ }
+ }
+ finally
+ {
+ label2.BackColor = SystemColors.Control;
+ label2.BackColor = label2.Parent.BackColor;
+ label2.ForeColor = SystemColors.ControlText;
+ label2.Text = "Drop TSO File Here!";
+ }
+ }
+
+ private void GenerateTso(string file)
+ {
+ TSOGeneratorConfig config = new TSOGeneratorConfig();
+ config.ShowMaterials = cbShowMaterials.Checked;
+
+ if (rbRefBone.Checked)
+ {
+ TSOGeneratorMqxBone gen = new TSOGeneratorMqxBone(config);
+ gen.Generate(file, tbTsoFileRef.Text, tbTsoFile.Text);
+ }
+ else if (rbOneBone.Checked)
+ {
+ TSOGeneratorOneBone gen = new TSOGeneratorOneBone(config);
+
+ foreach (ListViewItem item in lvObjects.Items)
+ {
+ if (item.SubItems[1].Text == "")
+ {
+ MessageBox.Show("すべてのオブジェクトにボーンを設定してください");
+ return;
+ }
+
+ gen.ObjectBoneNames.Add(item.SubItems[0].Text, item.SubItems[1].Text);
+ }
+
+ gen.Generate(file, tbTsoFileRef.Text, tbTsoFile.Text);
+ }
+ }
+ #region tso->mqo UI
+ private void button1_Click(object sender, EventArgs e)
+ {
+ FolderBrowserDialog dlg = new FolderBrowserDialog();
+ dlg.SelectedPath = tbPath.Text;
+
+ if (dlg.ShowDialog() == DialogResult.OK)
+ tbPath.Text = dlg.SelectedPath;
+ }
+ #endregion
+ #region mqo->tso UI
+ private void radioButton1_CheckedChanged(object sender, EventArgs e)
+ {
+ EnableControlStuff();
+ }
+
+ private void radioButton2_CheckedChanged(object sender, EventArgs e)
+ {
+ EnableControlStuff();
+ }
+
+ private void EnableControlStuff()
+ {
+ gbBone.Enabled = rbOneBone.Checked;
+ }
+
+ private void BuildBoneTree(TreeNodeCollection nodes, TSONode node)
+ {
+ TreeNode tn = nodes.Add(node.Name);
+ tn.Tag = node;
+
+ if (node.children != null)
+ foreach (TSONode i in node.children)
+ BuildBoneTree(tn.Nodes, i);
+ }
+
+ private void SaveAssign()
+ {
+ foreach (ListViewItem item in lvObjects.Items)
+ {
+ string obj = item.SubItems[0].Text;
+ string bone = item.SubItems[1].Text;
+
+ if (Config.Instance.object_bone_map.ContainsKey(obj))
+ Config.Instance.object_bone_map[obj] = bone;
+ else
+ Config.Instance.object_bone_map.Add(obj, bone);
+ }
+ }
+
+ private void btnMqoFile_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ OpenFileDialog dlg = new OpenFileDialog();
+ dlg.Filter = "Metasequoia File (*.mqo)|*.mqo";
+ dlg.FileName = tbMqoFile.Text;
+
+ if (dlg.ShowDialog() == DialogResult.OK)
+ tbMqoFile.Text = dlg.FileName;
+ }
+ catch (Exception exception)
+ {
+ Util.ProcessError(exception);
+ }
+ }
+
+ private void btnTsoFileRef_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ OpenFileDialog dlg = new OpenFileDialog();
+ dlg.Filter = "TSO File (*.tso)|*.tso";
+ dlg.FileName = tbTsoFileRef.Text;
+
+ if (dlg.ShowDialog() == DialogResult.OK)
+ tbTsoFileRef.Text = dlg.FileName;
+ }
+ catch (Exception exception)
+ {
+ Util.ProcessError(exception);
+ }
+ }
+
+ private void btnTsoFile_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ SaveFileDialog dlg = new SaveFileDialog();
+ dlg.Filter = "TSO File (*.tso)|*.tso";
+ dlg.FileName = tbTsoFile.Text;
+
+ if (dlg.ShowDialog() == DialogResult.OK)
+ tbTsoFile.Text = dlg.FileName;
+ }
+ catch (Exception exception)
+ {
+ Util.ProcessError(exception);
+ }
+ }
+
+ private void btnRefresh_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ // 一旦現状を保存
+ SaveAssign();
+
+ // オブジェクト
+ MqoReader mqo = new MqoReader();
+ mqo.Load(tbMqoFile.Text);
+ lvObjects.Items.Clear();
+
+ foreach (MqoObject obj in mqo.Objects)
+ {
+ ListViewItem item = lvObjects.Items.Add(obj.name);
+ item.Tag = obj;
+ string bone;
+
+ if (Config.Instance.object_bone_map.TryGetValue(obj.name, out bone))
+ item.SubItems.Add(bone);
+ else
+ item.SubItems.Add("");
+ }
+
+ // ボーン構造
+ TSOFile tso = new TSOFile(tbTsoFileRef.Text);
+ tso.ReadAll();
+ tvBones.Visible = false;
+ tvBones.Nodes.Clear();
+ BuildBoneTree(tvBones.Nodes, tso.nodes[0]);
+ tvBones.ExpandAll();
+ tvBones.Nodes[0].EnsureVisible();
+ }
+ catch (Exception exception)
+ {
+ Util.ProcessError(exception);
+ }
+ finally
+ {
+ tvBones.Visible = true;
+ }
+ }
+
+ private void btnSelectAll_Click(object sender, EventArgs e)
+ {
+ foreach (ListViewItem item in lvObjects.Items)
+ item.Selected = true;
+ }
+
+ private void btnDeselectAll_Click(object sender, EventArgs e)
+ {
+ foreach (ListViewItem item in lvObjects.Items)
+ item.Selected = false;
+ }
+
+ private void btnAssign_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ TreeNode node = tvBones.SelectedNode;
+
+ if (node == null)
+ {
+ MessageBox.Show("割り当てるボーンを選択してください");
+ return;
+ }
+
+ foreach (ListViewItem item in lvObjects.SelectedItems)
+ item.SubItems[1].Text = node.Text;
+
+ SaveAssign();
+ }
+ catch (Exception ex)
+ {
+ Util.ProcessError(ex);
+ }
+ }
+
+ private void btnGenerate_Click(object sender, EventArgs e)
+ {
+ Color c = tabPage2.BackColor;
+
+ try
+ {
+ tabPage2.BackColor = Color.Tomato;
+ tabPage2.Update();
+ string file = tbMqoFile.Text;
+ GenerateTso(file);
+ }
+ catch (Exception exception)
+ {
+ Util.ProcessError(exception);
+ }
+ finally
+ {
+ tabPage2.BackColor = c;
+ }
+ }
+ #endregion
+ #region Merge UI
+ private void AddMergeTso(string[] files)
+ {
+ foreach (string file in files)
+ {
+ if (Path.GetExtension(files[0]).ToUpper() != ".TSO")
+ continue;
+
+ if (tvMerge.Nodes.Find(file, false).Length == 0)
+ {
+ TreeNode node = tvMerge.Nodes.Add(file);
+ node.Name = file;
+ node.Checked = true;
+
+ TSOFile tso = new TSOFile(file);
+ tso.ReadAll();
+
+ foreach (TSOMesh j in tso.meshes)
+ {
+ TreeNode mesh = node.Nodes.Add(j.Name);
+ mesh.Name = j.Name;
+ mesh.Checked = true;
+ }
+ }
+ }
+ }
+
+ 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, Pair<TSOMaterial, int>> materialmap = new Dictionary<string, Pair<TSOMaterial, int>>();
+ Dictionary<string, TSOTex> textures = new Dictionary<string, TSOTex>();
+ TSOFile last = null;
+
+ foreach (TreeNode node in tvMerge.Nodes)
+ {
+ TSOFile tso = new TSOFile(node.Text);
+ last = tso;
+ ulong mtls = 0;
+ ulong mask = 1;
+ tso.ReadAll();
+
+ 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))
+ {
+ Pair<TSOMaterial, int> value = new Pair<TSOMaterial, int>(mat, materialmap.Count);
+ materialmap.Add(mat.Name, value);
+
+ 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.Second] = i.First;
+
+ foreach (TSOMesh mesh in meshes)
+ {
+ foreach (TSOSubMesh sub in mesh.sub_meshes)
+ {
+ TSOMaterial spec = mesh.file.materials[sub.spec];
+ sub.spec = materialmap[spec.Name].Second;
+ }
+ }
+
+ 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;
+ }
+ }
+
+ private void btnMergeAdd_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ OpenFileDialog dlg = new OpenFileDialog();
+ dlg.Filter = "TSO File(*.tso)|*.tso";
+ dlg.Multiselect = true;
+
+ if (dlg.ShowDialog() == DialogResult.OK)
+ AddMergeTso(dlg.FileNames);
+ }
+ catch (Exception exception)
+ {
+ Util.ProcessError(exception);
+ }
+ }
+
+ private void btnMergeDel_Click(object sender, EventArgs e)
+ {
+ if (tvMerge.SelectedNode != null && tvMerge.SelectedNode.Level == 0)
+ tvMerge.SelectedNode.Remove();
+ }
+
+ private void btnMergeReset_Click(object sender, EventArgs e)
+ {
+ tvMerge.Nodes.Clear();
+ }
+
+ private void btnRefMergeTso_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ SaveFileDialog dlg = new SaveFileDialog();
+ dlg.Filter = "TSO File (*.tso)|*.tso";
+ dlg.FileName = tbMergeTso.Text;
+
+ if (dlg.ShowDialog() == DialogResult.OK)
+ tbMergeTso.Text = dlg.FileName;
+ }
+ catch (Exception exception)
+ {
+ Util.ProcessError(exception);
+ }
+ }
+
+ public static bool bTvMerge_AfterCheck = false;
+
+ private void tvMerge_AfterCheck(object sender, TreeViewEventArgs e)
+ {
+ if (bTvMerge_AfterCheck)
+ return;
+
+ bTvMerge_AfterCheck = true;
+
+ try
+ {
+ if (e.Node.Level == 0)
+ {
+ foreach (TreeNode node in e.Node.Nodes)
+ node.Checked = e.Node.Checked;
+ }
+ else
+ {
+ bool check = false;
+
+ foreach (TreeNode node in e.Node.Parent.Nodes)
+ if (node.Checked) check = true;
+
+ e.Node.Parent.Checked = check;
+ }
+ }
+ finally
+ {
+ bTvMerge_AfterCheck = false;
+ }
+ }
+ #endregion
+ }
+
+ public class Util
+ {
+ public static void ProcessError(Exception exception)
+ {
+ MessageBox.Show(exception.ToString());
+ }
+ }
+}