2 using System.Collections.Generic;
5 using System.Text.RegularExpressions;
11 private delegate bool SectionHandler(string[] tokens);
13 public static char[] delimiters = new char[] { ' ', '\t' };
14 public static char[] delimiters2 = new char[] { ' ', '\t', '(', ')' };
17 private StreamReader sr;
18 private MqoScene scene;
19 private List<MqoMaterial> materials;
20 private List<MqoObject> objects = new List<MqoObject>();
21 private MqoObject current;
23 public MqoScene Scene { get { return scene; } }
24 public List<MqoMaterial> Materials { get { return materials; } }
25 public List<MqoObject> Objects { get { return objects; } }
27 public void Load(string file)
29 using (FileStream fs = File.OpenRead(file))
32 sr = new StreamReader(fs, Encoding.Default);
39 System.Diagnostics.Debug.WriteLine(file);
40 System.Diagnostics.Debug.WriteLine(scene);
42 foreach (MqoMaterial i in materials)
43 System.Diagnostics.Debug.WriteLine(i);
45 foreach (MqoObject i in objects)
46 System.Diagnostics.Debug.WriteLine(i);
54 private static string[] SplitString(string s)
56 List<string> tokens = new List<string>();
57 StringBuilder sb = new StringBuilder(s.Length);
61 s = s.Trim(' ', '\t', '\r', '\n');
76 if (str) sb.Append(i);
81 if (bracket) { sb.Append(i); }
82 else if (str) { sb.Append(i); }
83 else if (sb.Length > 0) { tokens.Add(sb.ToString()); sb.Length = 0; }
106 tokens.Add(sb.ToString());
108 return tokens.ToArray();
111 private void DoRead(SectionHandler h)
113 for (int no = 1; ; ++no)
115 string line = sr.ReadLine();
121 string[] tokens = SplitString(line);
125 if (tokens.Length == 0)
131 catch (Exception exception)
133 string msg = string.Format("File format error: {0} \"{1}\"", no, line);
134 throw new Exception(msg, exception);
139 public void Error(string[] tokens)
141 throw new Exception("File Format Error: \"" + string.Concat(tokens) + "\"");
144 private bool SectionRoot(string[] tokens)
146 switch (tokens[0].ToLower())
148 case "metasequoia": ParseMetasequoia(tokens); return true;
149 case "format": ParseFormat(tokens); return true;
150 case "scene": ParseScene(tokens); return true;
151 case "material": ParseMaterial(tokens); return true;
152 case "object": ParseObject(tokens); return true;
153 case "eof": return false;
154 //default: Error(tokens); return false;
155 default: return true;
159 private bool SectionScene(string[] tokens)
161 scene = new MqoScene();
163 switch (tokens[0].ToLower())
165 case "pos": scene.pos = Point3.Parse(tokens, 1); return true;
166 case "lookat": scene.lookat = Point3.Parse(tokens, 1); return true;
167 case "head": scene.head = float.Parse(tokens[1]); return true;
168 case "pich": scene.pich = float.Parse(tokens[1]); return true;
169 case "ortho": scene.ortho = float.Parse(tokens[1]); return true;
170 case "zoom2": scene.zoom2 = float.Parse(tokens[1]); return true;
171 case "amb": scene.amb = Color3.Parse(tokens, 1); return true;
172 case "}": return false;
173 //default: Error(tokens); return false;
174 default: return true;
178 private static string[] SplitParam(string s)
180 return s.Split(delimiters2, StringSplitOptions.RemoveEmptyEntries);
183 private bool SectionMaterial(string[] tokens)
185 if (tokens[0] == "}")
188 StringBuilder sb = new StringBuilder();
190 foreach (string i in tokens)
191 sb.Append(' ').Append(i);
193 string line = sb.ToString().Trim();
194 MqoMaterial m = new MqoMaterial(tokens[0].Trim('"'));
195 tokens = SplitString(line);
198 for (int i = 1; i < tokens.Length; ++i)
200 string t = tokens[i];
201 string t2 = t.ToLower();
203 if (t2.StartsWith("shader(")) m.shader = int.Parse(SplitParam(t)[1]);
204 else if (t2.StartsWith("col(")) m.col = Color3.Parse(SplitParam(t), 1);
205 else if (t2.StartsWith("dif(")) m.dif = float.Parse(SplitParam(t)[1]);
206 else if (t2.StartsWith("amb(")) m.amb = float.Parse(SplitParam(t)[1]);
207 else if (t2.StartsWith("emi(")) m.emi = float.Parse(SplitParam(t)[1]);
208 else if (t2.StartsWith("spc(")) m.spc = float.Parse(SplitParam(t)[1]);
209 else if (t2.StartsWith("power(")) m.power = float.Parse(SplitParam(t)[1]);
210 else if (t2.StartsWith("tex(")) m.tex = t.Substring(3).Trim('(', ')', '"');
216 private bool SectionObject(string[] tokens)
218 switch (tokens[0].ToLower())
220 case "visible": current.visible = int.Parse(tokens[1]); return true;
221 case "locking": current.locking = int.Parse(tokens[1]); return true;
222 case "shading": current.shading = int.Parse(tokens[1]); return true;
223 case "facet": current.facet = float.Parse(tokens[1]); return true;
224 case "color": current.color = Color3.Parse(tokens, 1); return true;
225 case "color_type": current.color_type = int.Parse(tokens[1]); return true;
226 case "vertex": ParseVertex(tokens); return true;
227 case "face": ParseFace(tokens); return true;
228 case "}": return false;
229 //default: Error(tokens); return false;
230 default: return true;
234 private bool SectionVertex(string[] tokens)
236 if (tokens[0] == "}")
239 current.vertices.Add(Point3.Parse(tokens, 0));
244 private bool SectionFace(string[] tokens)
246 if (tokens[0] == "}")
249 int nface = int.Parse(tokens[0]);
251 StringBuilder sb = new StringBuilder();
252 foreach (string i in tokens)
253 sb.Append(' ').Append(i);
254 string line = sb.ToString().Trim();
255 tokens = SplitString(line);
261 MqoFace f = new MqoFace();
263 for (int i = 1; i < tokens.Length; ++i)
265 string t = tokens[i];
266 string t2 = t.ToLower();
268 if (t2.StartsWith("v("))
270 string[] t3 = SplitParam(t);
271 f.a = ushort.Parse(t3[1]);
272 f.b = ushort.Parse(t3[2]);
273 f.c = ushort.Parse(t3[3]);
276 if (t2.StartsWith("m("))
278 string[] t3 = SplitParam(t);
279 f.mtl = ushort.Parse(t3[1]);
282 if (t2.StartsWith("uv("))
284 string[] t3 = SplitParam(t);
285 f.ta = Point2.Parse(t3, 1);
286 f.tb = Point2.Parse(t3, 3);
287 f.tc = Point2.Parse(t3, 5);
290 current.faces.Add(f);
295 MqoFace f = new MqoFace();
296 MqoFace f2 = new MqoFace();
298 for (int i = 1; i < tokens.Length; ++i)
300 string t = tokens[i];
301 string t2 = t.ToLower();
303 if (t2.StartsWith("v("))
305 string[] t3 = SplitParam(t);
306 f.a = ushort.Parse(t3[1]);
307 f.b = ushort.Parse(t3[2]);
308 f.c = ushort.Parse(t3[3]);
311 f2.c = ushort.Parse(t3[4]);
314 if (t2.StartsWith("m("))
316 string[] t3 = SplitParam(t);
317 f.mtl = ushort.Parse(t3[1]);
321 if (t2.StartsWith("uv("))
323 string[] t3 = SplitParam(t);
324 f.ta = Point2.Parse(t3, 1);
325 f.tb = Point2.Parse(t3, 3);
326 f.tc = Point2.Parse(t3, 5);
329 f2.tc = Point2.Parse(t3, 7);
332 current.faces.Add(f);
333 current.faces.Add(f2);
340 //----- Root elements ----------------------------------------------
341 private void ParseMetasequoia(string[] tokens)
343 if (tokens[1].ToLower() != "document") Error(tokens);
346 private void ParseFormat(string[] tokens)
348 if (tokens[1].ToLower() != "text") Error(tokens);
349 if (tokens[2].ToLower() != "ver") Error(tokens);
350 if (tokens[3].ToLower() != "1.0") Error(tokens);
353 private void ParseScene(string[] tokens)
355 if (tokens[1].ToLower() != "{") Error(tokens);
357 DoRead(SectionScene);
360 private void ParseMaterial(string[] tokens)
362 if (tokens[2].ToLower() != "{") Error(tokens);
364 materials = new List<MqoMaterial>(int.Parse(tokens[1]));
365 DoRead(SectionMaterial);
368 private void ParseObject(string[] tokens)
370 if (tokens[2].ToLower() != "{") Error(tokens);
372 current = new MqoObject(tokens[1].Trim('"'));
373 objects.Add(current);
374 DoRead(SectionObject);
377 private void ParseVertex(string[] tokens)
379 if (tokens[2].ToLower() != "{") Error(tokens);
381 current.vertices = new List<Point3>(int.Parse(tokens[1]));
382 DoRead(SectionVertex);
385 private void ParseFace(string[] tokens)
387 if (tokens[2].ToLower() != "{") Error(tokens);
389 current.faces = new List<MqoFace>(int.Parse(tokens[1]));
394 public class MqoScene
397 public Point3 lookat;
404 public override string ToString()
406 return (new StringBuilder(256))
407 .Append(" pos: ").Append(pos)
408 .Append(" lookat: ").Append(lookat)
409 .Append(" head: ").Append(head)
410 .Append(" pich: ").Append(pich)
411 .Append(" ortho: ").Append(ortho)
412 .Append(" zoom2: ").Append(zoom2)
413 .Append(" amb: ").Append(amb)
418 public class MqoMaterial
430 public MqoMaterial() { }
431 public MqoMaterial(string n) { name = n; }
433 public override string ToString()
435 return (new StringBuilder(256))
436 .Append(" shader: ").Append(shader)
437 .Append(" col: ").Append(col)
438 .Append(" dif: ").Append(dif)
439 .Append(" amb: ").Append(amb)
440 .Append(" emi: ").Append(emi)
441 .Append(" spc: ").Append(spc)
442 .Append(" power: ").Append(power)
443 .Append(" tex: ").Append(tex)
444 .Append(" name: ").Append(name)
449 public class MqoObject
457 public int color_type;
458 public List<Point3> vertices;
459 public List<MqoFace> faces;
461 public MqoObject() { }
462 public MqoObject(string n) { name = n; }
464 public override string ToString()
466 return (new StringBuilder(256))
467 .Append(" visible: ").Append(visible)
468 .Append(" locking: ").Append(locking)
469 .Append(" shading: ").Append(shading)
470 .Append(" facet: ").Append(facet)
471 .Append(" color: ").Append(color)
472 .Append(" color_type: ").Append(color_type)
473 .Append(" vertices: ").Append(vertices.Count)
474 .Append(" faces: ").Append(faces.Count)
475 .Append(" name: ").Append(name)
482 public ushort a, b, c, mtl;
483 public Point2 ta, tb, tc;
489 public MqoFace(ushort a, ushort b, ushort c, ushort mtl, Point2 ta, Point2 tb, Point2 tc)
500 public override string ToString()
502 return (new StringBuilder(256))
503 .Append("v: ").Append(a).Append(" ").Append(b).Append(" ").Append(c)
504 .Append(" mtl: ").Append(mtl)
505 .Append(" uv: ").Append(ta).Append(" ").Append(tb).Append(" ").Append(tc)