OSDN Git Service

read bitmap created gimp 2.8
[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         protected override bool DoLoadRefTSO(string path)
16         {
17             return true;
18         }
19
20         protected override bool DoGenerateMeshes()
21         {
22             meshes = new List<TSOMesh>();
23
24             foreach (MqoObject obj in mqo.Objects)
25             {
26                 if (obj.name.ToLower() == "bone")
27                     continue;
28
29                 Console.WriteLine("object:" + obj.name);
30
31                 int object_id = obj.id;
32
33                 obj.CreateNormal();
34
35                 List<int> faces_1 = new List<int>();
36                 List<int> faces_2 = new List<int>();
37                 Heap<int> bh = new Heap<int>();
38                 Heap<Vertex> vh = new Heap<Vertex>();
39                 Vertex[] refvs = new Vertex[3];
40                 List<ushort> vert_indices = new List<ushort>();
41                 Dictionary<int, bool> adding_bone_indices = new Dictionary<int, bool>();
42                 List<TSOSubMesh> subs = new List<TSOSubMesh>();
43
44                 for (int i = 0, n = obj.faces.Count; i < n; ++i)
45                     faces_1.Add(i);
46
47                 #region ボーンパーティション
48                 Console.WriteLine("  vertices bone_indices");
49                 Console.WriteLine("  -------- ------------");
50
51                 while (faces_1.Count != 0)
52                 {
53                     int spec = obj.faces[faces_1[0]].spec;
54                     bh.Clear();
55                     vh.Clear();
56                     vert_indices.Clear();
57
58                     foreach (int f in faces_1)
59                     {
60                         MqoFace face = obj.faces[f];
61
62                         if (face.spec != spec)
63                         {
64                             faces_2.Add(f);
65                             continue;
66                         }
67
68                         for (int k = 0; k < 3; ++k)
69                         {
70                             refvs[k] = new Vertex();
71                         }
72
73                         adding_bone_indices.Clear();
74
75                         for (int k = 0; k < 3; ++k)
76                         {
77                             UInt32 idx0 = refvs[k].Idx;
78                             Point4 wgt0 = refvs[k].Wgt;
79                             byte* idx = (byte*)(&idx0);
80                             float* wgt = (float*)(&wgt0);
81
82                             int vertex_id = obj.vertices[face.vert_indices[k]].id;
83                             //Console.WriteLine("v.{0} oi:{1} vi:{2}", k, object_id, vertex_id);
84                             mqx.UpdateWeits(object_id, vertex_id);
85                             for (int l = 0; l < 4; ++l)
86                             {
87                                 idx[l] = (byte)mqx.weits[l].node_id;
88                                 wgt[l] = mqx.weits[l].weit;
89                                 //Console.WriteLine("  w.{0} i:{1} w:{2}", l, idx[l], wgt[l]);
90                             }
91                             refvs[k].Idx = idx0;
92                             refvs[k].Wgt = wgt0;
93
94                             for (int l = 0; l < 4; ++l)
95                             {
96                                 if (wgt[l] <= float.Epsilon)
97                                     continue;
98                                 if (bh.map.ContainsKey(idx[l]))
99                                     continue;
100
101                                 adding_bone_indices[idx[l]] = true;
102                             }
103                         }
104
105                         if (bh.Count + adding_bone_indices.Count > 16)
106                         {
107                             faces_2.Add(f);
108                             continue;
109                         }
110
111                         foreach (int i in adding_bone_indices.Keys)
112                         {
113                             bh.Add(i);
114                         }
115
116                         for (int k = 0; k < 3; ++k)
117                         {
118                             UInt32 idx0 = refvs[k].Idx;
119                             Point4 wgt0 = refvs[k].Wgt;
120                             byte* idx = (byte*)(&idx0);
121                             float* wgt = (float*)(&wgt0);
122
123                             for (int l = 0; l < 4; ++l)
124                             {
125                                 if (wgt[l] <= float.Epsilon)
126                                     continue;
127
128                                 idx[l] = (byte)bh[idx[l]];
129                             }
130
131                             refvs[k].Idx = idx0;
132                         }
133
134                         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));
135                         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));
136                         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));
137
138                         vert_indices.Add(vh.Add(va));
139                         vert_indices.Add(vh.Add(vc));
140                         vert_indices.Add(vh.Add(vb));
141                     }
142
143                     ushort[] optimized_indices = NvTriStrip.Optimize(vert_indices.ToArray());
144
145                     TSOSubMesh sub = new TSOSubMesh();
146                     sub.spec = spec;
147                     sub.numbones = bh.Count;
148                     sub.bones = bh.ary.ToArray();
149
150                     sub.numvertices = optimized_indices.Length;
151                     Vertex[] vertices = new Vertex[optimized_indices.Length];
152                     for (int i = 0; i < optimized_indices.Length; ++i)
153                     {
154                         vertices[i] = vh.ary[optimized_indices[i]];
155                     }
156                     sub.vertices = vertices;
157
158                     Console.WriteLine("  {0,8} {1,12}", sub.vertices.Length, sub.bones.Length);
159
160                     subs.Add(sub);
161
162                     List<int> faces_tmp = faces_1;
163                     faces_1 = faces_2;
164                     faces_2 = faces_tmp;
165                     faces_tmp.Clear();
166                 }
167                 #endregion
168                 TSOMesh mesh = new TSOMesh();
169                 mesh.name = obj.name;
170                 mesh.numsubs = subs.Count;
171                 mesh.sub_meshes = subs.ToArray();
172                 mesh.matrix = Matrix44.Identity;
173                 mesh.effect = 0;
174                 meshes.Add(mesh);
175             }
176
177             return true;
178         }
179     }
180 }