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
        }