From b7ebf0bf8ada854bb04c403927328bf0ca273599 Mon Sep 17 00:00:00 2001 From: Cyrille Henry Date: Tue, 13 Jun 2006 17:47:10 +0000 Subject: spliting pmpd lib to single files svn path=/trunk/externals/pmpd/; revision=5221 --- src/lia.c | 162 --------- src/lia2D.c | 213 ----------- src/lia3D.c | 238 ------------- src/link.c | 161 +++++++++ src/link2D.c | 212 +++++++++++ src/link3D.c | 237 +++++++++++++ src/mass.c | 186 ++++++++++ src/mass2D.c | 811 ++++++++++++++++++++++++++++++++++++++++++ src/mass3D.c | 1095 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/masse.c | 183 ---------- src/masse2D.c | 809 ------------------------------------------ src/masse3D.c | 1093 -------------------------------------------------------- src/pmpd.c | 48 ++- src/pmpd~.c | 9 +- 14 files changed, 2750 insertions(+), 2707 deletions(-) delete mode 100755 src/lia.c delete mode 100755 src/lia2D.c delete mode 100755 src/lia3D.c create mode 100755 src/link.c create mode 100755 src/link2D.c create mode 100755 src/link3D.c create mode 100755 src/mass.c create mode 100755 src/mass2D.c create mode 100755 src/mass3D.c delete mode 100755 src/masse.c delete mode 100755 src/masse2D.c delete mode 100755 src/masse3D.c (limited to 'src') diff --git a/src/lia.c b/src/lia.c deleted file mode 100755 index 1293cac..0000000 --- a/src/lia.c +++ /dev/null @@ -1,162 +0,0 @@ -#include "m_pd.h" -#include "math.h" - -static t_class *liaKD_class; - -typedef struct _liaKD { - t_object x_obj; - t_float raideur, viscosite, D2, longueur, distance_old, position1, position2, position_old1, position_old2; - t_outlet *force1; - t_outlet *force2; - t_float Lmin, Lmax; - t_symbol *x_sym; // receive -} t_liaKD; - -void liaKD_float(t_liaKD *x, t_floatarg f1) -{ - x->position1 = f1; -} - -void liaKD_bang(t_liaKD *x) -{ - t_float force1, force2, distance; - - distance = (x->position2 - x->position1); -//distance = abs(x->position2 - x->position1); - if (distance<0) distance = -distance; - - force1 = x->raideur*(distance-(x->longueur)) + x->viscosite*(distance - x->distance_old) ; - - x->distance_old = distance; - - if (distance > x->Lmax) force1=0; - if (distance < x->Lmin) force1=0; - - if (distance != 0) - { - force1 = force1 * (x->position2 - x->position1) / distance; - } - - force2 = -force1 + (x->position_old2 - x->position2)*x->D2; - force1 += (x->position_old1 - x->position1)*x->D2; - // masse damping - - outlet_float(x->force1, force1); - outlet_float(x->force2, force2); - - - x->position_old1 = x->position1; - x->position_old2 = x->position2; - -} - -void liaKD_reset(t_liaKD *x) -{ - x->position1 = 0; - x->position2 = 0; - - x->position_old1 = 0; - x->position_old2 = 0; - - x->distance_old = x->longueur; -} - -void liaKD_resetF(t_liaKD *x) -{ - x->position_old1 = x->position1; - x->position_old2 = x->position2; - - x->distance_old = x->longueur; -} - -void liaKD_resetl(t_liaKD *x) -{ - x->longueur = (x->position1 - x->position2); -} - -void liaKD_setL(t_liaKD *x, t_float L) -{ - x->longueur = L; -} - -void liaKD_setK(t_liaKD *x, t_float K) -{ - x->raideur = K; -} - -void liaKD_setD(t_liaKD *x, t_float D) -{ - x->viscosite = D; -} - -void liaKD_setD2(t_liaKD *x, t_float D2) -{ - x->D2 = D2; -} - -void liaKD_Lmin(t_liaKD *x, t_float Lmin) -{ - x->Lmin = Lmin; -} - -void liaKD_Lmax(t_liaKD *x, t_float Lmax) -{ - x->Lmax = Lmax; -} - -static void liaKD_free(t_liaKD *x) -{ - pd_unbind(&x->x_obj.ob_pd, x->x_sym); -} - -void *liaKD_new(t_symbol *s, t_floatarg L, t_floatarg K, t_floatarg D, t_floatarg D2 ) -{ - - t_liaKD *x = (t_liaKD *)pd_new(liaKD_class); - - x->x_sym = s; - pd_bind(&x->x_obj.ob_pd, s); - - floatinlet_new(&x->x_obj, &x->position2); - - x->force1=outlet_new(&x->x_obj, 0); - x->force2=outlet_new(&x->x_obj, 0); - - x->position1 = 0; - x->position2 = 0; - - x->raideur=K; - x->viscosite=D; - x->D2=D2; - - x->Lmin= 0; - x->Lmax= 10000; - - x->longueur=L; - - return (void *)x; -} - -void lia_setup(void) -{ - liaKD_class = class_new(gensym("lia"), - (t_newmethod)liaKD_new, - (t_method)liaKD_free, - sizeof(t_liaKD), - CLASS_DEFAULT, A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); - - class_addcreator((t_newmethod)liaKD_new, gensym("link"), A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); - class_addcreator((t_newmethod)liaKD_new, gensym("pmpd.link"), A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); - - class_addfloat(liaKD_class, liaKD_float); - class_addbang(liaKD_class, liaKD_bang); - class_addmethod(liaKD_class, (t_method)liaKD_reset, gensym("reset"), 0); - class_addmethod(liaKD_class, (t_method)liaKD_resetl, gensym("resetL"), 0); - class_addmethod(liaKD_class, (t_method)liaKD_resetF, gensym("resetF"), 0); - class_addmethod(liaKD_class, (t_method)liaKD_setD, gensym("setD"), A_DEFFLOAT, 0); - class_addmethod(liaKD_class, (t_method)liaKD_setD2, gensym("setD2"), A_DEFFLOAT, 0); - class_addmethod(liaKD_class, (t_method)liaKD_setK, gensym("setK"), A_DEFFLOAT, 0); - class_addmethod(liaKD_class, (t_method)liaKD_setL, gensym("setL"), A_DEFFLOAT, 0); - class_addmethod(liaKD_class, (t_method)liaKD_Lmin, gensym("setLmin"), A_DEFFLOAT, 0); - class_addmethod(liaKD_class, (t_method)liaKD_Lmax, gensym("setLmax"), A_DEFFLOAT, 0); -} diff --git a/src/lia2D.c b/src/lia2D.c deleted file mode 100755 index ff5e0aa..0000000 --- a/src/lia2D.c +++ /dev/null @@ -1,213 +0,0 @@ -#include "m_pd.h" -#include "math.h" - -static t_class *lia2D_class; - -typedef struct _lia2D { - t_object x_obj; - t_float raideur, viscosite, D2, longueur, distance_old; - t_float position2Dx1, position2Dx2, posx_old1, posx_old2; - t_float position2Dy1, position2Dy2, posy_old1, posy_old2; - t_float Lmin, Lmax, muscle; - t_outlet *force1; - t_outlet *force2; - t_symbol *x_sym; // receive -} t_lia2D; - -void lia2D_position2D(t_lia2D *x, t_floatarg f1, t_floatarg f2) -{ - x->position2Dx1 = f1; - x->position2Dy1 = f2; -} - -void lia2D_position2D2(t_lia2D *x, t_floatarg f1, t_floatarg f2) -{ - x->position2Dx2 = f1; - x->position2Dy2 = f2; -} - -void lia2D_bang(t_lia2D *x) -{ - t_float force, force2, forcex1, forcey1, forcex2, forcey2, distance; - t_atom force1[2]; - - distance = sqrt ( pow((x->position2Dx2-x->position2Dx1), 2) + pow((x->position2Dy2-x->position2Dy1), 2) ); - - force = ( x->raideur*(distance-(x->longueur * x->muscle)) ) + ( x->viscosite*(distance-x->distance_old) ); - - if (distance > x->Lmax) force=0; - if (distance < x->Lmin) force=0; - - if (distance != 0) - { - forcex1 = force * (x->position2Dx2 - x->position2Dx1) / distance; - forcey1 = force * (x->position2Dy2 - x->position2Dy1) / distance; - } - else - { - forcex1 = 0; - forcey1 = 0 ; - } - - forcex2 = -forcex1; - forcey2 = -forcey1; - - forcex1 += (x->posx_old1 - x->position2Dx1)*x->D2; - forcey1 += (x->posy_old1 - x->position2Dy1)*x->D2; - - forcex2 += (x->posx_old2 - x->position2Dx2)*x->D2; - forcey2 += (x->posy_old2 - x->position2Dy2)*x->D2; - - SETFLOAT(&(force1[0]), forcex2 ); - SETFLOAT(&(force1[1]), forcey2 ); - - outlet_anything(x->force2, gensym("force2D"), 2, force1); - - SETFLOAT(&(force1[0]), forcex1 ); - SETFLOAT(&(force1[1]), forcey1 ); - - outlet_anything(x->force1, gensym("force2D"), 2, force1); - - x->posx_old2 = x->position2Dx2; - x->posx_old1 = x->position2Dx1; - - x->posy_old2 = x->position2Dy2; - x->posy_old1 = x->position2Dy1; - - x->distance_old = distance; -} - -void lia2D_reset(t_lia2D *x) -{ - x->position2Dx1 = 0; - x->position2Dx2 = 0; - x->posx_old1 = 0; - x->posx_old2 = 0; - - x->position2Dy1 = 0; - x->position2Dy2 = 0; - x->posy_old1 = 0; - x->posy_old2 = 0; - - x->distance_old = x->longueur; -} - -void lia2D_resetF(t_lia2D *x) -{ - - x->posx_old1 = x->position2Dx1; - x->posx_old2 = x->position2Dx2; - - x->posy_old1 = x->position2Dy1; - x->posy_old2 = x->position2Dy2; - - x->distance_old = x->longueur; - -} - -void lia2D_resetL(t_lia2D *x) -{ - x->longueur = sqrt ( pow((x->position2Dx2-x->position2Dx1), 2) + pow((x->position2Dy2-x->position2Dy1), 2) ); -} - - -void lia2D_setK(t_lia2D *x, t_float K) -{ - x->raideur = K; -} - -void lia2D_setL(t_lia2D *x, t_float L) -{ - x->longueur = L; -} - -void lia2D_setD(t_lia2D *x, t_float D) -{ - x->viscosite = D; -} - -void lia2D_setD2(t_lia2D *x, t_float D) -{ - x->D2 = D; -} - -void lia2D_Lmin(t_lia2D *x, t_float Lmin) -{ - x->Lmin = Lmin; -} - -void lia2D_Lmax(t_lia2D *x, t_float Lmax) -{ - x->Lmax = Lmax; -} - -void lia2D_muscle(t_lia2D *x, t_float muscle) -{ - x->muscle = muscle; -} - -static void lia2D_free(t_lia2D *x) -{ - pd_unbind(&x->x_obj.ob_pd, x->x_sym); -} - -void *lia2D_new(t_symbol *s, t_floatarg l, t_floatarg K, t_floatarg D, t_floatarg D2) -{ - - t_lia2D *x = (t_lia2D *)pd_new(lia2D_class); - - x->x_sym = s; - pd_bind(&x->x_obj.ob_pd, s); - - inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("position2D"), gensym("position2D2")); - - x->force1=outlet_new(&x->x_obj, 0); - x->force2=outlet_new(&x->x_obj, 0); - - x->position2Dx1 = 0; - x->position2Dx2 = 0; - x->position2Dy1 = 0; - x->position2Dy2 = 0; - - x->raideur=K; - x->viscosite=D; - x->longueur = l; - - x->D2=D2; - - x->Lmin= 0; - x->Lmax= 10000; - x->muscle= 1; - - x->distance_old = x->longueur; - - return (x); -} - -void lia2D_setup(void) -{ - - lia2D_class = class_new(gensym("lia2D"), - (t_newmethod)lia2D_new, - (t_method)lia2D_free, - sizeof(t_lia2D), - CLASS_DEFAULT, A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); - - class_addcreator((t_newmethod)lia2D_new, gensym("link2D"), A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); - class_addcreator((t_newmethod)lia2D_new, gensym("pmpd.link2D"), A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); - - class_addbang(lia2D_class, lia2D_bang); - class_addmethod(lia2D_class, (t_method)lia2D_reset, gensym("reset"), 0); - class_addmethod(lia2D_class, (t_method)lia2D_resetL, gensym("resetL"), 0); - class_addmethod(lia2D_class, (t_method)lia2D_resetF, gensym("resetF"), 0); - class_addmethod(lia2D_class, (t_method)lia2D_setD, gensym("setD"), A_DEFFLOAT, 0); - class_addmethod(lia2D_class, (t_method)lia2D_setD2, gensym("setD2"), A_DEFFLOAT, 0); - class_addmethod(lia2D_class, (t_method)lia2D_setK, gensym("setK"), A_DEFFLOAT, 0); - class_addmethod(lia2D_class, (t_method)lia2D_setL, gensym("setL"), A_DEFFLOAT, 0); - class_addmethod(lia2D_class, (t_method)lia2D_Lmin, gensym("setLmin"), A_DEFFLOAT, 0); - class_addmethod(lia2D_class, (t_method)lia2D_Lmax, gensym("setLmax"), A_DEFFLOAT, 0); - class_addmethod(lia2D_class, (t_method)lia2D_muscle, gensym("setM"), A_DEFFLOAT, 0); - class_addmethod(lia2D_class, (t_method)lia2D_position2D, gensym("position2D"), A_DEFFLOAT, A_DEFFLOAT, 0); - class_addmethod(lia2D_class, (t_method)lia2D_position2D2, gensym("position2D2"), A_DEFFLOAT, A_DEFFLOAT, 0); - -} diff --git a/src/lia3D.c b/src/lia3D.c deleted file mode 100755 index 4621516..0000000 --- a/src/lia3D.c +++ /dev/null @@ -1,238 +0,0 @@ -#include "m_pd.h" -#include "math.h" - -static t_class *lia3D_class; - -typedef struct _lia3D { - t_object x_obj; - t_float raideur, viscosite, D2, longueur, distance_old; - t_float position3Dx1, position3Dx2, posx_old1, posx_old2; - t_float position3Dy1, position3Dy2, posy_old1, posy_old2; - t_float position3Dz1, position3Dz2, posz_old1, posz_old2; - t_float Lmin, Lmax, muscle; - t_outlet *force1; - t_outlet *force2; - t_symbol *x_sym; // receive -} t_lia3D; - -void lia3D_position3D(t_lia3D *x, t_floatarg f1, t_floatarg f2, t_floatarg f3) -{ - x->position3Dx1 = f1; - x->position3Dy1 = f2; - x->position3Dz1 = f3; - -} - -void lia3D_position3D2(t_lia3D *x, t_floatarg f1, t_floatarg f2, t_floatarg f3) -{ - x->position3Dx2 = f1; - x->position3Dy2 = f2; - x->position3Dz2 = f3; -} - -void lia3D_bang(t_lia3D *x) -{ - t_float force, force2, forcex1, forcey1, forcez1, forcex2, forcey2, forcez2, distance; - t_atom force1[3]; - - distance = sqrt ( pow((x->position3Dx2-x->position3Dx1), 2) + pow((x->position3Dy2-x->position3Dy1),2) + pow((x->position3Dz2-x->position3Dz1), 2) ); - - force = ( x->raideur*(distance-(x->longueur * x->muscle)) ) + ( x->viscosite*(distance-x->distance_old) ); - - if (distance > x->Lmax) force=0; - if (distance < x->Lmin) force=0; - - if (distance != 0) - { - forcex1 = force * (x->position3Dx2 - x->position3Dx1) / distance; - forcey1 = force * (x->position3Dy2 - x->position3Dy1) / distance; - forcez1 = force * (x->position3Dz2 - x->position3Dz1) / distance; - } - else - { - forcex1 = 0; - forcey1 = 0; - forcez1 = 0; - } - - forcex2 = -forcex1; - forcey2 = -forcey1; - forcez2 = -forcez1; - - forcex1 += (x->posx_old1 - x->position3Dx1)*x->D2; - forcey1 += (x->posy_old1 - x->position3Dy1)*x->D2; - forcez1 += (x->posz_old1 - x->position3Dz1)*x->D2; - - forcex2 += (x->posx_old2 - x->position3Dx2)*x->D2; - forcey2 += (x->posy_old2 - x->position3Dy2)*x->D2; - forcez2 += (x->posz_old2 - x->position3Dz2)*x->D2; - - - SETFLOAT(&(force1[0]), forcex1 ); - SETFLOAT(&(force1[1]), forcey1 ); - SETFLOAT(&(force1[2]), forcez1 ); - outlet_anything(x->force1, gensym("force3D"), 3, force1); - - SETFLOAT(&(force1[0]), forcex2 ); - SETFLOAT(&(force1[1]), forcey2 ); - SETFLOAT(&(force1[2]), forcez2 ); - - outlet_anything(x->force2, gensym("force3D"), 3, force1); - - x->posx_old2 = x->position3Dx2; - x->posx_old1 = x->position3Dx1; - - x->posy_old2 = x->position3Dy2; - x->posy_old1 = x->position3Dy1; - - x->posz_old2 = x->position3Dz2; - x->posz_old1 = x->position3Dz1; - - x->distance_old = distance; -} - -void lia3D_reset(t_lia3D *x) -{ - x->position3Dx1 = 0; - x->position3Dx2 = 0; - x->posx_old1 = 0; - x->posx_old2 = 0; - - x->position3Dy1 = 0; - x->position3Dy2 = 0; - x->posy_old1 = 0; - x->posy_old2 = 0; - - x->position3Dz1 = 0; - x->position3Dz2 = 0; - x->posz_old1 = 0; - x->posz_old2 = 0; - - x->distance_old = x->longueur; - -} - -void lia3D_resetF(t_lia3D *x) -{ - - x->posx_old1 = x->position3Dx1; - x->posx_old2 = x->position3Dx2; - - x->posy_old1 = x->position3Dy1; - x->posy_old2 = x->position3Dy2; - - x->posz_old1 = x->position3Dz1; - x->posz_old2 = x->position3Dz2; - - x->distance_old = x->longueur; - -} - -void lia3D_resetL(t_lia3D *x) -{ - x->longueur = sqrt ( pow((x->position3Dx2-x->position3Dx1), 2) + pow((x->position3Dy2-x->position3Dy1),2) + pow((x->position3Dz2-x->position3Dz1), 2) ); -} - -void lia3D_setK(t_lia3D *x, t_float K) -{ - x->raideur = K; -} - -void lia3D_setL(t_lia3D *x, t_float L) -{ - x->longueur = L; -} - -void lia3D_setD(t_lia3D *x, t_float D) -{ - x->viscosite = D; -} - -void lia3D_setD2(t_lia3D *x, t_float D2) -{ - x->D2 = D2; -} - -void lia3D_Lmin(t_lia3D *x, t_float Lmin) -{ - x->Lmin = Lmin; -} - -void lia3D_Lmax(t_lia3D *x, t_float Lmax) -{ - x->Lmax = Lmax; -} - -void lia3D_muscle(t_lia3D *x, t_float muscle) -{ - x->muscle = muscle; -} - -static void lia3D_free(t_lia3D *x) -{ - pd_unbind(&x->x_obj.ob_pd, x->x_sym); -} - -void *lia3D_new(t_symbol *s, t_floatarg l, t_floatarg K, t_floatarg D, t_floatarg D2) -{ - - t_lia3D *x = (t_lia3D *)pd_new(lia3D_class); - - x->x_sym = s; - pd_bind(&x->x_obj.ob_pd, s); - - inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("position3D"), gensym("position3D2")); - - x->force1=outlet_new(&x->x_obj, 0); - x->force2=outlet_new(&x->x_obj, 0); - - x->position3Dx1 = 0; - x->position3Dx2 = 0; - x->position3Dy1 = 0; - x->position3Dy2 = 0; - x->position3Dz1 = 0; - x->position3Dz2 = 0; - - x->raideur = K; - x->viscosite = D; - x->longueur = l; - - x->D2 = D2; - - x->Lmin= 0; - x->Lmax= 10000; - - x->distance_old = x->longueur; - - x->muscle = 1; - - return (void *)x; -} - -void lia3D_setup(void) -{ - - lia3D_class = class_new(gensym("lia3D"), - (t_newmethod)lia3D_new, - (t_method)lia3D_free, - sizeof(t_lia3D), - CLASS_DEFAULT, A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); - - class_addcreator((t_newmethod)lia3D_new, gensym("link3D"), A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); - class_addcreator((t_newmethod)lia3D_new, gensym("pmpd.link3D"), A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); - - class_addbang(lia3D_class, lia3D_bang); - class_addmethod(lia3D_class, (t_method)lia3D_reset, gensym("reset"), 0); - class_addmethod(lia3D_class, (t_method)lia3D_resetL, gensym("resetL"), 0); - class_addmethod(lia3D_class, (t_method)lia3D_resetF, gensym("resetF"), 0); - class_addmethod(lia3D_class, (t_method)lia3D_setD, gensym("setD"), A_DEFFLOAT, 0); - class_addmethod(lia3D_class, (t_method)lia3D_setD2, gensym("setD2"), A_DEFFLOAT, 0); - class_addmethod(lia3D_class, (t_method)lia3D_setK, gensym("setK"), A_DEFFLOAT, 0); - class_addmethod(lia3D_class, (t_method)lia3D_setL, gensym("setL"), A_DEFFLOAT, 0); - class_addmethod(lia3D_class, (t_method)lia3D_Lmin, gensym("setLmin"), A_DEFFLOAT, 0); - class_addmethod(lia3D_class, (t_method)lia3D_Lmax, gensym("setLmax"), A_DEFFLOAT, 0); - class_addmethod(lia3D_class, (t_method)lia3D_muscle, gensym("setM"), A_DEFFLOAT, 0); - class_addmethod(lia3D_class, (t_method)lia3D_position3D, gensym("position3D"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); - class_addmethod(lia3D_class, (t_method)lia3D_position3D2, gensym("position3D2"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); - -} diff --git a/src/link.c b/src/link.c new file mode 100755 index 0000000..459f4a2 --- /dev/null +++ b/src/link.c @@ -0,0 +1,161 @@ +#include "m_pd.h" +#include "math.h" + +static t_class *linkKD_class; + +typedef struct _linkKD { + t_object x_obj; + t_float raideur, viscosite, D2, longueur, distance_old, position1, position2, position_old1, position_old2; + t_outlet *force1; + t_outlet *force2; + t_float Lmin, Lmax; + t_symbol *x_sym; // receive +} t_linkKD; + +void linkKD_float(t_linkKD *x, t_floatarg f1) +{ + x->position1 = f1; +} + +void linkKD_bang(t_linkKD *x) +{ + t_float force1, force2, distance; + + distance = (x->position2 - x->position1); +//distance = abs(x->position2 - x->position1); + if (distance<0) distance = -distance; + + force1 = x->raideur*(distance-(x->longueur)) + x->viscosite*(distance - x->distance_old) ; + + x->distance_old = distance; + + if (distance > x->Lmax) force1=0; + if (distance < x->Lmin) force1=0; + + if (distance != 0) + { + force1 = force1 * (x->position2 - x->position1) / distance; + } + + force2 = -force1 + (x->position_old2 - x->position2)*x->D2; + force1 += (x->position_old1 - x->position1)*x->D2; + // masse damping + + outlet_float(x->force1, force1); + outlet_float(x->force2, force2); + + + x->position_old1 = x->position1; + x->position_old2 = x->position2; + +} + +void linkKD_reset(t_linkKD *x) +{ + x->position1 = 0; + x->position2 = 0; + + x->position_old1 = 0; + x->position_old2 = 0; + + x->distance_old = x->longueur; +} + +void linkKD_resetF(t_linkKD *x) +{ + x->position_old1 = x->position1; + x->position_old2 = x->position2; + + x->distance_old = x->longueur; +} + +void linkKD_resetl(t_linkKD *x) +{ + x->longueur = (x->position1 - x->position2); +} + +void linkKD_setL(t_linkKD *x, t_float L) +{ + x->longueur = L; +} + +void linkKD_setK(t_linkKD *x, t_float K) +{ + x->raideur = K; +} + +void linkKD_setD(t_linkKD *x, t_float D) +{ + x->viscosite = D; +} + +void linkKD_setD2(t_linkKD *x, t_float D2) +{ + x->D2 = D2; +} + +void linkKD_Lmin(t_linkKD *x, t_float Lmin) +{ + x->Lmin = Lmin; +} + +void linkKD_Lmax(t_linkKD *x, t_float Lmax) +{ + x->Lmax = Lmax; +} + +static void linkKD_free(t_linkKD *x) +{ + pd_unbind(&x->x_obj.ob_pd, x->x_sym); +} + +void *linkKD_new(t_symbol *s, t_floatarg L, t_floatarg K, t_floatarg D, t_floatarg D2 ) +{ + + t_linkKD *x = (t_linkKD *)pd_new(linkKD_class); + + x->x_sym = s; + pd_bind(&x->x_obj.ob_pd, s); + + floatinlet_new(&x->x_obj, &x->position2); + + x->force1=outlet_new(&x->x_obj, 0); + x->force2=outlet_new(&x->x_obj, 0); + + x->position1 = 0; + x->position2 = 0; + + x->raideur=K; + x->viscosite=D; + x->D2=D2; + + x->Lmin= 0; + x->Lmax= 10000; + + x->longueur=L; + + return (void *)x; +} + +void link_setup(void) +{ + linkKD_class = class_new(gensym("link"), + (t_newmethod)linkKD_new, + (t_method)linkKD_free, + sizeof(t_linkKD), + CLASS_DEFAULT, A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + + class_addcreator((t_newmethod)linkKD_new, gensym("lia"), A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + + class_addfloat(linkKD_class, linkKD_float); + class_addbang(linkKD_class, linkKD_bang); + class_addmethod(linkKD_class, (t_method)linkKD_reset, gensym("reset"), 0); + class_addmethod(linkKD_class, (t_method)linkKD_resetl, gensym("resetL"), 0); + class_addmethod(linkKD_class, (t_method)linkKD_resetF, gensym("resetF"), 0); + class_addmethod(linkKD_class, (t_method)linkKD_setD, gensym("setD"), A_DEFFLOAT, 0); + class_addmethod(linkKD_class, (t_method)linkKD_setD2, gensym("setD2"), A_DEFFLOAT, 0); + class_addmethod(linkKD_class, (t_method)linkKD_setK, gensym("setK"), A_DEFFLOAT, 0); + class_addmethod(linkKD_class, (t_method)linkKD_setL, gensym("setL"), A_DEFFLOAT, 0); + class_addmethod(linkKD_class, (t_method)linkKD_Lmin, gensym("setLmin"), A_DEFFLOAT, 0); + class_addmethod(linkKD_class, (t_method)linkKD_Lmax, gensym("setLmax"), A_DEFFLOAT, 0); +} diff --git a/src/link2D.c b/src/link2D.c new file mode 100755 index 0000000..318685d --- /dev/null +++ b/src/link2D.c @@ -0,0 +1,212 @@ +#include "m_pd.h" +#include "math.h" + +static t_class *link2D_class; + +typedef struct _link2D { + t_object x_obj; + t_float raideur, viscosite, D2, longueur, distance_old; + t_float position2Dx1, position2Dx2, posx_old1, posx_old2; + t_float position2Dy1, position2Dy2, posy_old1, posy_old2; + t_float Lmin, Lmax, muscle; + t_outlet *force1; + t_outlet *force2; + t_symbol *x_sym; // receive +} t_link2D; + +void link2D_position2D(t_link2D *x, t_floatarg f1, t_floatarg f2) +{ + x->position2Dx1 = f1; + x->position2Dy1 = f2; +} + +void link2D_position2D2(t_link2D *x, t_floatarg f1, t_floatarg f2) +{ + x->position2Dx2 = f1; + x->position2Dy2 = f2; +} + +void link2D_bang(t_link2D *x) +{ + t_float force, force2, forcex1, forcey1, forcex2, forcey2, distance; + t_atom force1[2]; + + distance = sqrt ( pow((x->position2Dx2-x->position2Dx1), 2) + pow((x->position2Dy2-x->position2Dy1), 2) ); + + force = ( x->raideur*(distance-(x->longueur * x->muscle)) ) + ( x->viscosite*(distance-x->distance_old) ); + + if (distance > x->Lmax) force=0; + if (distance < x->Lmin) force=0; + + if (distance != 0) + { + forcex1 = force * (x->position2Dx2 - x->position2Dx1) / distance; + forcey1 = force * (x->position2Dy2 - x->position2Dy1) / distance; + } + else + { + forcex1 = 0; + forcey1 = 0 ; + } + + forcex2 = -forcex1; + forcey2 = -forcey1; + + forcex1 += (x->posx_old1 - x->position2Dx1)*x->D2; + forcey1 += (x->posy_old1 - x->position2Dy1)*x->D2; + + forcex2 += (x->posx_old2 - x->position2Dx2)*x->D2; + forcey2 += (x->posy_old2 - x->position2Dy2)*x->D2; + + SETFLOAT(&(force1[0]), forcex2 ); + SETFLOAT(&(force1[1]), forcey2 ); + + outlet_anything(x->force2, gensym("force2D"), 2, force1); + + SETFLOAT(&(force1[0]), forcex1 ); + SETFLOAT(&(force1[1]), forcey1 ); + + outlet_anything(x->force1, gensym("force2D"), 2, force1); + + x->posx_old2 = x->position2Dx2; + x->posx_old1 = x->position2Dx1; + + x->posy_old2 = x->position2Dy2; + x->posy_old1 = x->position2Dy1; + + x->distance_old = distance; +} + +void link2D_reset(t_link2D *x) +{ + x->position2Dx1 = 0; + x->position2Dx2 = 0; + x->posx_old1 = 0; + x->posx_old2 = 0; + + x->position2Dy1 = 0; + x->position2Dy2 = 0; + x->posy_old1 = 0; + x->posy_old2 = 0; + + x->distance_old = x->longueur; +} + +void link2D_resetF(t_link2D *x) +{ + + x->posx_old1 = x->position2Dx1; + x->posx_old2 = x->position2Dx2; + + x->posy_old1 = x->position2Dy1; + x->posy_old2 = x->position2Dy2; + + x->distance_old = x->longueur; + +} + +void link2D_resetL(t_link2D *x) +{ + x->longueur = sqrt ( pow((x->position2Dx2-x->position2Dx1), 2) + pow((x->position2Dy2-x->position2Dy1), 2) ); +} + + +void link2D_setK(t_link2D *x, t_float K) +{ + x->raideur = K; +} + +void link2D_setL(t_link2D *x, t_float L) +{ + x->longueur = L; +} + +void link2D_setD(t_link2D *x, t_float D) +{ + x->viscosite = D; +} + +void link2D_setD2(t_link2D *x, t_float D) +{ + x->D2 = D; +} + +void link2D_Lmin(t_link2D *x, t_float Lmin) +{ + x->Lmin = Lmin; +} + +void link2D_Lmax(t_link2D *x, t_float Lmax) +{ + x->Lmax = Lmax; +} + +void link2D_muscle(t_link2D *x, t_float muscle) +{ + x->muscle = muscle; +} + +static void link2D_free(t_link2D *x) +{ + pd_unbind(&x->x_obj.ob_pd, x->x_sym); +} + +void *link2D_new(t_symbol *s, t_floatarg l, t_floatarg K, t_floatarg D, t_floatarg D2) +{ + + t_link2D *x = (t_link2D *)pd_new(link2D_class); + + x->x_sym = s; + pd_bind(&x->x_obj.ob_pd, s); + + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("position2D"), gensym("position2D2")); + + x->force1=outlet_new(&x->x_obj, 0); + x->force2=outlet_new(&x->x_obj, 0); + + x->position2Dx1 = 0; + x->position2Dx2 = 0; + x->position2Dy1 = 0; + x->position2Dy2 = 0; + + x->raideur=K; + x->viscosite=D; + x->longueur = l; + + x->D2=D2; + + x->Lmin= 0; + x->Lmax= 10000; + x->muscle= 1; + + x->distance_old = x->longueur; + + return (x); +} + +void link2D_setup(void) +{ + + link2D_class = class_new(gensym("link2D"), + (t_newmethod)link2D_new, + (t_method)link2D_free, + sizeof(t_link2D), + CLASS_DEFAULT, A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + + class_addcreator((t_newmethod)link2D_new, gensym("lia2D"), A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + + class_addbang(link2D_class, link2D_bang); + class_addmethod(link2D_class, (t_method)link2D_reset, gensym("reset"), 0); + class_addmethod(link2D_class, (t_method)link2D_resetL, gensym("resetL"), 0); + class_addmethod(link2D_class, (t_method)link2D_resetF, gensym("resetF"), 0); + class_addmethod(link2D_class, (t_method)link2D_setD, gensym("setD"), A_DEFFLOAT, 0); + class_addmethod(link2D_class, (t_method)link2D_setD2, gensym("setD2"), A_DEFFLOAT, 0); + class_addmethod(link2D_class, (t_method)link2D_setK, gensym("setK"), A_DEFFLOAT, 0); + class_addmethod(link2D_class, (t_method)link2D_setL, gensym("setL"), A_DEFFLOAT, 0); + class_addmethod(link2D_class, (t_method)link2D_Lmin, gensym("setLmin"), A_DEFFLOAT, 0); + class_addmethod(link2D_class, (t_method)link2D_Lmax, gensym("setLmax"), A_DEFFLOAT, 0); + class_addmethod(link2D_class, (t_method)link2D_muscle, gensym("setM"), A_DEFFLOAT, 0); + class_addmethod(link2D_class, (t_method)link2D_position2D, gensym("position2D"), A_DEFFLOAT, A_DEFFLOAT, 0); + class_addmethod(link2D_class, (t_method)link2D_position2D2, gensym("position2D2"), A_DEFFLOAT, A_DEFFLOAT, 0); + +} diff --git a/src/link3D.c b/src/link3D.c new file mode 100755 index 0000000..bbf0987 --- /dev/null +++ b/src/link3D.c @@ -0,0 +1,237 @@ +#include "m_pd.h" +#include "math.h" + +static t_class *link3D_class; + +typedef struct _link3D { + t_object x_obj; + t_float raideur, viscosite, D2, longueur, distance_old; + t_float position3Dx1, position3Dx2, posx_old1, posx_old2; + t_float position3Dy1, position3Dy2, posy_old1, posy_old2; + t_float position3Dz1, position3Dz2, posz_old1, posz_old2; + t_float Lmin, Lmax, muscle; + t_outlet *force1; + t_outlet *force2; + t_symbol *x_sym; // receive +} t_link3D; + +void link3D_position3D(t_link3D *x, t_floatarg f1, t_floatarg f2, t_floatarg f3) +{ + x->position3Dx1 = f1; + x->position3Dy1 = f2; + x->position3Dz1 = f3; + +} + +void link3D_position3D2(t_link3D *x, t_floatarg f1, t_floatarg f2, t_floatarg f3) +{ + x->position3Dx2 = f1; + x->position3Dy2 = f2; + x->position3Dz2 = f3; +} + +void link3D_bang(t_link3D *x) +{ + t_float force, force2, forcex1, forcey1, forcez1, forcex2, forcey2, forcez2, distance; + t_atom force1[3]; + + distance = sqrt ( pow((x->position3Dx2-x->position3Dx1), 2) + pow((x->position3Dy2-x->position3Dy1),2) + pow((x->position3Dz2-x->position3Dz1), 2) ); + + force = ( x->raideur*(distance-(x->longueur * x->muscle)) ) + ( x->viscosite*(distance-x->distance_old) ); + + if (distance > x->Lmax) force=0; + if (distance < x->Lmin) force=0; + + if (distance != 0) + { + forcex1 = force * (x->position3Dx2 - x->position3Dx1) / distance; + forcey1 = force * (x->position3Dy2 - x->position3Dy1) / distance; + forcez1 = force * (x->position3Dz2 - x->position3Dz1) / distance; + } + else + { + forcex1 = 0; + forcey1 = 0; + forcez1 = 0; + } + + forcex2 = -forcex1; + forcey2 = -forcey1; + forcez2 = -forcez1; + + forcex1 += (x->posx_old1 - x->position3Dx1)*x->D2; + forcey1 += (x->posy_old1 - x->position3Dy1)*x->D2; + forcez1 += (x->posz_old1 - x->position3Dz1)*x->D2; + + forcex2 += (x->posx_old2 - x->position3Dx2)*x->D2; + forcey2 += (x->posy_old2 - x->position3Dy2)*x->D2; + forcez2 += (x->posz_old2 - x->position3Dz2)*x->D2; + + + SETFLOAT(&(force1[0]), forcex1 ); + SETFLOAT(&(force1[1]), forcey1 ); + SETFLOAT(&(force1[2]), forcez1 ); + outlet_anything(x->force1, gensym("force3D"), 3, force1); + + SETFLOAT(&(force1[0]), forcex2 ); + SETFLOAT(&(force1[1]), forcey2 ); + SETFLOAT(&(force1[2]), forcez2 ); + + outlet_anything(x->force2, gensym("force3D"), 3, force1); + + x->posx_old2 = x->position3Dx2; + x->posx_old1 = x->position3Dx1; + + x->posy_old2 = x->position3Dy2; + x->posy_old1 = x->position3Dy1; + + x->posz_old2 = x->position3Dz2; + x->posz_old1 = x->position3Dz1; + + x->distance_old = distance; +} + +void link3D_reset(t_link3D *x) +{ + x->position3Dx1 = 0; + x->position3Dx2 = 0; + x->posx_old1 = 0; + x->posx_old2 = 0; + + x->position3Dy1 = 0; + x->position3Dy2 = 0; + x->posy_old1 = 0; + x->posy_old2 = 0; + + x->position3Dz1 = 0; + x->position3Dz2 = 0; + x->posz_old1 = 0; + x->posz_old2 = 0; + + x->distance_old = x->longueur; + +} + +void link3D_resetF(t_link3D *x) +{ + + x->posx_old1 = x->position3Dx1; + x->posx_old2 = x->position3Dx2; + + x->posy_old1 = x->position3Dy1; + x->posy_old2 = x->position3Dy2; + + x->posz_old1 = x->position3Dz1; + x->posz_old2 = x->position3Dz2; + + x->distance_old = x->longueur; + +} + +void link3D_resetL(t_link3D *x) +{ + x->longueur = sqrt ( pow((x->position3Dx2-x->position3Dx1), 2) + pow((x->position3Dy2-x->position3Dy1),2) + pow((x->position3Dz2-x->position3Dz1), 2) ); +} + +void link3D_setK(t_link3D *x, t_float K) +{ + x->raideur = K; +} + +void link3D_setL(t_link3D *x, t_float L) +{ + x->longueur = L; +} + +void link3D_setD(t_link3D *x, t_float D) +{ + x->viscosite = D; +} + +void link3D_setD2(t_link3D *x, t_float D2) +{ + x->D2 = D2; +} + +void link3D_Lmin(t_link3D *x, t_float Lmin) +{ + x->Lmin = Lmin; +} + +void link3D_Lmax(t_link3D *x, t_float Lmax) +{ + x->Lmax = Lmax; +} + +void link3D_muscle(t_link3D *x, t_float muscle) +{ + x->muscle = muscle; +} + +static void link3D_free(t_link3D *x) +{ + pd_unbind(&x->x_obj.ob_pd, x->x_sym); +} + +void *link3D_new(t_symbol *s, t_floatarg l, t_floatarg K, t_floatarg D, t_floatarg D2) +{ + + t_link3D *x = (t_link3D *)pd_new(link3D_class); + + x->x_sym = s; + pd_bind(&x->x_obj.ob_pd, s); + + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("position3D"), gensym("position3D2")); + + x->force1=outlet_new(&x->x_obj, 0); + x->force2=outlet_new(&x->x_obj, 0); + + x->position3Dx1 = 0; + x->position3Dx2 = 0; + x->position3Dy1 = 0; + x->position3Dy2 = 0; + x->position3Dz1 = 0; + x->position3Dz2 = 0; + + x->raideur = K; + x->viscosite = D; + x->longueur = l; + + x->D2 = D2; + + x->Lmin= 0; + x->Lmax= 10000; + + x->distance_old = x->longueur; + + x->muscle = 1; + + return (void *)x; +} + +void link3D_setup(void) +{ + + link3D_class = class_new(gensym("link3D"), + (t_newmethod)link3D_new, + (t_method)link3D_free, + sizeof(t_link3D), + CLASS_DEFAULT, A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + + class_addcreator((t_newmethod)link3D_new, gensym("lia3D"), A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + + class_addbang(link3D_class, link3D_bang); + class_addmethod(link3D_class, (t_method)link3D_reset, gensym("reset"), 0); + class_addmethod(link3D_class, (t_method)link3D_resetL, gensym("resetL"), 0); + class_addmethod(link3D_class, (t_method)link3D_resetF, gensym("resetF"), 0); + class_addmethod(link3D_class, (t_method)link3D_setD, gensym("setD"), A_DEFFLOAT, 0); + class_addmethod(link3D_class, (t_method)link3D_setD2, gensym("setD2"), A_DEFFLOAT, 0); + class_addmethod(link3D_class, (t_method)link3D_setK, gensym("setK"), A_DEFFLOAT, 0); + class_addmethod(link3D_class, (t_method)link3D_setL, gensym("setL"), A_DEFFLOAT, 0); + class_addmethod(link3D_class, (t_method)link3D_Lmin, gensym("setLmin"), A_DEFFLOAT, 0); + class_addmethod(link3D_class, (t_method)link3D_Lmax, gensym("setLmax"), A_DEFFLOAT, 0); + class_addmethod(link3D_class, (t_method)link3D_muscle, gensym("setM"), A_DEFFLOAT, 0); + class_addmethod(link3D_class, (t_method)link3D_position3D, gensym("position3D"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + class_addmethod(link3D_class, (t_method)link3D_position3D2, gensym("position3D2"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + +} diff --git a/src/mass.c b/src/mass.c new file mode 100755 index 0000000..de1a331 --- /dev/null +++ b/src/mass.c @@ -0,0 +1,186 @@ +#include "m_pd.h" +#include "math.h" + +#define max(a,b) ( ((a) > (b)) ? (a) : (b) ) +#define min(a,b) ( ((a) < (b)) ? (a) : (b) ) + + +static t_class *mass_class; + +typedef struct _mass { + t_object x_obj; + t_float pos_old_1, pos_old_2, Xinit; + t_float force, mass, dX; + t_float minX, maxX; + t_outlet *position_new, *vitesse_out, *force_out; + t_symbol *x_sym; // receive + unsigned int x_state; // random + t_float x_f; // random + +} t_mass; + +static int makeseed(void) +{ + static unsigned int random_nextseed = 1489853723; + random_nextseed = random_nextseed * 435898247 + 938284287; + return (random_nextseed & 0x7fffffff); +} + +static float random_bang(t_mass *x) +{ + int nval; + int range = 2000000; + float rnd; + unsigned int randval = x->x_state; + x->x_state = randval = randval * 472940017 + 832416023; + nval = ((double)range) * ((double)randval) + * (1./4294967296.); + if (nval >= range) nval = range-1; + + rnd=nval; + + rnd-=1000000; + rnd=rnd/1000000.; //pour mettre entre -1 et 1; + return (rnd); +} + +void mass_minX(t_mass *x, t_floatarg f1) +{ + x->minX = f1; +} + +void mass_maxX(t_mass *x, t_floatarg f1) +{ + x->maxX = f1; +} + +void mass_float(t_mass *x, t_floatarg f1) +{ + x->force += f1; +} + +void mass_bang(t_mass *x) +{ + t_float pos_new; + + if (x->mass > 0) + pos_new = x->force/x->mass + 2*x->pos_old_1 - x->pos_old_2; + else pos_new = x->pos_old_1; + + pos_new = max(min(x->maxX, pos_new), x->minX); + + pos_new += x->dX; + + x->pos_old_1 += x->dX; // pour ne pas avoir d'inertie suplementaire du a ce deplacement + + outlet_float(x->vitesse_out, x->pos_old_1 - x->pos_old_2); + outlet_float(x->force_out, x->force); + outlet_float(x->position_new, pos_new); + + x->pos_old_2 = x->pos_old_1; + x->pos_old_1 = pos_new; + +// x->force = 0; + + x->force = random_bang(x)*1e-25; // avoiding denormal problem by adding low amplitude noise + + x->dX = 0; + +} + +void mass_reset(t_mass *x) +{ + x->pos_old_2 = x->Xinit; + x->pos_old_1 = x->Xinit; + + x->force=0; + + outlet_float(x->position_new, x->Xinit); +} + +void mass_resetF(t_mass *x) +{ + x->force=0; + +} + +void mass_dX(t_mass *x, t_float posX) +{ + x->dX += posX; +} + +void mass_setX(t_mass *x, t_float posX) +{ + x->pos_old_2 = posX; // clear history for stability (instability) problem + x->pos_old_1 = posX; + + x->force=0; + + outlet_float(x->position_new, posX); +} + +void mass_loadbang(t_mass *x) +{ + outlet_float(x->position_new, x->Xinit); +} + +void mass_set_mass(t_mass *x, t_float mass) +{ + x->mass=mass; +} + +static void mass_free(t_mass *x) +{ + pd_unbind(&x->x_obj.ob_pd, x->x_sym); +} + +void *mass_new(t_symbol *s, t_floatarg M, t_floatarg X) +{ + + t_mass *x = (t_mass *)pd_new(mass_class); + + x->x_sym = s; + pd_bind(&x->x_obj.ob_pd, s); + + x->position_new=outlet_new(&x->x_obj, 0); + x->force_out=outlet_new(&x->x_obj, 0); + x->vitesse_out=outlet_new(&x->x_obj, 0); + + x->Xinit=X; + + x->pos_old_1 = X; + x->pos_old_2 = X; + x->force=0; + x->mass=M; + + x->minX = -100000; + x->maxX = 100000; + + if (x->mass<=0) x->mass=1; + + makeseed(); + + return (void *)x; +} + +void mass_setup(void) +{ + + mass_class = class_new(gensym("mass"), + (t_newmethod)mass_new, + (t_method)mass_free, + sizeof(t_mass), + CLASS_DEFAULT, A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT,0); + class_addcreator((t_newmethod)mass_new, gensym("masse"), A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT,0); + class_addfloat(mass_class, mass_float); + class_addbang(mass_class, mass_bang); + class_addmethod(mass_class, (t_method)mass_set_mass, gensym("setM"), A_DEFFLOAT, 0); + class_addmethod(mass_class, (t_method)mass_setX, gensym("setX"), A_DEFFLOAT, 0); + class_addmethod(mass_class, (t_method)mass_dX, gensym("dX"), A_DEFFLOAT, 0); + class_addmethod(mass_class, (t_method)mass_reset, gensym("reset"), 0); + class_addmethod(mass_class, (t_method)mass_resetF, gensym("resetF"), 0); + class_addmethod(mass_class, (t_method)mass_minX, gensym("setXmin"), A_DEFFLOAT, 0); + class_addmethod(mass_class, (t_method)mass_maxX, gensym("setXmax"), A_DEFFLOAT, 0); + class_addmethod(mass_class, (t_method)mass_loadbang, gensym("loadbang"), 0); +} + diff --git a/src/mass2D.c b/src/mass2D.c new file mode 100755 index 0000000..bea7cd7 --- /dev/null +++ b/src/mass2D.c @@ -0,0 +1,811 @@ +#include "m_pd.h" +#include "math.h" + +#define max(a,b) ( ((a) > (b)) ? (a) : (b) ) +#define min(a,b) ( ((a) < (b)) ? (a) : (b) ) + +static t_class *mass2D_class; + +typedef struct _mass2D { + t_object x_obj; + t_float posX_old_1, posX_old_2, posY_old_1, posY_old_2, Xinit, Yinit; + t_float forceX, forceY, VX, VY, dX, dY, onoff; + t_float mass2D, seuil, damp; + t_float minX, maxX, minY, maxY; + t_atom pos_new[2], vitesse[3], force[3]; + t_outlet *position2D_new, *vitesse_out, *force_out; + t_symbol *x_sym; // receive + unsigned int x_state; // random + t_float x_f; // random +} t_mass2D; + +static int makeseed2D(void) +{ + static unsigned int random_nextseed = 1489853723; + random_nextseed = random_nextseed * 435898247 + 938284287; + return (random_nextseed & 0x7fffffff); +} + +static float random_bang2D(t_mass2D *x) +{ + int nval; + int range = 2000000; + float rnd; + unsigned int randval = x->x_state; + x->x_state = randval = randval * 472940017 + 832416023; + nval = ((double)range) * ((double)randval) + * (1./4294967296.); + if (nval >= range) nval = range-1; + + rnd=nval; + + rnd-=1000000; + rnd=rnd/1000000.; //pour mettre entre -1 et 1; + return (rnd); +} + +void mass2D_seuil(t_mass2D *x, t_floatarg f1) +{ + x->seuil = f1; +} + +void mass2D_on(t_mass2D *x) +{ + x->onoff = 1; +} + +void mass2D_off(t_mass2D *x) +{ + x->onoff = 0; +} + +void mass2D_minX(t_mass2D *x, t_floatarg f1) +{ + x->minX = f1; +} + +void mass2D_maxX(t_mass2D *x, t_floatarg f1) +{ + x->maxX = f1; +} + +void mass2D_minY(t_mass2D *x, t_floatarg f1) +{ + x->minY = f1; +} + +void mass2D_maxY(t_mass2D *x, t_floatarg f1) +{ + x->maxY = f1; +} + +void mass2D_force(t_mass2D *x, t_floatarg f1, t_floatarg f2) +{ + x->forceX = x->forceX+f1; + x->forceY = x->forceY+f2; +} + +void mass2D_displace(t_mass2D *x, t_floatarg f1, t_floatarg f2) +{ + x->dX += f1; + x->dY += f2; +} + +void mass2D_damp(t_mass2D *x, t_floatarg f1) +{ + x->damp = f1; +} + +void mass2D_dX(t_mass2D *x, t_floatarg f1) +{ + x->dX += f1; +} + +void mass2D_dY(t_mass2D *x, t_floatarg f1) +{ + x->dY += f1; +} + +void mass2D_bang(t_mass2D *x) +{ + t_float posX_new, posY_new, vX=1, vY=1; + if (x->onoff != 0) + { + + if (x->seuil > 0) + { + if (x->posY_old_1 == x->minY) // si on est en dehors de la structure -> frottement sec sur les bords + { + if (fabs(x->forceX)<=(x->seuil * -(x->forceY))) + vX = 0; // on est a l'interieur du cone de frotement, + } + + if (x->posY_old_1 == x->maxY) // si on est en dehors de la structure -> frottement sec sur les bords + { + if (fabs(x->forceX)<=(x->seuil * (x->forceY))) + vX = 0; // on est a l'interieur du cone de frotement, + } + + if (x->posX_old_1 == x->minX) // si on est en dehors de la structure -> frottement sec sur les bords + { + if (fabs(x->forceX)<=(x->seuil * -(x->forceY))) + vY = 0; // on est a l'interieur du cone de frotement, + } + + if (x->posX_old_1 == x->maxX) // si on est en dehors de la structure -> frottement sec sur les bords + { + if (fabs(x->forceX)<=(x->seuil * (x->forceY))) + vY = 0; // on est a l'interieur du cone de frotement, + } + } + + x->forceX += x->damp * ((x->posX_old_2)-(x->posX_old_1)); + x->forceY += x->damp * ((x->posY_old_2)-(x->posY_old_1)); // damping + + if (x->mass2D != 0) + { + posX_new = x->forceX/x->mass2D + 2*x->posX_old_1 - x->posX_old_2; + posY_new = x->forceY/x->mass2D + 2*x->posY_old_1 - x->posY_old_2; + } + else + { + posX_new = x->posX_old_1; + posY_new = x->posY_old_1; + } + + if (vX==0) + posX_new = x->posX_old_1; // on n'a pas de mv qd on est a l'interieur du cone de frotement + if (vY==0) + posY_new = x->posY_old_1; + + posX_new = max(min(posX_new, x->maxX), x->minX); + posY_new = max(min(posY_new, x->maxY), x->minY); + + posX_new += x->dX; + posY_new += x->dY; + + x->posX_old_1 += x->dX; // pour eviter l'inertie + x->posY_old_1 += x->dY; + + SETFLOAT(&(x->pos_new[0]), posX_new ); + SETFLOAT(&(x->pos_new[1]), posY_new ); + + x->posX_old_2 = x->posX_old_1; + x->posX_old_1 = posX_new; + + x->posY_old_2 = x->posY_old_1; + x->posY_old_1 = posY_new; + + SETFLOAT(&(x->force[0]), x->forceX ); + SETFLOAT(&(x->force[1]), x->forceY ); + SETFLOAT(&(x->force[2]), sqrt( (x->forceX * x->forceX) + (x->forceY * x->forceY) )); + +// x->forceX=0; +// x->forceY=0; + + x->forceX = random_bang2D(x)*1e-25; + x->forceY = random_bang2D(x)*1e-25; // avoiding denormal problem by adding low amplitude noise + + + x->dX=0; + x->dY=0; + + x->VX = x->posX_old_1 - x->posX_old_2; + x->VY = x->posY_old_1 - x->posY_old_2; + + SETFLOAT(&(x->vitesse[0]), x->VX ); + SETFLOAT(&(x->vitesse[1]), x->VY ); + SETFLOAT(&(x->vitesse[2]), sqrt( (x->VX * x->VX) + (x->VY * x->VY) )); + + outlet_anything(x->vitesse_out, gensym("velocity2D"), 3, x->vitesse); + outlet_anything(x->force_out, gensym("force2D"), 3, x->force); + outlet_anything(x->position2D_new, gensym("position2D"), 2, x->pos_new); + } +} + +void mass2D_reset(t_mass2D *x) +{ + x->posX_old_2 = x->Xinit; + x->posX_old_1 = x->Xinit; + x->forceX=0; + + x->posY_old_2 = x->Yinit; + x->posY_old_1 = x->Yinit; + x->forceY=0; + + x->VX = 0; + x->VY = 0; + + x->dX=0; + x->dY=0; + + x->seuil=0; + + x->onoff = 1; + + SETFLOAT(&(x->pos_new[0]), x->Xinit ); + SETFLOAT(&(x->pos_new[1]), x->Yinit ); + + SETFLOAT(&(x->force[0]), 0 ); + SETFLOAT(&(x->force[1]), 0 ); + SETFLOAT(&(x->force[2]), 0 ); + + SETFLOAT(&(x->vitesse[0]), 0 ); + SETFLOAT(&(x->vitesse[1]), 0 ); + SETFLOAT(&(x->vitesse[2]), 0 ); + + outlet_anything(x->vitesse_out, gensym("velocity2D"), 3, x->vitesse); + outlet_anything(x->force_out, gensym("force2D"), 3, x->force); + outlet_anything(x->position2D_new, gensym("position2D"), 2, x->pos_new); +} + +void mass2D_resetf(t_mass2D *x) +{ + x->dX=0; + x->dY=0; + + x->forceX=0; + x->forceY=0; +} + +void mass2D_setXY(t_mass2D *x, t_float posX, t_float posY) +{ + x->posX_old_2 = posX; + x->posX_old_1 = posX; + x->forceX=0; + + x->posY_old_2 = posY; + x->posY_old_1 = posY; + x->forceY=0; + + SETFLOAT(&(x->pos_new[0]), posX ); + SETFLOAT(&(x->pos_new[1]), posY ); + + outlet_anything(x->position2D_new, gensym("position2D"), 2, x->pos_new); +} + +void mass2D_setX(t_mass2D *x, t_float posX) +{ + x->posX_old_2 = posX; + x->posX_old_1 = posX; + x->forceX=0; + + SETFLOAT(&(x->pos_new[0]), posX ); + + outlet_anything(x->position2D_new, gensym("position2D"), 2, x->pos_new); +} + +void mass2D_setY(t_mass2D *x, t_float posY) +{ + x->posY_old_2 = posY; + x->posY_old_1 = posY; + x->forceY=0; + + SETFLOAT(&(x->pos_new[1]), posY ); + + outlet_anything(x->position2D_new, gensym("position2D"), 2, x->pos_new); +} + +void mass2D_loadbang(t_mass2D *x) +{ + outlet_anything(x->position2D_new, gensym("position2D"), 2, x->pos_new); +} + + +void mass2D_set_mass2D(t_mass2D *x, t_float mass) +{ + x->mass2D=mass; +} + +void mass2D_inter_ambient(t_mass2D *x, t_symbol *s, int argc, t_atom *argv) +{ + if (argc == 12) + // 0 : FX + // 1 : FY + // 2 : RndX + // 3 : RndY + // 4 : D2 + // 5 : rien + // 6 : Xmin + // 7 : Xmax + // 8 : Ymin + // 9 : Ymax + // 10 : dX + // 11 : dY + { + if (x->posX_old_1 > atom_getfloatarg(6, argc, argv)) + { + if (x->posX_old_1 < atom_getfloatarg(7, argc, argv)) + { + if (x->posY_old_1 > atom_getfloatarg(8, argc, argv)) + { + if (x->posY_old_1 < atom_getfloatarg(9, argc, argv)) + { + x->forceX += atom_getfloatarg(0, argc, argv); + x->forceY += atom_getfloatarg(1, argc, argv); // constant + + x->forceX += random_bang2D(x)*atom_getfloatarg(2, argc, argv); + x->forceY += random_bang2D(x)*atom_getfloatarg(3, argc, argv); // random + + x->forceX += atom_getfloatarg(4, argc, argv) * ((x->posX_old_2)-(x->posX_old_1)); + x->forceY += atom_getfloatarg(4, argc, argv) * ((x->posY_old_2)-(x->posY_old_1)); // damping + + x->dX += atom_getfloatarg(10, argc, argv); + x->dY += atom_getfloatarg(11, argc, argv); // constant + } + } + } + } + } + else + { + error("bad ambient interraction message"); + } +} + +void mass2D_inter_seg(t_mass2D *x, t_symbol *s, int argc, t_atom *argv) +{ +t_float a1, b1, c1, a2, b2, c2, a3, b3, c3, tmp; +t_float posx1, posx2, posy1, posy2; +t_float profondeur, prof_max; + + if (argc == 12) + // 0 : posx1 + // 1 : posy1 + // 2 : posx2 + // 3 : posy2 + // 4 : profondeur max + // 5 : F CT Normal + // 6 : F CT Tengentiel + // 7 : K normal + // 8 : Damp2 normal + // 9 : Damp2 tan + // 10 : displacement Normal + // 11 : d Tan + + { + posx1 = atom_getfloatarg(0, argc, argv); + posy1 = atom_getfloatarg(1, argc, argv); + posx2 = atom_getfloatarg(2, argc, argv); + posy2 = atom_getfloatarg(3, argc, argv); + + b1 = posx2 - posx1; + a1 = -posy2 + posy1; + + if (!((a1==0) & (b1==0))) + { + + tmp = sqrt((a1*a1)+(b1*b1)); // = longueur du vecteur pour renormalisation + if (tmp !=0) + { + a1 = a1/tmp; + b1 = b1/tmp; + } + else + { + a1 = 0; + b1 = 0; + } + + c1 = a1*posx1+b1*posy1; + + profondeur = ( (a1 * x->posX_old_1) + (b1 * x->posY_old_1) ) - c1; + + if ( ( profondeur < 0) & (profondeur > - atom_getfloatarg(4, argc, argv)) ) + { + a2 = b1; + b2 = -a1; + c2 = a2*posx1+b2*posy1; + if (( (a2 * x->posX_old_1) + (b2 * x->posY_old_1) ) > c2) + { + a3 = a2; + b3 = b2; + c3 = a3*posx2+b3*posy2; + if (( (a3 * x->posX_old_1) + (b3 * x->posY_old_1) ) < c3) + { + tmp = atom_getfloatarg(5, argc, argv); // force ct normal + x->forceX += tmp * a1; + x->forceY += tmp * b1; + + tmp = atom_getfloatarg(6, argc, argv); // force ct normal + x->forceX -= tmp * b1; + x->forceY -= tmp * -a1; + + tmp = atom_getfloatarg(7, argc, argv); // force K normal + tmp *= profondeur; + x->forceX -= tmp * a1; + x->forceY -= tmp * b1; + + tmp = atom_getfloatarg(8, argc, argv); // damping2 normal + tmp *= ( x->VX * a1 + x->VY * b1 ); + x->forceX -= tmp * a1 ; + x->forceY -= tmp * b1 ; + + tmp = atom_getfloatarg(9, argc, argv); // damping2 tangentiel + tmp *= ( x->VX * b1 - x->VY * a1 ); + x->forceX -= tmp * b1 ; + x->forceY -= tmp * -a1 ; + + tmp = atom_getfloatarg(10, argc, argv); // displacement normal + x->dX += tmp * a1 ; + x->dY += tmp * b1 ; + + tmp = atom_getfloatarg(11, argc, argv); // displacement tengentiel + x->dX -= tmp * b1 ; + x->dY -= tmp * -a1 ; + } + } + } + } + } + else + { + error("bad interact_2D_segment message"); + } +} + +void mass2D_inter_line(t_mass2D *x, t_symbol *s, int argc, t_atom *argv) +{ +t_float a1, b1, c1, tmp; +t_float posx1, posx2, posy1, posy2; +t_float profondeur, prof_max; + + if (argc == 12) + // 0 : posx1 + // 1 : posy1 + // 2 : posx2 + // 3 : posy2 + // 4 : profondeur max + // 5 : F CT Normal + // 6 : F CT Tengentiel + // 7 : K normal + // 8 : Damp2 normal + // 9 : Damp2 tan + // 10 : d normal + // 11 : d tengential + { + posx1 = atom_getfloatarg(0, argc, argv); + posy1 = atom_getfloatarg(1, argc, argv); + posx2 = atom_getfloatarg(2, argc, argv); + posy2 = atom_getfloatarg(3, argc, argv); + + b1 = posx2 - posx1; + a1 = -posy2 + posy1; + + if (!((a1==0) & (b1==0))) + { + tmp = sqrt((a1*a1)+(b1*b1)); // = longueur du vecteur pour renormalisation + a1 = a1/tmp; // composante X de la normal + b1 = b1/tmp; // composante Y de la normal + c1 = a1*posx1+b1*posy1; // + + profondeur = ( (a1 * x->posX_old_1) + (b1 * x->posY_old_1) ) - c1; + if ( ( profondeur < 0) & (profondeur > - atom_getfloatarg(4, argc, argv)) ) + { + tmp = atom_getfloatarg(5, argc, argv); // force ct normal + x->forceX += tmp * a1; + x->forceY += tmp * b1; + + tmp = atom_getfloatarg(6, argc, argv); // force ct tengentiel + x->forceX -= tmp * b1; + x->forceY -= tmp * -a1; + + tmp = atom_getfloatarg(7, argc, argv); // force K normal + tmp *= profondeur ; + x->forceX -= tmp * a1; + x->forceY -= tmp * b1; + + tmp = atom_getfloatarg(8, argc, argv); // damping2 normal + tmp *= ( x->VX * a1 + x->VY * b1 ) ; + x->forceX -= tmp * a1 ; + x->forceY -= tmp * b1 ; + + tmp = atom_getfloatarg(9, argc, argv); // damping2 tangentiel + tmp *= ( x->VX * b1 - x->VY * a1 ); + x->forceX -= tmp * b1 ; + x->forceY -= tmp * -a1 ; + + tmp = atom_getfloatarg(10, argc, argv); // d normal + x->dX += tmp * a1; + x->dY += tmp * b1; + + tmp = atom_getfloatarg(11, argc, argv); // d tangentiel + x->dX -= tmp * b1; + x->dY -= tmp * -a1; + } + } + } + else + { + error("bad interact_2D_line message"); + } +} + +void mass2D_inter_circle(t_mass2D *x, t_symbol *s, int argc, t_atom *argv) +{ +t_float posx1, posy1, Nx, Ny, dx, dy, distance, Dmax, tmp; +t_float deltaX_old, deltaY_old, distance_old ; +t_float fnx=0, fny=0; +t_float ftx=0, fty=0; + + if (argc == 20) + // 0 : Xcentre + // 1 : Ycendre + // 2 : Rmin + // 3 : Rmax + // 4 : F normal + // 5 : F tangentiel + // 6 : K normal + // 7 : K tengentiel + // 8 : F normal proportionel a 1/R + // 9 : F tengentiel proportionel a 1/R + // 10 : Damp2 normal + // 11 : Damp2 tan + // 12 : deplacement N proportionel a 1/R + // 13 : deplacement tengentiel proportionel a 1/R + // 14 : position ancienne de l'interacteur en X + // 15 : position abcienne de l'interacteur en Y + // 16 : damping de liaison + // 17 : F normal proportionel a 1/R*R + // 18 : normal displacement + // 19 : tengential displacement + + { + posx1 = atom_getfloatarg(0, argc, argv); + posy1 = atom_getfloatarg(1, argc, argv); + Nx = (x->posX_old_1)-posx1; // vecteur deplacement X + Ny = (x->posY_old_1)-posy1; // vecteur deplacement Y + + distance = sqrt((Nx * Nx)+(Ny * Ny)); // distance entre le centre de l'interaction, et le pts + + Dmax= atom_getfloatarg(3, argc, argv); // distance max de l'interaction + if ( (distance > atom_getfloatarg(2, argc, argv)) & (distance < Dmax) ) + { + Nx = Nx/distance; // composante X de la normal (normalisé) + Ny = Ny/distance; // composante Y de la normal. + + tmp = atom_getfloatarg(4, argc, argv); // force constante normal +// x->forceX += tmp * Nx; +// x->forceY += tmp * Ny; + fnx +=tmp; +// fny +=tmp; + + tmp = atom_getfloatarg(5, argc, argv); // force constante tengentiel +// x->forceX += tmp * Ny; +// x->forceY += tmp * -Nx; + ftx +=tmp; +// fty +=tmp; + + tmp = atom_getfloatarg(6, argc, argv); // force variable (K) normal + tmp *= ( Dmax-distance ); +// x->forceX += tmp * Nx ; +// x->forceY += tmp * Ny ; + fnx +=tmp; +// fny +=tmp; + + tmp = atom_getfloatarg(7, argc, argv); // force variable (K) tengentiel + tmp *= ( Dmax-distance ); +// x->forceX += tmp * Ny ; +// x->forceY += tmp * -Nx ; + ftx +=tmp; +// fty +=tmp; + + tmp = atom_getfloatarg(8, argc, argv); // force normal proportionel a 1/r + if (distance != 0) + { + tmp /= distance; +// x->forceX += tmp * Nx ; +// x->forceY += tmp * Ny ; + fnx +=tmp; +// fny +=tmp; + } + + tmp = atom_getfloatarg(9, argc, argv); // force tengentiel proportionel a 1/r + if (distance != 0) + { + tmp /= distance; +// x->forceX -= tmp * Ny ; +// x->forceY -= tmp * -Nx ; + ftx -=tmp; +// fty -=tmp; + } + + tmp = atom_getfloatarg(10, argc, argv); // damping2 normal + tmp *= ( x->VX * Nx + x->VY * Ny ); +// x->forceX -= tmp * Nx ; +// x->forceY -= tmp * Ny ; + fnx -=tmp; +// fny -=tmp; + + tmp = atom_getfloatarg(11, argc, argv); // damping2 tangentiel + tmp *= ( x->VX * Ny - x->VY * Nx ); +// x->forceX -= tmp * Ny ; +// x->forceY -= tmp * -Ny ; + ftx -=tmp; +// fty -=tmp; + + tmp = atom_getfloatarg(12, argc, argv); // d normal + if (distance != 0) + { + tmp /= distance; + x->dX += tmp * Nx ; + x->dY += tmp * Ny ; + } + + tmp = atom_getfloatarg(13, argc, argv); // d tangentiel + if (distance != 0) + { + tmp /= distance; + + x->dX -= tmp * Ny ; + x->dY -= tmp * -Nx ; + } + + tmp = atom_getfloatarg(16, argc, argv); // damping de liaison + if (tmp!= 0) + { + deltaX_old = atom_getfloatarg(14, argc, argv) - x->posX_old_2; + deltaY_old = atom_getfloatarg(15, argc, argv) - x->posY_old_2; + distance_old = sqrt( (deltaX_old * deltaX_old) + (deltaY_old * deltaY_old)); + +// x->forceX -= Nx * tmp * (distance - distance_old); +// x->forceY -= Ny * tmp * (distance - distance_old); + + tmp *= (distance - distance_old); + fnx -=tmp; +// fny -=tmp; + } + + tmp = atom_getfloatarg(17, argc, argv); // force normal proportionel a 1/r2 + if (distance != 0) + { + tmp /= (distance*distance); +// x->forceX -= tmp * Nx; +// x->forceY -= tmp * Ny; + fnx +=tmp; +// fny +=tmp; + } + + tmp = atom_getfloatarg(18, argc, argv); // deplacement constante normal + x->dX += tmp * Nx; + x->dY += tmp * Ny; + + tmp = atom_getfloatarg(19, argc, argv); // deplacement constante tengentiel + x->dX -= tmp * Ny; + x->dY -= tmp * -Nx; + + x->forceX += fnx * Nx + ftx * Ny; // optimisation, but does not change anything... + x->forceY += fnx * Ny - ftx * Nx; + } + } + else + { + error("bad interact_2D_circle message"); + } +} + +void *mass2D_new(t_symbol *s, int argc, t_atom *argv) +{ + + t_mass2D *x = (t_mass2D *)pd_new(mass2D_class); + + x->x_sym = atom_getsymbolarg(0, argc, argv); + x->x_state = makeseed2D(); + + pd_bind(&x->x_obj.ob_pd, atom_getsymbolarg(0, argc, argv)); + + x->position2D_new=outlet_new(&x->x_obj, 0); + x->force_out=outlet_new(&x->x_obj, 0); + x->vitesse_out=outlet_new(&x->x_obj, 0); + + x->forceX=0; + x->forceY=0; + + if (argc >= 2) + x->mass2D = atom_getfloatarg(1, argc, argv) ; + else + x->mass2D = 1; + + x->onoff = 1; + + x->VX = 0; + x->VY = 0; + + x->dX=0; + x->dY=0; + + if (argc >= 3) + x->Xinit = atom_getfloatarg(2, argc, argv); + else + x->Xinit = 0 ; + + x->posX_old_1 = x->Xinit ; + x->posX_old_2 = x->Xinit; + SETFLOAT(&(x->pos_new[0]), x->Xinit); + + if (argc >= 4) + x->Yinit = atom_getfloatarg(3, argc, argv); + else + x->Yinit = 0 ; + + x->posY_old_1 = x->Yinit ; + x->posY_old_2 = x->Yinit; + SETFLOAT(&(x->pos_new[1]), x->Yinit); + + if (argc >= 5) + x->minX = atom_getfloatarg(4, argc, argv) ; + else + x->minX = -100000; + + if (argc >= 6) + x->maxX = atom_getfloatarg(5, argc, argv) ; + else + x->maxX = 100000; + + if (argc >= 7) + x->minY = atom_getfloatarg(6, argc, argv) ; + else + x->minY = -100000; + + if (argc >= 8) + x->maxY = atom_getfloatarg(7, argc, argv) ; + else + x->maxY = 100000; + + if (argc >= 9) + x->seuil = atom_getfloatarg(8, argc, argv) ; + else + x->seuil = 0; + + if (argc >= 10) + x->damp = atom_getfloatarg(9, argc, argv) ; + else + x->damp = 0; + + return (x); +} + +static void mass2D_free(t_mass2D *x) +{ + pd_unbind(&x->x_obj.ob_pd, x->x_sym); +} + +void mass2D_setup(void) +{ + + mass2D_class = class_new(gensym("mass2D"), + (t_newmethod)mass2D_new, + (t_method)mass2D_free, sizeof(t_mass2D), + CLASS_DEFAULT, A_GIMME, 0); + + class_addcreator((t_newmethod)mass2D_new, gensym("masse2D"), A_GIMME, 0); + + class_addbang(mass2D_class, mass2D_bang); + + class_addmethod(mass2D_class, (t_method)mass2D_force, gensym("force2D"),A_DEFFLOAT, A_DEFFLOAT, 0); + class_addmethod(mass2D_class, (t_method)mass2D_displace, gensym("dXY"),A_DEFFLOAT, A_DEFFLOAT, 0); + class_addmethod(mass2D_class, (t_method)mass2D_dX, gensym("dX"),A_DEFFLOAT, 0); + class_addmethod(mass2D_class, (t_method)mass2D_dY, gensym("dY"),A_DEFFLOAT, 0); + + class_addmethod(mass2D_class, (t_method)mass2D_inter_ambient, gensym("interactor_ambient_2D"), A_GIMME, 0); + class_addmethod(mass2D_class, (t_method)mass2D_inter_line, gensym("interactor_line_2D"), A_GIMME, 0); + class_addmethod(mass2D_class, (t_method)mass2D_inter_seg, gensym("interactor_segment_2D"), A_GIMME, 0); + class_addmethod(mass2D_class, (t_method)mass2D_inter_circle, gensym("interactor_circle_2D"), A_GIMME, 0); + + class_addmethod(mass2D_class, (t_method)mass2D_seuil, gensym("setT"), A_DEFFLOAT, 0); + class_addmethod(mass2D_class, (t_method)mass2D_set_mass2D, gensym("setM"), A_DEFFLOAT, 0); + class_addmethod(mass2D_class, (t_method)mass2D_setX, gensym("setX"), A_DEFFLOAT, 0); + class_addmethod(mass2D_class, (t_method)mass2D_setY, gensym("setY"), A_DEFFLOAT, 0); + class_addmethod(mass2D_class, (t_method)mass2D_minX, gensym("setXmin"), A_DEFFLOAT, 0); + class_addmethod(mass2D_class, (t_method)mass2D_minY, gensym("setYmin"), A_DEFFLOAT, 0); + class_addmethod(mass2D_class, (t_method)mass2D_maxX, gensym("setXmax"), A_DEFFLOAT, 0); + class_addmethod(mass2D_class, (t_method)mass2D_maxY, gensym("setYmax"), A_DEFFLOAT, 0); + class_addmethod(mass2D_class, (t_method)mass2D_setXY, gensym("setXY"), A_DEFFLOAT, A_DEFFLOAT, 0); + class_addmethod(mass2D_class, (t_method)mass2D_damp, gensym("setD"), A_DEFFLOAT, 0); + class_addmethod(mass2D_class, (t_method)mass2D_on, gensym("on"), 0); + class_addmethod(mass2D_class, (t_method)mass2D_off, gensym("off"), 0); + class_addmethod(mass2D_class, (t_method)mass2D_reset, gensym("reset"), 0); + class_addmethod(mass2D_class, (t_method)mass2D_resetf, gensym("resetF"), 0); + class_addmethod(mass2D_class, (t_method)mass2D_loadbang, gensym("loadbang"), 0); + +} diff --git a/src/mass3D.c b/src/mass3D.c new file mode 100755 index 0000000..e8e362b --- /dev/null +++ b/src/mass3D.c @@ -0,0 +1,1095 @@ +#include "m_pd.h" +#include "math.h" + +#define max(a,b) ( ((a) > (b)) ? (a) : (b) ) +#define min(a,b) ( ((a) < (b)) ? (a) : (b) ) + +static t_class *mass3D_class; + +typedef struct _mass3D { + t_object x_obj; + t_float posX_old_1, posX_old_2, posY_old_1, posY_old_2, posZ_old_1, posZ_old_2; + t_float Xinit, Yinit, Zinit, forceX, forceY, forceZ, VX, VY, VZ, dX, dY, dZ; + t_float mass3D, seuil, onoff, damp; + t_atom pos_new[3], vitesse[4], force[4]; + t_float minX, maxX, minY, maxY, minZ, maxZ; + t_outlet *position3D_new, *vitesse_out, *force_out; + t_symbol *x_sym; // receive + unsigned int x_state; // random + t_float x_f; // random +} t_mass3D; + +static int makeseed3D(void) +{ + static unsigned int random_nextseed = 1489853723; + random_nextseed = random_nextseed * 435898247 + 938284287; + return (random_nextseed & 0x7fffffff); +} + +static float random_bang3D(t_mass3D *x) +{ + int nval; + int range = 2000000; + float rnd; + unsigned int randval = x->x_state; + x->x_state = randval = randval * 472940017 + 832416023; + nval = ((double)range) * ((double)randval) + * (1./4294967296.); + if (nval >= range) nval = range-1; + + rnd=nval; + + rnd-=1000000; + rnd=rnd/1000000.; //pour mettre entre -1 et 1; + return (rnd); +} + +void mass3D_on(t_mass3D *x) +{ + x->onoff = 1; +} + +void mass3D_off(t_mass3D *x) +{ + x->onoff = 0; +} + +void mass3D_minX(t_mass3D *x, t_floatarg f1) +{ + x->minX = f1; +} + +void mass3D_maxX(t_mass3D *x, t_floatarg f1) +{ + x->maxX = f1; +} + +void mass3D_minY(t_mass3D *x, t_floatarg f1) +{ + x->minY = f1; +} + +void mass3D_maxY(t_mass3D *x, t_floatarg f1) +{ + x->maxY = f1; +} + +void mass3D_minZ(t_mass3D *x, t_floatarg f1) +{ + x->minZ = f1; +} + +void mass3D_maxZ(t_mass3D *x, t_floatarg f1) +{ + x->maxZ = f1; +} + +void mass3D_seuil(t_mass3D *x, t_floatarg f1) +{ + x->seuil = f1; +} + +void mass3D_damp(t_mass3D *x, t_floatarg f1) +{ + x->damp = f1; +} + +void mass3D_loadbang(t_mass3D *x, t_float posZ) +{ + outlet_anything(x->position3D_new, gensym("position3D"), 3, x->pos_new); +} + +void mass3D_setX(t_mass3D *x, t_float posX) +{ + + x->posX_old_2 = posX; + x->posX_old_1 = posX; + x->forceX=0; + + SETFLOAT(&(x->pos_new[0]), posX); + + outlet_anything(x->position3D_new, gensym("position3D"), 3, x->pos_new); + +} + +void mass3D_setY(t_mass3D *x, t_float posY) +{ + x->posY_old_2 = posY; + x->posY_old_1 = posY; + x->forceY=0; + + SETFLOAT(&(x->pos_new[1]), posY); + + outlet_anything(x->position3D_new, gensym("position3D"), 3, x->pos_new); + +} + +void mass3D_setZ(t_mass3D *x, t_float posZ) +{ + x->posZ_old_2 = posZ; + x->posZ_old_1 = posZ; + x->forceZ=0; + + SETFLOAT(&(x->pos_new[2]), posZ); + + outlet_anything(x->position3D_new, gensym("position3D"), 3, x->pos_new); + +} + +void mass3D_setXYZ(t_mass3D *x, t_float posX, t_float posY, t_float posZ) +{ + + x->posX_old_2 = posX; + x->posX_old_1 = posX; + x->forceX=0; + + x->posY_old_2 = posY; + x->posY_old_1 = posY; + x->forceY=0; + + x->posZ_old_2 = posZ; + x->posZ_old_1 = posZ; + x->forceZ=0; + + SETFLOAT(&(x->pos_new[0]), posX); + SETFLOAT(&(x->pos_new[1]), posY); + SETFLOAT(&(x->pos_new[2]), posZ); + + outlet_anything(x->position3D_new, gensym("position3D"), 3, x->pos_new); +} + +void mass3D_set_mass3D(t_mass3D *x, t_float mass) +{ + x->mass3D=mass; +} + + +void mass3D_force(t_mass3D *x, t_floatarg f1, t_floatarg f2, t_floatarg f3) +{ + x->forceX += f1; + x->forceY += f2; + x->forceZ += f3; +} + +void mass3D_dXYZ(t_mass3D *x, t_floatarg f1, t_floatarg f2, t_floatarg f3) +{ + x->dX += f1; + x->dY += f2; + x->dZ += f3; +} + +void mass3D_dX(t_mass3D *x, t_floatarg f1 ) +{ + x->dX += f1; +} + +void mass3D_dY(t_mass3D *x, t_floatarg f1 ) +{ + x->dY += f1; +} + +void mass3D_dZ(t_mass3D *x, t_floatarg f1 ) +{ + x->dZ += f1; +} + +void mass3D_bang(t_mass3D *x) +{ + t_float posX_new, posY_new, posZ_new, vX=1, vY=1, vZ=1; + if (x->onoff != 0) + { + + if (x->seuil > 0) + { + if (x->posZ_old_1 == x->minZ) // si on est en dehors de la structure -> frottement sec sur les bords + { + if (sqrt(x->forceX*x->forceX + x->forceY*x->forceY)<=(x->seuil * -(x->forceZ))) + { + vX = 0; // on est a l'interieur du cone de frotement, + vY = 0; // on est a l'interieur du cone de frotement, + } + } + + if (x->posZ_old_1 == x->maxZ) // si on est en dehors de la structure -> frottement sec sur les bords + { + if (sqrt(x->forceX*x->forceX + x->forceY*x->forceY)<=(x->seuil * (x->forceZ))) + { + vX = 0; // on est a l'interieur du cone de frotement, + vY = 0; // on est a l'interieur du cone de frotement, + } + } + + if (x->posY_old_1 == x->minY) // si on est en dehors de la structure -> frottement sec sur les bords + { + if (sqrt(x->forceX*x->forceX + x->forceZ*x->forceZ)<=(x->seuil * -(x->forceY))) + { + vX = 0; // on est a l'interieur du cone de frotement, + vZ = 0; // on est a l'interieur du cone de frotement, + } + } + + if (x->posY_old_1 == x->maxY) // si on est en dehors de la structure -> frottement sec sur les bords + { + if (sqrt(x->forceX*x->forceX + x->forceZ*x->forceZ)<=(x->seuil * (x->forceY))) + { + vX = 0; // on est a l'interieur du cone de frotement, + vZ = 0; // on est a l'interieur du cone de frotement, + } + } + + if (x->posX_old_1 == x->minX) // si on est en dehors de la structure -> frottement sec sur les bords + { + if (sqrt(x->forceY*x->forceY + x->forceZ*x->forceZ)<=(x->seuil * -(x->forceX))) + { + vY = 0; // on est a l'interieur du cone de frotement, + vZ = 0; // on est a l'interieur du cone de frotement, + } + } + + if (x->posX_old_1 == x->maxX) // si on est en dehors de la structure -> frottement sec sur les bords + { + if (sqrt(x->forceY*x->forceY + x->forceZ*x->forceZ)<=(x->seuil * (x->forceX))) + { + vY = 0; // on est a l'interieur du cone de frotement, + vZ = 0; // on est a l'interieur du cone de frotement, + } + } + } + + x->forceX += x->damp * ((x->posX_old_2)-(x->posX_old_1)); + x->forceY += x->damp * ((x->posY_old_2)-(x->posY_old_1)); // damping + x->forceZ += x->damp * ((x->posZ_old_2)-(x->posZ_old_1)); // damping + + if (!(x->mass3D == 0)) + { + posX_new = x->forceX/x->mass3D + 2*x->posX_old_1 - x->posX_old_2; + posY_new = x->forceY/x->mass3D + 2*x->posY_old_1 - x->posY_old_2; + posZ_new = x->forceZ/x->mass3D + 2*x->posZ_old_1 - x->posZ_old_2; + } + else + { + posX_new = x->posX_old_1; + posY_new = x->posY_old_1; + posZ_new = x->posY_old_1; + } + + + if (vX==0) + posX_new = x->posX_old_1; // on n'a pas de mv qd on est a l'interieur du cone de frotement + if (vY==0) + posY_new = x->posY_old_1; + if (vZ==0) + posZ_new = x->posZ_old_1; + + posX_new = max(min(x->maxX, posX_new), x->minX); + posY_new = max(min(x->maxY, posY_new), x->minY); + posZ_new = max(min(x->maxZ, posZ_new), x->minZ); + + + posX_new += x->dX; + posY_new += x->dY; + posZ_new += x->dZ; + + x->posX_old_1 += x->dX; + x->posY_old_1 += x->dY; + x->posZ_old_1 += x->dZ; + + SETFLOAT(&(x->pos_new[0]), posX_new ); + SETFLOAT(&(x->pos_new[1]), posY_new ); + SETFLOAT(&(x->pos_new[2]), posZ_new ); + + x->posX_old_2 = x->posX_old_1; + x->posX_old_1 = posX_new; + + x->posY_old_2 = x->posY_old_1; + x->posY_old_1 = posY_new; + + x->posZ_old_2 = x->posZ_old_1; + x->posZ_old_1 = posZ_new; + + SETFLOAT(&(x->force[0]), x->forceX ); + SETFLOAT(&(x->force[1]), x->forceY ); + SETFLOAT(&(x->force[2]), x->forceZ ); + SETFLOAT(&(x->force[3]), sqrt( (x->forceX * x->forceX) + (x->forceY * x->forceY) + (x->forceZ * x->forceZ) )); + +// x->forceX=0; +// x->forceY=0; +// x->forceZ=0; + + x->forceX = random_bang3D(x)*1e-25; + x->forceY = random_bang3D(x)*1e-25; // avoiding denormal problem by adding low amplitude noise + x->forceZ = random_bang3D(x)*1e-25; + + + x->dX=0; + x->dY=0; + x->dZ=0; + + x->VX = x->posX_old_1 - x->posX_old_2; + x->VY = x->posY_old_1 - x->posY_old_2; + x->VZ = x->posZ_old_1 - x->posZ_old_2; + + SETFLOAT(&(x->vitesse[0]), x->VX ); + SETFLOAT(&(x->vitesse[1]), x->VY ); + SETFLOAT(&(x->vitesse[2]), x->VZ ); + SETFLOAT(&(x->vitesse[3]), sqrt( (x->VX * x->VX) + (x->VY * x->VY) + (x->VZ * x->VZ) )); + + outlet_anything(x->vitesse_out, gensym("velocity3D"), 4, x->vitesse); + outlet_anything(x->force_out, gensym("force3D"), 4, x->force); + outlet_anything(x->position3D_new, gensym("position3D"), 3, x->pos_new); + } +} + +void mass3D_reset(t_mass3D *x) +{ + + x->posX_old_2 = x->Xinit; + x->posX_old_1 = x->Xinit; + x->forceX=0; + + x->posY_old_2 = x->Yinit; + x->posY_old_1 = x->Yinit; + x->forceY=0; + + x->posZ_old_2 = x->Zinit; + x->posZ_old_1 = x->Zinit; + x->forceZ=0; + + x->VX = 0; + x->VY = 0; + x->VZ = 0; + + x->dX=0; + x->dY=0; + x->dZ=0; + + x->seuil=0; + + x->onoff = 1; + + SETFLOAT(&(x->pos_new[0]), x->Xinit ); + SETFLOAT(&(x->pos_new[1]), x->Yinit ); + SETFLOAT(&(x->pos_new[2]), x->Zinit ); + + SETFLOAT(&(x->force[0]), 0 ); + SETFLOAT(&(x->force[1]), 0 ); + SETFLOAT(&(x->force[2]), 0 ); + SETFLOAT(&(x->force[3]), 0 ); + + SETFLOAT(&(x->vitesse[0]), 0 ); + SETFLOAT(&(x->vitesse[1]), 0 ); + SETFLOAT(&(x->vitesse[2]), 0 ); + SETFLOAT(&(x->vitesse[3]), 0 ); + + outlet_anything(x->vitesse_out, gensym("velocity3D"), 4, x->vitesse); + outlet_anything(x->force_out, gensym("force3D"), 4, x->force); + outlet_anything(x->position3D_new, gensym("position3D"), 3, x->pos_new); + +} + + +void mass3D_resetf(t_mass3D *x) +{ + x->forceX=0; + x->forceY=0; + x->forceZ=0; + + x->dX=0; + x->dY=0; + x->dZ=0; +} + +void mass3D_inter_ambient(t_mass3D *x, t_symbol *s, int argc, t_atom *argv) +{ + t_float tmp; + + if (argc == 17) + // 0 : FX + // 1 : FY + // 2 : FZ + // 3 : RndX + // 4 : RndY + // 5 : RndZ + // 6 : D2 + // 7 : rien + // 8 : Xmin + // 9 : Xmax + // 10 : Ymin + // 11 : Ymax + // 12 : Zmin + // 13 : Zmax + // 14 : dX + // 15 : dY + // 16 : dZ + { + if (x->posX_old_1 > atom_getfloatarg(8, argc, argv)) + { + if (x->posX_old_1 < atom_getfloatarg(9, argc, argv)) + { + if (x->posY_old_1 > atom_getfloatarg(10, argc, argv)) + { + if (x->posY_old_1 < atom_getfloatarg(11, argc, argv)) + { + if (x->posZ_old_1 > atom_getfloatarg(12, argc, argv)) + { + if (x->posZ_old_1 < atom_getfloatarg(13, argc, argv)) + { + x->forceX += atom_getfloatarg(0, argc, argv); + x->forceY += atom_getfloatarg(1, argc, argv); // constant + x->forceZ += atom_getfloatarg(2, argc, argv); // constant + + x->forceX += random_bang3D(x)*atom_getfloatarg(3, argc, argv); + x->forceY += random_bang3D(x)*atom_getfloatarg(4, argc, argv); // random + x->forceZ += random_bang3D(x)*atom_getfloatarg(5, argc, argv); // random + + tmp = atom_getfloatarg(6, argc, argv); + if (tmp != 0) + { + x->forceX += tmp * ((x->posX_old_2)-(x->posX_old_1)); + x->forceY += tmp * ((x->posY_old_2)-(x->posY_old_1)); // damping + x->forceZ += tmp * ((x->posZ_old_2)-(x->posZ_old_1)); // damping + } + + x->dX += atom_getfloatarg(14, argc, argv); + x->dY += atom_getfloatarg(15, argc, argv); // constant + x->dZ += atom_getfloatarg(16, argc, argv); // constant + } + } + } + } + } + } + } + else + { + error("bad ambient interraction message"); + } +} + +void mass3D_inter_plane(t_mass3D *x, t_symbol *s, int argc, t_atom *argv) +{ + t_float a, b, c, d, profondeur, distance, tmp, profondeur_old; + + if (argc == 12) + // 0 : Xvector + // 1 : Yvector + // 2 : Zvector + // 3 : Xcenter + // 4 : Ycenter + // 5 : Zcenter + // 6 : FNCt + // 7 : KN + // 8 : damping de liaison (profondeur) + // 9 : Profondeur maximum + // 10 : deplacement normal X + // 11 : deplacement proportionel a P + + { + +// ax+by+cz-d=0 +// a = Xvector / |V| +// b = Yvector ... +// d est tel que aXcenter +bYcenter + cYcenter = d + + a = atom_getfloatarg(0, argc, argv); + b = atom_getfloatarg(1, argc, argv); + c = atom_getfloatarg(2, argc, argv); + + tmp = sqrt (a*a + b*b + c*c); + if (tmp != 0) + { + a /= tmp; + b /= tmp; + c /= tmp; + + } + else + { + a=1; + b=0; + c=0; + } + + d = a * atom_getfloatarg(3, argc, argv) + b * atom_getfloatarg(4, argc, argv) + c * atom_getfloatarg(5, argc, argv); +//C a optimiser : envoyer directement les coef directeur et l'offset +//C a faire pour les autres obj aussi + + profondeur = a * x->posX_old_1 + b * x->posY_old_1 + c * x->posZ_old_1 - d; + + if ( (profondeur < 0) & (profondeur > -atom_getfloatarg(9, argc, argv)) ) + { + + tmp = atom_getfloatarg(6, argc, argv); // force normal constante + + x->forceX += tmp * a; + x->forceY += tmp * b; + x->forceZ += tmp * c; + + tmp = atom_getfloatarg(7, argc, argv); // force normal proportionelle a la profondeur + tmp *= profondeur; + x->forceX -= tmp * a; + x->forceY -= tmp * b; + x->forceZ -= tmp * c; + + tmp = atom_getfloatarg(8, argc, argv); // force normal proportionelle a la profondeur + + profondeur_old = a * x->posX_old_2 + b * x->posY_old_2 + c * x->posZ_old_2 - d; + tmp *= (profondeur - profondeur_old); + x->forceX -= tmp * a; + x->forceY -= tmp * b; + x->forceZ -= tmp * c; + + + tmp = atom_getfloatarg(10, argc, argv); // deplacement normal constant + + x->dX += tmp * a; + x->dY += tmp * b; + x->dZ += tmp * c; + + tmp = atom_getfloatarg(11, argc, argv); // deplacement normal proportionel + tmp *= profondeur; + + x->dX -= tmp * a; + x->dY -= tmp * b; + x->dZ -= tmp * c; + } + + } + else + { + error("bad plane interraction message"); + } +} + + +void mass3D_inter_sphere(t_mass3D *x, t_symbol *s, int argc, t_atom *argv) +{ +t_float posx1, posy1, posz1, Nx, Ny, Nz, dx, dy, dz, distance, Dmax, tmp; +t_float deltaX_old, deltaY_old, deltaZ_old, distance_old ; + + if (argc == 17) + // 0 : Xcentre + // 1 : Ycendre + // 2 : Zcentre + // 3 : Rmin + // 4 : Rmax + // 5 : F normal + // 6 : K normal + // 7 : F normal proportionel a 1/R + // 8 : Damp de liason normal + // 9 : deplacement N Ct + // 10 : position ancienne de l'interacteur en X + // 11 : position abcienne de l'interacteur en Y + // 12 : position abcienne de l'interacteur en Z + // 13 : d dormal proportionel a R + // 14 : force normal proportionel a 1/R2 + // 15 : d dormal proportionel a 1/R + // 16 : d dormal proportionel a 1/R*R + + { + posx1 = atom_getfloatarg(0, argc, argv); + posy1 = atom_getfloatarg(1, argc, argv); + posz1 = atom_getfloatarg(2, argc, argv); + Nx = (x->posX_old_1)-posx1; // vecteur deplacement X + Ny = (x->posY_old_1)-posy1; // vecteur deplacement Y + Nz = (x->posZ_old_1)-posz1; // vecteur deplacement Y + + distance = sqrt((Nx * Nx)+(Ny * Ny)+(Nz * Nz)); // distance entre le centre de l'interaction, et le pts + + Nx = Nx/distance; // composante X de la normal (normalisé) + Ny = Ny/distance; // composante Y de la normal. + Nz = Nz/distance; // composante Y de la normal. + + Dmax= atom_getfloatarg(4, argc, argv); // distance max de l'interaction + if ( (distance > atom_getfloatarg(3, argc, argv)) & (distance < Dmax) ) + { + tmp = atom_getfloatarg(5, argc, argv); // force constante normal + x->forceX += tmp * Nx; + x->forceY += tmp * Ny; + x->forceZ += tmp * Nz; + + tmp = atom_getfloatarg(6, argc, argv); // force variable (K) normal + tmp *= ( Dmax-distance ); + x->forceX += tmp * Nx ; + x->forceY += tmp * Ny ; + x->forceZ += tmp * Nz ; + + tmp = atom_getfloatarg(7, argc, argv); // force normal proportionel a 1/r + if ( (distance != 0) & (tmp != 0) ) + { + tmp /= distance; + x->forceX += tmp * Nx; + x->forceY += tmp * Ny; + x->forceZ += tmp * Nz ; + } + + tmp = atom_getfloatarg(8, argc, argv); // damping2 normal + tmp *= ( x->VX * Nx + x->VY * Ny + x->VZ * Nz ); + x->forceX -= tmp * Nx ; + x->forceY -= tmp * Ny ; + x->forceZ -= tmp * Nz ; + + tmp = atom_getfloatarg(9, argc, argv); // d normal + x->dX += tmp * Nx ; + x->dY += tmp * Ny ; + x->dZ += tmp * Nz ; + + tmp = atom_getfloatarg(13, argc, argv); // force normal proportionel a 1/r2 + if ( (distance != 0) & (tmp != 0) ) + { + tmp /= (distance * distance); + x->forceX += tmp * Nx ; + x->forceY += tmp * Ny ; + x->forceZ += tmp * Nz ; + } + + tmp = atom_getfloatarg(14, argc, argv); // deplacement variable (K) normal + tmp *= ( Dmax-distance ); + x->dX += tmp * Nx ; + x->dY += tmp * Ny ; + x->dZ += tmp * Nz ; + + tmp = atom_getfloatarg(15, argc, argv); // deplacement normal proportionel a 1/r + if ( (distance != 0) & (tmp != 0) ) + { + tmp /= distance; + x->dX += tmp * Nx ; + x->dY += tmp * Ny ; + x->dZ += tmp * Nz ; + } + + tmp = atom_getfloatarg(16, argc, argv); // deplacement normal proportionel a 1/r2 + if ( (distance != 0) & (tmp != 0) ) + { + tmp /= (distance * distance); + x->dX += tmp * Nx; + x->dY += tmp * Ny; + x->dZ += tmp * Nz; + } + + } + } + else + { + error("bad interact_3D_sphere message"); + } +} + + +void mass3D_inter_circle(t_mass3D *x, t_symbol *s, int argc, t_atom *argv) +{ + t_float a, b, c, d, profondeur, distance, tmp, profondeur_old, rayon, rayon_old; + + if (argc == 14) + // 0 : Xvector + // 1 : Yvector + // 2 : Zvector + // 3 : Xcenter + // 4 : Ycenter + // 5 : Zcenter + // 6 : Rmin + // 7 : RMax + // 8 : FNCt + // 9 : KN + // 10 : damping de liaison (profondeur) + // 11 : Profondeur maximum + // 12 : dN + // 13 : dKN + + { +// ax+by+cz-d=0 +// a = Xvector / |V| +// b = Yvector ... +// d est tel que aXcenter +bYcenter + cYcenter = d + + a = atom_getfloatarg(0, argc, argv); + b = atom_getfloatarg(1, argc, argv); + c = atom_getfloatarg(2, argc, argv); + + tmp = sqrt (a*a + b*b + c*c); + if (tmp != 0) + { + a /= tmp; + b /= tmp; + c /= tmp; + } + else + { + a=1; + b=0; + c=0; + } + + d = a * atom_getfloatarg(3, argc, argv) + b * atom_getfloatarg(4, argc, argv) + c * atom_getfloatarg(5, argc, argv); + + profondeur = a * x->posX_old_1 + b * x->posY_old_1 + c * x->posZ_old_1 - d; + + rayon = sqrt ( pow(x->posX_old_1-atom_getfloatarg(3, argc, argv), 2) +pow(x->posY_old_1-atom_getfloatarg(4, argc, argv) , 2) + pow(x->posZ_old_1 - atom_getfloatarg(5, argc, argv) , 2) - profondeur*profondeur ); + + if ( (profondeur < 0) & (profondeur > - atom_getfloatarg(11, argc, argv)) & (rayon > atom_getfloatarg(6, argc, argv)) & (rayon < atom_getfloatarg(7, argc, argv))) + { + + tmp = atom_getfloatarg(8, argc, argv); // force normal constante + + x->forceX += tmp * a; + x->forceY += tmp * b; + x->forceZ += tmp * c; + + tmp = atom_getfloatarg(9, argc, argv); // force normal proportionelle a la profondeur + tmp *= profondeur; + x->forceX -= tmp * a; + x->forceY -= tmp * b; + x->forceZ -= tmp * c; + + tmp = atom_getfloatarg(10, argc, argv); // force normal proportionelle a la profondeur + + profondeur_old = a * x->posX_old_2 + b * x->posY_old_2 + c * x->posZ_old_2 - d; + tmp *= (profondeur - profondeur_old); + + x->forceX -= tmp * a; + x->forceY -= tmp * b; + x->forceZ -= tmp * c; + + tmp = atom_getfloatarg(12, argc, argv); // deplacement normal constante + x->dX += tmp * a; + x->dY += tmp * b; + x->dZ += tmp * c; + + tmp = atom_getfloatarg(13, argc, argv); // deplacement normal proportionelle a la profondeur + tmp *= profondeur; + x->dX -= tmp * a; + x->dY -= tmp * b; + x->dZ -= tmp * c; + } + } + else + { + error("bad circle interraction message"); + } +} + + +void mass3D_inter_cylinder(t_mass3D *x, t_symbol *s, int argc, t_atom *argv) +{ + t_float a, b, c, d, profondeur, profondeur_old, distance, tmp, rayon_old, rayon; + t_float Xb, Yb, Zb, Ta, Tb, Tc, Xb_old, Yb_old, Zb_old; + + if (argc == 21) + // 0 : Xvector + // 1 : Yvector + // 2 : Zvector + // 3 : Xcenter + // 4 : Ycenter + // 5 : Zcenter + // 6 : Rmin + // 7 : Rmax + // 8 : FNCt + // 9 : KN + // 10 : damping de liaison (rayon) + // 11 : FN 1/R + // 12 : FN 1/R2 + // 13 : Pmin + // 14 : Pmax + // 15 : FTct + // 16 : KT + // 17 : dNct + // 18 : dTct + // 19 : dKN + // 20 : dKT + + { + +// ax+by+cz-d=0 +// a = Xvector / |V| +// b = Yvector ... +// d est tel que aXcenter +bYcenter + cYcenter = d + + a = atom_getfloatarg(0, argc, argv); + b = atom_getfloatarg(1, argc, argv); + c = atom_getfloatarg(2, argc, argv); + + tmp = sqrt (a*a + b*b + c*c); + if (tmp != 0) + { + a /= tmp; + b /= tmp; + c /= tmp; + } + else + { + a=1; + b=0; + c=0; + } + + d = a * atom_getfloatarg(3, argc, argv) + b * atom_getfloatarg(4, argc, argv) + c * atom_getfloatarg(5, argc, argv); + + profondeur = a * x->posX_old_1 + b * x->posY_old_1 + c * x->posZ_old_1 - d; + + Xb = x->posX_old_1 - atom_getfloatarg(3, argc, argv) - profondeur * a; + Yb = x->posY_old_1 - atom_getfloatarg(4, argc, argv) - profondeur * b; + Zb = x->posZ_old_1 - atom_getfloatarg(5, argc, argv) - profondeur * c; + + rayon = sqrt ( pow(Xb, 2) + pow(Yb, 2) + pow(Zb, 2) ); + + if (rayon != 0) + { + Xb /= rayon; // normalisation + Yb /= rayon; + Zb /= rayon; + } + else + { + Xb = 0; // normalisation + Yb = 0; + Zb = 0; + } + + + Ta = b*Zb - c*Yb; // vecteur tengentiel = vecteur vectoriel rayon + Tb = c*Xb - a*Zb; + Tc = a*Yb - b*Xb; + + if ( (profondeur < atom_getfloatarg(14, argc, argv)) & (profondeur > atom_getfloatarg(13, argc, argv)) & (rayon < atom_getfloatarg(7, argc, argv)) & (rayon > atom_getfloatarg(6, argc, argv)) ) + { + + tmp = atom_getfloatarg(8, argc, argv); // force normal constante + + x->forceX += tmp * Xb; + x->forceY += tmp * Yb; + x->forceZ += tmp * Zb; + + tmp = atom_getfloatarg(9, argc, argv); // rigidité normal proportionelle + tmp *= ( atom_getfloatarg(7, argc, argv) - rayon ) ; + x->forceX += tmp * Xb; + x->forceY += tmp * Yb; + x->forceZ += tmp * Zb; + + tmp = atom_getfloatarg(10, argc, argv); // damping normal proportionelle a la profondeur + + profondeur_old = a * x->posX_old_2 + b * x->posY_old_2 + c * x->posZ_old_2 - d; + + Xb_old = x->posX_old_2 - atom_getfloatarg(3, argc, argv) - profondeur_old * a; + Yb_old = x->posY_old_2 - atom_getfloatarg(4, argc, argv) - profondeur_old * b; + Zb_old = x->posZ_old_2 - atom_getfloatarg(5, argc, argv) - profondeur_old * c; + + rayon_old = sqrt ( pow(Xb_old, 2) + pow(Yb_old, 2) + pow(Zb_old, 2) ); + + tmp *= (rayon - rayon_old); + + x->forceX -= tmp * Xb; + x->forceY -= tmp * Yb; + x->forceZ -= tmp * Zb; + + tmp = atom_getfloatarg(11, argc, argv); // force normal proportionne a 1/R + if (rayon != 0) + { + tmp /= rayon; + x->forceX += tmp * Xb; + x->forceY += tmp * Yb; + x->forceZ += tmp * Zb; + } + + tmp = atom_getfloatarg(12, argc, argv); // force normal proportionne a 1/R*R + if (rayon != 0) + { + tmp /= (rayon*rayon); + x->forceX += tmp * Xb; + x->forceY += tmp * Yb; + x->forceZ += tmp * Zb; + } + + tmp = atom_getfloatarg(15, argc, argv); // force tengente constante + x->forceX -= tmp * Ta; + x->forceY -= tmp * Tb; + x->forceZ -= tmp * Tc; + + tmp = atom_getfloatarg(16, argc, argv); // rigidité tengentiel proportionelle + tmp *= ( atom_getfloatarg(7, argc, argv) - rayon ) ; + x->forceX += tmp * Ta; + x->forceY += tmp * Tb; + x->forceZ += tmp * Tc; + + tmp = atom_getfloatarg(17, argc, argv); // deplacement normal constante + + x->dX += tmp * Xb; + x->dY += tmp * Yb; + x->dZ += tmp * Zb; + + tmp = atom_getfloatarg(19, argc, argv); // deplacement normal proportionelle + tmp *= ( atom_getfloatarg(7, argc, argv) - rayon ) ; + x->dX += tmp * Xb; + x->dY += tmp * Yb; + x->dZ += tmp * Zb; + + tmp = atom_getfloatarg(18, argc, argv); // deplacement tengente constante + x->dX += tmp * Ta; + x->dY += tmp * Tb; + x->dZ += tmp * Tc; + + tmp = atom_getfloatarg(20, argc, argv); // deplacement tengentiel proportionelle + tmp *= ( atom_getfloatarg(7, argc, argv) - rayon ) ; + x->dX += tmp * Ta; + x->dY += tmp * Tb; + x->dZ += tmp * Tc; + } + } + else + { + error("bad cylinder interraction message"); + } +} + +void *mass3D_new(t_symbol *s, int argc, t_atom *argv) +{ + t_mass3D *x = (t_mass3D *)pd_new(mass3D_class); + + x->x_sym = atom_getsymbolarg(0, argc, argv); + x->x_state = makeseed3D(); + + pd_bind(&x->x_obj.ob_pd, atom_getsymbolarg(0, argc, argv)); + + x->position3D_new=outlet_new(&x->x_obj, 0); + x->force_out=outlet_new(&x->x_obj, 0); + x->vitesse_out=outlet_new(&x->x_obj, 0); + + x->forceX=0; + x->forceY=0; + x->forceZ=0; + + if (argc >= 2) + x->mass3D = atom_getfloatarg(1, argc, argv) ; + else + x->mass3D = 1; + + x->onoff = 1; + + x->VX = 0; + x->VY = 0; + x->VZ = 0; + + x->dX=0; + x->dY=0; + x->dZ=0; + + if (argc >= 3) + x->Xinit = atom_getfloatarg(2, argc, argv); + else + x->Xinit = 0 ; + + x->posX_old_1 = x->Xinit ; + x->posX_old_2 = x->Xinit; + SETFLOAT(&(x->pos_new[0]), x->Xinit); + + if (argc >= 4) + x->Yinit = atom_getfloatarg(3, argc, argv); + else + x->Yinit = 0 ; + + x->posY_old_1 = x->Yinit ; + x->posY_old_2 = x->Yinit; + SETFLOAT(&(x->pos_new[1]), x->Yinit); + + if (argc >= 5) + x->Zinit = atom_getfloatarg(4, argc, argv); + else + x->Zinit = 0 ; + + x->posZ_old_1 = x->Zinit ; + x->posZ_old_2 = x->Zinit; + SETFLOAT(&(x->pos_new[2]), x->Zinit); + + + if (argc >= 6) + x->minX = atom_getfloatarg(5, argc, argv) ; + else + x->minX = -100000; + + if (argc >= 7) + x->maxX = atom_getfloatarg(6, argc, argv) ; + else + x->maxX = 100000; + + if (argc >= 8) + x->minY = atom_getfloatarg(7, argc, argv) ; + else + x->minY = -100000; + + if (argc >= 9) + x->maxY = atom_getfloatarg(8, argc, argv) ; + else + x->maxY = 100000; + + if (argc >= 10) + x->minZ = atom_getfloatarg(9, argc, argv) ; + else + x->minZ = -100000; + + if (argc >= 11) + x->maxZ = atom_getfloatarg(10, argc, argv) ; + else + x->maxZ = 100000; + + if (argc >= 12) + x->seuil = atom_getfloatarg(11, argc, argv) ; + else + x->seuil = 0; + + if (argc >= 13) + x->damp = atom_getfloatarg(12, argc, argv) ; + else + x->damp = 0; + + return (void *)x; +} + +static void mass3D_free(t_mass3D *x) +{ + pd_unbind(&x->x_obj.ob_pd, x->x_sym); +} + + +void mass3D_setup(void) +{ + + mass3D_class = class_new(gensym("mass3D"), + (t_newmethod)mass3D_new, + (t_method)mass3D_free, + sizeof(t_mass3D), + CLASS_DEFAULT, A_GIMME, 0); + + class_addcreator((t_newmethod)mass3D_new, gensym("masse3D"), A_GIMME, 0); + + class_addmethod(mass3D_class, (t_method)mass3D_force, gensym("force3D"),A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + class_addbang(mass3D_class, mass3D_bang); + + class_addmethod(mass3D_class, (t_method)mass3D_dX, gensym("dX"), A_DEFFLOAT, 0); + class_addmethod(mass3D_class, (t_method)mass3D_dY, gensym("dY"), A_DEFFLOAT, 0); + class_addmethod(mass3D_class, (t_method)mass3D_dZ, gensym("dZ"), A_DEFFLOAT, 0); + class_addmethod(mass3D_class, (t_method)mass3D_dXYZ, gensym("dXYZ"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + class_addmethod(mass3D_class, (t_method)mass3D_setX, gensym("setX"), A_DEFFLOAT, 0); + class_addmethod(mass3D_class, (t_method)mass3D_setY, gensym("setY"), A_DEFFLOAT, 0); + class_addmethod(mass3D_class, (t_method)mass3D_setZ, gensym("setZ"), A_DEFFLOAT, 0); + class_addmethod(mass3D_class, (t_method)mass3D_setXYZ, gensym("setXYZ"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + class_addmethod(mass3D_class, (t_method)mass3D_minX, gensym("setXmin"), A_DEFFLOAT, 0); + class_addmethod(mass3D_class, (t_method)mass3D_minY, gensym("setYmin"), A_DEFFLOAT, 0); + class_addmethod(mass3D_class, (t_method)mass3D_maxX, gensym("setXmax"), A_DEFFLOAT, 0); + class_addmethod(mass3D_class, (t_method)mass3D_maxY, gensym("setYmax"), A_DEFFLOAT, 0); + class_addmethod(mass3D_class, (t_method)mass3D_minZ, gensym("setZmin"), A_DEFFLOAT, 0); + class_addmethod(mass3D_class, (t_method)mass3D_maxZ, gensym("setZmax"), A_DEFFLOAT, 0); + class_addmethod(mass3D_class, (t_method)mass3D_set_mass3D, gensym("setM"), A_DEFFLOAT, 0); + class_addmethod(mass3D_class, (t_method)mass3D_reset, gensym("reset"), 0); + class_addmethod(mass3D_class, (t_method)mass3D_resetf, gensym("resetF"), 0); + class_addmethod(mass3D_class, (t_method)mass3D_reset, gensym("loadbang"), 0); + class_addmethod(mass3D_class, (t_method)mass3D_on, gensym("on"), 0); + class_addmethod(mass3D_class, (t_method)mass3D_off, gensym("off"), 0); + class_addmethod(mass3D_class, (t_method)mass3D_seuil, gensym("setT"), A_DEFFLOAT, 0); + class_addmethod(mass3D_class, (t_method)mass3D_damp, gensym("setD"), A_DEFFLOAT, 0); + + class_addmethod(mass3D_class, (t_method)mass3D_inter_ambient, gensym("interactor_ambient_3D"), A_GIMME, 0); + class_addmethod(mass3D_class, (t_method)mass3D_inter_sphere, gensym("interactor_sphere_3D"), A_GIMME, 0); + class_addmethod(mass3D_class, (t_method)mass3D_inter_plane, gensym("interactor_plane_3D"), A_GIMME, 0); + class_addmethod(mass3D_class, (t_method)mass3D_inter_circle, gensym("interactor_circle_3D"), A_GIMME, 0); + class_addmethod(mass3D_class, (t_method)mass3D_inter_cylinder, gensym("interactor_cylinder_3D"), A_GIMME, 0); + +} diff --git a/src/masse.c b/src/masse.c deleted file mode 100755 index fccee2b..0000000 --- a/src/masse.c +++ /dev/null @@ -1,183 +0,0 @@ -#include "m_pd.h" -#include "math.h" - -static t_class *masse_class; - -typedef struct _masse { - t_object x_obj; - t_float pos_old_1, pos_old_2, Xinit; - t_float force, masse, dX; - t_float minX, maxX; - t_outlet *position_new, *vitesse_out, *force_out; - t_symbol *x_sym; // receive - unsigned int x_state; // random - t_float x_f; // random - -} t_masse; - -static int makeseed(void) -{ - static unsigned int random_nextseed = 1489853723; - random_nextseed = random_nextseed * 435898247 + 938284287; - return (random_nextseed & 0x7fffffff); -} - -static float random_bang(t_masse *x) -{ - int nval; - int range = 2000000; - float rnd; - unsigned int randval = x->x_state; - x->x_state = randval = randval * 472940017 + 832416023; - nval = ((double)range) * ((double)randval) - * (1./4294967296.); - if (nval >= range) nval = range-1; - - rnd=nval; - - rnd-=1000000; - rnd=rnd/1000000.; //pour mettre entre -1 et 1; - return (rnd); -} - -void masse_minX(t_masse *x, t_floatarg f1) -{ - x->minX = f1; -} - -void masse_maxX(t_masse *x, t_floatarg f1) -{ - x->maxX = f1; -} - -void masse_float(t_masse *x, t_floatarg f1) -{ - x->force += f1; -} - -void masse_bang(t_masse *x) -{ - t_float pos_new; - - if (x->masse > 0) - pos_new = x->force/x->masse + 2*x->pos_old_1 - x->pos_old_2; - else pos_new = x->pos_old_1; - - pos_new = max(min(x->maxX, pos_new), x->minX); - - pos_new += x->dX; - - x->pos_old_1 += x->dX; // pour ne pas avoir d'inertie suplementaire du a ce deplacement - - outlet_float(x->vitesse_out, x->pos_old_1 - x->pos_old_2); - outlet_float(x->force_out, x->force); - outlet_float(x->position_new, pos_new); - - x->pos_old_2 = x->pos_old_1; - x->pos_old_1 = pos_new; - -// x->force = 0; - - x->force = random_bang(x)*1e-25; // avoiding denormal problem by adding low amplitude noise - - x->dX = 0; - -} - -void masse_reset(t_masse *x) -{ - x->pos_old_2 = x->Xinit; - x->pos_old_1 = x->Xinit; - - x->force=0; - - outlet_float(x->position_new, x->Xinit); -} - -void masse_resetF(t_masse *x) -{ - x->force=0; - -} - -void masse_dX(t_masse *x, t_float posX) -{ - x->dX += posX; -} - -void masse_setX(t_masse *x, t_float posX) -{ - x->pos_old_2 = posX; // clear history for stability (instability) problem - x->pos_old_1 = posX; - - x->force=0; - - outlet_float(x->position_new, posX); -} - -void masse_loadbang(t_masse *x) -{ - outlet_float(x->position_new, x->Xinit); -} - -void masse_set_masse(t_masse *x, t_float mass) -{ - x->masse=mass; -} - -static void masse_free(t_masse *x) -{ - pd_unbind(&x->x_obj.ob_pd, x->x_sym); -} - -void *masse_new(t_symbol *s, t_floatarg M, t_floatarg X) -{ - - t_masse *x = (t_masse *)pd_new(masse_class); - - x->x_sym = s; - pd_bind(&x->x_obj.ob_pd, s); - - x->position_new=outlet_new(&x->x_obj, 0); - x->force_out=outlet_new(&x->x_obj, 0); - x->vitesse_out=outlet_new(&x->x_obj, 0); - - x->Xinit=X; - - x->pos_old_1 = X; - x->pos_old_2 = X; - x->force=0; - x->masse=M; - - x->minX = -100000; - x->maxX = 100000; - - if (x->masse<=0) x->masse=1; - - makeseed(); - - return (void *)x; -} - -void masse_setup(void) -{ - - masse_class = class_new(gensym("masse"), - (t_newmethod)masse_new, - (t_method)masse_free, - sizeof(t_masse), - CLASS_DEFAULT, A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT,0); - class_addcreator((t_newmethod)masse_new, gensym("mass"), A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT,0); - class_addcreator((t_newmethod)masse_new, gensym("pmpd.mass"), A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT,0); - class_addfloat(masse_class, masse_float); - class_addbang(masse_class, masse_bang); - class_addmethod(masse_class, (t_method)masse_set_masse, gensym("setM"), A_DEFFLOAT, 0); - class_addmethod(masse_class, (t_method)masse_setX, gensym("setX"), A_DEFFLOAT, 0); - class_addmethod(masse_class, (t_method)masse_dX, gensym("dX"), A_DEFFLOAT, 0); - class_addmethod(masse_class, (t_method)masse_reset, gensym("reset"), 0); - class_addmethod(masse_class, (t_method)masse_resetF, gensym("resetF"), 0); - class_addmethod(masse_class, (t_method)masse_minX, gensym("setXmin"), A_DEFFLOAT, 0); - class_addmethod(masse_class, (t_method)masse_maxX, gensym("setXmax"), A_DEFFLOAT, 0); - class_addmethod(masse_class, (t_method)masse_loadbang, gensym("loadbang"), 0); -} - diff --git a/src/masse2D.c b/src/masse2D.c deleted file mode 100755 index 7064cf8..0000000 --- a/src/masse2D.c +++ /dev/null @@ -1,809 +0,0 @@ -#include "m_pd.h" -#include "math.h" - -static t_class *masse2D_class; - -typedef struct _masse2D { - t_object x_obj; - t_float posX_old_1, posX_old_2, posY_old_1, posY_old_2, Xinit, Yinit; - t_float forceX, forceY, VX, VY, dX, dY, onoff; - t_float masse2D, seuil, damp; - t_float minX, maxX, minY, maxY; - t_atom pos_new[2], vitesse[3], force[3]; - t_outlet *position2D_new, *vitesse_out, *force_out; - t_symbol *x_sym; // receive - unsigned int x_state; // random - t_float x_f; // random -} t_masse2D; - -static int makeseed2D(void) -{ - static unsigned int random_nextseed = 1489853723; - random_nextseed = random_nextseed * 435898247 + 938284287; - return (random_nextseed & 0x7fffffff); -} - -static float random_bang2D(t_masse2D *x) -{ - int nval; - int range = 2000000; - float rnd; - unsigned int randval = x->x_state; - x->x_state = randval = randval * 472940017 + 832416023; - nval = ((double)range) * ((double)randval) - * (1./4294967296.); - if (nval >= range) nval = range-1; - - rnd=nval; - - rnd-=1000000; - rnd=rnd/1000000.; //pour mettre entre -1 et 1; - return (rnd); -} - -void masse2D_seuil(t_masse2D *x, t_floatarg f1) -{ - x->seuil = f1; -} - -void masse2D_on(t_masse2D *x) -{ - x->onoff = 1; -} - -void masse2D_off(t_masse2D *x) -{ - x->onoff = 0; -} - -void masse2D_minX(t_masse2D *x, t_floatarg f1) -{ - x->minX = f1; -} - -void masse2D_maxX(t_masse2D *x, t_floatarg f1) -{ - x->maxX = f1; -} - -void masse2D_minY(t_masse2D *x, t_floatarg f1) -{ - x->minY = f1; -} - -void masse2D_maxY(t_masse2D *x, t_floatarg f1) -{ - x->maxY = f1; -} - -void masse2D_force(t_masse2D *x, t_floatarg f1, t_floatarg f2) -{ - x->forceX = x->forceX+f1; - x->forceY = x->forceY+f2; -} - -void masse2D_displace(t_masse2D *x, t_floatarg f1, t_floatarg f2) -{ - x->dX += f1; - x->dY += f2; -} - -void masse2D_damp(t_masse2D *x, t_floatarg f1) -{ - x->damp = f1; -} - -void masse2D_dX(t_masse2D *x, t_floatarg f1) -{ - x->dX += f1; -} - -void masse2D_dY(t_masse2D *x, t_floatarg f1) -{ - x->dY += f1; -} - -void masse2D_bang(t_masse2D *x) -{ - t_float posX_new, posY_new, vX=1, vY=1; - if (x->onoff != 0) - { - - if (x->seuil > 0) - { - if (x->posY_old_1 == x->minY) // si on est en dehors de la structure -> frottement sec sur les bords - { - if (fabs(x->forceX)<=(x->seuil * -(x->forceY))) - vX = 0; // on est a l'interieur du cone de frotement, - } - - if (x->posY_old_1 == x->maxY) // si on est en dehors de la structure -> frottement sec sur les bords - { - if (fabs(x->forceX)<=(x->seuil * (x->forceY))) - vX = 0; // on est a l'interieur du cone de frotement, - } - - if (x->posX_old_1 == x->minX) // si on est en dehors de la structure -> frottement sec sur les bords - { - if (fabs(x->forceX)<=(x->seuil * -(x->forceY))) - vY = 0; // on est a l'interieur du cone de frotement, - } - - if (x->posX_old_1 == x->maxX) // si on est en dehors de la structure -> frottement sec sur les bords - { - if (fabs(x->forceX)<=(x->seuil * (x->forceY))) - vY = 0; // on est a l'interieur du cone de frotement, - } - } - - x->forceX += x->damp * ((x->posX_old_2)-(x->posX_old_1)); - x->forceY += x->damp * ((x->posY_old_2)-(x->posY_old_1)); // damping - - if (x->masse2D != 0) - { - posX_new = x->forceX/x->masse2D + 2*x->posX_old_1 - x->posX_old_2; - posY_new = x->forceY/x->masse2D + 2*x->posY_old_1 - x->posY_old_2; - } - else - { - posX_new = x->posX_old_1; - posY_new = x->posY_old_1; - } - - if (vX==0) - posX_new = x->posX_old_1; // on n'a pas de mv qd on est a l'interieur du cone de frotement - if (vY==0) - posY_new = x->posY_old_1; - - posX_new = max(min(posX_new, x->maxX), x->minX); - posY_new = max(min(posY_new, x->maxY), x->minY); - - posX_new += x->dX; - posY_new += x->dY; - - x->posX_old_1 += x->dX; // pour eviter l'inertie - x->posY_old_1 += x->dY; - - SETFLOAT(&(x->pos_new[0]), posX_new ); - SETFLOAT(&(x->pos_new[1]), posY_new ); - - x->posX_old_2 = x->posX_old_1; - x->posX_old_1 = posX_new; - - x->posY_old_2 = x->posY_old_1; - x->posY_old_1 = posY_new; - - SETFLOAT(&(x->force[0]), x->forceX ); - SETFLOAT(&(x->force[1]), x->forceY ); - SETFLOAT(&(x->force[2]), sqrt( (x->forceX * x->forceX) + (x->forceY * x->forceY) )); - -// x->forceX=0; -// x->forceY=0; - - x->forceX = random_bang2D(x)*1e-25; - x->forceY = random_bang2D(x)*1e-25; // avoiding denormal problem by adding low amplitude noise - - - x->dX=0; - x->dY=0; - - x->VX = x->posX_old_1 - x->posX_old_2; - x->VY = x->posY_old_1 - x->posY_old_2; - - SETFLOAT(&(x->vitesse[0]), x->VX ); - SETFLOAT(&(x->vitesse[1]), x->VY ); - SETFLOAT(&(x->vitesse[2]), sqrt( (x->VX * x->VX) + (x->VY * x->VY) )); - - outlet_anything(x->vitesse_out, gensym("velocity2D"), 3, x->vitesse); - outlet_anything(x->force_out, gensym("force2D"), 3, x->force); - outlet_anything(x->position2D_new, gensym("position2D"), 2, x->pos_new); - } -} - -void masse2D_reset(t_masse2D *x) -{ - x->posX_old_2 = x->Xinit; - x->posX_old_1 = x->Xinit; - x->forceX=0; - - x->posY_old_2 = x->Yinit; - x->posY_old_1 = x->Yinit; - x->forceY=0; - - x->VX = 0; - x->VY = 0; - - x->dX=0; - x->dY=0; - - x->seuil=0; - - x->onoff = 1; - - SETFLOAT(&(x->pos_new[0]), x->Xinit ); - SETFLOAT(&(x->pos_new[1]), x->Yinit ); - - SETFLOAT(&(x->force[0]), 0 ); - SETFLOAT(&(x->force[1]), 0 ); - SETFLOAT(&(x->force[2]), 0 ); - - SETFLOAT(&(x->vitesse[0]), 0 ); - SETFLOAT(&(x->vitesse[1]), 0 ); - SETFLOAT(&(x->vitesse[2]), 0 ); - - outlet_anything(x->vitesse_out, gensym("velocity2D"), 3, x->vitesse); - outlet_anything(x->force_out, gensym("force2D"), 3, x->force); - outlet_anything(x->position2D_new, gensym("position2D"), 2, x->pos_new); -} - -void masse2D_resetf(t_masse2D *x) -{ - x->dX=0; - x->dY=0; - - x->forceX=0; - x->forceY=0; -} - -void masse2D_setXY(t_masse2D *x, t_float posX, t_float posY) -{ - x->posX_old_2 = posX; - x->posX_old_1 = posX; - x->forceX=0; - - x->posY_old_2 = posY; - x->posY_old_1 = posY; - x->forceY=0; - - SETFLOAT(&(x->pos_new[0]), posX ); - SETFLOAT(&(x->pos_new[1]), posY ); - - outlet_anything(x->position2D_new, gensym("position2D"), 2, x->pos_new); -} - -void masse2D_setX(t_masse2D *x, t_float posX) -{ - x->posX_old_2 = posX; - x->posX_old_1 = posX; - x->forceX=0; - - SETFLOAT(&(x->pos_new[0]), posX ); - - outlet_anything(x->position2D_new, gensym("position2D"), 2, x->pos_new); -} - -void masse2D_setY(t_masse2D *x, t_float posY) -{ - x->posY_old_2 = posY; - x->posY_old_1 = posY; - x->forceY=0; - - SETFLOAT(&(x->pos_new[1]), posY ); - - outlet_anything(x->position2D_new, gensym("position2D"), 2, x->pos_new); -} - -void masse2D_loadbang(t_masse2D *x) -{ - outlet_anything(x->position2D_new, gensym("position2D"), 2, x->pos_new); -} - - -void masse2D_set_masse2D(t_masse2D *x, t_float mass) -{ - x->masse2D=mass; -} - -void masse2D_inter_ambient(t_masse2D *x, t_symbol *s, int argc, t_atom *argv) -{ - if (argc == 12) - // 0 : FX - // 1 : FY - // 2 : RndX - // 3 : RndY - // 4 : D2 - // 5 : rien - // 6 : Xmin - // 7 : Xmax - // 8 : Ymin - // 9 : Ymax - // 10 : dX - // 11 : dY - { - if (x->posX_old_1 > atom_getfloatarg(6, argc, argv)) - { - if (x->posX_old_1 < atom_getfloatarg(7, argc, argv)) - { - if (x->posY_old_1 > atom_getfloatarg(8, argc, argv)) - { - if (x->posY_old_1 < atom_getfloatarg(9, argc, argv)) - { - x->forceX += atom_getfloatarg(0, argc, argv); - x->forceY += atom_getfloatarg(1, argc, argv); // constant - - x->forceX += random_bang2D(x)*atom_getfloatarg(2, argc, argv); - x->forceY += random_bang2D(x)*atom_getfloatarg(3, argc, argv); // random - - x->forceX += atom_getfloatarg(4, argc, argv) * ((x->posX_old_2)-(x->posX_old_1)); - x->forceY += atom_getfloatarg(4, argc, argv) * ((x->posY_old_2)-(x->posY_old_1)); // damping - - x->dX += atom_getfloatarg(10, argc, argv); - x->dY += atom_getfloatarg(11, argc, argv); // constant - } - } - } - } - } - else - { - error("bad ambient interraction message"); - } -} - -void masse2D_inter_seg(t_masse2D *x, t_symbol *s, int argc, t_atom *argv) -{ -t_float a1, b1, c1, a2, b2, c2, a3, b3, c3, tmp; -t_float posx1, posx2, posy1, posy2; -t_float profondeur, prof_max; - - if (argc == 12) - // 0 : posx1 - // 1 : posy1 - // 2 : posx2 - // 3 : posy2 - // 4 : profondeur max - // 5 : F CT Normal - // 6 : F CT Tengentiel - // 7 : K normal - // 8 : Damp2 normal - // 9 : Damp2 tan - // 10 : displacement Normal - // 11 : d Tan - - { - posx1 = atom_getfloatarg(0, argc, argv); - posy1 = atom_getfloatarg(1, argc, argv); - posx2 = atom_getfloatarg(2, argc, argv); - posy2 = atom_getfloatarg(3, argc, argv); - - b1 = posx2 - posx1; - a1 = -posy2 + posy1; - - if (!((a1==0) & (b1==0))) - { - - tmp = sqrt((a1*a1)+(b1*b1)); // = longueur du vecteur pour renormalisation - if (tmp !=0) - { - a1 = a1/tmp; - b1 = b1/tmp; - } - else - { - a1 = 0; - b1 = 0; - } - - c1 = a1*posx1+b1*posy1; - - profondeur = ( (a1 * x->posX_old_1) + (b1 * x->posY_old_1) ) - c1; - - if ( ( profondeur < 0) & (profondeur > - atom_getfloatarg(4, argc, argv)) ) - { - a2 = b1; - b2 = -a1; - c2 = a2*posx1+b2*posy1; - if (( (a2 * x->posX_old_1) + (b2 * x->posY_old_1) ) > c2) - { - a3 = a2; - b3 = b2; - c3 = a3*posx2+b3*posy2; - if (( (a3 * x->posX_old_1) + (b3 * x->posY_old_1) ) < c3) - { - tmp = atom_getfloatarg(5, argc, argv); // force ct normal - x->forceX += tmp * a1; - x->forceY += tmp * b1; - - tmp = atom_getfloatarg(6, argc, argv); // force ct normal - x->forceX -= tmp * b1; - x->forceY -= tmp * -a1; - - tmp = atom_getfloatarg(7, argc, argv); // force K normal - tmp *= profondeur; - x->forceX -= tmp * a1; - x->forceY -= tmp * b1; - - tmp = atom_getfloatarg(8, argc, argv); // damping2 normal - tmp *= ( x->VX * a1 + x->VY * b1 ); - x->forceX -= tmp * a1 ; - x->forceY -= tmp * b1 ; - - tmp = atom_getfloatarg(9, argc, argv); // damping2 tangentiel - tmp *= ( x->VX * b1 - x->VY * a1 ); - x->forceX -= tmp * b1 ; - x->forceY -= tmp * -a1 ; - - tmp = atom_getfloatarg(10, argc, argv); // displacement normal - x->dX += tmp * a1 ; - x->dY += tmp * b1 ; - - tmp = atom_getfloatarg(11, argc, argv); // displacement tengentiel - x->dX -= tmp * b1 ; - x->dY -= tmp * -a1 ; - } - } - } - } - } - else - { - error("bad interact_2D_segment message"); - } -} - -void masse2D_inter_line(t_masse2D *x, t_symbol *s, int argc, t_atom *argv) -{ -t_float a1, b1, c1, tmp; -t_float posx1, posx2, posy1, posy2; -t_float profondeur, prof_max; - - if (argc == 12) - // 0 : posx1 - // 1 : posy1 - // 2 : posx2 - // 3 : posy2 - // 4 : profondeur max - // 5 : F CT Normal - // 6 : F CT Tengentiel - // 7 : K normal - // 8 : Damp2 normal - // 9 : Damp2 tan - // 10 : d normal - // 11 : d tengential - { - posx1 = atom_getfloatarg(0, argc, argv); - posy1 = atom_getfloatarg(1, argc, argv); - posx2 = atom_getfloatarg(2, argc, argv); - posy2 = atom_getfloatarg(3, argc, argv); - - b1 = posx2 - posx1; - a1 = -posy2 + posy1; - - if (!((a1==0) & (b1==0))) - { - tmp = sqrt((a1*a1)+(b1*b1)); // = longueur du vecteur pour renormalisation - a1 = a1/tmp; // composante X de la normal - b1 = b1/tmp; // composante Y de la normal - c1 = a1*posx1+b1*posy1; // - - profondeur = ( (a1 * x->posX_old_1) + (b1 * x->posY_old_1) ) - c1; - if ( ( profondeur < 0) & (profondeur > - atom_getfloatarg(4, argc, argv)) ) - { - tmp = atom_getfloatarg(5, argc, argv); // force ct normal - x->forceX += tmp * a1; - x->forceY += tmp * b1; - - tmp = atom_getfloatarg(6, argc, argv); // force ct tengentiel - x->forceX -= tmp * b1; - x->forceY -= tmp * -a1; - - tmp = atom_getfloatarg(7, argc, argv); // force K normal - tmp *= profondeur ; - x->forceX -= tmp * a1; - x->forceY -= tmp * b1; - - tmp = atom_getfloatarg(8, argc, argv); // damping2 normal - tmp *= ( x->VX * a1 + x->VY * b1 ) ; - x->forceX -= tmp * a1 ; - x->forceY -= tmp * b1 ; - - tmp = atom_getfloatarg(9, argc, argv); // damping2 tangentiel - tmp *= ( x->VX * b1 - x->VY * a1 ); - x->forceX -= tmp * b1 ; - x->forceY -= tmp * -a1 ; - - tmp = atom_getfloatarg(10, argc, argv); // d normal - x->dX += tmp * a1; - x->dY += tmp * b1; - - tmp = atom_getfloatarg(11, argc, argv); // d tangentiel - x->dX -= tmp * b1; - x->dY -= tmp * -a1; - } - } - } - else - { - error("bad interact_2D_line message"); - } -} - -void masse2D_inter_circle(t_masse2D *x, t_symbol *s, int argc, t_atom *argv) -{ -t_float posx1, posy1, Nx, Ny, dx, dy, distance, Dmax, tmp; -t_float deltaX_old, deltaY_old, distance_old ; -t_float fnx=0, fny=0; -t_float ftx=0, fty=0; - - if (argc == 20) - // 0 : Xcentre - // 1 : Ycendre - // 2 : Rmin - // 3 : Rmax - // 4 : F normal - // 5 : F tangentiel - // 6 : K normal - // 7 : K tengentiel - // 8 : F normal proportionel a 1/R - // 9 : F tengentiel proportionel a 1/R - // 10 : Damp2 normal - // 11 : Damp2 tan - // 12 : deplacement N proportionel a 1/R - // 13 : deplacement tengentiel proportionel a 1/R - // 14 : position ancienne de l'interacteur en X - // 15 : position abcienne de l'interacteur en Y - // 16 : damping de liaison - // 17 : F normal proportionel a 1/R*R - // 18 : normal displacement - // 19 : tengential displacement - - { - posx1 = atom_getfloatarg(0, argc, argv); - posy1 = atom_getfloatarg(1, argc, argv); - Nx = (x->posX_old_1)-posx1; // vecteur deplacement X - Ny = (x->posY_old_1)-posy1; // vecteur deplacement Y - - distance = sqrt((Nx * Nx)+(Ny * Ny)); // distance entre le centre de l'interaction, et le pts - - Dmax= atom_getfloatarg(3, argc, argv); // distance max de l'interaction - if ( (distance > atom_getfloatarg(2, argc, argv)) & (distance < Dmax) ) - { - Nx = Nx/distance; // composante X de la normal (normalisé) - Ny = Ny/distance; // composante Y de la normal. - - tmp = atom_getfloatarg(4, argc, argv); // force constante normal -// x->forceX += tmp * Nx; -// x->forceY += tmp * Ny; - fnx +=tmp; -// fny +=tmp; - - tmp = atom_getfloatarg(5, argc, argv); // force constante tengentiel -// x->forceX += tmp * Ny; -// x->forceY += tmp * -Nx; - ftx +=tmp; -// fty +=tmp; - - tmp = atom_getfloatarg(6, argc, argv); // force variable (K) normal - tmp *= ( Dmax-distance ); -// x->forceX += tmp * Nx ; -// x->forceY += tmp * Ny ; - fnx +=tmp; -// fny +=tmp; - - tmp = atom_getfloatarg(7, argc, argv); // force variable (K) tengentiel - tmp *= ( Dmax-distance ); -// x->forceX += tmp * Ny ; -// x->forceY += tmp * -Nx ; - ftx +=tmp; -// fty +=tmp; - - tmp = atom_getfloatarg(8, argc, argv); // force normal proportionel a 1/r - if (distance != 0) - { - tmp /= distance; -// x->forceX += tmp * Nx ; -// x->forceY += tmp * Ny ; - fnx +=tmp; -// fny +=tmp; - } - - tmp = atom_getfloatarg(9, argc, argv); // force tengentiel proportionel a 1/r - if (distance != 0) - { - tmp /= distance; -// x->forceX -= tmp * Ny ; -// x->forceY -= tmp * -Nx ; - ftx -=tmp; -// fty -=tmp; - } - - tmp = atom_getfloatarg(10, argc, argv); // damping2 normal - tmp *= ( x->VX * Nx + x->VY * Ny ); -// x->forceX -= tmp * Nx ; -// x->forceY -= tmp * Ny ; - fnx -=tmp; -// fny -=tmp; - - tmp = atom_getfloatarg(11, argc, argv); // damping2 tangentiel - tmp *= ( x->VX * Ny - x->VY * Nx ); -// x->forceX -= tmp * Ny ; -// x->forceY -= tmp * -Ny ; - ftx -=tmp; -// fty -=tmp; - - tmp = atom_getfloatarg(12, argc, argv); // d normal - if (distance != 0) - { - tmp /= distance; - x->dX += tmp * Nx ; - x->dY += tmp * Ny ; - } - - tmp = atom_getfloatarg(13, argc, argv); // d tangentiel - if (distance != 0) - { - tmp /= distance; - - x->dX -= tmp * Ny ; - x->dY -= tmp * -Nx ; - } - - tmp = atom_getfloatarg(16, argc, argv); // damping de liaison - if (tmp!= 0) - { - deltaX_old = atom_getfloatarg(14, argc, argv) - x->posX_old_2; - deltaY_old = atom_getfloatarg(15, argc, argv) - x->posY_old_2; - distance_old = sqrt( (deltaX_old * deltaX_old) + (deltaY_old * deltaY_old)); - -// x->forceX -= Nx * tmp * (distance - distance_old); -// x->forceY -= Ny * tmp * (distance - distance_old); - - tmp *= (distance - distance_old); - fnx -=tmp; -// fny -=tmp; - } - - tmp = atom_getfloatarg(17, argc, argv); // force normal proportionel a 1/r2 - if (distance != 0) - { - tmp /= (distance*distance); -// x->forceX -= tmp * Nx; -// x->forceY -= tmp * Ny; - fnx +=tmp; -// fny +=tmp; - } - - tmp = atom_getfloatarg(18, argc, argv); // deplacement constante normal - x->dX += tmp * Nx; - x->dY += tmp * Ny; - - tmp = atom_getfloatarg(19, argc, argv); // deplacement constante tengentiel - x->dX -= tmp * Ny; - x->dY -= tmp * -Nx; - - x->forceX += fnx * Nx + ftx * Ny; // optimisation, but does not change anything... - x->forceY += fnx * Ny - ftx * Nx; - } - } - else - { - error("bad interact_2D_circle message"); - } -} - -void *masse2D_new(t_symbol *s, int argc, t_atom *argv) -{ - - t_masse2D *x = (t_masse2D *)pd_new(masse2D_class); - - x->x_sym = atom_getsymbolarg(0, argc, argv); - x->x_state = makeseed2D(); - - pd_bind(&x->x_obj.ob_pd, atom_getsymbolarg(0, argc, argv)); - - x->position2D_new=outlet_new(&x->x_obj, 0); - x->force_out=outlet_new(&x->x_obj, 0); - x->vitesse_out=outlet_new(&x->x_obj, 0); - - x->forceX=0; - x->forceY=0; - - if (argc >= 2) - x->masse2D = atom_getfloatarg(1, argc, argv) ; - else - x->masse2D = 1; - - x->onoff = 1; - - x->VX = 0; - x->VY = 0; - - x->dX=0; - x->dY=0; - - if (argc >= 3) - x->Xinit = atom_getfloatarg(2, argc, argv); - else - x->Xinit = 0 ; - - x->posX_old_1 = x->Xinit ; - x->posX_old_2 = x->Xinit; - SETFLOAT(&(x->pos_new[0]), x->Xinit); - - if (argc >= 4) - x->Yinit = atom_getfloatarg(3, argc, argv); - else - x->Yinit = 0 ; - - x->posY_old_1 = x->Yinit ; - x->posY_old_2 = x->Yinit; - SETFLOAT(&(x->pos_new[1]), x->Yinit); - - if (argc >= 5) - x->minX = atom_getfloatarg(4, argc, argv) ; - else - x->minX = -100000; - - if (argc >= 6) - x->maxX = atom_getfloatarg(5, argc, argv) ; - else - x->maxX = 100000; - - if (argc >= 7) - x->minY = atom_getfloatarg(6, argc, argv) ; - else - x->minY = -100000; - - if (argc >= 8) - x->maxY = atom_getfloatarg(7, argc, argv) ; - else - x->maxY = 100000; - - if (argc >= 9) - x->seuil = atom_getfloatarg(8, argc, argv) ; - else - x->seuil = 0; - - if (argc >= 10) - x->damp = atom_getfloatarg(9, argc, argv) ; - else - x->damp = 0; - - return (x); -} - -static void masse2D_free(t_masse2D *x) -{ - pd_unbind(&x->x_obj.ob_pd, x->x_sym); -} - -void masse2D_setup(void) -{ - - masse2D_class = class_new(gensym("masse2D"), - (t_newmethod)masse2D_new, - (t_method)masse2D_free, sizeof(t_masse2D), - CLASS_DEFAULT, A_GIMME, 0); - - class_addcreator((t_newmethod)masse2D_new, gensym("mass2D"), A_GIMME, 0); - class_addcreator((t_newmethod)masse2D_new, gensym("pmpd.mass2D"), A_GIMME, 0); - - class_addbang(masse2D_class, masse2D_bang); - - class_addmethod(masse2D_class, (t_method)masse2D_force, gensym("force2D"),A_DEFFLOAT, A_DEFFLOAT, 0); - class_addmethod(masse2D_class, (t_method)masse2D_displace, gensym("dXY"),A_DEFFLOAT, A_DEFFLOAT, 0); - class_addmethod(masse2D_class, (t_method)masse2D_dX, gensym("dX"),A_DEFFLOAT, 0); - class_addmethod(masse2D_class, (t_method)masse2D_dY, gensym("dY"),A_DEFFLOAT, 0); - - class_addmethod(masse2D_class, (t_method)masse2D_inter_ambient, gensym("interactor_ambient_2D"), A_GIMME, 0); - class_addmethod(masse2D_class, (t_method)masse2D_inter_line, gensym("interactor_line_2D"), A_GIMME, 0); - class_addmethod(masse2D_class, (t_method)masse2D_inter_seg, gensym("interactor_segment_2D"), A_GIMME, 0); - class_addmethod(masse2D_class, (t_method)masse2D_inter_circle, gensym("interactor_circle_2D"), A_GIMME, 0); - - class_addmethod(masse2D_class, (t_method)masse2D_seuil, gensym("setT"), A_DEFFLOAT, 0); - class_addmethod(masse2D_class, (t_method)masse2D_set_masse2D, gensym("setM"), A_DEFFLOAT, 0); - class_addmethod(masse2D_class, (t_method)masse2D_setX, gensym("setX"), A_DEFFLOAT, 0); - class_addmethod(masse2D_class, (t_method)masse2D_setY, gensym("setY"), A_DEFFLOAT, 0); - class_addmethod(masse2D_class, (t_method)masse2D_minX, gensym("setXmin"), A_DEFFLOAT, 0); - class_addmethod(masse2D_class, (t_method)masse2D_minY, gensym("setYmin"), A_DEFFLOAT, 0); - class_addmethod(masse2D_class, (t_method)masse2D_maxX, gensym("setXmax"), A_DEFFLOAT, 0); - class_addmethod(masse2D_class, (t_method)masse2D_maxY, gensym("setYmax"), A_DEFFLOAT, 0); - class_addmethod(masse2D_class, (t_method)masse2D_setXY, gensym("setXY"), A_DEFFLOAT, A_DEFFLOAT, 0); - class_addmethod(masse2D_class, (t_method)masse2D_damp, gensym("setD"), A_DEFFLOAT, 0); - class_addmethod(masse2D_class, (t_method)masse2D_on, gensym("on"), 0); - class_addmethod(masse2D_class, (t_method)masse2D_off, gensym("off"), 0); - class_addmethod(masse2D_class, (t_method)masse2D_reset, gensym("reset"), 0); - class_addmethod(masse2D_class, (t_method)masse2D_resetf, gensym("resetF"), 0); - class_addmethod(masse2D_class, (t_method)masse2D_loadbang, gensym("loadbang"), 0); - -} diff --git a/src/masse3D.c b/src/masse3D.c deleted file mode 100755 index c254102..0000000 --- a/src/masse3D.c +++ /dev/null @@ -1,1093 +0,0 @@ -#include "m_pd.h" -#include "math.h" - -static t_class *masse3D_class; - -typedef struct _masse3D { - t_object x_obj; - t_float posX_old_1, posX_old_2, posY_old_1, posY_old_2, posZ_old_1, posZ_old_2; - t_float Xinit, Yinit, Zinit, forceX, forceY, forceZ, VX, VY, VZ, dX, dY, dZ; - t_float masse3D, seuil, onoff, damp; - t_atom pos_new[3], vitesse[4], force[4]; - t_float minX, maxX, minY, maxY, minZ, maxZ; - t_outlet *position3D_new, *vitesse_out, *force_out; - t_symbol *x_sym; // receive - unsigned int x_state; // random - t_float x_f; // random -} t_masse3D; - -static int makeseed3D(void) -{ - static unsigned int random_nextseed = 1489853723; - random_nextseed = random_nextseed * 435898247 + 938284287; - return (random_nextseed & 0x7fffffff); -} - -static float random_bang3D(t_masse3D *x) -{ - int nval; - int range = 2000000; - float rnd; - unsigned int randval = x->x_state; - x->x_state = randval = randval * 472940017 + 832416023; - nval = ((double)range) * ((double)randval) - * (1./4294967296.); - if (nval >= range) nval = range-1; - - rnd=nval; - - rnd-=1000000; - rnd=rnd/1000000.; //pour mettre entre -1 et 1; - return (rnd); -} - -void masse3D_on(t_masse3D *x) -{ - x->onoff = 1; -} - -void masse3D_off(t_masse3D *x) -{ - x->onoff = 0; -} - -void masse3D_minX(t_masse3D *x, t_floatarg f1) -{ - x->minX = f1; -} - -void masse3D_maxX(t_masse3D *x, t_floatarg f1) -{ - x->maxX = f1; -} - -void masse3D_minY(t_masse3D *x, t_floatarg f1) -{ - x->minY = f1; -} - -void masse3D_maxY(t_masse3D *x, t_floatarg f1) -{ - x->maxY = f1; -} - -void masse3D_minZ(t_masse3D *x, t_floatarg f1) -{ - x->minZ = f1; -} - -void masse3D_maxZ(t_masse3D *x, t_floatarg f1) -{ - x->maxZ = f1; -} - -void masse3D_seuil(t_masse3D *x, t_floatarg f1) -{ - x->seuil = f1; -} - -void masse3D_damp(t_masse3D *x, t_floatarg f1) -{ - x->damp = f1; -} - -void masse3D_loadbang(t_masse3D *x, t_float posZ) -{ - outlet_anything(x->position3D_new, gensym("position3D"), 3, x->pos_new); -} - -void masse3D_setX(t_masse3D *x, t_float posX) -{ - - x->posX_old_2 = posX; - x->posX_old_1 = posX; - x->forceX=0; - - SETFLOAT(&(x->pos_new[0]), posX); - - outlet_anything(x->position3D_new, gensym("position3D"), 3, x->pos_new); - -} - -void masse3D_setY(t_masse3D *x, t_float posY) -{ - x->posY_old_2 = posY; - x->posY_old_1 = posY; - x->forceY=0; - - SETFLOAT(&(x->pos_new[1]), posY); - - outlet_anything(x->position3D_new, gensym("position3D"), 3, x->pos_new); - -} - -void masse3D_setZ(t_masse3D *x, t_float posZ) -{ - x->posZ_old_2 = posZ; - x->posZ_old_1 = posZ; - x->forceZ=0; - - SETFLOAT(&(x->pos_new[2]), posZ); - - outlet_anything(x->position3D_new, gensym("position3D"), 3, x->pos_new); - -} - -void masse3D_setXYZ(t_masse3D *x, t_float posX, t_float posY, t_float posZ) -{ - - x->posX_old_2 = posX; - x->posX_old_1 = posX; - x->forceX=0; - - x->posY_old_2 = posY; - x->posY_old_1 = posY; - x->forceY=0; - - x->posZ_old_2 = posZ; - x->posZ_old_1 = posZ; - x->forceZ=0; - - SETFLOAT(&(x->pos_new[0]), posX); - SETFLOAT(&(x->pos_new[1]), posY); - SETFLOAT(&(x->pos_new[2]), posZ); - - outlet_anything(x->position3D_new, gensym("position3D"), 3, x->pos_new); -} - -void masse3D_set_masse3D(t_masse3D *x, t_float mass) -{ - x->masse3D=mass; -} - - -void masse3D_force(t_masse3D *x, t_floatarg f1, t_floatarg f2, t_floatarg f3) -{ - x->forceX += f1; - x->forceY += f2; - x->forceZ += f3; -} - -void masse3D_dXYZ(t_masse3D *x, t_floatarg f1, t_floatarg f2, t_floatarg f3) -{ - x->dX += f1; - x->dY += f2; - x->dZ += f3; -} - -void masse3D_dX(t_masse3D *x, t_floatarg f1 ) -{ - x->dX += f1; -} - -void masse3D_dY(t_masse3D *x, t_floatarg f1 ) -{ - x->dY += f1; -} - -void masse3D_dZ(t_masse3D *x, t_floatarg f1 ) -{ - x->dZ += f1; -} - -void masse3D_bang(t_masse3D *x) -{ - t_float posX_new, posY_new, posZ_new, vX=1, vY=1, vZ=1; - if (x->onoff != 0) - { - - if (x->seuil > 0) - { - if (x->posZ_old_1 == x->minZ) // si on est en dehors de la structure -> frottement sec sur les bords - { - if (sqrt(x->forceX*x->forceX + x->forceY*x->forceY)<=(x->seuil * -(x->forceZ))) - { - vX = 0; // on est a l'interieur du cone de frotement, - vY = 0; // on est a l'interieur du cone de frotement, - } - } - - if (x->posZ_old_1 == x->maxZ) // si on est en dehors de la structure -> frottement sec sur les bords - { - if (sqrt(x->forceX*x->forceX + x->forceY*x->forceY)<=(x->seuil * (x->forceZ))) - { - vX = 0; // on est a l'interieur du cone de frotement, - vY = 0; // on est a l'interieur du cone de frotement, - } - } - - if (x->posY_old_1 == x->minY) // si on est en dehors de la structure -> frottement sec sur les bords - { - if (sqrt(x->forceX*x->forceX + x->forceZ*x->forceZ)<=(x->seuil * -(x->forceY))) - { - vX = 0; // on est a l'interieur du cone de frotement, - vZ = 0; // on est a l'interieur du cone de frotement, - } - } - - if (x->posY_old_1 == x->maxY) // si on est en dehors de la structure -> frottement sec sur les bords - { - if (sqrt(x->forceX*x->forceX + x->forceZ*x->forceZ)<=(x->seuil * (x->forceY))) - { - vX = 0; // on est a l'interieur du cone de frotement, - vZ = 0; // on est a l'interieur du cone de frotement, - } - } - - if (x->posX_old_1 == x->minX) // si on est en dehors de la structure -> frottement sec sur les bords - { - if (sqrt(x->forceY*x->forceY + x->forceZ*x->forceZ)<=(x->seuil * -(x->forceX))) - { - vY = 0; // on est a l'interieur du cone de frotement, - vZ = 0; // on est a l'interieur du cone de frotement, - } - } - - if (x->posX_old_1 == x->maxX) // si on est en dehors de la structure -> frottement sec sur les bords - { - if (sqrt(x->forceY*x->forceY + x->forceZ*x->forceZ)<=(x->seuil * (x->forceX))) - { - vY = 0; // on est a l'interieur du cone de frotement, - vZ = 0; // on est a l'interieur du cone de frotement, - } - } - } - - x->forceX += x->damp * ((x->posX_old_2)-(x->posX_old_1)); - x->forceY += x->damp * ((x->posY_old_2)-(x->posY_old_1)); // damping - x->forceZ += x->damp * ((x->posZ_old_2)-(x->posZ_old_1)); // damping - - if (!(x->masse3D == 0)) - { - posX_new = x->forceX/x->masse3D + 2*x->posX_old_1 - x->posX_old_2; - posY_new = x->forceY/x->masse3D + 2*x->posY_old_1 - x->posY_old_2; - posZ_new = x->forceZ/x->masse3D + 2*x->posZ_old_1 - x->posZ_old_2; - } - else - { - posX_new = x->posX_old_1; - posY_new = x->posY_old_1; - posZ_new = x->posY_old_1; - } - - - if (vX==0) - posX_new = x->posX_old_1; // on n'a pas de mv qd on est a l'interieur du cone de frotement - if (vY==0) - posY_new = x->posY_old_1; - if (vZ==0) - posZ_new = x->posZ_old_1; - - posX_new = max(min(x->maxX, posX_new), x->minX); - posY_new = max(min(x->maxY, posY_new), x->minY); - posZ_new = max(min(x->maxZ, posZ_new), x->minZ); - - - posX_new += x->dX; - posY_new += x->dY; - posZ_new += x->dZ; - - x->posX_old_1 += x->dX; - x->posY_old_1 += x->dY; - x->posZ_old_1 += x->dZ; - - SETFLOAT(&(x->pos_new[0]), posX_new ); - SETFLOAT(&(x->pos_new[1]), posY_new ); - SETFLOAT(&(x->pos_new[2]), posZ_new ); - - x->posX_old_2 = x->posX_old_1; - x->posX_old_1 = posX_new; - - x->posY_old_2 = x->posY_old_1; - x->posY_old_1 = posY_new; - - x->posZ_old_2 = x->posZ_old_1; - x->posZ_old_1 = posZ_new; - - SETFLOAT(&(x->force[0]), x->forceX ); - SETFLOAT(&(x->force[1]), x->forceY ); - SETFLOAT(&(x->force[2]), x->forceZ ); - SETFLOAT(&(x->force[3]), sqrt( (x->forceX * x->forceX) + (x->forceY * x->forceY) + (x->forceZ * x->forceZ) )); - -// x->forceX=0; -// x->forceY=0; -// x->forceZ=0; - - x->forceX = random_bang3D(x)*1e-25; - x->forceY = random_bang3D(x)*1e-25; // avoiding denormal problem by adding low amplitude noise - x->forceZ = random_bang3D(x)*1e-25; - - - x->dX=0; - x->dY=0; - x->dZ=0; - - x->VX = x->posX_old_1 - x->posX_old_2; - x->VY = x->posY_old_1 - x->posY_old_2; - x->VZ = x->posZ_old_1 - x->posZ_old_2; - - SETFLOAT(&(x->vitesse[0]), x->VX ); - SETFLOAT(&(x->vitesse[1]), x->VY ); - SETFLOAT(&(x->vitesse[2]), x->VZ ); - SETFLOAT(&(x->vitesse[3]), sqrt( (x->VX * x->VX) + (x->VY * x->VY) + (x->VZ * x->VZ) )); - - outlet_anything(x->vitesse_out, gensym("velocity3D"), 4, x->vitesse); - outlet_anything(x->force_out, gensym("force3D"), 4, x->force); - outlet_anything(x->position3D_new, gensym("position3D"), 3, x->pos_new); - } -} - -void masse3D_reset(t_masse3D *x) -{ - - x->posX_old_2 = x->Xinit; - x->posX_old_1 = x->Xinit; - x->forceX=0; - - x->posY_old_2 = x->Yinit; - x->posY_old_1 = x->Yinit; - x->forceY=0; - - x->posZ_old_2 = x->Zinit; - x->posZ_old_1 = x->Zinit; - x->forceZ=0; - - x->VX = 0; - x->VY = 0; - x->VZ = 0; - - x->dX=0; - x->dY=0; - x->dZ=0; - - x->seuil=0; - - x->onoff = 1; - - SETFLOAT(&(x->pos_new[0]), x->Xinit ); - SETFLOAT(&(x->pos_new[1]), x->Yinit ); - SETFLOAT(&(x->pos_new[2]), x->Zinit ); - - SETFLOAT(&(x->force[0]), 0 ); - SETFLOAT(&(x->force[1]), 0 ); - SETFLOAT(&(x->force[2]), 0 ); - SETFLOAT(&(x->force[3]), 0 ); - - SETFLOAT(&(x->vitesse[0]), 0 ); - SETFLOAT(&(x->vitesse[1]), 0 ); - SETFLOAT(&(x->vitesse[2]), 0 ); - SETFLOAT(&(x->vitesse[3]), 0 ); - - outlet_anything(x->vitesse_out, gensym("velocity3D"), 4, x->vitesse); - outlet_anything(x->force_out, gensym("force3D"), 4, x->force); - outlet_anything(x->position3D_new, gensym("position3D"), 3, x->pos_new); - -} - - -void masse3D_resetf(t_masse3D *x) -{ - x->forceX=0; - x->forceY=0; - x->forceZ=0; - - x->dX=0; - x->dY=0; - x->dZ=0; -} - -void masse3D_inter_ambient(t_masse3D *x, t_symbol *s, int argc, t_atom *argv) -{ - t_float tmp; - - if (argc == 17) - // 0 : FX - // 1 : FY - // 2 : FZ - // 3 : RndX - // 4 : RndY - // 5 : RndZ - // 6 : D2 - // 7 : rien - // 8 : Xmin - // 9 : Xmax - // 10 : Ymin - // 11 : Ymax - // 12 : Zmin - // 13 : Zmax - // 14 : dX - // 15 : dY - // 16 : dZ - { - if (x->posX_old_1 > atom_getfloatarg(8, argc, argv)) - { - if (x->posX_old_1 < atom_getfloatarg(9, argc, argv)) - { - if (x->posY_old_1 > atom_getfloatarg(10, argc, argv)) - { - if (x->posY_old_1 < atom_getfloatarg(11, argc, argv)) - { - if (x->posZ_old_1 > atom_getfloatarg(12, argc, argv)) - { - if (x->posZ_old_1 < atom_getfloatarg(13, argc, argv)) - { - x->forceX += atom_getfloatarg(0, argc, argv); - x->forceY += atom_getfloatarg(1, argc, argv); // constant - x->forceZ += atom_getfloatarg(2, argc, argv); // constant - - x->forceX += random_bang3D(x)*atom_getfloatarg(3, argc, argv); - x->forceY += random_bang3D(x)*atom_getfloatarg(4, argc, argv); // random - x->forceZ += random_bang3D(x)*atom_getfloatarg(5, argc, argv); // random - - tmp = atom_getfloatarg(6, argc, argv); - if (tmp != 0) - { - x->forceX += tmp * ((x->posX_old_2)-(x->posX_old_1)); - x->forceY += tmp * ((x->posY_old_2)-(x->posY_old_1)); // damping - x->forceZ += tmp * ((x->posZ_old_2)-(x->posZ_old_1)); // damping - } - - x->dX += atom_getfloatarg(14, argc, argv); - x->dY += atom_getfloatarg(15, argc, argv); // constant - x->dZ += atom_getfloatarg(16, argc, argv); // constant - } - } - } - } - } - } - } - else - { - error("bad ambient interraction message"); - } -} - -void masse3D_inter_plane(t_masse3D *x, t_symbol *s, int argc, t_atom *argv) -{ - t_float a, b, c, d, profondeur, distance, tmp, profondeur_old; - - if (argc == 12) - // 0 : Xvector - // 1 : Yvector - // 2 : Zvector - // 3 : Xcenter - // 4 : Ycenter - // 5 : Zcenter - // 6 : FNCt - // 7 : KN - // 8 : damping de liaison (profondeur) - // 9 : Profondeur maximum - // 10 : deplacement normal X - // 11 : deplacement proportionel a P - - { - -// ax+by+cz-d=0 -// a = Xvector / |V| -// b = Yvector ... -// d est tel que aXcenter +bYcenter + cYcenter = d - - a = atom_getfloatarg(0, argc, argv); - b = atom_getfloatarg(1, argc, argv); - c = atom_getfloatarg(2, argc, argv); - - tmp = sqrt (a*a + b*b + c*c); - if (tmp != 0) - { - a /= tmp; - b /= tmp; - c /= tmp; - - } - else - { - a=1; - b=0; - c=0; - } - - d = a * atom_getfloatarg(3, argc, argv) + b * atom_getfloatarg(4, argc, argv) + c * atom_getfloatarg(5, argc, argv); -//C a optimiser : envoyer directement les coef directeur et l'offset -//C a faire pour les autres obj aussi - - profondeur = a * x->posX_old_1 + b * x->posY_old_1 + c * x->posZ_old_1 - d; - - if ( (profondeur < 0) & (profondeur > -atom_getfloatarg(9, argc, argv)) ) - { - - tmp = atom_getfloatarg(6, argc, argv); // force normal constante - - x->forceX += tmp * a; - x->forceY += tmp * b; - x->forceZ += tmp * c; - - tmp = atom_getfloatarg(7, argc, argv); // force normal proportionelle a la profondeur - tmp *= profondeur; - x->forceX -= tmp * a; - x->forceY -= tmp * b; - x->forceZ -= tmp * c; - - tmp = atom_getfloatarg(8, argc, argv); // force normal proportionelle a la profondeur - - profondeur_old = a * x->posX_old_2 + b * x->posY_old_2 + c * x->posZ_old_2 - d; - tmp *= (profondeur - profondeur_old); - x->forceX -= tmp * a; - x->forceY -= tmp * b; - x->forceZ -= tmp * c; - - - tmp = atom_getfloatarg(10, argc, argv); // deplacement normal constant - - x->dX += tmp * a; - x->dY += tmp * b; - x->dZ += tmp * c; - - tmp = atom_getfloatarg(11, argc, argv); // deplacement normal proportionel - tmp *= profondeur; - - x->dX -= tmp * a; - x->dY -= tmp * b; - x->dZ -= tmp * c; - } - - } - else - { - error("bad plane interraction message"); - } -} - - -void masse3D_inter_sphere(t_masse3D *x, t_symbol *s, int argc, t_atom *argv) -{ -t_float posx1, posy1, posz1, Nx, Ny, Nz, dx, dy, dz, distance, Dmax, tmp; -t_float deltaX_old, deltaY_old, deltaZ_old, distance_old ; - - if (argc == 17) - // 0 : Xcentre - // 1 : Ycendre - // 2 : Zcentre - // 3 : Rmin - // 4 : Rmax - // 5 : F normal - // 6 : K normal - // 7 : F normal proportionel a 1/R - // 8 : Damp de liason normal - // 9 : deplacement N Ct - // 10 : position ancienne de l'interacteur en X - // 11 : position abcienne de l'interacteur en Y - // 12 : position abcienne de l'interacteur en Z - // 13 : d dormal proportionel a R - // 14 : force normal proportionel a 1/R2 - // 15 : d dormal proportionel a 1/R - // 16 : d dormal proportionel a 1/R*R - - { - posx1 = atom_getfloatarg(0, argc, argv); - posy1 = atom_getfloatarg(1, argc, argv); - posz1 = atom_getfloatarg(2, argc, argv); - Nx = (x->posX_old_1)-posx1; // vecteur deplacement X - Ny = (x->posY_old_1)-posy1; // vecteur deplacement Y - Nz = (x->posZ_old_1)-posz1; // vecteur deplacement Y - - distance = sqrt((Nx * Nx)+(Ny * Ny)+(Nz * Nz)); // distance entre le centre de l'interaction, et le pts - - Nx = Nx/distance; // composante X de la normal (normalisé) - Ny = Ny/distance; // composante Y de la normal. - Nz = Nz/distance; // composante Y de la normal. - - Dmax= atom_getfloatarg(4, argc, argv); // distance max de l'interaction - if ( (distance > atom_getfloatarg(3, argc, argv)) & (distance < Dmax) ) - { - tmp = atom_getfloatarg(5, argc, argv); // force constante normal - x->forceX += tmp * Nx; - x->forceY += tmp * Ny; - x->forceZ += tmp * Nz; - - tmp = atom_getfloatarg(6, argc, argv); // force variable (K) normal - tmp *= ( Dmax-distance ); - x->forceX += tmp * Nx ; - x->forceY += tmp * Ny ; - x->forceZ += tmp * Nz ; - - tmp = atom_getfloatarg(7, argc, argv); // force normal proportionel a 1/r - if ( (distance != 0) & (tmp != 0) ) - { - tmp /= distance; - x->forceX += tmp * Nx; - x->forceY += tmp * Ny; - x->forceZ += tmp * Nz ; - } - - tmp = atom_getfloatarg(8, argc, argv); // damping2 normal - tmp *= ( x->VX * Nx + x->VY * Ny + x->VZ * Nz ); - x->forceX -= tmp * Nx ; - x->forceY -= tmp * Ny ; - x->forceZ -= tmp * Nz ; - - tmp = atom_getfloatarg(9, argc, argv); // d normal - x->dX += tmp * Nx ; - x->dY += tmp * Ny ; - x->dZ += tmp * Nz ; - - tmp = atom_getfloatarg(13, argc, argv); // force normal proportionel a 1/r2 - if ( (distance != 0) & (tmp != 0) ) - { - tmp /= (distance * distance); - x->forceX += tmp * Nx ; - x->forceY += tmp * Ny ; - x->forceZ += tmp * Nz ; - } - - tmp = atom_getfloatarg(14, argc, argv); // deplacement variable (K) normal - tmp *= ( Dmax-distance ); - x->dX += tmp * Nx ; - x->dY += tmp * Ny ; - x->dZ += tmp * Nz ; - - tmp = atom_getfloatarg(15, argc, argv); // deplacement normal proportionel a 1/r - if ( (distance != 0) & (tmp != 0) ) - { - tmp /= distance; - x->dX += tmp * Nx ; - x->dY += tmp * Ny ; - x->dZ += tmp * Nz ; - } - - tmp = atom_getfloatarg(16, argc, argv); // deplacement normal proportionel a 1/r2 - if ( (distance != 0) & (tmp != 0) ) - { - tmp /= (distance * distance); - x->dX += tmp * Nx; - x->dY += tmp * Ny; - x->dZ += tmp * Nz; - } - - } - } - else - { - error("bad interact_3D_sphere message"); - } -} - - -void masse3D_inter_circle(t_masse3D *x, t_symbol *s, int argc, t_atom *argv) -{ - t_float a, b, c, d, profondeur, distance, tmp, profondeur_old, rayon, rayon_old; - - if (argc == 14) - // 0 : Xvector - // 1 : Yvector - // 2 : Zvector - // 3 : Xcenter - // 4 : Ycenter - // 5 : Zcenter - // 6 : Rmin - // 7 : RMax - // 8 : FNCt - // 9 : KN - // 10 : damping de liaison (profondeur) - // 11 : Profondeur maximum - // 12 : dN - // 13 : dKN - - { -// ax+by+cz-d=0 -// a = Xvector / |V| -// b = Yvector ... -// d est tel que aXcenter +bYcenter + cYcenter = d - - a = atom_getfloatarg(0, argc, argv); - b = atom_getfloatarg(1, argc, argv); - c = atom_getfloatarg(2, argc, argv); - - tmp = sqrt (a*a + b*b + c*c); - if (tmp != 0) - { - a /= tmp; - b /= tmp; - c /= tmp; - } - else - { - a=1; - b=0; - c=0; - } - - d = a * atom_getfloatarg(3, argc, argv) + b * atom_getfloatarg(4, argc, argv) + c * atom_getfloatarg(5, argc, argv); - - profondeur = a * x->posX_old_1 + b * x->posY_old_1 + c * x->posZ_old_1 - d; - - rayon = sqrt ( pow(x->posX_old_1-atom_getfloatarg(3, argc, argv), 2) +pow(x->posY_old_1-atom_getfloatarg(4, argc, argv) , 2) + pow(x->posZ_old_1 - atom_getfloatarg(5, argc, argv) , 2) - profondeur*profondeur ); - - if ( (profondeur < 0) & (profondeur > - atom_getfloatarg(11, argc, argv)) & (rayon > atom_getfloatarg(6, argc, argv)) & (rayon < atom_getfloatarg(7, argc, argv))) - { - - tmp = atom_getfloatarg(8, argc, argv); // force normal constante - - x->forceX += tmp * a; - x->forceY += tmp * b; - x->forceZ += tmp * c; - - tmp = atom_getfloatarg(9, argc, argv); // force normal proportionelle a la profondeur - tmp *= profondeur; - x->forceX -= tmp * a; - x->forceY -= tmp * b; - x->forceZ -= tmp * c; - - tmp = atom_getfloatarg(10, argc, argv); // force normal proportionelle a la profondeur - - profondeur_old = a * x->posX_old_2 + b * x->posY_old_2 + c * x->posZ_old_2 - d; - tmp *= (profondeur - profondeur_old); - - x->forceX -= tmp * a; - x->forceY -= tmp * b; - x->forceZ -= tmp * c; - - tmp = atom_getfloatarg(12, argc, argv); // deplacement normal constante - x->dX += tmp * a; - x->dY += tmp * b; - x->dZ += tmp * c; - - tmp = atom_getfloatarg(13, argc, argv); // deplacement normal proportionelle a la profondeur - tmp *= profondeur; - x->dX -= tmp * a; - x->dY -= tmp * b; - x->dZ -= tmp * c; - } - } - else - { - error("bad circle interraction message"); - } -} - - -void masse3D_inter_cylinder(t_masse3D *x, t_symbol *s, int argc, t_atom *argv) -{ - t_float a, b, c, d, profondeur, profondeur_old, distance, tmp, rayon_old, rayon; - t_float Xb, Yb, Zb, Ta, Tb, Tc, Xb_old, Yb_old, Zb_old; - - if (argc == 21) - // 0 : Xvector - // 1 : Yvector - // 2 : Zvector - // 3 : Xcenter - // 4 : Ycenter - // 5 : Zcenter - // 6 : Rmin - // 7 : Rmax - // 8 : FNCt - // 9 : KN - // 10 : damping de liaison (rayon) - // 11 : FN 1/R - // 12 : FN 1/R2 - // 13 : Pmin - // 14 : Pmax - // 15 : FTct - // 16 : KT - // 17 : dNct - // 18 : dTct - // 19 : dKN - // 20 : dKT - - { - -// ax+by+cz-d=0 -// a = Xvector / |V| -// b = Yvector ... -// d est tel que aXcenter +bYcenter + cYcenter = d - - a = atom_getfloatarg(0, argc, argv); - b = atom_getfloatarg(1, argc, argv); - c = atom_getfloatarg(2, argc, argv); - - tmp = sqrt (a*a + b*b + c*c); - if (tmp != 0) - { - a /= tmp; - b /= tmp; - c /= tmp; - } - else - { - a=1; - b=0; - c=0; - } - - d = a * atom_getfloatarg(3, argc, argv) + b * atom_getfloatarg(4, argc, argv) + c * atom_getfloatarg(5, argc, argv); - - profondeur = a * x->posX_old_1 + b * x->posY_old_1 + c * x->posZ_old_1 - d; - - Xb = x->posX_old_1 - atom_getfloatarg(3, argc, argv) - profondeur * a; - Yb = x->posY_old_1 - atom_getfloatarg(4, argc, argv) - profondeur * b; - Zb = x->posZ_old_1 - atom_getfloatarg(5, argc, argv) - profondeur * c; - - rayon = sqrt ( pow(Xb, 2) + pow(Yb, 2) + pow(Zb, 2) ); - - if (rayon != 0) - { - Xb /= rayon; // normalisation - Yb /= rayon; - Zb /= rayon; - } - else - { - Xb = 0; // normalisation - Yb = 0; - Zb = 0; - } - - - Ta = b*Zb - c*Yb; // vecteur tengentiel = vecteur vectoriel rayon - Tb = c*Xb - a*Zb; - Tc = a*Yb - b*Xb; - - if ( (profondeur < atom_getfloatarg(14, argc, argv)) & (profondeur > atom_getfloatarg(13, argc, argv)) & (rayon < atom_getfloatarg(7, argc, argv)) & (rayon > atom_getfloatarg(6, argc, argv)) ) - { - - tmp = atom_getfloatarg(8, argc, argv); // force normal constante - - x->forceX += tmp * Xb; - x->forceY += tmp * Yb; - x->forceZ += tmp * Zb; - - tmp = atom_getfloatarg(9, argc, argv); // rigidité normal proportionelle - tmp *= ( atom_getfloatarg(7, argc, argv) - rayon ) ; - x->forceX += tmp * Xb; - x->forceY += tmp * Yb; - x->forceZ += tmp * Zb; - - tmp = atom_getfloatarg(10, argc, argv); // damping normal proportionelle a la profondeur - - profondeur_old = a * x->posX_old_2 + b * x->posY_old_2 + c * x->posZ_old_2 - d; - - Xb_old = x->posX_old_2 - atom_getfloatarg(3, argc, argv) - profondeur_old * a; - Yb_old = x->posY_old_2 - atom_getfloatarg(4, argc, argv) - profondeur_old * b; - Zb_old = x->posZ_old_2 - atom_getfloatarg(5, argc, argv) - profondeur_old * c; - - rayon_old = sqrt ( pow(Xb_old, 2) + pow(Yb_old, 2) + pow(Zb_old, 2) ); - - tmp *= (rayon - rayon_old); - - x->forceX -= tmp * Xb; - x->forceY -= tmp * Yb; - x->forceZ -= tmp * Zb; - - tmp = atom_getfloatarg(11, argc, argv); // force normal proportionne a 1/R - if (rayon != 0) - { - tmp /= rayon; - x->forceX += tmp * Xb; - x->forceY += tmp * Yb; - x->forceZ += tmp * Zb; - } - - tmp = atom_getfloatarg(12, argc, argv); // force normal proportionne a 1/R*R - if (rayon != 0) - { - tmp /= (rayon*rayon); - x->forceX += tmp * Xb; - x->forceY += tmp * Yb; - x->forceZ += tmp * Zb; - } - - tmp = atom_getfloatarg(15, argc, argv); // force tengente constante - x->forceX -= tmp * Ta; - x->forceY -= tmp * Tb; - x->forceZ -= tmp * Tc; - - tmp = atom_getfloatarg(16, argc, argv); // rigidité tengentiel proportionelle - tmp *= ( atom_getfloatarg(7, argc, argv) - rayon ) ; - x->forceX += tmp * Ta; - x->forceY += tmp * Tb; - x->forceZ += tmp * Tc; - - tmp = atom_getfloatarg(17, argc, argv); // deplacement normal constante - - x->dX += tmp * Xb; - x->dY += tmp * Yb; - x->dZ += tmp * Zb; - - tmp = atom_getfloatarg(19, argc, argv); // deplacement normal proportionelle - tmp *= ( atom_getfloatarg(7, argc, argv) - rayon ) ; - x->dX += tmp * Xb; - x->dY += tmp * Yb; - x->dZ += tmp * Zb; - - tmp = atom_getfloatarg(18, argc, argv); // deplacement tengente constante - x->dX += tmp * Ta; - x->dY += tmp * Tb; - x->dZ += tmp * Tc; - - tmp = atom_getfloatarg(20, argc, argv); // deplacement tengentiel proportionelle - tmp *= ( atom_getfloatarg(7, argc, argv) - rayon ) ; - x->dX += tmp * Ta; - x->dY += tmp * Tb; - x->dZ += tmp * Tc; - } - } - else - { - error("bad cylinder interraction message"); - } -} - -void *masse3D_new(t_symbol *s, int argc, t_atom *argv) -{ - t_masse3D *x = (t_masse3D *)pd_new(masse3D_class); - - x->x_sym = atom_getsymbolarg(0, argc, argv); - x->x_state = makeseed(); - - pd_bind(&x->x_obj.ob_pd, atom_getsymbolarg(0, argc, argv)); - - x->position3D_new=outlet_new(&x->x_obj, 0); - x->force_out=outlet_new(&x->x_obj, 0); - x->vitesse_out=outlet_new(&x->x_obj, 0); - - x->forceX=0; - x->forceY=0; - x->forceZ=0; - - if (argc >= 2) - x->masse3D = atom_getfloatarg(1, argc, argv) ; - else - x->masse3D = 1; - - x->onoff = 1; - - x->VX = 0; - x->VY = 0; - x->VZ = 0; - - x->dX=0; - x->dY=0; - x->dZ=0; - - if (argc >= 3) - x->Xinit = atom_getfloatarg(2, argc, argv); - else - x->Xinit = 0 ; - - x->posX_old_1 = x->Xinit ; - x->posX_old_2 = x->Xinit; - SETFLOAT(&(x->pos_new[0]), x->Xinit); - - if (argc >= 4) - x->Yinit = atom_getfloatarg(3, argc, argv); - else - x->Yinit = 0 ; - - x->posY_old_1 = x->Yinit ; - x->posY_old_2 = x->Yinit; - SETFLOAT(&(x->pos_new[1]), x->Yinit); - - if (argc >= 5) - x->Zinit = atom_getfloatarg(4, argc, argv); - else - x->Zinit = 0 ; - - x->posZ_old_1 = x->Zinit ; - x->posZ_old_2 = x->Zinit; - SETFLOAT(&(x->pos_new[2]), x->Zinit); - - - if (argc >= 6) - x->minX = atom_getfloatarg(5, argc, argv) ; - else - x->minX = -100000; - - if (argc >= 7) - x->maxX = atom_getfloatarg(6, argc, argv) ; - else - x->maxX = 100000; - - if (argc >= 8) - x->minY = atom_getfloatarg(7, argc, argv) ; - else - x->minY = -100000; - - if (argc >= 9) - x->maxY = atom_getfloatarg(8, argc, argv) ; - else - x->maxY = 100000; - - if (argc >= 10) - x->minZ = atom_getfloatarg(9, argc, argv) ; - else - x->minZ = -100000; - - if (argc >= 11) - x->maxZ = atom_getfloatarg(10, argc, argv) ; - else - x->maxZ = 100000; - - if (argc >= 12) - x->seuil = atom_getfloatarg(11, argc, argv) ; - else - x->seuil = 0; - - if (argc >= 13) - x->damp = atom_getfloatarg(12, argc, argv) ; - else - x->damp = 0; - - return (void *)x; -} - -static void masse3D_free(t_masse3D *x) -{ - pd_unbind(&x->x_obj.ob_pd, x->x_sym); -} - - -void masse3D_setup(void) -{ - - masse3D_class = class_new(gensym("masse3D"), - (t_newmethod)masse3D_new, - (t_method)masse3D_free, - sizeof(t_masse3D), - CLASS_DEFAULT, A_GIMME, 0); - - class_addcreator((t_newmethod)masse3D_new, gensym("mass3D"), A_GIMME, 0); - class_addcreator((t_newmethod)masse3D_new, gensym("pmpd.mass3D"), A_GIMME, 0); - - class_addmethod(masse3D_class, (t_method)masse3D_force, gensym("force3D"),A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); - class_addbang(masse3D_class, masse3D_bang); - - class_addmethod(masse3D_class, (t_method)masse3D_dX, gensym("dX"), A_DEFFLOAT, 0); - class_addmethod(masse3D_class, (t_method)masse3D_dY, gensym("dY"), A_DEFFLOAT, 0); - class_addmethod(masse3D_class, (t_method)masse3D_dZ, gensym("dZ"), A_DEFFLOAT, 0); - class_addmethod(masse3D_class, (t_method)masse3D_dXYZ, gensym("dXYZ"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); - class_addmethod(masse3D_class, (t_method)masse3D_setX, gensym("setX"), A_DEFFLOAT, 0); - class_addmethod(masse3D_class, (t_method)masse3D_setY, gensym("setY"), A_DEFFLOAT, 0); - class_addmethod(masse3D_class, (t_method)masse3D_setZ, gensym("setZ"), A_DEFFLOAT, 0); - class_addmethod(masse3D_class, (t_method)masse3D_setXYZ, gensym("setXYZ"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); - class_addmethod(masse3D_class, (t_method)masse3D_minX, gensym("setXmin"), A_DEFFLOAT, 0); - class_addmethod(masse3D_class, (t_method)masse3D_minY, gensym("setYmin"), A_DEFFLOAT, 0); - class_addmethod(masse3D_class, (t_method)masse3D_maxX, gensym("setXmax"), A_DEFFLOAT, 0); - class_addmethod(masse3D_class, (t_method)masse3D_maxY, gensym("setYmax"), A_DEFFLOAT, 0); - class_addmethod(masse3D_class, (t_method)masse3D_minZ, gensym("setZmin"), A_DEFFLOAT, 0); - class_addmethod(masse3D_class, (t_method)masse3D_maxZ, gensym("setZmax"), A_DEFFLOAT, 0); - class_addmethod(masse3D_class, (t_method)masse3D_set_masse3D, gensym("setM"), A_DEFFLOAT, 0); - class_addmethod(masse3D_class, (t_method)masse3D_reset, gensym("reset"), 0); - class_addmethod(masse3D_class, (t_method)masse3D_resetf, gensym("resetF"), 0); - class_addmethod(masse3D_class, (t_method)masse3D_reset, gensym("loadbang"), 0); - class_addmethod(masse3D_class, (t_method)masse3D_on, gensym("on"), 0); - class_addmethod(masse3D_class, (t_method)masse3D_off, gensym("off"), 0); - class_addmethod(masse3D_class, (t_method)masse3D_seuil, gensym("setT"), A_DEFFLOAT, 0); - class_addmethod(masse3D_class, (t_method)masse3D_damp, gensym("setD"), A_DEFFLOAT, 0); - - class_addmethod(masse3D_class, (t_method)masse3D_inter_ambient, gensym("interactor_ambient_3D"), A_GIMME, 0); - class_addmethod(masse3D_class, (t_method)masse3D_inter_sphere, gensym("interactor_sphere_3D"), A_GIMME, 0); - class_addmethod(masse3D_class, (t_method)masse3D_inter_plane, gensym("interactor_plane_3D"), A_GIMME, 0); - class_addmethod(masse3D_class, (t_method)masse3D_inter_circle, gensym("interactor_circle_3D"), A_GIMME, 0); - class_addmethod(masse3D_class, (t_method)masse3D_inter_cylinder, gensym("interactor_cylinder_3D"), A_GIMME, 0); - -} diff --git a/src/pmpd.c b/src/pmpd.c index 690c1d2..78c2f7f 100755 --- a/src/pmpd.c +++ b/src/pmpd.c @@ -28,10 +28,11 @@ */ #ifndef VERSION -#define VERSION "0.06" +#define VERSION "0.07" #endif -// #include "m_pd.h" +#include "m_pd.h" +#include "stdio.h" #ifndef __DATE__ #define __DATE__ "" @@ -46,7 +47,8 @@ #define max(a,b) ( ((a) > (b)) ? (a) : (b) ) #define min(a,b) ( ((a) < (b)) ? (a) : (b) ) - + +/* #include "masse.c" #include "lia.c" #include "masse2D.c" @@ -79,9 +81,41 @@ #include "tCylinder3D.c" #include "tLia3D.c" -#include "pmpd~.c" +#include "pmpd~.c" +*/ static t_class *pmpd_class; + +typedef struct _mass { + t_int Id; + t_float invM; + t_float speedX; + t_float posX; + t_float forceX; +} foo; + +typedef struct _link { + t_int Id; + struct _mass *mass1; + struct _mass *mass2; + t_float Ke, K1, D1, K2, D2; +} foo1 ; + +typedef struct _out { + // TODO ajouter un type pour diferencier les outlets en forces et celles en position + t_int Id; + t_int nbr_outlet; + struct _mass *mass1; + t_float influence; +} foo2; + +typedef struct _in { + // TODO ajouter un type pour diferencier les inlets en forces et celles en position + t_int Id; + t_int nbr_inlet; + struct _mass *mass1; + t_float influence; +} foo3; typedef struct _pmpd { @@ -96,9 +130,6 @@ typedef struct _pmpd int nb_link, nb_mass, nb_outlet, nb_inlet, nb_in, nb_out; } t_pmpd; -#define max(a,b) ( ((a) > (b)) ? (a) : (b) ) -#define min(a,b) ( ((a) < (b)) ? (a) : (b) ) - void pmpd_bang(t_pmpd *x) /////////////////////////////////////////////////////////////////////////////////// // this part is doing all the job! @@ -330,7 +361,7 @@ void pmpd_setup(void) class_addmethod(pmpd_class, (t_method)pmpd_forceX_20, gensym("forceX_20"), A_DEFFLOAT, 0); class_addmethod(pmpd_class, (t_method)pmpd_reset, gensym("reset"), 0); - +/* post(""); post(" pmpd = Physical Modeling for Pure Data"); post(" version "VERSION); @@ -371,5 +402,6 @@ tCircle3D_setup(); pmpd_tilde_setup(); +*/ } diff --git a/src/pmpd~.c b/src/pmpd~.c index ed17b68..62013a6 100755 --- a/src/pmpd~.c +++ b/src/pmpd~.c @@ -15,6 +15,13 @@ #define max(a,b) ( ((a) > (b)) ? (a) : (b) ) #define min(a,b) ( ((a) < (b)) ? (a) : (b) ) + +#define nb_max_link 2000 +#define nb_max_mass 2000 +#define nb_max_out 200 +#define nb_max_in 200 +#define nb_max_outlet 20 +#define nb_max_inlet 20 // hard-coded on the methods definition static t_class *pmpd_tilde_class; @@ -31,7 +38,7 @@ typedef struct _link { struct _mass *mass1; struct _mass *mass2; t_float Ke, K1, D1, K2, D2; -} foo1; +} foo1 ; typedef struct _out { // TODO ajouter un type pour diferencier les outlets en forces et celles en position -- cgit v1.2.1