bool AttributeAttractRepelParticleAffector::affect(ParticleSystemRefPtr System, Int32 ParticleIndex, const Time& elps)
{
    if(System != NULL)
    {
        Vec3f Displacement(System->getSecPosition(ParticleIndex) - System->getPosition(ParticleIndex) );

        Real32 Distance(Displacement.squareLength());

        if((Distance > getMinDistance()*getMinDistance()) &&
           (Distance < getMaxDistance()*getMaxDistance()))
        {
            Distance = osgSqrt(Distance);
            Displacement.normalize();

            Real32 t((getQuadratic() * (Distance*Distance) + getLinear() * Distance + getConstant())*elps);
            if(t > Distance)
            {
                t=Distance;
            }

            System->setPosition(System->getPosition(ParticleIndex) + (Displacement * t),ParticleIndex) ;
        }
    }
    return false;
}
bool TurbulenceParticleAffector::affect(ParticleSystemRefPtr System, Int32 ParticleIndex, const Time& elps)
{
	if(getBeacon() != NULL)
	{	
		Matrix BeaconToWorld(getBeacon()->getToWorld());
		Vec3f translation, tmp;
		Quaternion tmp2;
		BeaconToWorld.getTransform(translation,tmp2,tmp,tmp2);

		Pnt3f particlePos = System->getPosition(ParticleIndex);
		Real32 distanceFromAffector = particlePos.dist(Pnt3f(translation.x(),translation.y(),translation.z())); 

		if((getMaxDistance() < 0.0) || (distanceFromAffector <= getMaxDistance())) //only affect the particle if it is in range
		{	
			Real32 Xparam, Yparam, Zparam;

			Pnt3f pos(System->getPosition(ParticleIndex));
			getPerlinDistribution()->setPhase(getPhase()[0]);
			Xparam = getPerlinDistribution()->generate(pos[0]);
			getPerlinDistribution()->setPhase(getPhase()[1]);
			Yparam = getPerlinDistribution()->generate(pos[1]);
			getPerlinDistribution()->setPhase(getPhase()[2]);
			Zparam = getPerlinDistribution()->generate(pos[2]);

			Vec3f fieldAffect(Vec3f(Xparam, Yparam, Zparam));
			fieldAffect = fieldAffect * (getAmplitude()*
                                          (elps/(OSG::osgClamp<Real32>(1.0f,std::pow(distanceFromAffector,getAttenuation()),TypeTraits<Real32>::getMax()))));

			System->setVelocity(System->getVelocity(ParticleIndex) + fieldAffect, ParticleIndex);

		} // end distance conditional
	} // end null beacon conditional

	return false;
}
void GeometryCollisionParticleSystemAffector::affect(ParticleSystemRefPtr System, const Time& elps)
{
	UInt32 NumParticles(System->getNumParticles());
	
	Line ray;
    IntersectAction *iAct = IntersectAction::create();
	Pnt3f ParticlePos, ParticleSecPos;
    

	Real32 HitT(0.0f);
	for(UInt32 i(0) ; i<NumParticles ; ++i)
	{
		ParticlePos = System->getPosition(i);
		ParticleSecPos = System->getSecPosition(i);
		ray.setValue(ParticleSecPos, ParticlePos);
		iAct->setLine(ray);
		iAct->apply(getCollisionNode());
	    
		if (iAct->didHit())
		{
			HitT = iAct->getHitT();
			if(HitT > 0.0f && HitT*HitT<ParticlePos.dist2(ParticleSecPos))
			{
				produceParticleCollision(System, i, iAct);
                for(UInt32 j(0) ; j<getMFCollisionAffectors()->size(); ++j)
                {
                    getCollisionAffectors(i)->affect(System,i,elps);
                }
			}
		}
	}
}
bool VortexParticleAffector::affect(ParticleSystemRefPtr System, Int32 ParticleIndex, const Time& elps)
{
	if(getBeacon() != NULL)
	{
		Matrix BeaconToWorld(getBeacon()->getToWorld());
		Vec3f translation, tmp;
		Quaternion tmp2;
		BeaconToWorld.getTransform(translation,tmp2,tmp,tmp2);

		Pnt3f particlePos = System->getPosition(ParticleIndex);
		Real32 distanceFromAffector = particlePos.dist(Pnt3f(translation.x(),translation.y(),translation.z())); 

		if((getMaxDistance() < 0.0) || (distanceFromAffector <= getMaxDistance())) //only affect the particle if it is in range
		{	
			Vec3f particleDirectionFromVortex(particlePos.x() - translation.x(), particlePos.y() - translation.y(), particlePos.z() - translation.z());
			particleDirectionFromVortex = particleDirectionFromVortex.cross(getVortexAxis());
			particleDirectionFromVortex.normalize();
			particleDirectionFromVortex = particleDirectionFromVortex *
                ((-getMagnitude() *
                  elps)/OSG::osgClamp<Real32>(1.0f,std::pow(distanceFromAffector,getAttenuation()),TypeTraits<Real32>::getMax()));
			System->setVelocity(particleDirectionFromVortex + System->getVelocity(ParticleIndex),ParticleIndex);
		}
	}

	return false;
}