using System.Text;\r
using System.Runtime.InteropServices;\r
using System.ComponentModel;\r
-using System.Windows.Forms;\r
using System.Windows.Forms.Design;\r
\r
namespace Tso2MqoGui\r
{\r
public abstract class TSOGenerator\r
{\r
- private string dir;\r
- private TSOGeneratorConfig config;\r
+ string dir;\r
+ TSOGeneratorConfig config;\r
protected MqoReader mqo;\r
protected TSOFile tsoref;\r
- protected Dictionary<string, TSONode> nodes;\r
protected List<TSOMesh> meshes;\r
- private ImportInfo ii;\r
- private BinaryWriter bw;\r
- protected Dictionary<string, MaterialInfo> materials;\r
- private Dictionary<string, TextureInfo> textures;\r
+ ImportInfo ii;\r
+ BinaryWriter bw;\r
+ Dictionary<string, MaterialInfo> materials;\r
+ protected int nummaterials { get { return materials.Count; } }\r
+ Dictionary<string, TextureInfo> textures;\r
\r
public TSOGenerator(TSOGeneratorConfig config)\r
{\r
return tso;\r
}\r
\r
- private bool SetCurrentDirectory(string dir)\r
+ bool SetCurrentDirectory(string dir)\r
{\r
this.dir = dir;\r
Environment.CurrentDirectory = dir;\r
return true;\r
}\r
\r
- private bool DoLoadMQO(string mqo_file)\r
+ bool DoLoadMQO(string mqo_file)\r
{\r
// MQO読み込み\r
mqo = new MqoReader();\r
return true;\r
}\r
\r
- private bool DoLoadXml(string importinfo_file)\r
+ bool DoLoadXml(string importinfo_file)\r
{\r
// XML読み込み\r
ii = ImportInfo.Load(importinfo_file);\r
return true;\r
}\r
\r
- private bool DoWriteHeader()\r
+ bool DoWriteHeader()\r
{\r
bw.Write(0x314F5354);\r
return true;\r
}\r
\r
- private bool DoWriteNodeNames()\r
+ bool DoWriteNodeNames()\r
{\r
bw.Write(tsoref.nodes.Length);\r
\r
- nodes = new Dictionary<string, TSONode>();\r
-\r
foreach (TSONode i in tsoref.nodes)\r
{\r
WriteString(bw, i.Name);\r
- nodes.Add(i.ShortName, i);\r
}\r
\r
return true;\r
}\r
\r
- private bool DoWriteNodeMatrices()\r
+ bool DoWriteNodeMatrices()\r
{\r
bw.Write(tsoref.nodes.Length);\r
\r
return true;\r
}\r
\r
- private bool DoWriteTextures()\r
+ bool DoWriteTextures()\r
{\r
bw.Write(textures.Count);\r
\r
return true;\r
}\r
\r
- private bool DoWriteEffects()\r
+ bool DoWriteEffects()\r
{\r
bw.Write(ii.effects.Count);\r
\r
return true;\r
}\r
\r
- private bool DoWriteMaterials()\r
+ bool DoWriteMaterials()\r
{\r
bw.Write(mqo.Materials.Count);\r
\r
return true;\r
}\r
\r
- private bool DoWriteMeshes()\r
+ bool DoWriteMeshes()\r
{\r
bw.Write(meshes.Count);\r
\r
return true;\r
}\r
\r
- private bool DoOutput(string tsoout_file)\r
+ bool DoOutput(string path)\r
{\r
//----- 出力処理 -----------------------------------------------\r
ii.materials.Clear();\r
ii.textures.Clear();\r
\r
- using (FileStream fs = File.OpenWrite(tsoout_file))\r
+ using (FileStream fs = File.OpenWrite(path))\r
{\r
fs.SetLength(0);\r
bw = new BinaryWriter(fs);\r
\r
return true;\r
}\r
+\r
+ //メッシュリストを生成する。\r
+ //メッシュリストはthis.meshesに保持する。\r
protected abstract bool DoGenerateMeshes();\r
\r
- private bool DoSaveXml(string importinfo_file)\r
+ bool DoSaveXml(string importinfo_file)\r
{\r
// 結果を保存しておく\r
ImportInfo.Save(importinfo_file, ii);\r
{\r
dir = null;\r
tsoref = null;\r
- nodes = null;\r
meshes = null;\r
mqo = null;\r
ii = null;\r
}\r
}\r
\r
- protected abstract bool DoLoadRefTSO(string tsoref);\r
+ // 参照tsoを読み込む。\r
+ // 参照tsoはthis.tsorefに保持する。\r
+ protected abstract bool DoLoadRefTSO(string path);\r
\r
#region ユーティリティ\r
public void WriteString(BinaryWriter bw, string s)\r
#endregion\r
}\r
\r
- public class TSOGeneratorOneBone : TSOGenerator\r
- {\r
- public Dictionary<string, string> ObjectBoneNames = new Dictionary<string, string>();\r
-\r
- public TSOGeneratorOneBone(TSOGeneratorConfig config)\r
- : base(config)\r
- {\r
- }\r
-\r
- protected override bool DoLoadRefTSO(string tsoref_file)\r
- {\r
- // 参照TSOロード\r
- tsoref = LoadTSO(tsoref_file);\r
- return true;\r
- }\r
-\r
- protected override bool DoGenerateMeshes()\r
- {\r
- meshes = new List<TSOMesh>();\r
-\r
- foreach (MqoObject obj in mqo.Objects)\r
- {\r
- if (obj.name.ToLower() == "bone")\r
- continue;\r
-\r
- Console.WriteLine("object:" + obj.name);\r
-\r
- obj.CreateNormal();\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
- try\r
- {\r
- bone = ObjectBoneNames[obj.name];\r
- }\r
- catch (KeyNotFoundException)\r
- {\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
-\r
- Console.WriteLine(" vertices bone_indices");\r
- Console.WriteLine(" -------- ------------");\r
-\r
- for (int mtl = 0; mtl < materials.Count; ++mtl)\r
- {\r
- indices.Clear();\r
-\r
- foreach (MqoFace face in obj.faces)\r
- {\r
- if (face.mtl != mtl)\r
- continue;\r
-\r
- Vertex va = new Vertex(obj.vertices[face.a].Pos, wgt, idx, obj.vertices[face.a].Nrm, new Point2(face.ta.x, 1 - face.ta.y));\r
- Vertex vb = new Vertex(obj.vertices[face.b].Pos, wgt, idx, obj.vertices[face.b].Nrm, new Point2(face.tb.x, 1 - face.tb.y));\r
- Vertex vc = new Vertex(obj.vertices[face.c].Pos, wgt, idx, obj.vertices[face.c].Nrm, 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
- continue;\r
-\r
- // フェイス最適化\r
- ushort[] nidx = NvTriStrip.Optimize(indices.ToArray());\r
-\r
- // サブメッシュ生成\r
- Vertex[] verts = vh.verts.ToArray();\r
- TSOSubMesh sub = new TSOSubMesh();\r
- sub.spec = mtl;\r
- sub.numbones = bones.Length;\r
- sub.bones = bones;\r
- sub.numvertices = nidx.Length;\r
- sub.vertices = new Vertex[nidx.Length];\r
-\r
- for (int 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
- subs.Add(sub);\r
- }\r
-\r
- // メッシュ生成\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
- return true;\r
- }\r
-\r
- }\r
-\r
- public unsafe class TSOGeneratorRefBone : TSOGenerator\r
- {\r
- private List<Vertex> vlst;\r
- private PointCluster pc;\r
-\r
- public TSOGeneratorRefBone(TSOGeneratorConfig config)\r
- : base(config)\r
- {\r
- }\r
-\r
- private void CreatePointCluster(TSOFile tso)\r
- {\r
- vlst = new List<Vertex>();\r
-\r
- foreach (TSOMesh i in tso.meshes)\r
- foreach (TSOSubMesh j in i.sub_meshes)\r
- vlst.AddRange(j.vertices);\r
-\r
- pc = new PointCluster(vlst.Count);\r
-\r
- foreach (Vertex i in vlst)\r
- pc.Add(i.Pos.x, i.Pos.y, i.Pos.z);\r
-\r
- pc.Clustering();\r
- }\r
-\r
- protected override bool DoLoadRefTSO(string tsoref_file)\r
- {\r
- // 参照TSOロード\r
- tsoref = LoadTSO(tsoref_file);\r
- tsoref.SwitchBoneIndicesOnMesh();\r
- CreatePointCluster(tsoref);\r
- return true;\r
- }\r
-\r
- protected override bool DoGenerateMeshes()\r
- {\r
- meshes = new List<TSOMesh>();\r
-\r
- foreach (MqoObject obj in mqo.Objects)\r
- {\r
- if (obj.name.ToLower() == "bone")\r
- continue;\r
-\r
- Console.WriteLine("object:" + obj.name);\r
-\r
- // 一番近い頂点への参照\r
- List<int> vref = new List<int>(obj.vertices.Count);\r
-\r
- foreach (UVertex j in obj.vertices)\r
- vref.Add(pc.NearestIndex(j.Pos.x, j.Pos.y, j.Pos.z));\r
-\r
- obj.CreateNormal();\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 = obj.faces.Count; j < n; ++j)\r
- faces1.Add(j);\r
-\r
- #region ボーンパーティション\r
- Console.WriteLine(" vertices bone_indices");\r
- Console.WriteLine(" -------- ------------");\r
-\r
- while (faces1.Count > 0)\r
- {\r
- int mtl = obj.faces[faces1[0]].mtl;\r
- selected.Clear();\r
- indices.Clear();\r
- vh.Clear();\r
- bones.Clear();\r
-\r
- foreach (int j in faces1)\r
- {\r
- MqoFace f = obj.faces[j];\r
-\r
- if (f.mtl != mtl)\r
- {\r
- faces2.Add(j);\r
- continue;\r
- }\r
-\r
- v[0] = vlst[vref[f.a]];\r
- v[1] = vlst[vref[f.b]];\r
- v[2] = vlst[vref[f.c]];\r
-\r
- work.Clear();\r
-\r
- for (int k = 0; k < 3; ++k)\r
- {\r
- Vertex vv = v[k];\r
- UInt32 idx0 = vv.Idx;\r
- Point4 wgt0 = vv.Wgt;\r
- byte* idx = (byte*)(&idx0);\r
- float* wgt = (float*)(&wgt0);\r
-\r
- for (int l = 0; l < 4; ++l)\r
- {\r
- if (wgt[l] <= float.Epsilon) continue;\r
- if (selected.ContainsKey(idx[l])) continue;\r
-\r
- if (!work.ContainsKey(idx[l]))\r
- work.Add(idx[l], 0);\r
- }\r
- }\r
-\r
- if (selected.Count + work.Count > 16)\r
- {\r
- faces2.Add(j);\r
- continue;\r
- }\r
-\r
- // ボーンリストに足してvalid\r
- foreach (KeyValuePair<int, int> l in work)\r
- {\r
- selected.Add(l.Key, selected.Count); // ボーンテーブルに追加\r
- bones.Add(l.Key);\r
- }\r
-\r
- // \todo 点の追加\r
- Vertex va = new Vertex(obj.vertices[f.a].Pos, v[0].Wgt, v[0].Idx, obj.vertices[f.a].Nrm, new Point2(f.ta.x, 1 - f.ta.y));\r
- Vertex vb = new Vertex(obj.vertices[f.b].Pos, v[1].Wgt, v[1].Idx, obj.vertices[f.b].Nrm, new Point2(f.tb.x, 1 - f.tb.y));\r
- Vertex vc = new Vertex(obj.vertices[f.c].Pos, v[2].Wgt, v[2].Idx, obj.vertices[f.c].Nrm, new Point2(f.tc.x, 1 - f.tc.y));\r
-\r
- indices.Add(vh.Add(va));\r
- indices.Add(vh.Add(vc));\r
- indices.Add(vh.Add(vb));\r
- }\r
-\r
- // フェイス最適化\r
- ushort[] nidx = NvTriStrip.Optimize(indices.ToArray());\r
-\r
- // 頂点のボーン参照ローカルに変換\r
- Vertex[] verts = vh.verts.ToArray();\r
-\r
- for (int j = 0; j < verts.Length; ++j)\r
- {\r
- uint idx0 = verts[j].Idx;\r
- byte* idx = (byte*)(&idx0);\r
- Point4 wgt0 = verts[j].Wgt;\r
- float* wgt = (float*)(&wgt0);\r
-\r
- for (int k = 0; k < 4; ++k)\r
- if (wgt[k] > float.Epsilon)\r
- idx[k] = (byte)selected[idx[k]];\r
-\r
- verts[j].Idx = idx0;\r
- }\r
-\r
- // サブメッシュ生成\r
- TSOSubMesh sub = new TSOSubMesh();\r
- sub.spec = mtl;\r
- sub.numbones = bones.Count;\r
- sub.bones = bones.ToArray();\r
- sub.numvertices = nidx.Length;\r
- sub.vertices = new Vertex[nidx.Length];\r
-\r
- for (int j = 0; j < nidx.Length; ++j)\r
- sub.vertices[j] = verts[nidx[j]];\r
-\r
- Console.WriteLine(" {0,8} {1,12}", sub.vertices.Length, sub.bones.Length);\r
-\r
- subs.Add(sub);\r
-\r
- // 次の周回\r
- List<int> t = faces1;\r
- faces1 = faces2;\r
- faces2 = t;\r
- t.Clear();\r
- }\r
- #endregion\r
- // \todo TSOMesh生成\r
- TSOMesh mesh = new TSOMesh();\r
- mesh.name = 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
- return true;\r
- }\r
-\r
- protected override bool DoCleanup()\r
- {\r
- pc = null;\r
- vlst = null;\r
- return base.DoCleanup();\r
- }\r
- }\r
-\r
public class TextureInfo\r
{\r
public string name;\r