-using System;\r
-using System.Collections.Generic;\r
-using System.IO;\r
-using System.Text;\r
-using System.Xml.Serialization;\r
-\r
-namespace Tso2MqoGui\r
-{\r
- [XmlRoot("TsoMqoConfig")]\r
- [Serializable]\r
- public class Config\r
- {\r
- public struct KeyAndValue\r
- {\r
- [XmlAttribute("key")] public string Key;\r
- [XmlAttribute("value")] public string Value;\r
-\r
- public KeyAndValue(string k, string v)\r
- {\r
- Key = k;\r
- Value = v;\r
- }\r
- }\r
-\r
- public static Config Instance;\r
-\r
- public static string AssemblyPath { get { return Path.GetDirectoryName(Type.Assembly.Location); } }\r
- public static string ConfigFile { get { return Path.Combine(AssemblyPath, "config.xml"); } }\r
- public static Type Type { get { return typeof(Config); } }\r
-\r
- [XmlElement("object_bone_list")] public List<KeyAndValue> object_bone_list = new List<KeyAndValue>();\r
- [XmlIgnore] public Dictionary<string, string> object_bone_map = new Dictionary<string,string>();\r
-\r
- static Config()\r
- {\r
- Load();\r
- }\r
-\r
- public static void Load()\r
- {\r
- try\r
- {\r
- using(FileStream fs= File.OpenRead(ConfigFile))\r
- {\r
- XmlSerializer s = new XmlSerializer(Type);\r
- Instance = s.Deserialize(fs) as Config;\r
- Instance.AfterDeserialize();\r
- }\r
- } catch(Exception e)\r
- {\r
- System.Diagnostics.Debug.WriteLine(e.ToString());\r
- Instance = new Config();\r
- }\r
- }\r
-\r
- public static void Save()\r
- {\r
- try\r
- {\r
- using(FileStream fs= File.OpenWrite(ConfigFile))\r
- {\r
- fs.SetLength(0);\r
- XmlSerializer s = new XmlSerializer(Type);\r
- Instance.BeforeSerialize();\r
- s.Serialize(fs, Instance);\r
- fs.Flush();\r
- }\r
- } catch(Exception e)\r
- {\r
- System.Diagnostics.Debug.WriteLine(e.ToString());\r
- }\r
- }\r
-\r
- public void BeforeSerialize()\r
- {\r
- object_bone_list.Clear();\r
-\r
- foreach(string i in object_bone_map.Keys)\r
- object_bone_list.Add(new KeyAndValue(i, object_bone_map[i]));\r
- }\r
-\r
- public void AfterDeserialize()\r
- {\r
- object_bone_map.Clear();\r
-\r
- foreach(KeyAndValue i in object_bone_list)\r
- object_bone_map.Add(i.Key, i.Value);\r
- }\r
- }\r
-}\r
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Xml.Serialization;
+
+namespace Tso2MqoGui
+{
+ [XmlRoot("TsoMqoConfig")]
+ [Serializable]
+ public class Config
+ {
+ public struct KeyAndValue
+ {
+ [XmlAttribute("key")]
+ public string Key;
+ [XmlAttribute("value")]
+ public string Value;
+
+ public KeyAndValue(string k, string v)
+ {
+ Key = k;
+ Value = v;
+ }
+ }
+
+ public static Config Instance;
+
+ public static string AssemblyPath { get { return Path.GetDirectoryName(Type.Assembly.Location); } }
+ public static string ConfigFile { get { return Path.Combine(AssemblyPath, "config.xml"); } }
+ public static Type Type { get { return typeof(Config); } }
+
+ [XmlElement("object_bone_list")]
+ public List<KeyAndValue> object_bone_list = new List<KeyAndValue>();
+ [XmlIgnore]
+ public Dictionary<string, string> object_bone_map = new Dictionary<string, string>();
+
+ static Config()
+ {
+ Load();
+ }
+
+ public static void Load()
+ {
+ try
+ {
+ using (FileStream fs = File.OpenRead(ConfigFile))
+ {
+ XmlSerializer s = new XmlSerializer(Type);
+ Instance = s.Deserialize(fs) as Config;
+ Instance.AfterDeserialize();
+ }
+ }
+ catch (Exception exception)
+ {
+ System.Diagnostics.Debug.WriteLine(exception.ToString());
+ Instance = new Config();
+ }
+ }
+
+ public static void Save()
+ {
+ try
+ {
+ using (FileStream fs = File.OpenWrite(ConfigFile))
+ {
+ fs.SetLength(0);
+ XmlSerializer s = new XmlSerializer(Type);
+ Instance.BeforeSerialize();
+ s.Serialize(fs, Instance);
+ fs.Flush();
+ }
+ }
+ catch (Exception exception)
+ {
+ System.Diagnostics.Debug.WriteLine(exception.ToString());
+ }
+ }
+
+ public void BeforeSerialize()
+ {
+ object_bone_list.Clear();
+
+ foreach (string i in object_bone_map.Keys)
+ object_bone_list.Add(new KeyAndValue(i, object_bone_map[i]));
+ }
+
+ public void AfterDeserialize()
+ {
+ object_bone_map.Clear();
+
+ foreach (KeyAndValue i in object_bone_list)
+ object_bone_map.Add(i.Key, i.Value);
+ }
+ }
+}
\ No newline at end of file
-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
- tbMqoFile.Text = (string)reg.GetValue("MqoIn", "");\r
- tbTsoFileRef.Text = (string)reg.GetValue("Tso", "");\r
- tbTsoFile.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", tbMqoFile.Text);\r
- reg.SetValue("Tso", tbTsoFileRef.Text);\r
- reg.SetValue("TsoEx", tbTsoFile.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": tbTsoFileRef.Text = files[0]; break;\r
- case ".MQO": tbMqoFile.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 file)\r
- {\r
- string dir = OutPath;\r
-\r
- if (cbMakeSub.Checked)\r
- {\r
- dir = Path.Combine(dir, Path.GetFileNameWithoutExtension(file));\r
-\r
- if (!Directory.Exists(dir))\r
- Directory.CreateDirectory(dir);\r
- }\r
-\r
- string mqo_path = Path.Combine(dir, Path.ChangeExtension(Path.GetFileName(file), ".mqo"));\r
- string importinfo_path = Path.Combine(dir, Path.ChangeExtension(Path.GetFileName(file), ".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(mqo_path))\r
- {\r
- TSOFile tso = new TSOFile(file);\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
- }\r
-\r
- ImportInfo.Save(importinfo_path, ii);\r
- }\r
-\r
- if (cbCopyTSO.Checked)\r
- {\r
- string tso_path = Path.Combine(dir, Path.GetFileName(file));\r
-\r
- if (file != tso_path)\r
- File.Copy(file, tso_path, true);\r
- }\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
-\r
- private void OpenMQOFile(string file)\r
- {\r
- TSOGeneratorConfig config = new TSOGeneratorConfig();\r
- config.ShowMaterials = cbShowMaterials.Checked;\r
-\r
- if (rbRefBone.Checked)\r
- {\r
- TSOGeneratorRefBone gen = new TSOGeneratorRefBone(config);\r
- gen.Generate(file, tbTsoFileRef.Text, tbTsoFile.Text);\r
- }\r
- else\r
- if (rbOneBone.Checked)\r
- {\r
- TSOGeneratorOneBone gen = new TSOGeneratorOneBone(config);\r
-\r
- foreach (ListViewItem i in lvObjects.Items)\r
- {\r
- if (i.SubItems[1].Text == "")\r
- {\r
- MessageBox.Show("すべてのオブジェクトにボーンを設定してください");\r
- return;\r
- }\r
-\r
- gen.ObjectBoneNames.Add(i.SubItems[0].Text, i.SubItems[1].Text);\r
- }\r
-\r
- gen.Generate(file, tbTsoFileRef.Text, tbTsoFile.Text);\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 lvObjects.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 btnMqoFile_Click(object sender, EventArgs e)\r
- {\r
- try\r
- {\r
- OpenFileDialog dlg = new OpenFileDialog();\r
- dlg.Filter = "Metasequoia File (*.mqo)|*.mqo";\r
- dlg.FileName = tbMqoFile.Text;\r
-\r
- if (dlg.ShowDialog() == DialogResult.OK)\r
- tbMqoFile.Text = dlg.FileName;\r
- }\r
- catch (Exception ex)\r
- {\r
- Util.ProcessError(ex);\r
- }\r
- }\r
-\r
- private void btnTsoFileRef_Click(object sender, EventArgs e)\r
- {\r
- try\r
- {\r
- OpenFileDialog dlg = new OpenFileDialog();\r
- dlg.Filter = "TSO File (*.tso)|*.tso";\r
- dlg.FileName = tbTsoFileRef.Text;\r
-\r
- if (dlg.ShowDialog() == DialogResult.OK)\r
- tbTsoFileRef.Text = dlg.FileName;\r
- }\r
- catch (Exception ex)\r
- {\r
- Util.ProcessError(ex);\r
- }\r
- }\r
-\r
- private void btnTsoFile_Click(object sender, EventArgs e)\r
- {\r
- try\r
- {\r
- SaveFileDialog dlg = new SaveFileDialog();\r
- dlg.Filter = "TSO File (*.tso)|*.tso";\r
- dlg.FileName = tbTsoFile.Text;\r
-\r
- if (dlg.ShowDialog() == DialogResult.OK)\r
- tbTsoFile.Text = dlg.FileName;\r
- }\r
- catch (Exception ex)\r
- {\r
- Util.ProcessError(ex);\r
- }\r
- }\r
-\r
- private void btnRefresh_Click(object sender, EventArgs e)\r
- {\r
- try\r
- {\r
- // 一旦現状を保存\r
- SaveAssign();\r
-\r
- // オブジェクト\r
- MqoFile mqo = new MqoFile();\r
- mqo.Load(tbMqoFile.Text);\r
- lvObjects.Items.Clear();\r
-\r
- foreach (MqoObject i in mqo.Objects)\r
- {\r
- ListViewItem item = lvObjects.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(tbTsoFileRef.Text);\r
- tso.ReadAll();\r
- tvBones.Visible = false;\r
- tvBones.Nodes.Clear();\r
- BuildBoneTree(tvBones.Nodes, tso.nodes[0]);\r
- tvBones.ExpandAll();\r
- tvBones.Nodes[0].EnsureVisible();\r
- }\r
- catch (Exception ex)\r
- {\r
- Util.ProcessError(ex);\r
- }\r
- finally\r
- {\r
- tvBones.Visible = true;\r
- }\r
- }\r
-\r
- private void btnSelectAll_Click(object sender, EventArgs e)\r
- {\r
- foreach (ListViewItem i in lvObjects.Items)\r
- i.Selected = true;\r
- }\r
-\r
- private void btnDeselectAll_Click(object sender, EventArgs e)\r
- {\r
- foreach (ListViewItem i in lvObjects.Items)\r
- i.Selected = false;\r
- }\r
-\r
- private void btnAssign_Click(object sender, EventArgs e)\r
- {\r
- try\r
- {\r
- TreeNode n = tvBones.SelectedNode;\r
-\r
- if (n == null)\r
- {\r
- MessageBox.Show("割り当てるボーンを選択してください");\r
- return;\r
- }\r
-\r
- foreach (ListViewItem i in lvObjects.SelectedItems)\r
- i.SubItems[1].Text = n.Text;\r
-\r
- SaveAssign();\r
- }\r
- catch (Exception ex)\r
- {\r
- Util.ProcessError(ex);\r
- }\r
- }\r
-\r
- private void btnGenerate_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 = tbMqoFile.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 btnMerge_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
- }\r
- catch (Exception ex)\r
- {\r
- Util.ProcessError(ex);\r
- }\r
- finally\r
- {\r
- tabPage2.BackColor = c;\r
- }\r
- }\r
-\r
- private void btnMergeAdd_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 btnMergeDel_Click(object sender, EventArgs e)\r
- {\r
- if (tvMerge.SelectedNode != null && tvMerge.SelectedNode.Level == 0)\r
- tvMerge.SelectedNode.Remove();\r
- }\r
-\r
- private void btnMergeReset_Click(object sender, EventArgs e)\r
- {\r
- tvMerge.Nodes.Clear();\r
- }\r
-\r
- private void btnRefMergeTso_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
- }\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 string OutPath
+ {
+ get { return tbPath.Text; }
+ set { tbPath.Text = value; }
+ }
+
+ public Form1()
+ {
+ InitializeComponent();
+ }
+
+ private void Form1_Load(object sender, EventArgs e)
+ {
+ RegistryKey reg = Application.UserAppDataRegistry.CreateSubKey("Config");
+ OutPath = (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", OutPath);
+ 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")
+ OpenTSOFile(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 OpenTSOFile(string file)
+ {
+ string dir = OutPath;
+
+ if (cbMakeSub.Checked)
+ {
+ dir = Path.Combine(dir, Path.GetFileNameWithoutExtension(file));
+
+ if (!Directory.Exists(dir))
+ Directory.CreateDirectory(dir);
+ }
+
+ string mqo_path = Path.Combine(dir, Path.ChangeExtension(Path.GetFileName(file), ".mqo"));
+ string importinfo_path = Path.Combine(dir, Path.ChangeExtension(Path.GetFileName(file), ".xml"));
+
+ try
+ {
+ label2.BackColor = Color.Tomato;
+ label2.ForeColor = Color.White;
+ label2.Text = "Processing";
+ label2.Invalidate();
+ label2.Update();
+
+ // モデル、テクスチャの作成
+ using (MqoWriter mqo = new MqoWriter(mqo_path))
+ {
+ TSOFile tso = new TSOFile(file);
+ tso.ReadAll();
+
+ if (rbBoneRokDeBone.Checked) mqo.BoneMode = MqoBoneMode.RokDeBone;
+
+ mqo.Write(tso);
+ mqo.Close();
+
+ ImportInfo ii = new ImportInfo();
+
+ // テクスチャ情報
+ foreach (TSOTex tex in tso.textures)
+ ii.textures.Add(new ImportTextureInfo(tex));
+
+ // エフェクトの作成
+ foreach (TSOEffect effect in tso.effects)
+ {
+ ii.effects.Add(new ImportEffectInfo(effect));
+ File.WriteAllText(Path.Combine(dir, effect.Name), effect.code, Encoding.Default);
+ }
+
+ // マテリアルの作成
+ foreach (TSOMaterial mat in tso.materials)
+ {
+ ii.materials.Add(new ImportMaterialInfo(mat));
+ File.WriteAllText(Path.Combine(dir, mat.Name), mat.code, Encoding.Default);
+ }
+
+ ImportInfo.Save(importinfo_path, ii);
+ }
+
+ if (cbCopyTSO.Checked)
+ {
+ string tso_path = Path.Combine(dir, Path.GetFileName(file));
+
+ if (file != tso_path)
+ File.Copy(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 OpenMQOFile(string file)
+ {
+ TSOGeneratorConfig config = new TSOGeneratorConfig();
+ config.ShowMaterials = cbShowMaterials.Checked;
+
+ if (rbRefBone.Checked)
+ {
+ TSOGeneratorRefBone gen = new TSOGeneratorRefBone(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);
+ }
+ else
+ {
+ }
+ }
+ #region tso->mqo UI
+ private void button1_Click(object sender, EventArgs e)
+ {
+ FolderBrowserDialog dlg = new FolderBrowserDialog();
+ dlg.SelectedPath = OutPath;
+
+ if (dlg.ShowDialog() == DialogResult.OK)
+ OutPath = 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.ShortName);
+ 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();
+
+ // オブジェクト
+ MqoFile mqo = new MqoFile();
+ 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;
+ OpenMQOFile(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 mtl = mesh.file.materials[sub.spec];
+ sub.spec = materialmap[mtl.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());
+ }
+ }
+}
\ No newline at end of file
{\r
public partial class FormMaterial : Form\r
{\r
- public Dictionary<string, MaterialInfo> materials;\r
+ public Dictionary<string, MaterialInfo> materials;\r
\r
public FormMaterial()\r
{\r
InitializeComponent();\r
- DialogResult = DialogResult.Cancel;\r
+ DialogResult = DialogResult.Cancel;\r
}\r
\r
private void FormMaterial_Load(object sender, EventArgs e)\r
{\r
- foreach(MaterialInfo i in materials.Values)\r
+ foreach (MaterialInfo mat_info in materials.Values)\r
{\r
- ListViewItem item= lvMaterials.Items.Add(i.Name);\r
- item.Tag = i;\r
- item.SubItems.Add(i.diffuse == null ? "" : i.diffuse);\r
- item.SubItems.Add(i.shadow == null ? "" : i.shadow);\r
- item.SubItems.Add(i.shader == null ? "" : i.shader);\r
+ ListViewItem item = lvMaterials.Items.Add(mat_info.Name);\r
+ item.Tag = mat_info;\r
+ item.SubItems.Add(mat_info.diffuse == null ? "" : mat_info.diffuse);\r
+ item.SubItems.Add(mat_info.shadow == null ? "" : mat_info.shadow);\r
+ item.SubItems.Add(mat_info.shader == null ? "" : mat_info.shader);\r
}\r
}\r
\r
}\r
}\r
\r
- DialogResult = DialogResult.OK;\r
+ DialogResult = DialogResult.OK;\r
Hide();\r
}\r
\r
private void bCancel_Click(object sender, EventArgs e)\r
{\r
- DialogResult = DialogResult.Cancel;\r
+ DialogResult = DialogResult.Cancel;\r
Hide();\r
}\r
\r
private void lvMaterials_SelectedIndexChanged(object sender, EventArgs e)\r
{\r
- if(lvMaterials.SelectedItems.Count > 0)\r
+ if (lvMaterials.SelectedItems.Count > 0)\r
{\r
- MaterialInfo mi = lvMaterials.SelectedItems[0].Tag as MaterialInfo;\r
- pgMaterial.SelectedObject = mi;\r
- } else\r
+ MaterialInfo mat_info = lvMaterials.SelectedItems[0].Tag as MaterialInfo;\r
+ pgMaterial.SelectedObject = mat_info;\r
+ }\r
+ else\r
{\r
- pgMaterial.SelectedObject = null;\r
+ pgMaterial.SelectedObject = null;\r
}\r
}\r
\r
private void pgMaterial_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)\r
{\r
- if(lvMaterials.SelectedItems.Count > 0)\r
+ if (lvMaterials.SelectedItems.Count > 0)\r
{\r
- ListViewItem item= lvMaterials.SelectedItems[0];\r
+ ListViewItem item = lvMaterials.SelectedItems[0];\r
\r
- switch(e.ChangedItem.PropertyDescriptor.Name)\r
+ switch (e.ChangedItem.PropertyDescriptor.Name)\r
{\r
- case "DiffuseTexture": item.SubItems[1].Text= e.ChangedItem.Value.ToString(); break;\r
- case "ShadowTexture": item.SubItems[2].Text= e.ChangedItem.Value.ToString(); break;\r
- case "ShaderFile": item.SubItems[3].Text= e.ChangedItem.Value.ToString(); break;\r
+ case "DiffuseTexture":\r
+ item.SubItems[1].Text = e.ChangedItem.Value.ToString();\r
+ break;\r
+ case "ShadowTexture":\r
+ item.SubItems[2].Text = e.ChangedItem.Value.ToString();\r
+ break;\r
+ case "ShaderFile":\r
+ item.SubItems[3].Text = e.ChangedItem.Value.ToString();\r
+ break;\r
}\r
}\r
}\r
-using System;\r
-using System.Collections.Generic;\r
-using System.Text;\r
-\r
-namespace Tso2MqoGui\r
-{\r
- public partial struct Point2 : IComparable<Point2>\r
- {\r
- public float x, y;\r
-\r
- public Point2(float x, float y)\r
- {\r
- this.x = x;\r
- this.y = y;\r
- }\r
-\r
- public float X { get { return x; } set { x= value; } }\r
- public float Y { get { return y; } set { y= value; } }\r
-\r
- public override string ToString()\r
- {\r
- return X+","+Y;\r
- }\r
-\r
- public static Point2 Parse(string[] t, int begin)\r
- {\r
- return new Point2(\r
- float.Parse(t[begin+0]),\r
- float.Parse(t[begin+1]));\r
- }\r
-\r
- public int CompareTo(Point2 obj)\r
- {\r
- int cmp;\r
- cmp = x.CompareTo(obj.x); if (cmp != 0) return cmp;\r
- cmp = y.CompareTo(obj.y);\r
- return cmp;\r
- }\r
-\r
- public override int GetHashCode()\r
- {\r
- return x.GetHashCode() ^ y.GetHashCode();\r
- }\r
-\r
- public bool Equals(Point2 p)\r
- {\r
- return (x == p.x) && (y == p.y);\r
- }\r
- }\r
-\r
- public partial struct Point3 : IComparable<Point3>\r
- {\r
- public float x, y, z;\r
-\r
- public Point3(float x, float y, float z)\r
- {\r
- this.x = x;\r
- this.y = y;\r
- this.z = z;\r
- }\r
-\r
- public float X { get { return x; } set { x= value; } }\r
- public float Y { get { return y; } set { y= value; } }\r
- public float Z { get { return z; } set { z= value; } }\r
-\r
- public static Point3 operator+(Point3 a, Point3 b)\r
- {\r
- return new Point3(a.x+b.x, a.y+b.y, a.z+b.z);\r
- }\r
-\r
- public static Point3 operator-(Point3 a, Point3 b)\r
- {\r
- return new Point3(a.x-b.x, a.y-b.y, a.z-b.z);\r
- }\r
-\r
- public override string ToString()\r
- {\r
- return X+","+Y+","+Z;\r
- }\r
-\r
- public static Point3 Cross(Point3 p, Point3 q)\r
- {\r
- return new Point3(\r
- p.y*q.z - p.z*q.y,\r
- p.z*q.x - p.x*q.z,\r
- p.x*q.y - p.y*q.x);\r
- }\r
-\r
- public static Point3 Normalize(Point3 p)\r
- {\r
- float d = p.x*p.x + p.y*p.y + p.z*p.z;\r
-\r
- if(d < 0.00001f)\r
- return p;\r
-\r
- d = (float)(1 / (Math.Sqrt(d)));\r
- return new Point3(p.x*d, p.y*d, p.z*d);\r
- }\r
-\r
- public static Point3 Parse(string[] t, int begin)\r
- {\r
- return new Point3(\r
- float.Parse(t[begin+0]),\r
- float.Parse(t[begin+1]),\r
- float.Parse(t[begin+2]));\r
- }\r
-\r
- public int CompareTo(Point3 obj)\r
- {\r
- int cmp;\r
- cmp = x.CompareTo(obj.x); if (cmp != 0) return cmp;\r
- cmp = y.CompareTo(obj.y); if (cmp != 0) return cmp;\r
- cmp = z.CompareTo(obj.z);\r
- return cmp;\r
- }\r
-\r
- public override int GetHashCode()\r
- {\r
- return x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode();\r
- }\r
-\r
- public bool Equals(Point3 p)\r
- {\r
- return (x == p.x) && (y == p.y) && (z == p.z);\r
- }\r
- }\r
-\r
- public partial struct Point4 : IComparable<Point4>\r
- {\r
- public float x, y, z, w;\r
-\r
- public Point4(float x, float y, float z, float w)\r
- {\r
- this.x = x;\r
- this.y = y;\r
- this.z = z;\r
- this.w = w;\r
- }\r
-\r
- public float X { get { return x; } set { x= value; } }\r
- public float Y { get { return y; } set { y= value; } }\r
- public float Z { get { return z; } set { z= value; } }\r
- public float W { get { return w; } set { w= value; } }\r
-\r
- public override string ToString()\r
- {\r
- return X+","+Y+","+Z+","+W;\r
- }\r
-\r
- public int CompareTo(Point4 obj)\r
- {\r
- int cmp;\r
- cmp = x.CompareTo(obj.x); if (cmp != 0) return cmp;\r
- cmp = y.CompareTo(obj.y); if (cmp != 0) return cmp;\r
- cmp = z.CompareTo(obj.z); if (cmp != 0) return cmp;\r
- cmp = w.CompareTo(obj.w);\r
- return cmp;\r
- }\r
-\r
- public override int GetHashCode()\r
- {\r
- return x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode() ^ w.GetHashCode();\r
- }\r
-\r
- public bool Equals(Point4 p)\r
- {\r
- return (x == p.x) && (y == p.y) && (z == p.z) && (w == p.w);\r
- }\r
- }\r
-\r
- public partial struct Color3\r
- {\r
- public float r, g, b;\r
- \r
- public Color3(float r, float g, float b)\r
- {\r
- this.r = r;\r
- this.g = g;\r
- this.b = b;\r
- }\r
-\r
- public float R { get { return r; } set { r= value; } }\r
- public float G { get { return g; } set { g= value; } }\r
- public float B { get { return b; } set { b= value; } }\r
-\r
- public override string ToString()\r
- {\r
- return R+","+G+","+B;\r
- }\r
-\r
- public static Color3 Parse(string[] t, int begin)\r
- {\r
- return new Color3(\r
- float.Parse(t[begin+0]),\r
- float.Parse(t[begin+1]),\r
- float.Parse(t[begin+2]));\r
- }\r
- }\r
-}\r
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tso2MqoGui
+{
+ public partial struct Point2 : IComparable<Point2>
+ {
+ public float x, y;
+
+ public Point2(float x, float y)
+ {
+ this.x = x;
+ this.y = y;
+ }
+
+ public float X { get { return x; } set { x = value; } }
+ public float Y { get { return y; } set { y = value; } }
+
+ public override string ToString()
+ {
+ return X + "," + Y;
+ }
+
+ public static Point2 Parse(string[] t, int begin)
+ {
+ return new Point2(
+ float.Parse(t[begin + 0]),
+ float.Parse(t[begin + 1]));
+ }
+
+ public int CompareTo(Point2 obj)
+ {
+ int cmp;
+ cmp = x.CompareTo(obj.x); if (cmp != 0) return cmp;
+ cmp = y.CompareTo(obj.y);
+ return cmp;
+ }
+
+ public override int GetHashCode()
+ {
+ return x.GetHashCode() ^ y.GetHashCode();
+ }
+
+ public bool Equals(Point2 p)
+ {
+ return (x == p.x) && (y == p.y);
+ }
+ }
+
+ public partial struct Point3 : IComparable<Point3>
+ {
+ public float x, y, z;
+
+ public Point3(float x, float y, float z)
+ {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ public float X { get { return x; } set { x = value; } }
+ public float Y { get { return y; } set { y = value; } }
+ public float Z { get { return z; } set { z = value; } }
+
+ public static Point3 operator +(Point3 a, Point3 b)
+ {
+ return new Point3(a.x + b.x, a.y + b.y, a.z + b.z);
+ }
+
+ public static Point3 operator -(Point3 a, Point3 b)
+ {
+ return new Point3(a.x - b.x, a.y - b.y, a.z - b.z);
+ }
+
+ public override string ToString()
+ {
+ return X + "," + Y + "," + Z;
+ }
+
+ public static Point3 Cross(Point3 p, Point3 q)
+ {
+ return new Point3(
+ p.y * q.z - p.z * q.y,
+ p.z * q.x - p.x * q.z,
+ p.x * q.y - p.y * q.x);
+ }
+
+ public static Point3 Normalize(Point3 p)
+ {
+ float d = p.x * p.x + p.y * p.y + p.z * p.z;
+
+ if (d < 0.00001f)
+ return p;
+
+ d = (float)(1 / (Math.Sqrt(d)));
+ return new Point3(p.x * d, p.y * d, p.z * d);
+ }
+
+ public static Point3 Parse(string[] t, int begin)
+ {
+ return new Point3(
+ float.Parse(t[begin + 0]),
+ float.Parse(t[begin + 1]),
+ float.Parse(t[begin + 2]));
+ }
+
+ public int CompareTo(Point3 obj)
+ {
+ int cmp;
+ cmp = x.CompareTo(obj.x); if (cmp != 0) return cmp;
+ cmp = y.CompareTo(obj.y); if (cmp != 0) return cmp;
+ cmp = z.CompareTo(obj.z);
+ return cmp;
+ }
+
+ public override int GetHashCode()
+ {
+ return x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode();
+ }
+
+ public bool Equals(Point3 p)
+ {
+ return (x == p.x) && (y == p.y) && (z == p.z);
+ }
+ }
+
+ public partial struct Point4 : IComparable<Point4>
+ {
+ public float x, y, z, w;
+
+ public Point4(float x, float y, float z, float w)
+ {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ this.w = w;
+ }
+
+ public float X { get { return x; } set { x = value; } }
+ public float Y { get { return y; } set { y = value; } }
+ public float Z { get { return z; } set { z = value; } }
+ public float W { get { return w; } set { w = value; } }
+
+ public override string ToString()
+ {
+ return X + "," + Y + "," + Z + "," + W;
+ }
+
+ public int CompareTo(Point4 obj)
+ {
+ int cmp;
+ cmp = x.CompareTo(obj.x); if (cmp != 0) return cmp;
+ cmp = y.CompareTo(obj.y); if (cmp != 0) return cmp;
+ cmp = z.CompareTo(obj.z); if (cmp != 0) return cmp;
+ cmp = w.CompareTo(obj.w);
+ return cmp;
+ }
+
+ public override int GetHashCode()
+ {
+ return x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode() ^ w.GetHashCode();
+ }
+
+ public bool Equals(Point4 p)
+ {
+ return (x == p.x) && (y == p.y) && (z == p.z) && (w == p.w);
+ }
+ }
+
+ public partial struct Color3
+ {
+ public float r, g, b;
+
+ public Color3(float r, float g, float b)
+ {
+ this.r = r;
+ this.g = g;
+ this.b = b;
+ }
+
+ public float R { get { return r; } set { r = value; } }
+ public float G { get { return g; } set { g = value; } }
+ public float B { get { return b; } set { b = value; } }
+
+ public override string ToString()
+ {
+ return R + "," + G + "," + B;
+ }
+
+ public static Color3 Parse(string[] t, int begin)
+ {
+ return new Color3(
+ float.Parse(t[begin + 0]),
+ float.Parse(t[begin + 1]),
+ float.Parse(t[begin + 2]));
+ }
+ }
+}
\ No newline at end of file
-using System;\r
-using System.Collections.Generic;\r
-using System.Text;\r
-using System.Runtime.InteropServices;\r
-\r
-namespace Tso2MqoGui\r
-{\r
- using BYTE = Byte;\r
- using WORD = UInt16;\r
- using DWORD = UInt32;\r
- using LONG = Int32;\r
-\r
- [StructLayout(LayoutKind.Sequential, Pack=1)]\r
- public struct TARGA_HEADER\r
- {\r
- public BYTE id;\r
- public BYTE colormap;\r
- public BYTE imagetype;\r
- public BYTE unknown0;\r
- public BYTE unknown1;\r
- public BYTE unknown2;\r
- public BYTE unknown3;\r
- public BYTE unknown4;\r
- public WORD x;\r
- public WORD y;\r
- public WORD width;\r
- public WORD height;\r
- public BYTE depth;\r
- public BYTE type;\r
- };\r
-\r
- [StructLayout(LayoutKind.Sequential, Pack=1)]\r
- public struct BITMAPFILEHEADER\r
- {\r
- public WORD bfType;\r
- public DWORD bfSize;\r
- public WORD bfReserved1;\r
- public WORD bfReserved2;\r
- public DWORD bfOffBits;\r
- }\r
-\r
- [StructLayout(LayoutKind.Sequential, Pack=1)]\r
- public struct BITMAPINFOHEADER\r
- {\r
- public DWORD biSize;\r
- public LONG biWidth;\r
- public LONG biHeight;\r
- public WORD biPlanes;\r
- public WORD biBitCount;\r
- public DWORD biCompression;\r
- public DWORD biSizeImage;\r
- public LONG biXPelsPerMeter;\r
- public LONG biYPelsPerMeter;\r
- public DWORD biClrUsed;\r
- public DWORD biClrImportant;\r
- }\r
-}\r
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Runtime.InteropServices;
+
+namespace Tso2MqoGui
+{
+ using BYTE = Byte;
+ using WORD = UInt16;
+ using DWORD = UInt32;
+ using LONG = Int32;
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct TARGA_HEADER
+ {
+ public BYTE id;
+ public BYTE colormap;
+ public BYTE imagetype;
+ public BYTE unknown0;
+ public BYTE unknown1;
+ public BYTE unknown2;
+ public BYTE unknown3;
+ public BYTE unknown4;
+ public WORD x;
+ public WORD y;
+ public WORD width;
+ public WORD height;
+ public BYTE depth;
+ public BYTE type;
+ };
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct BITMAPFILEHEADER
+ {
+ public WORD bfType;
+ public DWORD bfSize;
+ public WORD bfReserved1;
+ public WORD bfReserved2;
+ public DWORD bfOffBits;
+ }
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct BITMAPINFOHEADER
+ {
+ public DWORD biSize;
+ public LONG biWidth;
+ public LONG biHeight;
+ public WORD biPlanes;
+ public WORD biBitCount;
+ public DWORD biCompression;
+ public DWORD biSizeImage;
+ public LONG biXPelsPerMeter;
+ public LONG biYPelsPerMeter;
+ public DWORD biClrUsed;
+ public DWORD biClrImportant;
+ }
+}
\ No newline at end of file
[XmlRoot("TsoImportInfo")]\r
public class ImportInfo\r
{\r
- [XmlIgnore] public string filename;\r
- [XmlElement("Effect")] public List<ImportEffectInfo> effects = new List<ImportEffectInfo>();\r
- [XmlElement("Textures")] public List<ImportTextureInfo> textures = new List<ImportTextureInfo>();\r
- [XmlElement("Materials")] public List<ImportMaterialInfo> materials = new List<ImportMaterialInfo>();\r
- \r
- private Dictionary<string, ImportEffectInfo> effectmap;\r
- private Dictionary<string, ImportTextureInfo> texturemap;\r
- private Dictionary<string, ImportMaterialInfo> materialmap;\r
+ [XmlIgnore]\r
+ public string filename;\r
+ [XmlElement("Effect")]\r
+ public List<ImportEffectInfo> effects = new List<ImportEffectInfo>();\r
+ [XmlElement("Textures")]\r
+ public List<ImportTextureInfo> textures = new List<ImportTextureInfo>();\r
+ [XmlElement("Materials")]\r
+ public List<ImportMaterialInfo> materials = new List<ImportMaterialInfo>();\r
\r
- public static Type Type { get { return typeof(ImportInfo); } }\r
+ private Dictionary<string, ImportEffectInfo> effectmap;\r
+ private Dictionary<string, ImportTextureInfo> texturemap;\r
+ private Dictionary<string, ImportMaterialInfo> materialmap;\r
+\r
+ public static Type Type { get { return typeof(ImportInfo); } }\r
\r
public void PostLoad()\r
{\r
- effectmap = new Dictionary<string, ImportEffectInfo>();\r
- texturemap = new Dictionary<string, ImportTextureInfo>();\r
+ effectmap = new Dictionary<string, ImportEffectInfo>();\r
+ texturemap = new Dictionary<string, ImportTextureInfo>();\r
materialmap = new Dictionary<string, ImportMaterialInfo>();\r
\r
foreach (ImportEffectInfo i in effects)\r
}\r
}\r
\r
- foreach(ImportEffectInfo i in effects) i.PostLoad(this);\r
- foreach(ImportTextureInfo i in textures) i.PostLoad(this);\r
- foreach(ImportMaterialInfo i in materials) i.PostLoad(this);\r
+ foreach (ImportEffectInfo i in effects)\r
+ i.PostLoad(this);\r
+ foreach (ImportTextureInfo i in textures)\r
+ i.PostLoad(this);\r
+ foreach (ImportMaterialInfo i in materials)\r
+ i.PostLoad(this);\r
}\r
\r
public ImportEffectInfo GetEffect(string name)\r
{\r
- ImportEffectInfo info= null;\r
+ ImportEffectInfo info = null;\r
effectmap.TryGetValue(name, out info);\r
return info;\r
}\r
\r
public ImportTextureInfo GetTexture(string name)\r
{\r
- ImportTextureInfo info= null;\r
+ ImportTextureInfo info = null;\r
texturemap.TryGetValue(name, out info);\r
return info;\r
}\r
\r
public ImportMaterialInfo GetMaterial(string name)\r
{\r
- ImportMaterialInfo info= null;\r
+ ImportMaterialInfo info = null;\r
materialmap.TryGetValue(name, out info);\r
return info;\r
}\r
\r
public static ImportInfo Load(string file)\r
{\r
- using(FileStream fs= File.OpenRead(file))\r
+ using (FileStream fs = File.OpenRead(file))\r
{\r
- ImportInfo ii = new XmlSerializer(Type).Deserialize(fs) as ImportInfo;\r
- ii.filename = file;\r
+ ImportInfo ii = new XmlSerializer(Type).Deserialize(fs) as ImportInfo;\r
+ ii.filename = file;\r
ii.PostLoad();\r
return ii;\r
}\r
\r
public static void Save(string file, ImportInfo ii)\r
{\r
- using(FileStream fs= File.OpenWrite(file))\r
+ using (FileStream fs = File.OpenWrite(file))\r
{\r
fs.SetLength(0);\r
new XmlSerializer(Type).Serialize(fs, ii);\r
\r
public class ImportInfoItem\r
{\r
- [XmlIgnore] protected ImportInfo Owner;\r
+ [XmlIgnore]\r
+ protected ImportInfo Owner;\r
\r
public virtual void PostLoad(ImportInfo owner)\r
{\r
- this.Owner = owner;\r
+ this.Owner = owner;\r
}\r
}\r
\r
public class ImportEffectInfo : ImportInfoItem\r
{\r
- [XmlAttribute] public string Name;\r
+ [XmlAttribute]\r
+ public string Name;\r
\r
public ImportEffectInfo()\r
{\r
\r
public ImportEffectInfo(TSOEffect eff)\r
{\r
- Name = eff.Name;\r
+ Name = eff.Name;\r
}\r
\r
public override string ToString()\r
\r
public class ImportTextureInfo : ImportInfoItem\r
{\r
- [XmlAttribute] public string Name;\r
- [XmlAttribute] public string File;\r
- [XmlAttribute] public int BytesPerPixel;\r
- [XmlAttribute] public int Width;\r
- [XmlAttribute] public int Height;\r
+ [XmlAttribute]\r
+ public string Name;\r
+ [XmlAttribute]\r
+ public string File;\r
+ [XmlAttribute]\r
+ public int BytesPerPixel;\r
+ [XmlAttribute]\r
+ public int Width;\r
+ [XmlAttribute]\r
+ public int Height;\r
\r
public ImportTextureInfo()\r
{\r
\r
public ImportTextureInfo(TSOTex tex)\r
{\r
- Name = tex.Name;\r
- File = tex.File.Trim('"');\r
- BytesPerPixel = tex.Depth;\r
- Width = tex.Width;\r
- Height = tex.Height;\r
+ Name = tex.Name;\r
+ File = tex.File.Trim('"');\r
+ BytesPerPixel = tex.Depth;\r
+ Width = tex.Width;\r
+ Height = tex.Height;\r
}\r
\r
public override string ToString()\r
{\r
- return "Name:" + Name\r
- +", File:" + File\r
- +", BytesPerPixel:" + BytesPerPixel\r
- +", Width:" + Width\r
- +", Height:" + Height\r
+ return "Name:" + Name\r
+ + " File:" + File\r
+ + " BytesPerPixel:" + BytesPerPixel\r
+ + " Width:" + Width\r
+ + " Height:" + Height\r
;\r
}\r
}\r
\r
public class ImportMaterialInfo : ImportInfoItem\r
{\r
- [XmlAttribute] public string Name;\r
- [XmlAttribute] public string File;\r
- [XmlIgnore] public Dictionary<string, string> parameters;\r
- [XmlIgnore] public ImportTextureInfo color;\r
- [XmlIgnore] public ImportTextureInfo shadow;\r
+ [XmlAttribute]\r
+ public string Name;\r
+ [XmlAttribute]\r
+ public string File;\r
+ [XmlIgnore]\r
+ public Dictionary<string, string> parameters;\r
+ [XmlIgnore]\r
+ public ImportTextureInfo ColorTex;\r
+ [XmlIgnore]\r
+ public ImportTextureInfo ShadeTex;\r
\r
public ImportMaterialInfo()\r
{\r
}\r
\r
- public ImportMaterialInfo(TSOMaterial mtl)\r
+ public ImportMaterialInfo(TSOMaterial mat)\r
{\r
- Name = mtl.Name;\r
- File = mtl.File.Trim('"');\r
+ Name = mat.Name;\r
+ File = mat.File.Trim('"');\r
}\r
\r
public override void PostLoad(ImportInfo owner)\r
{\r
base.PostLoad(owner);\r
\r
- string dir = Path.GetDirectoryName(owner.filename);\r
- string codefile= Path.Combine(dir, Name);\r
+ string dir = Path.GetDirectoryName(owner.filename);\r
+ string codefile = Path.Combine(dir, Name);\r
\r
- if(System.IO.File.Exists(codefile))\r
+ if (System.IO.File.Exists(codefile))\r
{\r
- TSOMaterialCode code= TSOMaterialCode.GenerateFromFile(codefile);\r
- TSOParameter p;\r
+ TSOMaterialCode code = TSOMaterialCode.GenerateFromFile(codefile);\r
+ TSOParameter p;\r
\r
- if(code.TryGetValue("ColorTex", out p))\r
- color = owner.GetTexture(p.Value);\r
+ if (code.TryGetValue("ColorTex", out p))\r
+ ColorTex = owner.GetTexture(p.Value);\r
\r
- if(code.TryGetValue("ShadeTex", out p))\r
- shadow = owner.GetTexture(p.Value);\r
+ if (code.TryGetValue("ShadeTex", out p))\r
+ ShadeTex = owner.GetTexture(p.Value);\r
}\r
}\r
\r
public override string ToString()\r
{\r
- return "Name:" + Name\r
- +", File:" + File\r
+ return "Name:" + Name\r
+ + " File:" + File\r
;\r
}\r
}\r
-}\r
+}
\ No newline at end of file
-using System;\r
-using System.Collections.Generic;\r
-using System.IO;\r
-using System.Text;\r
-using System.Text.RegularExpressions;\r
-\r
-namespace Tso2MqoGui\r
-{\r
- public class MqoFile\r
- {\r
- private delegate bool SectionHandler(string[] tokens);\r
- \r
- public static char[] delimiters = new char[]{' ', '\t'};\r
- public static char[] delimiters2 = new char[]{' ', '\t', '(', ')'};\r
-\r
- private string file;\r
- private StreamReader sr;\r
- private MqoScene scene;\r
- private List<MqoMaterial> materials;\r
- private List<MqoObject> objects = new List<MqoObject>();\r
- private MqoObject current;\r
-\r
- public MqoScene Scene { get { return scene; } }\r
- public List<MqoMaterial> Materials { get { return materials; } }\r
- public List<MqoObject> Objects { get { return objects; } }\r
-\r
- public void Load(string file)\r
- {\r
- using(FileStream fs= File.OpenRead(file))\r
- {\r
- this.file = file;\r
- sr = new StreamReader(fs, Encoding.Default);\r
- ReadAll();\r
- }\r
- }\r
-\r
- public void Dump()\r
- {\r
- System.Diagnostics.Debug.WriteLine(file);\r
- System.Diagnostics.Debug.WriteLine(scene);\r
-\r
- foreach(MqoMaterial i in materials)\r
- System.Diagnostics.Debug.WriteLine(i);\r
-\r
- foreach(MqoObject i in objects)\r
- System.Diagnostics.Debug.WriteLine(i);\r
- }\r
-\r
- public void ReadAll()\r
- {\r
- DoRead(SectionRoot);\r
- }\r
-\r
- private static string[] SplitString(string s)\r
- {\r
- List<string> tokens = new List<string>();\r
- StringBuilder sb = new StringBuilder(s.Length);\r
- bool str = false;\r
- bool escape = false;\r
- bool bracket= false;\r
- s = s.Trim(' ', '\t', '\r', '\n');\r
-\r
- foreach(char i in s)\r
- {\r
- if(escape)\r
- {\r
- sb.Append(i);\r
- escape = false;\r
- continue;\r
- }\r
-\r
-\r
- switch(i)\r
- {\r
- case '\\':\r
- if(str) sb.Append(i);\r
- else escape = true;\r
- break;\r
- case ' ':\r
- case '\t':\r
- if(bracket) {sb.Append(i); }\r
- else if(str) {sb.Append(i); }\r
- else if(sb.Length > 0) {tokens.Add(sb.ToString()); sb.Length= 0; }\r
- break;\r
- case '(':\r
- sb.Append(i);\r
- if(!str)\r
- bracket= true;\r
- break;\r
- case ')':\r
- sb.Append(i);\r
- if(!str)\r
- bracket= false;\r
- break;\r
- case '\"':\r
- sb.Append(i);\r
- str = !str;\r
- break;\r
- default:\r
- sb.Append(i);\r
- break;\r
- }\r
- }\r
-\r
- if(sb.Length > 0)\r
- tokens.Add(sb.ToString());\r
-\r
- return tokens.ToArray();\r
- }\r
-\r
- private void DoRead(SectionHandler h)\r
- {\r
- for(int no= 1;; ++no)\r
- {\r
- string line= sr.ReadLine();\r
-\r
- if(line == null)\r
- break;\r
-\r
- line = line.Trim();\r
- string[] tokens = SplitString(line);\r
-\r
- try\r
- {\r
- if(tokens.Length == 0)\r
- continue;\r
-\r
- if(!h(tokens))\r
- break;\r
- } catch(Exception e)\r
- {\r
- string msg = string.Format("File format error: {0} \"{1}\"", no, line);\r
- throw new Exception(msg, e);\r
- }\r
- }\r
- }\r
-\r
- public void Error(string[] tokens)\r
- {\r
- throw new Exception("File Format Error: \"" + string.Concat(tokens) + "\"");\r
- }\r
-\r
- private bool SectionRoot(string[] tokens)\r
- {\r
- switch(tokens[0].ToLower())\r
- {\r
- case "metasequoia": ParseMetasequoia(tokens); return true;\r
- case "format": ParseFormat (tokens); return true;\r
- case "scene": ParseScene (tokens); return true;\r
- case "material": ParseMaterial (tokens); return true;\r
- case "object": ParseObject (tokens); return true;\r
- case "eof": return false;\r
- //default: Error(tokens); return false;\r
- default: return true;\r
- }\r
- }\r
-\r
- private bool SectionScene(string[] tokens)\r
- {\r
- scene = new MqoScene();\r
-\r
- switch(tokens[0].ToLower())\r
- {\r
- case "pos": scene.pos = Point3.Parse(tokens, 1); return true;\r
- case "lookat": scene.lookat = Point3.Parse(tokens, 1); return true;\r
- case "head": scene.head = float .Parse(tokens[1]); return true;\r
- case "pich": scene.pich = float .Parse(tokens[1]); return true;\r
- case "ortho": scene.ortho = float .Parse(tokens[1]); return true;\r
- case "zoom2": scene.zoom2 = float .Parse(tokens[1]); return true;\r
- case "amb": scene.amb = Color3.Parse(tokens, 1); return true;\r
- case "}": return false;\r
- //default: Error(tokens); return false;\r
- default: return true;\r
- }\r
- }\r
-\r
- private static string[] SplitParam(string s)\r
- {\r
- return s.Split(delimiters2, StringSplitOptions.RemoveEmptyEntries);\r
- }\r
-\r
- private bool SectionMaterial(string[] tokens)\r
- {\r
- if(tokens[0] == "}")\r
- return false;\r
-\r
- StringBuilder sb = new StringBuilder();\r
-\r
- foreach(string i in tokens)\r
- sb.Append(' ').Append(i);\r
-\r
- string line= sb.ToString().Trim();\r
- MqoMaterial m = new MqoMaterial(tokens[0].Trim('"'));\r
- tokens = SplitString(line);\r
- materials.Add(m);\r
-\r
- for(int i= 1 ; i < tokens.Length; ++i)\r
- {\r
- string t = tokens[i];\r
- string t2 = t.ToLower();\r
-\r
- if(t2.StartsWith("shader(")) m.shader = int .Parse(SplitParam(t)[1]);\r
- else if(t2.StartsWith("col(")) m.col = Color3.Parse(SplitParam(t), 1);\r
- else if(t2.StartsWith("dif(")) m.dif = float .Parse(SplitParam(t)[1]);\r
- else if(t2.StartsWith("amb(")) m.amb = float .Parse(SplitParam(t)[1]);\r
- else if(t2.StartsWith("emi(")) m.emi = float .Parse(SplitParam(t)[1]);\r
- else if(t2.StartsWith("spc(")) m.spc = float .Parse(SplitParam(t)[1]);\r
- else if(t2.StartsWith("power(")) m.power = float .Parse(SplitParam(t)[1]);\r
- else if(t2.StartsWith("tex(")) m.tex = t.Substring(3).Trim('(', ')', '"');\r
- }\r
-\r
- return true;\r
- }\r
-\r
- private bool SectionObject(string[] tokens)\r
- {\r
- switch(tokens[0].ToLower())\r
- {\r
- case "visible": current.visible = int .Parse(tokens[1]); return true;\r
- case "locking": current.locking = int .Parse(tokens[1]); return true;\r
- case "shading": current.shading = int .Parse(tokens[1]); return true;\r
- case "facet": current.facet = float .Parse(tokens[1]); return true;\r
- case "color": current.color = Color3.Parse(tokens, 1); return true;\r
- case "color_type": current.color_type = int .Parse(tokens[1]); return true;\r
- case "vertex": ParseVertex(tokens); return true;\r
- case "face": ParseFace(tokens); return true;\r
- case "}": return false;\r
- //default: Error(tokens); return false;\r
- default: return true;\r
- }\r
- }\r
-\r
- private bool SectionVertex(string[] tokens)\r
- {\r
- if (tokens[0] == "}")\r
- return false;\r
-\r
- current.vertices.Add(Point3.Parse(tokens, 0));\r
-\r
- return true;\r
- }\r
-\r
- private bool SectionFace(string[] tokens)\r
- {\r
- if (tokens[0] == "}")\r
- return false;\r
-\r
- int nface = int.Parse(tokens[0]);\r
- {\r
- StringBuilder sb = new StringBuilder();\r
- foreach (string i in tokens)\r
- sb.Append(' ').Append(i);\r
- string line = sb.ToString().Trim();\r
- tokens = SplitString(line);\r
- }\r
- switch (nface)\r
- {\r
- case 3:\r
- {\r
- MqoFace f = new MqoFace();\r
-\r
- for (int i = 1; i < tokens.Length; ++i)\r
- {\r
- string t = tokens[i];\r
- string t2 = t.ToLower();\r
-\r
- if (t2.StartsWith("v("))\r
- {\r
- string[] t3 = SplitParam(t);\r
- f.a = ushort.Parse(t3[1]);\r
- f.b = ushort.Parse(t3[2]);\r
- f.c = ushort.Parse(t3[3]);\r
- }\r
- else\r
- if (t2.StartsWith("m("))\r
- {\r
- string[] t3 = SplitParam(t);\r
- f.mtl = ushort.Parse(t3[1]);\r
- }\r
- else\r
- if (t2.StartsWith("uv("))\r
- {\r
- string[] t3 = SplitParam(t);\r
- f.ta = Point2.Parse(t3, 1);\r
- f.tb = Point2.Parse(t3, 3);\r
- f.tc = Point2.Parse(t3, 5);\r
- }\r
- }\r
- current.faces.Add(f);\r
- }\r
- break;\r
- case 4:\r
- {\r
- MqoFace f = new MqoFace();\r
- MqoFace f2 = new MqoFace();\r
-\r
- for (int i = 1; i < tokens.Length; ++i)\r
- {\r
- string t = tokens[i];\r
- string t2 = t.ToLower();\r
-\r
- if (t2.StartsWith("v("))\r
- {\r
- string[] t3 = SplitParam(t);\r
- f.a = ushort.Parse(t3[1]);\r
- f.b = ushort.Parse(t3[2]);\r
- f.c = ushort.Parse(t3[3]);\r
- f2.a = f.a;\r
- f2.b = f.c;\r
- f2.c = ushort.Parse(t3[4]);\r
- }\r
- else\r
- if (t2.StartsWith("m("))\r
- {\r
- string[] t3 = SplitParam(t);\r
- f.mtl = ushort.Parse(t3[1]);\r
- f2.mtl = f.mtl;\r
- }\r
- else\r
- if (t2.StartsWith("uv("))\r
- {\r
- string[] t3 = SplitParam(t);\r
- f.ta = Point2.Parse(t3, 1);\r
- f.tb = Point2.Parse(t3, 3);\r
- f.tc = Point2.Parse(t3, 5);\r
- f2.ta = f.ta;\r
- f2.tb = f.tc;\r
- f2.tc = Point2.Parse(t3, 7);\r
- }\r
- }\r
- current.faces.Add(f);\r
- current.faces.Add(f2);\r
- }\r
- break;\r
- }\r
- return true;\r
- }\r
-\r
- //----- Root elements ----------------------------------------------\r
- private void ParseMetasequoia(string[] tokens)\r
- {\r
- if(tokens[1].ToLower() != "document") Error(tokens);\r
- }\r
-\r
- private void ParseFormat(string[] tokens)\r
- {\r
- if(tokens[1].ToLower() != "text") Error(tokens);\r
- if(tokens[2].ToLower() != "ver") Error(tokens);\r
- if(tokens[3].ToLower() != "1.0") Error(tokens);\r
- }\r
-\r
- private void ParseScene(string[] tokens)\r
- {\r
- if(tokens[1].ToLower() != "{") Error(tokens);\r
-\r
- DoRead(SectionScene);\r
- }\r
-\r
- private void ParseMaterial(string[] tokens)\r
- {\r
- if(tokens[2].ToLower() != "{") Error(tokens);\r
-\r
- materials = new List<MqoMaterial>(int.Parse(tokens[1]));\r
- DoRead(SectionMaterial);\r
- }\r
-\r
- private void ParseObject(string[] tokens)\r
- {\r
- if(tokens[2].ToLower() != "{") Error(tokens);\r
-\r
- current = new MqoObject(tokens[1].Trim('"'));\r
- objects.Add(current);\r
- DoRead(SectionObject);\r
- }\r
-\r
- private void ParseVertex(string[] tokens)\r
- {\r
- if(tokens[2].ToLower() != "{") Error(tokens);\r
-\r
- current.vertices = new List<Point3>(int.Parse(tokens[1]));\r
- DoRead(SectionVertex);\r
- }\r
-\r
- private void ParseFace(string[] tokens)\r
- {\r
- if(tokens[2].ToLower() != "{") Error(tokens);\r
-\r
- current.faces = new List<MqoFace>(int.Parse(tokens[1]));\r
- DoRead(SectionFace);\r
- }\r
- }\r
-\r
- public class MqoScene\r
- {\r
- public Point3 pos;\r
- public Point3 lookat;\r
- public float head;\r
- public float pich;\r
- public float ortho;\r
- public float zoom2;\r
- public Color3 amb;\r
-\r
- public override string ToString()\r
- {\r
- return (new StringBuilder(256))\r
- .Append(" pos: ") .Append(pos)\r
- .Append(" lookat: ").Append(lookat)\r
- .Append(" head: ") .Append(head)\r
- .Append(" pich: ") .Append(pich)\r
- .Append(" ortho: ") .Append(ortho)\r
- .Append(" zoom2: ") .Append(zoom2)\r
- .Append(" amb: ") .Append(amb)\r
- .ToString();\r
- }\r
- }\r
-\r
- public class MqoMaterial\r
- {\r
- public string name;\r
- public int shader;\r
- public Color3 col;\r
- public float dif;\r
- public float amb;\r
- public float emi;\r
- public float spc;\r
- public float power;\r
- public string tex;\r
-\r
- public MqoMaterial() { }\r
- public MqoMaterial(string n) { name= n; }\r
-\r
- public override string ToString()\r
- {\r
- return (new StringBuilder(256))\r
- .Append(" shader: ").Append(shader)\r
- .Append(" col: ") .Append(col)\r
- .Append(" dif: ") .Append(dif)\r
- .Append(" amb: ") .Append(amb)\r
- .Append(" emi: ") .Append(emi)\r
- .Append(" spc: ") .Append(spc)\r
- .Append(" power: ") .Append(power)\r
- .Append(" tex: ") .Append(tex)\r
- .Append(" name: ") .Append(name)\r
- .ToString();\r
- }\r
- }\r
-\r
- public class MqoObject\r
- {\r
- public string name;\r
- public int visible;\r
- public int locking;\r
- public int shading;\r
- public float facet;\r
- public Color3 color;\r
- public int color_type;\r
- public List<Point3> vertices;\r
- public List<MqoFace> faces;\r
-\r
- public MqoObject() { }\r
- public MqoObject(string n) { name= n; }\r
-\r
- public override string ToString()\r
- {\r
- return (new StringBuilder(256))\r
- .Append(" visible: ") .Append(visible)\r
- .Append(" locking: ") .Append(locking)\r
- .Append(" shading: ") .Append(shading)\r
- .Append(" facet: ") .Append(facet)\r
- .Append(" color: ") .Append(color)\r
- .Append(" color_type: ").Append(color_type)\r
- .Append(" vertices: ") .Append(vertices.Count)\r
- .Append(" faces: ") .Append(faces.Count)\r
- .Append(" name: ") .Append(name)\r
- .ToString();\r
- }\r
- }\r
-\r
- public class MqoFace\r
- {\r
- public ushort a, b, c, mtl;\r
- public Point2 ta, tb, tc;\r
-\r
- public MqoFace()\r
- {\r
- }\r
-\r
- public MqoFace(ushort a, ushort b, ushort c, ushort mtl, Point2 ta, Point2 tb, Point2 tc)\r
- {\r
- this.a = a;\r
- this.b = b;\r
- this.c = c;\r
- this.mtl= mtl;\r
- this.ta = ta;\r
- this.tb = tb;\r
- this.tc = tc;\r
- }\r
-\r
- public override string ToString()\r
- {\r
- return (new StringBuilder(256))\r
- .Append("v: ") .Append(a).Append(" ").Append(b).Append(" ").Append(c)\r
- .Append(" mtl: ").Append(mtl)\r
- .Append(" uv: ") .Append(ta).Append(" ").Append(tb).Append(" ").Append(tc)\r
- .ToString();\r
- }\r
- }\r
-}\r
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace Tso2MqoGui
+{
+ public class MqoFile
+ {
+ private delegate bool SectionHandler(string[] tokens);
+
+ public static char[] delimiters = new char[] { ' ', '\t' };
+ public static char[] delimiters2 = new char[] { ' ', '\t', '(', ')' };
+
+ private string file;
+ private StreamReader sr;
+ private MqoScene scene;
+ private List<MqoMaterial> materials;
+ private List<MqoObject> objects = new List<MqoObject>();
+ private MqoObject current;
+
+ public MqoScene Scene { get { return scene; } }
+ public List<MqoMaterial> Materials { get { return materials; } }
+ public List<MqoObject> Objects { get { return objects; } }
+
+ public void Load(string file)
+ {
+ using (FileStream fs = File.OpenRead(file))
+ {
+ this.file = file;
+ sr = new StreamReader(fs, Encoding.Default);
+ ReadAll();
+ }
+ }
+
+ public void Dump()
+ {
+ System.Diagnostics.Debug.WriteLine(file);
+ System.Diagnostics.Debug.WriteLine(scene);
+
+ foreach (MqoMaterial i in materials)
+ System.Diagnostics.Debug.WriteLine(i);
+
+ foreach (MqoObject i in objects)
+ System.Diagnostics.Debug.WriteLine(i);
+ }
+
+ public void ReadAll()
+ {
+ DoRead(SectionRoot);
+ }
+
+ private static string[] SplitString(string s)
+ {
+ List<string> tokens = new List<string>();
+ StringBuilder sb = new StringBuilder(s.Length);
+ bool str = false;
+ bool escape = false;
+ bool bracket = false;
+ s = s.Trim(' ', '\t', '\r', '\n');
+
+ foreach (char i in s)
+ {
+ if (escape)
+ {
+ sb.Append(i);
+ escape = false;
+ continue;
+ }
+
+
+ switch (i)
+ {
+ case '\\':
+ if (str) sb.Append(i);
+ else escape = true;
+ break;
+ case ' ':
+ case '\t':
+ if (bracket) { sb.Append(i); }
+ else if (str) { sb.Append(i); }
+ else if (sb.Length > 0) { tokens.Add(sb.ToString()); sb.Length = 0; }
+ break;
+ case '(':
+ sb.Append(i);
+ if (!str)
+ bracket = true;
+ break;
+ case ')':
+ sb.Append(i);
+ if (!str)
+ bracket = false;
+ break;
+ case '\"':
+ sb.Append(i);
+ str = !str;
+ break;
+ default:
+ sb.Append(i);
+ break;
+ }
+ }
+
+ if (sb.Length > 0)
+ tokens.Add(sb.ToString());
+
+ return tokens.ToArray();
+ }
+
+ private void DoRead(SectionHandler h)
+ {
+ for (int no = 1; ; ++no)
+ {
+ string line = sr.ReadLine();
+
+ if (line == null)
+ break;
+
+ line = line.Trim();
+ string[] tokens = SplitString(line);
+
+ try
+ {
+ if (tokens.Length == 0)
+ continue;
+
+ if (!h(tokens))
+ break;
+ }
+ catch (Exception exception)
+ {
+ string msg = string.Format("File format error: {0} \"{1}\"", no, line);
+ throw new Exception(msg, exception);
+ }
+ }
+ }
+
+ public void Error(string[] tokens)
+ {
+ throw new Exception("File Format Error: \"" + string.Concat(tokens) + "\"");
+ }
+
+ private bool SectionRoot(string[] tokens)
+ {
+ switch (tokens[0].ToLower())
+ {
+ case "metasequoia": ParseMetasequoia(tokens); return true;
+ case "format": ParseFormat(tokens); return true;
+ case "scene": ParseScene(tokens); return true;
+ case "material": ParseMaterial(tokens); return true;
+ case "object": ParseObject(tokens); return true;
+ case "eof": return false;
+ //default: Error(tokens); return false;
+ default: return true;
+ }
+ }
+
+ private bool SectionScene(string[] tokens)
+ {
+ scene = new MqoScene();
+
+ switch (tokens[0].ToLower())
+ {
+ case "pos": scene.pos = Point3.Parse(tokens, 1); return true;
+ case "lookat": scene.lookat = Point3.Parse(tokens, 1); return true;
+ case "head": scene.head = float.Parse(tokens[1]); return true;
+ case "pich": scene.pich = float.Parse(tokens[1]); return true;
+ case "ortho": scene.ortho = float.Parse(tokens[1]); return true;
+ case "zoom2": scene.zoom2 = float.Parse(tokens[1]); return true;
+ case "amb": scene.amb = Color3.Parse(tokens, 1); return true;
+ case "}": return false;
+ //default: Error(tokens); return false;
+ default: return true;
+ }
+ }
+
+ private static string[] SplitParam(string s)
+ {
+ return s.Split(delimiters2, StringSplitOptions.RemoveEmptyEntries);
+ }
+
+ private bool SectionMaterial(string[] tokens)
+ {
+ if (tokens[0] == "}")
+ return false;
+
+ StringBuilder sb = new StringBuilder();
+
+ foreach (string i in tokens)
+ sb.Append(' ').Append(i);
+
+ string line = sb.ToString().Trim();
+ MqoMaterial m = new MqoMaterial(tokens[0].Trim('"'));
+ tokens = SplitString(line);
+ materials.Add(m);
+
+ for (int i = 1; i < tokens.Length; ++i)
+ {
+ string t = tokens[i];
+ string t2 = t.ToLower();
+
+ if (t2.StartsWith("shader(")) m.shader = int.Parse(SplitParam(t)[1]);
+ else if (t2.StartsWith("col(")) m.col = Color3.Parse(SplitParam(t), 1);
+ else if (t2.StartsWith("dif(")) m.dif = float.Parse(SplitParam(t)[1]);
+ else if (t2.StartsWith("amb(")) m.amb = float.Parse(SplitParam(t)[1]);
+ else if (t2.StartsWith("emi(")) m.emi = float.Parse(SplitParam(t)[1]);
+ else if (t2.StartsWith("spc(")) m.spc = float.Parse(SplitParam(t)[1]);
+ else if (t2.StartsWith("power(")) m.power = float.Parse(SplitParam(t)[1]);
+ else if (t2.StartsWith("tex(")) m.tex = t.Substring(3).Trim('(', ')', '"');
+ }
+
+ return true;
+ }
+
+ private bool SectionObject(string[] tokens)
+ {
+ switch (tokens[0].ToLower())
+ {
+ case "visible": current.visible = int.Parse(tokens[1]); return true;
+ case "locking": current.locking = int.Parse(tokens[1]); return true;
+ case "shading": current.shading = int.Parse(tokens[1]); return true;
+ case "facet": current.facet = float.Parse(tokens[1]); return true;
+ case "color": current.color = Color3.Parse(tokens, 1); return true;
+ case "color_type": current.color_type = int.Parse(tokens[1]); return true;
+ case "vertex": ParseVertex(tokens); return true;
+ case "face": ParseFace(tokens); return true;
+ case "}": return false;
+ //default: Error(tokens); return false;
+ default: return true;
+ }
+ }
+
+ private bool SectionVertex(string[] tokens)
+ {
+ if (tokens[0] == "}")
+ return false;
+
+ current.vertices.Add(Point3.Parse(tokens, 0));
+
+ return true;
+ }
+
+ private bool SectionFace(string[] tokens)
+ {
+ if (tokens[0] == "}")
+ return false;
+
+ int nface = int.Parse(tokens[0]);
+ {
+ StringBuilder sb = new StringBuilder();
+ foreach (string i in tokens)
+ sb.Append(' ').Append(i);
+ string line = sb.ToString().Trim();
+ tokens = SplitString(line);
+ }
+ switch (nface)
+ {
+ case 3:
+ {
+ MqoFace f = new MqoFace();
+
+ for (int i = 1; i < tokens.Length; ++i)
+ {
+ string t = tokens[i];
+ string t2 = t.ToLower();
+
+ if (t2.StartsWith("v("))
+ {
+ string[] t3 = SplitParam(t);
+ f.a = ushort.Parse(t3[1]);
+ f.b = ushort.Parse(t3[2]);
+ f.c = ushort.Parse(t3[3]);
+ }
+ else
+ if (t2.StartsWith("m("))
+ {
+ string[] t3 = SplitParam(t);
+ f.mtl = ushort.Parse(t3[1]);
+ }
+ else
+ if (t2.StartsWith("uv("))
+ {
+ string[] t3 = SplitParam(t);
+ f.ta = Point2.Parse(t3, 1);
+ f.tb = Point2.Parse(t3, 3);
+ f.tc = Point2.Parse(t3, 5);
+ }
+ }
+ current.faces.Add(f);
+ }
+ break;
+ case 4:
+ {
+ MqoFace f = new MqoFace();
+ MqoFace f2 = new MqoFace();
+
+ for (int i = 1; i < tokens.Length; ++i)
+ {
+ string t = tokens[i];
+ string t2 = t.ToLower();
+
+ if (t2.StartsWith("v("))
+ {
+ string[] t3 = SplitParam(t);
+ f.a = ushort.Parse(t3[1]);
+ f.b = ushort.Parse(t3[2]);
+ f.c = ushort.Parse(t3[3]);
+ f2.a = f.a;
+ f2.b = f.c;
+ f2.c = ushort.Parse(t3[4]);
+ }
+ else
+ if (t2.StartsWith("m("))
+ {
+ string[] t3 = SplitParam(t);
+ f.mtl = ushort.Parse(t3[1]);
+ f2.mtl = f.mtl;
+ }
+ else
+ if (t2.StartsWith("uv("))
+ {
+ string[] t3 = SplitParam(t);
+ f.ta = Point2.Parse(t3, 1);
+ f.tb = Point2.Parse(t3, 3);
+ f.tc = Point2.Parse(t3, 5);
+ f2.ta = f.ta;
+ f2.tb = f.tc;
+ f2.tc = Point2.Parse(t3, 7);
+ }
+ }
+ current.faces.Add(f);
+ current.faces.Add(f2);
+ }
+ break;
+ }
+ return true;
+ }
+
+ //----- Root elements ----------------------------------------------
+ private void ParseMetasequoia(string[] tokens)
+ {
+ if (tokens[1].ToLower() != "document") Error(tokens);
+ }
+
+ private void ParseFormat(string[] tokens)
+ {
+ if (tokens[1].ToLower() != "text") Error(tokens);
+ if (tokens[2].ToLower() != "ver") Error(tokens);
+ if (tokens[3].ToLower() != "1.0") Error(tokens);
+ }
+
+ private void ParseScene(string[] tokens)
+ {
+ if (tokens[1].ToLower() != "{") Error(tokens);
+
+ DoRead(SectionScene);
+ }
+
+ private void ParseMaterial(string[] tokens)
+ {
+ if (tokens[2].ToLower() != "{") Error(tokens);
+
+ materials = new List<MqoMaterial>(int.Parse(tokens[1]));
+ DoRead(SectionMaterial);
+ }
+
+ private void ParseObject(string[] tokens)
+ {
+ if (tokens[2].ToLower() != "{") Error(tokens);
+
+ current = new MqoObject(tokens[1].Trim('"'));
+ objects.Add(current);
+ DoRead(SectionObject);
+ }
+
+ private void ParseVertex(string[] tokens)
+ {
+ if (tokens[2].ToLower() != "{") Error(tokens);
+
+ current.vertices = new List<Point3>(int.Parse(tokens[1]));
+ DoRead(SectionVertex);
+ }
+
+ private void ParseFace(string[] tokens)
+ {
+ if (tokens[2].ToLower() != "{") Error(tokens);
+
+ current.faces = new List<MqoFace>(int.Parse(tokens[1]));
+ DoRead(SectionFace);
+ }
+ }
+
+ public class MqoScene
+ {
+ public Point3 pos;
+ public Point3 lookat;
+ public float head;
+ public float pich;
+ public float ortho;
+ public float zoom2;
+ public Color3 amb;
+
+ public override string ToString()
+ {
+ return (new StringBuilder(256))
+ .Append(" pos: ").Append(pos)
+ .Append(" lookat: ").Append(lookat)
+ .Append(" head: ").Append(head)
+ .Append(" pich: ").Append(pich)
+ .Append(" ortho: ").Append(ortho)
+ .Append(" zoom2: ").Append(zoom2)
+ .Append(" amb: ").Append(amb)
+ .ToString();
+ }
+ }
+
+ public class MqoMaterial
+ {
+ public string name;
+ public int shader;
+ public Color3 col;
+ public float dif;
+ public float amb;
+ public float emi;
+ public float spc;
+ public float power;
+ public string tex;
+
+ public MqoMaterial() { }
+ public MqoMaterial(string n) { name = n; }
+
+ public override string ToString()
+ {
+ return (new StringBuilder(256))
+ .Append(" shader: ").Append(shader)
+ .Append(" col: ").Append(col)
+ .Append(" dif: ").Append(dif)
+ .Append(" amb: ").Append(amb)
+ .Append(" emi: ").Append(emi)
+ .Append(" spc: ").Append(spc)
+ .Append(" power: ").Append(power)
+ .Append(" tex: ").Append(tex)
+ .Append(" name: ").Append(name)
+ .ToString();
+ }
+ }
+
+ public class MqoObject
+ {
+ public string name;
+ public int visible;
+ public int locking;
+ public int shading;
+ public float facet;
+ public Color3 color;
+ public int color_type;
+ public List<Point3> vertices;
+ public List<MqoFace> faces;
+
+ public MqoObject() { }
+ public MqoObject(string n) { name = n; }
+
+ public override string ToString()
+ {
+ return (new StringBuilder(256))
+ .Append(" visible: ").Append(visible)
+ .Append(" locking: ").Append(locking)
+ .Append(" shading: ").Append(shading)
+ .Append(" facet: ").Append(facet)
+ .Append(" color: ").Append(color)
+ .Append(" color_type: ").Append(color_type)
+ .Append(" vertices: ").Append(vertices.Count)
+ .Append(" faces: ").Append(faces.Count)
+ .Append(" name: ").Append(name)
+ .ToString();
+ }
+ }
+
+ public class MqoFace
+ {
+ public ushort a, b, c, mtl;
+ public Point2 ta, tb, tc;
+
+ public MqoFace()
+ {
+ }
+
+ public MqoFace(ushort a, ushort b, ushort c, ushort mtl, Point2 ta, Point2 tb, Point2 tc)
+ {
+ this.a = a;
+ this.b = b;
+ this.c = c;
+ this.mtl = mtl;
+ this.ta = ta;
+ this.tb = tb;
+ this.tc = tc;
+ }
+
+ public override string ToString()
+ {
+ return (new StringBuilder(256))
+ .Append("v: ").Append(a).Append(" ").Append(b).Append(" ").Append(c)
+ .Append(" mtl: ").Append(mtl)
+ .Append(" uv: ").Append(ta).Append(" ").Append(tb).Append(" ").Append(tc)
+ .ToString();
+ }
+ }
+}
\ No newline at end of file
public class Pair<T, U>
{
- public T First;
- public U Second;
+ public T First;
+ public U Second;
public Pair()
{
public Pair(T first, U second)
{
- First = first;
- Second = second;
+ First = first;
+ Second = second;
}
}
public class MqoWriter : IDisposable
{
- public TextWriter tw;
- public string OutPath;
- public string OutFile;
- public MqoBoneMode BoneMode = MqoBoneMode.None;
+ public TextWriter tw;
+ public string OutPath;
+ public string OutFile;
+ public MqoBoneMode BoneMode = MqoBoneMode.None;
public MqoWriter(string file)
{
- FileStream fs = File.OpenWrite(file);
+ FileStream fs = File.OpenWrite(file);
fs.SetLength(0);
- tw = new StreamWriter(fs, Encoding.Default);
- OutFile = file;
- OutPath = Path.GetDirectoryName(file);
+ tw = new StreamWriter(fs, Encoding.Default);
+ OutFile = file;
+ OutPath = Path.GetDirectoryName(file);
}
void IDisposable.Dispose()
public void Close()
{
- if(tw != null)
+ if (tw != null)
tw.Close();
- tw = null;
+ tw = null;
}
string GetTextureFileName(TSOTex tex)
public void CreateTextureFile(TSOTex tex)
{
string file = GetTexturePath(tex);
- byte[] data= tex.data;
+ byte[] data = tex.data;
- using(FileStream fs= File.OpenWrite(file))
+ using (FileStream fs = File.OpenWrite(file))
{
- BinaryWriter bw = new BinaryWriter(fs);
+ BinaryWriter bw = new BinaryWriter(fs);
- switch(Path.GetExtension(file).ToUpper())
+ 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;
+ 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);
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);
+ 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)
+ foreach (TSOTex tex in file.textures)
CreateTextureFile(tex);
tw.WriteLine("Material {0} {{", file.materials.Length);
- foreach(TSOMaterial mat in file.materials)
+ foreach (TSOMaterial mat in file.materials)
{
- if(mat.ColorTex != null)
+ if (mat.ColorTex != null)
{
- TSOTex tex = file.texturemap[mat.ColorTex];
+ 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, GetTextureFileName(tex));
- } else
+ }
+ 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))",
tw.WriteLine("}");
- foreach(TSOMesh i in file.meshes)
+ foreach (TSOMesh i in file.meshes)
{
vh.Clear();
face.Clear();
uv.Clear();
mtl.Clear();
- foreach(TSOSubMesh j in i.sub)
+ foreach (TSOSubMesh j in i.sub_meshes)
{
- int cnt = 0;
- ushort a= 0, b= 0, c= 0;
- Vertex va= new Vertex(), vb= new Vertex(), vc= new Vertex();
+ 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)
+ 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));
+ 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 < 3) continue;
+ if (a == b || b == c || c == a) continue;
- if((cnt & 1) == 0)
+ 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);
+ 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
+ }
+ 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);
+ 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("\tvertex {0} {{", vh.Count);
- foreach(UVertex j in vh.verts)
+ 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 * 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]);
+ 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)
+ 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>();
+ 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);
+ }
- 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);
+ List<Point3> points = new List<Point3>();
+ List<int> bones = new List<int>();
- foreach(TSONode i in file.nodes)
- {
- if(i.children.Count == 0)
- continue;
+ 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);
- 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;
- }
+ foreach (TSONode i in file.nodes)
+ {
+ if (i.children.Count == 0)
+ continue;
- p.x /=i.children.Count;
- p.y /=i.children.Count;
- p.z /=i.children.Count;
+ Point3 q = new Point3(i.world.M41, i.world.M42, i.world.M43);
+ Point3 p = new Point3();
- bones.Add(points.Count); points.Add(q);
- bones.Add(points.Count); points.Add(p);
- }
+ foreach (TSONode j in i.children)
+ {
+ p.x += j.world.M41;
+ p.y += j.world.M42;
+ p.z += j.world.M43;
+ }
- tw.WriteLine("\tvertex {0} {{", points.Count);
+ p.x /= i.children.Count;
+ p.y /= i.children.Count;
+ p.z /= i.children.Count;
- foreach(Point3 j in points)
- WriteVertex(j.x, j.y, j.z);
+ bones.Add(points.Count); points.Add(q);
+ bones.Add(points.Count); points.Add(p);
+ }
- tw.WriteLine("\t}");
+ tw.WriteLine("\tvertex {0} {{", points.Count);
- //
- tw.WriteLine("\tface {0} {{", bones.Count / 2);
+ foreach (Point3 j in points)
+ WriteVertex(j.x, j.y, j.z);
- 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("\t}");
- tw.WriteLine("}");
- }
- break;
+ //
+ tw.WriteLine("\tface {0} {{", bones.Count / 2);
- case MqoBoneMode.Mikoto:
- {
- }
- break;
+ 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 Point3 Pos;
public Point3 Nrm;
public Point2 Tex;
- public int mtl;
-
+ public int mtl;
+
public UVertex()
{
}
Pos = pos;
Nrm = nrm;
Tex = tex;
- this.mtl= mtl;
+ this.mtl = mtl;
}
public int CompareTo(UVertex o)
return Pos.Equals(v.Pos) && Nrm.Equals(v.Nrm);
}
}
-}
+}
\ No newline at end of file
-using System;\r
-using System.Collections.Generic;\r
-using System.Text;\r
-using System.Runtime.InteropServices;\r
-\r
-namespace Tso2MqoGui\r
-{\r
- public enum PrimType\r
- {\r
- PT_LIST,\r
- PT_STRIP,\r
- PT_FAN\r
- }\r
-\r
- public unsafe struct PrimitiveGroup\r
- {\r
- public PrimType type;\r
- public uint numIndices;\r
- public ushort* indices;\r
- }\r
-\r
- public unsafe class NvTriStrip\r
- {\r
- public static ushort[] Optimize(ushort[] triangles)\r
- {\r
- fixed(ushort* p= &triangles[0])\r
- {\r
- SetStitchStrips(true);\r
-\r
- PrimitiveGroup* pg = null;\r
- ushort num = 0;\r
- bool rc = GenerateStrips(p, (uint)triangles.Length, &pg, &num, false);\r
-\r
- if(!rc) throw new Exception();\r
-\r
- try\r
- {\r
- if(num != 1) throw new Exception();\r
- if(pg[0].type != PrimType.PT_STRIP) throw new Exception();\r
-\r
- ushort[] nidx= new ushort[pg[0].numIndices];\r
-\r
- for(int i= 0; i < nidx.Length; ++i)\r
- nidx[i] = pg[0].indices[i];\r
-\r
- return nidx;\r
- } finally\r
- {\r
- DeletePrimitiveGroup(pg);\r
- }\r
- }\r
- }\r
-\r
- //[DllImport("NvTriStrip.dll")] public extern static int GetPicture(byte* file, int len, uint flag, out IntPtr pHBInfo, out IntPtr pHBm, void* lpPrgressCallback, uint lData); \r
- [DllImport("NvTriStrip.dll")] public extern static void EnableRestart(uint _restartVal);\r
- [DllImport("NvTriStrip.dll")] public extern static void DisableRestart();\r
- [DllImport("NvTriStrip.dll")] public extern static void SetListsOnly(bool _bListsOnly);\r
- [DllImport("NvTriStrip.dll")] public extern static void SetCacheSize(uint _cacheSize);\r
- [DllImport("NvTriStrip.dll")] public extern static void SetStitchStrips(bool _bStitchStrips);\r
- [DllImport("NvTriStrip.dll")] public extern static void SetMinStripSize(uint _minStripSize);\r
- //[DllImport("NvTriStrip.dll")] public extern static void Cleanup(NvStripInfoVec& tempStrips, NvFaceInfoVec& tempFaces);\r
- [DllImport("NvTriStrip.dll")] public extern static bool SameTriangle(ushort firstTri0, ushort firstTri1, ushort firstTri2, ushort secondTri0, ushort secondTri1, ushort secondTri2);\r
- //[DllImport("NvTriStrip.dll")] public extern static bool TestTriangle(ushort v0, ushort v1, ushort v2, const std::vector<NvFaceInfo>* in_bins, const int NUMBINS);\r
- [DllImport("NvTriStrip.dll")] public extern static void DeletePrimitiveGroup(PrimitiveGroup* primGroups);\r
- [DllImport("NvTriStrip.dll")] public extern static bool GenerateStrips(ushort* in_indices, uint in_numIndices, PrimitiveGroup** primGroups, ushort* numGroups, bool validateEnabled);\r
- [DllImport("NvTriStrip.dll")] public extern static void RemapIndices(PrimitiveGroup* in_primGroups, ushort numGroups, ushort numVerts, PrimitiveGroup** remappedGroups);\r
- }\r
-}\r
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Runtime.InteropServices;
+
+namespace Tso2MqoGui
+{
+ public enum PrimType
+ {
+ PT_LIST,
+ PT_STRIP,
+ PT_FAN
+ }
+
+ public unsafe struct PrimitiveGroup
+ {
+ public PrimType type;
+ public uint numIndices;
+ public ushort* indices;
+ }
+
+ public unsafe class NvTriStrip
+ {
+ public static ushort[] Optimize(ushort[] triangles)
+ {
+ fixed (ushort* p = &triangles[0])
+ {
+ SetStitchStrips(true);
+
+ PrimitiveGroup* pg = null;
+ ushort num = 0;
+ bool rc = GenerateStrips(p, (uint)triangles.Length, &pg, &num, false);
+
+ if (!rc) throw new Exception();
+
+ try
+ {
+ if (num != 1) throw new Exception();
+ if (pg[0].type != PrimType.PT_STRIP) throw new Exception();
+
+ ushort[] nidx = new ushort[pg[0].numIndices];
+
+ for (int i = 0; i < nidx.Length; ++i)
+ nidx[i] = pg[0].indices[i];
+
+ return nidx;
+ }
+ finally
+ {
+ DeletePrimitiveGroup(pg);
+ }
+ }
+ }
+
+ //[DllImport("NvTriStrip.dll")] public extern static int GetPicture(byte* file, int len, uint flag, out IntPtr pHBInfo, out IntPtr pHBm, void* lpPrgressCallback, uint lData);
+ [DllImport("NvTriStrip.dll")]
+ public extern static void EnableRestart(uint _restartVal);
+ [DllImport("NvTriStrip.dll")]
+ public extern static void DisableRestart();
+ [DllImport("NvTriStrip.dll")]
+ public extern static void SetListsOnly(bool _bListsOnly);
+ [DllImport("NvTriStrip.dll")]
+ public extern static void SetCacheSize(uint _cacheSize);
+ [DllImport("NvTriStrip.dll")]
+ public extern static void SetStitchStrips(bool _bStitchStrips);
+ [DllImport("NvTriStrip.dll")]
+ public extern static void SetMinStripSize(uint _minStripSize);
+ //[DllImport("NvTriStrip.dll")] public extern static void Cleanup(NvStripInfoVec& tempStrips, NvFaceInfoVec& tempFaces);
+ [DllImport("NvTriStrip.dll")]
+ public extern static bool SameTriangle(ushort firstTri0, ushort firstTri1, ushort firstTri2, ushort secondTri0, ushort secondTri1, ushort secondTri2);
+ //[DllImport("NvTriStrip.dll")] public extern static bool TestTriangle(ushort v0, ushort v1, ushort v2, const std::vector<NvFaceInfo>* in_bins, const int NUMBINS);
+ [DllImport("NvTriStrip.dll")]
+ public extern static void DeletePrimitiveGroup(PrimitiveGroup* primGroups);
+ [DllImport("NvTriStrip.dll")]
+ public extern static bool GenerateStrips(ushort* in_indices, uint in_numIndices, PrimitiveGroup** primGroups, ushort* numGroups, bool validateEnabled);
+ [DllImport("NvTriStrip.dll")]
+ public extern static void RemapIndices(PrimitiveGroup* in_primGroups, ushort numGroups, ushort numVerts, PrimitiveGroup** remappedGroups);
+ }
+}
\ No newline at end of file
-//#define SEARCH_DEBUG\r
-using System;\r
-using System.Collections.Generic;\r
-using System.Text;\r
-\r
-namespace Tso2MqoGui\r
-{\r
- public class Array3D<T>\r
- {\r
- public T[] data;\r
- public int xx, yy, zz;\r
-\r
- public Array3D(int x, int y, int z)\r
- {\r
- data = new T[x*y*z];\r
- xx = x;\r
- yy = y;\r
- zz = z;\r
- }\r
-\r
- public T Get(int x, int y, int z)\r
- {\r
- return data[x+y*xx+z*xx*yy];\r
- }\r
-\r
- public void Set(int x, int y, int z, T v)\r
- {\r
- data[x+y*xx+z*xx*yy] = v;\r
- }\r
- }\r
-\r
- public class PointCluster\r
- {\r
- public List<Point3> points;\r
- public int div;\r
- public float divu;\r
- public Array3D<List<int>> clusters;\r
- public Point3 min= new Point3(float.MaxValue, float.MaxValue, float.MaxValue);\r
- public Point3 max= new Point3(float.MinValue, float.MinValue, float.MinValue);\r
-\r
- public PointCluster(int n)\r
- {\r
- points = new List<Point3>(n);\r
- }\r
-\r
- public Point3 GetPoint(int i)\r
- {\r
- return points[i];\r
- }\r
-\r
- public void Add(Point3 p)\r
- {\r
- points.Add(p);\r
- if(p.x < min.x) min.x= p.x; else if(p.x > max.x) max.x= p.x;\r
- if(p.y < min.y) min.y= p.y; else if(p.y > max.y) max.y= p.y;\r
- if(p.z < min.z) min.z= p.z; else if(p.z > max.z) max.z= p.z;\r
- }\r
-\r
- public void Add(float x, float y, float z)\r
- {\r
- Add(new Point3(x, y, z));\r
- }\r
-\r
- public void Clustering()\r
- {\r
- float x = max.x - min.x;\r
- float y = max.y - min.y;\r
- float z = max.z - min.z;\r
- div = (int)Math.Ceiling((float)Math.Sqrt(Math.Sqrt(points.Count)));\r
-\r
- if(x >= y && x >= z) divu= x / div;\r
- else if(y >= x && y >= z) divu= y / div;\r
- else if(z >= x && z >= y) divu= z / div;\r
-\r
- clusters = new Array3D<List<int>>\r
- (Math.Max(1, (int)(x / divu)),\r
- Math.Max(1, (int)(y / divu)),\r
- Math.Max(1, (int)(z / divu)));\r
-\r
- for(int i= 0, n= points.Count; i < n; ++i)\r
- AddCluster(i, points[i].x, points[i].y, points[i].z);\r
- }\r
-\r
- public int Clump(int a, int min, int max)\r
- {\r
- return a < min ? min : a > max ? max : a;\r
- }\r
-\r
- public int IndexX(float x) { return Clump((int)((x-min.x) / divu), 0, clusters.xx-1); }\r
- public int IndexY(float y) { return Clump((int)((y-min.y) / divu), 0, clusters.yy-1); }\r
- public int IndexZ(float z) { return Clump((int)((z-min.z) / divu), 0, clusters.zz-1); }\r
-\r
- public void AddCluster(int i, float x, float y, float z)\r
- {\r
- int a = IndexX(x), b= IndexY(y), c= IndexZ(z);\r
- List<int> l;\r
- \r
- try\r
- {\r
- l = clusters.Get(a, b, c);\r
-\r
- if(l == null)\r
- clusters.Set(a, b, c, l= new List<int>());\r
-\r
- l.Add(i);\r
- } catch(Exception e)\r
- {\r
- System.Diagnostics.Debug.WriteLine(e);\r
- }\r
- }\r
-\r
- public int NearestIndex(float x, float y, float z)\r
- {\r
-#if SEARCH_DEBUG\r
- int dbgcount= 0; \r
-#endif\r
- int limit = 99;\r
- int near = -1;\r
- float distsq = float.MaxValue;\r
- int a = IndexX(x);\r
- int b = IndexY(y);\r
- int c = IndexZ(z);\r
-\r
- for(int i= 0; i <= limit; ++i)\r
- {\r
- for(int xx= a-i; xx <= a+i; ++xx)\r
- for(int yy= b-i; yy <= b+i; ++yy)\r
- for(int zz= c-i; zz <= c+i; ++zz)\r
- {\r
- if(xx < 0 || xx >= clusters.xx) continue;\r
- if(yy < 0 || yy >= clusters.yy) continue;\r
- if(zz < 0 || zz >= clusters.zz) continue;\r
-\r
- List<int> l = clusters.Get(xx, yy, zz);\r
-\r
- if(l == null)\r
- continue;\r
-\r
- foreach(int j in l)\r
- {\r
- Point3 p = points[j];\r
- p.x -=x;\r
- p.y -=y;\r
- p.z -=z;\r
- float d = p.x*p.x + p.y*p.y + p.z*p.z;\r
-#if SEARCH_DEBUG\r
- ++dbgcount;\r
-#endif\r
- if(d >= distsq)\r
- continue;\r
-\r
- if(limit == 99)\r
- limit = i + 1;\r
- distsq = d;\r
- near = j;\r
- }\r
- }\r
- }\r
-#if SEARCH_DEBUG\r
- System.Diagnostics.Debug.WriteLine(string.Format(\r
- "dbgcount:{0} index:{1} distance:{2}", dbgcount, near, distsq));\r
-#endif\r
- return near;\r
- }\r
- }\r
-}\r
+//#define SEARCH_DEBUG
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tso2MqoGui
+{
+ public class Array3D<T>
+ {
+ public T[] data;
+ public int xx, yy, zz;
+
+ public Array3D(int x, int y, int z)
+ {
+ data = new T[x * y * z];
+ xx = x;
+ yy = y;
+ zz = z;
+ }
+
+ public T Get(int x, int y, int z)
+ {
+ return data[x + y * xx + z * xx * yy];
+ }
+
+ public void Set(int x, int y, int z, T v)
+ {
+ data[x + y * xx + z * xx * yy] = v;
+ }
+ }
+
+ public class PointCluster
+ {
+ public List<Point3> points;
+ public int div;
+ public float divu;
+ public Array3D<List<int>> clusters;
+ public Point3 min = new Point3(float.MaxValue, float.MaxValue, float.MaxValue);
+ public Point3 max = new Point3(float.MinValue, float.MinValue, float.MinValue);
+
+ public PointCluster(int n)
+ {
+ points = new List<Point3>(n);
+ }
+
+ public Point3 GetPoint(int i)
+ {
+ return points[i];
+ }
+
+ public void Add(Point3 p)
+ {
+ points.Add(p);
+ if (p.x < min.x) min.x = p.x; else if (p.x > max.x) max.x = p.x;
+ if (p.y < min.y) min.y = p.y; else if (p.y > max.y) max.y = p.y;
+ if (p.z < min.z) min.z = p.z; else if (p.z > max.z) max.z = p.z;
+ }
+
+ public void Add(float x, float y, float z)
+ {
+ Add(new Point3(x, y, z));
+ }
+
+ public void Clustering()
+ {
+ float x = max.x - min.x;
+ float y = max.y - min.y;
+ float z = max.z - min.z;
+ div = (int)Math.Ceiling((float)Math.Sqrt(Math.Sqrt(points.Count)));
+
+ if (x >= y && x >= z) divu = x / div;
+ else if (y >= x && y >= z) divu = y / div;
+ else if (z >= x && z >= y) divu = z / div;
+
+ clusters = new Array3D<List<int>>
+ (Math.Max(1, (int)(x / divu)),
+ Math.Max(1, (int)(y / divu)),
+ Math.Max(1, (int)(z / divu)));
+
+ for (int i = 0, n = points.Count; i < n; ++i)
+ AddCluster(i, points[i].x, points[i].y, points[i].z);
+ }
+
+ public int Clump(int a, int min, int max)
+ {
+ return a < min ? min : a > max ? max : a;
+ }
+
+ public int IndexX(float x) { return Clump((int)((x - min.x) / divu), 0, clusters.xx - 1); }
+ public int IndexY(float y) { return Clump((int)((y - min.y) / divu), 0, clusters.yy - 1); }
+ public int IndexZ(float z) { return Clump((int)((z - min.z) / divu), 0, clusters.zz - 1); }
+
+ public void AddCluster(int i, float x, float y, float z)
+ {
+ int a = IndexX(x), b = IndexY(y), c = IndexZ(z);
+ List<int> l;
+
+ try
+ {
+ l = clusters.Get(a, b, c);
+
+ if (l == null)
+ clusters.Set(a, b, c, l = new List<int>());
+
+ l.Add(i);
+ }
+ catch (Exception exception)
+ {
+ System.Diagnostics.Debug.WriteLine(exception);
+ }
+ }
+
+ public int NearestIndex(float x, float y, float z)
+ {
+#if SEARCH_DEBUG
+ int dbgcount= 0;
+#endif
+ int limit = 99;
+ int near = -1;
+ float distsq = float.MaxValue;
+ int a = IndexX(x);
+ int b = IndexY(y);
+ int c = IndexZ(z);
+
+ for (int i = 0; i <= limit; ++i)
+ {
+ for (int xx = a - i; xx <= a + i; ++xx)
+ for (int yy = b - i; yy <= b + i; ++yy)
+ for (int zz = c - i; zz <= c + i; ++zz)
+ {
+ if (xx < 0 || xx >= clusters.xx) continue;
+ if (yy < 0 || yy >= clusters.yy) continue;
+ if (zz < 0 || zz >= clusters.zz) continue;
+
+ List<int> l = clusters.Get(xx, yy, zz);
+
+ if (l == null)
+ continue;
+
+ foreach (int j in l)
+ {
+ Point3 p = points[j];
+ p.x -= x;
+ p.y -= y;
+ p.z -= z;
+ float d = p.x * p.x + p.y * p.y + p.z * p.z;
+#if SEARCH_DEBUG
+ ++dbgcount;
+#endif
+ if (d >= distsq)
+ continue;
+
+ if (limit == 99)
+ limit = i + 1;
+ distsq = d;
+ near = j;
+ }
+ }
+ }
+#if SEARCH_DEBUG
+ System.Diagnostics.Debug.WriteLine(string.Format(
+ "dbgcount:{0} index:{1} distance:{2}", dbgcount, near, distsq));
+#endif
+ return near;
+ }
+ }
+}
\ No newline at end of file
static int Main(string[] args)\r
{\r
if (args.Length != 0)\r
- { // バッチで処理する\r
+ {\r
+ // バッチで処理する\r
try\r
{\r
string tso = null;\r
switch (o)\r
{\r
default:\r
- if (o.StartsWith("-tso:")) tso = o.Substring(5).Trim('\r', '\n');\r
- else if (o.StartsWith("-mqo:")) mqo = o.Substring(5).Trim('\r', '\n');\r
- else if (o.StartsWith("-ref:")) tsoref = o.Substring(5).Trim('\r', '\n');\r
- else throw new ArgumentException("Invalid option: " + i);\r
+ if (o.StartsWith("-tso:"))\r
+ tso = o.Substring(5).Trim('\r', '\n');\r
+ else if (o.StartsWith("-mqo:"))\r
+ mqo = o.Substring(5).Trim('\r', '\n');\r
+ else if (o.StartsWith("-ref:"))\r
+ tsoref = o.Substring(5).Trim('\r', '\n');\r
+ else\r
+ throw new ArgumentException("Invalid option: " + i);\r
break;\r
}\r
}\r
config.ShowMaterials = false;\r
TSOGeneratorRefBone gen = new TSOGeneratorRefBone(config);\r
\r
- if (mqo == null) throw new ArgumentException("「-mso:ファイル名」の形式で入力Mqoファイル名を指定してください");\r
- if (tso == null) throw new ArgumentException("「-tso:ファイル名」の形式で出力Tsoファイル名を指定してください");\r
- if (tsoref == null) throw new ArgumentException("「-ref:ファイル名」の形式で参照Tsoファイル名を指定してください");\r
+ if (mqo == null)\r
+ throw new ArgumentException("「-mso:ファイル名」の形式で入力Mqoファイル名を指定してください");\r
+ if (tso == null)\r
+ throw new ArgumentException("「-tso:ファイル名」の形式で出力Tsoファイル名を指定してください");\r
+ if (tsoref == null)\r
+ throw new ArgumentException("「-ref:ファイル名」の形式で参照Tsoファイル名を指定してください");\r
\r
gen.Generate(mqo, tsoref, tso);\r
}\r
System.Console.Out.Flush();\r
return 1;\r
}\r
- catch (Exception e)\r
+ catch (Exception exception)\r
{\r
- System.Diagnostics.Debug.WriteLine(e.Message);\r
- System.Console.Out.WriteLine(e.Message);\r
+ System.Diagnostics.Debug.WriteLine(exception.Message);\r
+ System.Console.Out.WriteLine(exception.Message);\r
System.Console.Out.Flush();\r
return 1;\r
}\r
return 0;\r
}\r
}\r
-}\r
+}
\ No newline at end of file
-using System;\r
-using System.Collections.Generic;\r
-using System.IO;\r
-using System.Text;\r
-\r
-namespace Tso2MqoGui\r
-{\r
- public class RDBJoint\r
- {\r
- public int No;\r
- public string Name;\r
-\r
- public RDBJoint(int no, string name)\r
- {\r
- No = no;\r
- Name= name;\r
- }\r
-\r
- public override string ToString()\r
- {\r
- return No.ToString().PadLeft(4, '0') + ":" + Name;\r
- }\r
- }\r
-\r
- public class RDBBone\r
- {\r
- public int Begin;\r
- public int End;\r
-\r
- public RDBBone(int begin, int end)\r
- {\r
- Begin = begin;\r
- End = end;\r
- }\r
-\r
- public override string ToString()\r
- {\r
- return "0003," + Begin.ToString().PadLeft(4, '0')\r
- + "," + End .ToString().PadLeft(4, '0');\r
- }\r
- }\r
-\r
- public class RDBBonFile\r
- {\r
- public int no = 0;\r
- public List<RDBJoint> joints = new List<RDBJoint>();\r
- public Dictionary<string, RDBJoint> jointmap= new Dictionary<string, RDBJoint>();\r
- public List<RDBBone> bones = new List<RDBBone>();\r
-\r
- public void AddJoint(string name)\r
- {\r
- RDBJoint j = new RDBJoint(no++, name);\r
- joints.Add(j);\r
- jointmap.Add(name, j);\r
- }\r
-\r
- public void AddBone(int begin, int end)\r
- {\r
- bones.Add(new RDBBone(begin, end));\r
- }\r
-\r
- public void Save(string file)\r
- {\r
- StringBuilder sb = new StringBuilder();\r
-\r
- sb.AppendLine("BoneFile : type separated : ver1001")\r
- .AppendLine("")\r
- .AppendLine("NAMEPART_START");\r
-\r
- foreach(RDBJoint i in joints)\r
- sb.AppendLine(i.ToString());\r
-\r
- sb.AppendLine("NAMEPART_END")\r
- .AppendLine("")\r
- .AppendLine("")\r
- .AppendLine("TREEPART_START")\r
- .AppendLine("");\r
-\r
- foreach(RDBBone i in bones)\r
- sb.AppendLine(i.ToString());\r
- \r
- sb.AppendLine("TREEPART_END");\r
-\r
- File.WriteAllText(file, sb.ToString(), Encoding.Default);\r
- }\r
- }\r
-}\r
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace Tso2MqoGui
+{
+ public class RDBJoint
+ {
+ public int No;
+ public string Name;
+
+ public RDBJoint(int no, string name)
+ {
+ No = no;
+ Name = name;
+ }
+
+ public override string ToString()
+ {
+ return No.ToString().PadLeft(4, '0') + ":" + Name;
+ }
+ }
+
+ public class RDBBone
+ {
+ public int Begin;
+ public int End;
+
+ public RDBBone(int begin, int end)
+ {
+ Begin = begin;
+ End = end;
+ }
+
+ public override string ToString()
+ {
+ return "0003," + Begin.ToString().PadLeft(4, '0')
+ + "," + End.ToString().PadLeft(4, '0');
+ }
+ }
+
+ public class RDBBonFile
+ {
+ public int no = 0;
+ public List<RDBJoint> joints = new List<RDBJoint>();
+ public Dictionary<string, RDBJoint> jointmap = new Dictionary<string, RDBJoint>();
+ public List<RDBBone> bones = new List<RDBBone>();
+
+ public void AddJoint(string name)
+ {
+ RDBJoint j = new RDBJoint(no++, name);
+ joints.Add(j);
+ jointmap.Add(name, j);
+ }
+
+ public void AddBone(int begin, int end)
+ {
+ bones.Add(new RDBBone(begin, end));
+ }
+
+ public void Save(string file)
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.AppendLine("BoneFile : type separated : ver1001")
+ .AppendLine("")
+ .AppendLine("NAMEPART_START");
+
+ foreach (RDBJoint i in joints)
+ sb.AppendLine(i.ToString());
+
+ sb.AppendLine("NAMEPART_END")
+ .AppendLine("")
+ .AppendLine("")
+ .AppendLine("TREEPART_START")
+ .AppendLine("");
+
+ foreach (RDBBone i in bones)
+ sb.AppendLine(i.ToString());
+
+ sb.AppendLine("TREEPART_END");
+
+ File.WriteAllText(file, sb.ToString(), Encoding.Default);
+ }
+ }
+}
\ No newline at end of file
-using System;\r
-using System.Collections.Generic;\r
-using System.IO;\r
-using System.Text;\r
-\r
-namespace Tso2MqoGui\r
-{\r
- public class TDCGFile\r
- {\r
- protected BinaryReader r;\r
-\r
- public TDCGFile(string file)\r
- : this(File.OpenRead(file))\r
- {\r
- }\r
-\r
- public TDCGFile(Stream s)\r
- : this(new BinaryReader(s))\r
- {\r
- }\r
-\r
- public TDCGFile(BinaryReader r)\r
- {\r
- this.r = r;\r
- }\r
-\r
- public void ReadVertex(ref Vertex v)\r
- {\r
- v.Pos.X = r.ReadSingle();\r
- v.Pos.Y = r.ReadSingle();\r
- v.Pos.Z = r.ReadSingle();\r
- v.Nrm.X = r.ReadSingle();\r
- v.Nrm.Y = r.ReadSingle();\r
- v.Nrm.Z = r.ReadSingle();\r
- v.Tex.X = r.ReadSingle();\r
- v.Tex.Y = r.ReadSingle();\r
-\r
- int cnt = r.ReadInt32();\r
- byte[] idx = new byte[4]{0, 0, 0, 0};\r
-\r
- if(cnt >= 1) { idx[3]= (byte)r.ReadInt32(); v.Wgt.W = r.ReadSingle(); }\r
- if(cnt >= 2) { idx[2]= (byte)r.ReadInt32(); v.Wgt.Z = r.ReadSingle(); }\r
- if(cnt >= 3) { idx[1]= (byte)r.ReadInt32(); v.Wgt.Y = r.ReadSingle(); }\r
- if(cnt >= 4) { idx[0]= (byte)r.ReadInt32(); v.Wgt.X = r.ReadSingle(); }\r
- if(cnt >= 5) { r.ReadInt32(); r.ReadSingle(); }\r
- if(cnt >= 6) { r.ReadInt32(); r.ReadSingle(); }\r
- if(cnt >= 7) { r.ReadInt32(); r.ReadSingle(); }\r
- if(cnt >= 8) { r.ReadInt32(); r.ReadSingle(); }\r
-\r
- v.Idx = BitConverter.ToUInt32(idx, 0);\r
- }\r
-\r
- Encoding enc = Encoding.GetEncoding("Shift_JIS");\r
- List<byte> buf = new List<byte>();\r
-\r
- public string ReadString()\r
- {\r
- buf.Clear();\r
-\r
- for(;;)\r
- {\r
- byte b = r.ReadByte();\r
-\r
- if(b == 0)\r
- break;\r
-\r
- buf.Add(b);\r
- }\r
-\r
- return enc.GetString(buf.ToArray());\r
- }\r
-\r
- public unsafe Matrix44 ReadMatrix()\r
- {\r
- Matrix44 m = new Matrix44();\r
- float* p = &m.m11;\r
-\r
- for(int i= 0; i < 16; ++i)\r
- *p++ = r.ReadSingle();\r
-\r
- return m;\r
- }\r
- }\r
-}\r
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace Tso2MqoGui
+{
+ public class TDCGFile
+ {
+ protected BinaryReader r;
+
+ public TDCGFile(string file)
+ : this(File.OpenRead(file))
+ {
+ }
+
+ public TDCGFile(Stream s)
+ : this(new BinaryReader(s))
+ {
+ }
+
+ public TDCGFile(BinaryReader r)
+ {
+ this.r = r;
+ }
+
+ public void ReadVertex(ref Vertex v)
+ {
+ v.Pos.X = r.ReadSingle();
+ v.Pos.Y = r.ReadSingle();
+ v.Pos.Z = r.ReadSingle();
+ v.Nrm.X = r.ReadSingle();
+ v.Nrm.Y = r.ReadSingle();
+ v.Nrm.Z = r.ReadSingle();
+ v.Tex.X = r.ReadSingle();
+ v.Tex.Y = r.ReadSingle();
+
+ int cnt = r.ReadInt32();
+ byte[] idx = new byte[4] { 0, 0, 0, 0 };
+
+ if (cnt >= 1) { idx[3] = (byte)r.ReadInt32(); v.Wgt.W = r.ReadSingle(); }
+ if (cnt >= 2) { idx[2] = (byte)r.ReadInt32(); v.Wgt.Z = r.ReadSingle(); }
+ if (cnt >= 3) { idx[1] = (byte)r.ReadInt32(); v.Wgt.Y = r.ReadSingle(); }
+ if (cnt >= 4) { idx[0] = (byte)r.ReadInt32(); v.Wgt.X = r.ReadSingle(); }
+ if (cnt >= 5) { r.ReadInt32(); r.ReadSingle(); }
+ if (cnt >= 6) { r.ReadInt32(); r.ReadSingle(); }
+ if (cnt >= 7) { r.ReadInt32(); r.ReadSingle(); }
+ if (cnt >= 8) { r.ReadInt32(); r.ReadSingle(); }
+
+ v.Idx = BitConverter.ToUInt32(idx, 0);
+ }
+
+ Encoding enc = Encoding.GetEncoding("Shift_JIS");
+ List<byte> buf = new List<byte>();
+
+ public string ReadString()
+ {
+ buf.Clear();
+
+ for (; ; )
+ {
+ byte b = r.ReadByte();
+
+ if (b == 0)
+ break;
+
+ buf.Add(b);
+ }
+
+ return enc.GetString(buf.ToArray());
+ }
+
+ public unsafe Matrix44 ReadMatrix()
+ {
+ Matrix44 m = new Matrix44();
+ float* p = &m.m11;
+
+ for (int i = 0; i < 16; ++i)
+ *p++ = r.ReadSingle();
+
+ return m;
+ }
+ }
+}
\ No newline at end of file
-using System;\r
-using System.Collections.Generic;\r
-using System.IO;\r
-using System.Text;\r
-using System.ComponentModel;\r
-\r
-namespace Tso2MqoGui\r
-{\r
- public class TSOFile : TDCGFile\r
- {\r
- internal Dictionary<string, TSONode> nodemap;\r
- internal Dictionary<string, TSOTex> texturemap;\r
- internal TSONode[] nodes;\r
- internal TSOTex[] textures;\r
- internal TSOEffect[] effects;\r
- internal TSOMaterial[] materials;\r
- internal TSOMesh[] meshes;\r
-\r
- public TSOFile(string file) : base(file) {}\r
- public TSOFile(Stream s) : base(s) {}\r
- public TSOFile(BinaryReader r) : base(r) {}\r
-\r
- public void SaveTo(string file)\r
- {\r
- }\r
-\r
- [System.Diagnostics.Conditional("DEBUG_DETAIL")]\r
- public static void WriteLine(string s)\r
- {\r
- System.Diagnostics.Debug.WriteLine(s);\r
- }\r
-\r
- public static void ExchangeChannel(byte[] data, int depth)\r
- {\r
- for(int j= 0; j < data.Length; j+=depth)\r
- {\r
- byte tmp = data[j+2];\r
- data[j+2] = data[j+0];\r
- data[j+0] = tmp;\r
- }\r
- }\r
-\r
- public void ReadAll()\r
- {\r
- byte[] magic = r.ReadBytes(4);\r
-\r
- if(magic[0] != (byte)'T'\r
- || magic[1] != (byte)'S'\r
- || magic[2] != (byte)'O'\r
- || magic[3] != (byte)'1')\r
- throw new Exception("File is not TSO");\r
-\r
- //----- ノード -------------------------------------------------\r
- nodemap = new Dictionary<string, TSONode>();\r
- int count = r.ReadInt32();\r
- nodes = new TSONode[count];\r
-\r
- for(int i= 0; i < count; ++i)\r
- {\r
- nodes[i] = new TSONode();\r
- nodes[i].id = i;\r
- nodes[i].name = ReadString();\r
- nodes[i].sname = nodes[i].name.Substring(nodes[i].name.LastIndexOf('|')+1);\r
- nodemap.Add(nodes[i].name, nodes[i]);\r
-\r
- WriteLine(i+ ": " + nodes[i].name);\r
- }\r
-\r
- for(int i= 0; i < count; ++i)\r
- {\r
- int index = nodes[i].name.LastIndexOf('|');\r
-\r
- if(index <= 0)\r
- continue;\r
-\r
- string pname = nodes[i].name.Substring(0, index);\r
- WriteLine(pname);\r
- nodes[i].parent = nodemap[pname];\r
- nodes[i].parent.children.Add(nodes[i]);\r
- }\r
-\r
- WriteLine(r.BaseStream.Position.ToString("X"));\r
-\r
- count = r.ReadInt32();\r
-\r
- // Node Matrix\r
- for(int i= 0; i < count; ++i)\r
- {\r
- nodes[i].matrix = ReadMatrix();\r
- }\r
-\r
- WriteLine(r.BaseStream.Position.ToString("X"));\r
-\r
- //----- テクスチャ ---------------------------------------------\r
- count = r.ReadInt32();\r
- textures = new TSOTex[count];\r
- texturemap = new Dictionary<string, TSOTex>();\r
-\r
- for(int i= 0; i < count; ++i)\r
- {\r
- textures[i] = new TSOTex();\r
- textures[i].id = i;\r
- textures[i].name = ReadString();\r
- textures[i].File = ReadString();\r
- textures[i].width = r.ReadInt32();\r
- textures[i].height = r.ReadInt32();\r
- textures[i].depth = r.ReadInt32();\r
- textures[i].data = r.ReadBytes(textures[i].width * textures[i].height * textures[i].depth);\r
- texturemap.Add(textures[i].name, textures[i]);\r
-\r
- ExchangeChannel(textures[i].data, textures[i].depth);\r
-\r
- WriteLine(r.BaseStream.Position.ToString("X"));\r
- }\r
-\r
- //----- エフェクト ---------------------------------------------\r
- count = r.ReadInt32();\r
- effects = new TSOEffect[count];\r
-\r
- for(int i= 0; i < count; ++i)\r
- {\r
- StringBuilder sb = new StringBuilder();\r
- effects[i] = new TSOEffect();\r
- effects[i].name = ReadString();\r
- effects[i].line = r.ReadInt32();\r
-\r
- for(int j= 0; j < effects[i].line; ++j)\r
- sb.Append(ReadString()).Append('\n');\r
-\r
- effects[i].code = sb.ToString();\r
-\r
- WriteLine(r.BaseStream.Position.ToString("X"));\r
- }\r
-\r
- //----- マテリアル ---------------------------------------------\r
- count = r.ReadInt32();\r
- materials = new TSOMaterial[count];\r
-\r
- for(int i= 0; i < count; ++i)\r
- {\r
- StringBuilder sb = new StringBuilder();\r
- materials[i] = new TSOMaterial();\r
- materials[i].id = i;\r
- materials[i].name = ReadString();\r
- materials[i].file = ReadString();\r
- materials[i].line = r.ReadInt32();\r
-\r
- for(int j= 0; j < materials[i].line; ++j)\r
- sb.Append(ReadString()).Append('\n');\r
-\r
- materials[i].code = sb.ToString();\r
- materials[i].ParseParameters();\r
-\r
- WriteLine(r.BaseStream.Position.ToString("X"));\r
- }\r
-\r
- //----- メッシュ -----------------------------------------------\r
- count = r.ReadInt32();\r
- meshes = new TSOMesh[count];\r
- int check = 0;\r
- for(int i= 0; i < count; ++i)\r
- {\r
- meshes[i] = new TSOMesh();\r
- meshes[i].file = this;\r
- meshes[i].name = ReadString();\r
- meshes[i].matrix = ReadMatrix();\r
- meshes[i].effect = r.ReadInt32();\r
- meshes[i].numsubs = r.ReadInt32();\r
- meshes[i].sub = new TSOSubMesh[meshes[i].numsubs];\r
-\r
- for(int j= 0; j < meshes[i].numsubs; ++j)\r
- {\r
- meshes[i].sub[j] = new TSOSubMesh();\r
- meshes[i].sub[j].owner = meshes[i];\r
- meshes[i].sub[j].spec = r.ReadInt32();\r
- meshes[i].sub[j].numbones = r.ReadInt32();\r
- meshes[i].sub[j].bones = new int[meshes[i].sub[j].numbones];\r
-\r
- meshes[i].sub[j].ink = materials[meshes[i].sub[j].spec].technique.ToUpper().IndexOf("INKOFF") < 0;\r
- //meshes[i].sub[j].shadow = specs[meshes[i].sub[j].spec].technique.ToUpper().IndexOf(Shadow\r
-\r
- for(int k= 0; k < meshes[i].sub[j].numbones; ++k)\r
- meshes[i].sub[j].bones[k] = r.ReadInt32();\r
-\r
- meshes[i].sub[j].numvertices= r.ReadInt32();\r
- Vertex[] v = new Vertex[meshes[i].sub[j].numvertices];\r
- meshes[i].sub[j].vertices= v;\r
-\r
- for(int k= 0; k < meshes[i].sub[j].numvertices; ++k)\r
- {\r
- ReadVertex(ref v[k]);\r
- }\r
-\r
- WriteLine(r.BaseStream.Position.ToString("X"));\r
- System.Diagnostics.Debug.WriteLine(r.BaseStream.Position.ToString("X"));\r
- }\r
- }\r
-\r
- WriteLine(r.BaseStream.Position.ToString("X"));\r
- WriteLine(check.ToString("X"));\r
-\r
- r.BaseStream.Dispose();\r
- }\r
- }\r
-\r
- public class TSONode\r
- {\r
- internal int id;\r
- internal string name;\r
- internal string sname;\r
- internal Matrix44 matrix;\r
- internal Matrix44 world;\r
- internal List<TSONode> children = new List<TSONode>();\r
- internal TSONode parent;\r
-\r
- [Category("General")] public int ID { get { return id; } }\r
- [Category("General")] public string Name { get { return name; } }\r
- [Category("General")] public string ShortName { get { return sname; } }\r
- [Category("Detail")] public Matrix44 Matrix { get { return matrix; } set { matrix= value; } }\r
- [Category("Detail")] public Matrix44 World { get { return world; } set { world = value; } }\r
-\r
- public override string ToString()\r
- {\r
- StringBuilder sb = new StringBuilder();\r
- sb.Append("Name: ").AppendLine(name);\r
- sb.Append("Matrix: ").AppendLine(matrix.ToString());\r
- sb.Append("Children.Count: ").AppendLine(children.Count.ToString());\r
- return sb.ToString();\r
- }\r
- }\r
-\r
- public class TSOTex\r
- {\r
- internal int id;\r
- internal string name;\r
- string file;\r
- internal int width;\r
- internal int height;\r
- internal int depth;\r
- internal byte[] data;\r
-\r
- [Category("General")] public int ID { get { return id; } }\r
- [Category("General")] public string Name { get { return name; } }\r
- [Category("Detail")] public string File { get { return file; } set { file= value; } }\r
- [Category("Detail")] public int Width { get { return width; } }\r
- [Category("Detail")] public int Height { get { return height; } }\r
- [Category("Detail")] public int Depth { get { return depth; } }\r
-\r
- public override string ToString()\r
- {\r
- StringBuilder sb = new StringBuilder();\r
- sb.Append("Name: ").AppendLine(name);\r
- sb.Append("File: ").AppendLine(file);\r
- sb.Append("Width: ").AppendLine(width.ToString());\r
- sb.Append("Height: ").AppendLine(height.ToString());\r
- sb.Append("Depth: ").AppendLine(depth.ToString());\r
- sb.Append("Data.Length: ").AppendLine(data.Length.ToString());\r
- return sb.ToString();\r
- }\r
- }\r
-\r
- public class TSOEffect\r
- {\r
- internal string name;\r
- internal int line;\r
- internal string code;\r
-\r
- [Category("General")] public string Name { get { return name; } }\r
- [Category("Detail")] public string Code { get { return code; } set { code= value; } }\r
-\r
- public override string ToString()\r
- {\r
- StringBuilder sb = new StringBuilder();\r
- sb.Append("Name: ").AppendLine(name);\r
- sb.Append("Line: ").AppendLine(line.ToString());\r
- sb.AppendLine("Code:").AppendLine(code);\r
- return sb.ToString();\r
- }\r
- }\r
-\r
- public class TSOParameter\r
- {\r
- public string Name;\r
- public string Type;\r
- public string Value;\r
-\r
- public TSOParameter(string type, string name, string value)\r
- {\r
- Name = name;\r
- Type = type;\r
- Value = value;\r
- }\r
-\r
- public override string ToString()\r
- {\r
-#if true\r
- return Type + " " + Name + " = " + Value;\r
-#else\r
- switch(Type)\r
- {\r
- case "string": return Type + " " + Name + " = \"" + Value + "\"";\r
- case "float": return Type + " " + Name + " = [" + Value + "]";\r
- case "float4": return Type + " " + Name + " = [" + Value + "]";\r
- default: return Type + " " + Name + " = " + Value;\r
- }\r
-#endif\r
- }\r
- }\r
-\r
- public class TSOMaterialCode : Dictionary<string, TSOParameter>\r
- {\r
- public TSOMaterialCode(string code)\r
- : this(code.Split('\r', '\n'))\r
- {\r
- }\r
-\r
- public string GetValue(string index)\r
- {\r
- return this[index].Value;\r
- }\r
-\r
- public void SetValue(string index, string value)\r
- {\r
- TSOParameter p = this[index];\r
- p.Value = value;\r
- }\r
-\r
- public TSOMaterialCode(string[] code)\r
- {\r
- foreach(string i in code)\r
- {\r
- try\r
- {\r
- int n1, n2;\r
-\r
- if((n1= i.IndexOf(' ')) < 0) continue;\r
- if((n2= i.IndexOf('=', n1+1)) < 0) continue;\r
-\r
- TSOParameter p = new TSOParameter(\r
- i.Substring(0, n1) .Trim(),\r
- i.Substring(n1, n2-n1).Trim(),\r
- i.Substring(n2+1) .Trim());\r
- TSOFile.WriteLine(p.ToString());\r
- Add(p.Name, p);\r
- } catch(Exception e)\r
- {\r
- System.Diagnostics.Debug.WriteLine(e);\r
- }\r
- }\r
- }\r
-\r
- public static TSOMaterialCode GenerateFromFile(string filename)\r
- {\r
- return new TSOMaterialCode(File.ReadAllLines(filename));\r
- }\r
- }\r
-\r
- public class TSOMaterial\r
- {\r
- internal int id;\r
- internal string name;\r
- internal string file;\r
- internal int line;\r
- internal string code;\r
- internal TSOMaterialCode codedata;\r
-\r
- internal string description; // = "TA ToonShader v0.50"\r
- internal string shader; // = "TAToonshade_050.cgfx"\r
- internal string technique; // = "ShadowOn"\r
- internal float lightDirX; // = [-0.00155681]\r
- internal float lightDirY; // = [-0.0582338]\r
- internal float lightDirZ; // = [-0.998302]\r
- internal float lightDirW; // = [0]\r
- internal Point4 shadowColor; // = [0, 0, 0, 1]\r
- internal string shadeTex; // = Ninjya_Ribbon_Toon_Tex\r
- internal float highLight; // = [0]\r
- internal float colorBlend; // = [10]\r
- internal float highLightBlend; // = [10]\r
- internal Point4 penColor; // = [0.166, 0.166, 0.166, 1]\r
- internal float ambient; // = [38]\r
- internal string colorTex; // = file24\r
- internal float thickness; // = [0.018]\r
- internal float shadeBlend; // = [10]\r
- internal float highLightPower; // = [100]\r
-\r
- [Category("General")] public int ID { get { return id; } }\r
- [Category("General")] public string Name { get { return name; } }\r
- [Category("Detail")] public string File { get { return file; } }\r
- [Category("Detail")] public string Code { get { return code; } set { code= value; } }\r
-\r
- [Category("Parameters")] public string Description { get { return description; } set { description = value; } }\r
- [Category("Parameters")] public string Shader { get { return shader; } set { shader = value; } }\r
- [Category("Parameters")] public string Technique { get { return technique; } set { technique = value; } }\r
- [Category("Parameters")] public float LightDirX { get { return lightDirX; } set { lightDirX = value; } }\r
- [Category("Parameters")] public float LightDirY { get { return lightDirY; } set { lightDirY = value; } }\r
- [Category("Parameters")] public float LightDirZ { get { return lightDirZ; } set { lightDirZ = value; } }\r
- [Category("Parameters")] public float LightDirW { get { return lightDirW; } set { lightDirW = value; } }\r
- [Category("Parameters")] public Point4 ShadowColor { get { return shadowColor; } set { shadowColor = value; } }\r
- [Category("Parameters")] public string ShadeTex { get { return shadeTex; } set { shadeTex = value; } }\r
- [Category("Parameters")] public float HighLight { get { return highLight; } set { highLight = value; } }\r
- [Category("Parameters")] public float ColorBlend { get { return colorBlend; } set { colorBlend = value; } }\r
- [Category("Parameters")] public float HighLightBlend { get { return highLightBlend; } set { highLightBlend= value; } }\r
- [Category("Parameters")] public Point4 PenColor { get { return penColor; } set { penColor = value; } }\r
- [Category("Parameters")] public float Ambient { get { return ambient; } set { ambient = value; } }\r
- [Category("Parameters")] public string ColorTex { get { return colorTex; } set { colorTex = value; } }\r
- [Category("Parameters")] public float Thickness { get { return thickness; } set { thickness = value; } }\r
- [Category("Parameters")] public float ShadeBlend { get { return shadeBlend; } set { shadeBlend = value; } }\r
- [Category("Parameters")] public float HighLightPower { get { return highLightPower; } set { highLightPower= value; } }\r
-\r
- public override string ToString()\r
- {\r
- StringBuilder sb = new StringBuilder();\r
- sb.Append("Name: ").AppendLine(name);\r
- sb.Append("File: ").AppendLine(file);\r
- sb.Append("Line: ").AppendLine(line.ToString());\r
- sb.AppendLine("Code:").AppendLine(code);\r
-\r
- return sb.ToString();\r
- }\r
-\r
- public void ParseParameters()\r
- {\r
- codedata = new TSOMaterialCode(code);\r
-\r
- foreach(TSOParameter i in codedata.Values)\r
- SetValue(i.Type, i.Name, i.Value);\r
- }\r
-\r
- public void SetValue(string type, string name, string value)\r
- {\r
- switch(name)\r
- {\r
- case "description": description = GetString (value); break; // = "TA ToonShader v0.50"\r
- case "shader": shader = GetString (value); break; // = "TAToonshade_050.cgfx"\r
- case "technique": technique = GetString (value); break; // = "ShadowOn"\r
- case "LightDirX": lightDirX = GetFloat (value); break; // = [-0.00155681]\r
- case "LightDirY": lightDirY = GetFloat (value); break; // = [-0.0582338]\r
- case "LightDirZ": lightDirZ = GetFloat (value); break; // = [-0.998302]\r
- case "LightDirW": lightDirW = GetFloat (value); break; // = [0]\r
- case "ShadowColor": shadowColor = GetPoint4 (value); break; // = [0, 0, 0, 1]\r
- case "ShadeTex": shadeTex = GetTexture(value); break; // = Ninjya_Ribbon_Toon_Tex\r
- case "HighLight": highLight = GetFloat (value); break; // = [0]\r
- case "ColorBlend": colorBlend = GetFloat (value); break; // = [10]\r
- case "HighLightBlend": highLightBlend = GetFloat (value); break; // = [10]\r
- case "PenColor": penColor = GetPoint4 (value); break; // = [0.166, 0.166, 0.166, 1]\r
- case "Ambient": ambient = GetFloat (value); break; // = [38]\r
- case "ColorTex": colorTex = GetTexture(value); break; // = file24\r
- case "Thickness": thickness = GetFloat (value); break; // = [0.018]\r
- case "ShadeBlend": shadeBlend = GetFloat (value); break; // = [10]\r
- case "HighLightPower": highLightPower = GetFloat (value); break; // = [100]\r
- default:\r
- TSOFile.WriteLine("Unknown parameter. type=" + type + ", name=" + name + ", value=" + value);\r
- break;\r
- }\r
- }\r
-\r
- public string GetTexture(string value)\r
- {\r
- return value;\r
- }\r
-\r
- public string GetString(string value)\r
- {\r
- return value.Trim('"');\r
- }\r
-\r
- public float GetFloat(string value)\r
- {\r
- return float.Parse(value.Trim('[', ']', ' '));\r
- }\r
-\r
- public Point4 GetPoint4(string value)\r
- {\r
- string[] token = value.Trim('[', ']', ' ').Split(',');\r
- Point4 p = new Point4();\r
- p.X = float.Parse(token[0].Trim());\r
- p.Y = float.Parse(token[1].Trim());\r
- p.Z = float.Parse(token[2].Trim());\r
- p.W = float.Parse(token[3].Trim());\r
- return p;\r
- }\r
- }\r
-\r
- public class TSOMesh\r
- {\r
- internal TSOFile file;\r
- internal string name;\r
- internal Matrix44 matrix;\r
- internal int effect;\r
- internal int numsubs;\r
- internal TSOSubMesh[] sub;\r
-\r
- [Category("General")] public string Name { get { return name; } set { name= value; } }\r
- //[Category("Detail")] public int Effect { get { return name; } set { name= value; } }\r
- [Category("Detail")] public Matrix44 Matrix { get { return matrix; } set { matrix= value; } }\r
-\r
- public override string ToString()\r
- {\r
- StringBuilder sb = new StringBuilder();\r
- sb.Append("Name: ").AppendLine(name);\r
- sb.Append("Matrix: ").AppendLine(matrix.ToString());\r
- sb.Append("Effect?: ").AppendLine(effect.ToString());\r
- sb.Append("NumSubs: ").AppendLine(numsubs.ToString());\r
- sb.Append("SubMesh.Count: ").AppendLine(sub.Length.ToString());\r
- return sb.ToString();\r
- }\r
- }\r
-\r
- public class TSOSubMesh\r
- {\r
- internal int spec;\r
- internal int numbones;\r
- internal int[] bones;\r
- internal int numvertices;\r
- internal Vertex[] vertices;\r
- internal TSOMesh owner;\r
- //internal bool shadow;\r
- internal bool ink;\r
-\r
- [Category("Detail")] public int Spec { get { return spec; } set { spec= value; } }\r
- //[Category("Detail")] public int Effect { get { return name; } set { name= value; } }\r
-\r
- public override string ToString()\r
- {\r
- StringBuilder sb = new StringBuilder();\r
- sb.Append("Spec: ").AppendLine(spec.ToString());\r
- sb.Append("NumBones: ").AppendLine(numbones.ToString());\r
- sb.Append("NumVertices: ").AppendLine(numvertices.ToString());\r
- return sb.ToString();\r
- }\r
- }\r
-\r
- public struct Matrix44\r
- {\r
- public static readonly Matrix44 Identity = new Matrix44(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1);\r
-\r
- public float m11, m12, m13, m14;\r
- public float m21, m22, m23, m24;\r
- public float m31, m32, m33, m34;\r
- public float m41, m42, m43, m44;\r
-\r
- public float M11 { get { return m11; } set { m11= value; } }\r
- public float M12 { get { return m12; } set { m12= value; } }\r
- public float M13 { get { return m13; } set { m13= value; } }\r
- public float M14 { get { return m14; } set { m14= value; } }\r
- public float M21 { get { return m21; } set { m21= value; } }\r
- public float M22 { get { return m22; } set { m22= value; } }\r
- public float M23 { get { return m23; } set { m23= value; } }\r
- public float M24 { get { return m24; } set { m24= value; } }\r
- public float M31 { get { return m31; } set { m31= value; } }\r
- public float M32 { get { return m32; } set { m32= value; } }\r
- public float M33 { get { return m33; } set { m33= value; } }\r
- public float M34 { get { return m34; } set { m34= value; } }\r
- public float M41 { get { return m41; } set { m41= value; } }\r
- public float M42 { get { return m42; } set { m42= value; } }\r
- public float M43 { get { return m43; } set { m43= value; } }\r
- public float M44 { get { return m44; } set { m44= value; } }\r
-\r
- public Matrix44(\r
- float a11, float a12, float a13, float a14,\r
- float a21, float a22, float a23, float a24,\r
- float a31, float a32, float a33, float a34,\r
- float a41, float a42, float a43, float a44)\r
- {\r
- m11=a11; m12=a12; m13=a13; m14=a14;\r
- m21=a21; m22=a22; m23=a23; m24=a24;\r
- m31=a31; m32=a32; m33=a33; m34=a34;\r
- m41=a41; m42=a42; m43=a43; m44=a44;\r
- }\r
-\r
- public Point3 Translation { get { return new Point3(M41, M42, M43); } } \r
-\r
- public override string ToString()\r
- {\r
- StringBuilder sb = new StringBuilder();\r
- sb.AppendFormat("[{0:F4}, {1:F4}, {2:F4}, {3:F4}], ", M11, M12, M13, M14)\r
- .AppendFormat("[{0:F4}, {1:F4}, {2:F4}, {3:F4}], ", M21, M22, M23, M24)\r
- .AppendFormat("[{0:F4}, {1:F4}, {2:F4}, {3:F4}], ", M31, M32, M33, M34)\r
- .AppendFormat("[{0:F4}, {1:F4}, {2:F4}, {3:F4}]", M41, M42, M43, M44);\r
- return sb.ToString();\r
- }\r
-\r
- public static Matrix44 Mul(Matrix44 a, Matrix44 b)\r
- {\r
- Matrix44 m = new Matrix44();\r
-\r
- m.M11 = a.M11*b.M11 + a.M12*b.M21 + a.M13*b.M31 + a.M14*b.M41;\r
- m.M12 = a.M11*b.M12 + a.M12*b.M22 + a.M13*b.M32 + a.M14*b.M42;\r
- m.M13 = a.M11*b.M13 + a.M12*b.M23 + a.M13*b.M33 + a.M14*b.M43;\r
- m.M14 = a.M11*b.M14 + a.M12*b.M24 + a.M13*b.M34 + a.M14*b.M44;\r
-\r
- m.M21 = a.M21*b.M11 + a.M22*b.M21 + a.M23*b.M31 + a.M24*b.M41;\r
- m.M22 = a.M21*b.M12 + a.M22*b.M22 + a.M23*b.M32 + a.M24*b.M42;\r
- m.M23 = a.M21*b.M13 + a.M22*b.M23 + a.M23*b.M33 + a.M24*b.M43;\r
- m.M24 = a.M21*b.M14 + a.M22*b.M24 + a.M23*b.M34 + a.M24*b.M44;\r
-\r
- m.M31 = a.M31*b.M11 + a.M32*b.M21 + a.M33*b.M31 + a.M34*b.M41;\r
- m.M32 = a.M31*b.M12 + a.M32*b.M22 + a.M33*b.M32 + a.M34*b.M42;\r
- m.M33 = a.M31*b.M13 + a.M32*b.M23 + a.M33*b.M33 + a.M34*b.M43;\r
- m.M34 = a.M31*b.M14 + a.M32*b.M24 + a.M33*b.M34 + a.M34*b.M44;\r
-\r
- m.M41 = a.M41*b.M11 + a.M42*b.M21 + a.M43*b.M31 + a.M44*b.M41;\r
- m.M42 = a.M41*b.M12 + a.M42*b.M22 + a.M43*b.M32 + a.M44*b.M42;\r
- m.M43 = a.M41*b.M13 + a.M42*b.M23 + a.M43*b.M33 + a.M44*b.M43;\r
- m.M44 = a.M41*b.M14 + a.M42*b.M24 + a.M43*b.M34 + a.M44*b.M44;\r
-\r
- return m;\r
- }\r
- }\r
-\r
- public partial struct Vertex : IComparable<Vertex>\r
- {\r
- public Point3 Pos;\r
- public Point4 Wgt;\r
- public UInt32 Idx;\r
- public Point3 Nrm;\r
- public Point2 Tex;\r
- //public int Count;\r
- //public Weights[] Weights;\r
-\r
- public Vertex(Point3 pos, Point4 wgt, UInt32 idx, Point3 nrm, Point2 tex)\r
- {\r
- Pos = pos;\r
- Wgt = wgt;\r
- Idx = idx;\r
- Nrm = nrm;\r
- Tex = tex;\r
- }\r
-\r
- public int CompareTo(Vertex o)\r
- {\r
- int cmp = 0;\r
- cmp = Pos.CompareTo(o.Pos); if (cmp != 0) return cmp;\r
- cmp = Nrm.CompareTo(o.Nrm); if (cmp != 0) return cmp;\r
- cmp = Tex.CompareTo(o.Tex);\r
- return cmp;\r
- }\r
-\r
- public override int GetHashCode()\r
- {\r
- return Pos.GetHashCode() ^ Nrm.GetHashCode() ^ Tex.GetHashCode();\r
- }\r
-\r
- public override bool Equals(object obj)\r
- {\r
- if (obj is Vertex)\r
- {\r
- Vertex v = (Vertex)obj;\r
- return Pos.Equals(v.Pos) && Nrm.Equals(v.Nrm) && Tex.Equals(v.Tex);\r
- }\r
- return false;\r
- }\r
-\r
- public bool Equals(Vertex v)\r
- {\r
- return Pos.Equals(v.Pos) && Nrm.Equals(v.Nrm) && Tex.Equals(v.Tex);\r
- }\r
- }\r
-\r
- /*\r
- public struct Weights\r
- {\r
- public int Index;\r
- public float Weight;\r
- }\r
- */\r
-}\r
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.ComponentModel;
+
+namespace Tso2MqoGui
+{
+ public class TSOFile : TDCGFile
+ {
+ internal Dictionary<string, TSONode> nodemap;
+ internal Dictionary<string, TSOTex> texturemap;
+ internal TSONode[] nodes;
+ internal TSOTex[] textures;
+ internal TSOEffect[] effects;
+ internal TSOMaterial[] materials;
+ internal TSOMesh[] meshes;
+
+ public TSOFile(string file) : base(file) { }
+ public TSOFile(Stream s) : base(s) { }
+ public TSOFile(BinaryReader r) : base(r) { }
+
+ public void SaveTo(string file)
+ {
+ }
+
+ [System.Diagnostics.Conditional("DEBUG_DETAIL")]
+ public static void WriteLine(string s)
+ {
+ System.Diagnostics.Debug.WriteLine(s);
+ }
+
+ public static void ExchangeChannel(byte[] data, int depth)
+ {
+ for (int j = 0; j < data.Length; j += depth)
+ {
+ byte tmp = data[j + 2];
+ data[j + 2] = data[j + 0];
+ data[j + 0] = tmp;
+ }
+ }
+
+ 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_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];
+
+ meshes[i].sub_meshes[j].ink = materials[meshes[i].sub_meshes[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_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]);
+ }
+
+ 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 class TSONode
+ {
+ internal int id;
+ internal string name;
+ internal string sname;
+ internal Matrix44 matrix;
+ internal Matrix44 world;
+ internal List<TSONode> children = new List<TSONode>();
+ internal TSONode parent;
+
+ [Category("General")]
+ public int ID { get { return id; } }
+ [Category("General")]
+ public string Name { get { return name; } }
+ [Category("General")]
+ public string ShortName { get { return sname; } }
+ [Category("Detail")]
+ public Matrix44 Matrix { get { return matrix; } set { matrix = value; } }
+ [Category("Detail")]
+ public Matrix44 World { get { return world; } set { world = value; } }
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.Append("Name: ").AppendLine(name);
+ sb.Append("Matrix: ").AppendLine(matrix.ToString());
+ sb.Append("Children.Count: ").AppendLine(children.Count.ToString());
+ return sb.ToString();
+ }
+ }
+
+ public class TSOTex
+ {
+ internal int id;
+ internal string name;
+ string file;
+ internal int width;
+ internal int height;
+ internal int depth;
+ internal byte[] data;
+
+ [Category("General")]
+ public int ID { get { return id; } }
+ [Category("General")]
+ public string Name { get { return name; } }
+ [Category("Detail")]
+ public string File { get { return file; } set { file = value; } }
+ [Category("Detail")]
+ public int Width { get { return width; } }
+ [Category("Detail")]
+ public int Height { get { return height; } }
+ [Category("Detail")]
+ public int Depth { get { return depth; } }
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.Append("Name: ").AppendLine(name);
+ sb.Append("File: ").AppendLine(file);
+ sb.Append("Width: ").AppendLine(width.ToString());
+ sb.Append("Height: ").AppendLine(height.ToString());
+ sb.Append("Depth: ").AppendLine(depth.ToString());
+ sb.Append("Data.Length: ").AppendLine(data.Length.ToString());
+ return sb.ToString();
+ }
+ }
+
+ public class TSOEffect
+ {
+ internal string name;
+ internal int line;
+ internal string code;
+
+ [Category("General")]
+ public string Name { get { return name; } }
+ [Category("Detail")]
+ public string Code { get { return code; } set { code = value; } }
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.Append("Name: ").AppendLine(name);
+ sb.Append("Line: ").AppendLine(line.ToString());
+ sb.AppendLine("Code:").AppendLine(code);
+ return sb.ToString();
+ }
+ }
+
+ public class TSOParameter
+ {
+ public string Name;
+ public string Type;
+ public string Value;
+
+ public TSOParameter(string type, string name, string value)
+ {
+ Name = name;
+ Type = type;
+ Value = value;
+ }
+
+ public override string ToString()
+ {
+#if true
+ return Type + " " + Name + " = " + Value;
+#else
+ switch(Type)
+ {
+ case "string": return Type + " " + Name + " = \"" + Value + "\"";
+ case "float": return Type + " " + Name + " = [" + Value + "]";
+ case "float4": return Type + " " + Name + " = [" + Value + "]";
+ default: return Type + " " + Name + " = " + Value;
+ }
+#endif
+ }
+ }
+
+ public class TSOMaterialCode : Dictionary<string, TSOParameter>
+ {
+ public TSOMaterialCode(string code)
+ : this(code.Split('\r', '\n'))
+ {
+ }
+
+ public string GetValue(string index)
+ {
+ return this[index].Value;
+ }
+
+ public void SetValue(string index, string value)
+ {
+ TSOParameter p = this[index];
+ p.Value = value;
+ }
+
+ public TSOMaterialCode(string[] code)
+ {
+ foreach (string i in code)
+ {
+ try
+ {
+ int n1, n2;
+
+ if ((n1 = i.IndexOf(' ')) < 0) continue;
+ if ((n2 = i.IndexOf('=', n1 + 1)) < 0) continue;
+
+ TSOParameter p = new TSOParameter(
+ i.Substring(0, n1).Trim(),
+ i.Substring(n1, n2 - n1).Trim(),
+ i.Substring(n2 + 1).Trim());
+ TSOFile.WriteLine(p.ToString());
+ Add(p.Name, p);
+ }
+ catch (Exception e)
+ {
+ System.Diagnostics.Debug.WriteLine(e);
+ }
+ }
+ }
+
+ public static TSOMaterialCode GenerateFromFile(string filename)
+ {
+ return new TSOMaterialCode(File.ReadAllLines(filename));
+ }
+ }
+
+ public class TSOMaterial
+ {
+ internal int id;
+ internal string name;
+ internal string file;
+ internal int line;
+ internal string code;
+ internal TSOMaterialCode codedata;
+
+ internal string description; // = "TA ToonShader v0.50"
+ internal string shader; // = "TAToonshade_050.cgfx"
+ internal string technique; // = "ShadowOn"
+ internal float lightDirX; // = [-0.00155681]
+ internal float lightDirY; // = [-0.0582338]
+ internal float lightDirZ; // = [-0.998302]
+ internal float lightDirW; // = [0]
+ internal Point4 shadowColor; // = [0, 0, 0, 1]
+ internal string shadeTex; // = Ninjya_Ribbon_Toon_Tex
+ internal float highLight; // = [0]
+ internal float colorBlend; // = [10]
+ internal float highLightBlend; // = [10]
+ internal Point4 penColor; // = [0.166, 0.166, 0.166, 1]
+ internal float ambient; // = [38]
+ internal string colorTex; // = file24
+ internal float thickness; // = [0.018]
+ internal float shadeBlend; // = [10]
+ internal float highLightPower; // = [100]
+
+ [Category("General")]
+ public int ID { get { return id; } }
+ [Category("General")]
+ public string Name { get { return name; } }
+ [Category("Detail")]
+ public string File { get { return file; } }
+ [Category("Detail")]
+ public string Code { get { return code; } set { code = value; } }
+
+ [Category("Parameters")]
+ public string Description { get { return description; } set { description = value; } }
+ [Category("Parameters")]
+ public string Shader { get { return shader; } set { shader = value; } }
+ [Category("Parameters")]
+ public string Technique { get { return technique; } set { technique = value; } }
+ [Category("Parameters")]
+ public float LightDirX { get { return lightDirX; } set { lightDirX = value; } }
+ [Category("Parameters")]
+ public float LightDirY { get { return lightDirY; } set { lightDirY = value; } }
+ [Category("Parameters")]
+ public float LightDirZ { get { return lightDirZ; } set { lightDirZ = value; } }
+ [Category("Parameters")]
+ public float LightDirW { get { return lightDirW; } set { lightDirW = value; } }
+ [Category("Parameters")]
+ public Point4 ShadowColor { get { return shadowColor; } set { shadowColor = value; } }
+ [Category("Parameters")]
+ public string ShadeTex { get { return shadeTex; } set { shadeTex = value; } }
+ [Category("Parameters")]
+ public float HighLight { get { return highLight; } set { highLight = value; } }
+ [Category("Parameters")]
+ public float ColorBlend { get { return colorBlend; } set { colorBlend = value; } }
+ [Category("Parameters")]
+ public float HighLightBlend { get { return highLightBlend; } set { highLightBlend = value; } }
+ [Category("Parameters")]
+ public Point4 PenColor { get { return penColor; } set { penColor = value; } }
+ [Category("Parameters")]
+ public float Ambient { get { return ambient; } set { ambient = value; } }
+ [Category("Parameters")]
+ public string ColorTex { get { return colorTex; } set { colorTex = value; } }
+ [Category("Parameters")]
+ public float Thickness { get { return thickness; } set { thickness = value; } }
+ [Category("Parameters")]
+ public float ShadeBlend { get { return shadeBlend; } set { shadeBlend = value; } }
+ [Category("Parameters")]
+ public float HighLightPower { get { return highLightPower; } set { highLightPower = value; } }
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.Append("Name: ").AppendLine(name);
+ sb.Append("File: ").AppendLine(file);
+ sb.Append("Line: ").AppendLine(line.ToString());
+ sb.AppendLine("Code:").AppendLine(code);
+
+ return sb.ToString();
+ }
+
+ public void ParseParameters()
+ {
+ codedata = new TSOMaterialCode(code);
+
+ foreach (TSOParameter i in codedata.Values)
+ SetValue(i.Type, i.Name, i.Value);
+ }
+
+ public void SetValue(string type, string name, string value)
+ {
+ switch (name)
+ {
+ case "description": description = GetString(value); break; // = "TA ToonShader v0.50"
+ case "shader": shader = GetString(value); break; // = "TAToonshade_050.cgfx"
+ case "technique": technique = GetString(value); break; // = "ShadowOn"
+ case "LightDirX": lightDirX = GetFloat(value); break; // = [-0.00155681]
+ case "LightDirY": lightDirY = GetFloat(value); break; // = [-0.0582338]
+ case "LightDirZ": lightDirZ = GetFloat(value); break; // = [-0.998302]
+ case "LightDirW": lightDirW = GetFloat(value); break; // = [0]
+ case "ShadowColor": shadowColor = GetPoint4(value); break; // = [0, 0, 0, 1]
+ case "ShadeTex": shadeTex = GetTexture(value); break; // = Ninjya_Ribbon_Toon_Tex
+ case "HighLight": highLight = GetFloat(value); break; // = [0]
+ case "ColorBlend": colorBlend = GetFloat(value); break; // = [10]
+ case "HighLightBlend": highLightBlend = GetFloat(value); break; // = [10]
+ case "PenColor": penColor = GetPoint4(value); break; // = [0.166, 0.166, 0.166, 1]
+ case "Ambient": ambient = GetFloat(value); break; // = [38]
+ case "ColorTex": colorTex = GetTexture(value); break; // = file24
+ case "Thickness": thickness = GetFloat(value); break; // = [0.018]
+ case "ShadeBlend": shadeBlend = GetFloat(value); break; // = [10]
+ case "HighLightPower": highLightPower = GetFloat(value); break; // = [100]
+ default:
+ TSOFile.WriteLine("Unknown parameter. type=" + type + ", name=" + name + ", value=" + value);
+ break;
+ }
+ }
+
+ public string GetTexture(string value)
+ {
+ return value;
+ }
+
+ public string GetString(string value)
+ {
+ return value.Trim('"');
+ }
+
+ public float GetFloat(string value)
+ {
+ return float.Parse(value.Trim('[', ']', ' '));
+ }
+
+ public Point4 GetPoint4(string value)
+ {
+ string[] token = value.Trim('[', ']', ' ').Split(',');
+ Point4 p = new Point4();
+ p.X = float.Parse(token[0].Trim());
+ p.Y = float.Parse(token[1].Trim());
+ p.Z = float.Parse(token[2].Trim());
+ p.W = float.Parse(token[3].Trim());
+ return p;
+ }
+ }
+
+ public class TSOMesh
+ {
+ internal TSOFile file;
+ internal string name;
+ internal Matrix44 matrix;
+ internal int effect;
+ internal int numsubs;
+ internal TSOSubMesh[] sub_meshes;
+
+ [Category("General")]
+ public string Name { get { return name; } set { name = value; } }
+ //[Category("Detail")] public int Effect { get { return name; } set { name= value; } }
+ [Category("Detail")]
+ public Matrix44 Matrix { get { return matrix; } set { matrix = value; } }
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.Append("Name: ").AppendLine(name);
+ sb.Append("Matrix: ").AppendLine(matrix.ToString());
+ sb.Append("Effect?: ").AppendLine(effect.ToString());
+ sb.Append("NumSubs: ").AppendLine(numsubs.ToString());
+ sb.Append("SubMesh.Count: ").AppendLine(sub_meshes.Length.ToString());
+ return sb.ToString();
+ }
+ }
+
+ public class TSOSubMesh
+ {
+ internal int spec;
+ internal int numbones;
+ internal int[] bones;
+ internal int numvertices;
+ internal Vertex[] vertices;
+ internal TSOMesh owner;
+ //internal bool shadow;
+ internal bool ink;
+
+ [Category("Detail")]
+ public int Spec { get { return spec; } set { spec = value; } }
+ //[Category("Detail")] public int Effect { get { return name; } set { name= value; } }
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.Append("Spec: ").AppendLine(spec.ToString());
+ sb.Append("NumBones: ").AppendLine(numbones.ToString());
+ sb.Append("NumVertices: ").AppendLine(numvertices.ToString());
+ return sb.ToString();
+ }
+ }
+
+ public struct Matrix44
+ {
+ public static readonly Matrix44 Identity = new Matrix44(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+
+ public float m11, m12, m13, m14;
+ public float m21, m22, m23, m24;
+ public float m31, m32, m33, m34;
+ public float m41, m42, m43, m44;
+
+ public float M11 { get { return m11; } set { m11 = value; } }
+ public float M12 { get { return m12; } set { m12 = value; } }
+ public float M13 { get { return m13; } set { m13 = value; } }
+ public float M14 { get { return m14; } set { m14 = value; } }
+ public float M21 { get { return m21; } set { m21 = value; } }
+ public float M22 { get { return m22; } set { m22 = value; } }
+ public float M23 { get { return m23; } set { m23 = value; } }
+ public float M24 { get { return m24; } set { m24 = value; } }
+ public float M31 { get { return m31; } set { m31 = value; } }
+ public float M32 { get { return m32; } set { m32 = value; } }
+ public float M33 { get { return m33; } set { m33 = value; } }
+ public float M34 { get { return m34; } set { m34 = value; } }
+ public float M41 { get { return m41; } set { m41 = value; } }
+ public float M42 { get { return m42; } set { m42 = value; } }
+ public float M43 { get { return m43; } set { m43 = value; } }
+ public float M44 { get { return m44; } set { m44 = value; } }
+
+ public Matrix44(
+ float a11, float a12, float a13, float a14,
+ float a21, float a22, float a23, float a24,
+ float a31, float a32, float a33, float a34,
+ float a41, float a42, float a43, float a44)
+ {
+ m11 = a11; m12 = a12; m13 = a13; m14 = a14;
+ m21 = a21; m22 = a22; m23 = a23; m24 = a24;
+ m31 = a31; m32 = a32; m33 = a33; m34 = a34;
+ m41 = a41; m42 = a42; m43 = a43; m44 = a44;
+ }
+
+ public Point3 Translation { get { return new Point3(M41, M42, M43); } }
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.AppendFormat("[{0:F4}, {1:F4}, {2:F4}, {3:F4}], ", M11, M12, M13, M14)
+ .AppendFormat("[{0:F4}, {1:F4}, {2:F4}, {3:F4}], ", M21, M22, M23, M24)
+ .AppendFormat("[{0:F4}, {1:F4}, {2:F4}, {3:F4}], ", M31, M32, M33, M34)
+ .AppendFormat("[{0:F4}, {1:F4}, {2:F4}, {3:F4}]", M41, M42, M43, M44);
+ return sb.ToString();
+ }
+
+ public static Matrix44 Mul(Matrix44 a, Matrix44 b)
+ {
+ Matrix44 m = new Matrix44();
+
+ m.M11 = a.M11 * b.M11 + a.M12 * b.M21 + a.M13 * b.M31 + a.M14 * b.M41;
+ m.M12 = a.M11 * b.M12 + a.M12 * b.M22 + a.M13 * b.M32 + a.M14 * b.M42;
+ m.M13 = a.M11 * b.M13 + a.M12 * b.M23 + a.M13 * b.M33 + a.M14 * b.M43;
+ m.M14 = a.M11 * b.M14 + a.M12 * b.M24 + a.M13 * b.M34 + a.M14 * b.M44;
+
+ m.M21 = a.M21 * b.M11 + a.M22 * b.M21 + a.M23 * b.M31 + a.M24 * b.M41;
+ m.M22 = a.M21 * b.M12 + a.M22 * b.M22 + a.M23 * b.M32 + a.M24 * b.M42;
+ m.M23 = a.M21 * b.M13 + a.M22 * b.M23 + a.M23 * b.M33 + a.M24 * b.M43;
+ m.M24 = a.M21 * b.M14 + a.M22 * b.M24 + a.M23 * b.M34 + a.M24 * b.M44;
+
+ m.M31 = a.M31 * b.M11 + a.M32 * b.M21 + a.M33 * b.M31 + a.M34 * b.M41;
+ m.M32 = a.M31 * b.M12 + a.M32 * b.M22 + a.M33 * b.M32 + a.M34 * b.M42;
+ m.M33 = a.M31 * b.M13 + a.M32 * b.M23 + a.M33 * b.M33 + a.M34 * b.M43;
+ m.M34 = a.M31 * b.M14 + a.M32 * b.M24 + a.M33 * b.M34 + a.M34 * b.M44;
+
+ m.M41 = a.M41 * b.M11 + a.M42 * b.M21 + a.M43 * b.M31 + a.M44 * b.M41;
+ m.M42 = a.M41 * b.M12 + a.M42 * b.M22 + a.M43 * b.M32 + a.M44 * b.M42;
+ m.M43 = a.M41 * b.M13 + a.M42 * b.M23 + a.M43 * b.M33 + a.M44 * b.M43;
+ m.M44 = a.M41 * b.M14 + a.M42 * b.M24 + a.M43 * b.M34 + a.M44 * b.M44;
+
+ return m;
+ }
+ }
+
+ public partial struct Vertex : IComparable<Vertex>
+ {
+ public Point3 Pos;
+ public Point4 Wgt;
+ public UInt32 Idx;
+ public Point3 Nrm;
+ public Point2 Tex;
+ //public int Count;
+ //public Weights[] Weights;
+
+ public Vertex(Point3 pos, Point4 wgt, UInt32 idx, Point3 nrm, Point2 tex)
+ {
+ Pos = pos;
+ Wgt = wgt;
+ Idx = idx;
+ Nrm = nrm;
+ Tex = tex;
+ }
+
+ public int CompareTo(Vertex o)
+ {
+ int cmp = 0;
+ cmp = Pos.CompareTo(o.Pos); if (cmp != 0) return cmp;
+ cmp = Nrm.CompareTo(o.Nrm); if (cmp != 0) return cmp;
+ cmp = Tex.CompareTo(o.Tex);
+ return cmp;
+ }
+
+ public override int GetHashCode()
+ {
+ return Pos.GetHashCode() ^ Nrm.GetHashCode() ^ Tex.GetHashCode();
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj is Vertex)
+ {
+ Vertex v = (Vertex)obj;
+ return Pos.Equals(v.Pos) && Nrm.Equals(v.Nrm) && Tex.Equals(v.Tex);
+ }
+ return false;
+ }
+
+ public bool Equals(Vertex v)
+ {
+ return Pos.Equals(v.Pos) && Nrm.Equals(v.Nrm) && Tex.Equals(v.Tex);
+ }
+ }
+
+ /*
+ public struct Weights
+ {
+ public int Index;
+ public float Weight;
+ }
+ */
+}
\ No newline at end of file
{\r
bw.Write(tsoref.nodes.Length);\r
\r
- nodes = new Dictionary<string,TSONode>();\r
+ nodes = new Dictionary<string, TSONode>();\r
\r
- foreach(TSONode i in tsoref.nodes)\r
+ foreach (TSONode i in tsoref.nodes)\r
{\r
WriteString(bw, i.Name);\r
nodes.Add(i.ShortName, i);\r
{\r
bw.Write(tsoref.nodes.Length);\r
\r
- foreach(TSONode i in tsoref.nodes)\r
+ foreach (TSONode i in tsoref.nodes)\r
WriteMatrix(bw, i.Matrix);\r
\r
return true;\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
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 (file_directory_name != "" && file_directory_name.ToUpper() != dir.ToUpper())\r
{\r
- iti.File = Path.Combine(dir, file_name);\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
{\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
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
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
DoCleanup();\r
}\r
}\r
- \r
+\r
protected abstract bool DoLoadRefTSO(string tsoref);\r
\r
-#region ユーティリティ\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
+ 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
+ #endregion\r
}\r
\r
public class TSOGeneratorOneBone : TSOGenerator\r
\r
protected override bool DoGenerateMeshes()\r
{\r
- meshes = new List<TSOMesh>();\r
+ meshes = new List<TSOMesh>();\r
\r
- foreach(MqoObject i in mqo.Objects)\r
+ foreach (MqoObject obj in mqo.Objects)\r
{\r
- if(i.name.ToLower() == "bone")\r
+ if (obj.name.ToLower() == "bone")\r
continue;\r
\r
- Console.WriteLine("object:" + i.name);\r
+ Console.WriteLine("object:" + obj.name);\r
\r
// 法線生成\r
- Point3[] nrm = new Point3[i.vertices.Count];\r
- \r
- foreach(MqoFace j in i.faces)\r
+ Point3[] nrm = new Point3[obj.vertices.Count];\r
+\r
+ foreach (MqoFace face in obj.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
+ Point3 v1 = Point3.Normalize(obj.vertices[face.b] - obj.vertices[face.a]);\r
+ Point3 v2 = Point3.Normalize(obj.vertices[face.c] - obj.vertices[face.b]);\r
+ Point3 n = Point3.Normalize(Point3.Cross(v1, v2));\r
+ nrm[face.a] -= n;\r
+ nrm[face.b] -= n;\r
+ nrm[face.c] -= n;\r
}\r
\r
- for(int j= 0; j < nrm.Length; ++j)\r
- nrm[j] = Point3.Normalize(nrm[j]);\r
+ for (int i = 0; i < nrm.Length; ++i)\r
+ nrm[i] = Point3.Normalize(nrm[i]);\r
\r
// ボーン情報作成\r
- uint idx = 0x00000000;\r
- Point4 wgt = new Point4(1, 0, 0, 0);\r
- int[] bones = new int[1];\r
- string bone;\r
+ uint idx = 0x00000000;\r
+ Point4 wgt = new Point4(1, 0, 0, 0);\r
+ int[] bones = new int[1];\r
+ string bone;\r
try\r
{\r
- bone = ObjectBoneNames[i.name];\r
+ bone = ObjectBoneNames[obj.name];\r
}\r
catch (KeyNotFoundException)\r
{\r
- throw new KeyNotFoundException(string.Format("ボーン指定に誤りがあります。オブジェクト {0} にボーンを割り当てる必要があります。", i.name));\r
+ throw new KeyNotFoundException(string.Format("ボーン指定に誤りがあります。オブジェクト {0} にボーンを割り当てる必要があります。", obj.name));\r
}\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
+ 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
+ for (int mtl = 0; mtl < materials.Count; ++mtl)\r
{\r
- int mtl = j;\r
indices.Clear();\r
\r
- foreach(MqoFace f in i.faces)\r
+ foreach (MqoFace face in obj.faces)\r
{\r
- if(f.mtl != mtl)\r
+ if (face.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
+ Vertex va = new Vertex(obj.vertices[face.a], wgt, idx, nrm[face.a], new Point2(face.ta.x, 1 - face.ta.y));\r
+ Vertex vb = new Vertex(obj.vertices[face.b], wgt, idx, nrm[face.b], new Point2(face.tb.x, 1 - face.tb.y));\r
+ Vertex vc = new Vertex(obj.vertices[face.c], wgt, idx, nrm[face.c], new Point2(face.tc.x, 1 - face.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
+ if (indices.Count == 0)\r
continue;\r
\r
// フェイス最適化\r
- ushort[] nidx = NvTriStrip.Optimize(indices.ToArray());\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
+ 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
+ sub.vertices = new Vertex[nidx.Length];\r
+\r
+ for (int i = 0; i < nidx.Length; ++i)\r
+ sub.vertices[i] = verts[nidx[i]];\r
\r
Console.WriteLine(" {0,8} {1,12}", sub.vertices.Length, sub.bones.Length);\r
\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
+ TSOMesh mesh = new TSOMesh();\r
+ mesh.name = obj.name;\r
+ mesh.numsubs = subs.Count;\r
+ mesh.sub_meshes = subs.ToArray();\r
+ mesh.matrix = Matrix44.Identity;\r
+ mesh.effect = 0;\r
meshes.Add(mesh);\r
}\r
\r
}\r
\r
}\r
- \r
+\r
public unsafe class TSOGeneratorRefBone : TSOGenerator\r
{\r
private List<Vertex> vlst;\r
vlst = new List<Vertex>();\r
\r
foreach (TSOMesh i in tso.meshes)\r
- foreach (TSOSubMesh j in i.sub)\r
+ foreach (TSOSubMesh j in i.sub_meshes)\r
vlst.AddRange(j.vertices);\r
\r
pc = new PointCluster(vlst.Count);\r
// 参照TSOロード\r
tsoref = LoadTSO(tsoref_file);\r
\r
- foreach (TSOMesh i in tsoref.meshes)\r
- foreach (TSOSubMesh j in i.sub)\r
+ foreach (TSOMesh mesh in tsoref.meshes)\r
+ foreach (TSOSubMesh sub in mesh.sub_meshes)\r
{\r
- int[] bones = j.bones;\r
+ int[] bones = sub.bones;\r
\r
- for (int k = 0, n = j.numvertices; k < n; ++k)\r
+ for (int k = 0, n = sub.numvertices; k < n; ++k)\r
{\r
// ボーンをグローバルな番号に変換\r
- uint idx0 = j.vertices[k].Idx;\r
+ uint idx0 = sub.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
+ sub.vertices[k].Idx = idx0;\r
}\r
}\r
\r
\r
protected override bool DoGenerateMeshes()\r
{\r
- meshes = new List<TSOMesh>();\r
+ meshes = new List<TSOMesh>();\r
\r
- foreach(MqoObject i in mqo.Objects)\r
+ foreach (MqoObject obj in mqo.Objects)\r
{\r
- if(i.name.ToLower() == "bone")\r
+ if (obj.name.ToLower() == "bone")\r
continue;\r
\r
- Console.WriteLine("object:" + i.name);\r
+ Console.WriteLine("object:" + obj.name);\r
\r
// 一番近い頂点への参照\r
- List<int> vref= new List<int>(i.vertices.Count);\r
+ List<int> vref = new List<int>(obj.vertices.Count);\r
\r
- foreach(Point3 j in i.vertices)\r
+ foreach (Point3 j in obj.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
+ Point3[] nrm = new Point3[obj.vertices.Count];\r
+\r
+ foreach (MqoFace j in obj.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
+ Point3 v1 = Point3.Normalize(obj.vertices[j.b] - obj.vertices[j.a]);\r
+ Point3 v2 = Point3.Normalize(obj.vertices[j.c] - obj.vertices[j.b]);\r
+ Point3 n = Point3.Normalize(Point3.Cross(v1, v2));\r
\r
- nrm[j.a] -=n;\r
- nrm[j.b] -=n;\r
- nrm[j.c] -=n;\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
+ 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
+ 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 = obj.faces.Count; j < n; ++j)\r
faces1.Add(j);\r
\r
-#region ボーンパーティション\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
+ int mtl = obj.faces[faces1[0]].mtl;\r
selected.Clear();\r
- indices .Clear();\r
- vh .Clear();\r
- bones .Clear();\r
+ indices.Clear();\r
+ vh.Clear();\r
+ bones.Clear();\r
\r
- foreach(int j in faces1)\r
+ foreach (int j in faces1)\r
{\r
- MqoFace f = i.faces[j];\r
+ MqoFace f = obj.faces[j];\r
\r
- if(f.mtl != mtl)\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
+ 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
+ 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
+ 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
+ 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
+ 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
\r
// ボーンリストに足してvalid\r
- foreach(KeyValuePair<int, int> l in work)\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
+ Vertex va = new Vertex(obj.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(obj.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(obj.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
}\r
\r
// フェイス最適化\r
- ushort[] nidx = NvTriStrip.Optimize(indices.ToArray());\r
+ ushort[] nidx = NvTriStrip.Optimize(indices.ToArray());\r
\r
// 頂点のボーン参照ローカルに変換\r
- Vertex[] verts = vh.verts.ToArray();\r
+ Vertex[] verts = vh.verts.ToArray();\r
\r
- for(int j= 0; j < verts.Length; ++j)\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
+ 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
+ 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
+ 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
+ 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 = 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
subs.Add(sub);\r
\r
// 次の周回\r
- List<int> t = faces1;\r
- faces1 = faces2;\r
- faces2 = t;\r
+ List<int> t = faces1;\r
+ faces1 = faces2;\r
+ faces2 = t;\r
t.Clear();\r
}\r
-#endregion\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
+ TSOMesh mesh = new TSOMesh();\r
+ mesh.name = obj.name;\r
+ mesh.numsubs = subs.Count;\r
+ mesh.sub_meshes = subs.ToArray();\r
+ mesh.matrix = Matrix44.Identity;\r
+ mesh.effect = 0;\r
meshes.Add(mesh);\r
}\r
\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
+ public string name;\r
+ public string shader;\r
+ public string diffuse;\r
+ public string shadow;\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
+ diffuse = 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 = file;\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
+ shadow = file;\r
}\r
}\r
}\r
\r
- public bool Valid\r
+ public bool Valid\r
{\r
get\r
{\r
\r
public string[] GetCode()\r
{\r
- TSOMaterialCode code= TSOMaterialCode.GenerateFromFile(shader);\r
- List<string> line= new List<string>();\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
+ 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
\r
[Editor(typeof(FileNameEditor), typeof(UITypeEditor))]\r
[DisplayNameAttribute("テクスチャ:シェーティング")]\r
- public string ShadowTexture { get { return shadow; } set { shadow = value; } }\r
+ public string ShadowTexture { get { return shadow; } set { shadow = value; } }\r
}\r
-}\r
+}
\ No newline at end of file
-using System;\r
-using System.Collections.Generic;\r
-using System.Text;\r
-\r
-namespace Tso2MqoGui\r
-{\r
- public class TSOGeneratorConfig\r
- {\r
- public bool ShowMaterials = false;\r
- public bool cui = false;\r
- }\r
-}\r
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tso2MqoGui
+{
+ public class TSOGeneratorConfig
+ {
+ public bool ShowMaterials = false;
+ public bool cui = false;
+ }
+}
\ No newline at end of file
-using System;\r
-using System.Collections.Generic;\r
-using System.IO;\r
-using System.Text;\r
-\r
-namespace Tso2MqoGui\r
-{\r
- public class TSOWriter\r
- {\r
- public static void WriteHeader(BinaryWriter bw)\r
- {\r
- bw.Write(0x314F5354);\r
- }\r
-\r
- public static void Write(BinaryWriter bw, string s)\r
- {\r
- foreach(byte i in Encoding.Default.GetBytes(s))\r
- bw.Write(i);\r
-\r
- bw.Write((byte)0);\r
- }\r
-\r
- public static void Write(BinaryWriter bw, string[] s)\r
- {\r
- int n = s[s.Length-1] == "" ? s.Length-1 : s.Length;\r
-\r
- bw.Write(n);\r
-\r
- for(int i= 0; i < n; ++i)\r
- Write(bw, s[i]);\r
- }\r
-\r
- public static void Write(BinaryWriter bw, TSONode[] items)\r
- {\r
- bw.Write(items.Length);\r
-\r
- foreach(var i in items)\r
- Write(bw, i);\r
-\r
- bw.Write(items.Length);\r
-\r
- foreach(var i in items)\r
- Write(bw, i.Matrix);\r
- }\r
-\r
- public static void Write(BinaryWriter bw, TSONode item)\r
- {\r
- Write(bw, item.Name);\r
- }\r
-\r
- public static void Write(BinaryWriter bw, Matrix44 item)\r
- {\r
- bw.Write(item.M11); bw.Write(item.M12); bw.Write(item.M13); bw.Write(item.M14);\r
- bw.Write(item.M21); bw.Write(item.M22); bw.Write(item.M23); bw.Write(item.M24);\r
- bw.Write(item.M31); bw.Write(item.M32); bw.Write(item.M33); bw.Write(item.M34);\r
- bw.Write(item.M41); bw.Write(item.M42); bw.Write(item.M43); bw.Write(item.M44);\r
- }\r
-\r
- public static void Write(BinaryWriter bw, TSOTex[] items)\r
- {\r
- bw.Write(items.Length);\r
-\r
- foreach(var i in items)\r
- Write(bw, i);\r
- }\r
-\r
- public static void Write(BinaryWriter bw, TSOTex item)\r
- {\r
- Write(bw, item.name);\r
- Write(bw, item.File);\r
- bw.Write(item.Width);\r
- bw.Write(item.Height);\r
- bw.Write(item.Depth);\r
- bw.Write(item.data, 0, item.data.Length);\r
- }\r
-\r
- public static void Write(BinaryWriter bw, TSOEffect[] items)\r
- {\r
- bw.Write(items.Length);\r
-\r
- foreach(var i in items)\r
- Write(bw, i);\r
- }\r
-\r
- public static void Write(BinaryWriter bw, TSOEffect item)\r
- {\r
- Write(bw, item.Name);\r
- Write(bw, item.Code.Split('\n'));\r
- }\r
-\r
- public static void Write(BinaryWriter bw, TSOMaterial[] items)\r
- {\r
- bw.Write(items.Length);\r
-\r
- foreach(var i in items)\r
- Write(bw, i);\r
- }\r
-\r
- public static void Write(BinaryWriter bw, TSOMaterial item)\r
- {\r
- Write(bw, item.Name);\r
- Write(bw, item.File);\r
- Write(bw, item.Code.Split('\n'));\r
- }\r
-\r
- public static void Write(BinaryWriter bw, TSOMesh[] items)\r
- {\r
- bw.Write(items.Length);\r
-\r
- foreach(var i in items)\r
- Write(bw, i);\r
- }\r
-\r
- public static void Write(BinaryWriter bw, TSOMesh item)\r
- {\r
- Write(bw, item.Name);\r
- Write(bw, item.Matrix);\r
- bw.Write(1);\r
- Write(bw, item.sub);\r
- }\r
-\r
- public static void Write(BinaryWriter bw, TSOSubMesh[] items)\r
- {\r
- bw.Write(items.Length);\r
-\r
- foreach(var i in items)\r
- Write(bw, i);\r
- }\r
-\r
- public static void Write(BinaryWriter bw, TSOSubMesh item)\r
- {\r
- bw.Write(item.spec);\r
- bw.Write(item.numbones);\r
-\r
- foreach(int k in item.bones)\r
- bw.Write(k);\r
-\r
- bw.Write(item.numvertices);\r
-\r
- foreach(Vertex k in item.vertices)\r
- Write(bw, k);\r
- }\r
-\r
- public unsafe static void Write(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
-\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
- bw.Write(v.Tex.X); bw.Write(v.Tex.Y);\r
-\r
- bw.Write(wgts.Count);\r
-\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
- }\r
-}\r
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace Tso2MqoGui
+{
+ public class TSOWriter
+ {
+ public static void WriteHeader(BinaryWriter bw)
+ {
+ bw.Write(0x314F5354);
+ }
+
+ public static void Write(BinaryWriter bw, string s)
+ {
+ foreach (byte i in Encoding.Default.GetBytes(s))
+ bw.Write(i);
+
+ bw.Write((byte)0);
+ }
+
+ public static void Write(BinaryWriter bw, string[] s)
+ {
+ int n = s[s.Length - 1] == "" ? s.Length - 1 : s.Length;
+
+ bw.Write(n);
+
+ for (int i = 0; i < n; ++i)
+ Write(bw, s[i]);
+ }
+
+ public static void Write(BinaryWriter bw, TSONode[] items)
+ {
+ bw.Write(items.Length);
+
+ foreach (var i in items)
+ Write(bw, i);
+
+ bw.Write(items.Length);
+
+ foreach (var i in items)
+ Write(bw, i.Matrix);
+ }
+
+ public static void Write(BinaryWriter bw, TSONode item)
+ {
+ Write(bw, item.Name);
+ }
+
+ public static void Write(BinaryWriter bw, Matrix44 item)
+ {
+ bw.Write(item.M11); bw.Write(item.M12); bw.Write(item.M13); bw.Write(item.M14);
+ bw.Write(item.M21); bw.Write(item.M22); bw.Write(item.M23); bw.Write(item.M24);
+ bw.Write(item.M31); bw.Write(item.M32); bw.Write(item.M33); bw.Write(item.M34);
+ bw.Write(item.M41); bw.Write(item.M42); bw.Write(item.M43); bw.Write(item.M44);
+ }
+
+ public static void Write(BinaryWriter bw, TSOTex[] items)
+ {
+ bw.Write(items.Length);
+
+ foreach (var i in items)
+ Write(bw, i);
+ }
+
+ 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);
+ }
+
+ public static void Write(BinaryWriter bw, TSOEffect[] items)
+ {
+ bw.Write(items.Length);
+
+ foreach (var i in items)
+ Write(bw, i);
+ }
+
+ public static void Write(BinaryWriter bw, TSOEffect item)
+ {
+ Write(bw, item.Name);
+ Write(bw, item.Code.Split('\n'));
+ }
+
+ public static void Write(BinaryWriter bw, TSOMaterial[] items)
+ {
+ bw.Write(items.Length);
+
+ foreach (var i in items)
+ Write(bw, i);
+ }
+
+ public static void Write(BinaryWriter bw, TSOMaterial item)
+ {
+ Write(bw, item.Name);
+ Write(bw, item.File);
+ Write(bw, item.Code.Split('\n'));
+ }
+
+ public static void Write(BinaryWriter bw, TSOMesh[] items)
+ {
+ bw.Write(items.Length);
+
+ foreach (var i in items)
+ Write(bw, i);
+ }
+
+ public static void Write(BinaryWriter bw, TSOMesh item)
+ {
+ Write(bw, item.Name);
+ Write(bw, item.Matrix);
+ bw.Write(1);
+ Write(bw, item.sub_meshes);
+ }
+
+ public static void Write(BinaryWriter bw, TSOSubMesh[] items)
+ {
+ bw.Write(items.Length);
+
+ foreach (var i in items)
+ Write(bw, i);
+ }
+
+ public static void Write(BinaryWriter bw, TSOSubMesh item)
+ {
+ bw.Write(item.spec);
+ bw.Write(item.numbones);
+
+ foreach (int k in item.bones)
+ bw.Write(k);
+
+ bw.Write(item.numvertices);
+
+ foreach (Vertex k in item.vertices)
+ Write(bw, k);
+ }
+
+ public unsafe static void Write(BinaryWriter bw, Vertex v)
+ {
+ uint idx0 = v.Idx;
+ byte* idx = (byte*)(&idx0);
+ List<int> idxs = new List<int>(4);
+ List<float> wgts = new List<float>(4);
+
+ if (v.Wgt.x > 0) { idxs.Add(idx[0]); wgts.Add(v.Wgt.x); }
+ if (v.Wgt.y > 0) { idxs.Add(idx[1]); wgts.Add(v.Wgt.y); }
+ if (v.Wgt.z > 0) { idxs.Add(idx[2]); wgts.Add(v.Wgt.z); }
+ if (v.Wgt.w > 0) { idxs.Add(idx[3]); wgts.Add(v.Wgt.w); }
+
+ bw.Write(v.Pos.X); bw.Write(v.Pos.Y); bw.Write(v.Pos.Z);
+ bw.Write(v.Nrm.X); bw.Write(v.Nrm.Y); bw.Write(v.Nrm.Z);
+ bw.Write(v.Tex.X); bw.Write(v.Tex.Y);
+
+ bw.Write(wgts.Count);
+
+ for (int i = 0, n = idxs.Count; i < n; ++i)
+ {
+ bw.Write(idxs[i]);
+ bw.Write(wgts[i]);
+ }
+ }
+ }
+}
\ No newline at end of file
-using System;\r
-using System.Collections.Generic;\r
-using System.Text;\r
-\r
-namespace Tso2MqoGui\r
-{\r
- public class VertexHeap<T>\r
- {\r
- public Dictionary<T, ushort> map = new Dictionary<T, ushort>();\r
- public List<T> verts = new List<T>();\r
-\r
- public void Clear()\r
- {\r
- map.Clear();\r
- verts.Clear();\r
- }\r
-\r
- public ushort Add(T v)\r
- {\r
- ushort n;\r
-\r
- if(map.TryGetValue(v, out n))\r
- return n;\r
-\r
- n = (ushort)verts.Count;\r
- map.Add(v, n);\r
- verts.Add(v);\r
- return n;\r
- }\r
-\r
- public int Count { get { return verts.Count; } }\r
- public ushort this[T index] { get { return map[index]; } }\r
- public T this[int index] { get { return verts[index]; } }\r
- }\r
-}\r
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tso2MqoGui
+{
+ public class VertexHeap<T>
+ {
+ public Dictionary<T, ushort> map = new Dictionary<T, ushort>();
+ public List<T> verts = new List<T>();
+
+ public void Clear()
+ {
+ map.Clear();
+ verts.Clear();
+ }
+
+ public ushort Add(T v)
+ {
+ ushort n;
+
+ if (map.TryGetValue(v, out n))
+ return n;
+
+ n = (ushort)verts.Count;
+ map.Add(v, n);
+ verts.Add(v);
+ return n;
+ }
+
+ public int Count { get { return verts.Count; } }
+ public ushort this[T index] { get { return map[index]; } }
+ public T this[int index] { get { return verts[index]; } }
+ }
+}
\ No newline at end of file