[PD-cvs] externals/nusmuk/msd 01_msdtest.pd, NONE, 1.1 02_imsdtest.pd, NONE, 1.1 Makefile.am, NONE, 1.1 help-msd.pd, NONE, 1.1 main.cpp, NONE, 1.1 package.txt, NONE, 1.1

cyrille nusmuk at users.sourceforge.net
Tue Apr 12 20:09:23 CEST 2005


Update of /cvsroot/pure-data/externals/nusmuk/msd
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24052

Added Files:
	01_msdtest.pd 02_imsdtest.pd Makefile.am help-msd.pd main.cpp 
	package.txt 
Log Message:
Nicolas objects...




--- NEW FILE: main.cpp ---


/* 
 msd - mass spring damper model for Pure Data or Max/MSP

 Written by Nicolas Montgermont for a Master's train in Acoustic,
 Signal processing and Computing Applied to Music (ATIAM, Paris 6) 
 at La Kitchen supervised by Cyrille Henry.

 Based on Pure Data by Miller Puckette and others
 Use FLEXT C++ Layer by Thomas Grill (xovo at gmx.net)
 Based on pmpd by Cyrille Henry 


 Contact : Nicolas Montgermont, montgermont at la-kitchen.fr
	   Cyrille Henry, Cyrille.Henry at la-kitchen.fr

 This program is free software; you can redistribute it and/or                
 modify it under the terms of the GNU General Public License                  
 as published by the Free Software Foundation; either version 2               
 of the License, or (at your option) any later version.                       
                                                                             
 This program is distributed in the hope that it will be useful,              
 but WITHOUT ANY WARRANTY; without even the implied warranty of               
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                
 GNU General Public License for more details.                           
                                                                              
 You should have received a copy of the GNU General Public License           
 along with this program; if not, write to the Free Software                  
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

 Version 0.01, 12.04.2005

*/

// include flext header
#include <flext.h>

#include <math.h>

// define constants
#define MSD_VERSION  0.01
#define nb_max_link   4000
#define nb_max_mass   4000
#define Id_length   20

// check for appropriate flext version
#if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 401)
#error You need at least flext version 0.4.1
#endif

#define max(a,b) ( ((a) > (b)) ? (a) : (b) ) 
#define min(a,b) ( ((a) < (b)) ? (a) : (b) )

typedef struct _mass {
	t_symbol *Id;
	t_int nbr;
	t_int mobile;
	t_float invM;
	t_float speedX;
	t_float posX;
	t_float posX2;
	t_float forceX;
	t_float out_forceX;
	char Id_string[Id_length];
} t_mass;

typedef struct _link {
	t_symbol *Id;
	t_int nbr;
	t_mass *mass1;
	t_mass *mass2;
	t_float K1, D1, D2;
	t_float longx, longueur;
	t_float distance_old;
	char Id_string[Id_length];
} t_link;

