bool BlendedKeyframeAnimator::animate(UInt32 InterpType,
                         UInt32 ReplacementPolicy,
                                      bool Cycling,
                                      const Real32& time,
                                      const Real32& prevTime,
                                      EditFieldHandlePtr Result,
                                      UInt32 Index)
{
    if( getMFKeyframeSequences()->size() != 0)
    {
        ValueReplacementPolicy BlendRepPol;
        if(ReplacementPolicy == OVERWRITE)
        {
            //Zero out the value of the Field
            getMFKeyframeSequences()->front()->zeroField(Result, Index);
            BlendRepPol = ADDITIVE_ABSOLUTE;
        }
        else
        {
            BlendRepPol = static_cast<ValueReplacementPolicy>(ReplacementPolicy);
        }
        bool RetValue(true);
        for(UInt32 i(0) ; i< getMFKeyframeSequences()->size() ; ++i)
        {
            RetValue = RetValue && getKeyframeSequences(i)->interpolate(InterpType, time, prevTime, BlendRepPol, Cycling, Result, Index, getBlendAmounts(i));
        }
        return RetValue;
    }
    else
    {
        return false;
    }
}
void SkeletonBlendedAnimation::internalUpdate(Real32 t, const Real32 prev_t)
{
	if(getMFSkeletonAnimations()->size() == getMFBlendAmounts()->size())
	{
		//Get scaled transformations and add them together
		std::vector<std::map<unsigned long, Matrix> > relTransformations;  //Each map in the vector contains the rel trans matrices for skeletonAnimation[i]
		std::set<JointUnrecPtr> animatedJoints;
		for (int i(0); i < getMFSkeletonAnimations()->size(); ++i)
		{
			relTransformations.push_back(getSkeletonAnimations(i)->getRelTransformations(t, prev_t, animatedJoints));
		}

		//Apply the transformations to the joints
		std::set<JointUnrecPtr>::iterator iter;
		for (iter = animatedJoints.begin(); iter != animatedJoints.end(); ++iter)
		{
			//Find all of the rel dif transformations for this joint
			//Note that i will correspond to the skeleton animation from which these rel dif trans matrices came
			//(so it we should scale them by blendAmounts[i])
			Matrix blendedRelDifTrans;
			bool firstForThisJoint = true;
			for(int i(0); i < relTransformations.size(); ++i)
			{
				int exists = relTransformations[i].count((*iter)->getId());
				if(exists)
				{
					if(getOverrideStatuses(i) && getBlendAmounts(i) != 0)
					{
						//If this skeleton animation is set to override, we don't consider any other difference transformations
						//Matrix relDifTrans = (*iter)->previewRelativeDifferenceTransformation(relTransformations[i][(*iter)->getId()]);
						//blendedRelDifTrans = (OSG::lerp(Matrix().identity(), relDifTrans, getBlendAmounts(i)));
						break;
					}
					else
					{
						if(firstForThisJoint)
						{
							//Use the calculated relative difference transformation from bind pose to the transformation defined by
							//the skeleton animation
							//Matrix relDifTrans = (*iter)->previewRelativeDifferenceTransformation(relTransformations[i][(*iter)->getId()]);
							//blendedRelDifTrans = (OSG::lerp(Matrix().identity(), relDifTrans, getBlendAmounts(i)));
						}
						else
						{
							//Use the difference transformation between the joint's current transformation and the transformation
							//defined by the skeleton animation
							//Matrix relDifTrans = (*iter)->previewRelativeTransformation(blendedRelDifTrans);
							//relDifTrans.invert();
							//relDifTrans.multLeft(relTransformations[i][(*iter)->getId()]);

							//blendedRelDifTrans.mult(OSG::lerp(Matrix().identity(), relDifTrans, getBlendAmounts(i)));
						}
					}
					if(getBlendAmounts(i) != 0)
					{
						firstForThisJoint = false;
					}
				}
			}
			//blendedRelDifTrans.mult((*iter)->getBindRelativeTransformation());
			//(*iter)->setRelativeTransformation(blendedRelDifTrans);

			////Update joint, but don't tell skeleton
			//(*iter)->updateTransformations(false, false);

		}

		//Tell skeleton to update
		//(*animatedJoints.begin())->getParentSkeleton()->skeletonUpdated();
	}
}
void SkeletonBlendedGeometry::calculatePositions(void)
{
	if(getBaseGeometry() == NULL)
	{
		//Error
		SWARNING << "SkeletonBlendedGeometry::calculatePositions(): Base Geometry is NULL." << std::endl;
        return;
	if(getPositions() == NULL)
	{
		//Error
		SWARNING << "SkeletonBlendedGeometry::calculatePositions(): Positions is NULL." << std::endl;
        return;
	}
	if(getBaseGeometry()->getPositions() == NULL)
	{
		//Error
		SWARNING << "SkeletonBlendedGeometry::calculatePositions(): Base Geometry Postions is NULL." << std::endl;
        return;
	}
	if(getMFPositionIndexes()->size() != getMFJoints()->size())
	{
		//Error
		SWARNING << "SkeletonBlendedGeometry::calculatePositions(): Positions Indexes size is not the same as the affecting Joints size." << std::endl;
        return;
	}
	}
	if(getMFPositionIndexes()->size() != getMFBlendAmounts()->size())
	{
		//Error
		SWARNING << "SkeletonBlendedGeometry::calculatePositions(): Positions Indexes size is not the same as the affecting blend amount size." << std::endl;
        return;
	}

    Pnt3f CalculatedPoint;
    Pnt3f PointTemp;
    Vec3f CalculatedNormal;


    //Set the values of all points to 0
    for (int i(0); i < getPositions()->size(); ++i)
    {
        getPositions()->setValue(Pnt3f(0, 0, 0), i);
    }

    //Update the Positions and Normals
    for(UInt32 i(0) ; i < getMFPositionIndexes()->size() ; ++i)
    {

        Matrix temp = getJoints(i)->getAbsoluteDifferenceTransformation();
        temp.scale(getBlendAmounts(i));
        getBaseGeometry()->getPositions()->getValue<Pnt3f>(PointTemp, getPositionIndexes(i));
        temp.mult(PointTemp, CalculatedPoint);
        //temp.mult(getBaseGeometry()->getNormals()->getValue(getPositionIndexes(i)), CalculatedNormal);
        

        //Add
        CalculatedPoint += PointTemp.subZero();
        getPositions()->setValue<Pnt3f>(CalculatedPoint, getPositionIndexes(i));
    }

    for(UInt32 i = 0; i < _mfParents.size(); i++)
    {
        _mfParents[i]->invalidateVolume();
    }

    _volumeCache.setValid();
    _volumeCache.setEmpty();
}