diff options
Diffstat (limited to 'msd3D/main.cpp')
-rwxr-xr-x | msd3D/main.cpp | 1127 |
1 files changed, 2 insertions, 1125 deletions
diff --git a/msd3D/main.cpp b/msd3D/main.cpp index 3ca4597..79010f5 100755 --- a/msd3D/main.cpp +++ b/msd3D/main.cpp @@ -1,1126 +1,3 @@ +#include "../msd.h" - -/* - msd3D - mass spring damper model for Pure Data or Max/MSP - - Copyright (C) 2005 Nicolas Montgermont - 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 library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Version 0.05 -- 28.04.2005 -*/ - -// include flext header -#include <flext.h> -#include <math.h> - -// define constants -#define MSD3D_VERSION 0.05 -#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) ) - -#ifdef _MSC_VER -#define NEWARR(type,var,size) type *var = new type[size] -#define DELARR(var) delete[] var -#else -#define NEWARR(type,var,size) type var[size] -#define DELARR(var) ((void)0) -#endif - - - -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; - t_float speedY; - t_float posY; - t_float posY2; - t_float forceY; - t_float out_forceY; - t_float speedZ; - t_float posZ; - t_float posZ2; - t_float forceZ; - t_float out_forceZ; -} 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, longy, longz, longueur, long_min, long_max; - t_float distance_old; -} t_link; - -inline t_float sqr(t_float x) { return x*x; } - -class msd3D: - public flext_base -{ - FLEXT_HEADER_S(msd3D,flext_base,setup) //class with setup - -public: - // constructor with no arguments - msd3D(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_mass **mi; - t_link **li; - - for (i=0, mi=mass; i<nb_mass;mi++, i++) { - delete (*mi); - } - for (i=0, li=link; i<nb_link;li++, i++) { - delete (*li); - } - ToOutAnything(1,S_Reset,0,NULL); - nb_link = 0; - nb_mass = 0; - id_mass = 0; - id_link = 0; - } - -// -------------------------------------------------------------- COMPUTE -// ----------------------------------------------------------------------- - void m_bang() - { - t_int i; - for (i=0; i<nb_link; i++) { - t_link *li = link[i]; - t_mass *m1 = li->mass1,*m2 = li->mass2; - // compute link forces - t_float distance = sqrt(sqr(m1->posX-m2->posX) + sqr(m1->posY-m2->posY) + sqr(m1->posZ-m2->posZ)); // L[n] - t_float Fx,Fy,Fz; - if (distance < li->long_min || distance > li->long_max || distance == 0) - Fx = Fy = Fz = 0; - else { - t_float F = (li->K1 * (distance - li->longueur) + li->D1 * (distance - li->distance_old))/distance ; //F = K1(L[n] - L[0])/L[n] + D1(L[n] - L[n-1])/L[n] - Fx = F * (m1->posX - m2->posX); // Fx[n] = F * Lx[n] - Fy = F * (m1->posY - m2->posY); // Fy[n] = F * Ly[n] - Fz = F * (m1->posZ - m2->posZ); // Fy[n] = F * Lz[n] - } - m1->forceX -= Fx + li->D2*m1->speedX; // Fx1[n] = -Fx,Fx1[n] = Fx1[n] - D2 * vx1[n-1] - m2->forceX += Fx - li->D2*m2->speedX; //Fx2[n] = Fx, Fx2[n] = Fx2[n] - D2 * vx2[n-1] - m1->forceY -= Fy + li->D2*m1->speedY; // Fy1[n] = -Fy,Fy1[n] = Fy1[n] - D2 * vy1[n-1] - m2->forceY += Fy - li->D2*m2->speedY; // Fy2[n] = Fy,Fy2[n] = Fy2[n] - D2 * vy2[n-1] - m1->forceZ -= Fz + li->D2*m1->speedZ; // Fz1[n] = -Fz,Fz1[n] = Fz1[n] - D2 * vz1[n-1] - m2->forceZ += Fz - li->D2*m2->speedZ; // Fz2[n] = Fz,Fz2[n] = Fz2[n] - D2 * vz2[n-1] - li->distance_old = distance; // L[n-1] = L[n] - } - - for (i=0; i<nb_mass; i++) { - t_mass *mi = mass[i]; - // compute new masses position only if mobile = 1 - if (mi->mobile == 1) { - t_float X_new = mi->forceX * mi->invM + 2*mi->posX - mi->posX2; // x[n] =Fx[n]/M+2x[n]-x[n-1] - mi->posX2 = mi->posX; // x[n-2] = x[n-1] - mi->posX = max(min(X_new,Xmax),Xmin); // x[n-1] = x[n] - mi->speedX = mi->posX - mi->posX2; // vx[n] = x[n] - x[n-1] - t_float Y_new = mi->forceY * mi->invM + 2*mi->posY - mi->posY2; // y[n] =Fy[n]/M+2y[n]-y[n-1] - mi->posY2 = mi->posY; // y[n-2] = y[n-1] - mi->posY = max(min(Y_new,Ymax),Ymin); // y[n-1] = y[n] - mi->speedY = mi->posY - mi->posY2; // vy[n] = y[n] - y[n-1] - t_float Z_new = mi->forceZ * mi->invM + 2*mi->posZ - mi->posZ2; // x[n] =Fx[n]/M+2x[n]-x[n-1] - mi->posZ2 = mi->posZ; // z[n-2] = z[n-1] - mi->posZ = max(min(Z_new,Zmax),Zmin); // z[n-1] = z[n] - mi->speedZ = mi->posZ - mi->posZ2; // vz[n] = z[n] - z[n-1] - } - } - - for (i=0; i<nb_mass; i++) { - t_mass *mi = mass[i]; - // clear forces - mi->out_forceX = mi->forceX; - mi->out_forceY = mi->forceY; - mi->out_forceZ = mi->forceZ; - mi->forceX = mi->forceY = mi->forceZ = 0; - } - } - -// -------------------------------------------------------------- MASSES -// ---------------------------------------------------------------------- - void m_mass(int argc,t_atom *argv) - // add a mass - // Id, nbr, mobile, invM, speedX, posX, forceX - { - t_atom sortie[7], aux[2]; - t_float M; - - if (argc != 6) - error("mass : Id mobile mass X Y Z"); - - mass[nb_mass] = new t_mass; // new mass - mass[nb_mass]->Id = GetSymbol(argv[0]); // Id - mass[nb_mass]->mobile = GetInt(argv[1]); // mobile - if (GetFloat(argv[2])==0) - M=1; - else M = GetFloat(argv[2]); - mass[nb_mass]->invM = 1/(M); // 1/M - mass[nb_mass]->speedX = 0; // vx[n] - mass[nb_mass]->posX = GetFloat(argv[3]); // x[n] - mass[nb_mass]->posX2 = GetFloat(argv[3]); // x[n-1] - mass[nb_mass]->forceX = 0; // Fx[n] - mass[nb_mass]->speedY = 0; // vy[n] - mass[nb_mass]->posY = GetFloat(argv[4]); // y[n] - mass[nb_mass]->posY2 = GetFloat(argv[4]); // y[n-1] - mass[nb_mass]->forceY = 0; // Fz[n] - mass[nb_mass]->speedZ = 0; // vz[n] - mass[nb_mass]->posZ = GetFloat(argv[5]); // z[n] - mass[nb_mass]->posZ2 = GetFloat(argv[5]); // z[n-1] - mass[nb_mass]->forceZ = 0; // Fz[n] - mass[nb_mass]->nbr = id_mass; // id number - nb_mass++ ; - id_mass++; - nb_mass = min ( nb_max_mass -1, nb_mass ); - SetFloat((sortie[0]),id_mass-1); - SetSymbol((sortie[1]),GetSymbol(argv[0])); - SetFloat((sortie[2]),mass[nb_mass-1]->mobile); - SetFloat((sortie[3]),M); - SetFloat((sortie[4]),mass[nb_mass-1]->posX); - SetFloat((sortie[5]),mass[nb_mass-1]->posY); - SetFloat((sortie[6]),mass[nb_mass-1]->posZ); - ToOutAnything(1,S_Mass ,7,sortie); - } - - void m_forceX(int argc,t_atom *argv) - { - // add a force to mass(es) named Id or No - t_int i; - const t_symbol *sym = GetASymbol(argv[0]); - t_mass **mi; - - if (argc != 2) - error("forceX : Idmass value"); - - if (sym ==0) - for (i=0, mi=mass; i<nb_mass; mi++, i++) - { - if (GetInt(argv[0]) == (*mi)->nbr) { - (*mi)->forceX = GetFloat(argv[1]); - break; - } - } - else - for (i=0, mi=mass; i<nb_mass; mi++, i++) - { - if (sym == (*mi)->Id) - (*mi)->forceX = GetFloat(argv[1]); - } - } - - void m_forceY(int argc,t_atom *argv) - { - // add a force to mass(es) named Id or No - t_int i; - const t_symbol *sym = GetASymbol(argv[0]); - t_mass **mi; - - if (argc != 2) - error("forceX : Idmass value"); - - if (sym ==0) - for (i=0, mi=mass; i<nb_mass; mi++, i++) - { - if (GetInt(argv[0]) == (*mi)->nbr) { - (*mi)->forceY = GetFloat(argv[1]); - break; - } - } - else - for (i=0, mi=mass; i<nb_mass; mi++, i++) - { - if (sym == (*mi)->Id) - (*mi)->forceY = GetFloat(argv[1]); - } - } - - void m_forceZ(int argc,t_atom *argv) - { - // add a force to mass(es) named Id or No - t_int i; - const t_symbol *sym = GetASymbol(argv[0]); - t_mass **mi; - - if (argc != 2) - error("forceX : Idmass value"); - - if (sym ==0) - for (i=0, mi=mass; i<nb_mass; mi++, i++) - { - if (GetInt(argv[0]) == (*mi)->nbr) { - (*mi)->forceZ = GetFloat(argv[1]); - break; - } - } - else - for (i=0, mi=mass; i<nb_mass; mi++, i++) - { - if (sym == (*mi)->Id) - (*mi)->forceZ = GetFloat(argv[1]); - } - } - - void m_posX(int argc,t_atom *argv) - { - // displace mass(es) named Id to a certain position - t_int i; - const t_symbol *sym = GetASymbol(argv[0]); - t_mass **mi; - - if (argc != 2) - error("posX : Id/Nomass value"); - - if (GetFloat(argv[1]) < Xmax && GetFloat(argv[1]) > Xmin) - if (sym ==0) - for (i=0, mi=mass; i<nb_mass; mi++, i++) - { - if (GetInt(argv[0]) == (*mi)->nbr) { - (*mi)->posX = GetFloat(argv[1]); - (*mi)->posX2 = GetFloat(argv[1]); - break; - } - } - else - for (i=0, mi=mass; i<nb_mass; mi++, i++) - if (sym == (*mi)->Id) { - (*mi)->posX = GetFloat(argv[1]); - (*mi)->posX2 = GetFloat(argv[1]); - } - } - - void m_posY(int argc,t_atom *argv) - { - // displace mass(es) named Id to a certain position - t_int i; - const t_symbol *sym = GetASymbol(argv[0]); - t_mass **mi; - - if (argc != 2) - error("posY : Id/Nomass value"); - - if (GetFloat(argv[1]) < Ymax && GetFloat(argv[1]) > Ymin) - if (sym ==0) - for (i=0, mi=mass; i<nb_mass; mi++, i++) - { - if (GetInt(argv[0]) == (*mi)->nbr) { - (*mi)->posY = GetFloat(argv[1]); - (*mi)->posY2 = GetFloat(argv[1]); - break; - } - } - else - for (i=0, mi=mass; i<nb_mass; mi++, i++) - if (sym == (*mi)->Id) { - (*mi)->posY = GetFloat(argv[1]); - (*mi)->posY2 = GetFloat(argv[1]); - } - } - - void m_posZ(int argc,t_atom *argv) - { - // displace mass(es) named Id to a certain position - t_int i; - const t_symbol *sym = GetASymbol(argv[0]); - t_mass **mi; - - if (argc != 2) - error("posY : Id/Nomass value"); - - if (GetFloat(argv[1]) < Zmax && GetFloat(argv[1]) > Zmin) - if (sym ==0) - for (i=0, mi=mass; i<nb_mass; mi++, i++) - { - if (GetInt(argv[0]) == (*mi)->nbr) { - (*mi)->posZ = GetFloat(argv[1]); - (*mi)->posZ2 = GetFloat(argv[1]); - break; - } - } - else - for (i=0, mi=mass; i<nb_mass; mi++, i++) - if (sym == (*mi)->Id) { - (*mi)->posZ = GetFloat(argv[1]); - (*mi)->posZ2 = GetFloat(argv[1]); - } - } - - void m_set_mobile(int argc,t_atom *argv) - { - // set mass No to mobile - t_int i,aux; - t_mass **mi; - - if (argc != 1) - error("setMobile : Idmass"); - - aux = GetInt(argv[0]); - for (i=0, mi=mass; i<nb_mass;mi++, i++) - { - if ((*mi)->nbr == aux) - (*mi)->mobile = 1; - } - - } - - void m_set_fixe(int argc,t_atom *argv) - { - // set mass No to fixed - t_int i,aux; - t_mass **mi; - - if (argc != 1) - error("setFixed : Idmass"); - - aux = GetAInt(argv[0]); - for (i=0, mi=mass; i<nb_mass;mi++, i++) - { - if ((*mi)->nbr == aux) - (*mi)->mobile = 0; - } - - } - - void m_delete_mass(int argc,t_atom *argv) - { - // Delete mass - t_int i,nb_link_delete=0; - t_atom sortie[7]; - NEWARR(t_atom,aux,nb_link); - t_mass **mi; - t_link **li; - - if (argc != 1) - error("deleteMass : Nomass"); - - // Delete associated links - for (i=0, li=link; i<nb_link;li++, i++) { - if ((*li)->mass1->nbr == GetInt(argv[0]) || (*li)->mass2->nbr == GetInt(argv[0])) { - SetFloat((aux[nb_link_delete]),(*li)->nbr); - nb_link_delete++; - } - } - - for (i=0; i<nb_link_delete;i++) - m_delete_link(1,&aux[i]); - - // Delete mass - for (i=0, mi=mass; i<nb_mass;mi++, i++) - if ((*mi)->nbr == GetInt(argv[0])) { - SetFloat((sortie[0]),(*mi)->nbr); - SetSymbol((sortie[1]),(*mi)->Id); - SetFloat((sortie[2]),(*mi)->mobile); - SetFloat((sortie[3]),1/(*mi)->invM); - SetFloat((sortie[4]),(*mi)->posX); - SetFloat((sortie[5]),(*mi)->posY); - SetFloat((sortie[6]),(*mi)->posZ); - delete (*mi); - (*mi) = mass[nb_mass-1]; // copy last mass indeed - nb_mass--; - ToOutAnything(1,S_Mass_deleted,7,sortie); - break; - } - DELARR(aux); - } - - - void m_Xmax(int argc,t_atom *argv) - { - // set X max - if (argc != 1) - error("Xmax : Value"); - Xmax = GetFloat(argv[0]); - } - - void m_Xmin(int argc,t_atom *argv) - { - // set X min - if (argc != 1) - error("Xmin : Value"); - Xmin = GetFloat(argv[0]); - } - void m_Ymax(int argc,t_atom *argv) - { - // set Y max - if (argc != 1) - error("Ymax : Value"); - Ymax = GetFloat(argv[0]); - } - - void m_Ymin(int argc,t_atom *argv) - { - // set Y min - if (argc != 1) - error("Ymin : Value"); - Ymin = GetFloat(argv[0]); - } - - void m_Zmax(int argc,t_atom *argv) - { - // set maximum Z of all masses - if (argc != 1) - error("Zmax : Value"); - Zmax = GetFloat(argv[0]); - } - - void m_Zmin(int argc,t_atom *argv) - { - // set minimum Z of all masses - if (argc != 1) - error("Zmin : Value"); - Zmin = GetFloat(argv[0]); - } - -// -------------------------------------------------------------- LINKS -// --------------------------------------------------------------------- - void m_link(int argc,t_atom *argv) - // add a link - // Id, *mass1, *mass2, K1, D1, D2, (Lmin,Lmax) - { - t_atom sortie[7], aux[2]; - t_int i; - t_mass *mass1 = NULL; - t_mass *mass2 = NULL; - t_mass **mi; - - if (argc < 6 || argc > 8) - error("link : Id Nomass1 Nomass2 K D1 D2 (Lmin Lmax)"); - - // check for existence of link masses: - for (i=0, mi=mass; i<nb_mass;mi++, i++) - if ((*mi)->nbr==GetInt(argv[1])) // pointer to mass1 - // we found mass1 - mass1 = (*mi); - else if ((*mi)->nbr==GetInt(argv[2])) // pointer to mass2 - // ... and mass2 - mass2 = (*mi); - - if (mass1 and mass2) - { - link[nb_link] = new t_link; // New pointer - link[nb_link]->Id = GetSymbol(argv[0]); // ID - link[nb_link]->mass1 = mass1; // pointer to mass1 - link[nb_link]->mass2 = mass2; // pointer to mass2 - link[nb_link]->K1 = GetFloat(argv[3]); // K1 - link[nb_link]->D1 = GetFloat(argv[4]); // D1 - link[nb_link]->D2 = GetFloat(argv[5]); // D2 - link[nb_link]->longx = link[nb_link]->mass1->posX - link[nb_link]->mass2->posX; // Lx[0] - link[nb_link]->longy = link[nb_link]->mass1->posY - link[nb_link]->mass2->posY; // Ly[0] - link[nb_link]->longz = link[nb_link]->mass1->posZ - link[nb_link]->mass2->posZ; // Lz[0] - link[nb_link]->longueur = sqrt(pow(link[nb_link]->longx,2)+pow(link[nb_link]->longy,2)+pow(link[nb_link]->longz,2));//L[0] - link[nb_link]->nbr = id_link; // id number - link[nb_link]->distance_old = link[nb_link]->longueur; // L[n-1] - switch (argc) { - case 6 : - link[nb_link]->long_max = 32768; - link[nb_link]->long_min = 0; - break; - case 7 : - link[nb_link]->long_min = GetFloat(argv[6]); - link[nb_link]->long_max = 32768; - break; - case 8 : - link[nb_link]->long_min = GetFloat(argv[6]); - link[nb_link]->long_max = GetFloat(argv[7]); - break; - } - 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]),GetInt(argv[1])); - SetFloat((sortie[3]),GetInt(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,S_Link,7,sortie); - } - else - error("link : Cannot create link: Not all masses for this link have been created yet."); - } - - void m_ilink(int argc,t_atom *argv) - // add interactor link - // Id, Id masses1, Id masses2, K1, D1, D2, (Lmin, Lmax) - { - t_atom aux[2], arglist[8]; - t_int i,j, nbmass1=0, nbmass2=0; - NEWARR(t_int,imass1,nb_mass); - NEWARR(t_int,imass2,nb_mass); - t_symbol *Id1, *Id2; - t_mass **mi; - - if (argc < 6 || argc > 8) - error("ilink : Id Idmass1 Idmass2 K D1 D2 (Lmin Lmax)"); - - Id1 = GetSymbol(argv[1]); - Id2 = GetSymbol(argv[2]); - ToOutAnything(1,S_iLink,0,aux); - - for (i=0, mi=mass; i<nb_mass;mi++, i++) { - if (Id1 == (*mi)->Id) { - imass1[nbmass1]=i; - nbmass1++; - } - if (Id2 == (*mi)->Id) { - imass2[nbmass2]=i; - nbmass2++; - } - } - - for(i=0;i<nbmass1;i++) - for(j=0;j<nbmass2;j++) - if (imass1[i] != imass2[j]) { - SetSymbol((arglist[0]),GetSymbol(argv[0])); - SetFloat((arglist[1]),mass[imass1[i]]->nbr); - SetFloat((arglist[2]),mass[imass2[j]]->nbr); - SetFloat((arglist[3]),GetFloat(argv[3])); - SetFloat((arglist[4]),GetFloat(argv[4])); - SetFloat((arglist[5]),GetFloat(argv[5])); - switch (argc) { - case 7 : - SetFloat(arglist[6],GetFloat(argv[6])); - break; - case 8 : - SetFloat(arglist[6],GetFloat(argv[6])); - SetFloat(arglist[7],GetFloat(argv[7])); - break; - } - m_link(argc,arglist); - } - DELARR(imass1); - DELARR(imass2); - } - - void m_setK(int argc,t_atom *argv) - { - // set rigidity of link(s) named Id - t_int i; - const t_symbol *sym = GetSymbol(argv[0]); - t_link **li; - - if (argc != 2) - error("setK : IdLink Value"); - - for (i=0, li=link; i<nb_link;li++, i++) - { - if (sym == (*li)->Id) - (*li)->K1 = GetFloat(argv[1]); - } - } - - void m_setD(int argc,t_atom *argv) - { - // set damping of link(s) named Id - t_int i; - const t_symbol *sym = GetSymbol(argv[0]); - t_link **li; - - if (argc != 2) - error("setD : IdLink Value"); - - for (i=0, li=link; i<nb_link;li++, i++) - { - if (sym == (*li)->Id) - (*li)->D1 = GetFloat(argv[1]); - } - } - - void m_setD2(int argc,t_atom *argv) - { - // set damping of link(s) named Id - t_int i; - const t_symbol *sym = GetSymbol(argv[0]); - t_link **li; - - if (argc != 2) - error("setD2 : IdLink Value"); - - for (i=0, li=link; i<nb_link;li++, i++) - { - if (sym == (*li)->Id) - (*li)->D2 = GetFloat(argv[1]); - } - } - - void m_delete_link(int argc,t_atom *argv) - { - // Delete link - t_int i; - t_atom sortie[7]; - t_link **li; - - if (argc != 1) - error("deleteLink : NoLink"); - - for (i=0, li=link; i<nb_link;li++, i++) - if ((*li)->nbr == GetInt(argv[0])) { - SetFloat((sortie[0]),(*li)->nbr); - SetSymbol((sortie[1]),(*li)->Id); - SetFloat((sortie[2]),(*li)->mass1->nbr); - SetFloat((sortie[3]),(*li)->mass2->nbr); - SetFloat((sortie[4]),(*li)->K1); - SetFloat((sortie[5]),(*li)->D1); - SetFloat((sortie[6]),(*li)->D2); - delete (*li); - (*li)=link[nb_link-1]; // copy last link instead - nb_link--; - ToOutAnything(1,S_Link_deleted,7,sortie); - break; - } - } - - -// -------------------------------------------------------------- GET -// ------------------------------------------------------------------- - void m_get(int argc,t_atom *argv) - // get attributes - { - t_int i,j; - t_symbol *auxarg,*auxarg2, *auxtype; - t_atom sortie[7]; - auxtype = GetSymbol(argv[0]); - auxarg = GetASymbol(argv[1]); //auxarg : & symbol, 0 else - t_mass **mi; - t_link **li; - - if (argc == 1) - { - if (auxtype == S_massesPos)// get all masses positions - for (i=0, mi=mass; i<nb_mass;mi++, i++) - { - SetFloat(sortie[0],(*mi)->nbr); - SetFloat(sortie[1],(*mi)->posX); - SetFloat(sortie[2],(*mi)->posY); - SetFloat(sortie[3],(*mi)->posZ); - ToOutAnything(0,S_massesPos,4,sortie); - } - else if (auxtype == S_massesForces)// get all masses forces - for (i=0, mi=mass; i<nb_mass;mi++, i++) - { - SetFloat(sortie[0],(*mi)->nbr); - SetFloat(sortie[1],(*mi)->out_forceX); - SetFloat(sortie[2],(*mi)->out_forceY); - SetFloat(sortie[3],(*mi)->out_forceZ); - ToOutAnything(0,S_massesForces,4,sortie); - } - else if (auxtype == S_linksPos)// get all links positions - for (i=0, li=link; i<nb_link;li++, i++) - { - SetFloat(sortie[0],(*li)->nbr); - SetFloat(sortie[1],(*li)->mass1->posX); - SetFloat(sortie[2],(*li)->mass1->posY); - SetFloat(sortie[3],(*li)->mass1->posZ); - SetFloat(sortie[4],(*li)->mass2->posX); - SetFloat(sortie[5],(*li)->mass2->posY); - SetFloat(sortie[6],(*li)->mass2->posZ); - ToOutAnything(0,S_linksPos,7,sortie); - } - else // get all masses speeds - for (i=0, mi=mass; i<nb_mass;mi++, i++) - { - SetFloat(sortie[0],(*mi)->nbr); - SetFloat(sortie[1],(*mi)->speedX); - SetFloat(sortie[2],(*mi)->speedY); - SetFloat(sortie[3],(*mi)->speedZ); - ToOutAnything(0,S_massesSpeeds,4,sortie); - } - } - else if (auxtype == S_massesPos) // get mass positions - { - if (auxarg == 0) // No - { - for (j = 1; j<argc; j++) - for (i=0, mi=mass; i<nb_mass;mi++, i++) - if ((*mi)->nbr==GetInt(argv[j])) - { - SetFloat(sortie[0],(*mi)->nbr); - SetFloat(sortie[1],(*mi)->posX); - SetFloat(sortie[2],(*mi)->posY); - SetFloat(sortie[3],(*mi)->posZ); - ToOutAnything(0,S_massesPosNo,4,sortie); - } - } - else //symbol - { - for (j = 1; j<argc; j++) - { - auxarg2 = GetSymbol(argv[j]); - for (i=0, mi=mass; i<nb_mass;mi++, i++) - { - if (auxarg2==(*mi)->Id) - { - SetSymbol(sortie[0],(*mi)->Id); - SetFloat(sortie[1],(*mi)->posX); - SetFloat(sortie[2],(*mi)->posY); - SetFloat(sortie[3],(*mi)->posZ); - ToOutAnything(0,S_massesPosId,4,sortie); - } - } - } - } - } - else if (auxtype == S_massesForces) // get mass forces - { - if (auxarg == 0) // No - { - for (j = 1; j<argc; j++) - for (i=0, mi=mass; i<nb_mass;mi++, i++) - if ((*mi)->nbr==GetInt(argv[j])) - { - SetFloat(sortie[0],(*mi)->nbr); - SetFloat(sortie[1],(*mi)->out_forceX); - SetFloat(sortie[2],(*mi)->out_forceY); - SetFloat(sortie[3],(*mi)->out_forceZ); - ToOutAnything(0,S_massesForcesNo,4,sortie); - } - } - else //symbol - { - for (j = 1; j<argc; j++) - { - auxarg2 = GetSymbol(argv[j]); - for (i=0, mi=mass; i<nb_mass;mi++, i++) - { - if (auxarg2==(*mi)->Id) - { - SetSymbol(sortie[0],(*mi)->Id); - SetFloat(sortie[1],(*mi)->out_forceX); - SetFloat(sortie[2],(*mi)->out_forceY); - SetFloat(sortie[3],(*mi)->out_forceZ); - ToOutAnything(0,S_massesForcesId,4,sortie); - } - } - } - } - } - else if (auxtype == S_linksPos) // get links positions - { - if (auxarg == 0) // No - { - for (j = 1; j<argc; j++) - for (i=0, li=link; i<nb_link;li++, i++) - if ((*li)->nbr==GetInt(argv[j])) - { - SetFloat(sortie[0],(*li)->nbr); - SetFloat(sortie[1],(*li)->mass1->posX); - SetFloat(sortie[2],(*li)->mass1->posY); - SetFloat(sortie[3],(*li)->mass1->posZ); - SetFloat(sortie[4],(*li)->mass2->posX); - SetFloat(sortie[5],(*li)->mass2->posY); - SetFloat(sortie[6],(*li)->mass2->posZ); - ToOutAnything(0,S_linksPosNo,7,sortie); - } - } - else //symbol - { - for (j = 1; j<argc; j++) - { - auxarg2 = GetSymbol(argv[j]); - for (i=0, li=link; i<nb_link;li++, i++) - { - if (auxarg2==(*li)->Id) - { - SetSymbol(sortie[0],(*li)->Id); - SetFloat(sortie[1],(*li)->mass1->posX); - SetFloat(sortie[2],(*li)->mass1->posY); - SetFloat(sortie[3],(*li)->mass1->posZ); - SetFloat(sortie[4],(*li)->mass2->posX); - SetFloat(sortie[5],(*li)->mass2->posY); - SetFloat(sortie[6],(*li)->mass2->posZ); - ToOutAnything(0,S_linksPosId,7,sortie); - } - } - } - } - } - else // get mass speeds - { - if (auxarg == 0) // No - { - for (j = 1; j<argc; j++) - for (i=0, mi=mass; i<nb_mass;mi++, i++) - if ((*mi)->nbr==GetInt(argv[j])) - { - SetFloat(sortie[0],(*mi)->nbr); - SetFloat(sortie[1],(*mi)->speedX); - SetFloat(sortie[2],(*mi)->speedY); - SetFloat(sortie[3],(*mi)->speedZ); - ToOutAnything(0,S_massesSpeedsNo,4,sortie); - } - } - else //symbol - { - for (j = 1; j<argc; j++) - { - auxarg2 = GetSymbol(argv[j]); - for (i=0, mi=mass; i<nb_mass;mi++, i++) - { - if (auxarg2==(*mi)->Id) - { - SetSymbol(sortie[0],(*mi)->Id); - SetFloat(sortie[1],(*mi)->speedX); - SetFloat(sortie[2],(*mi)->speedY); - SetFloat(sortie[3],(*mi)->speedZ); - ToOutAnything(0,S_massesSpeedsId,4,sortie); - } - } - } - } - } - - - } - - void m_mass_dumpl() - // List of masses positions on first outlet - { - NEWARR(t_atom,sortie,3*nb_mass); - t_int i; - t_mass **mi; - - for (i=0, mi=mass; i<nb_mass;mi++, i++) { - SetFloat((sortie[3*i]),(*mi)->posX); - SetFloat((sortie[3*i+1]),(*mi)->posY); - SetFloat((sortie[3*i+2]),(*mi)->posZ); - } - ToOutAnything(0, S_massesPosL, 3*nb_mass, sortie); - DELARR(sortie); - } - - void m_force_dumpl() - // List of masses positions on first outlet - { - NEWARR(t_atom,sortie,3*nb_mass); - t_int i; - t_mass **mi; - - for (i=0, mi=mass; i<nb_mass;mi++, i++) { - SetFloat((sortie[3*i]),(*mi)->out_forceX); - SetFloat((sortie[3*i+1]),(*mi)->out_forceY); - SetFloat((sortie[3*i+2]),(*mi)->out_forceZ); - } - ToOutAnything(0, S_massesForcesL, 3*nb_mass, sortie); - DELARR(sortie); - } - - void m_info_dumpl() - // List of masses positions on first outlet - { - t_atom sortie[7]; - t_int i; - t_mass **mi; - t_link **li; - - for (i=0, mi=mass; i<nb_mass;mi++, i++) { - SetFloat((sortie[0]),(*mi)->nbr); - SetSymbol((sortie[1]),(*mi)->Id); - SetFloat((sortie[2]),(*mi)->mobile); - SetFloat((sortie[3]),1/(*mi)->invM); - SetFloat((sortie[4]),(*mi)->posX); - SetFloat((sortie[5]),(*mi)->posY); - SetFloat((sortie[6]),(*mi)->posZ); - ToOutAnything(1, S_Mass, 7, sortie); - } - - for (i=0, li=link; i<nb_link;li++, i++) { - SetFloat((sortie[0]),(*li)->nbr); - SetSymbol((sortie[1]),(*li)->Id); - SetFloat((sortie[2]),(*li)->mass1->nbr); - SetFloat((sortie[3]),(*li)->mass2->nbr); - SetFloat((sortie[4]),(*li)->K1); - SetFloat((sortie[5]),(*li)->D1); - SetFloat((sortie[6]),(*li)->D2); - ToOutAnything(1, S_Link, 7, sortie); - } - - } - -// -------------------------------------------------------------- GLOBAL VARIABLES -// -------------------------------------------------------------------------------- - t_link * link[nb_max_link]; - t_mass * mass[nb_max_mass]; - t_float Xmin, Xmax, Ymin, Ymax, Zmin, Zmax; - int nb_link, nb_mass, id_mass, id_link; - -// -------------------------------------------------------------- SETUP -// --------------------------------------------------------------------- -private: - - // static symbols - const static t_symbol *S_Reset; - const static t_symbol *S_Mass; - const static t_symbol *S_Link; - const static t_symbol *S_iLink; - const static t_symbol *S_Mass_deleted; - const static t_symbol *S_Link_deleted; - const static t_symbol *S_massesPos; - const static t_symbol *S_massesPosNo; - const static t_symbol *S_massesPosId; - const static t_symbol *S_linksPos; - const static t_symbol *S_linksPosNo; - const static t_symbol *S_linksPosId; - const static t_symbol *S_massesForces; - const static t_symbol *S_massesForcesNo; - const static t_symbol *S_massesForcesId; - const static t_symbol *S_massesSpeeds; - const static t_symbol *S_massesSpeedsNo; - const static t_symbol *S_massesSpeedsId; - const static t_symbol *S_massesPosL; - const static t_symbol *S_massesForcesL; - - static void setup(t_classid c) - { - - // --- set up methods (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,"forceY",m_forceY); - FLEXT_CADDMETHOD_(c,0,"forceZ",m_forceZ); - 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,"Ymax",m_Ymax); - FLEXT_CADDMETHOD_(c,0,"Ymin",m_Ymin); - FLEXT_CADDMETHOD_(c,0,"posY",m_posY); - FLEXT_CADDMETHOD_(c,0,"Zmax",m_Zmax); - FLEXT_CADDMETHOD_(c,0,"Zmin",m_Zmin); - FLEXT_CADDMETHOD_(c,0,"posZ",m_posZ); - 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); - FLEXT_CADDMETHOD_(c,0,"setMobile",m_set_mobile); - FLEXT_CADDMETHOD_(c,0,"setFixed",m_set_fixe); - } - - // 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_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_Ymax) - FLEXT_CALLBACK_V(m_Ymin) - FLEXT_CALLBACK_V(m_Zmax) - FLEXT_CALLBACK_V(m_Zmin) - FLEXT_CALLBACK_V(m_setK) - FLEXT_CALLBACK_V(m_setD) - FLEXT_CALLBACK_V(m_setD2) - FLEXT_CALLBACK_V(m_forceX) - FLEXT_CALLBACK_V(m_forceY) - FLEXT_CALLBACK_V(m_forceZ) - FLEXT_CALLBACK_V(m_posX) - FLEXT_CALLBACK_V(m_posY) - FLEXT_CALLBACK_V(m_posZ) - FLEXT_CALLBACK_V(m_get) - FLEXT_CALLBACK_V(m_delete_link) - FLEXT_CALLBACK_V(m_delete_mass) - FLEXT_CALLBACK_V(m_set_mobile) - FLEXT_CALLBACK_V(m_set_fixe) -}; - - const t_symbol *msd3D::S_Reset = MakeSymbol("Reset"); - const t_symbol *msd3D::S_Mass = MakeSymbol("Mass"); - const t_symbol *msd3D::S_Link = MakeSymbol("Link"); - const t_symbol *msd3D::S_iLink = MakeSymbol("iLink"); - const t_symbol *msd3D::S_Mass_deleted = MakeSymbol("Mass deleted"); - const t_symbol *msd3D::S_Link_deleted = MakeSymbol("Link deleted"); - const t_symbol *msd3D::S_massesPos = MakeSymbol("massesPos"); - const t_symbol *msd3D::S_massesPosNo = MakeSymbol("massesPosNo"); - const t_symbol *msd3D::S_massesPosId = MakeSymbol("massesPosId"); - const t_symbol *msd3D::S_linksPos = MakeSymbol("linksPos"); - const t_symbol *msd3D::S_linksPosNo = MakeSymbol("linksPosNo"); - const t_symbol *msd3D::S_linksPosId = MakeSymbol("linksPosId"); - const t_symbol *msd3D::S_massesForces = MakeSymbol("massesForces"); - const t_symbol *msd3D::S_massesForcesNo = MakeSymbol("massesForcesNo"); - const t_symbol *msd3D::S_massesForcesId = MakeSymbol("massesForcesId"); - const t_symbol *msd3D::S_massesSpeeds = MakeSymbol("massesSpeeds"); - const t_symbol *msd3D::S_massesSpeedsNo = MakeSymbol("massesSpeedsNo"); - const t_symbol *msd3D::S_massesSpeedsId = MakeSymbol("massesSpeedsId"); - const t_symbol *msd3D::S_massesPosL = MakeSymbol("massesPosL"); - const t_symbol *msd3D::S_massesForcesL = MakeSymbol("massesForcesL"); - -// instantiate the class (constructor has a variable argument list) -FLEXT_NEW_V("msd3D",msd3D) - - +MSD("msd3D",msd3D,3) |