aboutsummaryrefslogtreecommitdiff
path: root/msd
diff options
context:
space:
mode:
authorCyrille Henry <nusmuk@users.sourceforge.net>2005-04-12 18:09:20 +0000
committerCyrille Henry <nusmuk@users.sourceforge.net>2005-04-12 18:09:20 +0000
commit88b2ec0c703d5c2fb9a34c8b39ab64ab6d4e2d0e (patch)
treee732960c30ea2d6d8c5e82ae38e36b6aebd95490 /msd
parenta6e8193f42affae14fc1b5091469acdc3f99d8af (diff)
Nicolas objects...
svn path=/trunk/externals/nusmuk/; revision=2748
Diffstat (limited to 'msd')
-rw-r--r--msd/01_msdtest.pd94
-rw-r--r--msd/02_imsdtest.pd92
-rw-r--r--msd/Makefile.am51
-rw-r--r--msd/help-msd.pd76
-rwxr-xr-xmsd/main.cpp753
-rw-r--r--msd/package.txt2
6 files changed, 1068 insertions, 0 deletions
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 <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)
+
+
diff --git a/msd/package.txt b/msd/package.txt
new file mode 100644
index 0000000..39c00ee
--- /dev/null
+++ b/msd/package.txt
@@ -0,0 +1,2 @@
+NAME=msd
+SRCS=main.cpp