void BuildSymbolTable() { LineSplitter ls = new LineSplitter(lines[state.LineNumber]); Dictionary <string, string> SymbolTable = new Dictionary <string, string>(); while (ls.Next() != "#endsymbols") { ls.Reset(); //split a name=value pair string[] kvp = ls.Next(true).Split('='); //check if exactly 2 pieces exist (name and value), this also conveniently ignores empty values if (kvp.Length == 2) { //if symbol exists, redefine it, else add to table if (SymbolTable.ContainsKey(kvp[0])) { SymbolTable[kvp[0]] = kvp[1]; } else { SymbolTable.Add(kvp[0], kvp[1]); } } state.LineNumber++; ls = new LineSplitter(lines[state.LineNumber]); } //make this table the current table LineSplitter.SymbolTable = SymbolTable; }
ModelPart ReadPart() { ModelPart result = new ModelPart(); LineSplitter ls = new LineSplitter(lines[state.LineNumber]); List <ModelVertex> vertices = new List <ModelVertex>(); while (ls.Next() != "#endpart") { ls.Reset(); switch (ls.Next()) { case "#beginpoints": { state.LineNumber++; result.SetVertices(this.ReadPoints()); break; } case "#beginmesh": { state.LineNumber++; result.SetIndices(this.ReadMesh()); break; } case "#texture": //TODO: set part's tex { result.TextureName = ls.NextQuoted(); if (!Textures.Contains(result.TextureName)) { Textures.Add(result.TextureName); } break; } case "#billboard": //TODO: turn into PartLight, set tex and bb type { result = ReadBB(ls); break; } default: //throw an error or something lol { break; } } state.LineNumber++; ls = new LineSplitter(lines[state.LineNumber]); } return(result); }
ModelVertex ReadPoint(LineSplitter ls) { ModelVertex v = new ModelVertex(); //read format X Y Z Colour U V W float X, Y, Z, U, V, W; Microsoft.Xna.Framework.Color c = new Microsoft.Xna.Framework.Color(); string[] rgb; X = ls.NextFloat(); Y = ls.NextFloat(); Z = ls.NextFloat(); rgb = ls.Next().Split(':'); c = new Microsoft.Xna.Framework.Color(int.Parse(rgb[0]), int.Parse(rgb[1]), int.Parse(rgb[2])); //c.A = 127; U = ls.NextFloat(); V = ls.NextFloat(); W = 1f; if (!ls.EOL) { W = ls.NextFloat(); } W += 0; v.Position = new Microsoft.Xna.Framework.Vector3(X, Y, Z); v.Color = c; v.TextureCoordinate = new Microsoft.Xna.Framework.Vector2(U, V); v.BoneWeightData.X = W; return(v); }
ModelPart ReadBB(LineSplitter ls) { ModelPart result = new ModelPart(); string type = ls.Next(); int H = ls.NextInt(); int W = ls.NextInt(); Color c; string[] rgb; rgb = ls.Next().Split(':'); c = new Microsoft.Xna.Framework.Color(int.Parse(rgb[0]), int.Parse(rgb[1]), int.Parse(rgb[2])); TestParts.PartLight p = new TestParts.PartLight(c); p.Width = W; p.Height = H; result = p; return(result); }
ModelVertex[] ReadPoints() { LineSplitter ls = new LineSplitter(lines[state.LineNumber]); List <ModelVertex> vertices = new List <ModelVertex>(); //keep reading points until end command while (ls.Next() != "#endpoints") { ls.Reset(); //rewind because of next vertices.Add(ReadPoint(ls)); //read point and add to list //prepare for next line state.LineNumber++; ls = new LineSplitter(lines[state.LineNumber]); } //flatten and return return(vertices.ToArray()); }
int[] ReadMesh() { LineSplitter ls = new LineSplitter(lines[state.LineNumber].Replace(',', ' ')); List <int> indices = new List <int>(); //keep going until end mesh command while (ls.Next() != "#endmesh") { //rewind because of next ls.Reset(); while (!ls.EOL) //read the rest of the line as ints { indices.Add(ls.NextInt()); } //prepare for next line state.LineNumber++; ls = new LineSplitter(lines[state.LineNumber].Replace(',', ' ')); } return(indices.ToArray()); }
void AssembleModel(Dictionary <string, ModelPart> parts) { LineSplitter ls = new LineSplitter(lines[state.LineNumber]); ModelPart root = new ModelPart(); Stack <ModelPart> TreeBuilder = new Stack <ModelPart>(); ModelPart last; Model Model; int depth; while (ls.Next() != "#endassembly") { ls.Reset(); string name = ""; string first = ls.Next(); //first token if (first[0] == '*') //if first character is *, count { depth = first.Length; } else //root part { depth = 0; ls.Reset(); //rewind } name = ls.NextQuoted(); //part "name" used in animation string partname = ls.Next(); if (!parts.ContainsKey(partname)) //find part by name from loaded parts { state.LineNumber++; ls = new LineSplitter(lines[state.LineNumber]); continue; //skip if invalid part } Matrix m = ls.NextTransform(); //get whatever transforms are there ModelPart next = (ModelPart)parts[partname].Clone(); //both cool with 0 as default next.Phase = ls.NextFloat(); next.BoneFactor = ls.NextFloat(); next.Title = name; //determine correct parent while (depth < TreeBuilder.Count) //go back part by part until correct part is found ( { TreeBuilder.Pop(); } if (depth != 0) //the stack is not empty and its top is the last parent { TreeBuilder.Peek().Append(next, m); } else { root = next; } TreeBuilder.Push(next); //put current as last parent state.LineNumber++; ls = new LineSplitter(lines[state.LineNumber]); } Model = new Model(root); Output = Model; R = root; }
public static Dictionary <string, Dictionary <string, PartAnimation> > LoadChoreo(string input) { Dictionary <string, Dictionary <string, PartAnimation> > result = new Dictionary <string, Dictionary <string, PartAnimation> >(); string[] filelines = SplitLines(input); int pointer = 0; Dictionary <string, PartAnimation> CurrentMove = new Dictionary <string, PartAnimation>(); string CurrentMoveName = ""; string CurrentPartName = ""; PartAnimation CurrentPart = new PartAnimation(); LineSplitter ls; while (pointer < filelines.Length) { ls = new LineSplitter(filelines[pointer]); string cmd = ls.Next(); switch (cmd) { case "#beginmove": { CurrentMove = new Dictionary <string, PartAnimation>(); CurrentMoveName = ls.NextQuoted(); break; } case "#endmove": { if (result.ContainsKey(CurrentMoveName)) { break; } result.Add(CurrentMoveName, CurrentMove); break; } case "#beginpart": { CurrentPart = new PartAnimation(); CurrentPartName = ls.NextQuoted(); break; } case "#endpart": { if (CurrentMove.ContainsKey(CurrentPartName)) { break; } CurrentMove.Add(CurrentPartName, CurrentPart); break; } case "#beginchoreo": { break; } case "#endchoreo": { break; } case "#moveparam": { break; } default: { ls.Reset(); float duration = ls.NextFloat(); Matrix transform = ls.NextTransform(); CurrentPart.Add(transform, duration); break; } } pointer++; } return(result); }
public ModelGeometryCompiler(string input) { this.lines = SplitLines(input); LineSplitter ls = new LineSplitter(lines[state.LineNumber]); Dictionary <string, ModelPart> parts = new Dictionary <string, ModelPart>(); List <ModelPart> p = new List <ModelPart>(); string choreoname = ""; Vector3 offset = Vector3.Zero; string command = ls.Next(); while (command != "#endmodel") { switch (command) { case "#beginpart": { state.LineNumber++; parts.Add(ls.NextQuoted(), ReadPart()); break; } case "#beginassembly": { AssembleModel(parts); break; } case "#beginsymbols": { state.LineNumber++; BuildSymbolTable(); break; } case "#choreo": { choreoname = ls.NextQuoted(); break; } case "#offset": { float X, Y, Z; X = ls.NextFloat(); Y = ls.NextFloat(); Z = ls.NextFloat(); offset = new Vector3(X, Y, Z); break; } default: { //throw error here or something break; } } state.LineNumber++; ls = new LineSplitter(lines[state.LineNumber]); command = ls.Next(); } string choreofname = ModelBaseDir + "\\" + choreoname + ".mcf"; //create a dummy if doesn't exist. Dumb workaround but works for now if (!System.IO.File.Exists(choreofname)) { System.IO.FileStream s = System.IO.File.Create(choreofname); s.Close(); } Output.Choreo = LoadChoreo(System.IO.File.ReadAllText(choreofname)); Output.ChoreoName = choreoname; Output.Offset = offset; ls = null; }