#include	"..\SCOL\ZooSCOL.h"

//#define		_PCL_DEBUG_

//////////////////////////////////////////////////////////////////////////////////////////////
///		M3createEmitter
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d I F [I [F F F] [F F F]]]	H3d
int M3createEmitter(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"Start M3createEmitter\n");
#endif

	int		volume		= MTOP(	MMpull(m) );
	int		life		=		MMpull(m)  ;
	int		mask		= MTOI( MMpull(m) );
	int		s3d			= MTOP( MMget(m,0));


    if(s3d==NIL)									{	MMset(m,0,NIL);		return 0;	}
    ZScene	*scene = (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)									{	MMset(m,0,NIL);		return 0;	}

	T_VOLUME		_volume;
	if(volume==NIL)
	{
		_volume.type = VOLUME_SPHERE;
		_volume.vectorA.SetCoord(1.0f, 0.0f, 0.0f);
		_volume.vectorB.SetNull();
	}
	else
	{
		_volume.type = MMfetch(m,volume,0);
		if(_volume.type==NIL)	_volume.type = VOLUME_SPHERE;
		else
		{
			_volume.type = MTOI(_volume.type);
			if(_volume.type<VOLUME_CONE || _volume.type>VOLUME_LINE)	
													{	MMset(m,0,NIL);		return 0;	}
		}

		int ptr	= MTOP( MMfetch(m,volume,1) );
		if(ptr==NIL)	_volume.vectorA.SetCoord(1.0f, 0.0f, 0.0f);
		else
		{
			if(MMfetch(m,ptr,0)==NIL)	_volume.vectorA.x = 0.0f;
			else						_volume.vectorA.x = MTOF( MMfetch(m,ptr,0) ) / 100.0f;
			if(MMfetch(m,ptr,1)==NIL)	_volume.vectorA.y = 0.0f;
			else						_volume.vectorA.y = MTOF( MMfetch(m,ptr,1) ) / 100.0f;
			if(MMfetch(m,ptr,2)==NIL)	_volume.vectorA.z = 0.0f;
			else						_volume.vectorA.z = MTOF( MMfetch(m,ptr,2) ) / 100.0f;
		}

		ptr		= MTOP( MMfetch(m,volume,2) );
		if(ptr==NIL)	_volume.vectorB.SetNull();
		else
		{
			if(MMfetch(m,ptr,0)==NIL)	_volume.vectorB.x = 0.0f;
			else						_volume.vectorB.x = MTOF( MMfetch(m,ptr,0) ) / 100.0f;
			if(MMfetch(m,ptr,1)==NIL)	_volume.vectorB.y = 0.0f;
			else						_volume.vectorB.y = MTOF( MMfetch(m,ptr,1) ) / 100.0f;
			if(MMfetch(m,ptr,2)==NIL)	_volume.vectorB.z = 0.0f;
			else						_volume.vectorB.z = MTOF( MMfetch(m,ptr,2) ) / 100.0f;
		}
	}


	float			lifef = 0.0f;
	if(life!=NIL)	lifef = MTOF( life ) / 100.0f;

	ZEmitter *emitter = new ZEmitter((int)scene, mask, lifef, _volume);

	emitter->InsertAsChildOf(scene->World);

	int hash_tab = MTOP( MMfetch(m,s3d,1) );
	int	h3d = createH3D(m, (int)emitter, hash_tab);

	// Pose le résultat sur la pile
	if(h3d!=NIL)	h3d = PTOM(h3d);
    MMset(m,0,h3d);

#ifdef	_PCL_DEBUG_
	MMechostr(0,"End M3createEmitter\n");
#endif
	return 0;
}



//////////////////////////////////////////////////////////////////////////////////////////////
///		M3setEmitter
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d H3d I [I [F F F] [F F F]]]	I
int M3setEmitter(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3setEmitter\n");
#endif

	int		volume		= MTOP(	MMpull(m) );
	int		life		=		MMpull(m) ;
	int		mask		= MTOI( MMpull(m) );
	int		h3d			= MTOP( MMpull(m) ) ;
	int		s3d			= MTOP( MMget(m,0)) ;

    if((s3d==NIL)||(h3d==NIL))							{	MMset(m,0,NIL);		return 0;	}
    ZScene	*scene = (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)										{	MMset(m,0,NIL);		return 0;	}

	ZNode	*node = (ZNode*) MMfetch(m,h3d,0);
	if((node==NULL)||(node->type!=PCL_TYPE_ID))			{   MMset(m,0,NIL);		return 0;	}

	ZEmitter	*emitter = (ZEmitter*) node;

	T_VOLUME		_volume;
	if(volume==NIL)
	{
		_volume.type = emitter->volume.type;
		_volume.vectorA = emitter->volume.vectorA;
		_volume.vectorB = emitter->volume.vectorB;
	}
	else
	{
		_volume.type = MTOI( MMfetch(m,volume,0) );
		if(_volume.type==NIL)	_volume.type = VOLUME_SPHERE;
		else	
			if(_volume.type<VOLUME_CONE || _volume.type>VOLUME_LINE)	
													{	MMset(m,0,NIL);		return 0;	}
		
		int ptr	= MTOP( MMfetch(m,volume,1) );
		if(ptr==NIL)	_volume.vectorA = emitter->volume.vectorA;
		else
		{
			if(MMfetch(m,ptr,0)==NIL)	_volume.vectorA.x = emitter->volume.vectorA.x;
			else						_volume.vectorA.x = MTOF( MMfetch(m,ptr,0) ) / 100.0f;
			if(MMfetch(m,ptr,1)==NIL)	_volume.vectorA.y = emitter->volume.vectorA.y;
			else						_volume.vectorA.y = MTOF( MMfetch(m,ptr,1) ) / 100.0f;
			if(MMfetch(m,ptr,2)==NIL)	_volume.vectorA.z = emitter->volume.vectorA.z;
			else						_volume.vectorA.z = MTOF( MMfetch(m,ptr,2) ) / 100.0f;
		}

		ptr		= MTOP( MMfetch(m,volume,2) );
		if(ptr==NIL)	_volume.vectorB.SetNull();
		else
		{
			if(MMfetch(m,ptr,0)==NIL)	_volume.vectorB.x = emitter->volume.vectorB.x;
			else						_volume.vectorB.x = MTOF( MMfetch(m,ptr,0) ) / 100.0f;
			if(MMfetch(m,ptr,1)==NIL)	_volume.vectorB.y = emitter->volume.vectorB.y;
			else						_volume.vectorB.y = MTOF( MMfetch(m,ptr,1) ) / 100.0f;
			if(MMfetch(m,ptr,2)==NIL)	_volume.vectorB.z = emitter->volume.vectorB.z;
			else						_volume.vectorB.z = MTOF( MMfetch(m,ptr,2) ) / 100.0f;
		}
	}
	
	float lifef;
	if(mask==NIL) mask	= emitter->mask;
	if(life==NIL) lifef = emitter->life; else lifef = MTOF( life )/100;
	emitter->SetEmitter(mask, lifef, _volume);

    MMset(m,0,ITOM(0));

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3setEmitter\n");
#endif
	return 0;
}





