void SkeletonBlendedGeometry::addJointBlending(UInt32 VertexIndex, Joint* const TheJoint, Real32 BlendAmount)
{
    if(getWeightIndexes() == NULL)
    {
        GeoUInt32PropertyUnrecPtr Indexes = GeoUInt32Property::create();
        setWeightIndexes(Indexes);
    }
    if(getWeights() == NULL)
    {
        GeoVec1fPropertyUnrecPtr Weights = GeoVec1fProperty::create();
        setWeights(Weights);
    }
    
    Int32 JointIndex(getMFInternalJoints()->findIndex(TheJoint));
    if(JointIndex < 0)
    {
        SFATAL << "Cannot add weight for joint, because that joint is not connected." << std::endl;
        return;
    }

    //Vertex Index
    getWeightIndexes()->push_back(VertexIndex);

    //Joint Index
    getWeightIndexes()->push_back(JointIndex);

    //Weight Index
    getWeightIndexes()->push_back(getWeights()->getSize());

    getWeights()->push_back(Pnt1f(BlendAmount));
}
void SkeletonBlendedGeometry::addJointBlending(UInt32 VertexIndex,
                                               UInt32 JointIndex,
                                               Real32 BlendAmount)
{
    if(getWeightIndexes() == NULL)
    {
        GeoUInt32PropertyUnrecPtr Indexes = GeoUInt32Property::create();
        setWeightIndexes(Indexes);
    }
    if(getWeights() == NULL)
    {
        GeoVec1fPropertyUnrecPtr Weights = GeoVec1fProperty::create();
        setWeights(Weights);
    }

    //Vertex Index
    getWeightIndexes()->push_back(VertexIndex);

    //Joint Index
    getWeightIndexes()->push_back(JointIndex);

    //Weight Index
    getWeightIndexes()->push_back(getWeights()->getSize());

    getWeights()->push_back(Pnt1f(BlendAmount));
}
void SkeletonBlendedGeometry::calculatePositions(void)
{
    if(getBaseGeometry() == NULL)
    {
        //Error
        SWARNING << "Base Geometry is NULL." << std::endl;
        return;
    }
    if(getPositions() == NULL)
    {
        //Error
        SWARNING << "Positions is NULL." << std::endl;
        return;
    }
    if(getBaseGeometry()->getPositions() == NULL)
    {
        //Error
        SWARNING << "Base Geometry Postions is NULL." << std::endl;
        return;
    }

    Pnt3f CalculatedPoint;
    Pnt3f BasePoint;
    //Vec3f CalculatedNormal;

    //Zero the Position Property
    zeroGeoProperty(getPositions());

    //Update the Positions and Normals
    UInt32 WeightIndex, JointIndex, VertexIndex;
    UInt32 NumWeightIndexTuples(getWeightIndexes()->size()/3);
    for(UInt32 i(0) ; i < NumWeightIndexTuples ; ++i)
    {
        VertexIndex = getWeightIndexes()->getValue<UInt32>( 3 * i     );
        JointIndex  = getWeightIndexes()->getValue<UInt32>((3 * i) + 1);
        WeightIndex = getWeightIndexes()->getValue<UInt32>((3 * i) + 2);

        //v*BSM*IBM*JM*JW
        getBaseGeometry()->getPositions()->getValue<Pnt3f>(BasePoint, VertexIndex);

        _JointPoseTransforms[JointIndex].mult(BasePoint, BasePoint);

        //Add the displacement to the value at this position
        getPositions()->getValue<Pnt3f>(CalculatedPoint, VertexIndex);
        CalculatedPoint += Vec3f(BasePoint) * getWeights()->getValue<Pnt1f>(WeightIndex)[0];
        getPositions()->setValue<Pnt3f>(CalculatedPoint, VertexIndex);
    }

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

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

    _NeedRecalc = false;
}
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;
	}

    Pnt3f CalculatedPoint;
    Pnt3f BasePointInfluenced;
    Pnt3f BasePoint;
    Vec3f CalculatedNormal;


    //Reset all points
    GeoVectorPropertyUnrecPtr ResetPositions(dynamic_pointer_cast<GeoVectorProperty>(getBaseGeometry()->getPositions()->clone()));
    setPositions(ResetPositions);

    UInt32 WeightIndex, JointIndex, VertexIndex;
    //Update the Positions and Normals
    for(UInt32 i(0) ; i < getWeights()->size() ; ++i)
    {
        VertexIndex = getWeightIndexes()->getValue<UInt32>( 3 * i     );
        JointIndex  = getWeightIndexes()->getValue<UInt32>((3 * i) + 1);
        WeightIndex = getWeightIndexes()->getValue<UInt32>((3 * i) + 2);

        //Get the position of this index from the base geometry
        getBaseGeometry()->getPositions()->getValue<Pnt3f>(BasePoint, VertexIndex);

        //Get the Influence matrix of this joint
        //Apply the influence of this joint to the position
        getBindTransformationDiff(JointIndex).mult(BasePoint, BasePointInfluenced);

        //Add the displacement to the value at this position
        getPositions()->getValue<Pnt3f>(CalculatedPoint, VertexIndex);
        //Scale the influence by the blend amount
        CalculatedPoint += getWeights()->getValue<Pnt1f>(WeightIndex)[0] * (BasePointInfluenced - BasePoint);
        getPositions()->setValue<Pnt3f>(CalculatedPoint, VertexIndex);
    }

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

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