void QuadParticleSystemDrawer::fill(DrawableStatsAttachment *pStat,
                                    ParticleSystemUnrecPtr System,
                                    const MFUInt32& Sort)
{
    if(pStat == NULL)
    {
        FINFO(("QuadParticleSystemDrawer::fill(DrawableStatsAttachment *, ParticleSystemUnrecPtr , const MFUInt32& ): "
               "No attachment given.\n"));

        return;
    }
    if(System == NULL)
    {
        FINFO(("QuadParticleSystemDrawer::fill(DrawableStatsAttachment *, ParticleSystemUnrecPtr , const MFUInt32& ): "
               "Particle System is NULL.\n"));

        return;
    }

    UInt32 NumParticles;

    if(Sort.size() > 0)
    {
        NumParticles = Sort.size();
    }
    else
    {
        NumParticles = System->getNumParticles();
    }

    pStat->setVertices(4*NumParticles);
    pStat->setTriangles(2*NumParticles);
    pStat->setValid(true);
}
void LineParticleSystemDrawer::adjustVolume(ParticleSystemUnrecPtr System, Volume & volume)
{
    UInt32 NumParticles = System->getNumParticles();
    for(UInt32 i(0) ; i<NumParticles ; ++i)
    {
        volume.extendBy(System->getPosition(i));
        volume.extendBy(getLineEndpoint(System, i));
    }
}
Action::ResultE QuadParticleSystemDrawer::draw(DrawEnv *pEnv, ParticleSystemUnrecPtr System, const MFUInt32& Sort)
{
    bool isSorted(Sort.size() > 0);
    UInt32 NumParticles;
    if(isSorted)
    {
        NumParticles = Sort.size();
    }
    else
    {
        NumParticles = System->getNumParticles();
    }
    Pnt3f P1,P2,P3,P4;
    UInt32 Index;

    //Calculate the CameraToObject basis
    Matrix WorldToObject(pEnv->getObjectToWorld()); 
    WorldToObject.invert();

    Matrix CameraToObject(pEnv->getCameraToWorld()); 
    CameraToObject.mult(WorldToObject);

    glBegin(GL_QUADS);
        for(UInt32 i(0); i<NumParticles;++i)
        {
            if(isSorted)
            {
                Index = Sort[i];
            }
            else
            {
                Index = i;
            }
            //Loop through all particles
            //Get The Normal of the Particle
            Vec3f Normal = getQuadNormal(pEnv, System, Index, CameraToObject);


            //Calculate the Binormal as the cross between Normal and Up
            Vec3f Binormal = getQuadUpDir(pEnv,  System, Index, CameraToObject).cross(Normal);

            //Get the Up Direction of the Particle
            Vec3f Up = Normal.cross(Binormal);

            //Determine Local Space of the Particle
            //This is where error occurs
            Pnt3f Position = System->getPosition(Index);

            //Determine the Width and Height of the quad
            Real32 Width = System->getSize(Index).x()*getQuadSizeScaling().x(),Height =System->getSize(Index).y()*getQuadSizeScaling().y();

            //Calculate Quads positions
            P1 = Position + (Width/2.0f)*Binormal + (Height/2.0f)*Up;
            P2 = Position + (Width/2.0f)*Binormal - (Height/2.0f)*Up;
            P3 = Position - (Width/2.0f)*Binormal - (Height/2.0f)*Up;
            P4 = Position - (Width/2.0f)*Binormal + (Height/2.0f)*Up;

            //Draw the Quad
            glNormal3fv(Normal.getValues());

            glColor4fv(System->getColor(Index).getValuesRGBA());
            glTexCoord2f(1.0, 1.0);
            glVertex3fv(P1.getValues());


            glTexCoord2f(0.0, 1.0);
            glVertex3fv(P4.getValues());


            glTexCoord2f(0.0, 0.0);
            glVertex3fv(P3.getValues());

            glTexCoord2f(1.0, 0.0);
            glVertex3fv(P2.getValues());
        }
        glColor4f(1.0f,1.0f,1.0f,1.0f);
    glEnd();

    //Generate a local space for the particle
    return Action::Continue;
}
Action::ResultE LineParticleSystemDrawer::draw(DrawEnv *pEnv,
                                               ParticleSystemUnrecPtr System,
                                               const MFUInt32& Sort)
{
 	UInt32 NumParticles(System->getNumParticles());

	bool areEndpointsFadeSame(getEndPointFading().x() == getEndPointFading().y());
	Color4f Color;

	if(NumParticles != 0)
	{

		bool SeparateColors(System->getNumColors() > 1);
		bool SeparateSizes(System->getNumSizes() > 1);
		bool SeparateNormals(System->getNumNormals() > 1);

		glBegin(GL_LINES);
			//Colors
			if(!SeparateColors && areEndpointsFadeSame)
			{
				Color = System->getColor(0);
				glColor4f(Color.red(), Color.green(), Color.blue(), Color.alpha() * getEndPointFading().x());
			}
			//Sizes
			if(!SeparateSizes)
			{
				//glColor4fv(System->getColor(0).getValuesRGBA());
			}
			//Normals
			if(!SeparateNormals)
			{
				glNormal3fv(System->getNormal(0).getValues());
			}
			for(UInt32 i(0) ; i<NumParticles ; ++i)
			{
				//Start Color
				if(SeparateColors)
				{
					Color = System->getColor(i);
					glColor4f(Color.red(), Color.green(), Color.blue(), Color.alpha() * getEndPointFading().x());
				}
				else if(!SeparateColors && !areEndpointsFadeSame)
				{
					Color = System->getColor(0);
					glColor4f(Color.red(), Color.green(), Color.blue(), Color.alpha() * getEndPointFading().x());
				}
				//Sizes
				if(SeparateSizes)
				{
					//glColor4fv(System->getColor(i).getValuesRGBA());
				}
				//Normals
				if(SeparateNormals)
				{
					glNormal3fv(System->getNormal(i).getValues());
				}
				//Positions
				glVertex3fv(System->getPosition(i).getValues());
				
				//End Color
				if(SeparateColors && !areEndpointsFadeSame)
				{
					Color = System->getColor(i);
					glColor4f(Color.red(), Color.green(), Color.blue(), Color.alpha() * getEndPointFading().y());
				}
				else if(!SeparateColors && !areEndpointsFadeSame)
				{
					Color = System->getColor(0);
					glColor4f(Color.red(), Color.green(), Color.blue(), Color.alpha() * getEndPointFading().y());
				}
				glVertex3fv(getLineEndpoint(System, i).getValues());
			}
		glEnd();
	}

    return Action::Continue;
}