class msd:
	public flext_base
{
	FLEXT_HEADER_S(msd,flext_base,setup)	//class with setup
 
public:
	// constructor with no arguments
	msd(int argc,t_atom *argv)
	{

		nb_link = 0;
		nb_mass = 0;
		id_mass = 0;
		id_link = 0;

		// --- define inlets and outlets ---
		AddInAnything("bang, reset, etc."); 	// default inlet
		AddOutAnything("infos on masses");	// outlet for integer count
		AddOutAnything("control");		// outlet for bang
	}

protected:

// ---------------------------------------------------------------  RESET 

	void m_reset() 
	{ 
		t_int i;
		t_atom sortie[0];

		for (i=0; i<nb_mass; i++)	{
			delete mass[i];
			}
		for (i=0; i<nb_link; i++)	{
			delete link[i];
			}
		ToOutAnything(1,gensym("Reset"),0,sortie);
		nb_link = 0;
		nb_mass = 0;
		id_mass = 0;
		id_link = 0;
	}

// --------------------------------------------------------------  COMPUTE 

	void m_bang()
	{
		t_float F=0,Fx=0,distance,vitesse, X_new;
		t_int i;
		struct _mass mass_1, mass_2;
	
		for (i=0; i<nb_link; i++)	{
		// compute link forces
			distance = link[i]->mass1->posX-link[i]->mass2->posX;
			F  = link[i]->K1 * (distance - link[i]->longueur) ;	// F = k1(x1-x2)
			F += link[i]->D1 * (distance - link[i]->distance_old) ;	// F = F + D1(v1-v2)
			if (distance != 0) 	{
				Fx = F * (link[i]->mass1->posX - link[i]->mass2->posX)/distance;
			}
			link[i]->mass1->forceX -= Fx;
			link[i]->mass1->forceX -= link[i]->D2*link[i]->mass1->speedX;
			link[i]->mass2->forceX += Fx;
			link[i]->mass2->forceX -= link[i]->D2*link[i]->mass2->speedX;
			link[i]->distance_old = distance;
		}

		for (i=0; i<nb_mass; i++)
		// compute new masses position only if mobile = 1
			if (mass[i]->mobile == 1)  		{
				X_new = mass[i]->forceX * mass[i]->invM + 2*mass[i]->posX - mass[i]->posX2;
				mass[i]->posX2 = mass[i]->posX;
				mass[i]->posX = max(min(X_new,Xmax),Xmin);			// x = x + v
				mass[i]->speedX = mass[i]->posX - mass[i]->posX2;	// v = v + F/M
				}

		for (i=0; i<nb_mass; i++)	{
		// clear forces
			mass[i]->out_forceX = mass[i]->forceX;
			mass[i]->forceX = 0;
		}
	}

// --------------------------------------------------------------  MASSES

	void m_mass(int argc,t_atom *argv) 
	// add a mass
	// Id, nbr, mobile, invM, speedX, posX, forceX
	{
		t_atom sortie[5], aux[2];
		int M;

		mass[nb_mass] = new t_mass;			// new pointer
		mass[nb_mass]->Id = GetASymbol(argv[0]);	// ID
		mass[nb_mass]->mobile = GetAInt(argv[1]);	// mobile
		if (GetAInt(argv[2])==0)
			M=1;
		else M = GetAInt(argv[2]);			
		mass[nb_mass]->invM = 1/((float)M);		// invM
		mass[nb_mass]->speedX = 0;			// vx
		mass[nb_mass]->posX = GetAInt(argv[3]);		// x
		mass[nb_mass]->posX2 = GetAInt(argv[3]);		// x
		mass[nb_mass]->forceX = 0;			// Fx
		mass[nb_mass]->nbr = id_mass;			// id_nbr
		SETSYMBOL(aux,GetASymbol(argv[0]));
		atom_string(aux,mass[nb_mass]->Id_string,Id_length);
		nb_mass++ ;
		id_mass++;
		nb_mass = min ( nb_max_mass -1, nb_mass );
		SETFLOAT(&(sortie[0]),id_mass-1);
		SETSYMBOL(&(sortie[1]),GetASymbol(argv[0]));
		SETFLOAT(&(sortie[2]),mass[nb_mass-1]->mobile);
		SETFLOAT(&(sortie[3]),M);
		SETFLOAT(&(sortie[4]),mass[nb_mass-1]->posX);
		ToOutAnything(1,gensym("Mass"),5,sortie);
	}

	void m_forceX(int argc,t_atom *argv) 
	{
	// add a force to mass(es) named Id
		t_int i,aux;
		t_atom atom[2];
		char buffer[Id_length];

		SETSYMBOL(atom,GetASymbol(argv[0]));
		atom_string(atom, buffer, Id_length);
		for (i=0; i<nb_mass;i++)
		{
			aux = strcmp(buffer,mass[i]->Id_string);
			if (aux == 0)
				mass[i]->forceX += GetAFloat(argv[1]);
		}
	}

	void m_posX(int argc,t_atom *argv) 
	{
	// displace mass(es) named Id to a certain position
		t_int i,aux;
		t_atom atom[2];
		char buffer[Id_length];

		if (GetAFloat(argv[1]) < Xmax && GetAFloat(argv[1]) > Xmin)
		{
			SETSYMBOL(atom,GetASymbol(argv[0]));
			atom_string(atom, buffer, Id_length);
			for (i=0; i<nb_mass;i++)
			{
				aux = strcmp(buffer,mass[i]->Id_string);
				if (aux == 0)
					mass[i]->posX = GetAFloat(argv[1]);
			}
		}
	}

	void m_set_mobile(int argc,t_atom *argv) 
	{
	// set mass No to mobile
		t_int i,aux;
		
		aux = GetAInt(argv[0]);	
		for (i=0; i<nb_mass;i++)
			{
				if (mass[i]->nbr == aux)
					mass[i]->mobile = 1;
			}
	
	}

	void m_set_fixe(int argc,t_atom *argv) 
	{
	// set mass No to fixed
		t_int i,aux;
		
		aux = GetAInt(argv[0]);	
		for (i=0; i<nb_mass;i++)
			{
				if (mass[i]->nbr == aux)
					mass[i]->mobile = 0;
			}
	
	}

	void m_delete_mass(int argc,t_atom *argv) 
	{
	// Delete mass
	t_int i,nb_link_delete=0;
	t_atom sortie[5], aux[nb_link];
	
	for (i=0; i<nb_link;i++)	{
		if (link[i]->mass1->nbr == GetAInt(argv[0]) || link[i]->mass2->nbr == GetAInt(argv[0]))	{
			SETFLOAT(&(aux[nb_link_delete]),link[i]->nbr);
			nb_link_delete++;
		}
	}

	for (i=0; i<nb_link_delete;i++)
		m_delete_link(1,&aux[i]);

	for (i=0; i<nb_mass;i++)
		if (mass[i]->nbr == GetAInt(argv[0]))	{
			SETFLOAT(&(sortie[0]),mass[i]->nbr);
			SETSYMBOL(&(sortie[1]),mass[i]->Id);
			SETFLOAT(&(sortie[2]),mass[i]->mobile);
			SETFLOAT(&(sortie[3]),1/mass[i]->invM);
			SETFLOAT(&(sortie[4]),mass[i]->posX);
			delete mass[i];
			mass[i] = mass[nb_mass-1];
			nb_mass--;
			ToOutAnything(1,gensym("Mass deleted"),5,sortie);
			break;
		}

	}


	void m_Xmax(int argc,t_atom *argv) 
	{
	// set damping of link(s) named Id
	Xmax = GetAFloat(argv[0]);
	}

	void m_Xmin(int argc,t_atom *argv) 
	{
	// set damping of link(s) named Id
	Xmin = GetAFloat(argv[0]);
	}

// --------------------------------------------------------------  LINKS 

	void m_link(int argc,t_atom *argv) 
	// add a link
	// Id, nbr, *mass1, *mass2, K1, D1
	{
		t_atom sortie[7], aux[2];
		t_int i;

		link[nb_link] = new t_link;
		link[nb_link]->Id = GetASymbol(argv[0]);
		for (i=0; i<nb_mass;i++)
			if (mass[i]->nbr==GetAInt(argv[1]))
				link[nb_link]->mass1 = mass[i];
			else if(mass[i]->nbr==GetAInt(argv[2]))
				link[nb_link]->mass2 = mass[i];
		link[nb_link]->K1 = GetAFloat(argv[3]);
		link[nb_link]->D1 = GetAFloat(argv[4]);
		link[nb_link]->D2 = GetAFloat(argv[5]);
		link[nb_link]->longx = link[nb_link]->mass1->posX - link[nb_link]->mass2->posX;
		link[nb_link]->longueur = link[nb_link]->longx ;
		link[nb_link]->nbr = id_link;
		link[nb_link]->distance_old = link[nb_link]->longueur;
		SETSYMBOL(aux,GetASymbol(argv[0]));
		atom_string(aux,(link[nb_link]->Id_string),Id_length);
		nb_link++;
		id_link++;
		nb_link = min ( nb_max_link -1, nb_link );
		SETFLOAT(&(sortie[0]),id_link-1);
		SETSYMBOL(&(sortie[1]),link[nb_link-1]->Id);
		SETFLOAT(&(sortie[2]),GetAInt(argv[1]));
		SETFLOAT(&(sortie[3]),GetAInt(argv[2]));
		SETFLOAT(&(sortie[4]),link[nb_link-1]->K1);
		SETFLOAT(&(sortie[5]),link[nb_link-1]->D1);
		SETFLOAT(&(sortie[6]),link[nb_link-1]->D2);
		ToOutAnything(1,gensym("Link"),7,sortie);
	}

	void m_ilink(int argc,t_atom *argv) 
	// add interactor link
	// Id, nbr, Id masses1, Id masses2, K1, D1
	{
		t_atom aux[2], arglist[6];
		t_int i,j, strvalue, strvalue2, imass1[nb_mass], nbmass1=0, imass2[nb_mass], nbmass2=0;
		char buffer[Id_length], buffer2[Id_length];

		ToOutAnything(1,gensym("iLink"),0,aux);
		SETSYMBOL(aux,GetASymbol(argv[1]));
		atom_string(aux, buffer, Id_length);
		SETSYMBOL(aux,GetASymbol(argv[2]));
		atom_string(aux, buffer2, Id_length);

		for (i=0;i<nb_mass;i++)	{
			strvalue=strcmp(buffer,mass[i]->Id_string);
			strvalue2=strcmp(buffer2,mass[i]->Id_string);
			if (strvalue ==0)	{
				imass1[nbmass1]=i;
				nbmass1++;
			}
			if (strvalue2 ==0)	{
				imass2[nbmass2]=i;
				nbmass2++;
			}
		}
		
		for(i=0;i<nbmass1;i++)
			for(j=0;j<nbmass2;j++)	
				if (imass1[i] != imass2[j])	{
					SETSYMBOL(&(arglist[0]),GetASymbol(argv[0]));
					SETFLOAT(&(arglist[1]),mass[imass1[i]]->nbr);
					SETFLOAT(&(arglist[2]),mass[imass2[j]]->nbr);
					SETFLOAT(&(arglist[3]),GetAInt(argv[3]));
					SETFLOAT(&(arglist[4]),GetAFloat(argv[4]));
					SETFLOAT(&(arglist[5]),GetAFloat(argv[5]));
					m_link(6,arglist);
				}
	}

	void m_setK(int argc,t_atom *argv) 
	{
	// set rigidity of link(s) named Id
		t_int i,aux;
		t_atom atom[2];
		char buffer[Id_length];

		SETSYMBOL(atom,GetASymbol(argv[0]));
		atom_string(atom, buffer, Id_length);
		for (i=0; i<nb_link;i++)
		{
			aux = strcmp(buffer,link[i]->Id_string);
			if (aux == 0)
				link[i]->K1 = GetAFloat(argv[1]);
		}
	}

	void m_setD(int argc,t_atom *argv) 
	{
	// set damping of link(s) named Id
		t_int i,aux;
		t_atom atom[2];
		char buffer[Id_length];

		SETSYMBOL(atom,GetASymbol(argv[0]));
		atom_string(atom, buffer, Id_length);
		for (i=0; i<nb_link;i++)
		{
			aux = strcmp(buffer,link[i]->Id_string);
			if (aux == 0)
				link[i]->D1 = GetAFloat(argv[1]);
		}
	}

	void m_setD2(int argc,t_atom *argv) 
	{
	// set damping of link(s) named Id
		t_int i,aux;
		t_atom atom[2];
		char buffer[Id_length];

		SETSYMBOL(atom,GetASymbol(argv[0]));
		atom_string(atom, buffer, Id_length);
		for (i=0; i<nb_link;i++)
		{
			aux = strcmp(buffer,link[i]->Id_string);
			if (aux == 0)
				link[i]->D2 = GetAFloat(argv[1]);
		}
	}

	void m_delete_link(int argc,t_atom *argv) 
	{
	// Delete link
	t_int i;
	t_atom sortie[7];

	for (i=0; i<nb_link;i++)
		if (link[i]->nbr == GetAInt(argv[0]))	{
			SETFLOAT(&(sortie[0]),link[i]->nbr);
			SETSYMBOL(&(sortie[1]),link[i]->Id);
			SETFLOAT(&(sortie[2]),link[i]->mass1->nbr);
			SETFLOAT(&(sortie[3]),link[i]->mass2->nbr);
			SETFLOAT(&(sortie[4]),link[i]->K1);
			SETFLOAT(&(sortie[5]),link[i]->D1);
			SETFLOAT(&(sortie[6]),link[i]->D2);
			delete link[i];
			link[i]=link[nb_link-1];
			nb_link--;
			ToOutAnything(1,gensym("Link deleted"),7,sortie);
			break;
		}
	}


// --------------------------------------------------------------  GET 

	void m_get(int argc,t_atom *argv)
	// get attributes
	{
		t_int i,j, auxstring1, auxstring2, auxstring3, aux;
		t_symbol *auxarg;
		t_atom sortie[4],atom[2];
		char buffer[Id_length],masses[]="massesPos",buffer2[Id_length], forces[] = "massesForces", links[] = "linksPos";

		SETSYMBOL(atom,GetASymbol(argv[0]));
		atom_string(atom, buffer, 20);
		auxstring1 = strcmp(buffer,masses);	//auxstring1 : 0 masses, 1 else
		auxstring2 = strcmp(buffer,forces);	//auxstring2 : 0 forces, 1 else
		auxstring3 = strcmp(buffer,links);	//auxstring2 : 0 links, 1 else
		auxarg = GetASymbol(argv[1]);		//auxarg : & symbol, 0 else
		if (argc == 1)
		{
			if (auxstring1 == 0)// get all masses positions
				for (i=0; i<nb_mass; i++)
				{		atom_string(atom, buffer, Id_length);
					SETFLOAT(&sortie[0],mass[i]->posX);
					ToOutAnything(0,gensym("massesPos"),1,sortie);
				}
			else if (auxstring2 == 0)// get all masses forces
				for (i=0; i<nb_mass; i++)
				{
					SETFLOAT(&sortie[0],mass[i]->out_forceX);
					ToOutAnything(0,gensym("massesForces"),1,sortie);
				}
			else if (auxstring3 == 0)// get all links positions
				for (i=0; i<nb_link; i++)
				{
					SETFLOAT(&sortie[0],link[i]->mass1->posX);
					SETFLOAT(&sortie[2],link[i]->mass2->posX);
					ToOutAnything(0,gensym("linksPos"),2,sortie);
				}
			else 		// get all masses speeds
				for (i=0; i<nb_mass; i++)
				{
					SETFLOAT(&sortie[0],mass[i]->speedX);
					ToOutAnything(0,gensym("massesSpeeds"),1,sortie);
				}
		}
		else if (auxstring1 == 0) // get mass positions
		{
			if (auxarg == 0) // No
			{
				for (j = 1; j<argc; j++)
					for (i=0;i<nb_mass;i++)
						if (mass[i]->nbr==GetAInt(argv[j]))
						{
							SETFLOAT(&sortie[0],mass[i]->posX);
							ToOutAnything(0,gensym("massesPosNo"),1,sortie);
						}
			}
			else 		//strin		FLEXT_CADDMETHOD_(c,0,"Xmin",m_Xmin);g
			{
				for (j = 1; j<argc; j++)
				{
					SETSYMBOL(&atom[1],GetASymbol(argv[j]));
					atom_string(&atom[1], buffer2, Id_length);
					for (i=0;i<nb_mass;i++)	
					{
						
						aux = strcmp(buffer2,mass[i]->Id_string);
						if (aux==0)
						{
							SETFLOAT(&sortie[0],mass[i]->posX);
							ToOutAnything(0,gensym("massesPosId"),1,sortie);
						}
					}
				}
			}
		}
		else if (auxstring2 == 0)			 // get mass forces
		{
			if (auxarg == 0) // No
			{
				for (j = 1; j<argc; j++)
					for (i=0;i<nb_mass;i++)
						if (mass[i]->nbr==GetAInt(argv[j]))
						{
							SETFLOAT(&sortie[0],mass[i]->out_forceX);
							ToOutAnything(0,gensym("massesForcesNo"),1,sortie);
						}
			}
			else 		//string
			{
				for (j = 1; j<argc; j++)
				{
					SETSYMBOL(&atom[1],GetASymbol(argv[j]));
					atom_string(&atom[1], buffer2, Id_length);
					for (i=0;i<nb_mass;i++)	
					{
		
						aux = strcmp(buffer2,mass[i]->Id_string);
						if (aux==0)
						{
							SETFLOAT(&sortie[0],mass[i]->out_forceX);
							ToOutAnything(0,gensym("massesForcesId"),1,sortie);
						}
					}
				}
			}
		}
		else if (auxstring3 == 0)			 // get links positions
		{
			if (auxarg == 0) // No
			{
				for (j = 1; j<argc; j++)
					for (i=0;i<nb_link;i++)
						if (link[i]->nbr==GetAInt(argv[j]))
						{
							SETFLOAT(&sortie[0],link[i]->mass1->posX);
							SETFLOAT(&sortie[2],link[i]->mass2->posX);
							ToOutAnything(0,gensym("linksPosNo"),2,sortie);
						}
			}
			else 		//string
			{
				for (j = 1; j<argc; j++)
				{
					SETSYMBOL(&atom[1],GetASymbol(argv[j]));
					atom_string(&atom[1], buffer2, Id_length);
					for (i=0;i<nb_link;i++)	
					{
		
						aux = strcmp(buffer2,link[i]->Id_string);
						if (aux==0)
						{
							SETFLOAT(&sortie[0],link[i]->mass1->posX);
							SETFLOAT(&sortie[2],link[i]->mass2->posX);
							ToOutAnything(0,gensym("linksPosId"),2,sortie);
						}
					}
				}
			}
		}
		else 			 // get mass speeds
		{
			if (auxarg == 0) // No
			{
				for (j = 1; j<argc; j++)
					for (i=0;i<nb_mass;i++)
						if (mass[i]->nbr==GetAInt(argv[j]))
						{
							SETFLOAT(&sortie[0],mass[i]->speedX);
							ToOutAnything(0,gensym("massesSpeedsNo"),1,sortie);
						}
			}
			else 		//string
			{
				for (j = 1; j<argc; j++)
				{
					SETSYMBOL(&atom[1],GetASymbol(argv[j]));
					atom_string(&atom[1], buffer2, Id_length);
					for (i=0;i<nb_mass;i++)	
					{
		
						aux = strcmp(buffer2,mass[i]->Id_string);
						if (aux==0)
						{
							SETFLOAT(&sortie[0],mass[i]->speedX);
							ToOutAnything(0,gensym("massesSpeedsId"),1,sortie);
						}
					}
				}
			}
		}
		

	}

	void m_mass_dumpl()
	// List of masses positions on first outlet
	{	
		t_atom sortie[nb_mass];
		t_int i;
	
		for (i=0; i<nb_mass; i++)	{
			SETFLOAT(&(sortie[i]),mass[i]->posX);
		}
		ToOutAnything(0, gensym("massesPosL"), nb_mass, sortie);
	}

	void m_force_dumpl()
	// List of masses positions on first outlet
	{	
		t_atom sortie[nb_mass];
		t_int i;
	
		for (i=0; i<nb_mass; i++)	{
			SETFLOAT(&(sortie[i]),mass[i]->out_forceX);
		}
		ToOutAnything(0, gensym("massesForcesL"), nb_mass, sortie);
	}

	void m_info_dumpl()
	// List of masses positions on first outlet
	{	
		t_atom sortie[7];
		t_int i;
	
		for (i=0; i<nb_mass; i++)	{
			SETFLOAT(&(sortie[0]),mass[i]->nbr);
			SETSYMBOL(&(sortie[1]),mass[i]->Id);
			SETFLOAT(&(sortie[2]),mass[i]->mobile);
			SETFLOAT(&(sortie[3]),1/mass[i]->invM);
			SETFLOAT(&(sortie[4]),mass[i]->posX);
		ToOutAnything(1, gensym("Mass"), 5, sortie);
		}

		for (i=0; i<nb_link; i++)	{
			SETFLOAT(&(sortie[0]),link[i]->nbr);
			SETSYMBOL(&(sortie[1]),link[i]->Id);
			SETFLOAT(&(sortie[2]),link[i]->mass1->nbr);
			SETFLOAT(&(sortie[3]),link[i]->mass2->nbr);
			SETFLOAT(&(sortie[4]),link[i]->K1);
			SETFLOAT(&(sortie[5]),link[i]->D1);
			SETFLOAT(&(sortie[6]),link[i]->D2);
		ToOutAnything(1, gensym("Link"), 7, sortie);
		}

	}


// --------------------------------------------------------------  GLOBAL VARIABLES 

	t_link * link[nb_max_link];
	t_mass * mass[nb_max_mass];
	t_float Xmin, Xmax, Ymin, Ymax;
	int nb_link, nb_mass, id_mass, id_link;

// --------------------------------------------------------------  SETUP

private:

	static void setup(t_classid c)
	{
		// --- set up meth(i=0; i<nb_link;i++)ods (class scope) ---

		// register a bang method to the default inlet (0)
		FLEXT_CADDBANG(c,0,m_bang);

		// set up tagged methods for the default inlet (0)
		// the underscore _ after CADDMETHOD indicates that a message tag is used
		// no, variable list or anything and all single arguments are recognized automatically, ...
		FLEXT_CADDMETHOD_(c,0,"reset",m_reset);
		FLEXT_CADDMETHOD_(c,0,"forceX",m_forceX);
		FLEXT_CADDMETHOD_(c,0,"posX",m_posX);
		FLEXT_CADDMETHOD_(c,0,"Xmax",m_Xmax);
		FLEXT_CADDMETHOD_(c,0,"Xmin",m_Xmin);
		FLEXT_CADDMETHOD_(c,0,"setMobile",m_set_mobile);
		FLEXT_CADDMETHOD_(c,0,"setFixed",m_set_fixe);
		FLEXT_CADDMETHOD_(c,0,"setK",m_setK);
		FLEXT_CADDMETHOD_(c,0,"setD",m_setD);
		FLEXT_CADDMETHOD_(c,0,"setD2",m_setD2);
		FLEXT_CADDMETHOD_(c,0,"mass",m_mass);
		FLEXT_CADDMETHOD_(c,0,"link",m_link);
		FLEXT_CADDMETHOD_(c,0,"iLink",m_ilink);
		FLEXT_CADDMETHOD_(c,0,"get",m_get);
		FLEXT_CADDMETHOD_(c,0,"deleteLink",m_delete_link);
		FLEXT_CADDMETHOD_(c,0,"deleteMass",m_delete_mass);
		FLEXT_CADDMETHOD_(c,0,"massesPosL",m_mass_dumpl);
		FLEXT_CADDMETHOD_(c,0,"infosL",m_info_dumpl);
		FLEXT_CADDMETHOD_(c,0,"massesForcesL",m_force_dumpl);
	}

	// for every registered method a callback has to be declared
	FLEXT_CALLBACK(m_bang)
	FLEXT_CALLBACK(m_mass_dumpl)
	FLEXT_CALLBACK(m_info_dumpl)
	FLEXT_CALLBACK(m_force_dumpl)
	FLEXT_CALLBACK(m_reset)
	FLEXT_CALLBACK_V(m_set_mobile)
	FLEXT_CALLBACK_V(m_set_fixe)
	FLEXT_CALLBACK_V(m_mass)
	FLEXT_CALLBACK_V(m_link)
	FLEXT_CALLBACK_V(m_ilink)
	FLEXT_CALLBACK_V(m_Xmax)
	FLEXT_CALLBACK_V(m_Xmin)
	FLEXT_CALLBACK_V(m_setK)
	FLEXT_CALLBACK_V(m_setD)
	FLEXT_CALLBACK_V(m_setD2)
	FLEXT_CALLBACK_V(m_forceX)
	FLEXT_CALLBACK_V(m_posX)
	FLEXT_CALLBACK_V(m_get)
	FLEXT_CALLBACK_V(m_delete_link)
	FLEXT_CALLBACK_V(m_delete_mass)
};