//////////////////////////////////////////////////////////////////////////////////////////////
///		M3getEmitter
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d H3d] [I F [I [F F F] [F F F]]]
int M3getEmitter(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getEmitter\n");
#endif

	int		h3d			= MTOP( MMpull(m) ) ;
	int		s3d			= MTOP( MMget(m,0));

    if((s3d==NIL)||(h3d==NIL))							{	MMset(m,0,NIL);		return 0;	}

    ZNode	*node = (ZNode*) MMfetch(m,h3d,0);
	if((node==NULL)||(node->type!=PCL_TYPE_ID))			{   MMset(m,0,NIL);		return 0;	}

	ZScene	*scene = (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)										{	MMset(m,0,NIL);		return 0;	}


	ZEmitter	*emitter = (ZEmitter*) node;

	MMpull(m);

	if (MMpush(m,ITOM(emitter->mask)))							return MERRMEM;
	if (MMpush(m,FTOM(emitter->life*100.0f)))					return MERRMEM;

	int vA		= MMmalloc(m, 3, TYPETAB);	if(vA==NIL)	{	MMpush(m, NIL);		return MERRMEM;	}
	MMstore(m, vA, 0, FTOM(emitter->volume.vectorA.x*100.0f));
	MMstore(m, vA, 1, FTOM(emitter->volume.vectorA.y*100.0f));
	MMstore(m, vA, 2, FTOM(emitter->volume.vectorA.z*100.0f));
	MMpush(m, PTOM(vA));

	int vB		= MMmalloc(m, 3, TYPETAB);	if(vB==NIL)	{	MMpush(m, NIL);		return MERRMEM;	}
	MMstore(m, vB, 0, FTOM(emitter->volume.vectorB.x*100.0f));
	MMstore(m, vB, 1, FTOM(emitter->volume.vectorB.y*100.0f));
	MMstore(m, vB, 2, FTOM(emitter->volume.vectorB.z*100.0f));
	MMpush(m, PTOM(vB));

	int volume	= MMmalloc(m, 3, TYPETAB);
	MMstore(m, volume, 0, ITOM( emitter->volume.type));
	MMstore(m, volume, 2, MMpull(m));				// stocke vB
    MMstore(m, volume, 1, MMpull(m));				// stocke vA

    MMpush(m, PTOM(volume));

	if(MMpush(m, 3*2))											return MERRMEM;
	MBdeftab(m);

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getEmitter\n");
#endif
	return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///		M3setEmitterState
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d H3d I] I
int M3setEmitterState(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3setEmitterState\n");
#endif

	int state	= MTOI( MMpull(m) );
	int h3d		= MTOP( MMpull(m) );
	int s3d		= MTOP( MMget(m,0));

	if((s3d==NIL)||(h3d==NIL)||(state==NIL))			{   MMset(m,0,NIL);		return 0;	}

	ZScene		*scene	= (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)										{	MMset(m,0,NIL);		return 0;	}

	ZNode		*node	= (ZNode*) MMfetch(m,h3d,0); 
	if((node==NULL)||(node->type!=PCL_TYPE_ID))			{   MMset(m,0,NIL);		return 0;	}

	ZEmitter	*emitter= (ZEmitter*) node;

	if(state==PCL_ENABLE)
	{
		emitter->state |= PCL_ENABLE;
		MMset(m,0,ITOM(PCL_ENABLE));
	}
	else if(state==PCL_DISABLE)
	{
		emitter->nbFrame = 0;
		emitter->state &= (0xfff - PCL_ENABLE);
		emitter->age = 0;

		MMset(m,0,ITOM(PCL_DISABLE));
	}
	else if(state==PCL_RESTART)
	{
		emitter->nbFrame = 0;
		for(int i=0;i<emitter->particlelist.size();i++)
			emitter->particlelist[i].nbpart = 0;

		emitter->age = 0;
		emitter->state |= PCL_ENABLE;
		MMset(m,0,ITOM(PCL_ENABLE));
	}
	else
		MMset(m,0,NIL);

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3setEmitterState\n");
#endif
	return 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////
///		M3getEmitterState
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d H3d] I
int M3getEmitterState(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getEmitterState\n");
#endif

	int h3d		= MTOP( MMpull(m) );
	int s3d		= MTOP( MMget(m,0));

	if((s3d==NIL)||(h3d==NIL))							{   MMset(m,0,NIL);		return 0;	}

	ZScene	 *scene		= (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)										{	MMset(m,0,NIL);		return 0;	}

	ZNode	 *node		= (ZNode*) MMfetch(m,h3d,0); 
	if((node==NULL)||(node->type!=PCL_TYPE_ID))			{   MMset(m,0,NIL);		return 0;	}

	ZEmitter *emitter	= (ZEmitter*) node;

	if(emitter->state&PCL_ENABLE)		MMset(m,0,ITOM(emitter->nbMaxPart));
	else								MMset(m,0,ITOM(0));

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getEmitterState\n");
#endif

	return 0;
}



//////////////////////////////////////////////////////////////////////////////////////////////
///		M3setEmitterTimestep
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d H3d F] F
int M3setEmitterTimestep(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3setEmitterTimestep\n");
#endif

	int step	=		MMpull(m)  ;
	int h3d		= MTOP( MMpull(m) );
	int s3d		= MTOP( MMget(m,0));

	if((s3d==NIL)||(h3d==NIL)||(step==NIL))				{   MMset(m,0,NIL);		return 0;	}

	ZScene		*scene	= (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)										{	MMset(m,0,NIL);		return 0;	}

	ZNode		*node	= (ZNode*) MMfetch(m,h3d,0); 
	if((node==NULL)||(node->type!=PCL_TYPE_ID))			{   MMset(m,0,NIL);		return 0;	}

	ZEmitter	*emitter= (ZEmitter*) node;


	float newdt = fabs( MTOF( step ) );
	if(newdt!=0.0f)	
	{
		emitter->age *= newdt/emitter->dt;
		emitter->dt = newdt;
	}

	MMset(m,0,FTOM(emitter->dt));

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3setEmitterTimestep\n");
#endif
	return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///		M3getEmitterTimestep
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d H3d] F
int M3getEmitterTimestep(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getEmitterTimestep\n");
#endif

	int h3d		= MTOP( MMpull(m) );
	int s3d		= MTOP( MMget(m,0));

	if((s3d==NIL)||(h3d==NIL))							{   MMset(m,0,NIL);		return 0;	}

	ZScene	 *scene		= (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)										{	MMset(m,0,NIL);		return 0;	}

	ZNode	 *node		= (ZNode*) MMfetch(m,h3d,0); 
	if((node==NULL)||(node->type!=PCL_TYPE_ID))			{   MMset(m,0,NIL);		return 0;	}

	ZEmitter *emitter	= (ZEmitter*) node;
	MMset(m,0,FTOM(emitter->dt));

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getEmitterTimestep\n");
#endif

	return 0;
}



//////////////////////////////////////////////////////////////////////////////////////////////
///		M3setParticleFather
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d H3d H3d] I
int M3setParticleFather(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3setParticleFather\n");
#endif

	int father	= MTOP(	MMpull(m) );
	int h3d		= MTOP( MMpull(m) );
	int s3d		= MTOP( MMget(m,0));

	if((s3d==NIL)||(h3d==NIL)||(father==NIL))			{   MMset(m,0,NIL);		return 0;	}

	ZScene		*scene	= (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)										{	MMset(m,0,NIL);		return 0;	}

	ZNode		*node	= (ZNode*) MMfetch(m,h3d,0); 
	if((node==NULL)||(node->type!=PCL_TYPE_ID))			{   MMset(m,0,NIL);		return 0;	}

	ZNode		*node2	= (ZNode*) MMfetch(m,father,0); 
	if((node==NULL)||(node->type>MAX_NODE_SCENE))		{   MMset(m,0,NIL);		return 0;	}

	ZEmitter	*emitter= (ZEmitter*) node;
	ZNodeGraph	*ng		= (ZNodeGraph*)node2;
	emitter->pFather	= (ZNodeGraph*)ng;

	MMset(m,0,ITOM(0));

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3setParticleFather\n");
#endif

	return 0;
}













//////////////////////////////////////////////////////////////////////////////////////////////
///		M3createParticle
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d H3d I F F F F F F] HPart3d
int M3createParticle(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3createParticle\n");
#endif

	int polar	=		MMpull(m) ;
	int spin	=		MMpull(m) ;
	int size	=		MMpull(m) ;
	int weight	=		MMpull(m) ;
	int rate	=		MMpull(m) ;
	int life	=		MMpull(m) ;
	int mask	= MTOI( MMpull(m) );
	int h3d		= MTOP( MMpull(m) );
	int s3d		= MTOP( MMget(m,0));

	if((s3d==NIL)||(h3d==NIL))								{   MMset(m,0,NIL);		return 0;	}

	ZNode	*node = (ZNode*) MMfetch(m,h3d,0);
	if((node==NULL)||(node->type!=MSH_TYPE_ID))				{   MMset(m,0,NIL);		return 0;	}
		
	ZScene	*scene = (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)											{	MMset(m,0,NIL);		return 0;	}

	float polarf, spinf, sizef, weightf, ratef, lifef;

	if(polar!=NIL)	polarf	= MTOF( polar ) / 100.0f;	else polarf	= 0.0f;
	if(spin!=NIL)	spinf	= MTOF( spin ) / 100.0f;	else spinf	= 0.0f;
	if(size!=NIL)	sizef	= MTOF( size ) / 100.0f;	else sizef	= 1.0f;
	if(weight!=NIL)	weightf	= MTOF( weight ) / 100.0f;	else weightf= 0.0f;
	if(rate!=NIL)	ratef	= MTOF( rate ) / 100.0f;	else ratef	= 100.0f;
	if(life!=NIL)	lifef	= MTOF( life ) / 100.0f;	else lifef	= 100.0f;
	if(mask==NIL)	mask	= 0;		

	ZParticle		*part	=	new ZParticle((int)s3d, (ZMesh*)node, mask, lifef, ratef, weightf, sizef, spinf, polarf);
	scene->PclDef.Add(part);

	int hash_tab = MTOP( MMfetch(m,s3d,1) );
	int	part3d = createH3D(m, (int)part, hash_tab);	// on cast pour passer le pointeur (pas d'utilisation en tant que ZNode..)

	// Pose le résultat sur la pile
	if(part3d!=NIL)	part3d = PTOM(part3d);
    MMset(m,0,part3d);

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3createParticle\n");
#endif

	return 0;
}

