aboutsummaryrefslogtreecommitdiff
path: root/pmpd.c
diff options
context:
space:
mode:
authorCyrille Henry <nusmuk@users.sourceforge.net>2011-02-08 21:00:50 +0000
committerCyrille Henry <nusmuk@users.sourceforge.net>2011-02-08 21:00:50 +0000
commitc70ffd6a91d1d898e9ca6af934198d7836e1951b (patch)
treee09c185546fee5049082663a4692e9bc9f898fcf /pmpd.c
parenta41666ea5b8d26b81da4ec2629658d851dc0ee16 (diff)
the pmpd object should be compatible with msd
svn path=/trunk/externals/pmpd/; revision=14878
Diffstat (limited to 'pmpd.c')
-rw-r--r--pmpd.c913
1 files changed, 636 insertions, 277 deletions
diff --git a/pmpd.c b/pmpd.c
index 78c2f7f..577a3f8 100644
--- a/pmpd.c
+++ b/pmpd.c
@@ -3,9 +3,9 @@
pmpd = physical modeling for pure data
- Written by Cyrille Henry (cyrille.henry@la-kitchen.fr)
+ Written by Cyrille Henry (ch@chnry.net)
- Get sources at http://drpichon.free.fr/pure-data/physical-modeling/
+ Get sources on pd svn on sourceforge.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -28,301 +28,714 @@
*/
#ifndef VERSION
-#define VERSION "0.07"
+#define VERSION "0.10"
#endif
#include "m_pd.h"
-#include "stdio.h"
+#include "stdio.h"
#ifndef __DATE__
#define __DATE__ ""
#endif
-#define nb_max_link 2000
-#define nb_max_mass 2000
-#define nb_max_out 200
-#define nb_max_in 200
-#define nb_max_outlet 20
-#define nb_max_inlet 20 // hard-coded on the methods definition
+#define nb_max_link 1000000
+#define nb_max_mass 100000
#define max(a,b) ( ((a) > (b)) ? (a) : (b) )
#define min(a,b) ( ((a) < (b)) ? (a) : (b) )
-
-/*
-#include "masse.c"
-#include "lia.c"
-#include "masse2D.c"
-#include "lia2D.c"
-#include "masse3D.c"
-#include "lia3D.c"
-
-#include "iAmbient2D.c"
-#include "iLine2D.c"
-#include "iSeg2D.c"
-#include "iCircle2D.c"
-
-#include "tSquare2D.c"
-#include "tLine2D.c"
-#include "tSeg2D.c"
-#include "tCircle2D.c"
-#include "tLia2D.c"
-
-#include "iAmbient3D.c"
-#include "iSphere3D.c"
-#include "iPlane3D.c"
-#include "iCircle3D.c"
-#include "iCylinder3D.c"
-
-
-#include "tCube3D.c"
-#include "tSphere3D.c"
-#include "tPlane3D.c"
-#include "tCircle3D.c"
-#include "tCylinder3D.c"
-#include "tLia3D.c"
-
-#include "pmpd~.c"
-*/
+#define sign(a) ( ((a) < 0) ? -1 : 1 )
static t_class *pmpd_class;
-
+
typedef struct _mass {
- t_int Id;
+ t_symbol *Id;
+ int mobile;
t_float invM;
t_float speedX;
t_float posX;
t_float forceX;
+ int num;
} foo;
typedef struct _link {
- t_int Id;
+ t_symbol *Id;
struct _mass *mass1;
struct _mass *mass2;
- t_float Ke, K1, D1, K2, D2;
+ t_float K;
+ t_float D;
+ t_float L;
+ t_float Pow;
+ t_float Lmin;
+ t_float Lmax;
+ t_float distance;
} foo1 ;
-typedef struct _out {
- // TODO ajouter un type pour diferencier les outlets en forces et celles en position
- t_int Id;
- t_int nbr_outlet;
- struct _mass *mass1;
- t_float influence;
-} foo2;
-
-typedef struct _in {
- // TODO ajouter un type pour diferencier les inlets en forces et celles en position
- t_int Id;
- t_int nbr_inlet;
- struct _mass *mass1;
- t_float influence;
-} foo3;
-
typedef struct _pmpd
{
t_object x_obj;
struct _link link[nb_max_link];
struct _mass mass[nb_max_mass];
- struct _out out[nb_max_out];
- struct _in in[nb_max_in];
- t_float outlet[nb_max_outlet];
- t_outlet *taboutlet[nb_max_outlet];
- t_float inlet[nb_max_inlet];
- int nb_link, nb_mass, nb_outlet, nb_inlet, nb_in, nb_out;
+ t_outlet *main_outlet;
+ t_outlet *info_outlet;
+ int nb_link;
+ int nb_mass;
+ t_float minX, maxX;
} t_pmpd;
void pmpd_bang(t_pmpd *x)
///////////////////////////////////////////////////////////////////////////////////
-// this part is doing all the job!
+// this part is doing all the PM
{
- t_float F;
+ t_float F, L;
t_int i;
- struct _mass mass_1, mass_2;
-
- for (i=0; i<x->nb_in; i++)
- // compute input
- {
- x->in[i].mass1->forceX += x->in[i].influence * x->inlet[x->in[i].nbr_inlet];
- }
-
- for (i=0; i<x->nb_inlet; i++)
- // clear inlet[i]
- {
- x->inlet[i]=0;
- }
-
- for (i=0; i<x->nb_link; i++)
- // comput link forces
- {
- F = x->link[i].K1 * ( x->link[i].mass1->posX - x->link[i].mass2->posX ) ;
- F += x->link[i].D1 * ( x->link[i].mass1->speedX - x->link[i].mass2->speedX) ;
- x->link[i].mass1->forceX -= F;
- x->link[i].mass2->forceX += F;
- }
for (i=1; i<x->nb_mass; i++)
// compute new masses position
- if (x->mass[i].Id >0) // only if Id >0
- {
+ if (x->mass[i].mobile > 0) // only if mobile
+ {
x->mass[i].speedX += x->mass[i].forceX * x->mass[i].invM;
x->mass[i].forceX = 0;
x->mass[i].posX += x->mass[i].speedX ;
- }
+ x->mass[i].posX = min(x->maxX,max(x->minX,x->mass[i].posX));
+ }
- for (i=0; i<x->nb_out; i++)
- // compute output point
- {
- x->outlet[x->out[i].nbr_outlet] += x->out[i].mass1->posX * x->out[i].influence ;
- }
-
-// for (i=0; i<x->nb_outlet; i++)
- for (i=x->nb_outlet-1; i>=0; i--)
- // output everything on the corresponding outlet
+ for (i=0; i<x->nb_link; i++)
+ // comput link forces
{
- outlet_float(x->taboutlet[i], x->outlet[i]);
- x->outlet[i] = 0;
+ L = x->link[i].mass1->posX - x->link[i].mass2->posX;
+ L -= x->link[i].L;
+ if ( (L > x->link[i].Lmin) & (L < x->link[i].Lmax) & (L!=0))
+ {
+ F = x->link[i].D * (L - x->link[i].distance) ;
+ x->link[i].distance=L;
+
+ if (L-x->link[i].L >= 0)
+ L = pow(L, x->link[i].Pow);
+ else
+ L = -pow(-L, x->link[i].Pow);
+
+ F += x->link[i].K * L;
+ x->link[i].mass1->forceX -= F;
+ x->link[i].mass2->forceX += F;
+ }
}
}
-void pmpd_forceX(t_pmpd *x, t_float nbr_mass, t_float force)
+void pmpd_forceX(t_pmpd *x, t_symbol *s, int argc, t_atom *argv)
{
// add a force to a specific mass
- nbr_mass = max(0, min( x->nb_mass, (int)nbr_mass));
- x->mass[(int)nbr_mass].forceX += force;
+ int tmp, i;
+
+ if ( ( argv[0].a_type == A_FLOAT ) & ( argv[1].a_type == A_FLOAT ) )
+ {
+ tmp = atom_getfloatarg(0, argc, argv);
+ tmp = max(0, min( x->nb_mass-1, tmp));
+ x->mass[tmp].forceX += atom_getfloatarg(1, argc, argv);
+ }
+ if ( ( argv[0].a_type == A_SYMBOL ) & ( argv[1].a_type == A_FLOAT ) )
+ {
+ for (i=0; i< x->nb_mass; i++)
+ {
+ if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+ {
+ x->mass[i].forceX += atom_getfloatarg(1, argc, argv);
+ }
+ }
+ }
}
-void pmpd_posX(t_pmpd *x, t_float nbr_mass, t_float posX)
+void pmpd_posX(t_pmpd *x, t_symbol *s, int argc, t_atom *argv)
{
// displace a mass to a certain position
- nbr_mass = max(0, min( x->nb_mass, (int)nbr_mass));
- x->mass[(int)nbr_mass].posX = posX;
+ int tmp, i;
+
+ if ( ( argv[0].a_type == A_FLOAT ) & ( argv[1].a_type == A_FLOAT ) )
+ {
+ tmp = atom_getfloatarg(0, argc, argv);
+ tmp = max(0, min( x->nb_mass-1, tmp));
+ x->mass[tmp].posX = atom_getfloatarg(1, argc, argv);
+ x->mass[tmp].speedX = 0; // ??? TODO : esce la bonne chose a faire?
+ }
+ if ( ( argv[0].a_type == A_SYMBOL ) & ( argv[1].a_type == A_FLOAT ) )
+ {
+ for (i=0; i< x->nb_mass; i++)
+ {
+ if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+ {
+ x->mass[i].posX = atom_getfloatarg(1, argc, argv);
+ x->mass[i].speedX = 0; // ??? TODO : esce la bonne chose a faire?
+ }
+ }
+ }
}
-void pmpd_mass(t_pmpd *x, t_float Id, t_float M, t_float posX)
+void pmpd_mass(t_pmpd *x, t_symbol *Id, t_float mobile, t_float M, t_float posX )
// add a mass
// Id, invM speedX posX forceX
{
- if (M==0) M=1;
- x->mass[x->nb_mass].Id = (int)Id;
+ if (M<=0) M=1;
+ x->mass[x->nb_mass].Id = Id;
+ x->mass[x->nb_mass].mobile = (int)mobile;
x->mass[x->nb_mass].invM = 1/M;
x->mass[x->nb_mass].speedX = 0;
x->mass[x->nb_mass].posX = posX;
x->mass[x->nb_mass].forceX = 0;
+ x->mass[x->nb_mass].num = x->nb_mass;
x->nb_mass++ ;
x->nb_mass = min ( nb_max_mass -1, x->nb_mass );
}
-void pmpd_link(t_pmpd *x, t_float Id, t_float mass_1, t_float mass_2, t_float K1, t_float D1)
+void pmpd_create_link(t_pmpd *x, t_symbol *Id, int mass1, int mass2, t_float K, t_float D, t_float Pow, t_float Lmin, t_float Lmax)
+{ // create a link based on mass number
+
+ if ((x->nb_mass>0) & (mass1 != mass2) & (mass1 >= 0) & (mass2 >= 0) & (mass1 < x->nb_mass) & (mass2 < x->nb_mass) )
+ {
+ x->link[x->nb_link].Id = Id;
+ x->link[x->nb_link].mass1 = &x->mass[mass1];
+ x->link[x->nb_link].mass2 = &x->mass[mass2];
+ x->link[x->nb_link].K = K;
+ x->link[x->nb_link].D = D;
+ x->link[x->nb_link].L = x->mass[mass1].posX - x->mass[mass2].posX;
+ x->link[x->nb_link].Pow = Pow;
+ x->link[x->nb_link].Lmin = Lmin;
+ x->link[x->nb_link].Lmax = Lmax;
+ x->link[x->nb_link].distance = 0;
+
+ x->nb_link++ ;
+ x->nb_link = min ( nb_max_link -1, x->nb_link );
+ }
+}
+
+void pmpd_link(t_pmpd *x, t_symbol *s, int argc, t_atom *argv)
// add a link
-// Id, *mass1, *mass2, Ke, K1, D1, K2, D2;
+// Id, *mass1, *mass2, K, D, Pow, Lmin, Lmax;
+{
+ int i, j;
+
+ t_symbol *Id = atom_getsymbolarg(0,argc,argv);
+ int mass1 = atom_getfloatarg(1, argc, argv);
+ int mass2 = atom_getfloatarg(2, argc, argv);
+ t_float K = atom_getfloatarg(3, argc, argv);
+ t_float D = atom_getfloatarg(4, argc, argv);
+ t_float Pow = 1;
+ if (argc > 5) Pow = atom_getfloatarg(5, argc, argv);
+ t_float Lmin = -1000000;
+ if (argc > 6) Lmin = atom_getfloatarg(6, argc, argv);
+ t_float Lmax = 1000000;
+ if (argc > 7) Lmax = atom_getfloatarg(7, argc, argv);
+// post("%d,%d, %f,%f", mass1, mass2, K, D);
+
+ if ( ( argv[1].a_type == A_FLOAT ) & ( argv[2].a_type == A_FLOAT ) )
+ {
+ pmpd_create_link(x, Id, mass1, mass2, K, D, Pow, Lmin, Lmax);
+ }
+ else
+ if ( ( argv[1].a_type == A_SYMBOL ) & ( argv[2].a_type == A_FLOAT ) )
+ {
+ for (i=0; i< x->nb_mass; i++)
+ {
+ if ( atom_getsymbolarg(1,argc,argv) == x->mass[i].Id)
+ {
+ pmpd_create_link(x, Id, i, mass2, K, D, Pow, Lmin, Lmax);
+ }
+ }
+ }
+ else
+ if ( ( argv[1].a_type == A_FLOAT ) & ( argv[2].a_type == A_SYMBOL ) )
+ {
+ for (i=0; i< x->nb_mass; i++)
+ {
+ if ( atom_getsymbolarg(2,argc,argv) == x->mass[i].Id)
+ {
+ pmpd_create_link(x, Id, mass1, i, K, D, Pow, Lmin, Lmax);
+ }
+ }
+ }
+ else
+ if ( ( argv[1].a_type == A_SYMBOL ) & ( argv[2].a_type == A_SYMBOL ) )
+ {
+ for (i=0; i< x->nb_mass; i++)
+ {
+ for (j=0; j< x->nb_mass; j++)
+ {
+ if ( (atom_getsymbolarg(1,argc,argv) == x->mass[i].Id)&(atom_getsymbolarg(2,argc,argv) == x->mass[j].Id))
+ {
+ pmpd_create_link(x, Id, i, j, K, D, Pow, Lmin, Lmax);
+ }
+ }
+ }
+ }
+}
+
+void pmpd_reset(t_pmpd *x)
{
+ x->nb_link = 0;
+ x->nb_mass = 0;
+ x->minX = -1000000;
+ x->maxX = 1000000;
+}
- x->link[x->nb_link].Id = (int)Id;
- x->link[x->nb_link].mass1 = &x->mass[max(0, min ( x->nb_mass, (int)mass_1))];
- x->link[x->nb_link].mass2 = &x->mass[max(0, min ( x->nb_mass, (int)mass_2))];
- x->link[x->nb_link].K1 = K1;
- x->link[x->nb_link].D1 = D1;
+void pmpd_infosL(t_pmpd *x)
+{
+ int i;
+ post("list of mass");
+ post("number, Id, mobile, mass, position, speed, forces");
+ for(i=0; i < x->nb_mass; i++)
+ {
+ post("masse %i: %s, %d, %f, %f, %f, %f",i, x->mass[i].Id->s_name, x->mass[i].mobile, 1/x->mass[i].invM, x->mass[i].posX, x->mass[i].speedX, x->mass[i].forceX );
+ }
+
+ post("list of link");
+ post("number, Id, mass1, mass2, K, D, Pow, L, Lmin, Lmax");
+ for(i=0; i < x->nb_link; i++)
+ {
+ post("link %i: %s, %i, %i, %f, %f, %f, %f, %f, %f", i, x->link[i].Id->s_name, x->link[i].mass1->num, x->link[i].mass2->num, x->link[i].K, x->link[i].D, x->link[i].Pow, x->link[i].L, x->link[i].Lmin, x->link[i].Lmax);
+ }
+}
- x->nb_link++ ;
- x->nb_link = min ( nb_max_link -1, x->nb_link );
+void pmpd_minX(t_pmpd *x, t_float min)
+{
+ x->minX = min;
}
-void pmpd_out(t_pmpd *x, t_float Id, t_float nb_outlet, t_float mass_1, t_float influence)
-// add an output point
-// Id, nbr_outlet, *mass1, influence;
+void pmpd_maxX(t_pmpd *x, t_float max)
{
- x->out[x->nb_out].Id = (int)Id;
- x->out[x->nb_out].nbr_outlet = max(0, min( x->nb_outlet,(int)nb_outlet));
- x->out[x->nb_out].mass1 = &x->mass[max(0, min ( x->nb_mass, (int)mass_1))];
- x->out[x->nb_out].influence = influence;
+ x->maxX = max;
+}
- x->nb_out++ ;
- x->nb_out = min ( nb_max_out - 1, x->nb_out );
+void pmpd_setFixed(t_pmpd *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int tmp, i;
+
+ if ( argv[0].a_type == A_FLOAT )
+ {
+ tmp = atom_getfloatarg(0, argc, argv);
+ tmp = max(0, min( x->nb_mass-1, tmp));
+ x->mass[tmp].mobile = 0;
+ }
+ if ( argv[0].a_type == A_SYMBOL )
+ {
+ for (i=0; i< x->nb_mass; i++)
+ {
+ if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+ {
+ x->mass[i].mobile = 0;
+ }
+ }
+ }
}
-void pmpd_in(t_pmpd *x, t_float Id, t_float nb_inlet, t_float mass_1, t_float influence)
-//add an input point
-// Id, nbr_inlet, *mass1, influence;
+void pmpd_setMobile(t_pmpd *x, t_symbol *s, int argc, t_atom *argv)
{
- x->in[x->nb_in].Id = (int)Id;
- x->in[x->nb_in].nbr_inlet = max(0, min( x->nb_inlet,(int)nb_inlet));
- x->in[x->nb_in].mass1 = &x->mass[max(0, min ( x->nb_mass, (int)mass_1))];
- x->in[x->nb_in].influence = influence;
+ int tmp, i;
+
+ if ( argv[0].a_type == A_FLOAT )
+ {
+ tmp = atom_getfloatarg(0, argc, argv);
+ tmp = max(0, min( x->nb_mass-1, tmp));
+ x->mass[tmp].mobile = 1;
+ }
+ if ( argv[0].a_type == A_SYMBOL )
+ {
+ for (i=0; i< x->nb_mass; i++)
+ {
+ if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+ {
+ x->mass[i].mobile = 1;
+ }
+ }
+ }
+}
- x->nb_in++;
- x->nb_in = min ( nb_max_in - 1, x->nb_in );
+void pmpd_setK(t_pmpd *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int tmp, i;
+
+ if ( ( argv[0].a_type == A_FLOAT ) & ( argv[1].a_type == A_FLOAT ) )
+ {
+ tmp = atom_getfloatarg(0, argc, argv);
+ tmp = max(0, min( x->nb_link-1, tmp));
+ x->link[tmp].K = atom_getfloatarg(1, argc, argv);
+ }
+ if ( ( argv[0].a_type == A_SYMBOL ) & ( argv[1].a_type == A_FLOAT ) )
+ {
+ for (i=0; i< x->nb_link; i++)
+ {
+ if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+ {
+ x->link[i].K = atom_getfloatarg(1, argc, argv);
+ }
+ }
+ }
}
-void pmpd_forceX_1(t_pmpd *x, t_float force)
- { x->inlet[0] += force; }
-void pmpd_forceX_2(t_pmpd *x, t_float force)
- { x->inlet[1] += force; }
-void pmpd_forceX_3(t_pmpd *x, t_float force)
- { x->inlet[2] += force; }
-void pmpd_forceX_4(t_pmpd *x, t_float force)
- { x->inlet[3] += force; }
-void pmpd_forceX_5(t_pmpd *x, t_float force)
- { x->inlet[4] += force; }
-void pmpd_forceX_6(t_pmpd *x, t_float force)
- { x->inlet[5] += force; }
-void pmpd_forceX_7(t_pmpd *x, t_float force)
- { x->inlet[6] += force; }
-void pmpd_forceX_8(t_pmpd *x, t_float force)
- { x->inlet[7] += force; }
-void pmpd_forceX_9(t_pmpd *x, t_float force)
- { x->inlet[8] += force; }
-void pmpd_forceX_10(t_pmpd *x, t_float force)
- { x->inlet[9] += force; }
-void pmpd_forceX_11(t_pmpd *x, t_float force)
- { x->inlet[10]+= force; }
-void pmpd_forceX_12(t_pmpd *x, t_float force)
- { x->inlet[11]+= force; }
-void pmpd_forceX_13(t_pmpd *x, t_float force)
- { x->inlet[12]+= force; }
-void pmpd_forceX_14(t_pmpd *x, t_float force)
- { x->inlet[13]+= force; }
-void pmpd_forceX_15(t_pmpd *x, t_float force)
- { x->inlet[14]+= force; }
-void pmpd_forceX_16(t_pmpd *x, t_float force)
- { x->inlet[15]+= force; }
-void pmpd_forceX_17(t_pmpd *x, t_float force)
- { x->inlet[16]+= force; }
-void pmpd_forceX_18(t_pmpd *x, t_float force)
- { x->inlet[17]+= force; }
-void pmpd_forceX_19(t_pmpd *x, t_float force)
- { x->inlet[18]+= force; }
-void pmpd_forceX_20(t_pmpd *x, t_float force)
- { x->inlet[19]+= force; }
+void pmpd_setD(t_pmpd *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int tmp, i;
+
+ if ( ( argv[0].a_type == A_FLOAT ) & ( argv[1].a_type == A_FLOAT ) )
+ {
+ tmp = atom_getfloatarg(0, argc, argv);
+ tmp = max(0, min( x->nb_link-1, tmp));
+ x->link[tmp].D = atom_getfloatarg(1, argc, argv);
+ }
+ if ( ( argv[0].a_type == A_SYMBOL ) & ( argv[1].a_type == A_FLOAT ) )
+ {
+ for (i=0; i< x->nb_link; i++)
+ {
+ if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+ {
+ x->link[i].D = atom_getfloatarg(1, argc, argv);
+ }
+ }
+ }
+}
-void pmpd_reset(t_pmpd *x)
+void pmpd_setL(t_pmpd *x, t_symbol *s, int argc, t_atom *argv)
{
- x->nb_link = 0;
- x->nb_mass = 1;
- x->nb_out= 0;
- x->nb_in= 0;
+ int tmp, i;
+
+ if ( ( argv[0].a_type == A_FLOAT ) & ( argv[1].a_type == A_FLOAT ) )
+ {
+ tmp = atom_getfloatarg(0, argc, argv);
+ tmp = max(0, min( x->nb_link-1, tmp));
+ x->link[tmp].L = atom_getfloatarg(1, argc, argv);
+ }
+ if ( ( argv[0].a_type == A_SYMBOL ) & ( argv[1].a_type == A_FLOAT ) )
+ {
+ for (i=0; i< x->nb_link; i++)
+ {
+ if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+ {
+ x->link[i].L = atom_getfloatarg(1, argc, argv);
+ }
+ }
+ }
}
-void *pmpd_new(t_symbol *s, int argc, t_atom *argv)
+void pmpd_get(t_pmpd *x, t_symbol *s, int argc, t_atom *argv)
{
- int i;
- char buffer[10];
+ int tmp, i;
+ t_float X;
+ t_symbol *toget;
+ t_atom toout[2];
+ toget = atom_getsymbolarg(0, argc, argv);
+
+ if ( (toget == gensym("massesPos")) & (argv[1].a_type == A_FLOAT) )
+ {
+ i = atom_getfloatarg(1, argc, argv);
+ if ( (i>=0) & (i<x->nb_mass) )
+ {
+ SETFLOAT(&(toout[0]), i);
+ SETFLOAT(&(toout[1]), x->mass[i].posX);
+ outlet_anything(x->main_outlet, gensym("massesPosNo"), 2, toout);
+ }
+ }
+ else
+ if ( (toget == gensym("massesPos")) & (argv[1].a_type == A_SYMBOL) )
+ {
+ for (i=0; i< x->nb_mass; i++)
+ {
+ if ( atom_getsymbolarg(1,argc,argv) == x->mass[i].Id)
+ {
+ SETFLOAT(&(toout[0]), i);
+ SETFLOAT(&(toout[1]), x->mass[i].posX);
+ outlet_anything(x->main_outlet, gensym("massesPosId"), 2, toout);
+ }
+ }
+ }
+ else
+ if ( (toget == gensym("massesPos")) & (argc == 1) )
+ {
+ for (i=0; i< x->nb_mass; i++)
+ {
+ SETFLOAT(&(toout[0]), i);
+ SETFLOAT(&(toout[1]), x->mass[i].posX);
+ outlet_anything(x->main_outlet, gensym("massesPos"), 2, toout);
+ }
+ }
+ else
+ if ( (toget == gensym("massesPosName")) & (argv[1].a_type == A_FLOAT) )
+ {
+ i = atom_getfloatarg(1, argc, argv);
+ if ( (i>=0) & (i<x->nb_mass) )
+ {
+ SETSYMBOL(&(toout[0]), x->mass[i].Id);
+ SETFLOAT(&(toout[1]), x->mass[i].posX);
+ outlet_anything(x->main_outlet, gensym("massesPosNameNo"), 2, toout);
+ }
+ }
+ else
+ if ( (toget == gensym("massesPosName")) & (argv[1].a_type == A_SYMBOL) )
+ {
+ for (i=0; i< x->nb_mass; i++)
+ {
+ if ( atom_getsymbolarg(1,argc,argv) == x->mass[i].Id)
+ {
+ SETSYMBOL(&(toout[0]), x->mass[i].Id);
+ SETFLOAT(&(toout[1]), x->mass[i].posX);
+ outlet_anything(x->main_outlet, gensym("massesPosNameId"), 2, toout);
+ }
+ }
+ }
+ else
+ if ( (toget == gensym("massesPosName")) & (argc == 1) )
+ {
+ for (i=0; i< x->nb_mass; i++)
+ {
+ SETSYMBOL(&(toout[0]), x->mass[i].Id);
+ SETFLOAT(&(toout[1]), x->mass[i].posX);
+ outlet_anything(x->main_outlet, gensym("massesPosName"), 2, toout);
+ }
+ }
+ else
+ if ( (toget == gensym("massesSpeeds")) & (argv[1].a_type == A_FLOAT) )
+ {
+ i = atom_getfloatarg(1, argc, argv);
+ if ( (i>=0) & (i<x->nb_mass) )
+ {
+ SETFLOAT(&(toout[0]), i);
+ SETFLOAT(&(toout[1]), x->mass[i].speedX);
+ outlet_anything(x->main_outlet, gensym("massesSpeedsNo"), 2, toout);
+ }
+ }
+ else
+ if ( (toget == gensym("massesSpeeds")) & (argv[1].a_type == A_SYMBOL) )
+ {
+ for (i=0; i< x->nb_mass; i++)
+ {
+ if ( atom_getsymbolarg(1,argc,argv) == x->mass[i].Id)
+ {
+ SETFLOAT(&(toout[0]), i);
+ SETFLOAT(&(toout[1]), x->mass[i].speedX);
+ outlet_anything(x->main_outlet, gensym("massesSpeedsId"), 2, toout);
+ }
+ }
+ }
+ else
+ if ( (toget == gensym("massesSpeeds")) & (argc == 1) )
+ {
+ for (i=0; i< x->nb_mass; i++)
+ {
+ SETFLOAT(&(toout[0]), i);
+ SETFLOAT(&(toout[1]), x->mass[i].speedX);
+ outlet_anything(x->main_outlet, gensym("massesSpeeds"), 2, toout);
+ }
+ }
+ else
+ if ( (toget == gensym("massesSpeedsName")) & (argv[1].a_type == A_FLOAT) )
+ {
+ i = atom_getfloatarg(1, argc, argv);
+ if ( (i>=0) & (i<x->nb_mass) )
+ {
+ SETSYMBOL(&(toout[0]), x->mass[i].Id);
+ SETFLOAT(&(toout[1]), x->mass[i].speedX);
+ outlet_anything(x->main_outlet, gensym("massesSpeedsNameNo"), 2, toout);
+ }
+ }
+ else
+ if ( (toget == gensym("massesSpeedsName")) & (argv[1].a_type == A_SYMBOL) )
+ {
+ for (i=0; i< x->nb_mass; i++)
+ {
+ if ( atom_getsymbolarg(1,argc,argv) == x->mass[i].Id)
+ {
+ SETSYMBOL(&(toout[0]), x->mass[i].Id);
+ SETFLOAT(&(toout[1]), x->mass[i].speedX);
+ outlet_anything(x->main_outlet, gensym("massesSpeedsNameId"), 2, toout);
+ }
+ }
+ }
+ else
+ if ( (toget == gensym("massesSpeedsName")) & (argc == 1) )
+ {
+ for (i=0; i< x->nb_mass; i++)
+ {
+ SETSYMBOL(&(toout[0]), x->mass[i].Id);
+ SETFLOAT(&(toout[1]), x->mass[i].speedX);
+ outlet_anything(x->main_outlet, gensym("massesSpeedsName"), 2, toout);
+ }
+ }
+ else
+ if ( (toget == gensym("massesForces")) & (argv[1].a_type == A_FLOAT) )
+ {
+ i = atom_getfloatarg(1, argc, argv);
+ if ( (i>=0) & (i<x->nb_mass) )
+ {
+ SETFLOAT(&(toout[0]), i);
+ SETFLOAT(&(toout[1]), x->mass[i].forceX);
+ outlet_anything(x->main_outlet, gensym("massesForcesNo"), 2, toout);
+ }
+ }
+ else
+ if ( (toget == gensym("massesForces")) & (argv[1].a_type == A_SYMBOL) )
+ {
+ for (i=0; i< x->nb_mass; i++)
+ {
+ if ( atom_getsymbolarg(1,argc,argv) == x->mass[i].Id)
+ {
+ SETFLOAT(&(toout[0]), i);
+ SETFLOAT(&(toout[1]), x->mass[i].forceX);
+ outlet_anything(x->main_outlet, gensym("massesForcesId"), 2, toout);
+ }
+ }
+ }
+ else
+ if ( (toget == gensym("massesForces")) & (argc == 1) )
+ {
+ for (i=0; i< x->nb_mass; i++)
+ {
+ SETFLOAT(&(toout[0]), i);
+ SETFLOAT(&(toout[1]), x->mass[i].forceX);
+ outlet_anything(x->main_outlet, gensym("massesForces"), 2, toout);
+ }
+ }
+ else
+ if ( (toget == gensym("massesForcesName")) & (argv[1].a_type == A_FLOAT) )
+ {
+ i = atom_getfloatarg(1, argc, argv);
+ if ( (i>=0) & (i<x->nb_mass) )
+ {
+ SETSYMBOL(&(toout[0]), x->mass[i].Id);
+ SETFLOAT(&(toout[1]), x->mass[i].forceX);
+ outlet_anything(x->main_outlet, gensym("massesForcesNameNo"), 2, toout);
+ }
+ }
+ else
+ if ( (toget == gensym("massesForcesName")) & (argv[1].a_type == A_SYMBOL) )
+ {
+ for (i=0; i< x->nb_mass; i++)
+ {
+ if ( atom_getsymbolarg(1,argc,argv) == x->mass[i].Id)
+ {
+ SETSYMBOL(&(toout[0]), x->mass[i].Id);
+ SETFLOAT(&(toout[1]), x->mass[i].forceX);
+ outlet_anything(x->main_outlet, gensym("massesForcesNameId"), 2, toout);
+ }
+ }
+ }
+ else
+ if ( (toget == gensym("massesForcesName")) & (argc == 1) )
+ {
+ for (i=0; i< x->nb_mass; i++)
+ {
+ SETSYMBOL(&(toout[0]), x->mass[i].Id);
+ SETFLOAT(&(toout[1]), x->mass[i].forceX);
+ outlet_anything(x->main_outlet, gensym("massesForcesName"), 2, toout);
+ }
+ }
+ else
+ if ( (toget == gensym("linksPos")) & (argv[1].a_type == A_FLOAT) )
+ {
+ i = atom_getfloatarg(1, argc, argv);
+ if ( (i>=0) & (i<x->nb_mass) )
+ {
+ SETFLOAT(&(toout[0]), i);
+ SETFLOAT(&(toout[1]), x->link[i].mass1->posX);
+ SETFLOAT(&(toout[2]), x->link[i].mass2->posX);
+ outlet_anything(x->main_outlet, gensym("linksPosNo"), 3, toout);
+ }
+ }
+ else
+ if ( (toget == gensym("linksPos")) & (argv[1].a_type == A_SYMBOL) )
+ {
+ for (i=0; i< x->nb_link; i++)
+ {
+ if ( atom_getsymbolarg(1,argc,argv) == x->link[i].Id)
+ {
+ SETFLOAT(&(toout[0]), i);
+ SETFLOAT(&(toout[1]), x->link[i].mass1->posX);
+ SETFLOAT(&(toout[2]), x->link[i].mass2->posX);
+ outlet_anything(x->main_outlet, gensym("linksPosId"), 3, toout);
+ }
+ }
+ }
+ else
+ if ( (toget == gensym("linksPos")) & (argc == 1) )
+ {
+ for (i=0; i< x->nb_link; i++)
+ {
+ SETFLOAT(&(toout[0]), i);
+ SETFLOAT(&(toout[1]), x->link[i].mass1->posX);
+ SETFLOAT(&(toout[2]), x->link[i].mass2->posX);
+ outlet_anything(x->main_outlet, gensym("linksPos"), 3, toout);
+ }
+ }
+ else
+ if ( (toget == gensym("linksPosName")) & (argv[1].a_type == A_FLOAT) )
+ {
+ i = atom_getfloatarg(1, argc, argv);
+ if ( (i>=0) & (i<x->nb_mass) )
+ {
+ SETSYMBOL(&(toout[0]), x->link[i].Id);
+ SETFLOAT(&(toout[1]), x->link[i].mass1->posX);
+ SETFLOAT(&(toout[2]), x->link[i].mass2->posX);
+ outlet_anything(x->main_outlet, gensym("linksPosNameNo"), 3, toout);
+ }
+ }
+ else
+ if ( (toget == gensym("linksPosName")) & (argv[1].a_type == A_SYMBOL) )
+ {
+ for (i=0; i< x->nb_link; i++)
+ {
+ if ( atom_getsymbolarg(1,argc,argv) == x->link[i].Id)
+ {
+ SETSYMBOL(&(toout[0]), x->link[i].Id);
+ SETFLOAT(&(toout[1]), x->link[i].mass1->posX);
+ SETFLOAT(&(toout[2]), x->link[i].mass2->posX);
+ outlet_anything(x->main_outlet, gensym("linksPosNameId"), 3, toout);
+ }
+ }
+ }
+ else
+ if ( (toget == gensym("linksPosName")) & (argc == 1) )
+ {
+ for (i=0; i< x->nb_link; i++)
+ {
+ SETSYMBOL(&(toout[0]), x->link[i].Id);
+ SETFLOAT(&(toout[1]), x->link[i].mass1->posX);
+ SETFLOAT(&(toout[2]), x->link[i].mass2->posX);
+ outlet_anything(x->main_outlet, gensym("linksPosName"), 3, toout);
+ }
+ }
+ else
+ error("not get attribute");
+}
+
+void pmpd_massesPosL(t_pmpd *x)
+{
+ int i;
+ t_atom pos_list[nb_max_link];
+
+ for (i=0; i< x->nb_mass; i++)
+ {
+ SETFLOAT(&(pos_list[i]),x->mass[i].posX);
+ }
+ outlet_anything(x->main_outlet, gensym("massesPosL"),x->nb_mass , pos_list);
+}
+
+void pmpd_massesForcesL(t_pmpd *x)
+{
+ int i;
+ t_atom pos_list[nb_max_link];
+
+ for (i=0; i< x->nb_mass; i++)
+ {
+ SETFLOAT(&(pos_list[i]),x->mass[i].forceX);
+ }
+ outlet_anything(x->main_outlet, gensym("massesForcesL"),x->nb_mass , pos_list);
+}
+void *pmpd_new()
+{
t_pmpd *x = (t_pmpd *)pd_new(pmpd_class);
pmpd_reset(x);
- x->nb_outlet= (int)atom_getfloatarg(1, argc, argv);
- x->nb_outlet= max(0, min(nb_max_outlet, x->nb_outlet) );
- for(i=0; i<x->nb_outlet; i++)
- x->taboutlet[i]=outlet_new(&x->x_obj, 0);
-
- x->nb_inlet = (int)atom_getfloatarg(0, argc, argv);
- x->nb_inlet= max(0, min(nb_max_inlet, x->nb_inlet) );
- for(i=0; i<x->nb_inlet; i++)
- {
- sprintf (buffer, "forceX_%i", i+1);
- inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("forceX"), gensym(buffer));
- }
+ x->main_outlet=outlet_new(&x->x_obj, 0);
+ x->info_outlet=outlet_new(&x->x_obj, 0); // TODO
+
return (void *)x;
}
@@ -330,78 +743,24 @@ void pmpd_setup(void)
{
pmpd_class = class_new(gensym("pmpd"),
(t_newmethod)pmpd_new,
- 0, sizeof(t_pmpd),CLASS_DEFAULT, A_GIMME, 0);
+ 0, sizeof(t_pmpd),CLASS_DEFAULT, 0);
class_addbang(pmpd_class, pmpd_bang);
- class_addmethod(pmpd_class, (t_method)pmpd_mass, gensym("mass"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_link, gensym("link"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_out, gensym("out"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_in, gensym("in"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_posX, gensym("posX"), A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_forceX, gensym("forceX"), A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_forceX_1, gensym("forceX_1"), A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_forceX_2, gensym("forceX_2"), A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_forceX_3, gensym("forceX_3"), A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_forceX_4, gensym("forceX_4"), A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_forceX_5, gensym("forceX_5"), A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_forceX_6, gensym("forceX_6"), A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_forceX_7, gensym("forceX_7"), A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_forceX_8, gensym("forceX_8"), A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_forceX_9, gensym("forceX_9"), A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_forceX_10, gensym("forceX_10"), A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_forceX_11, gensym("forceX_11"), A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_forceX_12, gensym("forceX_12"), A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_forceX_13, gensym("forceX_13"), A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_forceX_14, gensym("forceX_14"), A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_forceX_15, gensym("forceX_15"), A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_forceX_16, gensym("forceX_16"), A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_forceX_17, gensym("forceX_17"), A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_forceX_18, gensym("forceX_18"), A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_forceX_19, gensym("forceX_19"), A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_forceX_20, gensym("forceX_20"), A_DEFFLOAT, 0);
- class_addmethod(pmpd_class, (t_method)pmpd_reset, gensym("reset"), 0);
-
-/*
- post("");
- post(" pmpd = Physical Modeling for Pure Data");
- post(" version "VERSION);
- post(" compiled "__DATE__);
- post(" Contact : cyrille.henry@la-kitchen.fr");
- post("");
-
-masse_setup() ;
-lia_setup() ;
-masse2D_setup() ;
-lia2D_setup() ;
-masse3D_setup() ;
-lia3D_setup() ;
-
-iAmbient2D_setup();
-iLine2D_setup();
-iSeg2D_setup();
-iCircle2D_setup();
-
-tSquare2D_setup();
-tCircle2D_setup();
-tLine2D_setup();
-tSeg2D_setup();
-tLia2D_setup();
-
-iAmbient3D_setup();
-iSphere3D_setup();
-iPlane3D_setup();
-iCircle3D_setup();
-iCylinder3D_setup();
-
-tLia3D_setup();
-tCube3D_setup();
-tPlane3D_setup();
-tSphere3D_setup();
-tCylinder3D_setup();
-tCircle3D_setup();
-
-pmpd_tilde_setup();
-
-*/
+ class_addmethod(pmpd_class, (t_method)pmpd_mass, gensym("mass"), A_DEFSYMBOL, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_link, gensym("link"), A_GIMME, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_posX, gensym("posX"), A_GIMME, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_forceX, gensym("forceX"), A_GIMME, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_reset, gensym("reset"), 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_infosL, gensym("infosL"), 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_minX, gensym("Xmin"), A_DEFFLOAT, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_maxX, gensym("Xmax"), A_DEFFLOAT, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_setFixed, gensym("setFixed"), A_GIMME, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_setMobile, gensym("setMobile"), A_GIMME, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_setK, gensym("setK"), A_GIMME, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_setD, gensym("setD"), A_GIMME, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_setL, gensym("setL"), A_GIMME, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_get, gensym("get"), A_GIMME, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_massesPosL, gensym("massesPosL"), 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_massesForcesL, gensym("massesForcesL"), 0);
}