// instantiate the class (constructor has a variable argument list)
FLEXT_NEW_V("msd",msd)



--- NEW FILE: help-msd.pd ---
#N canvas 0 0 794 877 10;
#X obj 33 821 msd;
#X obj 62 14 cnv 15 610 305 empty empty CREATION 20 12 0 14 -262131
-66577 0;
#X msg 79 43 reset;
#X text 249 74 Add a mass;
#X text 335 75 \$1 : Id (symbol);
#X text 334 95 \$2 : fixed or mobile (0/1);
#X text 334 113 \$3 : mass;
#X text 334 151 \$1 : Id (symbol);
#X text 246 151 Add a link;
#X text 333 171 \$2 : creation No of mass1;
#X text 333 189 \$3 : creation No of mass2;
#X text 332 207 \$4 : rigidity;
#X text 251 44 Delete all masses and links;
#X text 332 225 \$5 : viscosity;
#X text 332 242 \$6 : damping;
#X obj 62 324 cnv 15 610 60 empty empty COMPUTATION 20 12 0 14 -261689
-66577 0;
#X msg 82 353 bang;
#X text 235 353 Compute new masses positions;
#X obj 61 388 cnv 15 610 220 empty empty DYNAMIC_SETTING 20 12 0 14
-262131 -66577 0;
#X msg 169 410 setD \$1 \$2;
#X text 354 428 \$1 : Id (symbol);
#X text 354 446 \$2 : New value;
#X msg 87 410 setK \$1 \$2;
#X text 350 482 \$1 : Id (symbol);
#X text 350 500 \$2 : New value;
#X text 348 539 \$1 : Id (symbol);
#X text 348 557 \$2 : New value;
#X msg 87 462 posX \$1 \$2;
#X text 350 464 Set position of mass(es);
#X text 347 522 Add force on mass(es);
#X msg 85 521 forceX \$1 \$2;
#X msg 255 410 setD2 \$1 \$2;
#X text 354 410 Set rigidity \, viscosity or damping of link(s);
#X obj 60 617 cnv 15 610 198 empty empty GET_ATTRIBUTES 20 12 0 14
-261689 -66577 0;
#X msg 146 644 massePosL;
#X msg 146 672 masseForcesL;
#X text 247 644 output all masses positions in a list on outlet No
1;
#X text 246 673 output all masses forces in a list on outlet No 1;
#X msg 145 710 get \$1 \$2;
#X text 248 711 Get specific attribute;
#X text 248 736 \$1 : Attribute type ( massesPos / massesSpeeds / massesForces
/ linksPos );
#X text 248 773 \$2 : Id (symbol or creations numbers);
#X text 334 131 \$4 : position;
#X msg 79 74 mass \$1 \$2 \$3 \$4;
#X msg 76 151 link \$1 \$2 \$3 \$4 \$5 \$6;
#X msg 75 258 deleteMass \$1;
#X text 240 260 Delete a mass and associated links;
#X text 330 277 \$1 : Creation No of mass;
#X msg 74 294 deleteLink \$1;
#X text 239 296 Delete a link;
#X text 340 296 \$1 : Creation No of link;
#X msg 143 793 infosL;
#X text 246 793 Get infos on all masses and links on outlet No 2;
#X msg 84 573 Xmin \$1 \, Xmax \$1;
#X text 347 576 Set minimimum and maximum X of masses;
#X text 347 593 \$1 : Value;
#X connect 2 0 0 0;
#X connect 16 0 0 0;
#X connect 22 0 0 0;
#X connect 27 0 0 0;
#X connect 30 0 0 0;
#X connect 34 0 0 0;
#X connect 35 0 0 0;
#X connect 38 0 0 0;
#X connect 43 0 0 0;
#X connect 44 0 0 0;
#X connect 45 0 0 0;
#X connect 48 0 0 0;
#X connect 51 0 0 0;

