AnimationTransitPtr setupAnimation(const std::vector<Pnt3f>& Path, Transform* const transCore)
{
    //Transformation Keyframe Sequence
    KeyframeTransformationSequenceRecPtr TransformationKeyframes = KeyframeTransformationSequenceMatrix4f::create();
    Matrix TempMat;
    TempMat.setScale(0.06f);
    Real32 Speed(1.0f);
    Real32 SeqTime;
    Real32 TotalPathDistance(0.0f);
    for(UInt32 i(0) ; i<Path.size()-1 ; ++i)
    {
        TotalPathDistance += Path[i].dist(Path[(i+1)]);
    }

    Real32 CumPathDistance(0.0f);
    Quaternion Rotation;
    Vec3f Direction;
    for(UInt32 i(0) ; i<Path.size() ; ++i)
    {
        SeqTime = CumPathDistance / Speed;
        Direction = Path[(i+1)%Path.size()]-Path[i];
        Direction[1] = 0.0f;
        Direction.normalize();
        Rotation = Quaternion(Vec3f(0.0f,0.0f,1.0f),Direction);
        TempMat.setTransform(Vec3f(Path[i]),Rotation,Vec3f(0.1f,0.1f,0.1f));
        TransformationKeyframes->addKeyframe(TempMat,SeqTime);

        if(i<Path.size()-1)
        {
            CumPathDistance += Path[i].dist(Path[(i+1)]);
        }
    }

    //Animator
    KeyframeAnimatorRecPtr TheAnimator = KeyframeAnimator::create();
    TheAnimator->setKeyframeSequence(TransformationKeyframes);

    //Animation
    FieldAnimationRecPtr TheAnimation = FieldAnimation::create();
    TheAnimation->setAnimator(TheAnimator);
    TheAnimation->setInterpolationType(Animator::LINEAR_INTERPOLATION);
    TheAnimation->setCycling(1);
    TheAnimation->setAnimatedField(transCore, std::string("matrix"));

    return AnimationTransitPtr(TheAnimation);
}
AnimationTransitPtr setupAnimation(GradientBackground* const TutorialBackground)
{
    //Color Keyframe Sequence
    KeyframeColorSequenceUnrecPtr ColorKeyframes = KeyframeColorSequenceColor3f::create();
    ColorKeyframes->addKeyframe(Color4f(1.0f,0.0f,0.0f,1.0f),0.0f);
    ColorKeyframes->addKeyframe(Color4f(0.0f,1.0f,0.0f,1.0f),2.0f);
    ColorKeyframes->addKeyframe(Color4f(0.0f,0.0f,1.0f,1.0f),4.0f);
    ColorKeyframes->addKeyframe(Color4f(1.0f,0.0f,0.0f,1.0f),6.0f);

    //Animator
    KeyframeAnimatorUnrecPtr TheAnimator = KeyframeAnimator::create();
    TheAnimator->setKeyframeSequence(ColorKeyframes);

    //Animation
    FieldAnimationUnrecPtr TheAnimation = FieldAnimation::create();
    TheAnimation->setAnimator(TheAnimator);
    TheAnimation->setInterpolationType(Animator::LINEAR_INTERPOLATION);
    TheAnimation->setCycling(-1);
    TheAnimation->setAnimatedMultiField(TutorialBackground, std::string("color"), 1);

    TheAnimation->connectAnimationCycled(boost::bind(animationCycled, _1));
    return AnimationTransitPtr(TheAnimation);
}
AnimationTransitPtr setupAnimation(FieldContainer* const AnimatedObject,
                                   const std::string& AnimatedField)
{
    //Color Keyframe Sequence
    KeyframeVectorSequenceVec4fUnrecPtr ColorKeyframes = KeyframeVectorSequenceVec4f::create();
    ColorKeyframes->addRawKeyframe(Vec4f(1.0f,0.0f,0.0f,1.0f),0.0f);
    ColorKeyframes->addRawKeyframe(Vec4f(0.0f,1.0f,0.0f,1.0f),2.0f);
    ColorKeyframes->addRawKeyframe(Vec4f(0.0f,0.0f,1.0f,1.0f),4.0f);
    ColorKeyframes->addRawKeyframe(Vec4f(1.0f,0.0f,0.0f,1.0f),6.0f);

    //Animator
    KeyframeAnimatorUnrecPtr Animator = KeyframeAnimator::create();
    Animator->setKeyframeSequence(ColorKeyframes);

    //Animation
    FieldAnimationUnrecPtr ColorAnimation = FieldAnimation::create();
    ColorAnimation->setAnimator(Animator);
    ColorAnimation->setInterpolationType(Animator::LINEAR_INTERPOLATION);
    ColorAnimation->setCycling(-1);
    ColorAnimation->setAnimatedField(AnimatedObject, AnimatedField);

    return AnimationTransitPtr(ColorAnimation);
}
AnimationTransitPtr setupAnimation(ChunkMaterial* const TheBoxMaterial)
{
    std::vector<BoostPath> _ImagePaths;
    _ImagePaths.push_back(BoostPath("./Data/Anim001.jpg"));
    _ImagePaths.push_back(BoostPath("./Data/Anim002.jpg"));
    _ImagePaths.push_back(BoostPath("./Data/Anim003.jpg"));
    _ImagePaths.push_back(BoostPath("./Data/Anim004.jpg"));
    _ImagePaths.push_back(BoostPath("./Data/Anim005.jpg"));

    TextureSelectChunkRefPtr AnimSequenceTexture = TextureSelectChunk::create();
    AnimSequenceTexture->setChoice(0);

    //Make the textures
    for(UInt32 i(0) ; i<_ImagePaths.size(); ++i)
    {
        ImageRefPtr AnimFrameImage = ImageFileHandler::the()->read(_ImagePaths[i].string().c_str());

        TextureObjChunkRefPtr AnimFrameTexture = TextureObjChunk::create();
        AnimFrameTexture->setImage(AnimFrameImage);

        AnimSequenceTexture->pushToTextures(AnimFrameTexture);
    }

    //Box Material
    MaterialChunkUnrecPtr TheMaterialChunk = MaterialChunk::create();
    TheMaterialChunk->setAmbient(Color4f(0.4,0.4,0.4,1.0));
    TheMaterialChunk->setDiffuse(Color4f(0.8,0.8,0.8,1.0));
    TheMaterialChunk->setSpecular(Color4f(1.0,1.0,1.0,1.0));

    //Texture Env Chunk
    TextureEnvChunkRefPtr TexEnv = TextureEnvChunk::create();
    TexEnv->setEnvMode(GL_MODULATE);

    TheBoxMaterial->addChunk(AnimSequenceTexture);
    TheBoxMaterial->addChunk(TexEnv);
    TheBoxMaterial->addChunk(TheMaterialChunk);

    //Texture Keyframe Sequence
    KeyframeNumberSequenceUInt32RefPtr FrameChoiceKeyframes = KeyframeNumberSequenceUInt32::create();
    Real32 Rate(0.05f);
    for(UInt32 i(0) ; i<AnimSequenceTexture->getMFTextures()->size(); ++i)
    {
        FrameChoiceKeyframes->addRawKeyframe(i,static_cast<Real32>(i)*Rate);
    }
    for(UInt32 i(0) ; i<AnimSequenceTexture->getMFTextures()->size(); ++i)
    {
        FrameChoiceKeyframes->addRawKeyframe(AnimSequenceTexture->getMFTextures()->size()-i-1,
                                             static_cast<Real32>(i+AnimSequenceTexture->getMFTextures()->size())*Rate);
    }

    //Animator
    KeyframeAnimatorUnrecPtr TutorialTextureAnimator = KeyframeAnimator::create();
    TutorialTextureAnimator->setKeyframeSequence(FrameChoiceKeyframes);

    //Animation
    FieldAnimationUnrecPtr TutorialTextureAnimation = FieldAnimation::create();
    TutorialTextureAnimation->setAnimator(TutorialTextureAnimator);
    TutorialTextureAnimation->setInterpolationType(Animator::STEP_INTERPOLATION);
    TutorialTextureAnimation->setCycling(-1);
    TutorialTextureAnimation->setAnimatedField(AnimSequenceTexture,TextureSelectChunk::ChoiceFieldId);

    return AnimationTransitPtr(TutorialTextureAnimation);
}
AnimationTransitPtr setupAnimation(Transform* const transCore, WindowEventProducer* const win)
{
    //Number Keyframe Sequence
    KeyframeNumberSequenceRecPtr NumberKeyframes = KeyframeNumberSequenceReal32::create();
    NumberKeyframes->addKeyframe(1.0,0.0f);
    NumberKeyframes->addKeyframe(60.0,1.0f);
    NumberKeyframes->addKeyframe(20.0,2.0f);
    NumberKeyframes->addKeyframe(1.0,3.0f);
    
    //Color Keyframe Sequence
    KeyframeColorSequenceRecPtr ColorKeyframes = KeyframeColorSequenceColor3f::create();
    ColorKeyframes->addKeyframe(Color4f(1.0f,0.0f,0.0f,1.0f),0.0f);
    ColorKeyframes->addKeyframe(Color4f(0.0f,1.0f,0.0f,1.0f),2.0f);
    ColorKeyframes->addKeyframe(Color4f(0.0f,0.0f,1.0f,1.0f),4.0f);
    ColorKeyframes->addKeyframe(Color4f(1.0f,0.0f,0.0f,1.0f),6.0f);

    //Position Keyframe Sequence
    KeyframePositionSequenceRecPtr PositionKeyframes = KeyframePositionSequencePnt3f::create();
    PositionKeyframes->addKeyframe(Pnt3f(1.0f,1.0f,1.0f),0.0f);
    PositionKeyframes->addKeyframe(Pnt3f(0.5f,1.0f,0.5f),1.0f);
    PositionKeyframes->addKeyframe(Pnt3f(1.0f,1.0f,0.5f),2.0f);
    PositionKeyframes->addKeyframe(Pnt3f(1.0f,0.5f,0.5f),3.0f);
    PositionKeyframes->addKeyframe(Pnt3f(1.0f,1.0f,1.0f),4.0f);

    //Vector Keyframe Sequence
    KeyframeVectorSequenceRecPtr VectorKeyframes = KeyframeVectorSequenceVec3f::create();
    VectorKeyframes->addKeyframe(Vec3f(1.0f,1.0f,1.0f),0.0f);
    VectorKeyframes->addKeyframe(Vec3f(0.5f,1.0f,0.5f),1.0f);
    VectorKeyframes->addKeyframe(Vec3f(1.0f,1.0f,0.5f),2.0f);
    VectorKeyframes->addKeyframe(Vec3f(1.0f,0.5f,0.5f),3.0f);
    VectorKeyframes->addKeyframe(Vec3f(1.0f,1.0f,1.0f),4.0f);
    
    //Rotation Keyframe Sequence
    KeyframeRotationSequenceRecPtr RotationKeyframes = KeyframeRotationSequenceQuaternion::create();
    RotationKeyframes->addKeyframe(Quaternion(Vec3f(0.0f,1.0f,0.0f), 3.14159f*0.0f),0.0f);
    RotationKeyframes->addKeyframe(Quaternion(Vec3f(0.0f,1.0f,0.0f), 3.14159f*0.5f),1.0f);
    RotationKeyframes->addKeyframe(Quaternion(Vec3f(0.0f,1.0f,0.0f), 3.14159f*1.0f),2.0f);
    RotationKeyframes->addKeyframe(Quaternion(Vec3f(0.0f,1.0f,0.0f), 3.14159f*1.5f),3.0f);
    RotationKeyframes->addKeyframe(Quaternion(Vec3f(0.0f,1.0f,0.0f), 3.14159f*2.0f),4.0f);

    //Transformation Keyframe Sequence
    KeyframeTransformationSequenceRecPtr TransformationKeyframes = KeyframeTransformationSequenceMatrix4f::create();
    Matrix TempMat;
    TempMat.setTransform(Vec3f(0.0f,0.0f,0.0f), Quaternion(Vec3f(0.0f,1.0f,0.0f), 3.14159f*0.0f));
    TransformationKeyframes->addKeyframe(TempMat,0.0f);
    TempMat.setTransform(Vec3f(0.0f,1.0f,0.0f), Quaternion(Vec3f(0.0f,1.0f,0.0f), 3.14159f*0.5f));
    TransformationKeyframes->addKeyframe(TempMat,1.0f);
    TempMat.setTransform(Vec3f(1.0f,1.0f,0.0f), Quaternion(Vec3f(0.0f,1.0f,0.0f), 3.14159f*1.0f));
    TransformationKeyframes->addKeyframe(TempMat,2.0f);
    TempMat.setTransform(Vec3f(1.0f,0.0f,0.0f), Quaternion(Vec3f(0.0f,1.0f,0.0f), 3.14159f*1.5f));
    TransformationKeyframes->addKeyframe(TempMat,3.0f);
    TempMat.setTransform(Vec3f(0.0f,0.0f,0.0f), Quaternion(Vec3f(0.0f,1.0f,0.0f), 3.14159f*2.0f));
    TransformationKeyframes->addKeyframe(TempMat,4.0f);
    
    //Animator
    KeyframeAnimatorRecPtr TheAnimator = KeyframeAnimator::create();
    //TheAnimator->setKeyframeSequence(VectorKeyframes);
    //TheAnimator->setKeyframeSequence(RotationKeyframes);
    //TheAnimator->setKeyframeSequence(ColorKeyframes);
    TheAnimator->setKeyframeSequence(TransformationKeyframes);
    //TheAnimator->setKeyframeSequence(NumberKeyframes);
    
    //Animation
    FieldAnimationRecPtr TheAnimation = FieldAnimation::create();
    TheAnimation->setAnimator(TheAnimator);
    TheAnimation->setInterpolationType(Animator::LINEAR_INTERPOLATION);
    TheAnimation->setCycling(2);
    //TheAnimation->setAnimatedField(getFieldContainer("Transform",std::string("TorusNodeTransformationCore")), std::string("matrix"));
    //TheAnimation->setAnimatedField(Trans, std::string("scale"));
    //TheAnimation->setAnimatedField(Trans, std::string("rotation"));
    //TheAnimation->setAnimatedField(TheTorusMaterial, std::string("diffuse"));
    //TheAnimation->setAnimatedField(TheTorusMaterial, std::string("shininess"));
    TheAnimation->setAnimatedField(transCore, std::string("matrix"));

    AnimationGroupRecPtr TheAnimationGroup = AnimationGroup::create();
    TheAnimationGroup->pushToAnimations(TheAnimation);
    TheAnimationGroup->setCycling(2);

    TheAnimationGroup->attachUpdateProducer(win);
    TheAnimationGroup->start();

    return AnimationTransitPtr(TheAnimationGroup);
}
AnimationTransitPtr setupAnimation(Transform* const TheJoint, Transform* const TheChildJoint)
{
    //Create an animation for TheJoint
    //TheJoint Transformation keyframes (we'll animate TheJoint's translation)
    Matrix transform = TheJoint->getMatrix();

    KeyframeTransformationSequenceUnrecPtr TheJointTranformationKeyframes = KeyframeTransformationSequenceMatrix4f::create();

    transform.setTranslate(0.0f,0.0f,0.0f);
    TheJointTranformationKeyframes->addKeyframe(transform, 0.0f);

    transform.setTranslate(2.0f,0.0f,0.0f);
    TheJointTranformationKeyframes->addKeyframe(transform, 2.0f);

    transform.setTranslate(1.0f,0.0f,0.0f);
    TheJointTranformationKeyframes->addKeyframe(transform, 4.0f);

    transform.setTranslate(3.0f,0.0f,0.0f);
    TheJointTranformationKeyframes->addKeyframe(transform, 6.0f);

    transform = TheJoint->getMatrix();
    transform.setTranslate(0.0f,0.0f,0.0f);
    TheJointTranformationKeyframes->addKeyframe(transform, 8.0f);

    //TheJoint Animator
    AnimatorUnrecPtr TheJointAnimator = KeyframeAnimator::create();
    dynamic_pointer_cast<KeyframeAnimator>(TheJointAnimator)->setKeyframeSequence(TheJointTranformationKeyframes);

    //TheJoint Animation
    FieldAnimationUnrecPtr TheJointAnimation = FieldAnimation::create();
    TheJointAnimation->setAnimator(TheJointAnimator);
    TheJointAnimation->setInterpolationType(Animator::CUBIC_INTERPOLATION);
    TheJointAnimation->setCycling(-1);
    TheJointAnimation->setAnimatedField(TheJoint,
                                        std::string("matrix"));

    //Create an animation for TheChildJoint
    //TheChildJoint Transformation keyframes (we'll animate TheChildJoint's rotation)
    transform = TheChildJoint->getMatrix();

    KeyframeTransformationSequenceUnrecPtr TheChildJointTransformationKeyframes = KeyframeTransformationSequenceMatrix4f::create();

    TheChildJointTransformationKeyframes->addKeyframe(transform, 0.0f);

    transform.setRotate(Quaternion(Vec3f(0.0,1.0,0.0),0.0));
    TheChildJointTransformationKeyframes->addKeyframe(transform, 2.0f);

    transform.setRotate(Quaternion(Vec3f(0.0,1.0,0.0),0.5*Pi));
    TheChildJointTransformationKeyframes->addKeyframe(transform, 4.0f);

    transform.setRotate(Quaternion(Vec3f(0.0,1.0,0.0),Pi));
    TheChildJointTransformationKeyframes->addKeyframe(transform, 6.0f);

    transform.setRotate(Quaternion(Vec3f(0.0,1.0,0.0),1.5*Pi));
    TheChildJointTransformationKeyframes->addKeyframe(transform, 8.0f);

    transform.setRotate(Quaternion(Vec3f(0.0,1.0,0.0),2.0*Pi));
    TheChildJointTransformationKeyframes->addKeyframe(transform, 10.0f);

    //TheChildJoint Animator
    AnimatorUnrecPtr TheChildJointAnimator = KeyframeAnimator::create();
    dynamic_pointer_cast<KeyframeAnimator>(TheChildJointAnimator)->setKeyframeSequence(TheChildJointTransformationKeyframes);

    //TheChildJoint Animation
    FieldAnimationUnrecPtr TheChildJointAnimation = FieldAnimation::create();
    TheChildJointAnimation->setAnimator(TheChildJointAnimator);
    TheChildJointAnimation->setInterpolationType(Animator::CUBIC_INTERPOLATION);
    TheChildJointAnimation->setCycling(-1);
    TheChildJointAnimation->setAnimatedField(TheChildJoint, std::string("matrix"));

    AnimationGroupUnrecPtr TheAnimationGroup = AnimationGroup::create();
    TheAnimationGroup->pushToAnimations(TheJointAnimation);
    TheAnimationGroup->pushToAnimations(TheChildJointAnimation);

    return AnimationTransitPtr(TheAnimationGroup);
}