2 using System.Collections.Generic;
9 public class Pair<T, U>
18 public Pair(T first, U second)
25 public class MqoWriter : IDisposable
28 public string OutPath;
29 public string OutFile;
30 public bool MqxEnabled;
32 public MqoWriter(string file)
34 FileStream fs = File.OpenWrite(file);
36 tw = new StreamWriter(fs, Encoding.Default);
38 OutPath = Path.GetDirectoryName(file);
41 void IDisposable.Dispose()
53 string GetTextureFileName(TSOTex tex)
55 string filename = Path.GetFileName(tex.File.Trim('"'));
61 string GetTexturePath(TSOTex tex)
63 return Path.Combine(OutPath, GetTextureFileName(tex));
66 public void CreateTextureFile(TSOTex tex)
68 string file = GetTexturePath(tex);
69 byte[] data = tex.data;
71 //TODO: .bmpのはずが.psdになってるものがある
73 using (FileStream fs = File.OpenWrite(file))
75 BinaryWriter bw = new BinaryWriter(fs);
77 switch (Path.GetExtension(file).ToUpper())
80 bw.Write((byte)0); // id
81 bw.Write((byte)0); // colormap
82 bw.Write((byte)2); // imagetype
83 bw.Write((byte)0); // unknown0
84 bw.Write((byte)0); // unknown1
85 bw.Write((byte)0); // unknown2
86 bw.Write((byte)0); // unknown3
87 bw.Write((byte)0); // unknown4
88 bw.Write((short)0); // width
89 bw.Write((short)0); // height
90 bw.Write((short)tex.Width); // width
91 bw.Write((short)tex.Height); // height
92 bw.Write((byte)(tex.depth * 8));// depth
93 bw.Write((byte)0); // depth
99 bw.Write((int)(54 + data.Length));
103 bw.Write((int)tex.Width);
104 bw.Write((int)tex.Height);
106 bw.Write((short)(tex.Depth * 8));
108 bw.Write((int)data.Length);
116 bw.Write(data, 0, data.Length);
121 public void Write(TSOFile tso)
123 tw.WriteLine("Metasequoia Document");
124 tw.WriteLine("Format Text Ver 1.0");
128 tw.WriteLine("IncludeXml \"{0}\"", Path.GetFileName(Path.ChangeExtension(OutFile, ".mqx")));
131 tw.WriteLine("Scene {");
132 tw.WriteLine("\tpos -7.0446 4.1793 1541.1764");
133 tw.WriteLine("\tlookat 11.8726 193.8590 0.4676");
134 tw.WriteLine("\thead 0.8564");
135 tw.WriteLine("\tpich 0.1708");
136 tw.WriteLine("\tortho 0");
137 tw.WriteLine("\tzoom2 31.8925");
138 tw.WriteLine("\tamb 0.250 0.250 0.250");
141 foreach (TSOTex tex in tso.textures)
142 CreateTextureFile(tex);
144 tw.WriteLine("Material {0} {{", tso.materials.Length);
146 foreach (TSOMaterial mat in tso.materials)
149 if (tso.texturemap.TryGetValue(mat.ColorTex, out tex))
152 "\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}\")",
153 mat.name, GetTextureFileName(tex));
158 "\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))",
165 MqoBone[] bones = null;
168 bones = CreateBones(tso);
170 MqoObjectGen.uid_enabled = MqxEnabled;
171 MqoObjectGen obj = new MqoObjectGen();
173 ushort object_id = 0;
174 foreach (TSOMesh mesh in tso.meshes)
176 obj.id = ++object_id;
177 obj.name = mesh.Name;
187 MqxWriter writer = new MqxWriter();
188 writer.MqoFile = OutFile;
189 writer.Write(bones, object_id /* eq numobjects */);
195 MqoBone[] CreateBones(TSOFile tso)
197 MqoBone[] bones = new MqoBone[tso.nodes.Length];
199 tso.UpdateNodesWorld();
201 foreach (TSONode node in tso.nodes)
203 MqoBone bone = new MqoBone();
205 bone.name = node.ShortName;
206 bone.tail = node.children.Count == 0;
208 if (node.parent == null)
214 bone.pid = node.parent.id+1;
215 bones[node.parent.id].cids.Add(bone.id);
219 bone.q = node.world.Translation;
222 bone.p = node.children[0].world.Translation;
224 bone.p = node.world.Translation;
226 bones[node.id] = bone;
232 public class MqoObjectGen
234 public static bool uid_enabled;
236 public int id; //object_id
238 Heap<UVertex> vh = new Heap<UVertex>();
239 public List<MqoFace> faces;
241 public int numvertices { get { return vh.Count; } }
242 public List<UVertex> vertices { get { return vh.ary; } }
243 public int numfaces { get { return faces.Count; } }
245 public MqoObjectGen()
247 faces = new List<MqoFace>(2048);
250 public void Update(TSOMesh mesh)
255 foreach (TSOSubMesh sub_mesh in mesh.sub_meshes)
258 ushort a = 0, b = 0, c = 0;
259 Vertex va = new Vertex(), vb = new Vertex(), vc = new Vertex();
261 foreach (Vertex v in sub_mesh.vertices)
266 vc = v; c = vh.Add(new UVertex(v.Pos, v.Wgt, v.Idx, v.Nrm));
268 if (cnt < 3) continue;
269 if (a == b || b == c || c == a) continue;
273 MqoFace f = new MqoFace(a, b, c, (ushort)sub_mesh.spec,
274 new Point2(va.Tex.x, 1 - va.Tex.y),
275 new Point2(vb.Tex.x, 1 - vb.Tex.y),
276 new Point2(vc.Tex.x, 1 - vc.Tex.y));
281 MqoFace f = new MqoFace(a, c, b, (ushort)sub_mesh.spec,
282 new Point2(va.Tex.x, 1 - va.Tex.y),
283 new Point2(vc.Tex.x, 1 - vc.Tex.y),
284 new Point2(vb.Tex.x, 1 - vb.Tex.y));
291 public void Write(TextWriter tw)
293 tw.WriteLine("Object \"{0}\" {{", name);
295 tw.WriteLine("\tuid {0}", id);
296 tw.WriteLine("\tvisible {0}", 15);
297 tw.WriteLine("\tlocking {0}", 0);
298 tw.WriteLine("\tshading {0}", 1);
299 tw.WriteLine("\tfacet {0}", 59.5);
300 tw.WriteLine("\tcolor {0:F3} {1:F3} {2:F3}", 0.898f, 0.498f, 0.698f);
301 tw.WriteLine("\tcolor_type {0}", 0);
304 tw.WriteLine("\tvertex {0} {{", numvertices);
306 foreach (UVertex v in vertices)
313 tw.WriteLine("\tvertexattr {");
314 tw.WriteLine("\t\tuid {");
316 ushort vertex_id = 0;
317 foreach (UVertex v in vertices)
318 tw.WriteLine("\t\t\t{0}", ++vertex_id);
320 tw.WriteLine("\t\t}");
325 tw.WriteLine("\tface {0} {{", numfaces);
327 for (int i = 0, n = numfaces; i < n; i++)
333 public unsafe void AddWeits(MqoBone[] bones)
335 ushort vertex_id = 0;
336 foreach (UVertex v in vertices)
341 byte* idx = (byte*)(&idx0);
343 float* wgt = (float*)(&wgt0);
345 for (int k = 0; k < 4; ++k)
346 if (wgt[k] > float.Epsilon)
348 MqoWeit weit = new MqoWeit();
350 weit.vertex_id = vertex_id;
352 bones[idx[k]].weits.Add(weit);