int UpdateEmitter(ZNode *curNode, ZParticle *particle, float rate)
{
	if(curNode==NULL)	return 0;

	if(curNode->type==PCL_TYPE_ID)
	{
		ZEmitter *emitter = (ZEmitter*)curNode;
		for(int i=0;i<emitter->particlelist.size();i++)
			if(emitter->particlelist[i].parttype==particle)
				emitter->particlelist[i].nbpart=rate*emitter->age/emitter->dt;
	}
	UpdateEmitter(curNode->son, particle, rate);
	UpdateEmitter(curNode->next, particle, rate);

	return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///		M3setParticle
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d Hpart3d H3d I F F F F F F] I
int M3setParticle(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3setParticle\n");
#endif

	int polar	=		MMpull(m) ;
	int spin	=		MMpull(m) ;
	int size	=		MMpull(m) ;
	int weight	=		MMpull(m) ;
	int rate	=		MMpull(m) ;
	int life	=		MMpull(m) ;
	int mask	= MTOI( MMpull(m) );
	int h3d		= MTOP( MMpull(m) );
	int hpart	= MTOP( MMpull(m) );
	int s3d		= MTOP( MMget(m,0));

	if((s3d==NIL)||(hpart==NIL))							{   MMset(m,0,NIL);		return 0;	}

	ZScene	*scene = (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)											{	MMset(m,0,NIL);		return 0;	}

	ZParticle	*part = (ZParticle*) MMfetch(m,hpart,0);
	if((part==NULL)||(part->type!=PCLDEF_TYPE_ID))			{   MMset(m,0,NIL);		return 0;	}

	float polarf, spinf, sizef, weightf, ratef, lifef;

	if(polar!=NIL)	polarf	= MTOF( polar ) / 100.0f;	else polarf	= part->polarity;
	if(spin!=NIL)	spinf	= MTOF( spin ) / 100.0f;	else spinf	= part->spin[0].value;
	if(size!=NIL)	sizef	= MTOF( size ) / 100.0f;	else sizef	= part->size[0].value;
	if(weight!=NIL)	weightf	= MTOF( weight ) / 100.0f;	else weightf= part->weight;
	if(rate!=NIL)	ratef	= MTOF( rate ) / 100.0f;	else ratef	= part->rate;
	if(life!=NIL)	lifef	= MTOF( life ) / 100.0f;	else lifef	= part->life;
	if(mask==NIL)	mask	= part->mask;		

	ZNode *node=NULL;
	if(h3d!=NIL)	node = (ZNode*)MMfetch(m,h3d,0);

	if((node==NULL)||(node->type!=MSH_TYPE_ID))		node = (ZNode*)part->GetMesh();

	if(ratef!=part->rate)		UpdateEmitter(scene->World, part, ratef);

	part->SetParticle((ZMesh*)node, mask, lifef, ratef, weightf, sizef, spinf, polarf);

    MMset(m,0,ITOM(0));

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3setParticle\n");
#endif

	return 0;
}




//////////////////////////////////////////////////////////////////////////////////////////////
///		M3getParticle
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d HPart3d]	 [H3d I F F F F F F]
int M3getParticle(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getParticle\n");
#endif

	int part3d		= MTOP( MMpull(m) );
	int s3d			= MTOP( MMget(m,0));

	if((s3d==NIL)||(part3d==NIL))						{   MMset(m,0,NIL);		return 0;	}
	ZScene	*scene = (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)										{	MMset(m,0,NIL);		return 0;	}

	ZParticle	*part = (ZParticle*) MMfetch(m,part3d,0);
	if((part==NULL)||(part->type!=PCLDEF_TYPE_ID))		{   MMset(m,0,NIL);		return 0;	}

	MMpull(m);

	int	h3d = NodeTOHandle(m, MTOP(MMfetch(m,s3d,1)), (int)part->GetMesh());

	if (MMpush(m,PTOM(h3d)))						return MERRMEM;
	if (MMpush(m,ITOM(part->mask)))					return MERRMEM;
	if (MMpush(m,FTOM(part->life*100.0f)))			return MERRMEM;
	if (MMpush(m,FTOM(part->rate*100.0f)))			return MERRMEM;
	if (MMpush(m,FTOM(part->weight*100.0f)))		return MERRMEM;
	if (MMpush(m,FTOM(part->size[0].value*100.0f)))	return MERRMEM;
	if (MMpush(m,FTOM(part->spin[0].value*100.0f)))	return MERRMEM;
	if (MMpush(m,FTOM(part->polarity*100.0f)))		return MERRMEM;

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getParticle\n");
#endif

	if(MMpush(m, 8*2))					return MERRMEM;
	return MBdeftab(m);
}


