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 MorphGeometry::updateMorph(void)
{
    if(!getBaseGeometry())
    {
        SWARNING << "No Base Geometry" << std::endl;
        return;
    }

    for(UInt32 i(0) ; i<getMFMorphProperties()->size() ; ++i)
    {
        GeoVectorProperty* BaseProp(getBaseGeometry()->getProperty(getMorphProperties(i)));

        GeoVectorPropertyUnrecPtr Prop(getProperty(getMorphProperties(i)));
        switch(getBlendingMethod())
        {
            case Relative:
                {
                    //Reset the Base mesh
                    UInt32 NumBytesToCopy(Prop->getFormatSize() * BaseProp->size() * BaseProp->getDimension());
                    memcpy(Prop->editData(), BaseProp->getData(), NumBytesToCopy);
                }
                break;
            default:
                SWARNING << "Invalid blending method: " << getBlendingMethod()
                         << ". Using Normalized method." << std::endl;
            case Normalized:
                {
                    Real32 Weight(1.0f);
                    for(UInt32 j(0) ; j < getNumMorphTargets() ; ++j)
                    {
                        Weight -= osgAbs(getMorphTargetWeight(j));
                    }
                    //Zero out the property
                    zeroGeoProperty(Prop);

                    //Call the morph property with the given property format
                    morphGeoProperty(BaseProp, Prop, Weight);
                }
                break;
        }
        setProperty(Prop, getMorphProperties(i));

        //Loop through all morph targets
        Geometry* Target;
        GeoVectorProperty* TargetProp;
        Real32 Weight;
        for(UInt32 j(0) ; j < getNumMorphTargets() ; ++j)
        {
            //If the Weight is really small then don't apply it
            Weight = osgAbs(getMorphTargetWeight(j));
            if(Weight < 0.000001f)
            {
                continue;
            }

            Target = getMorphTarget(j);
            TargetProp = Target->getProperty(getMorphProperties(i));

            //Call the morph property with the given property format
            morphGeoProperty(TargetProp, Prop, Weight);
        }
    }
}