2 using System.Collections.Generic;
\r
5 using System.Text.RegularExpressions;
\r
11 private delegate bool SectionHandler(string[] tokens);
\r
13 public static char[] delimiters = new char[]{' ', '\t'};
\r
14 public static char[] delimiters2 = new char[]{' ', '\t', '(', ')'};
\r
16 private string file;
\r
17 private StreamReader sr;
\r
18 private MqoScene scene;
\r
19 private List<MqoMaterial> materials;
\r
20 private List<MqoObject> objects = new List<MqoObject>();
\r
21 private MqoObject current;
\r
23 public MqoScene Scene { get { return scene; } }
\r
24 public List<MqoMaterial> Materials { get { return materials; } }
\r
25 public List<MqoObject> Objects { get { return objects; } }
\r
27 public void Load(string file)
\r
29 using(FileStream fs= File.OpenRead(file))
\r
32 sr = new StreamReader(fs, Encoding.Default);
\r
39 System.Diagnostics.Debug.WriteLine(file);
\r
40 System.Diagnostics.Debug.WriteLine(scene);
\r
42 foreach(MqoMaterial i in materials)
\r
43 System.Diagnostics.Debug.WriteLine(i);
\r
45 foreach(MqoObject i in objects)
\r
46 System.Diagnostics.Debug.WriteLine(i);
\r
49 public void ReadAll()
\r
51 DoRead(SectionRoot);
\r
54 private static string[] SplitString(string s)
\r
56 List<string> tokens = new List<string>();
\r
57 StringBuilder sb = new StringBuilder(s.Length);
\r
59 bool escape = false;
\r
60 bool bracket= false;
\r
61 s = s.Trim(' ', '\t', '\r', '\n');
\r
63 foreach(char i in s)
\r
76 if(str) sb.Append(i);
\r
81 if(bracket) {sb.Append(i); }
\r
82 else if(str) {sb.Append(i); }
\r
83 else if(sb.Length > 0) {tokens.Add(sb.ToString()); sb.Length= 0; }
\r
106 tokens.Add(sb.ToString());
\r
108 return tokens.ToArray();
\r
111 private void DoRead(SectionHandler h)
\r
113 for(int no= 1;; ++no)
\r
115 string line= sr.ReadLine();
\r
120 line = line.Trim();
\r
121 string[] tokens = SplitString(line);
\r
125 if(tokens.Length == 0)
\r
130 } catch(Exception e)
\r
132 string msg = string.Format("File format error: {0} \"{1}\"", no, line);
\r
133 throw new Exception(msg, e);
\r
138 public void Error(string[] tokens)
\r
140 throw new Exception("File Format Error: \"" + string.Concat(tokens) + "\"");
\r
143 private bool SectionRoot(string[] tokens)
\r
145 switch(tokens[0].ToLower())
\r
147 case "metasequoia": ParseMetasequoia(tokens); return true;
\r
148 case "format": ParseFormat (tokens); return true;
\r
149 case "scene": ParseScene (tokens); return true;
\r
150 case "material": ParseMaterial (tokens); return true;
\r
151 case "object": ParseObject (tokens); return true;
\r
152 case "eof": return false;
\r
153 //default: Error(tokens); return false;
\r
154 default: return true;
\r
158 private bool SectionScene(string[] tokens)
\r
160 scene = new MqoScene();
\r
162 switch(tokens[0].ToLower())
\r
164 case "pos": scene.pos = Point3.Parse(tokens, 1); return true;
\r
165 case "lookat": scene.lookat = Point3.Parse(tokens, 1); return true;
\r
166 case "head": scene.head = float .Parse(tokens[1]); return true;
\r
167 case "pich": scene.pich = float .Parse(tokens[1]); return true;
\r
168 case "ortho": scene.ortho = float .Parse(tokens[1]); return true;
\r
169 case "zoom2": scene.zoom2 = float .Parse(tokens[1]); return true;
\r
170 case "amb": scene.amb = Color3.Parse(tokens, 1); return true;
\r
171 case "}": return false;
\r
172 //default: Error(tokens); return false;
\r
173 default: return true;
\r
177 private static string[] SplitParam(string s)
\r
179 return s.Split(delimiters2, StringSplitOptions.RemoveEmptyEntries);
\r
182 private bool SectionMaterial(string[] tokens)
\r
184 if(tokens[0] == "}")
\r
187 StringBuilder sb = new StringBuilder();
\r
189 foreach(string i in tokens)
\r
190 sb.Append(' ').Append(i);
\r
192 string line= sb.ToString().Trim();
\r
193 MqoMaterial m = new MqoMaterial(tokens[0].Trim('"'));
\r
194 tokens = SplitString(line);
\r
197 for(int i= 1 ; i < tokens.Length; ++i)
\r
199 string t = tokens[i];
\r
200 string t2 = t.ToLower();
\r
202 if(t2.StartsWith("shader(")) m.shader = int .Parse(SplitParam(t)[1]);
\r
203 else if(t2.StartsWith("col(")) m.col = Color3.Parse(SplitParam(t), 1);
\r
204 else if(t2.StartsWith("dif(")) m.dif = float .Parse(SplitParam(t)[1]);
\r
205 else if(t2.StartsWith("amb(")) m.amb = float .Parse(SplitParam(t)[1]);
\r
206 else if(t2.StartsWith("emi(")) m.emi = float .Parse(SplitParam(t)[1]);
\r
207 else if(t2.StartsWith("spc(")) m.spc = float .Parse(SplitParam(t)[1]);
\r
208 else if(t2.StartsWith("power(")) m.power = float .Parse(SplitParam(t)[1]);
\r
209 else if(t2.StartsWith("tex(")) m.tex = t.Substring(3).Trim('(', ')', '"');
\r
215 private bool SectionObject(string[] tokens)
\r
217 switch(tokens[0].ToLower())
\r
219 case "visible": current.visible = int .Parse(tokens[1]); return true;
\r
220 case "locking": current.locking = int .Parse(tokens[1]); return true;
\r
221 case "shading": current.shading = int .Parse(tokens[1]); return true;
\r
222 case "facet": current.facet = float .Parse(tokens[1]); return true;
\r
223 case "color": current.color = Color3.Parse(tokens, 1); return true;
\r
224 case "color_type": current.color_type = int .Parse(tokens[1]); return true;
\r
225 case "vertex": ParseVertex(tokens); return true;
\r
226 case "face": ParseFace(tokens); return true;
\r
227 case "}": return false;
\r
228 //default: Error(tokens); return false;
\r
229 default: return true;
\r
233 private bool SectionVertex(string[] tokens)
\r
235 if(tokens[0] == "}")
\r
238 current.vertices.Add(Point3.Parse(tokens, 0));
\r
243 private bool SectionFace(string[] tokens)
\r
245 if(tokens[0] == "}")
\r
248 if(3 != int.Parse(tokens[0]))
\r
251 StringBuilder sb = new StringBuilder();
\r
253 foreach(string i in tokens)
\r
254 sb.Append(' ').Append(i);
\r
256 string line= sb.ToString().Trim();
\r
257 MqoFace f = new MqoFace();
\r
258 tokens = SplitString(line);
\r
259 current.faces.Add(f);
\r
261 for(int i= 1 ; i < tokens.Length; ++i)
\r
263 string t = tokens[i];
\r
264 string t2 = t.ToLower();
\r
266 if(t2.StartsWith("v("))
\r
268 string[] t3 = SplitParam(t);
\r
269 f.a = ushort.Parse(t3[1]);
\r
270 f.b = ushort.Parse(t3[2]);
\r
271 f.c = ushort.Parse(t3[3]);
\r
273 if(t2.StartsWith("m("))
\r
275 string[] t3 = SplitParam(t);
\r
276 f.mtl = ushort.Parse(t3[1]);
\r
278 if(t2.StartsWith("uv("))
\r
280 string[] t3 = SplitParam(t);
\r
281 f.ta = Point2.Parse(t3, 1);
\r
282 f.tb = Point2.Parse(t3, 3);
\r
283 f.tc = Point2.Parse(t3, 5);
\r
290 //----- Root elements ----------------------------------------------
\r
291 private void ParseMetasequoia(string[] tokens)
\r
293 if(tokens[1].ToLower() != "document") Error(tokens);
\r
296 private void ParseFormat(string[] tokens)
\r
298 if(tokens[1].ToLower() != "text") Error(tokens);
\r
299 if(tokens[2].ToLower() != "ver") Error(tokens);
\r
300 if(tokens[3].ToLower() != "1.0") Error(tokens);
\r
303 private void ParseScene(string[] tokens)
\r
305 if(tokens[1].ToLower() != "{") Error(tokens);
\r
307 DoRead(SectionScene);
\r
310 private void ParseMaterial(string[] tokens)
\r
312 if(tokens[2].ToLower() != "{") Error(tokens);
\r
314 materials = new List<MqoMaterial>(int.Parse(tokens[1]));
\r
315 DoRead(SectionMaterial);
\r
318 private void ParseObject(string[] tokens)
\r
320 if(tokens[2].ToLower() != "{") Error(tokens);
\r
322 current = new MqoObject(tokens[1].Trim('"'));
\r
323 objects.Add(current);
\r
324 DoRead(SectionObject);
\r
327 private void ParseVertex(string[] tokens)
\r
329 if(tokens[2].ToLower() != "{") Error(tokens);
\r
331 current.vertices = new List<Point3>(int.Parse(tokens[1]));
\r
332 DoRead(SectionVertex);
\r
335 private void ParseFace(string[] tokens)
\r
337 if(tokens[2].ToLower() != "{") Error(tokens);
\r
339 current.faces = new List<MqoFace>(int.Parse(tokens[1]));
\r
340 DoRead(SectionFace);
\r
344 public class MqoScene
\r
347 public Point3 lookat;
\r
350 public float ortho;
\r
351 public float zoom2;
\r
354 public override string ToString()
\r
356 return (new StringBuilder(256))
\r
357 .Append(" pos: ") .Append(pos)
\r
358 .Append(" lookat: ").Append(lookat)
\r
359 .Append(" head: ") .Append(head)
\r
360 .Append(" pich: ") .Append(pich)
\r
361 .Append(" ortho: ") .Append(ortho)
\r
362 .Append(" zoom2: ") .Append(zoom2)
\r
363 .Append(" amb: ") .Append(amb)
\r
368 public class MqoMaterial
\r
370 public string name;
\r
377 public float power;
\r
380 public MqoMaterial() { }
\r
381 public MqoMaterial(string n) { name= n; }
\r
383 public override string ToString()
\r
385 return (new StringBuilder(256))
\r
386 .Append(" shader: ").Append(shader)
\r
387 .Append(" col: ") .Append(col)
\r
388 .Append(" dif: ") .Append(dif)
\r
389 .Append(" amb: ") .Append(amb)
\r
390 .Append(" emi: ") .Append(emi)
\r
391 .Append(" spc: ") .Append(spc)
\r
392 .Append(" power: ") .Append(power)
\r
393 .Append(" tex: ") .Append(tex)
\r
394 .Append(" name: ") .Append(name)
\r
399 public class MqoObject
\r
401 public string name;
\r
402 public int visible;
\r
403 public int locking;
\r
404 public int shading;
\r
405 public float facet;
\r
406 public Color3 color;
\r
407 public int color_type;
\r
408 public List<Point3> vertices;
\r
409 public List<MqoFace> faces;
\r
411 public MqoObject() { }
\r
412 public MqoObject(string n) { name= n; }
\r
414 public override string ToString()
\r
416 return (new StringBuilder(256))
\r
417 .Append(" visible: ") .Append(visible)
\r
418 .Append(" locking: ") .Append(locking)
\r
419 .Append(" shading: ") .Append(shading)
\r
420 .Append(" facet: ") .Append(facet)
\r
421 .Append(" color: ") .Append(color)
\r
422 .Append(" color_type: ").Append(color_type)
\r
423 .Append(" vertices: ") .Append(vertices.Count)
\r
424 .Append(" faces: ") .Append(faces.Count)
\r
425 .Append(" name: ") .Append(name)
\r
430 public class MqoFace
\r
432 public ushort a, b, c, mtl;
\r
433 public Point2 ta, tb, tc;
\r
439 public MqoFace(ushort a, ushort b, ushort c, ushort mtl, Point2 ta, Point2 tb, Point2 tc)
\r
450 public override string ToString()
\r
452 return (new StringBuilder(256))
\r
453 .Append("v: ") .Append(a).Append(" ").Append(b).Append(" ").Append(c)
\r
454 .Append(" mtl: ").Append(mtl)
\r
455 .Append(" uv: ") .Append(ta).Append(" ").Append(tb).Append(" ").Append(tc)
\r