OSDN Git Service

reformat
authornomeu <nomeu@nomeu.org>
Wed, 27 Feb 2013 21:54:44 +0000 (06:54 +0900)
committernomeu <nomeu@nomeu.org>
Wed, 27 Feb 2013 21:54:44 +0000 (06:54 +0900)
18 files changed:
Config.cs
Form1.cs
FormMaterial.cs
General.cs
ImageFile.cs
ImportInfo.cs
MqoFile.cs
MqoWriter.cs
NvTriStrip.cs
PointCluster.cs
Program.cs
RDBBonFile.cs
TDCGFile.cs
TSOFile.cs
TSOGenerator.cs
TSOGeneratorConfig.cs
TSOWriter.cs
VertexHeap.cs

index e9b497c..23265ce 100644 (file)
--- a/Config.cs
+++ b/Config.cs
@@ -1,90 +1,96 @@
-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
index 7407d20..2b301a3 100644 (file)
--- a/Form1.cs
+++ b/Form1.cs
-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
index a2a7b28..4bc77cf 100644 (file)
@@ -11,23 +11,23 @@ namespace Tso2MqoGui
 {\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
@@ -59,39 +59,46 @@ namespace Tso2MqoGui
                 }\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
index 0f11dda..8099b4a 100644 (file)
-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
index 6cd002c..689a649 100644 (file)
@@ -1,57 +1,57 @@
-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
index 5715a71..dadb173 100644 (file)
@@ -9,21 +9,25 @@ namespace Tso2MqoGui
     [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
@@ -60,38 +64,41 @@ namespace Tso2MqoGui
                 }\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
@@ -99,7 +106,7 @@ namespace Tso2MqoGui
 \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
@@ -109,17 +116,19 @@ namespace Tso2MqoGui
 \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
@@ -127,7 +136,7 @@ namespace Tso2MqoGui
 \r
         public ImportEffectInfo(TSOEffect eff)\r
         {\r
-            Name            = eff.Name;\r
+            Name = eff.Name;\r
         }\r
 \r
         public override string ToString()\r
@@ -138,11 +147,16 @@ namespace Tso2MqoGui
 \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
@@ -150,67 +164,72 @@ namespace Tso2MqoGui
 \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
index f7ae8ad..58ef4b3 100644 (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
index 41e7fed..e39a9cb 100644 (file)
@@ -14,8 +14,8 @@ namespace Tso2MqoGui
 
     public class Pair<T, U>
     {
-        public T    First;
-        public U    Second;
+        public T First;
+        public U Second;
 
         public Pair()
         {
@@ -23,25 +23,25 @@ namespace Tso2MqoGui
 
         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()
@@ -51,9 +51,9 @@ namespace Tso2MqoGui
 
         public void Close()
         {
-            if(tw != null)
+            if (tw != null)
                 tw.Close();
-            tw  = null;
+            tw = null;
         }
 
         string GetTextureFileName(TSOTex tex)
@@ -72,50 +72,50 @@ namespace Tso2MqoGui
         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);
@@ -138,25 +138,26 @@ namespace Tso2MqoGui
             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))",
@@ -166,40 +167,41 @@ namespace Tso2MqoGui
 
             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);
                         }
                     }
@@ -216,7 +218,7 @@ namespace Tso2MqoGui
                 //
                 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}");
@@ -224,89 +226,89 @@ namespace Tso2MqoGui
                 //
                 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");
@@ -329,8 +331,8 @@ namespace Tso2MqoGui
         public Point3 Pos;
         public Point3 Nrm;
         public Point2 Tex;
-        public int      mtl;
-        
+        public int mtl;
+
         public UVertex()
         {
         }
@@ -340,7 +342,7 @@ namespace Tso2MqoGui
             Pos = pos;
             Nrm = nrm;
             Tex = tex;
-            this.mtl= mtl;
+            this.mtl = mtl;
         }
 
         public int CompareTo(UVertex o)
@@ -376,4 +378,4 @@ namespace Tso2MqoGui
             return Pos.Equals(v.Pos) && Nrm.Equals(v.Nrm);
         }
     }
-}
+}
\ No newline at end of file
index 0ccda2a..582ba0c 100644 (file)
@@ -1,68 +1,79 @@
-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
index 6be9a65..0b813c9 100644 (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
index 4351f3e..e721860 100644 (file)
@@ -15,7 +15,8 @@ namespace Tso2MqoGui
         static int Main(string[] args)\r
         {\r
             if (args.Length != 0)\r
-            {   // バッチで処理する\r
+            {\r
+                // バッチで処理する\r
                 try\r
                 {\r
                     string tso = null;\r
@@ -29,10 +30,14 @@ namespace Tso2MqoGui
                         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
@@ -42,9 +47,12 @@ namespace Tso2MqoGui
                     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
@@ -55,10 +63,10 @@ namespace Tso2MqoGui
                     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
@@ -73,4 +81,4 @@ namespace Tso2MqoGui
             return 0;\r
         }\r
     }\r
-}\r
+}
\ No newline at end of file
index aa13f90..ba5d468 100644 (file)
@@ -1,87 +1,87 @@
-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
index 47097a9..cd8c067 100644 (file)
@@ -1,84 +1,84 @@
-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
index a6d48d8..0611250 100644 (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
index 47a638c..40e94bd 100644 (file)
@@ -108,9 +108,9 @@ namespace Tso2MqoGui
         {\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
@@ -123,7 +123,7 @@ namespace Tso2MqoGui
         {\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
@@ -133,10 +133,10 @@ namespace Tso2MqoGui
         {\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
@@ -145,21 +145,21 @@ namespace Tso2MqoGui
                 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
@@ -170,16 +170,16 @@ namespace Tso2MqoGui
         {\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
@@ -189,25 +189,25 @@ namespace Tso2MqoGui
         {\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
@@ -217,25 +217,25 @@ namespace Tso2MqoGui
         {\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
@@ -309,13 +309,13 @@ namespace Tso2MqoGui
                 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
@@ -330,15 +330,15 @@ namespace Tso2MqoGui
 \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
@@ -346,86 +346,86 @@ namespace Tso2MqoGui
 \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
@@ -446,90 +446,89 @@ namespace Tso2MqoGui
 \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
@@ -537,12 +536,12 @@ namespace Tso2MqoGui
                 }\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
@@ -550,7 +549,7 @@ namespace Tso2MqoGui
         }\r
 \r
     }\r
-    \r
+\r
     public unsafe class TSOGeneratorRefBone : TSOGenerator\r
     {\r
         private List<Vertex> vlst;\r
@@ -566,7 +565,7 @@ namespace Tso2MqoGui
             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
@@ -582,21 +581,21 @@ namespace Tso2MqoGui
             // 参照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
@@ -606,95 +605,95 @@ namespace Tso2MqoGui
 \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
@@ -706,16 +705,16 @@ namespace Tso2MqoGui
                         }\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
@@ -723,34 +722,34 @@ namespace Tso2MqoGui
                     }\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
@@ -758,19 +757,19 @@ namespace Tso2MqoGui
                     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
@@ -792,42 +791,42 @@ namespace Tso2MqoGui
 \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
@@ -839,30 +838,30 @@ namespace Tso2MqoGui
 \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
index 78a8db8..5691f69 100644 (file)
@@ -1,12 +1,12 @@
-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
index 30fbef5..1571c15 100644 (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
index ec15d7a..3b11dbc 100644 (file)
@@ -1,35 +1,35 @@
-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