OSDN Git Service

b5348fa65cb27d6876f5bdf52112a7c325f7240e
[tdcgexplorer/tso2mqo.git] / TSOGeneratorOneBone.cs
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Text;
5
6 namespace Tso2MqoGui
7 {
8     public class TSOGeneratorOneBone : TSOGenerator
9     {
10         public TSOGeneratorOneBone(TSOGeneratorConfig config)
11             : base(config)
12         {
13         }
14
15         //ボーンの名称からidを得る辞書
16         protected Dictionary<string, int> node_idmap;
17
18         //ボーンの名称からidを得る辞書を生成する。参照tsoを基にする。
19         void CreateNodeMap()
20         {
21             node_idmap = new Dictionary<string, int>();
22
23             foreach (TSONode i in tsoref.nodes)
24             {
25                 node_idmap.Add(i.ShortName, i.ID);
26             }
27         }
28
29         protected override bool DoLoadRefTSO(string path)
30         {
31             tsoref = LoadTSO(path);
32             CreateNodeMap();
33             return true;
34         }
35
36         protected override bool DoGenerateMeshes()
37         {
38             meshes = new List<TSOMesh>();
39
40             foreach (MqoObject obj in mqo.Objects)
41             {
42                 if (obj.name.ToLower() == "bone")
43                     continue;
44
45                 Console.WriteLine("object:" + obj.name);
46
47                 obj.CreateNormal();
48
49                 // ボーン情報作成
50                 uint idx = 0x00000000;
51                 Point4 wgt = new Point4(1, 0, 0, 0);
52                 int[] bones = CreateBones(obj);
53
54                 // マテリアル別に処理を実行
55                 List<ushort> indices = new List<ushort>();
56                 VertexHeap<Vertex> vh = new VertexHeap<Vertex>();
57                 List<TSOSubMesh> subs = new List<TSOSubMesh>();
58
59                 Console.WriteLine("  vertices bone_indices");
60                 Console.WriteLine("  -------- ------------");
61
62                 for (int mtl = 0; mtl < nummaterials; ++mtl)
63                 {
64                     indices.Clear();
65
66                     foreach (MqoFace face in obj.faces)
67                     {
68                         if (face.mtl != mtl)
69                             continue;
70
71                         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));
72                         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));
73                         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));
74
75                         indices.Add(vh.Add(va));
76                         indices.Add(vh.Add(vc));
77                         indices.Add(vh.Add(vb));
78                     }
79
80                     if (indices.Count == 0)
81                         continue;
82
83                     // フェイス最適化
84                     ushort[] nidx = NvTriStrip.Optimize(indices.ToArray());
85
86                     // サブメッシュ生成
87                     Vertex[] verts = vh.verts.ToArray();
88                     TSOSubMesh sub = new TSOSubMesh();
89                     sub.spec = mtl;
90                     sub.numbones = bones.Length;
91                     sub.bones = bones;
92                     sub.numvertices = nidx.Length;
93                     sub.vertices = new Vertex[nidx.Length];
94
95                     for (int i = 0; i < nidx.Length; ++i)
96                         sub.vertices[i] = verts[nidx[i]];
97
98                     Console.WriteLine("  {0,8} {1,12}", sub.vertices.Length, sub.bones.Length);
99
100                     subs.Add(sub);
101                 }
102
103                 // メッシュ生成
104                 TSOMesh mesh = new TSOMesh();
105                 mesh.name = obj.name;
106                 mesh.numsubs = subs.Count;
107                 mesh.sub_meshes = subs.ToArray();
108                 mesh.matrix = Matrix44.Identity;
109                 mesh.effect = 0;
110                 meshes.Add(mesh);
111             }
112
113             return true;
114         }
115
116         public Dictionary<string, string> ObjectBoneNames = new Dictionary<string, string>();
117
118         // objに対応するボーンid配列を生成する。
119         int[] CreateBones(MqoObject obj)
120         {
121             int[] bones = new int[1];
122             string name;
123             try
124             {
125                 name = ObjectBoneNames[obj.name];
126             }
127             catch (KeyNotFoundException)
128             {
129                 throw new KeyNotFoundException(string.Format("ボーン指定に誤りがあります。オブジェクト {0} にボーンを割り当てる必要があります。", obj.name));
130             }
131             bones[0] = node_idmap[name];
132             return bones;
133         }
134     }
135 }