void ReadSkeleton(Tokenizer input, SortedList<int, List<ModelBoneAnimationFrame>> frames) { string text = input.GetNextToken(); while (text != "skeleton") text = input.GetNextToken(); int currTime = 0; timeStart = currTime; while (input.Peek() != "end") { text = input.GetNextToken(); if (text == "time") { currTime = int.Parse(input.GetNextToken()); if (currTime > timeEnd && timeEnd > -1) { currTime = (int)timeEnd; break; } } else { int boneID = int.Parse(text); Vector3 posDisp; posDisp.X = float.Parse(input.GetNextToken()); posDisp.Y = float.Parse(input.GetNextToken()); posDisp.Z = float.Parse(input.GetNextToken()); Vector3 rotDisp; rotDisp.X = float.Parse(input.GetNextToken()); rotDisp.Y = float.Parse(input.GetNextToken()); rotDisp.Z = float.Parse(input.GetNextToken()); ModelBoneAnimationFrame frame = new ModelBoneAnimationFrame(); frame.Position = posDisp; frame.Rotation = rotDisp; frame.time = currTime; if (!frames.ContainsKey(boneID)) frames.Add(boneID, new List<ModelBoneAnimationFrame>()); frames[boneID].Add(frame); } } timeEnd = currTime; fps = 24; }
void ReadSMD(string filename) { using (FileStream fs = new FileStream(filename, FileMode.Open)) { using (StreamReader reader = new StreamReader(fs)) { Tokenizer tokenizer = new Tokenizer(reader); SortedList<int, string> nodesToNames = new SortedList<int,string>(); ReadNodes(tokenizer, nodesToNames); SortedList<int, List<ModelBoneAnimationFrame>> frames = new SortedList<int,List<ModelBoneAnimationFrame>>(); ReadSkeleton(tokenizer, frames); SortedList<string, AnimationNode> nodes; SortedList<string, char> rootNodes = new SortedList<string, char>(); AnimationNode[] roots = mesh.GetRootNodes(out nodes); for (int i = 0; i < roots.Length; i++) { rootNodes.Add(roots[i].Name, '1'); } animationFrames = new SortedList<string, ModelBoneAnimationFrame[]>(); for (int i = 0; i < frames.Keys.Count; i++) { int currKey = frames.Keys[i]; string currName = nodesToNames[currKey]; animationFrames.Add(currName, frames[currKey].ToArray()); for (int j = 0; j < animationFrames[currName].Length; j++) { animationFrames[currName][j].boneName = currName; if (rootNodes.ContainsKey(currName)) { if (recenterRoots) animationFrames[currName][j].Position = nodes[currName].Translation; } animationFrames[currName][j].Position -= nodes[currName].Translation; animationFrames[currName][j].Rotation -= nodes[currName].Rotation; Vector3 rot = animationFrames[currName][j].Rotation; animationFrames[currName][j].Rotation = new Vector3(MathHelper.WrapAngle(rot.X), MathHelper.WrapAngle(rot.Y), MathHelper.WrapAngle(rot.Z)); } } } } }
void ReadNodes(Tokenizer input, SortedList<int, string> nodesToNames) { string text = input.GetNextToken(); while (text != "nodes") text = input.GetNextToken(); while (input.Peek() != "end") { int id = int.Parse(input.GetNextToken()); string name = input.GetNextToken(); int temp = 0; while (!int.TryParse(input.Peek(), out temp)) name += " " + input.GetNextToken(); name = name.Substring(1, name.Length - 2); nodesToNames.Add(id, name); input.GetNextToken(); // the parent index (not important) } input.GetNextToken(); //read over the end }