//////////////////////////////////////////////////////////////////////////////////////////////
///		M3linkParticleList
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d H3d [HPart3d r1]]	I
int M3linkParticleList(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3linkParticleList\n");
#endif

	int liste		= MTOP( MMpull(m) );
	int h3d			= MTOP( MMpull(m) );
	int s3d			= MTOP( MMget(m,0));

	if((s3d==NIL)||(h3d==NIL))							{   MMset(m,0,NIL);		return 0;	}

	ZNode	*node = (ZNode*) MMfetch(m,h3d,0);
	if((node==NULL)||(node->type!=PCL_TYPE_ID))			{   MMset(m,0,NIL);		return 0;	}

	ZScene	*scene = (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)										{	MMset(m,0,NIL);		return 0;	}


	ZEmitter *emitter = (ZEmitter*) node;

	std::vector<T_PCL_LIST>::iterator	it0 = emitter->particlelist.begin();
	std::vector<T_PARTICLE*>::iterator	it1;

	for(; it0!=emitter->particlelist.end(); it0++)
	{
		it1 = it0->list.begin();
		for(; it1!=it0->list.end();it1++)		{	delete *it1;(*it1=NULL);	}
		it0->list.resize(0);
	}

	emitter->particlelist.resize(0);
	emitter->nbMaxPart = 0;

	if(liste==NIL)										{	MMset(m,0,ITOM(0));	return 0;	}
	else
	{
		ZParticle	*particle;

		int tmp=liste, ppart, nbpart=0;
		
		// Check every element of the list
		int curPart;

		while(tmp!=NIL)
		{
			if((ppart=MTOP( MMfetch(m,tmp,0)))==NIL)	{	MMset(m,0,NIL);		return 0;	}
			tmp = MTOP( MMfetch(m,tmp,1));
			nbpart++;
		}

		while(liste!=NIL)
		{
			curPart	= MTOP( MMfetch(m,liste,0) );
			particle = (ZParticle*)	MMfetch(m,curPart,0);
			emitter->LinkParticle(particle);
			liste = MTOP( MMfetch(m,liste,1));
		}
		MMset(m,0,ITOM(nbpart));
	}

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3linkParticleList\n");
#endif

	return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///		M3getLinkedParticleList
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d H3d] [HPart3d r1]
int M3getLinkedParticleList(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getLinkedParticleList\n");
#endif

	int h3d			= MTOP( MMpull(m) );
	int s3d			= MTOP( MMget(m,0));

    if((s3d==NIL)||(h3d==NIL))							{	MMset(m,0,NIL);		return 0;	}

	ZNode	*node = (ZNode*) MMfetch(m,h3d,0);
	if((node==NULL)||(node->type!=PCL_TYPE_ID))			{   MMset(m,0,NIL);		return 0;	}

	ZScene	*scene = (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)										{	MMset(m,0,NIL);		return 0;	}


	ZEmitter	*emitter = (ZEmitter*)node;

	int nb = emitter->particlelist.size();
	int partdef;
	ZNode *curNode;

	if(nb==0)											{	MMset(m,0,NIL);		return 0;	}

	int	tmp_res;

	for(int i=0;i<nb;i++)
	{
		curNode = (ZNode*)emitter->particlelist[i].parttype;

		s3d	= MTOP(MMget(m,0));
		partdef = NodeTOHandle(m, MTOP(MMfetch(m,s3d,1)), (int)curNode);

		if(partdef!=NIL)	partdef = PTOM(partdef);
		MMpush(m,partdef);

		INVERT(m,0,1);			// place S3d en début de pile
	}

	MMpull(m);					// supprime S3d de la pile

	if(MMpush(m,NIL))			return MERRMEM;

	for(i=0; i<nb; i++)
	{
		if (MMpush(m,2*2))		return MERRMEM;
		MBdeftab(m);
	}

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getLinkedParticleList\n");
#endif

	return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///		make_rgba
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [I I I I] I
int make_rgba(mmachine m)
{	
#ifdef	_PCL_DEBUG_
	MMechostr(0,"make_rgba\n");
#endif

	int a	= MTOI( MMpull(m) );
	int b	= MTOI( MMpull(m) );
	int g	= MTOI( MMpull(m) );
	int r	= MTOI( MMget(m,0));
	
	if((r==NIL)||(g==NIL)||(b==NIL)||(a==NIL))			{   MMset(m,0,NIL);		return 0;	}
	
	int color = (a&0x0000007E) + ((b&0x000000ff)<<7) + ((g&0x000000ff)<<15) + ((r&0x000000ff)<<23);
	MMset(m,0,ITOM(color) );

#ifdef	_PCL_DEBUG_
	MMechostr(0,"make_rgba\n");
#endif

	return 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////
///		get_rgba
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [I] [I I I I]
int get_rgba(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"get_rgba\n");
#endif

	int c	= MTOI( MMpull(m) );
	
	if(c==NIL)											{   MMpush(m,NIL);		return 0;	}

	int color = MMmalloc(m, 4, TYPETAB);
	if(color==NIL)										{	MMpush(m, NIL);		return MERRMEM;	}
	int r,g,b,a;
	r = (c>>23)&0x000000ff;
	g = (c>>15)&0x000000ff;
	b = (c>>7 )&0x000000ff;
	a = (c    )&0x0000007E;

	MMstore(m, color, 0, ITOM(r) );
	MMstore(m, color, 1, ITOM(g) );
	MMstore(m, color, 2, ITOM(b) );
	MMstore(m, color, 3, ITOM(a) );

    MMpush(m, PTOM(color));

#ifdef	_PCL_DEBUG_
	MMechostr(0,"get_rgba\n");
#endif

	return 0;
}



//////////////////////////////////////////////////////////////////////////////////////////////
///		M3setParticleColors
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d HPart3d [[I F] r1]] I
int M3setParticleColors(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3setParticleColors\n");
#endif

	int liste	= MTOP( MMpull(m) );
	int hpart	= MTOP( MMpull(m) );
	int s3d		= MTOP( MMget(m,0));

	if((s3d==NIL)||(hpart==NIL)||(liste==NIL))			{   MMset(m,0,NIL);		return 0;	}

	ZNode	*node = (ZNode*) MMfetch(m,hpart,0);
	if((node==NULL)||(node->type!=PCLDEF_TYPE_ID))		{   MMset(m,0,NIL);		return 0;	}

	ZScene	*scene = (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)										{	MMset(m,0,NIL);		return 0;	}

	ZParticle	*part = (ZParticle*) node;
	part->color.resize(0);

	int		tmp=liste, color, tuple, nbcolor=0;
	float	time;

	while(tmp!=NIL)
	{
		if(MMfetch(m,tmp,0)==NIL)						{   MMset(m,0,NIL);		return 0;	}
		tmp = MTOP( MMfetch(m,tmp,1));
	}

	while(liste!=NIL)
	{
		tuple	= MTOP( MMfetch(m,liste,0)); 
		color	= MTOI( MMfetch(m,tuple,0));
		time	= MTOF( MMfetch(m,tuple,1));
		time	= time<=100.0f ? time:100.0f;
		time	= time>=0.0f ? time:0.0f;

		float	r = (float)((color>>23)&0x000000ff)	/ 255.0f;
		float	g = (float)((color>>15)&0x000000ff)	/ 255.0f;
		float	b = (float)((color>>7 )&0x000000ff)	/ 255.0f;
		float	a = (float)((color    )&0x0000007E)	/ 127.0f;

		part->color.resize(nbcolor+1);
		part->color[nbcolor].value.SetCoord( r, g, b, a );
		part->color[nbcolor].pos = time;
		nbcolor++;

		liste = MTOP( MMfetch(m,liste,1));
	}

	MMset(m,0,ITOM(nbcolor));

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3setParticleColors\n");
#endif

	return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///		M3getParticleColors
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d HPart3d]	[[I F] r1]
int M3getParticleColors(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getParticleColors\n");
#endif

	int hpart	= MTOP( MMpull(m) );
	int s3d		= MTOP( MMget(m,0));

    if((s3d==NIL)||(hpart==NIL))							{	MMset(m,0,NIL);		return 0;	}

	ZNode	*node = (ZNode*) MMfetch(m,hpart,0);
	if((node==NULL)||(node->type!=PCLDEF_TYPE_ID))			{   MMset(m,0,NIL);		return 0;	}

	ZScene	*scene = (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)											{	MMset(m,0,NIL);		return 0;	}

	ZParticle			*part	= (ZParticle*) node;
	vector<T_COLOR>		*colors	= &(part->color);

	MMpull(m);

	for(int i=0;i<(*colors).size();i++)
	{
		MMpush(m, ITOM(		( AROUNDINT( (*colors)[i].value.w*127.0f )      )
						+	( AROUNDINT( (*colors)[i].value.z*255.0f ) <<7  )
						+	( AROUNDINT( (*colors)[i].value.y*255.0f ) <<15 )
						+	( AROUNDINT( (*colors)[i].value.x*255.0f ) <<23 )));

		MMpush(m, FTOM( (*colors)[i].pos) );

		if(MMpush(m, 2*2))									return MERRMEM;
		MBdeftab(m);
	}

	if(MMpush(m,NIL))										return MERRMEM;

	for(i=0; i<(*colors).size(); i++)
	{
		if (MMpush(m,2*2))									return MERRMEM;
		MBdeftab(m);
	}

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getParticleColors\n");
#endif

	return 0;
}