--- NEW FILE: 01_msdtest.pd ---
#N canvas 489 48 887 847 10;
#X obj 53 15 loadbang;
#X obj 299 517 print msd;
#X obj 52 490 msd --------------------------------;
#X obj 52 243 tgl 25 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
;
#X text 83 242 ON / OFF;
#X obj 45 305 cnv 15 700 60 empty empty empty 20 12 0 14 -261689 -66577
0;
#X obj 52 312 metro 50;
#X text 474 328 COMPUTE AND GET MASSES POSITIONS;
#X obj 151 28 cnv 15 595 270 empty empty empty 20 12 0 14 -262131 -66577
0;
#X obj 167 274 t a;
#X obj 167 33 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262131 -1
-1;
#X msg 253 78 reset;
#X msg 218 153 mass mob 1 \$1 \$2;
#X msg 201 181 Xmax 100 \, Xmin 0;
#X msg 235 104 mass fix 0 100 80;
#X msg 218 129 100 65 \, 100 50 \, 100 35 \, 100 20;
#X text 490 126 CREATION : 5 MASSES \, 4 LINKS;
#X obj 46 380 cnv 15 700 90 empty empty empty 20 12 0 14 -262131 -66577
0;
#X msg 176 385 setD souple 0.01;
#X msg 66 384 setK souple 1;
#X msg 176 407 setD souple 1;
#X msg 66 406 setK souple 2;
#X text 455 399 SET RIGIDITY AND VISCOSITY OF LINKS;
#X text 455 438 ADD FORCE ON ALL MOBILE MASSES;
#X msg 184 153 0;
#X obj 45 576 cnv 15 300 200 empty empty empty 20 12 0 14 -261689 -66577
0;
#X obj 88 590 vsl 15 128 0 100 0 0 empty empty empty 0 -8 0 8 -261689
-1 -1 7759 1;
#X obj 111 590 vsl 15 128 0 100 0 0 empty empty empty 0 -8 0 8 -261689
-1 -1 5259 1;
#X obj 66 590 vsl 15 128 0 100 0 0 empty empty empty 0 -8 0 8 -261689
-1 -1 10160 1;
#X msg 52 736 posX fix \$1;
#X obj 156 590 vsl 15 128 0 100 0 0 empty empty empty 0 -8 0 8 -261689
-1 -1 983 1;
#X obj 134 590 vsl 15 128 0 100 0 0 empty empty empty 0 -8 0 8 -261689
-1 -1 2910 1;
#X text 199 638 MOVE FIRST SLIDER;
#X text 182 662 TO MOVE THE FIXED MASS;
#X msg 184 248 link souple \$1 \$2 10 0.5 0.5;
#X msg 184 226 0 1 \, 1 2 \, 2 3 \, 3 4;
#X msg 66 438 forceX mob 300;
#X msg 180 438 forceX mob -300;
#X obj 167 55 t b b b b b b;
#X text 205 34 RESET;
#X obj 52 523 route massesPosL;
#X msg 52 335 bang \, massesPosL;
#X obj 52 545 unpack f f f f f;
#X connect 0 0 38 0;
#X connect 2 0 40 0;
#X connect 2 1 1 0;
#X connect 3 0 6 0;
#X connect 6 0 41 0;
#X connect 9 0 2 0;
#X connect 10 0 38 0;
#X connect 11 0 9 0;
#X connect 12 0 9 0;
#X connect 13 0 9 0;
#X connect 14 0 9 0;
#X connect 15 0 12 0;
#X connect 18 0 2 0;
#X connect 19 0 2 0;
#X connect 20 0 2 0;
#X connect 21 0 2 0;
#X connect 24 0 3 0;
#X connect 28 0 29 0;
#X connect 29 0 2 0;
#X connect 34 0 9 0;
#X connect 35 0 34 0;
#X connect 36 0 2 0;
#X connect 37 0 2 0;
#X connect 38 0 36 0;
#X connect 38 0 3 0;
#X connect 38 1 35 0;
#X connect 38 1 24 0;
#X connect 38 2 13 0;
#X connect 38 3 15 0;
#X connect 38 4 14 0;
#X connect 38 5 11 0;
#X connect 40 0 42 0;
#X connect 40 1 1 0;
#X connect 41 0 2 0;
#X connect 42 0 28 0;
#X connect 42 1 26 0;
#X connect 42 2 27 0;
#X connect 42 3 31 0;
#X connect 42 4 30 0;

