//~SceneAnimator(){ Release(); }
        void Init(Scene pScene)
        {
            // this must be called to fill the SceneAnimator with valid data
            if(!pScene.HasAnimations)
                return;
            Release();

            Skeleton = CreateBoneTree(pScene.RootNode, null);
            ExtractAnimations(pScene);

            for (int i = 0; i < pScene.MeshCount; ++i)
            {
                Mesh mesh = pScene.Meshes[i];

                for (int n = 0; n < mesh.BoneCount; ++n)
                {
                    Bone bone = mesh.Bones[n];
                    //std::map<std::string, cBone*>::iterator found = BonesByName.find(bone->mName.data);
                    if(BonesByName.ContainsKey(bone.Name))
                    {
                        // FOUND IT!!! woohoo, make sure its not already in the bone list
                        bool skip = false;
                        for(int j = 0; j < Bones.Count; j++)
                        {
                            string bname = bone.Name;
                            if(Bones[j].Name == bname)
                            {
                                skip = true;// already inserted, skip this so as not to insert the same bone multiple times
                                break;
                            }
                        }
                        if(!skip)
                        {
                            // only insert the bone if it has not already been inserted
                            var found = BonesByName[bone.Name];
                            string tes = found.Name;

                            //this line may require a custom TransposeMatrix function
                            found.Offset = bone.OffsetMatrix;
                            found.Offset.Transpose(); // transpose their matrix to get in the correct format
                            Bones.Add(found);
                            BonesToIndex[bone.Name] = Bones.Count()-1;
                        }
                    }
                }
            }
            float timestep = 1.0f/30.0f;// 30 per second
            for(int i = 0; i< Animations.Count(); i++)
            {
                // pre calculate the animations
                SetAnimIndex(i);
                float dt = 0;
                for(float ticks = 0; ticks < Animations[i].Duration; ticks += Animations[i].TicksPerSecond/30.0f)
                {
                    dt +=timestep;
                    Calculate(dt);
                    List<Matrix4x4> trans = new List<Matrix4x4>();
                    for (int a = 0; a < Transforms.Count(); ++a)
                    {
                        Matrix4x4 rotationMatrix = Bones[a].Offset * Bones[a].GlobalTransform;
                        trans.Add(rotationMatrix);
                    }
                    Animations[i].Transforms.Add(trans);
                }
            }
            //OUTPUT_DEBUG_MSG("Finished loading animations with "<<Bones.size()<<" bones");
        }
        /*protected cBone LoadSkeleton(StreamReader file, cBone pNode)
        {
            cBone* internalNode = new cBone();// create a node
            internalNode->Parent = parent; //set the parent, in the case this is theroot node, it will be null
            uint32_t nsize=0;
            file.read(reinterpret_cast<char*>(&nsize), sizeof(uint32_t));// the number of chars
            char temp[250];
            file.read(temp, nsize);// the name of the bone
            temp[nsize]=0;
            internalNode->Name = temp;
            BonesByName[internalNode->Name] = internalNode;// use the name as a key
            file.read(reinterpret_cast<char*>(&internalNode->Offset), sizeof(internalNode->Offset));// the bone offsets
            file.read(reinterpret_cast<char*>(&internalNode->OriginalLocalTransform), sizeof(internalNode->OriginalLocalTransform));// original bind pose

            internalNode->LocalTransform = internalNode->OriginalLocalTransform;// a copy saved
            CalculateBoneToWorldTransform(internalNode);

            file.read(reinterpret_cast<char*>(&nsize), sizeof(uint32_t));// the number of children

            // continue for all child nodes and assign the created internal nodes as our children
            for( unsigned int a = 0; a < nsize && file; a++){// recursivly call this function on all children
                internalNode->Children.push_back(LoadSkeleton(file, internalNode));
            }
            return internalNode;
        }*/
        protected void UpdateTransforms(cBone pNode)
        {
            CalculateBoneToWorldTransform(pNode);
            // update global transform as well
            foreach(cBone c in pNode.Children)
            {
                UpdateTransforms(c);
            }
        }
 protected void SaveSkeleton(StreamWriter file, cBone pNode)
 {
 }
        protected cBone CreateBoneTree(Node pNode, cBone pParent)
        {
            // Recursively creates an internal node structure matching the current scene and animation.
               	cBone internalNode = new cBone();// create a node
            internalNode.Name = pNode.Name; // get the name of the bone
            internalNode.Parent = pParent; //set the parent, in the case this is theroot node, it will be null

            BonesByName[internalNode.Name] = internalNode; // use the name as a key

            //this may require a custom MatrixTranpose function
            internalNode.LocalTransform = pNode.Transform;
            internalNode.LocalTransform.Transpose();
            internalNode.OriginalLocalTransform = internalNode.LocalTransform;// a copy saved
            CalculateBoneToWorldTransform(internalNode);
            // continue for all child nodes and assign the created internal nodes as our children
            for(int a = 0; a < pNode.ChildCount; a++)
            {// recursivly call this function on all children
                internalNode.Children.Add(CreateBoneTree(pNode.Children[a], internalNode));
            }
            return internalNode;
        }
 protected void CalculateBoneToWorldTransform(cBone child)
 {
     /** Calculates the global transformation matrix for the given internal node */
     child.GlobalTransform = child.LocalTransform;
     cBone parent = child.Parent;
     while (parent != null)
     {// this will climb the nodes up along through the parents concentating all the matrices to get the Object to World transform, or in this case, the Bone To World transform
         child.GlobalTransform *= parent.LocalTransform;
         parent = parent.Parent;// get the parent of the bone we are working on
     }
 }
 public cBone()
 {
     Parent = null;
 }