aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Henry <nusmuk@users.sourceforge.net>2011-02-18 19:56:11 +0000
committerCyrille Henry <nusmuk@users.sourceforge.net>2011-02-18 19:56:11 +0000
commited864f40e547f6994ff61135016f40be682d74e2 (patch)
treeb02063db1415cff63998b316fccf5f29ac8ce8df
parent45db148cbbebda92ccc34ba8c7cbb0736d63c297 (diff)
1st test version of pmpd / pmpd2d / pmpd3d, as MSD compatible, but without flext
svn path=/trunk/externals/pmpd/; revision=14927
-rw-r--r--Makefile2
-rw-r--r--pmpd.c287
-rw-r--r--pmpd3d.c2233
-rw-r--r--pmpd~.c117
4 files changed, 2543 insertions, 96 deletions
diff --git a/Makefile b/Makefile
index fcb9e87..3a71685 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ LIBRARY_NAME = pmpd
# add your .c source files, one object per file, to the SOURCES
# variable, help files will be included automatically
-SOURCES = iAmbient2D.c iAmbient3D.c iCircle2D.c iCircle3D.c iCylinder3D.c iLine2D.c iPlane3D.c iSeg2D.c iSphere3D.c link.c link2D.c link3D.c mass.c mass2D.c mass3D.c pmpd.c pmpd~.c tCircle2D.c tCircle3D.c tCube3D.c tCylinder3D.c tLine2D.c tLink2D.c tLink3D.c tPlane3D.c tSeg2D.c tSphere3D.c tSquare2D.c
+SOURCES = iAmbient2D.c iAmbient3D.c iCircle2D.c iCircle3D.c iCylinder3D.c iLine2D.c iPlane3D.c iSeg2D.c iSphere3D.c link.c link2D.c link3D.c mass.c mass2D.c mass3D.c pmpd.c pmpd2d.c pmpd3d.c pmpd~.c tCircle2D.c tCircle3D.c tCube3D.c tCylinder3D.c tLine2D.c tLink2D.c tLink3D.c tPlane3D.c tSeg2D.c tSphere3D.c tSquare2D.c
# list all pd objects (i.e. myobject.pd) files here, and their helpfiles will
# be included automatically
diff --git a/pmpd.c b/pmpd.c
index c220638..b2a6feb 100644
--- a/pmpd.c
+++ b/pmpd.c
@@ -27,18 +27,11 @@
----------------------------------------------------------------------------
*/
-#ifndef VERSION
-#define VERSION "0.10"
-#endif
-
#include "m_pd.h"
#include "stdio.h"
+#include "math.h"
-#ifndef __DATE__
-#define __DATE__ ""
-#endif
-
-#define nb_max_link 1000000
+#define nb_max_link 100000
#define nb_max_mass 100000
#define max(a,b) ( ((a) > (b)) ? (a) : (b) )
@@ -49,6 +42,11 @@ t_float sign_ch(t_float v)
return v > 0 ? 1 : -1;
}
+t_float pow_ch(t_float x, t_float y)
+{
+ return x > 0 ? pow(x,y) : -pow(-x,y);
+}
+
static t_class *pmpd_class;
typedef struct _mass {
@@ -58,11 +56,13 @@ typedef struct _mass {
t_float speedX;
t_float posX;
t_float forceX;
+ t_float D2;
int num;
} foo;
typedef struct _link {
t_symbol *Id;
+ int type;
struct _mass *mass1;
struct _mass *mass2;
t_float K;
@@ -98,27 +98,36 @@ void pmpd_bang(t_pmpd *x)
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].forceX = 0;
x->mass[i].posX += x->mass[i].speedX ;
x->mass[i].posX = min(x->maxX,max(x->minX,x->mass[i].posX));
+ x->mass[i].forceX = -x->mass[i].D2 * x->mass[i].speedX;
}
for (i=0; i<x->nb_link; i++)
- // comput link forces
+ // compute link forces
{
- L = x->link[i].mass1->posX - x->link[i].mass2->posX;
- absL = fabs(L);
- if ( (absL >= x->link[i].Lmin) & (absL < x->link[i].Lmax) & (L!=0))
- {
- F = x->link[i].D * (L - x->link[i].distance) ;
- x->link[i].distance=L;
-
- L = sign_ch(L) * pow( absL - x->link[i].L, x->link[i].Pow);
-
- F += x->link[i].K * L;
- x->link[i].mass1->forceX -= F;
- x->link[i].mass2->forceX += F;
- }
+ switch (x->link[i].type)
+ {
+ case 0: // standard link
+
+ L = x->link[i].mass1->posX - x->link[i].mass2->posX;
+ absL = fabs(L);
+ if ( (absL >= x->link[i].Lmin) & (absL < x->link[i].Lmax) & (absL - x->link[i].L !=0))
+ {
+ F = x->link[i].D * (L - x->link[i].distance) ;
+ x->link[i].distance=L;
+
+ L = sign_ch(L) * pow_ch( absL - x->link[i].L, x->link[i].Pow);
+
+ F += x->link[i].K * L;
+ x->link[i].mass1->forceX -= F;
+ x->link[i].mass2->forceX += F;
+ }
+ break;
+ case 1: // link with rigidity from a table
+ break;
+ }
}
}
@@ -175,9 +184,8 @@ void pmpd_posX(t_pmpd *x, t_symbol *s, int argc, t_atom *argv)
}
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
-{
+{ // add a mass : Id, invM speedX posX forceX
+
if (M<=0) M=1;
x->mass[x->nb_mass].Id = Id;
x->mass[x->nb_mass].mobile = (int)mobile;
@@ -196,6 +204,7 @@ void pmpd_create_link(t_pmpd *x, t_symbol *Id, int mass1, int mass2, t_float K,
if ((x->nb_mass>0) & (mass1 != mass2) & (mass1 >= 0) & (mass2 >= 0) & (mass1 < x->nb_mass) & (mass2 < x->nb_mass) )
{
+ x->link[x->nb_link].type = 0;
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];
@@ -205,7 +214,7 @@ void pmpd_create_link(t_pmpd *x, t_symbol *Id, int mass1, int mass2, t_float K,
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->link[x->nb_link].distance = x->link[x->nb_link].L;
x->nb_link++ ;
x->nb_link = min ( nb_max_link -1, x->nb_link );
@@ -213,9 +222,8 @@ void pmpd_create_link(t_pmpd *x, t_symbol *Id, int mass1, int mass2, t_float K,
}
void pmpd_link(t_pmpd *x, t_symbol *s, int argc, t_atom *argv)
-// add a link
-// Id, *mass1, *mass2, K, D, Pow, Lmin, Lmax;
-{
+{ // add a link : Id, *mass1, *mass2, K, D, Pow, Lmin, Lmax;
+
int i, j;
t_symbol *Id = atom_getsymbolarg(0,argc,argv);
@@ -397,6 +405,94 @@ void pmpd_setD(t_pmpd *x, t_symbol *s, int argc, t_atom *argv)
}
}
+void pmpd_setD2(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_mass-1, tmp));
+ x->mass[tmp].D2 = 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].D2 = atom_getfloatarg(1, argc, argv);
+ }
+ }
+ }
+}
+
+void pmpd_setSpeedX(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_mass-1, tmp));
+ x->mass[tmp].speedX = 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].speedX = atom_getfloatarg(1, argc, argv);
+ }
+ }
+ }
+}
+
+void pmpd_addPosX(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_mass-1, tmp));
+ x->mass[tmp].posX += 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].posX += atom_getfloatarg(1, argc, argv);
+ }
+ }
+ }
+}
+
+void pmpd_setForceX(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_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_setL(t_pmpd *x, t_symbol *s, int argc, t_atom *argv)
{
int tmp, i;
@@ -417,12 +513,27 @@ void pmpd_setL(t_pmpd *x, t_symbol *s, int argc, t_atom *argv)
}
}
}
+ if ( ( argv[0].a_type == A_FLOAT ) & ( argc == 1 ) )
+ {
+ tmp = atom_getfloatarg(0, argc, argv);
+ tmp = max(0, min( x->nb_link-1, tmp));
+ x->link[tmp].L = x->link[tmp].mass2->posX - x->link[tmp].mass1->posX;
+ }
+ if ( ( argv[0].a_type == A_SYMBOL ) & ( argc == 1 ) )
+ {
+ for (i=0; i< x->nb_link; i++)
+ {
+ if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+ {
+ x->link[i].L = x->link[i].mass2->posX - x->link[i].mass1->posX;
+ }
+ }
+ }
}
void pmpd_get(t_pmpd *x, t_symbol *s, int argc, t_atom *argv)
{
- int tmp, i;
- t_float X;
+ int i;
t_symbol *toget;
t_atom toout[2];
toget = atom_getsymbolarg(0, argc, argv);
@@ -713,7 +824,7 @@ void pmpd_massesPosL(t_pmpd *x)
int i;
t_atom pos_list[nb_max_link];
- for (i=0; i< x->nb_mass; i++)
+ for (i=0; i < x->nb_mass; i++)
{
SETFLOAT(&(pos_list[i]),x->mass[i].posX);
}
@@ -732,6 +843,84 @@ void pmpd_massesForcesL(t_pmpd *x)
outlet_anything(x->main_outlet, gensym("massesForcesL"),x->nb_mass , pos_list);
}
+void pmpd_massesSpeedsL(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].speedX);
+ }
+ outlet_anything(x->main_outlet, gensym("massesSpeedsL"),x->nb_mass , pos_list);
+}
+
+void pmpd_massesPosT(t_pmpd *x, t_symbol *tab_name)
+{
+ int i, vecsize;
+ t_garray *a;
+ t_word *vec;
+
+ if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+ pd_error(x, "%s: no such array", tab_name->s_name);
+ else if (!garray_getfloatwords(a, &vecsize, &vec))
+ pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+ else
+ {
+ int taille_max = x->nb_mass;
+ taille_max = min(taille_max, vecsize);
+ for (i=0; i < taille_max ; i++)
+ {
+ vec[i].w_float = x->mass[i].posX;
+ }
+ garray_redraw(a);
+ }
+}
+
+void pmpd_massesSpeedsT(t_pmpd *x, t_symbol *tab_name)
+{
+ int i, vecsize;
+ t_garray *a;
+ t_word *vec;
+
+ if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+ pd_error(x, "%s: no such array", tab_name->s_name);
+ else if (!garray_getfloatwords(a, &vecsize, &vec))
+ pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+ else
+ {
+ int taille_max = x->nb_mass;
+ taille_max = min(taille_max, vecsize);
+ for (i=0; i < taille_max ; i++)
+ {
+ vec[i].w_float = x->mass[i].speedX;
+ }
+ garray_redraw(a);
+ }
+}
+
+void pmpd_massesForcesT(t_pmpd *x, t_symbol *tab_name)
+{
+ int i, vecsize;
+ t_garray *a;
+ t_word *vec;
+
+ if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+ pd_error(x, "%s: no such array", tab_name->s_name);
+ else if (!garray_getfloatwords(a, &vecsize, &vec))
+ pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+ else
+ {
+ int taille_max = x->nb_mass;
+ taille_max = min(taille_max, vecsize);
+ for (i=0; i < taille_max ; i++)
+ {
+ vec[i].w_float = x->mass[i].forceX;
+ }
+ garray_redraw(a);
+ }
+}
+
void *pmpd_new()
{
t_pmpd *x = (t_pmpd *)pd_new(pmpd_class);
@@ -739,7 +928,7 @@ void *pmpd_new()
pmpd_reset(x);
x->main_outlet=outlet_new(&x->x_obj, 0);
- x->info_outlet=outlet_new(&x->x_obj, 0); // TODO
+ // x->info_outlet=outlet_new(&x->x_obj, 0); // TODO
return (void *)x;
}
@@ -751,21 +940,45 @@ void pmpd_setup(void)
0, sizeof(t_pmpd),CLASS_DEFAULT, 0);
class_addbang(pmpd_class, pmpd_bang);
+ 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_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_link, gensym("tabLink"), A_GIMME, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_posX, gensym("pos"), 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("force"), 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_setD2, gensym("setD2"), A_GIMME, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_setSpeedX, gensym("setSpeed"), A_GIMME, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_setSpeedX, gensym("setSpeedX"), A_GIMME, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_setForceX, gensym("setForce"), A_GIMME, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_setForceX, gensym("setForceX"), A_GIMME, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_addPosX, gensym("addPos"), A_GIMME, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_addPosX, gensym("addPosX"), 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_massesSpeedsL, gensym("massesSpeedsL"), 0);
class_addmethod(pmpd_class, (t_method)pmpd_massesForcesL, gensym("massesForcesL"), 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_massesPosT, gensym("massesPosT"), A_DEFSYMBOL, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_massesSpeedsT, gensym("massesSpeedsT"),A_DEFSYMBOL, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_massesForcesT, gensym("massesForcesT"),A_DEFSYMBOL, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_massesPosL, gensym("massesPosXL"), 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_massesSpeedsL, gensym("massesSpeedsXL"), 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_massesForcesL, gensym("massesForcesXL"), 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_massesPosT, gensym("massesPosXT"), A_DEFSYMBOL, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_massesSpeedsT, gensym("massesSpeedsXT"),A_DEFSYMBOL, 0);
+ class_addmethod(pmpd_class, (t_method)pmpd_massesForcesT, gensym("massesForcesXT"),A_DEFSYMBOL, 0);
+ // class_addmethod(pmpd_class, (t_method)pmpd_massesPosL, gensym("massesPosMean"), 0);
+ // class_addmethod(pmpd_class, (t_method)pmpd_massesPosL, gensym("massesPosStd"), 0);
+ // setMassId, setLinkId
+
}
diff --git a/pmpd3d.c b/pmpd3d.c
new file mode 100644
index 0000000..f9bb712
--- /dev/null
+++ b/pmpd3d.c
@@ -0,0 +1,2233 @@
+/*
+-------------------------- pmpd3d ----------------------------------------
+
+
+ pmpd = physical modeling for pure data
+ Written by Cyrille Henry (ch@chnry.net)
+
+ 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
+ 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.
+
+ Based on PureData by Miller Puckette and others.
+
+
+----------------------------------------------------------------------------
+*/
+
+#include "m_pd.h"
+#include "stdio.h"
+#include "math.h"
+
+#define nb_max_link 100000
+#define nb_max_mass 100000
+
+#define max(a,b) ( ((a) > (b)) ? (a) : (b) )
+#define min(a,b) ( ((a) < (b)) ? (a) : (b) )
+
+t_float sign_ch(t_float v)
+{
+ return v > 0 ? 1 : -1;
+}
+
+t_float sqr(t_float x)
+{
+ return x*x ;
+}
+
+t_float pow_ch(t_float x, t_float y)
+{
+ return x > 0 ? pow(x,y) : -pow(-x,y);
+}
+
+static t_class *pmpd3d_class;
+
+typedef struct _mass {
+ t_symbol *Id;
+ int mobile;
+ t_float invM;
+ t_float speedX;
+ t_float speedY;
+ t_float speedZ;
+ t_float posX;
+ t_float posY;
+ t_float posZ;
+ t_float forceX;
+ t_float forceY;
+ t_float forceZ;
+ t_float D2;
+ int num;
+} foo;
+
+typedef struct _link {
+ t_symbol *Id;
+ int lType;
+ struct _mass *mass1;
+ struct _mass *mass2;
+ t_float K;
+ t_float D;
+ t_float L;
+ t_float Pow;
+ t_float Lmin;
+ t_float Lmax;
+ t_float distance;
+ t_float VX; // vecteur portant la liaison, si c'est le cas
+ t_float VY;
+ t_float VZ;
+ t_symbol *arrayK;
+ t_symbol *arrayD;
+} foo1 ;
+
+typedef struct _pmpd3d2d
+{
+ t_object x_obj;
+ struct _link link[nb_max_link];
+ struct _mass mass[nb_max_mass];
+ t_outlet *main_outlet;
+ t_outlet *info_outlet;
+ int nb_link;
+ int nb_mass;
+ t_float minX, maxX, minY, maxY, minZ, maxZ;
+ t_int grab; // si on grab une mass ou pas
+ t_int grab_nb; // la masse grabé
+} t_pmpd3d;
+
+t_float tabread2(t_pmpd3d *x, t_float pos, t_symbol *array)
+{
+ t_garray *a;
+ int npoints;
+ t_word *vec;
+ t_float posx;
+
+ if (!(a = (t_garray *)pd_findbyclass(array, garray_class)))
+ pd_error(x, "%s: no such array", array);
+ else if (!garray_getfloatwords(a, &npoints, &vec))
+ pd_error(x, "%s: bad template for tabLink", array);
+ else
+ {
+ posx = fabs(pos)*npoints;
+ int n=posx;
+ if (n >= npoints - 1)
+ return (sign_ch(pos)*vec[npoints-1].w_float);
+ float fract = posx-n;
+ return (sign_ch(pos) * ( fract*vec[n+1].w_float+(1-fract)*vec[n].w_float));
+ }
+ return( pos); // si il y a un pb sur le tableau, on renvoie l'identité
+}
+
+void pmpd3d_reset(t_pmpd3d *x)
+{
+ x->nb_link = 0;
+ x->nb_mass = 0;
+ x->minX = -1000000;
+ x->maxX = 1000000;
+ x->minY = -1000000;
+ x->maxY = 1000000;
+ x->minZ = -1000000;
+ x->maxZ = 1000000;
+ x->grab = 0;
+}
+
+void pmpd3d_infosL(t_pmpd3d *x)
+{
+ int i;
+ post("list of mass");
+ post("number, Id, mobile, mass, positionX Y Z, speedX Y Z, forcesX Y Z");
+ for(i=0; i < x->nb_mass; i++)
+ {
+ post("masse %i: %s, %d, %f, %f, %f, %f, %f, %f, %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].posY, x->mass[i].posZ, x->mass[i].speedX, x->mass[i].speedY, x->mass[i].speedZ, x->mass[i].forceX, x->mass[i].forceY, x->mass[i].forceZ );
+ }
+
+ 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);
+ }
+}
+
+void pmpd3d_bang(t_pmpd3d *x)
+{
+// this part is doing all the PM
+ t_float F, L, Lx,Ly, Lz, Fx, Fy, Fz, tmpX, tmpY, tmpZ;
+ t_int i;
+ // post("bang");
+
+ for (i=1; i<x->nb_mass; i++)
+ // compute new masses position
+ if (x->mass[i].mobile > 0) // only if mobile
+ {
+ x->mass[i].speedX += x->mass[i].forceX * x->mass[i].invM;
+ x->mass[i].speedY += x->mass[i].forceY * x->mass[i].invM;
+ x->mass[i].speedZ += x->mass[i].forceZ * x->mass[i].invM;
+ // x->mass[i].forceX = 0;
+ // x->mass[i].forceY = 0;
+ // x->mass[i].forceZ = 0;
+ x->mass[i].posX += x->mass[i].speedX ;
+ x->mass[i].posY += x->mass[i].speedY ;
+ x->mass[i].posZ += x->mass[i].speedZ ;
+ if ( (x->mass[i].posX < x->minX) || (x->mass[i].posX > x->maxX) || (x->mass[i].posY < x->minY) || (x->mass[i].posY > x->maxY) || (x->mass[i].posZ < x->minZ) || (x->mass[i].posZ > x->maxZ) )
+ {
+ tmpX = min(x->maxX,max(x->minX,x->mass[i].posX));
+ tmpY = min(x->maxY,max(x->minY,x->mass[i].posY));
+ tmpZ = min(x->maxZ,max(x->minZ,x->mass[i].posZ));
+ x->mass[i].speedX -= x->mass[i].posX - tmpX;
+ x->mass[i].speedY -= x->mass[i].posY - tmpY;
+ x->mass[i].speedZ -= x->mass[i].posZ - tmpZ;
+ x->mass[i].posX = tmpX;
+ x->mass[i].posY = tmpY;
+ x->mass[i].posZ = tmpZ;
+ }
+ x->mass[i].forceX = -x->mass[i].D2 * x->mass[i].speedX;
+ x->mass[i].forceY = -x->mass[i].D2 * x->mass[i].speedY;
+ x->mass[i].forceZ = -x->mass[i].D2 * x->mass[i].speedZ;
+ }
+
+ for (i=0; i<x->nb_link; i++)
+ // compute link forces
+ {
+ Lx = x->link[i].mass1->posX - x->link[i].mass2->posX;
+ Ly = x->link[i].mass1->posY - x->link[i].mass2->posY;
+ Lz = x->link[i].mass1->posZ - x->link[i].mass2->posZ;
+ L = sqrt( sqr(Lx) + sqr(Ly) + sqr(Lz) );
+
+ if ( (L >= x->link[i].Lmin) & (L < x->link[i].Lmax) & (L != 0))
+ {
+ if (x->link[i].lType == 2)
+ { // K et D viennent d'une table
+ if (x->link[i].D == 0)
+ F = 0;
+ else
+ F = tabread2(x, (L - x->link[i].distance) / x->link[i].D, x->link[i].arrayD);
+ if (x->link[i].K != 0)
+ F += tabread2(x, L / x->link[i].K, x->link[i].arrayK);
+ }
+ else
+ {
+ F = x->link[i].D * (L - x->link[i].distance) ;
+ F += x->link[i].K * pow_ch( L - x->link[i].L, x->link[i].Pow);
+ }
+
+ Fx = F * Lx/L;
+ Fy = F * Ly/L;
+ Fz = F * Lz/L;
+
+ if (x->link[i].lType == 1)
+ { // on projette selon 1 axe
+ F = Fx*x->link[i].VX + Fy*x->link[i].VY + Fz*x->link[i].VZ; // produit scalaire de la force sur le vecteur qui la porte
+ Fx = F*x->link[i].VX; // V est unitaire, dc on projete sans pb
+ Fy = F*x->link[i].VY;
+ Fz = F*x->link[i].VZ;
+ }
+
+ x->link[i].mass1->forceX -= Fx;
+ x->link[i].mass1->forceY -= Fy;
+ x->link[i].mass1->forceZ -= Fz;
+ x->link[i].mass2->forceX += Fx;
+ x->link[i].mass2->forceY += Fy;
+ x->link[i].mass2->forceZ += Fz;
+ }
+ x->link[i].distance=L;
+ }
+}
+
+void pmpd3d_mass(t_pmpd3d *x, t_symbol *Id, t_float mobile, t_float M, t_float posX, t_float posY, t_float posZ )
+{ // add a mass : Id, invM speedX posX
+
+ 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].speedY = 0;
+ x->mass[x->nb_mass].speedZ = 0;
+ x->mass[x->nb_mass].posX = posX;
+ x->mass[x->nb_mass].posY = posY;
+ x->mass[x->nb_mass].posZ = posZ;
+ x->mass[x->nb_mass].forceX = 0;
+ x->mass[x->nb_mass].forceY = 0;
+ x->mass[x->nb_mass].forceZ = 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 pmpd3d_create_link(t_pmpd3d *x, t_symbol *Id, int mass1, int mass2, t_float K, t_float D, t_float Pow, t_float Lmin, t_float Lmax, t_int type)
+{ // create a link based on mass number
+
+ if ((x->nb_mass>1) & (mass1 != mass2) & (mass1 >= 0) & (mass2 >= 0) & (mass1 < x->nb_mass) & (mass2 < x->nb_mass) )
+ {
+ x->link[x->nb_link].lType = type;
+ 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 = sqrt(sqr(x->mass[mass1].posX - x->mass[mass2].posX) + sqr(x->mass[mass1].posY - x->mass[mass2].posY) + sqr(x->mass[mass1].posZ - x->mass[mass2].posZ));
+ 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 = x->link[x->nb_link].L ;
+
+ x->nb_link++ ;
+ x->nb_link = min ( nb_max_link -1, x->nb_link );
+ }
+}
+
+void pmpd3d_link(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{ // add a link : 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 ) )
+ {
+ pmpd3d_create_link(x, Id, mass1, mass2, K, D, Pow, Lmin, Lmax, 0);
+ }
+ 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)
+ {
+ pmpd3d_create_link(x, Id, i, mass2, K, D, Pow, Lmin, Lmax, 0);
+ }
+ }
+ }
+ 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)
+ {
+ pmpd3d_create_link(x, Id, mass1, i, K, D, Pow, Lmin, Lmax, 0);
+ }
+ }
+ }
+ 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))
+ {
+ pmpd3d_create_link(x, Id, i, j, K, D, Pow, Lmin, Lmax, 0);
+ }
+ }
+ }
+ }
+}
+
+void pmpd3d_tLink(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{ // add a link : Id, *mass1, *mass2, K, D, Vx, Vy, 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 vecteurX = atom_getfloatarg(5, argc, argv);
+ t_float vecteurY = atom_getfloatarg(6, argc, argv);
+ t_float vecteur = sqrt( sqr(vecteurX) + sqr(vecteurY) );
+ vecteurX /= vecteur;
+ vecteurY /= vecteur;
+ t_float Pow = 1;
+ if (argc > 7) Pow = atom_getfloatarg(5, argc, argv);
+ t_float Lmin = 0;
+ if (argc > 8) Lmin = atom_getfloatarg(6, argc, argv);
+ t_float Lmax = 1000000;
+ if (argc > 9) Lmax = atom_getfloatarg(7, argc, argv);
+
+ if ( ( argv[1].a_type == A_FLOAT ) & ( argv[2].a_type == A_FLOAT ) )
+ {
+ pmpd3d_create_link(x, Id, mass1, mass2, K, D, Pow, Lmin, Lmax, 0);
+ x->link[x->nb_link-1].VX = vecteurX;
+ x->link[x->nb_link-1].VY = vecteurY;
+ }
+ 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)
+ {
+ pmpd3d_create_link(x, Id, i, mass2, K, D, Pow, Lmin, Lmax, 0);
+ x->link[x->nb_link-1].VX = vecteurX;
+ x->link[x->nb_link-1].VY = vecteurY;
+ }
+ }
+ }
+ 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)
+ {
+ pmpd3d_create_link(x, Id, mass1, i, K, D, Pow, Lmin, Lmax, 0);
+ x->link[x->nb_link-1].VX = vecteurX;
+ x->link[x->nb_link-1].VY = vecteurY;
+ }
+ }
+ }
+ 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))
+ {
+ pmpd3d_create_link(x, Id, i, j, K, D, Pow, Lmin, Lmax, 0);
+ x->link[x->nb_link-1].VX = vecteurX;
+ x->link[x->nb_link-1].VY = vecteurY;
+ }
+ }
+ }
+ }
+}
+
+void pmpd3d_tabLink(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+ 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_symbol *arrayK = atom_getsymbolarg(3,argc,argv);
+ t_float K = atom_getfloatarg(4, argc, argv);
+ t_symbol *arrayD = atom_getsymbolarg(5,argc,argv);
+ t_float D = atom_getfloatarg(6, argc, argv);
+
+ if ( ( argv[1].a_type == A_FLOAT ) & ( argv[2].a_type == A_FLOAT ) )
+ {
+ pmpd3d_create_link(x, Id, mass1, mass2, K, D, 1, 0, 1000000, 2);
+ x->link[x->nb_link-1].arrayK = arrayK;
+ x->link[x->nb_link-1].arrayD = arrayD;
+ }
+ 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)
+ {
+ pmpd3d_create_link(x, Id, i, mass2, K, D, 1, 0, 1000000, 2);
+ x->link[x->nb_link-1].arrayK = arrayK;
+ x->link[x->nb_link-1].arrayD = arrayD;
+ }
+ }
+ }
+ 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)
+ {
+ pmpd3d_create_link(x, Id, mass1, i, K, D, 1, 0, 1000000, 2);
+ x->link[x->nb_link-1].arrayK = arrayK;
+ x->link[x->nb_link-1].arrayD = arrayD;
+ }
+ }
+ }
+ 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))
+ {
+ pmpd3d_create_link(x, Id, i, j, K, D, 1, 0, 1000000, 2);
+ x->link[x->nb_link-1].arrayK = arrayK;
+ x->link[x->nb_link-1].arrayD = arrayD;
+ }
+ }
+ }
+ }
+
+}
+
+void pmpd3d_setK(t_pmpd3d *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 pmpd3d_setD(t_pmpd3d *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 pmpd3d_setL(t_pmpd3d *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].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);
+ }
+ }
+ }
+ if ( ( argv[0].a_type == A_FLOAT ) & ( argc == 1 ) )
+ {
+ tmp = atom_getfloatarg(0, argc, argv);
+ tmp = max(0, min( x->nb_link-1, tmp));
+ x->link[tmp].L = x->link[tmp].mass2->posX - x->link[tmp].mass1->posX;
+ }
+ if ( ( argv[0].a_type == A_SYMBOL ) & ( argc == 1 ) )
+ {
+ for (i=0; i< x->nb_link; i++)
+ {
+ if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+ {
+ x->link[i].L = x->link[i].mass2->posX - x->link[i].mass1->posX;
+ }
+ }
+ }
+}
+
+void pmpd3d_setLinkId(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int tmp, i;
+
+ if ( ( argv[0].a_type == A_FLOAT ) & ( argv[1].a_type == A_SYMBOL ) )
+ {
+ tmp = atom_getfloatarg(0, argc, argv);
+ tmp = max(0, min( x->nb_link-1, tmp));
+ x->link[tmp].Id = atom_getsymbolarg(1, argc, argv);
+ }
+ if ( ( argv[0].a_type == A_SYMBOL ) & ( argv[1].a_type == A_SYMBOL ) )
+ {
+ for (i=0; i< x->nb_link; i++)
+ {
+ if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+ {
+ x->link[i].Id = atom_getsymbolarg(1, argc, argv);
+ }
+ }
+ }
+}
+
+void pmpd3d_setMassId(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+// add a force to a specific mass
+ int tmp, i;
+
+ if ( ( argv[0].a_type == A_FLOAT ) & ( argv[1].a_type == A_SYMBOL ) )
+ {
+ tmp = atom_getfloatarg(0, argc, argv);
+ tmp = max(0, min( x->nb_mass-1, tmp));
+ x->mass[tmp].Id = atom_getsymbolarg(1, argc, argv);
+ }
+ if ( ( argv[0].a_type == A_SYMBOL ) & ( argv[1].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].Id = atom_getsymbolarg(1, argc, argv);
+ }
+ }
+ }
+}
+
+void pmpd3d_forceX(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+// add a force to a specific mass
+ 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 pmpd3d_forceY(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+// add a force to a specific mass
+ 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].forceY += 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].forceY += atom_getfloatarg(1, argc, argv);
+ }
+ }
+ }
+}
+
+void pmpd3d_forceZ(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+// add a force to a specific mass
+ 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].forceZ += 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].forceZ += atom_getfloatarg(1, argc, argv);
+ }
+ }
+ }
+}
+
+void pmpd3d_force(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+// add a force to a specific mass
+ int tmp, i;
+
+ if ( ( argv[0].a_type == A_FLOAT ) & ( argv[1].a_type == A_FLOAT ) & ( argv[2].a_type == A_FLOAT ) & ( argv[3].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);
+ x->mass[tmp].forceY += atom_getfloatarg(2, argc, argv);
+ x->mass[tmp].forceZ += atom_getfloatarg(3, argc, argv);
+ }
+ if ( ( argv[0].a_type == A_SYMBOL ) & ( argv[1].a_type == A_FLOAT ) & ( argv[2].a_type == A_FLOAT ) & ( argv[3].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);
+ x->mass[i].forceY += atom_getfloatarg(2, argc, argv);
+ x->mass[i].forceZ += atom_getfloatarg(3, argc, argv);
+ }
+ }
+ }
+}
+
+void pmpd3d_posX(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+// displace a mass to a certain position
+ 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;
+ x->mass[tmp].forceX = 0;
+
+ }
+ 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;
+ x->mass[i].forceX = 0;
+
+ }
+ }
+ }
+}
+
+void pmpd3d_posY(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+// displace a mass to a certain position
+ 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].posY = atom_getfloatarg(1, argc, argv);
+ x->mass[tmp].speedY = 0;
+ x->mass[tmp].forceY = 0;
+
+ }
+ 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].posY = atom_getfloatarg(1, argc, argv);
+ x->mass[i].speedY = 0;
+ x->mass[i].forceY = 0;
+ }
+ }
+ }
+}
+
+void pmpd3d_posZ(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+// displace a mass to a certain position
+ 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].posZ = atom_getfloatarg(1, argc, argv);
+ x->mass[tmp].speedZ = 0;
+ x->mass[tmp].forceZ = 0;
+
+ }
+ 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].posZ = atom_getfloatarg(1, argc, argv);
+ x->mass[i].speedZ = 0;
+ x->mass[i].forceZ = 0;
+ }
+ }
+ }
+}
+
+void pmpd3d_pos(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+// displace a mass to a certain position
+ int tmp, i;
+
+ if ( ( argv[0].a_type == A_FLOAT ) & ( argv[1].a_type == A_FLOAT ) & ( argv[2].a_type == A_FLOAT ) & ( argv[3].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;
+ x->mass[tmp].forceX = 0;
+ x->mass[tmp].posY = atom_getfloatarg(2, argc, argv);
+ x->mass[tmp].speedY = 0;
+ x->mass[tmp].forceY = 0;
+ x->mass[tmp].posZ = atom_getfloatarg(3, argc, argv);
+ x->mass[tmp].speedZ = 0;
+ x->mass[tmp].forceZ = 0;
+ }
+ if ( ( argv[0].a_type == A_SYMBOL ) & ( argv[1].a_type == A_FLOAT ) & ( argv[2].a_type == A_FLOAT ) & ( argv[3].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;
+ x->mass[i].forceX = 0;
+ x->mass[i].posY = atom_getfloatarg(2, argc, argv);
+ x->mass[i].speedY = 0;
+ x->mass[i].forceY = 0;
+ x->mass[i].posZ = atom_getfloatarg(3, argc, argv);
+ x->mass[i].speedZ = 0;
+ x->mass[i].forceZ = 0;
+ }
+ }
+ }
+}
+
+void pmpd3d_minX(t_pmpd3d *x, t_float min)
+{
+ x->minX = min;
+}
+
+void pmpd3d_maxX(t_pmpd3d *x, t_float max)
+{
+ x->maxX = max;
+}
+
+void pmpd3d_minY(t_pmpd3d *x, t_float min)
+{
+ x->minY = min;
+}
+
+void pmpd3d_maxY(t_pmpd3d *x, t_float max)
+{
+ x->maxY = max;
+}
+
+void pmpd3d_minZ(t_pmpd3d *x, t_float min)
+{
+ x->minZ = min;
+}
+
+void pmpd3d_maxZ(t_pmpd3d *x, t_float max)
+{
+ x->maxZ = max;
+}
+
+void pmpd3d_setFixed(t_pmpd3d *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 pmpd3d_setMobile(t_pmpd3d *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 = 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;
+ }
+ }
+ }
+}
+
+void pmpd3d_setD2(t_pmpd3d *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_mass-1, tmp));
+ x->mass[tmp].D2 = 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].D2 = atom_getfloatarg(1, argc, argv);
+ }
+ }
+ }
+}
+
+void pmpd3d_setSpeedX(t_pmpd3d *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_mass-1, tmp));
+ x->mass[tmp].speedX = 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].speedX = atom_getfloatarg(1, argc, argv);
+ }
+ }
+ }
+}
+
+void pmpd3d_setSpeedY(t_pmpd3d *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_mass-1, tmp));
+ x->mass[tmp].speedY = 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].speedY = atom_getfloatarg(1, argc, argv);
+ }
+ }
+ }
+}
+
+void pmpd3d_setSpeedZ(t_pmpd3d *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_mass-1, tmp));
+ x->mass[tmp].speedZ = 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].speedZ = atom_getfloatarg(1, argc, argv);
+ }
+ }
+ }
+}
+
+void pmpd3d_setSpeed(t_pmpd3d *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 ) & ( argv[2].a_type == A_FLOAT ) & ( argv[3].a_type == A_FLOAT ) )
+ {
+ tmp = atom_getfloatarg(0, argc, argv);
+ tmp = max(0, min( x->nb_mass-1, tmp));
+ x->mass[tmp].speedX = atom_getfloatarg(1, argc, argv);
+ x->mass[tmp].speedY = atom_getfloatarg(2, argc, argv);
+ x->mass[tmp].speedZ = atom_getfloatarg(3, argc, argv);
+ }
+ if ( ( argv[0].a_type == A_SYMBOL ) & ( argv[1].a_type == A_FLOAT ) & ( argv[2].a_type == A_FLOAT ) & ( argv[3].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].speedX = atom_getfloatarg(1, argc, argv);
+ x->mass[i].speedY = atom_getfloatarg(2, argc, argv);
+ x->mass[i].speedZ = atom_getfloatarg(3, argc, argv);
+ }
+ }
+ }
+}
+
+
+void pmpd3d_addPosX(t_pmpd3d *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_mass-1, tmp));
+ x->mass[tmp].posX += 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].posX += atom_getfloatarg(1, argc, argv);
+ }
+ }
+ }
+}
+
+void pmpd3d_addPosY(t_pmpd3d *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_mass-1, tmp));
+ x->mass[tmp].posY += 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].posY += atom_getfloatarg(1, argc, argv);
+ }
+ }
+ }
+}
+
+void pmpd3d_addPosZ(t_pmpd3d *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_mass-1, tmp));
+ x->mass[tmp].posZ += 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].posZ += atom_getfloatarg(1, argc, argv);
+ }
+ }
+ }
+}
+
+void pmpd3d_addPos(t_pmpd3d *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 ) & ( argv[2].a_type == A_FLOAT ) & ( argv[3].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].posY += atom_getfloatarg(2, argc, argv);
+ x->mass[tmp].posZ += atom_getfloatarg(3, argc, argv);
+ }
+ if ( ( argv[0].a_type == A_SYMBOL ) & ( argv[1].a_type == A_FLOAT ) & ( argv[2].a_type == A_FLOAT ) & ( argv[3].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].posY += atom_getfloatarg(2, argc, argv);
+ x->mass[i].posZ += atom_getfloatarg(3, argc, argv);
+ }
+ }
+ }
+}
+
+void pmpd3d_setForceX(t_pmpd3d *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_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 pmpd3d_setForceY(t_pmpd3d *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_mass-1, tmp));
+ x->mass[tmp].forceY = 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].forceY = atom_getfloatarg(1, argc, argv);
+ }
+ }
+ }
+}
+
+void pmpd3d_setForceZ(t_pmpd3d *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_mass-1, tmp));
+ x->mass[tmp].forceZ = 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].forceZ = atom_getfloatarg(1, argc, argv);
+ }
+ }
+ }
+}
+
+void pmpd3d_setForce(t_pmpd3d *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 ) & ( argv[2].a_type == A_FLOAT ) & ( argv[3].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);
+ x->mass[tmp].forceY = atom_getfloatarg(2, argc, argv);
+ x->mass[tmp].forceZ = atom_getfloatarg(3, argc, argv);
+ }
+ if ( ( argv[0].a_type == A_SYMBOL ) & ( argv[1].a_type == A_FLOAT ) & ( argv[2].a_type == A_FLOAT ) & ( argv[3].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);
+ x->mass[i].forceY = atom_getfloatarg(2, argc, argv);
+ x->mass[i].forceZ = atom_getfloatarg(3, argc, argv);
+ }
+ }
+ }
+}
+
+void pmpd3d_get(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int i;
+ t_symbol *toget;
+ t_atom toout[4];
+ toget = atom_getsymbolarg(0, argc, argv);
+
+ if ( (toget == gensym("massesPos")) & (argv[1].a_type == A_FLOAT) )
+ {
+ i = atom_getfloatarg(1, argc, argv);
+ if ( (i>=0) & (i<x->nb_mass) )
+ {
+ SETFLOAT(&(toout[0]), i);
+ SETFLOAT(&(toout[1]), x->mass[i].posX);
+ SETFLOAT(&(toout[2]), x->mass[i].posY);
+ SETFLOAT(&(toout[3]), x->mass[i].posZ);
+ outlet_anything(x->main_outlet, gensym("massesPosNo"), 4, 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);
+ SETFLOAT(&(toout[2]), x->mass[i].posY);
+ SETFLOAT(&(toout[3]), x->mass[i].posZ);
+ outlet_anything(x->main_outlet, gensym("massesPosId"), 4, 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);
+ SETFLOAT(&(toout[2]), x->mass[i].posY);
+ SETFLOAT(&(toout[3]), x->mass[i].posZ);
+ outlet_anything(x->main_outlet, gensym("massesPos"), 4, toout);
+ }
+ }
+ else
+ if ( (toget == gensym("massesPosName")) & (argv[1].a_type == A_FLOAT) )
+ {
+ i = atom_getfloatarg(1, argc, argv);
+ if ( (i>=0) & (i<x->nb_mass) )
+ {
+ SETSYMBOL(&(toout[0]), x->mass[i].Id);
+ SETFLOAT(&(toout[1]), x->mass[i].posX);
+ SETFLOAT(&(toout[2]), x->mass[i].posY);
+ SETFLOAT(&(toout[3]), x->mass[i].posZ);
+ outlet_anything(x->main_outlet, gensym("massesPosNameNo"), 4, 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);
+ SETFLOAT(&(toout[2]), x->mass[i].posY);
+ SETFLOAT(&(toout[3]), x->mass[i].posZ);
+ outlet_anything(x->main_outlet, gensym("massesPosNameId"), 4, 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);
+ SETFLOAT(&(toout[2]), x->mass[i].posY);
+ SETFLOAT(&(toout[3]), x->mass[i].posZ);
+ outlet_anything(x->main_outlet, gensym("massesPosName"), 4, toout);
+ }
+ }
+ else
+ if ( (toget == gensym("massesSpeeds")) & (argv[1].a_type == A_FLOAT) )
+ {
+ i = atom_getfloatarg(1, argc, argv);
+ if ( (i>=0) & (i<x->nb_mass) )
+ {
+ SETFLOAT(&(toout[0]), i);
+ SETFLOAT(&(toout[1]), x->mass[i].speedX);
+ SETFLOAT(&(toout[2]), x->mass[i].speedY);
+ SETFLOAT(&(toout[3]), x->mass[i].speedZ);
+ outlet_anything(x->main_outlet, gensym("massesSpeedsNo"), 4, 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);
+ SETFLOAT(&(toout[2]), x->mass[i].speedY);
+ SETFLOAT(&(toout[3]), x->mass[i].speedZ);
+ outlet_anything(x->main_outlet, gensym("massesSpeedsId"), 4, 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);
+ SETFLOAT(&(toout[2]), x->mass[i].speedY);
+ SETFLOAT(&(toout[3]), x->mass[i].speedZ);
+ outlet_anything(x->main_outlet, gensym("massesSpeeds"), 4, toout);
+ }
+ }
+ else
+ if ( (toget == gensym("massesSpeedsName")) & (argv[1].a_type == A_FLOAT) )
+ {
+ i = atom_getfloatarg(1, argc, argv);
+ if ( (i>=0) & (i<x->nb_mass) )
+ {
+ SETSYMBOL(&(toout[0]), x->mass[i].Id);
+ SETFLOAT(&(toout[1]), x->mass[i].speedX);
+ SETFLOAT(&(toout[2]), x->mass[i].speedY);
+ SETFLOAT(&(toout[3]), x->mass[i].speedZ);
+ outlet_anything(x->main_outlet, gensym("massesSpeedsNameNo"), 4, 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);
+ SETFLOAT(&(toout[2]), x->mass[i].speedY);
+ SETFLOAT(&(toout[3]), x->mass[i].speedZ);
+ outlet_anything(x->main_outlet, gensym("massesSpeedsNameId"), 4, 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);
+ SETFLOAT(&(toout[2]), x->mass[i].speedY);
+ SETFLOAT(&(toout[3]), x->mass[i].speedZ);
+ outlet_anything(x->main_outlet, gensym("massesSpeedsName"), 4, toout);
+ }
+ }
+ else
+ if ( (toget == gensym("massesForces")) & (argv[1].a_type == A_FLOAT) )
+ {
+ i = atom_getfloatarg(1, argc, argv);
+ if ( (i>=0) & (i<x->nb_mass) )
+ {
+ SETFLOAT(&(toout[0]), i);
+ SETFLOAT(&(toout[1]), x->mass[i].forceX);
+ SETFLOAT(&(toout[2]), x->mass[i].forceY);
+ SETFLOAT(&(toout[3]), x->mass[i].forceZ);
+ outlet_anything(x->main_outlet, gensym("massesForcesNo"), 4, 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);
+ SETFLOAT(&(toout[2]), x->mass[i].forceY);
+ SETFLOAT(&(toout[3]), x->mass[i].forceZ);
+ outlet_anything(x->main_outlet, gensym("massesForcesId"), 4, 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);
+ SETFLOAT(&(toout[2]), x->mass[i].forceY);
+ SETFLOAT(&(toout[3]), x->mass[i].forceZ);
+ outlet_anything(x->main_outlet, gensym("massesForces"), 4, toout);
+ }
+ }
+ else
+ if ( (toget == gensym("massesForcesName")) & (argv[1].a_type == A_FLOAT) )
+ {
+ i = atom_getfloatarg(1, argc, argv);
+ if ( (i>=0) & (i<x->nb_mass) )
+ {
+ SETSYMBOL(&(toout[0]), x->mass[i].Id);
+ SETFLOAT(&(toout[1]), x->mass[i].forceX);
+ SETFLOAT(&(toout[2]), x->mass[i].forceY);
+ SETFLOAT(&(toout[3]), x->mass[i].forceZ);
+ outlet_anything(x->main_outlet, gensym("massesForcesNameNo"), 4, 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);
+ SETFLOAT(&(toout[2]), x->mass[i].forceY);
+ SETFLOAT(&(toout[3]), x->mass[i].forceZ);
+ outlet_anything(x->main_outlet, gensym("massesForcesNameId"), 4, 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);
+ SETFLOAT(&(toout[2]), x->mass[i].forceY);
+ SETFLOAT(&(toout[3]), x->mass[i].forceZ);
+ outlet_anything(x->main_outlet, gensym("massesForcesName"), 4, toout);
+ }
+ }
+ else
+ if ( (toget == gensym("linksPos")) & (argv[1].a_type == A_FLOAT) )
+ {
+ i = atom_getfloatarg(1, argc, argv);
+ if ( (i>=0) & (i<x->nb_mass) )
+ {
+ SETFLOAT(&(toout[0]), i);
+ SETFLOAT(&(toout[1]), x->link[i].mass1->posX);
+ SETFLOAT(&(toout[2]), x->link[i].mass1->posY);
+ SETFLOAT(&(toout[3]), x->link[i].mass1->posZ);
+ SETFLOAT(&(toout[4]), x->link[i].mass2->posX);
+ SETFLOAT(&(toout[5]), x->link[i].mass2->posY);
+ SETFLOAT(&(toout[6]), x->link[i].mass2->posZ);
+ outlet_anything(x->main_outlet, gensym("linksPosNo"), 7, 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].mass1->posY);
+ SETFLOAT(&(toout[3]), x->link[i].mass1->posZ);
+ SETFLOAT(&(toout[4]), x->link[i].mass2->posX);
+ SETFLOAT(&(toout[5]), x->link[i].mass2->posY);
+ SETFLOAT(&(toout[6]), x->link[i].mass2->posZ);
+ outlet_anything(x->main_outlet, gensym("linksPosNo"), 7, 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].mass1->posY);
+ SETFLOAT(&(toout[3]), x->link[i].mass1->posZ);
+ SETFLOAT(&(toout[4]), x->link[i].mass2->posX);
+ SETFLOAT(&(toout[5]), x->link[i].mass2->posY);
+ SETFLOAT(&(toout[6]), x->link[i].mass2->posZ);
+ outlet_anything(x->main_outlet, gensym("linksPosNo"), 7, toout);
+ }
+ }
+ else
+ if ( (toget == gensym("linksPosName")) & (argv[1].a_type == A_FLOAT) )
+ {
+ i = atom_getfloatarg(1, argc, argv);
+ if ( (i>=0) & (i<x->nb_mass) )
+ {
+ SETFLOAT(&(toout[0]), i);
+ SETFLOAT(&(toout[1]), x->link[i].mass1->posX);
+ SETFLOAT(&(toout[2]), x->link[i].mass1->posY);
+ SETFLOAT(&(toout[3]), x->link[i].mass1->posZ);
+ SETFLOAT(&(toout[3]), x->link[i].mass2->posX);
+ SETFLOAT(&(toout[5]), x->link[i].mass2->posY);
+ SETFLOAT(&(toout[6]), x->link[i].mass2->posZ);
+ outlet_anything(x->main_outlet, gensym("linksPosNo"), 7, 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)
+ {
+ SETFLOAT(&(toout[0]), i);
+ SETFLOAT(&(toout[1]), x->link[i].mass1->posX);
+ SETFLOAT(&(toout[2]), x->link[i].mass1->posY);
+ SETFLOAT(&(toout[3]), x->link[i].mass1->posZ);
+ SETFLOAT(&(toout[4]), x->link[i].mass2->posX);
+ SETFLOAT(&(toout[5]), x->link[i].mass2->posY);
+ SETFLOAT(&(toout[6]), x->link[i].mass2->posZ);
+ outlet_anything(x->main_outlet, gensym("linksPosNo"), 7, toout);
+ }
+ }
+ }
+ else
+ if ( (toget == gensym("linksPosName")) & (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].mass1->posY);
+ SETFLOAT(&(toout[3]), x->link[i].mass1->posZ);
+ SETFLOAT(&(toout[4]), x->link[i].mass2->posX);
+ SETFLOAT(&(toout[5]), x->link[i].mass2->posY);
+ SETFLOAT(&(toout[6]), x->link[i].mass2->posZ);
+ outlet_anything(x->main_outlet, gensym("linksPosNo"), 7, toout);
+ }
+ }
+ else
+ error("not get attribute");
+}
+
+void pmpd3d_massesPosXL(t_pmpd3d *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("massesPosXL"),x->nb_mass , pos_list);
+}
+
+void pmpd3d_massesForcesXL(t_pmpd3d *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("massesForcesXL"),x->nb_mass , pos_list);
+}
+
+void pmpd3d_massesSpeedsXL(t_pmpd3d *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].speedX);
+ }
+ outlet_anything(x->main_outlet, gensym("massesSpeedsXL"),x->nb_mass , pos_list);
+}
+
+void pmpd3d_massesPosXT(t_pmpd3d *x, t_symbol *tab_name)
+{
+ int i, vecsize;
+ t_garray *a;
+ t_word *vec;
+
+ if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+ pd_error(x, "%s: no such array", tab_name->s_name);
+ else if (!garray_getfloatwords(a, &vecsize, &vec))
+ pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+ else
+ {
+ int taille_max = x->nb_mass;
+ taille_max = min(taille_max, vecsize);
+ for (i=0; i < taille_max ; i++)
+ {
+ vec[i].w_float = x->mass[i].posX;
+ }
+ garray_redraw(a);
+ }
+}
+
+void pmpd3d_massesSpeedsXT(t_pmpd3d *x, t_symbol *tab_name)
+{
+ int i, vecsize;
+ t_garray *a;
+ t_word *vec;
+
+ if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+ pd_error(x, "%s: no such array", tab_name->s_name);
+ else if (!garray_getfloatwords(a, &vecsize, &vec))
+ pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+ else
+ {
+ int taille_max = x->nb_mass;
+ taille_max = min(taille_max, vecsize);
+ for (i=0; i < taille_max ; i++)
+ {
+ vec[i].w_float = x->mass[i].speedX;
+ }
+ garray_redraw(a);
+ }
+}
+
+void pmpd3d_massesForcesXT(t_pmpd3d *x, t_symbol *tab_name)
+{
+ int i, vecsize;
+ t_garray *a;
+ t_word *vec;
+
+ if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+ pd_error(x, "%s: no such array", tab_name->s_name);
+ else if (!garray_getfloatwords(a, &vecsize, &vec))
+ pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+ else
+ {
+ int taille_max = x->nb_mass;
+ taille_max = min(taille_max, vecsize);
+ for (i=0; i < taille_max ; i++)
+ {
+ vec[i].w_float = x->mass[i].forceX;
+ }
+ garray_redraw(a);
+ }
+}
+
+void pmpd3d_massesPosYL(t_pmpd3d *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].posY);
+ }
+ outlet_anything(x->main_outlet, gensym("massesPosYL"),x->nb_mass , pos_list);
+}
+
+void pmpd3d_massesForcesYL(t_pmpd3d *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].forceY);
+ }
+ outlet_anything(x->main_outlet, gensym("massesForcesYL"),x->nb_mass , pos_list);
+}
+
+void pmpd3d_massesSpeedsYL(t_pmpd3d *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].speedY);
+ }
+ outlet_anything(x->main_outlet, gensym("massesSpeedsYL"),x->nb_mass , pos_list);
+}
+
+void pmpd3d_massesPosYT(t_pmpd3d *x, t_symbol *tab_name)
+{
+ int i, vecsize;
+ t_garray *a;
+ t_word *vec;
+
+ if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+ pd_error(x, "%s: no such array", tab_name->s_name);
+ else if (!garray_getfloatwords(a, &vecsize, &vec))
+ pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+ else
+ {
+ int taille_max = x->nb_mass;
+ taille_max = min(taille_max, vecsize);
+ for (i=0; i < taille_max ; i++)
+ {
+ vec[i].w_float = x->mass[i].posY;
+ }
+ garray_redraw(a);
+ }
+}
+
+void pmpd3d_massesSpeedsYT(t_pmpd3d *x, t_symbol *tab_name)
+{
+ int i, vecsize;
+ t_garray *a;
+ t_word *vec;
+
+ if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+ pd_error(x, "%s: no such array", tab_name->s_name);
+ else if (!garray_getfloatwords(a, &vecsize, &vec))
+ pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+ else
+ {
+ int taille_max = x->nb_mass;
+ taille_max = min(taille_max, vecsize);
+ for (i=0; i < taille_max ; i++)
+ {
+ vec[i].w_float = x->mass[i].speedY;
+ }
+ garray_redraw(a);
+ }
+}
+
+void pmpd3d_massesForcesYT(t_pmpd3d *x, t_symbol *tab_name)
+{
+ int i, vecsize;
+ t_garray *a;
+ t_word *vec;
+
+ if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+ pd_error(x, "%s: no such array", tab_name->s_name);
+ else if (!garray_getfloatwords(a, &vecsize, &vec))
+ pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+ else
+ {
+ int taille_max = x->nb_mass;
+ taille_max = min(taille_max, vecsize);
+ for (i=0; i < taille_max ; i++)
+ {
+ vec[i].w_float = x->mass[i].forceY;
+ }
+ garray_redraw(a);
+ }
+}
+
+void pmpd3d_massesPosZL(t_pmpd3d *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].posZ);
+ }
+ outlet_anything(x->main_outlet, gensym("massesPosZL"),x->nb_mass , pos_list);
+}
+
+void pmpd3d_massesForcesZL(t_pmpd3d *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].forceZ);
+ }
+ outlet_anything(x->main_outlet, gensym("massesForcesZL"),x->nb_mass , pos_list);
+}
+
+void pmpd3d_massesSpeedsZL(t_pmpd3d *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].speedZ);
+ }
+ outlet_anything(x->main_outlet, gensym("massesSpeedsZL"),x->nb_mass , pos_list);
+}
+
+void pmpd3d_massesPosZT(t_pmpd3d *x, t_symbol *tab_name)
+{
+ int i, vecsize;
+ t_garray *a;
+ t_word *vec;
+
+ if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+ pd_error(x, "%s: no such array", tab_name->s_name);
+ else if (!garray_getfloatwords(a, &vecsize, &vec))
+ pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+ else
+ {
+ int taille_max = x->nb_mass;
+ taille_max = min(taille_max, vecsize);
+ for (i=0; i < taille_max ; i++)
+ {
+ vec[i].w_float = x->mass[i].posZ;
+ }
+ garray_redraw(a);
+ }
+}
+
+void pmpd3d_massesSpeedsZT(t_pmpd3d *x, t_symbol *tab_name)
+{
+ int i, vecsize;
+ t_garray *a;
+ t_word *vec;
+
+ if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+ pd_error(x, "%s: no such array", tab_name->s_name);
+ else if (!garray_getfloatwords(a, &vecsize, &vec))
+ pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+ else
+ {
+ int taille_max = x->nb_mass;
+ taille_max = min(taille_max, vecsize);
+ for (i=0; i < taille_max ; i++)
+ {
+ vec[i].w_float = x->mass[i].speedZ;
+ }
+ garray_redraw(a);
+ }
+}
+
+void pmpd3d_massesForcesZT(t_pmpd3d *x, t_symbol *tab_name)
+{
+ int i, vecsize;
+ t_garray *a;
+ t_word *vec;
+
+ if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+ pd_error(x, "%s: no such array", tab_name->s_name);
+ else if (!garray_getfloatwords(a, &vecsize, &vec))
+ pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+ else
+ {
+ int taille_max = x->nb_mass;
+ taille_max = min(taille_max, vecsize);
+ for (i=0; i < taille_max ; i++)
+ {
+ vec[i].w_float = x->mass[i].forceZ;
+ }
+ garray_redraw(a);
+ }
+}
+
+void pmpd3d_massesPosL(t_pmpd3d *x)
+{
+ int i;
+ t_atom pos_list[3*nb_max_link];
+
+ for (i=0; i < x->nb_mass; i++)
+ {
+ SETFLOAT(&(pos_list[2*i] ),x->mass[i].posX);
+ SETFLOAT(&(pos_list[2*i+1]),x->mass[i].posY);
+ SETFLOAT(&(pos_list[2*i+2]),x->mass[i].posZ);
+ }
+ outlet_anything(x->main_outlet, gensym("massesPosL"),3*x->nb_mass , pos_list);
+}
+
+void pmpd3d_massesForcesL(t_pmpd3d *x)
+{
+ int i;
+ t_atom pos_list[3*nb_max_link];
+
+ for (i=0; i< x->nb_mass; i++)
+ {
+ SETFLOAT(&(pos_list[2*i] ),x->mass[i].forceX);
+ SETFLOAT(&(pos_list[2*i+1]),x->mass[i].forceY);
+ SETFLOAT(&(pos_list[2*i+2]),x->mass[i].forceZ);
+ }
+ outlet_anything(x->main_outlet, gensym("massesForcesL"),3*x->nb_mass , pos_list);
+}
+
+void pmpd3d_massesSpeedsL(t_pmpd3d *x)
+{
+ int i;
+ t_atom pos_list[3*nb_max_link];
+
+ for (i=0; i< x->nb_mass; i++)
+ {
+ SETFLOAT(&(pos_list[2*i] ),x->mass[i].speedX);
+ SETFLOAT(&(pos_list[2*i+1]),x->mass[i].speedY);
+ SETFLOAT(&(pos_list[2*i+2]),x->mass[i].speedZ);
+ }
+ outlet_anything(x->main_outlet, gensym("massesSpeedsL"),3*x->nb_mass , pos_list);
+}
+
+void pmpd3d_massesPosT(t_pmpd3d *x, t_symbol *tab_name)
+{
+ int i, vecsize;
+ t_garray *a;
+ t_word *vec;
+
+ if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+ pd_error(x, "%s: no such array", tab_name->s_name);
+ else if (!garray_getfloatwords(a, &vecsize, &vec))
+ pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+ else
+ {
+ int taille_max = x->nb_mass;
+ taille_max = min(taille_max, vecsize/3);
+ for (i=0; i < taille_max ; i++)
+ {
+ vec[2*i ].w_float = x->mass[i].posX;
+ vec[2*i+1].w_float = x->mass[i].posY;
+ vec[2*i+2].w_float = x->mass[i].posZ;
+ }
+ garray_redraw(a);
+ }
+}
+
+void pmpd3d_massesSpeedsT(t_pmpd3d *x, t_symbol *tab_name)
+{
+ int i, vecsize;
+ t_garray *a;
+ t_word *vec;
+
+ if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+ pd_error(x, "%s: no such array", tab_name->s_name);
+ else if (!garray_getfloatwords(a, &vecsize, &vec))
+ pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+ else
+ {
+ int taille_max = x->nb_mass;
+ taille_max = min(taille_max, vecsize/3);
+ for (i=0; i < taille_max ; i++)
+ {
+ vec[2*i ].w_float = x->mass[i].speedX;
+ vec[2*i+1].w_float = x->mass[i].speedY;
+ vec[2*i+2].w_float = x->mass[i].speedZ;
+ }
+ garray_redraw(a);
+ }
+}
+
+void pmpd3d_massesForcesT(t_pmpd3d *x, t_symbol *tab_name)
+{
+ int i, vecsize;
+ t_garray *a;
+ t_word *vec;
+
+ if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+ pd_error(x, "%s: no such array", tab_name->s_name);
+ else if (!garray_getfloatwords(a, &vecsize, &vec))
+ pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+ else
+ {
+ int taille_max = x->nb_mass;
+ taille_max = min(taille_max, vecsize/3);
+ for (i=0; i < taille_max ; i++)
+ {
+ vec[2*i ].w_float = x->mass[i].forceX;
+ vec[2*i+1].w_float = x->mass[i].forceY;
+ vec[2*i+1].w_float = x->mass[i].forceZ;
+ }
+ garray_redraw(a);
+ }
+}
+
+void pmpd3d_massesPosMean(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+ t_float sommeX, sommeY, sommeZ, somme;
+ t_int i,j;
+ t_atom mean[4];
+
+ sommeX = 0;
+ sommeY = 0;
+ sommeZ = 0;
+ somme = 0;
+ j = 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)
+ {
+ sommeX += x->mass[i].posX;
+ sommeY += x->mass[i].posY;
+ sommeZ += x->mass[i].posZ;
+ somme += sqrt(sqr(x->mass[i].posX) + sqr(x->mass[i].posY) + sqr(x->mass[i].posZ)); // distance au centre
+ j++;
+ }
+ }
+ }
+ else
+ {
+ for (i=0; i< x->nb_mass; i++)
+ {
+ sommeX += x->mass[i].posX;
+ sommeY += x->mass[i].posY;
+ somme += sqrt(sqr(x->mass[i].posX) + sqr(x->mass[i].posY) + sqr(x->mass[i].posZ)); // distance au centre
+ j++;
+ }
+ }
+
+ sommeX /= j;
+ sommeY /= j;
+ sommeZ /= j;
+ somme /= j;
+
+ SETFLOAT(&(mean[0]),sommeX);
+ SETFLOAT(&(mean[1]),sommeY);
+ SETFLOAT(&(mean[2]),sommeZ);
+ SETFLOAT(&(mean[3]),somme);
+
+ outlet_anything(x->main_outlet, gensym("massesPosMean"),4 , mean);
+}
+
+void pmpd3d_massesPosStd(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+ t_float sommeX, sommeY, sommeZ, somme;
+ t_int i,j;
+ t_float stdX, stdY, stdZ, std;
+ t_atom std_out[4];
+
+ sommeX = 0;
+ sommeY = 0;
+ sommeZ = 0;
+ somme = 0;
+ stdX = 0;
+ stdY = 0;
+ stdZ = 0;
+ std = 0;
+ j = 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)
+ {
+ sommeX += x->mass[i].posX;
+ sommeY += x->mass[i].posY;
+ sommeZ += x->mass[i].posZ;
+ somme += sqrt(sqr(x->mass[i].posX) + sqr(x->mass[i].posY) + sqr(x->mass[i].posZ)); // distance au centre
+ j++;
+ }
+ }
+ sommeX /= j;
+ sommeY /= j;
+ sommeZ /= j;
+ somme /= j;
+ for (i=0; i< x->nb_mass; i++)
+ {
+ if (atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+ {
+ stdX += sqr(x->mass[i].posX-sommeX);
+ stdY += sqr(x->mass[i].posY-sommeY);
+ stdZ += sqr(x->mass[i].posZ-sommeZ);
+ std += sqr(sqrt(sqr(x->mass[i].posX) + sqr(x->mass[i].posY) + sqr(x->mass[i].posZ))-somme);
+ }
+ }
+ }
+ else
+ {
+ for (i=0; i< x->nb_mass; i++)
+ {
+ sommeX += x->mass[i].posX;
+ sommeY += x->mass[i].posY;
+ sommeZ += x->mass[i].posZ;
+ somme += sqrt(sqr(x->mass[i].posX) + sqr(x->mass[i].posY) + sqr(x->mass[i].posZ)); // distance au centre
+ j++;
+ }
+ sommeX /= j;
+ sommeY /= j;
+ sommeZ /= j;
+ somme /= j;
+ for (i=0; i< x->nb_mass; i++)
+ {
+ stdX += sqr(x->mass[i].posX-sommeX);
+ stdY += sqr(x->mass[i].posY-sommeY);
+ stdZ += sqr(x->mass[i].posZ-sommeZ);
+ std += sqr(sqrt(sqr(x->mass[i].posX) + sqr(x->mass[i].posY) + sqr(x->mass[i].posZ))-somme);
+ }
+ }
+
+ stdX = sqrt(stdX/j);
+ stdY = sqrt(stdY/j);
+ stdZ = sqrt(stdZ/j);
+ std = sqrt(std /j);
+
+ SETFLOAT(&(std_out[0]),stdX);
+ SETFLOAT(&(std_out[1]),stdY);
+ SETFLOAT(&(std_out[2]),stdZ);
+ SETFLOAT(&(std_out[3]),std);
+
+ outlet_anything(x->main_outlet, gensym("massesPosStd"),4 , std_out);
+}
+
+void pmpd3d_grabMass(t_pmpd3d *x, t_float posX, t_float posY, t_float posZ, t_float grab)
+{
+ t_float dist, tmp;
+ t_int i;
+
+ if (grab == 0)
+ x->grab=0;
+ if ((x->grab == 0)&(grab == 1)&(x->nb_mass > 0))
+ {
+ x->grab=1;
+ x->grab_nb= 0;
+ dist = sqr(x->mass[0].posX - posX) + sqr(x->mass[0].posY - posY) + sqr(x->mass[0].posZ - posZ);
+ for (i=1; i<x->nb_mass; i++)
+ {
+ tmp = sqr(x->mass[i].posX - posX) + sqr(x->mass[i].posY - posY) + sqr(x->mass[i].posZ - posZ);
+ if (tmp < dist)
+ {
+ dist = tmp;
+ x->grab_nb= i;
+ }
+ }
+ }
+ if (x->grab == 1)
+ {
+ x->mass[x->grab_nb].posX = posX;
+ x->mass[x->grab_nb].posY = posY;
+ x->mass[x->grab_nb].posZ = posZ;
+ }
+}
+
+void *pmpd3d_new()
+{
+ t_pmpd3d *x = (t_pmpd3d *)pd_new(pmpd3d_class);
+
+ pmpd3d_reset(x);
+
+ x->main_outlet=outlet_new(&x->x_obj, 0);
+ // x->info_outlet=outlet_new(&x->x_obj, 0); // TODO
+
+ return (void *)x;
+}
+
+void pmpd3d_setup(void)
+{
+ pmpd3d_class = class_new(gensym("pmpd3d"),
+ (t_newmethod)pmpd3d_new,
+ 0, sizeof(t_pmpd3d),CLASS_DEFAULT, 0);
+
+ class_addbang(pmpd3d_class, pmpd3d_bang);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_reset, gensym("reset"), 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_infosL, gensym("infosL"), 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_mass, gensym("mass"), A_DEFSYMBOL, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_link, gensym("link"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_tabLink, gensym("tabLink"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_tLink, gensym("tLink"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_setK, gensym("setK"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_setD, gensym("setD"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_setL, gensym("setL"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_setLinkId, gensym("setLinkId"), A_GIMME, 0);
+
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_setMassId, gensym("setMassId"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_pos, gensym("pos"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_posX, gensym("posX"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_posY, gensym("posY"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_posZ, gensym("posZ"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_force, gensym("force"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_forceX, gensym("forceX"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_forceY, gensym("forceY"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_forceZ, gensym("forceZ"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_minX, gensym("Xmin"), A_DEFFLOAT, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_maxX, gensym("Xmax"), A_DEFFLOAT, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_minY, gensym("Ymin"), A_DEFFLOAT, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_maxY, gensym("Ymax"), A_DEFFLOAT, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_minZ, gensym("Zmin"), A_DEFFLOAT, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_maxZ, gensym("Zmax"), A_DEFFLOAT, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_setFixed, gensym("setFixed"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_setMobile, gensym("setMobile"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_setD2, gensym("setD2"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_setSpeed, gensym("setSpeed"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_setSpeedX, gensym("setSpeedX"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_setSpeedY, gensym("setSpeedY"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_setSpeedZ, gensym("setSpeedZ"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_setForce, gensym("setForce"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_setForceX, gensym("setForceX"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_setForceY, gensym("setForceY"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_setForceZ, gensym("setForceZ"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_addPos, gensym("addPos"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_addPosX, gensym("addPosX"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_addPosY, gensym("addPosY"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_addPosZ, gensym("addPosZ"), A_GIMME, 0);
+
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_get, gensym("get"), A_GIMME, 0);
+
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosL, gensym("massesPosL"), 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsL, gensym("massesSpeedsL"), 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesL, gensym("massesForcesL"), 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosT, gensym("massesPosT"), A_DEFSYMBOL, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsT, gensym("massesSpeedsT"),A_DEFSYMBOL, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesT, gensym("massesForcesT"),A_DEFSYMBOL, 0);
+
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosXL, gensym("massesPosXL"), 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsXL, gensym("massesSpeedsXL"), 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesXL, gensym("massesForcesXL"), 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosXT, gensym("massesPosXT"), A_DEFSYMBOL, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsXT, gensym("massesSpeedsXT"),A_DEFSYMBOL, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesXT, gensym("massesForcesXT"),A_DEFSYMBOL, 0);
+
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosYL, gensym("massesPosYL"), 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsYL, gensym("massesSpeedsYL"), 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesYL, gensym("massesForcesYL"), 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosYT, gensym("massesPosYT"), A_DEFSYMBOL, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsYT, gensym("massesSpeedsYT"),A_DEFSYMBOL, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesYT, gensym("massesForcesYT"),A_DEFSYMBOL, 0);
+
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosZL, gensym("massesPosZL"), 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsZL, gensym("massesSpeedsZL"), 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesZL, gensym("massesForcesZL"), 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosZT, gensym("massesPosZT"), A_DEFSYMBOL, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsZT, gensym("massesSpeedsZT"),A_DEFSYMBOL, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesZT, gensym("massesForcesZT"),A_DEFSYMBOL, 0);
+
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosMean, gensym("massesPosMean"), A_GIMME, 0);
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosStd, gensym("massesPosStd"),A_GIMME, 0);
+ // class_addmethod(pmpd3d_class, (t_method)pmpd3d_linkLMean, gensym("linkLMean"),A_GIMME, 0);
+ // class_addmethod(pmpd3d_class, (t_method)pmpd3d_linkLStd, gensym("linkLStd"),A_GIMME, 0);
+
+ class_addmethod(pmpd3d_class, (t_method)pmpd3d_grabMass, gensym("grabMass"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+
+}
+
diff --git a/pmpd~.c b/pmpd~.c
index ce8f02d..db5d821 100644
--- a/pmpd~.c
+++ b/pmpd~.c
@@ -11,18 +11,18 @@
#include "m_pd.h"
-#include "stdio.h"
+#include "stdio.h"
#include "math.h"
#define max(a,b) ( ((a) > (b)) ? (a) : (b) )
#define min(a,b) ( ((a) < (b)) ? (a) : (b) )
-
+
#define nb_max_link 10000
#define nb_max_mass 10000
-#define nb_max_in 1000
+#define nb_max_in 1000
#define nb_max_out 1000
#define nb_max_outlet 20
-#define nb_max_inlet 20 // hard-coded on the methods definition
+#define nb_max_inlet 20 // hard-coded on the methods definition
static t_class *pmpd_tilde_class;
@@ -37,13 +37,13 @@ typedef struct _link {
struct _mass *mass1;
struct _mass *mass2;
t_float Ke, K1, D1;
-} foo1 ;
-
+} foo1 ;
+
typedef struct _NLlink {
struct _mass *mass1;
struct _mass *mass2;
t_float Ke, K1, D1,L0,Lmin, Lmax, Pow;
-} foo1b ;
+} foo1b ;
typedef struct _inPos {
// in en position
@@ -51,27 +51,27 @@ typedef struct _inPos {
struct _mass *mass1;
t_float influence;
} foo2;
-
+
typedef struct _inForce {
// in en force
t_int nbr_inlet;
struct _mass *mass1;
t_float influence;
} foo3;
-
+
typedef struct _outPos {
// out en position
t_int nbr_outlet;
struct _mass *mass1;
t_float influence;
-} foo4;
-
+} foo4;
+
typedef struct _outSpeed {
// out en vitesse
t_int nbr_outlet;
struct _mass *mass1;
t_float influence;
-} foo5;
+} foo5;
typedef struct _pmpd_tilde {
t_object x_obj;
@@ -123,7 +123,7 @@ t_int *pmpd_tilde_perform(t_int *w)
t_float F,L;
t_int i;
- struct _mass mass_1, mass_2;
+// struct _mass mass_1, mass_2;
t_sample *out[nb_max_outlet];
t_sample *in[nb_max_inlet];
@@ -135,15 +135,16 @@ t_int *pmpd_tilde_perform(t_int *w)
out[i]= x->outlet_vector[i];
while (n--)
- {
+ {
x->loop = 0;
while (x->loop++ < x->nb_loop)
- {
+ {
for (i=0; i<x->nb_inPos; i++)
- // get inlet value and make it a position to the specified mass x->inPos[i].mass1->posX = x->inPos[i].influence * *in[x->inPos[i].nbr_inlet];
+ // get inlet value and make it a position to the specified mass
+ x->inPos[i].mass1->posX = x->inPos[i].influence * *in[x->inPos[i].nbr_inlet];
for (i=0; i<x->nb_inForce; i++)
- // get inlet value and make it a force to the specified mass
- x->inForce[i].mass1->forceX += x->inForce[i].influence * *in[x->inForce[i].nbr_inlet];
+ // get inlet value and make it a force to the specified mass
+ x->inForce[i].mass1->forceX += x->inForce[i].influence * *in[x->inForce[i].nbr_inlet];
for (i=0; i<x->nb_link; i++)
// compute forces generated by links (spring / dashpot)
@@ -157,14 +158,14 @@ t_int *pmpd_tilde_perform(t_int *w)
x->link[i].mass1->forceX -= F;
x->link[i].mass2->forceX += F;
}
-
+
for (i=0; i<x->nb_NLlink; i++)
// compute forces generated by NLlinks (spring / dashpot)
- {
- L=x->NLlink[i].mass1->posX - x->NLlink[i].mass2->posX - x->NLlink[i].L0;
- if (L<x->NLlink[i].Lmax & L>x->NLlink[i].Lmin)
+ {
+ L=x->NLlink[i].mass1->posX - x->NLlink[i].mass2->posX - x->NLlink[i].L0;
+ if (L<x->NLlink[i].Lmax & L>x->NLlink[i].Lmin)
{
- F = x->NLlink[i].K1 * pow(fabs(L) ,x->NLlink[i].Pow) ;
+ F = x->NLlink[i].K1 * pow(fabs(L) ,x->NLlink[i].Pow) ;
if (L < 0) F *= -1;
// spring
@@ -175,14 +176,14 @@ t_int *pmpd_tilde_perform(t_int *w)
x->NLlink[i].mass2->forceX += F;
}
}
- for (i=1; i<x->nb_mass; i++)
+ for (i=1; i<x->nb_mass; i++)
{
- // compute new masses position
+ // compute new masses position
// a mass does not move if M=0 (i.e : invM = 0)
- x->mass[i].speedX += x->mass[i].forceX * x->mass[i].invM;
+ x->mass[i].speedX += x->mass[i].forceX * x->mass[i].invM;
x->mass[i].forceX = 0;
- x->mass[i].forceX = random_bang_pmpd_tilde(x) * 1e-25;
- // only used for denormal problem
+ x->mass[i].forceX = random_bang_pmpd_tilde(x) * 1e-25;
+ // only used for denormal problem
// -ffast-math -O6 does not solve the problem
x->mass[i].posX += x->mass[i].speedX ;
}
@@ -254,21 +255,21 @@ void pmpd_tilde_posX(t_pmpd_tilde *x, t_float nbr_mass, t_float posX)
void pmpd_tilde_mass(t_pmpd_tilde *x, t_float M, t_float posX)
// add a mass
-//invM speedX posX force
+//invM speedX posX force
{
- if (M<=0)
- {
- M = 0;
+ if (M<=0)
+ {
+ M = 0;
x->mass[x->nb_mass].invM = 0;
- }
- else
+ }
+ else
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->nb_mass++ ;
+ x->nb_mass++ ;
if (x->nb_mass == nb_max_mass) error("to many mass");
x->nb_mass = min ( nb_max_mass -1, x->nb_mass );
}
@@ -282,31 +283,31 @@ void pmpd_tilde_link(t_pmpd_tilde *x, t_float mass_1, t_float mass_2, t_float K1
x->link[x->nb_link].K1 = K1;
x->link[x->nb_link].D1 = D1;
- x->nb_link++ ;
+ x->nb_link++ ;
if (x->nb_link == nb_max_link) error("to many link");
x->nb_link = min ( nb_max_link -1, x->nb_link );
-}
-
-void pmpd_tilde_NLlink(t_pmpd_tilde *x, t_symbol *s, int argc, t_atom *argv)
+}
+
+void pmpd_tilde_NLlink(t_pmpd_tilde *x, t_symbol *s, int argc, t_atom *argv)
// t_float mass_1, t_float mass_2, t_float K1, t_float D1, t_float Pow, t_float Lmin, t_float Lmax, t_float L0
// add a NLlink
-{
+{
if (argc == 8)
- {
+ {
x->NLlink[x->nb_NLlink].mass1 = &x->mass[max(0, min ( x->nb_mass, (int)atom_getfloatarg(0, argc, argv)))];
x->NLlink[x->nb_NLlink].mass2 = &x->mass[max(0, min ( x->nb_mass, (int)atom_getfloatarg(1, argc, argv)))];
x->NLlink[x->nb_NLlink].K1 = atom_getfloatarg(2, argc, argv);
x->NLlink[x->nb_NLlink].D1 = atom_getfloatarg(3, argc, argv);
- x->NLlink[x->nb_NLlink].Pow = atom_getfloatarg(4, argc, argv);
+ x->NLlink[x->nb_NLlink].Pow = atom_getfloatarg(4, argc, argv);
x->NLlink[x->nb_NLlink].L0 = atom_getfloatarg(5, argc, argv);
x->NLlink[x->nb_NLlink].Lmin = atom_getfloatarg(6, argc, argv);
x->NLlink[x->nb_NLlink].Lmax = atom_getfloatarg(7, argc, argv);
- x->nb_NLlink++ ;
+ x->nb_NLlink++ ;
if (x->nb_NLlink == nb_max_link) error("to many NLlink");
- x->nb_NLlink = min ( nb_max_link -1, x->nb_NLlink );
- }
- else
+ x->nb_NLlink = min ( nb_max_link -1, x->nb_NLlink );
+ }
+ else
error("wrong argument number for NLlink");
}
@@ -318,10 +319,10 @@ void pmpd_tilde_inPos(t_pmpd_tilde *x, t_float nb_inlet, t_float mass_1, t_float
x->inPos[x->nb_inPos].mass1 = &x->mass[max(0, min ( x->nb_mass, (int)mass_1))];
x->inPos[x->nb_inPos].influence = influence;
- x->nb_inPos++;
+ x->nb_inPos++;
if (x->nb_inPos == nb_max_in) error("to many inPos");
x->nb_inPos = min ( nb_max_in - 1, x->nb_inPos );
-}
+}
void pmpd_tilde_inForce(t_pmpd_tilde *x, t_float nb_inlet, t_float mass_1, t_float influence)
//add an input point
// nbr_inlet, *mass1, influence;
@@ -330,10 +331,10 @@ void pmpd_tilde_inForce(t_pmpd_tilde *x, t_float nb_inlet, t_float mass_1, t_flo
x->inForce[x->nb_inForce].mass1 = &x->mass[max(0, min ( x->nb_mass, (int)mass_1))];
x->inForce[x->nb_inForce].influence = influence;
- x->nb_inForce++;
+ x->nb_inForce++;
if (x->nb_inForce == nb_max_in) error("to many inForce");
x->nb_inForce = min ( nb_max_in - 1, x->nb_inForce );
-}
+}
void pmpd_tilde_outPos(t_pmpd_tilde *x, t_float nb_outlet, t_float mass_1, t_float influence)
// add an output point
@@ -343,7 +344,7 @@ void pmpd_tilde_outPos(t_pmpd_tilde *x, t_float nb_outlet, t_float mass_1, t_flo
x->outPos[x->nb_outPos].mass1 = &x->mass[max(0, min ( x->nb_mass, (int)mass_1))];
x->outPos[x->nb_outPos].influence = influence;
- x->nb_outPos++ ;
+ x->nb_outPos++ ;
if (x->nb_outPos == nb_max_out) error("to many outPos");
x->nb_outPos = min ( nb_max_out - 1, x->nb_outPos );
}
@@ -356,14 +357,14 @@ void pmpd_tilde_outSpeed(t_pmpd_tilde *x, t_float nb_outlet, t_float mass_1, t_f
x->outSpeed[x->nb_outSpeed].mass1 = &x->mass[max(0, min ( x->nb_mass, (int)mass_1))];
x->outSpeed[x->nb_outSpeed].influence = influence;
- x->nb_outSpeed++ ;
+ x->nb_outSpeed++ ;
if (x->nb_outSpeed == nb_max_out) error("to many outSpeed");
x->nb_outSpeed = min ( nb_max_out - 1, x->nb_outSpeed );
}
void pmpd_tilde_reset(t_pmpd_tilde *x)
{
- x->nb_link = 0;
+ x->nb_link = 0;
x->nb_NLlink = 0;
x->nb_mass = 0;
x->nb_inPos= 0;
@@ -391,7 +392,7 @@ void *pmpd_tilde_new(t_symbol *s, int argc, t_atom *argv)
for(i=0; i<x->nb_inlet-1; i++)
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
- x->nb_loop = max (1, (int)atom_getfloatarg(2, argc, argv) );
+ x->nb_loop = max (1, (int)atom_getfloatarg(2, argc, argv) );
return (void *)x;
}
@@ -404,9 +405,9 @@ void pmpd_tilde_setup(void) {
class_addbang(pmpd_tilde_class, pmpd_tilde_bang);
class_addfloat(pmpd_tilde_class, (t_method)pmpd_tilde_float);
class_addmethod(pmpd_tilde_class, (t_method)pmpd_tilde_mass, gensym("mass"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addmethod(pmpd_tilde_class, (t_method)pmpd_tilde_link, gensym("link"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addmethod(pmpd_tilde_class, (t_method)pmpd_tilde_NLlink, gensym("NLlink"), A_GIMME, 0);
- class_addmethod(pmpd_tilde_class, (t_method)pmpd_tilde_inPos, gensym("inPos"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addmethod(pmpd_tilde_class, (t_method)pmpd_tilde_link, gensym("link"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addmethod(pmpd_tilde_class, (t_method)pmpd_tilde_NLlink, gensym("NLlink"), A_GIMME, 0);
+ class_addmethod(pmpd_tilde_class, (t_method)pmpd_tilde_inPos, gensym("inPos"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
class_addmethod(pmpd_tilde_class, (t_method)pmpd_tilde_inForce, gensym("inForce"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
class_addmethod(pmpd_tilde_class, (t_method)pmpd_tilde_outPos, gensym("outPos"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
class_addmethod(pmpd_tilde_class, (t_method)pmpd_tilde_outSpeed, gensym("outSpeed"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);