--- NEW FILE: package.txt ---
NAME=msd
SRCS=main.cpp

--- NEW FILE: 02_imsdtest.pd ---
#N canvas 489 48 887 847 10;
#X obj 53 15 loadbang;
#X obj 299 517 print msd;
#X obj 52 490 msd --------------------------------;
#X obj 52 243 tgl 25 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
;
#X text 83 242 ON / OFF;
#X obj 45 305 cnv 15 700 60 empty empty empty 20 12 0 14 -261689 -66577
0;
#X obj 52 312 metro 50;
#X text 474 328 COMPUTE AND GET MASSES POSITIONS;
#X obj 151 28 cnv 15 595 270 empty empty empty 20 12 0 14 -262131 -66577
0;
#X obj 167 274 t a;
#X obj 167 33 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262131 -1
-1;
#X msg 253 78 reset;
#X msg 218 153 mass mob 1 \$1 \$2;
#X msg 201 181 Xmax 100 \, Xmin 0;
#X msg 235 104 mass fix 0 100 80;
#X msg 218 129 100 65 \, 100 50 \, 100 35 \, 100 20;
#X obj 46 380 cnv 15 700 90 empty empty empty 20 12 0 14 -262131 -66577
0;
#X msg 176 385 setD souple 0.01;
#X msg 66 384 setK souple 1;
#X msg 176 407 setD souple 1;
#X msg 66 406 setK souple 2;
#X text 455 399 SET RIGIDITY AND VISCOSITY OF LINKS;
#X text 455 438 ADD FORCE ON ALL MOBILE MASSES;
#X msg 184 153 0;
#X obj 45 576 cnv 15 300 200 empty empty empty 20 12 0 14 -261689 -66577
0;
#X obj 88 590 vsl 15 128 0 100 0 0 empty empty empty 0 -8 0 8 -261689
-1 -1 8228 1;
#X obj 111 590 vsl 15 128 0 100 0 0 empty empty empty 0 -8 0 8 -261689
-1 -1 6323 1;
#X obj 66 590 vsl 15 128 0 100 0 0 empty empty empty 0 -8 0 8 -261689
-1 -1 10160 1;
#X msg 52 736 posX fix \$1;
#X obj 156 590 vsl 15 128 0 100 0 0 empty empty empty 0 -8 0 8 -261689
-1 -1 2513 1;
#X obj 134 590 vsl 15 128 0 100 0 0 empty empty empty 0 -8 0 8 -261689
-1 -1 4418 1;
#X text 199 638 MOVE FIRST SLIDER;
#X text 182 662 TO MOVE THE FIXED MASS;
#X msg 66 438 forceX mob 300;
#X msg 180 438 forceX mob -300;
#X obj 167 55 t b b b b b b;
#X text 205 34 RESET;
#X obj 52 523 route massesPosL;
#X msg 52 335 bang \, massesPosL;
#X obj 52 545 unpack f f f f f;
#X msg 184 223 iLink inter fix mob 10 2.5 0.5;
#X text 490 126 CREATION : 5 MASSES \, 1 iLINK;
#X connect 0 0 35 0;
#X connect 2 0 37 0;
#X connect 2 1 1 0;
#X connect 3 0 6 0;
#X connect 6 0 38 0;
#X connect 9 0 2 0;
#X connect 10 0 35 0;
#X connect 11 0 9 0;
#X connect 12 0 9 0;
#X connect 13 0 9 0;
#X connect 14 0 9 0;
#X connect 15 0 12 0;
#X connect 17 0 2 0;
#X connect 18 0 2 0;
#X connect 19 0 2 0;
#X connect 20 0 2 0;
#X connect 23 0 3 0;
#X connect 27 0 28 0;
#X connect 28 0 2 0;
#X connect 33 0 2 0;
#X connect 34 0 2 0;
#X connect 35 0 33 0;
#X connect 35 0 3 0;
#X connect 35 1 23 0;
#X connect 35 1 40 0;
#X connect 35 2 13 0;
#X connect 35 3 15 0;
#X connect 35 4 14 0;
#X connect 35 5 11 0;
#X connect 37 0 39 0;
#X connect 37 1 1 0;
#X connect 38 0 2 0;
#X connect 39 0 27 0;
#X connect 39 1 25 0;
#X connect 39 2 26 0;
#X connect 39 3 30 0;
#X connect 39 4 29 0;
#X connect 40 0 9 0;

