OSDN Git Service

e6c598c5a0c68832c07714e78659113cef24f163
[tdcgexplorer/tso2mqo.git] / TSOGeneratorMqxBone.cs
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Text;
5
6 namespace Tso2MqoGui
7 {
8     public unsafe class TSOGeneratorMqxBone : TSOGenerator
9     {
10         public TSOGeneratorMqxBone(TSOGeneratorConfig config)
11             : base(config)
12         {
13         }
14
15         MqoWeit[] weits;
16
17         void CreateWeits()
18         {
19             weits = new MqoWeit[4];
20             for (int i = 0; i < 4; ++i)
21             {
22                 weits[i] = new MqoWeit();
23             }
24         }
25
26         protected override bool DoLoadRefTSO(string path)
27         {
28             tsoref = LoadTSO(path);
29             CreateWeits();
30             return true;
31         }
32
33         void UpdateWeits(int object_id, int vertex_id)
34         {
35             //todo
36
37             for (int i = 0; i < 4; ++i)
38             {
39                 weits[i].bone_id = 1;
40                 weits[i].weit = 0.0f;
41             }
42             weits[0].weit = 1.0f;
43         }
44
45         protected override bool DoGenerateMeshes()
46         {
47             meshes = new List<TSOMesh>();
48
49             foreach (MqoObject obj in mqo.Objects)
50             {
51                 if (obj.name.ToLower() == "bone")
52                     continue;
53
54                 Console.WriteLine("object:" + obj.name);
55
56                 int object_id = obj.id;
57
58                 obj.CreateNormal();
59
60                 List<int> faces_1 = new List<int>();
61                 List<int> faces_2 = new List<int>();
62                 Heap<int> bh = new Heap<int>();
63                 Heap<Vertex> vh = new Heap<Vertex>();
64                 Vertex[] refvs = new Vertex[3];
65                 List<ushort> vert_indices = new List<ushort>();
66                 Dictionary<int, bool> adding_bone_indices = new Dictionary<int, bool>();
67                 List<TSOSubMesh> subs = new List<TSOSubMesh>();
68
69                 for (int i = 0, n = obj.faces.Count; i < n; ++i)
70                     faces_1.Add(i);
71
72                 #region ボーンパーティション
73                 Console.WriteLine("  vertices bone_indices");
74                 Console.WriteLine("  -------- ------------");
75
76                 while (faces_1.Count != 0)
77                 {
78                     int spec = obj.faces[faces_1[0]].spec;
79                     bh.Clear();
80                     vh.Clear();
81                     vert_indices.Clear();
82
83                     foreach (int f in faces_1)
84                     {
85                         MqoFace face = obj.faces[f];
86
87                         if (face.spec != spec)
88                         {
89                             faces_2.Add(f);
90                             continue;
91                         }
92
93                         for (int k = 0; k < 3; ++k)
94                         {
95                             refvs[k] = new Vertex();
96                         }
97
98                         adding_bone_indices.Clear();
99
100                         for (int k = 0; k < 3; ++k)
101                         {
102                             UInt32 idx0 = refvs[k].Idx;
103                             Point4 wgt0 = refvs[k].Wgt;
104                             byte* idx = (byte*)(&idx0);
105                             float* wgt = (float*)(&wgt0);
106
107                             int vertex_id = obj.vertices[face.vert_indices[k]].id;
108                             UpdateWeits(object_id, vertex_id);
109
110                             for (int l = 0; l < 4; ++l)
111                             {
112                                 idx[l] = (byte)(weits[l].bone_id-1);
113                                 wgt[l] = weits[l].weit;
114                             }
115                             refvs[k].Idx = idx0;
116                             refvs[k].Wgt = wgt0;
117
118                             for (int l = 0; l < 4; ++l)
119                             {
120                                 if (wgt[l] <= float.Epsilon)
121                                     continue;
122                                 if (bh.map.ContainsKey(idx[l]))
123                                     continue;
124
125                                 adding_bone_indices[idx[l]] = true;
126                             }
127                         }
128
129                         if (bh.Count + adding_bone_indices.Count > 16)
130                         {
131                             faces_2.Add(f);
132                             continue;
133                         }
134
135                         foreach (int i in adding_bone_indices.Keys)
136                         {
137                             bh.Add(i);
138                         }
139
140                         for (int k = 0; k < 3; ++k)
141                         {
142                             UInt32 idx0 = refvs[k].Idx;
143                             Point4 wgt0 = refvs[k].Wgt;
144                             byte* idx = (byte*)(&idx0);
145                             float* wgt = (float*)(&wgt0);
146
147                             for (int l = 0; l < 4; ++l)
148                             {
149                                 if (wgt[l] <= float.Epsilon)
150                                     continue;
151
152                                 idx[l] = (byte)bh[idx[l]];
153                             }
154
155                             refvs[k].Idx = idx0;
156                         }
157
158                         Vertex va = new Vertex(obj.vertices[face.a].Pos, refvs[0].Wgt, refvs[0].Idx, obj.vertices[face.a].Nrm, new Point2(face.ta.x, 1 - face.ta.y));
159                         Vertex vb = new Vertex(obj.vertices[face.b].Pos, refvs[1].Wgt, refvs[1].Idx, obj.vertices[face.b].Nrm, new Point2(face.tb.x, 1 - face.tb.y));
160                         Vertex vc = new Vertex(obj.vertices[face.c].Pos, refvs[2].Wgt, refvs[2].Idx, obj.vertices[face.c].Nrm, new Point2(face.tc.x, 1 - face.tc.y));
161
162                         vert_indices.Add(vh.Add(va));
163                         vert_indices.Add(vh.Add(vc));
164                         vert_indices.Add(vh.Add(vb));
165                     }
166
167                     ushort[] optimized_indices = NvTriStrip.Optimize(vert_indices.ToArray());
168
169                     TSOSubMesh sub = new TSOSubMesh();
170                     sub.spec = spec;
171                     sub.numbones = bh.Count;
172                     sub.bones = bh.ary.ToArray();
173
174                     sub.numvertices = optimized_indices.Length;
175                     Vertex[] vertices = new Vertex[optimized_indices.Length];
176                     for (int i = 0; i < optimized_indices.Length; ++i)
177                     {
178                         vertices[i] = vh.ary[optimized_indices[i]];
179                     }
180                     sub.vertices = vertices;
181
182                     Console.WriteLine("  {0,8} {1,12}", sub.vertices.Length, sub.bones.Length);
183
184                     subs.Add(sub);
185
186                     List<int> faces_tmp = faces_1;
187                     faces_1 = faces_2;
188                     faces_2 = faces_tmp;
189                     faces_tmp.Clear();
190                 }
191                 #endregion
192                 TSOMesh mesh = new TSOMesh();
193                 mesh.name = obj.name;
194                 mesh.numsubs = subs.Count;
195                 mesh.sub_meshes = subs.ToArray();
196                 mesh.matrix = Matrix44.Identity;
197                 mesh.effect = 0;
198                 meshes.Add(mesh);
199             }
200
201             return true;
202         }
203     }
204 }