From c70ffd6a91d1d898e9ca6af934198d7836e1951b Mon Sep 17 00:00:00 2001 From: Cyrille Henry Date: Tue, 8 Feb 2011 21:00:50 +0000 Subject: the pmpd object should be compatible with msd svn path=/trunk/externals/pmpd/; revision=14878 --- pmpd.c | 913 +++++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 636 insertions(+), 277 deletions(-) (limited to 'pmpd.c') 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; inb_in; i++) - // compute input - { - x->in[i].mass1->forceX += x->in[i].influence * x->inlet[x->in[i].nbr_inlet]; - } - - for (i=0; inb_inlet; i++) - // clear inlet[i] - { - x->inlet[i]=0; - } - - for (i=0; inb_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; inb_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; inb_out; i++) - // compute output point - { - x->outlet[x->out[i].nbr_outlet] += x->out[i].mass1->posX * x->out[i].influence ; - } - -// for (i=0; inb_outlet; i++) - for (i=x->nb_outlet-1; i>=0; i--) - // output everything on the corresponding outlet + for (i=0; inb_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) & (inb_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) & (inb_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) & (inb_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) & (inb_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) & (inb_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) & (inb_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) & (inb_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) & (inb_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; inb_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; inb_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); } -- cgit v1.2.1