--- NEW FILE: Makefile.am ---
#
# automake template
# added by tim blechmann
#

NAME = msd2

BUILT_SOURCES = main.cpp

EXTRA_DIST = main.cpp \
	$(NAME).mcp \
	$(NAME).vcproj

CXXFLAGS  = @CXXFLAGS@ \
	@OPT_FLAGS@ \
	@INCLUDEDIR@ \
	-I../../source \
	$(DEFS) \
	-DFLEXT_SHARED

LDFLAGS = @DYNAMIC_LDFLAGS@ @LDFLAGS@ \
	$(patsubst %,-framework %,$(FRAMEWORKS))

LIBS = @LIBS@ -lflext-pd

FRAMEWORKS = @FRAMEWORKS@

TARGETDIR = @TARGETDIR@

TARGET =$(NAME). at EXTENSION@

OBJECTS = $(patsubst %.cpp,./%. at OBJEXT@,$(BUILT_SOURCES))

SYSDIR = @SYSDIR@


# ----------------------------- targets --------------------------------

all-local: $(OBJECTS)
	$(CXX) $(LDFLAGS) ./*. at OBJEXT@ $(LIBS) -o ../$(TARGETDIR)/$(TARGET)
	strip --strip-unneeded ../$(TARGETDIR)/$(TARGET)

./%. at OBJEXT@ : %.cpp 
	$(CXX) -c $(CXXFLAGS) $< -o $@

clean-local:
	rm -f ../$(TARGETDIR)/$(TARGET)
	rm -f ./$(OBJECTS)

install-exec-local:
	install ../$(TARGET) $(SYSDIR)extra





More information about the Pd-cvs mailing list