2 using System.Collections.Generic;
5 using System.Text.RegularExpressions;
11 delegate bool SectionHandler(string[] tokens);
13 static char[] param_delimiters = new char[] { ' ', '\t', '(', ')' };
18 List<MqoMaterial> materials;
19 List<MqoObject> objects = new List<MqoObject>();
22 public MqoScene Scene { get { return scene; } }
23 public List<MqoMaterial> Materials { get { return materials; } }
24 public List<MqoObject> Objects { get { return objects; } }
26 public void Load(string file)
28 using (FileStream fs = File.OpenRead(file))
31 sr = new StreamReader(fs, Encoding.Default);
41 static string[] SplitString(string s)
43 List<string> tokens = new List<string>();
44 StringBuilder sb = new StringBuilder(s.Length);
48 s = s.Trim(' ', '\t', '\r', '\n');
63 if (str) sb.Append(i);
68 if (bracket) { sb.Append(i); }
69 else if (str) { sb.Append(i); }
70 else if (sb.Length > 0) { tokens.Add(sb.ToString()); sb.Length = 0; }
93 tokens.Add(sb.ToString());
95 return tokens.ToArray();
98 void DoRead(SectionHandler h)
100 for (int lineno = 1; ; ++lineno)
102 string line = sr.ReadLine();
108 string[] tokens = SplitString(line);
112 if (tokens.Length == 0)
118 catch (Exception exception)
120 throw new Exception(string.Format("File format error: {0} \"{1}\"", lineno, line), exception);
125 public void Error(string[] tokens)
127 throw new Exception(string.Format("File Format Error: \"{0}\"", string.Concat(tokens)));
130 bool SectionRoot(string[] tokens)
136 // Metasequoia Document
137 if (tokens[1] != "Document")
144 // Format Text Ver 1.0
146 // Format Text Ver 1.1
147 if (tokens[1] != "Text")
149 if (tokens[2] != "Ver")
151 if (tokens[3] != "1.0" && tokens[3] != "1.1")
157 // Thumbnail 128 128 24 rgb raw {
160 if (tokens[6] != "{")
163 DoRead(SectionThumbnail);
168 if (tokens[1] != "{")
171 DoRead(SectionScene);
176 if (tokens[2] != "{")
179 materials = new List<MqoMaterial>(int.Parse(tokens[1]));
180 DoRead(SectionMaterial);
185 if (tokens[2] != "{")
188 current = new MqoObject(tokens[1].Trim('"'));
189 objects.Add(current);
190 DoRead(SectionObject);
200 bool SectionThumbnail(string[] tokens)
211 bool SectionScene(string[] tokens)
213 scene = new MqoScene();
217 case "pos": scene.pos = Point3.Parse(tokens, 1); return true;
218 case "lookat": scene.lookat = Point3.Parse(tokens, 1); return true;
219 case "head": scene.head = float.Parse(tokens[1]); return true;
220 case "pich": scene.pich = float.Parse(tokens[1]); return true;
221 case "ortho": scene.ortho = float.Parse(tokens[1]); return true;
222 case "zoom2": scene.zoom2 = float.Parse(tokens[1]); return true;
223 case "amb": scene.amb = Color3.Parse(tokens, 1); return true;
229 if (tokens[2] != "{")
232 DoRead(SectionDirlights);
242 bool SectionDirlights(string[] tokens)
251 if (tokens[1] != "{")
254 DoRead(SectionLight);
263 bool SectionLight(string[] tokens)
273 static string[] SplitParam(string s)
275 return s.Split(param_delimiters, StringSplitOptions.RemoveEmptyEntries);
278 bool SectionMaterial(string[] tokens)
280 if (tokens[0] == "}")
283 StringBuilder sb = new StringBuilder();
285 foreach (string i in tokens)
286 sb.Append(' ').Append(i);
288 string line = sb.ToString().Trim();
289 MqoMaterial m = new MqoMaterial(tokens[0].Trim('"'));
290 tokens = SplitString(line);
293 for (int i = 1; i < tokens.Length; ++i)
295 string t = tokens[i];
296 string t2 = t.ToLower();
298 if (t2.StartsWith("shader(")) m.shader = int.Parse(SplitParam(t)[1]);
299 else if (t2.StartsWith("col(")) m.col = Color3.Parse(SplitParam(t), 1);
300 else if (t2.StartsWith("dif(")) m.dif = float.Parse(SplitParam(t)[1]);
301 else if (t2.StartsWith("amb(")) m.amb = float.Parse(SplitParam(t)[1]);
302 else if (t2.StartsWith("emi(")) m.emi = float.Parse(SplitParam(t)[1]);
303 else if (t2.StartsWith("spc(")) m.spc = float.Parse(SplitParam(t)[1]);
304 else if (t2.StartsWith("power(")) m.power = float.Parse(SplitParam(t)[1]);
305 else if (t2.StartsWith("tex(")) m.tex = t.Substring(3).Trim('(', ')', '"');
311 bool SectionObject(string[] tokens)
315 case "visible": current.visible = int.Parse(tokens[1]); break;
316 case "locking": current.locking = int.Parse(tokens[1]); break;
317 case "shading": current.shading = int.Parse(tokens[1]); break;
318 case "facet": current.facet = float.Parse(tokens[1]); break;
319 case "color": current.color = Color3.Parse(tokens, 1); break;
320 case "color_type": current.color_type = int.Parse(tokens[1]); break;
323 if (tokens[2] != "{")
326 current.vertices = new List<UVertex>(int.Parse(tokens[1]));
327 DoRead(SectionVertex);
332 if (tokens[1] != "{")
335 DoRead(SectionVertexAttr);
340 if (tokens[2] != "{")
343 current.faces = new List<MqoFace>(int.Parse(tokens[1]));
353 bool SectionVertex(string[] tokens)
355 if (tokens[0] == "}")
358 UVertex v = new UVertex();
359 v.Pos = Point3.Parse(tokens, 0);
360 current.vertices.Add(v);
365 bool SectionVertexAttr(string[] tokens)
374 if (tokens[1] != "{")
386 bool SectionUid(string[] tokens)
396 bool SectionFace(string[] tokens)
398 if (tokens[0] == "}")
401 int nface = int.Parse(tokens[0]);
403 StringBuilder sb = new StringBuilder();
404 foreach (string i in tokens)
405 sb.Append(' ').Append(i);
406 string line = sb.ToString().Trim();
407 tokens = SplitString(line);
413 MqoFace f = new MqoFace();
415 for (int i = 1; i < tokens.Length; ++i)
417 string t = tokens[i];
418 string t2 = t.ToLower();
420 if (t2.StartsWith("v("))
422 string[] t3 = SplitParam(t);
423 f.a = ushort.Parse(t3[1]);
424 f.b = ushort.Parse(t3[2]);
425 f.c = ushort.Parse(t3[3]);
427 else if (t2.StartsWith("m("))
429 string[] t3 = SplitParam(t);
430 f.mtl = ushort.Parse(t3[1]);
432 else if (t2.StartsWith("uv("))
434 string[] t3 = SplitParam(t);
435 f.ta = Point2.Parse(t3, 1);
436 f.tb = Point2.Parse(t3, 3);
437 f.tc = Point2.Parse(t3, 5);
440 current.faces.Add(f);
445 MqoFace f = new MqoFace();
446 MqoFace f2 = new MqoFace();
448 for (int i = 1; i < tokens.Length; ++i)
450 string t = tokens[i];
451 string t2 = t.ToLower();
453 if (t2.StartsWith("v("))
455 string[] t3 = SplitParam(t);
456 f.a = ushort.Parse(t3[1]);
457 f.b = ushort.Parse(t3[2]);
458 f.c = ushort.Parse(t3[3]);
461 f2.c = ushort.Parse(t3[4]);
463 else if (t2.StartsWith("m("))
465 string[] t3 = SplitParam(t);
466 f.mtl = ushort.Parse(t3[1]);
469 else if (t2.StartsWith("uv("))
471 string[] t3 = SplitParam(t);
472 f.ta = Point2.Parse(t3, 1);
473 f.tb = Point2.Parse(t3, 3);
474 f.tc = Point2.Parse(t3, 5);
477 f2.tc = Point2.Parse(t3, 7);
480 current.faces.Add(f);
481 current.faces.Add(f2);
489 public class MqoScene
492 public Point3 lookat;
500 public class MqoMaterial
512 public MqoMaterial() { }
513 public MqoMaterial(string n) { name = n; }
516 public class MqoObject
524 public int color_type;
525 public List<UVertex> vertices;
526 public List<MqoFace> faces;
528 public MqoObject() { }
529 public MqoObject(string n) { name = n; }
534 public ushort a, b, c, mtl;
535 public Point2 ta, tb, tc;
541 public MqoFace(ushort a, ushort b, ushort c, ushort mtl, Point2 ta, Point2 tb, Point2 tc)
552 public void Write(TextWriter tw)
554 tw.WriteLine("\t\t{0} V({1} {2} {3}) M({10}) UV({4:F5} {5:F5} {6:F5} {7:F5} {8:F5} {9:F5})",
555 3, a, b, c, ta.x, ta.y, tb.x, tb.y, tc.x, tc.y, mtl);