//////////////////////////////////////////////////////////////////////////////////////////////
///		M3setParticleSizes
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d HPart3d [[F F] r1]] I
int M3setParticleSizes(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3setParticleSizes\n");
#endif

	int liste	= MTOP( MMpull(m) );
	int hpart	= MTOP( MMpull(m) );
	int s3d		= MTOP( MMget(m,0));

	if((s3d==NIL)||(hpart==NIL)||(liste==NIL))			{   MMset(m,0,NIL);		return 0;	}

	ZNode	*node = (ZNode*) MMfetch(m,hpart,0);
	if((node==NULL)||(node->type!=PCLDEF_TYPE_ID))		{   MMset(m,0,NIL);		return 0;	}

	ZScene	*scene = (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)										{	MMset(m,0,NIL);		return 0;	}

	ZParticle	*part = (ZParticle*) node;
	part->size.resize(0);

	int		tmp=liste, tuple, nbsize=0;
	float	time, value;

	while(tmp!=NIL)
	{
		if(MMfetch(m,tmp,0)==NIL)						{   MMset(m,0,NIL);		return 0;	}
		tmp = MTOP( MMfetch(m,tmp,1));
	}

	while(liste!=NIL)
	{
		tuple	= MTOP( MMfetch(m,liste,0)); 
		value	= MTOF( MMfetch(m,tuple,0));
		time	= MTOF( MMfetch(m,tuple,1));
		time	= time<=100.0f ? time:100.0f;
		time	= time>=0.0f ? time:0.0f;

		T_PARAM p;
		p.pos	= time;
		p.value	= value / 100.0f;

		part->size.push_back(p);
		nbsize++;

		liste = MTOP( MMfetch(m,liste,1));
	}

	part->SortLists();

	MMset(m,0,ITOM(nbsize));

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3setParticleSizes\n");
#endif

	return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///		M3getParticleSizes
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d HPart3d]	[[F F] r1]
int M3getParticleSizes(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getParticleSizes\n");
#endif

	int hpart	= MTOP( MMpull(m) );
	int s3d		= MTOP( MMget(m,0));

    if((s3d==NIL)||(hpart==NIL))							{	MMset(m,0,NIL);		return 0;	}

	ZNode	*node = (ZNode*) MMfetch(m,hpart,0);
	if((node==NULL)||(node->type!=PCLDEF_TYPE_ID))			{   MMset(m,0,NIL);		return 0;	}

	ZScene	*scene = (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)											{	MMset(m,0,NIL);		return 0;	}

	ZParticle			*part	= (ZParticle*) node;
	vector<T_PARAM>		*sizes	= &(part->size);

	MMpull(m);

	for(int i=0;i<(*sizes).size();i++)
	{
		MMpush(m, FTOM( (*sizes)[i].value * 100.0f));
		MMpush(m, FTOM( (*sizes)[i].pos ));

		if(MMpush(m, 2*2))									return MERRMEM;
		MBdeftab(m);
	}

	if(MMpush(m,NIL))										return MERRMEM;

	for(i=0; i<(*sizes).size(); i++)
	{
		if (MMpush(m,2*2))									return MERRMEM;
		MBdeftab(m);
	}

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getParticleSizes\n");
#endif
	return 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////
///		M3setParticleSpins
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d HPart3d [[I F] r1]] I
int M3setParticleSpins(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3setParticleSpins\n");
#endif

	int liste	= MTOP( MMpull(m) );
	int hpart	= MTOP( MMpull(m) );
	int s3d		= MTOP( MMget(m,0));

	if((s3d==NIL)||(hpart==NIL)||(liste==NIL))			{   MMset(m,0,NIL);		return 0;	}

	ZNode	*node = (ZNode*) MMfetch(m,hpart,0);
	if((node==NULL)||(node->type!=PCLDEF_TYPE_ID))		{   MMset(m,0,NIL);		return 0;	}

	ZScene	*scene = (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)										{	MMset(m,0,NIL);		return 0;	}

	ZParticle	*part = (ZParticle*) node;
	part->spin.resize(0);

	int		tmp=liste, value, tuple, nbspin=0;
	float	time;

	while(tmp!=NIL)
	{
		if(MMfetch(m,tmp,0)==NIL)						{   MMset(m,0,NIL);		return 0;	}
		tmp = MTOP( MMfetch(m,tmp,1));
	}

	while(liste!=NIL)
	{
		tuple	= MTOP( MMfetch(m,liste,0)); 
		value	= MTOF( MMfetch(m,tuple,0));
		time	= MTOF( MMfetch(m,tuple,1));
		time	= time<=100.0f ? time:100.0f;
		time	= time>=0.0f ? time:0.0f;

		T_PARAM p;
		p.pos	= time;
		p.value	= value / 100.0f;

		part->spin.push_back(p);
		nbspin++;

		liste = MTOP( MMfetch(m,liste,1));
	}

	MMset(m,0,ITOM(nbspin));

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3setParticleSpins\n");
#endif
	return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///		M3getParticleSpins
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d HPart3d]	[[F F] r1]
int M3getParticleSpins(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getParticleSpins\n");
#endif

	int hpart	= MTOP( MMpull(m) );
	int s3d		= MTOP( MMget(m,0));

    if((s3d==NIL)||(hpart==NIL))							{	MMset(m,0,NIL);		return 0;	}

	ZNode	*node = (ZNode*) MMfetch(m,hpart,0);
	if((node==NULL)||(node->type!=PCLDEF_TYPE_ID))			{   MMset(m,0,NIL);		return 0;	}

	ZScene	*scene = (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)											{	MMset(m,0,NIL);		return 0;	}

	ZParticle			*part	= (ZParticle*) node;
	vector<T_PARAM>		*spins	= &(part->spin);

	MMpull(m);

	for(int i=0;i<(*spins).size();i++)
	{
		MMpush(m, FTOM( (*spins)[i].value * 100.0f));
		MMpush(m, FTOM( (*spins)[i].pos   ));

		if(MMpush(m, 2*2))									return MERRMEM;
		MBdeftab(m);
	}

	if(MMpush(m,NIL))										return MERRMEM;

	for(i=0; i<(*spins).size(); i++)
	{
		if (MMpush(m,2*2))									return MERRMEM;
		MBdeftab(m);
	}

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getParticleSpins\n");
#endif

	return 0;
}



//////////////////////////////////////////////////////////////////////////////////////////////
///		M3createEffect
//////////////////////////////////////////////////////////////////////////////////////////////
//fun	
int M3createEffect(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3createEffect\n");
#endif

	int vC		= MTOP( MMpull(m) );
	int vB		= MTOP( MMpull(m) );
	int vA		= MTOP( MMpull(m) );
	int type	= MTOI( MMpull(m) );
	int s3d		= MTOP( MMget(m,0));

	if((s3d==NIL)||(type==NIL)||(vA==NIL))				{   MMset(m,0,NIL);		return 0;	}

	ZScene	*scene = (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)										{	MMset(m,0,NIL);		return 0;	}

	if(type<EFFECT_CONSTANT || type>EFFECT_CHAOTIC1)	{	MMset(m,0,NIL);		return 0;	}

	ZVector3	vectorA, vectorB, vectorC;

	vectorA.x	= MTOF( MMfetch(m,vA,0) ) / 100.0f;
	vectorA.y	= MTOF( MMfetch(m,vA,1) ) / 100.0f;
	vectorA.z	= MTOF( MMfetch(m,vA,2) ) / (-100.0f);

	if(vB==NIL) vectorB.SetNull();
	else 
	{
		vectorB.x	= MTOF( MMfetch(m,vB,0) ) / 100.0f;
		vectorB.y	= MTOF( MMfetch(m,vB,1) ) / 100.0f;
		vectorB.z	= MTOF( MMfetch(m,vB,2) ) / (-100.0f);
	}

	if(vC==NIL) vectorC.SetNull();
	else 
	{
		vectorC.x	= MTOF( MMfetch(m,vC,0) ) / 100.0f;
		vectorC.y	= MTOF( MMfetch(m,vC,1) ) / 100.0f;
		vectorC.z	= MTOF( MMfetch(m,vC,2) ) / (-100.0f);
	}
	

	ZEffect	*effect = new ZEffect((int)s3d, type, vectorA, vectorB, vectorC);
	scene->PclEff.Add(effect);

	int hash_tab	=	MTOP( MMfetch(m,s3d,1) );
	int	heffect3d	=	createH3D(m, (int)effect, hash_tab); // on cast pour passer le pointeur (pas d'utilisation en tant que ZNode..)

	// Pose le résultat sur la pile
	if(heffect3d!=NIL)	heffect3d = PTOM(heffect3d);
    MMset(m,0,heffect3d);

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3createEffect\n");
#endif

	return 0;
}






//////////////////////////////////////////////////////////////////////////////////////////////
///		M3setEffect
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d HEffect3d I [F F F] [F F F] [F F F]]	I
int M3setEffect(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3setEffect\n");
#endif

	int vC		= MTOP( MMpull(m) );
	int vB		= MTOP( MMpull(m) );
	int vA		= MTOP( MMpull(m) );
	int type	= MTOI( MMpull(m) );
	int heffect	= MTOP( MMpull(m) );
	int s3d		= MTOP( MMget(m,0));

	if((s3d==NIL)||(heffect==NIL))						{   MMset(m,0,NIL);		return 0;	}

	ZScene	*scene = (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)										{	MMset(m,0,NIL);		return 0;	}
	
	if((type!=NIL) && (type<EFFECT_CONSTANT || type>EFFECT_CHAOTIC1))
														{	MMset(m,0,NIL);		return 0;	}

	ZEffect	*effect = (ZEffect*) MMfetch(m,heffect,0);
	if(effect==NULL)									{   MMset(m,0,NIL);		return 0;	}

	ZVector3	vectorA, vectorB, vectorC;

	if(vA==NIL) vectorA = effect->vectorA;
	else 
	{
		vectorA.x	= MTOF( MMfetch(m,vA,0) ) / 100.0f;
		vectorA.y	= MTOF( MMfetch(m,vA,1) ) / 100.0f;
		vectorA.z	= MTOF( MMfetch(m,vA,2) ) / (-100.0f);
	}

	if(vB==NIL) vectorB = effect->vectorB;
	else 
	{
		vectorB.x	= MTOF( MMfetch(m,vB,0) ) / 100.0f;
		vectorB.y	= MTOF( MMfetch(m,vB,1) ) / 100.0f;
		vectorB.z	= MTOF( MMfetch(m,vB,2) ) / (-100.0f);
	}

	if(vC==NIL) vectorC = effect->vectorC;
	else 
	{
		vectorC.x	= MTOF( MMfetch(m,vC,0) ) / 100.0f;
		vectorC.y	= MTOF( MMfetch(m,vC,1) ) / 100.0f;
		vectorC.z	= MTOF( MMfetch(m,vC,2) ) / (-100.0f);
	}

	if(type==NIL) type = effect->etype;

	effect->SetEffect(type, vectorA, vectorB, vectorC);

    MMset(m,0,ITOM(0));

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3setEffect\n");
#endif

	return 0;
}



