From 88b2ec0c703d5c2fb9a34c8b39ab64ab6d4e2d0e Mon Sep 17 00:00:00 2001 From: Cyrille Henry Date: Tue, 12 Apr 2005 18:09:20 +0000 Subject: Nicolas objects... svn path=/trunk/externals/nusmuk/; revision=2748 --- msd/01_msdtest.pd | 94 +++++++ msd/02_imsdtest.pd | 92 +++++++ msd/Makefile.am | 51 ++++ msd/help-msd.pd | 76 ++++++ msd/main.cpp | 753 +++++++++++++++++++++++++++++++++++++++++++++++++++++ msd/package.txt | 2 + 6 files changed, 1068 insertions(+) create mode 100644 msd/01_msdtest.pd create mode 100644 msd/02_imsdtest.pd create mode 100644 msd/Makefile.am create mode 100644 msd/help-msd.pd create mode 100755 msd/main.cpp create mode 100644 msd/package.txt (limited to 'msd') diff --git a/msd/01_msdtest.pd b/msd/01_msdtest.pd new file mode 100644 index 0000000..6991c3c --- /dev/null +++ b/msd/01_msdtest.pd @@ -0,0 +1,94 @@ +#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; diff --git a/msd/02_imsdtest.pd b/msd/02_imsdtest.pd new file mode 100644 index 0000000..9a5ee14 --- /dev/null +++ b/msd/02_imsdtest.pd @@ -0,0 +1,92 @@ +#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; diff --git a/msd/Makefile.am b/msd/Makefile.am new file mode 100644 index 0000000..59a3dff --- /dev/null +++ b/msd/Makefile.am @@ -0,0 +1,51 @@ +# +# 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).@EXTENSION@ + +OBJECTS = $(patsubst %.cpp,./%.@OBJEXT@,$(BUILT_SOURCES)) + +SYSDIR = @SYSDIR@ + + +# ----------------------------- targets -------------------------------- + +all-local: $(OBJECTS) + $(CXX) $(LDFLAGS) ./*.@OBJEXT@ $(LIBS) -o ../$(TARGETDIR)/$(TARGET) + strip --strip-unneeded ../$(TARGETDIR)/$(TARGET) + +./%.@OBJEXT@ : %.cpp + $(CXX) -c $(CXXFLAGS) $< -o $@ + +clean-local: + rm -f ../$(TARGETDIR)/$(TARGET) + rm -f ./$(OBJECTS) + +install-exec-local: + install ../$(TARGET) $(SYSDIR)extra diff --git a/msd/help-msd.pd b/msd/help-msd.pd new file mode 100644 index 0000000..80d792d --- /dev/null +++ b/msd/help-msd.pd @@ -0,0 +1,76 @@ +#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; diff --git a/msd/main.cpp b/msd/main.cpp new file mode 100755 index 0000000..324ab2d --- /dev/null +++ b/msd/main.cpp @@ -0,0 +1,753 @@ + + +/* + 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@gmx.net) + Based on pmpd by Cyrille Henry + + + Contact : Nicolas Montgermont, montgermont@la-kitchen.fr + Cyrille Henry, Cyrille.Henry@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 + +#include + +// 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; imass1->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; imobile == 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; iout_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; iId_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; iId_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; inbr == 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; inbr == 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; imass1->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; inbr == 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; inbr==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;iId_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;inbr); + 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; iId_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; iId_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; iId_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; inbr == 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; iposX); + ToOutAnything(0,gensym("massesPos"),1,sortie); + } + else if (auxstring2 == 0)// get all masses forces + for (i=0; iout_forceX); + ToOutAnything(0,gensym("massesForces"),1,sortie); + } + else if (auxstring3 == 0)// get all links positions + for (i=0; imass1->posX); + SETFLOAT(&sortie[2],link[i]->mass2->posX); + ToOutAnything(0,gensym("linksPos"),2,sortie); + } + else // get all masses speeds + for (i=0; ispeedX); + ToOutAnything(0,gensym("massesSpeeds"),1,sortie); + } + } + else if (auxstring1 == 0) // get mass positions + { + if (auxarg == 0) // No + { + for (j = 1; jnbr==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; jId_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; jnbr==GetAInt(argv[j])) + { + SETFLOAT(&sortie[0],mass[i]->out_forceX); + ToOutAnything(0,gensym("massesForcesNo"),1,sortie); + } + } + else //string + { + for (j = 1; jId_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; jnbr==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; jId_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; jnbr==GetAInt(argv[j])) + { + SETFLOAT(&sortie[0],mass[i]->speedX); + ToOutAnything(0,gensym("massesSpeedsNo"),1,sortie); + } + } + else //string + { + for (j = 1; jId_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; iposX); + } + 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; iout_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; inbr); + 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; inbr); + 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