//////////////////////////////////////////////////////////////////////////////////////////////
///		M3getEffect
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d HEffect3d] [I [F F F] [F F F] [F F F]]
int M3getEffect(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getEffect\n");
#endif

	int heffect	= MTOP( MMpull(m) );
	int s3d			= MTOP( MMget(m,0));

	if((s3d==NIL)||(heffect==NIL))					{   MMset(m,0,NIL);		return 0;	}

	ZEffect	*effect = (ZEffect*) MMfetch(m,heffect,0);
	if(effect==NULL)									{   MMset(m,0,NIL);		return 0;	}

	ZScene		*scene = (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)										{	MMset(m,0,NIL);		return 0;	}

	MMpull(m);

	MMpush(m, ITOM(effect->etype));					// Effect mode

	// Push vector A
	MMpush(m, FTOM(effect->vectorA.x*100.0f));
	MMpush(m, FTOM(effect->vectorA.y*100.0f));
	MMpush(m, FTOM(-effect->vectorA.z*100.0f));
	if(MMpush(m, 3*2))							return MERRMEM;
	MBdeftab(m);

	// Push vector B
	MMpush(m, FTOM(effect->vectorB.x*100.0f));
	MMpush(m, FTOM(effect->vectorB.y*100.0f));
	MMpush(m, FTOM(-effect->vectorB.z*100.0f));
	if(MMpush(m, 3*2))							return MERRMEM;
	MBdeftab(m);

	// Push vector C
	MMpush(m, FTOM(effect->vectorC.x*100.0f));
	MMpush(m, FTOM(effect->vectorC.y*100.0f));
	MMpush(m, FTOM(-effect->vectorC.z*100.0f));
	if(MMpush(m, 3*2))							return MERRMEM;
	MBdeftab(m);

	if(MMpush(m, 4*2))							return MERRMEM;
	MBdeftab(m);     

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getEffect\n");
#endif

	return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///		M3linkEffectList
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d H3d [HEffect3d r1]] I
int M3linkEffectList(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3linkEffectList\n");
#endif

	int liste		= MTOP( MMpull(m) );
	int h3d			= MTOP( MMpull(m) );
	int s3d			= MTOP( MMget(m,0));

	if((s3d==NIL)||(h3d==NIL))							{   MMset(m,0,NIL);		return 0;	}

	ZNode	 *node	= (ZNode*) MMfetch(m,h3d,0);
	if((node==NULL)||(node->type!=PCL_TYPE_ID))			{   MMset(m,0,NIL);		return 0;	}

	ZScene	 *scene	= (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)										{	MMset(m,0,NIL);		return 0;	}

	ZEmitter *emitter = (ZEmitter*) node;
	emitter->hasEffects = false;
	emitter->effectlist.resize(0);
	ZEffect	*effect;

	int tmp=liste, peffect, nbeffect=0;
	
	// Check every element of the list
	while(tmp!=NIL)
	{
		if((peffect=MTOP( MMfetch(m,tmp,0)))==NIL)		{	MMset(m,0,NIL);		return 0;	}
		tmp = MTOP( MMfetch(m,tmp,1));
		nbeffect++;
	}

	int curEffect;

	while(liste!=NIL)
	{
		curEffect = MTOP( MMfetch(m,liste,0) );
		effect = (ZEffect*)	MMfetch(m,curEffect,0);
		emitter->LinkEffect(effect);
		liste = MTOP( MMfetch(m,liste,1));
	}


	MMset(m,0,ITOM(nbeffect));

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3linkEffectList\n");
#endif
	return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///		M3getLinkedEffectList
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d H3d] [HEffect3d r1]
int M3getLinkedEffectList(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getLinkedEffectList\n");
#endif

	int h3d			= MTOP( MMpull(m) );
	int s3d			= MTOP( MMget(m,0));

	if((s3d==NIL)||(h3d==NIL))							{   MMset(m,0,NIL);		return 0;	}

	ZNode	*node = (ZNode*) MMfetch(m,h3d,0);
	if((node==NULL)||(node->type!=PCL_TYPE_ID))			{   MMset(m,0,NIL);		return 0;	}

	ZScene	*scene = (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)										{	MMset(m,0,NIL);		return 0;	}

	ZEmitter				*emitter	= (ZEmitter*)node;
	vector<ZEffect*>		*effectlist	= &(emitter->effectlist);
	ZEffect					*tmp;

	int curEffect;
	if(effectlist->size()==0)							{	MMset(m,0,NIL);		return 0;	}

	int	tmp_res;

	for(int i=0;i<effectlist->size();i++)
	{
		tmp	= emitter->effectlist[i];

		s3d = MTOP(MMget(m,0));
		curEffect = NodeTOHandle(m, MTOP(MMfetch(m,s3d,1)), (int)tmp);
		MMpush(m, PTOM(curEffect));
		INVERT(m,0,1);			// place S3d en début de pile
	}

	MMpull(m);					// supprime S3d de la pile

	if(MMpush(m,NIL))			return MERRMEM;

	for(i=0;i<effectlist->size();i++)
	{
		if (MMpush(m,2*2))		return MERRMEM;
		MBdeftab(m);
	}

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getLinkedEffectList\n");
#endif

	return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///		M3delPart3d
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d HPart3d] I
int M3delPart3d(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3delPart3d\n");
#endif

	int hpart		= MTOP( MMpull(m) );
	int s3d			= MTOP( MMget(m,0));

	if((s3d==NIL)||(hpart==NIL))						{   MMset(m,0,NIL);		return 0;	}

	ZScene		*scene	= (ZScene*)		MMfetch(m,s3d,0);
	if(scene==NULL)										{	MMset(m,0,NIL);		return 0;	}
	
	ZNode		*node	= (ZNode*) MMfetch(m,hpart,0);
	if((node==NULL)||(node->type!=PCLDEF_TYPE_ID))		{   MMset(m,0,NIL);		return 0;	}

	ZParticle	*part	= (ZParticle*)node;

	ZArray<ZEmitter*>	*pclList = &scene->pclList;
	ZEmitter			*curEmitter;


	int n = pclList->Size();

	for(int i=0;i<pclList->Size();i++)
	{
		curEmitter = (*pclList)[i];
		for(int j=0;j<curEmitter->particlelist.size();j++)
			if(curEmitter->particlelist[j].parttype==part)
				curEmitter->particlelist.erase(&curEmitter->particlelist[j]);
	}
	
	
	scene->PclDef.Delete(part);
	delete part;
	part = NULL;

	DelObj(m, MTOP(MMfetch(m,s3d,1)), hpart);

	MMset(m,0,ITOM(0));

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3delPart3d\n");
#endif
	return 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////
///		M3delEffect3d
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d HEffect3d] I
int M3delEffect3d(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3delEffect3d\n");
#endif

	int heffect		= MTOP( MMpull(m) );
	int s3d			= MTOP( MMget(m,0));

	if((s3d==NIL)||(heffect==NIL))						{   MMset(m,0,NIL);		return 0;	}

	ZScene		*scene	= (ZScene*)		MMfetch(m,s3d,0);
	if(scene==NULL)										{	MMset(m,0,NIL);		return 0;	}

	ZNode		*node	= (ZNode*) MMfetch(m,heffect,0);
	if((node==NULL)||(node->type!=PCLEFF_TYPE_ID))		{   MMset(m,0,NIL);		return 0;	}

	ZEffect	*effect		= (ZEffect*)node;


	ZArray<ZEmitter*>	*pclList = &scene->World->pclList;
	ZEmitter			*curEmitter;

	for(int i=0;i<pclList->Size();i++)
	{
		curEmitter = (*pclList)[i];
		for(int j=0;j<curEmitter->effectlist.size();j++)
			if(curEmitter->effectlist[j]==effect)
			{
				curEmitter->effectlist.erase(&curEmitter->effectlist[j]);
				if(curEmitter->effectlist.size()==0)	curEmitter->hasEffects = false;
			}
	}

	scene->PclEff.Delete(effect);
	delete effect;
	effect = NULL;

	DelObj(m, MTOP(MMfetch(m,s3d,1)), heffect);

	MMset(m,0,ITOM(0));

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3delEffect3d\n");
#endif

	return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///		M3getHPart3d
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d S] HPart3d
int M3getHPart3d(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getHPart3d\n");
#endif

	int name = MTOP( MMpull(m) );
    int s3d  = MTOP( MMget(m,0));

    if((name==NIL)||(s3d==NIL))		{	MMset(m,0,NIL);		return 0;	}

    ZScene	*scene = (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)					{	MMset(m,0,NIL);		return 0;	}

	string	nom = string(MMstartstr(m,name));

	ZParticle	*tmp, *result = NULL;
	
	for(int k=0; k<scene->PclDef.Size(); k++)
	{
		tmp = scene->PclDef[k];
		if( (tmp->name==nom) && ((result==NULL)||(tmp->version>result->version)) )		result = tmp;
	}

	if(result==NULL)		{	MMset(m,0,NIL);		return 0;	}

	int	hpart3d = NodeTOHandle(m, MTOP(MMfetch(m,s3d,1)), (int)result);
	if(hpart3d!=NIL)		hpart3d = PTOM(hpart3d);
	MMset(m,0,hpart3d);

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getHPart3d\n");
#endif
	
	return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///		M3HPart3dName
//////////////////////////////////////////////////////////////////////////////////////////////
/// fun [S3d HPart3d] S
int M3HPart3dName(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3HPart3dName\n");
#endif

    int hpart	= MTOP( MMpull(m) );
    int s3d		= MTOP( MMget(m,0));

    if((s3d==NIL)||(hpart==NIL))		{	MMset(m,0,NIL);		return 0;	}

    ZScene	*scene = (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)						{	MMset(m,0,NIL);		return 0;	}

    ZParticle	*part = (ZParticle*) MMfetch(m,hpart,0);
	if(part==NULL)						{	MMset(m,0,NIL);		return 0;	}

	MMpull(m);

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3HPart3dName\n");
#endif

	return Mpushstrbloc(m, (char*)part->name.c_str());
}


//////////////////////////////////////////////////////////////////////////////////////////////
///		M3renameHPart3d
//////////////////////////////////////////////////////////////////////////////////////////////
/// fun [S3d HPart3d S] I
int M3renameHPart3d(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3renameHPart3d\n");
#endif

    int name	= MTOP( MMpull(m) );
    int hpart	= MTOP( MMpull(m) );
    int s3d		= MTOP( MMget(m,0));

    if((s3d==NIL)||(hpart==NIL)||(name==NIL))			{	MMset(m,0,NIL);		return 0;	}

    ZScene		*scene	= (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)										{	MMset(m,0,NIL);		return 0;	}

    ZParticle	*part	= (ZParticle*) MMfetch(m,hpart,0);
	if(part==NULL)										{	MMset(m,0,NIL);		return 0;	}

	part->SetName((char*)MMstartstr(m,name));

	MMset(m,0,ITOM(0));

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3renameHPart3d\n");
#endif

	return 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////
///		M3getHEffect3d
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S3d S] HEffect3d
int M3getHEffect3d(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getHEffect3d\n");
#endif

	int name = MTOP( MMpull(m) );
    int s3d  = MTOP( MMget(m,0));

    if((name==NIL)||(s3d==NIL))		{	MMset(m,0,NIL);		return 0;	}

    ZScene	*scene = (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)					{	MMset(m,0,NIL);		return 0;	}

	string	nom = string(MMstartstr(m,name));

	ZEffect		*tmp, *result = NULL;

	for(int k=0; k<scene->PclEff.Size(); k++)
	{
		tmp = scene->PclEff[k];
		if( (tmp->name==nom) && ((result==NULL)||(tmp->version>result->version)) )		result = tmp;
	}
	
	if(result==NULL)		{	MMset(m,0,NIL);		return 0;	}

	int	heffect = NodeTOHandle(m, MTOP(MMfetch(m,s3d,1)), (int)result);
	if(heffect!=NIL)		heffect = PTOM(heffect);
	MMset(m,0,heffect);

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3getHEffect3d\n");
#endif
	return 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////
///		M3Heffect3dName
//////////////////////////////////////////////////////////////////////////////////////////////
/// fun [S3d HEffect3d] S
int M3HEffect3dName(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3HEffect3dName\n");
#endif

    int heffect	= MTOP( MMpull(m) );
    int s3d		= MTOP( MMget(m,0));

    if((s3d==NIL)||(heffect==NIL))		{	MMset(m,0,NIL);		return 0;	}

    ZScene	*scene	= (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)						{	MMset(m,0,NIL);		return 0;	}

    ZEffect	*effect = (ZEffect*) MMfetch(m,heffect,0);
	if(effect==NULL)					{	MMset(m,0,NIL);		return 0;	}

	MMpull(m);

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3HEffect3dName\n");
#endif

	return Mpushstrbloc(m, (char*)effect->name.c_str());
}


//////////////////////////////////////////////////////////////////////////////////////////////
///		M3renameHEffect3d
//////////////////////////////////////////////////////////////////////////////////////////////
/// fun [S3d HEffect3d S] I
int M3renameHEffect3d(mmachine m)
{
#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3renameHEffect3d\n");
#endif

    int name	= MTOP( MMpull(m) );
    int heffect = MTOP( MMpull(m) );
    int s3d		= MTOP( MMget(m,0));

    if((s3d==NIL)||(heffect==NIL)||(name==NIL))			{	MMset(m,0,NIL);		return 0;	}

    ZScene	*scene = (ZScene*) MMfetch(m,s3d,0);
	if(scene==NULL)										{	MMset(m,0,NIL);		return 0;	}

    ZEffect	*effect = (ZEffect*) MMfetch(m,heffect,0);
	if(effect==NULL)									{	MMset(m,0,NIL);		return 0;	}

	effect->SetName((char*)MMstartstr(m,name));

	MMset(m,0,ITOM(0));

#ifdef	_PCL_DEBUG_
	MMechostr(0,"M3renameHEffect3d\n");
#endif
	return 0;
}


/////////////////////////////////////////////////////// DEFINITIONS
#define NPCLPKG 55

char* PCLname [ NPCLPKG ] = 
{
	"HPart3d",							// HPart3d
	"HEffect3d",						// HEffect3d

	"EFFECT_CONSTANT",					// Constant force
	"EFFECT_ELECTRIC",					// Electric charge
	"EFFECT_MAGNETIC",					// Electric charge
	"EFFECT_HELICOID",					// Helicoidal trajectory
	"EFFECT_CHAOTIC0",					// Chaotic influance
	"EFFECT_PLANCOLL",					// Helicoidal trajectory
	"EFFECT_CHAOTIC1",					// Chaotic influance

	"VOLUME_CONE",						// Volume cone		
	"VOLUME_SPHERE",					// Volume sphere
	"VOLUME_PLAN",						// Volume plan
	"VOLUME_LINE",						// Volume line
	
	"PCL_ENABLE",		
	"PCL_RESTART",
	"PCL_DISABLE",
	
	"PCL_BILLBOARD",
	"PCL_RAINBOW",
	"PCL_JITTER", 

	"PCL_INFINIT",
	"PCL_ADDITIVE",
	

	"make_rgba",						// make_rgba,
	"get_rgba",							// get_rgba,

	"M3createEmitter",					// M3createEmitter
	"M3setEmitter",						// M3setEmitter
	"M3getEmitter",						// M3getEmitter
	"M3setEmitterState",				// M3setEmitterState
	"M3getEmitterState",				// M3getEmitterState
	"M3setEmitterTimestep",				// M3setEmitterTimestep
	"M3getEmitterTimestep",				// M3getEmitterTimestep
	"M3setParticleFather",				// M3setParticleFather

	"M3createParticle",					// M3createParticle
	"M3setParticle",					// M3setParticle
	"M3getParticle",					// M3getParticle
	"M3setParticleColors",				// M3setParticleColors
	"M3getParticleColors",				// M3getParticleColors,

	"M3setParticleSizes",				// M3setParticleSizes
	"M3getParticleSizes",				// M3getParticleSizes,
	"M3setParticleSpins",				// M3setParticleSpins
	"M3getParticleSpins",				// M3getParticleSpins,

	"M3linkParticleList",				// M3linkParticleList
	"M3getLinkedParticleList",			// M3getLinkedParticleList

	"M3createEffect",					// M3createEffect
	"M3setEffect",						// M3setEffect
	"M3getEffect",						// M3getEffect
	"M3linkEffectList",					// M3linkEffectList
	"M3getLinkedEffectList",			// M3getLinkedEffectList

	"M3HPart3dName",					// M3HPart3dName
	"M3renameHPart3d",					// M3renameHPart3d
	"M3delPart3d",						// M3delPart3d
	"M3getHPart3d",						// M3getHPart3d
	
	"M3HEffect3dName",					// M3HEffect3dName
	"M3renameHEffect3d",				// M3renameHEffect3d
	"M3delEffect3d",					// M3delEffect3d
	"M3getHEffect3d",					// M3getHEffect3d	
} ;

char * PCLtype [ NPCLPKG ] = 
{
	NULL,													// HPart3d
	NULL,													// HEffect3d

	"I",
	"I",
	"I",
	"I",
	"I",
	"I",
	"I",
	"I",
	"I",
	"I",
	"I",
	"I",
	"I",
	"I",
	"I",
	"I",
	"I",
	"I",
	"I",

	"fun [I I I I] I",										// make_rgba,
	"fun [I] [I I I I]",									// get_rgba,

	"fun [S3d I F [I [F F F] [F F F]]] H3d",				// M3createEmitter
	"fun [S3d H3d I F [I [F F F] [F F F]]] I",				// M3setEmitter
	"fun [S3d H3d] [I F [I [F F F] [F F F]]]",				// M3getEmitter
	"fun [S3d H3d I] I",									// M3setEmitterState
	"fun [S3d H3d] I",										// M3getEmitterState
	"fun [S3d H3d F] F",									// M3setEmitterTimestep
	"fun [S3d H3d] F",										// M3getEmitterTimestep
	"fun [S3d H3d H3d] I",									// M3setParticleFather

	"fun [S3d H3d I F F F F F F] HPart3d",					// M3createParticle
	"fun [S3d HPart3d H3d I F F F F F F] I",				// M3setParticle
	"fun [S3d HPart3d] [H3d I F F F F F F] I",				// M3getParticle
	"fun [S3d HPart3d [[I F] r1]] I",						// M3setParticleColors
	"fun [S3d HPart3d]	[[I F] r1]",						// M3getParticleColors,

	"fun [S3d HPart3d [[F F] r1]] I",						// M3setParticleSizes
	"fun [S3d HPart3d]	[[F F] r1]",						// M3getParticleSizes
	"fun [S3d HPart3d [[F F] r1]] I",						// M3setParticleSpins
	"fun [S3d HPart3d]	[[F F] r1]",						// M3getParticleSpins


	"fun [S3d H3d [HPart3d r1]] I",							// M3linkParticleList
	"fun [S3d H3d] [HPart3d r1]",							// M3getLinkedParticleList

	"fun [S3d I [F F F] [F F F] [F F F]] HEffect3d",		// M3createEffect
	"fun [S3d HEffect3d I [F F F] [F F F] [F F F]]	I",		// M3setEffect
	"fun [S3d HEffect3d] [I [F F F] [F F F] [F F F]]",		// M3getEffect
	"fun [S3d H3d [HEffect3d r1]] I",						// M3linkEffectList
	"fun [S3d H3d] [HEffect3d r1]",							// M3getLinkedEffectList

	"fun [S3d HPart3d] S",									// M3HPart3dName
	"fun [S3d HPart3d S] I",								// M3renameHPart3d
	"fun [S3d HPart3d] I",									// M3delPart3d
	"fun [S3d S] HPart3d",									// M3getHPart3d
	
	"fun [S3d HEffect3d] S",								// M3HEffect3dName
	"fun [S3d HEffect3d S] I",								// M3renameHEffect3d
	"fun [S3d HEffect3d] I",								// M3delEffect3d
	"fun [S3d S] HEffect3d",								// M3getHEffect3d	
} ;


int PCLnarg [ NPCLPKG ] = 
{
	TYPTYPE,			// HPart3d
	TYPTYPE,			// HEffect3d


	TYPVAR,
	TYPVAR,
	TYPVAR,
	TYPVAR,
	TYPVAR,
	TYPVAR,
	TYPVAR,
	TYPVAR,
	TYPVAR,
	TYPVAR,
	TYPVAR,
	TYPVAR,
	TYPVAR,
	TYPVAR,
	TYPVAR,
	TYPVAR,
	TYPVAR,
	TYPVAR,
	TYPVAR,

	4,					// make_rgba,
	1,					// get_rgba,

	4,					// M3createEmitter
	5,					// M3setEmitter
	2,					// M3getEmitter
	3,					// M3setEmitterState
	2,					// M3getEmitterState
	3,					// M3setEmitterTimestep
	2,					// M3getEmitterTimestep
	3,					// M3setParticleFather

	9,					// M3createParticle
	10,					// M3setParticle
	2,					// M3getParticle
	3,					// M3setParticleColors
	2,					// M3getParticleColors,

	3,					// M3setParticleSizes
	2,					// M3getParticleSizes,
	3,					// M3setParticleSpins
	2,					// M3getParticleSpins,

	3,					// M3linkParticleList
	2,					// M3getLinkedParticleList

	5,					// M3createEffect
	6,					// M3setEffect
	2,					// M3getEffect
	3,					// M3linkEffectList
	2,					// M3getLinkedEffectList

	2,					// M3HPart3dName
	3,					// M3renameHPart3d
	2,					// M3delPart3d
	2,					// M3getHPart3d
	
	2,					// M3HEffect3dName
	3,					// M3renameHEffect3d
	2,					// M3delEffect3d
	2,					// M3getHEffect3d
};


int (*PCLfun[NPCLPKG])(mmachine m)= 
{
	NULL,
	NULL,

	(int (__cdecl *)(struct Mmachine *))2,				// Constant force			0x000001
	(int (__cdecl *)(struct Mmachine *))4,				// Electric charge			0x000002
	(int (__cdecl *)(struct Mmachine *))6,				// Magnetic charge			0x000003
	(int (__cdecl *)(struct Mmachine *))8,				// Helicoidal trajectory	0x000004
	(int (__cdecl *)(struct Mmachine *))10,				// Chaotic influance		0x000005
	(int (__cdecl *)(struct Mmachine *))12,				// Helicoidal trajectory	0x000006
	(int (__cdecl *)(struct Mmachine *))14,				// Chaotic influance		0x000007

	(int (__cdecl *)(struct Mmachine *))2,				// VOLUME_CONE
	(int (__cdecl *)(struct Mmachine *))4,				// VOLUME_SPHERE
	(int (__cdecl *)(struct Mmachine *))6,				// VOLUME_PLAN	
	(int (__cdecl *)(struct Mmachine *))8,				// VOLUME_LINE

	(int (__cdecl *)(struct Mmachine *))4,				// PCL_ENABLE",	
	(int (__cdecl *)(struct Mmachine *))8,				// PCL_RESTART",
	(int (__cdecl *)(struct Mmachine *))0,				// PCL_DISABLE",

	(int (__cdecl *)(struct Mmachine *))2,				// PCL_BILLBOARD
	(int (__cdecl *)(struct Mmachine *))4,				// PCL_RAINBOW
	(int (__cdecl *)(struct Mmachine *))8,				// PCL_JITTER
	
	(int (__cdecl *)(struct Mmachine *))2,				// PCL_INFINIT
	(int (__cdecl *)(struct Mmachine *))4,				// PCL_ADDITIVE
	

	make_rgba,						// make_rgba
	get_rgba,						// get_rgba,

	M3createEmitter,				// M3createEmitter
	M3setEmitter,					// M3setEmitter
	M3getEmitter,					// M3getEmitter
	M3setEmitterState,				// M3setEmitterState
	M3getEmitterState,				// M3getEmitterState
	M3setEmitterTimestep,			// M3setEmitterTimestep
	M3getEmitterTimestep,			// M3getEmitterTimestep
	M3setParticleFather,			// M3setParticleFather

	M3createParticle,				// M3createParticle
	M3setParticle,					// M3setParticle
	M3getParticle,					// M3getParticle
	M3setParticleColors,			// M3setParticleColors
	M3getParticleColors,			// M3getParticleColors,

	M3setParticleSizes,				// M3setParticleSizes
	M3getParticleSizes,				// M3getParticleSizes
	M3setParticleSpins,				// M3setParticleSpins
	M3getParticleSpins,				// M3getParticleSpins


	M3linkParticleList,				// M3linkParticleList
	M3getLinkedParticleList,		// M3getLinkedParticleList

	M3createEffect,					// M3createEffect
	M3setEffect,					// M3setEffect
	M3getEffect,					// M3getEffect
	M3linkEffectList,				// M3linkEffectList
	M3getLinkedEffectList,			// M3getLinkedEffectList

	M3HPart3dName,					// M3HPart3dName
	M3renameHPart3d,				// M3renameHPart3d
	M3delPart3d,					// M3delPart3d
	M3getHPart3d,					// M3getHPart3d
	
	M3HEffect3dName,				// M3HEffect3dName
	M3renameHEffect3d,				// M3renameHEffect3d
	M3delEffect3d,					// M3delEffect3d
	M3getHEffect3d,					// M3getHEffect3d
};


int SCOLloadParticle(mmachine m,cbmachine w)
{
	int k;

	k=(PKhardpak(m,"ParticleEngine",NPCLPKG,PCLname,PCLfun,PCLnarg,PCLtype));

	return k;
}



int SCOLfreeParticle()
{
	MMechostr(1,"Release Particle engine ressources\n");

	return 0;
}







