From f4e258a9d70ea1355e3e4bcce676e35c511ff3f3 Mon Sep 17 00:00:00 2001 From: Cyrille Henry Date: Mon, 8 Apr 2013 20:42:34 +0000 Subject: add a "overdamp factor" svn path=/trunk/externals/pmpd/; revision=17070 --- pmpd3d.c | 3 ++- pmpd3d.h | 3 ++- pmpd3d_core.c | 25 ++++++++++++++++++++++++- pmpd3d_set.c | 24 ++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 3 deletions(-) diff --git a/pmpd3d.c b/pmpd3d.c index 5c9515b..ace3541 100644 --- a/pmpd3d.c +++ b/pmpd3d.c @@ -99,7 +99,8 @@ void pmpd3d_setup(void) class_addmethod(pmpd3d_class, (t_method)pmpd3d_posX, gensym("setPosX"), A_GIMME, 0); class_addmethod(pmpd3d_class, (t_method)pmpd3d_posY, gensym("setPosY"), A_GIMME, 0); class_addmethod(pmpd3d_class, (t_method)pmpd3d_posZ, gensym("setPosZ"), A_GIMME, 0); - + class_addmethod(pmpd3d_class, (t_method)pmpd3d_overdamp, gensym("setOverdamp"), A_GIMME, 0); + /* pmpd3d_get -- diff --git a/pmpd3d.h b/pmpd3d.h index 88d21ab..4101f54 100644 --- a/pmpd3d.h +++ b/pmpd3d.h @@ -26,6 +26,7 @@ typedef struct _mass { t_float forceZ; t_float D2; t_float D2offset; + t_float overdamp; int num; } foo; @@ -65,4 +66,4 @@ typedef struct _pmpd3d { t_float minX, maxX, minY, maxY, minZ, maxZ; t_int grab; // si on grab une mass ou pas t_int grab_nb; // la masse grabé -} t_pmpd3d; \ No newline at end of file +} t_pmpd3d; diff --git a/pmpd3d_core.c b/pmpd3d_core.c index a2a0d16..1ad06fd 100644 --- a/pmpd3d_core.c +++ b/pmpd3d_core.c @@ -74,7 +74,7 @@ void *pmpd3d_new() void pmpd3d_bang(t_pmpd3d *x) { // this part is doing all the PM - t_float F, L, Lx,Ly, Lz, Fx, Fy, Fz, tmpX, tmpY, tmpZ, speed; + t_float F, L, Lx,Ly, Lz, Fx, Fy, Fz, tmp, tmpX, tmpY, tmpZ, speed; t_int i; // post("bang"); @@ -82,15 +82,34 @@ void pmpd3d_bang(t_pmpd3d *x) // compute new masses position if (x->mass[i].mobile > 0) // only if mobile { + // amplify force that opose to movement + if (x->mass[i].overdamp != 0) + { + tmp = x->mass[i].speedX * x->mass[i].forceX + x->mass[i].speedY * x->mass[i].forceY + x->mass[i].speedZ * x->mass[i].forceZ; + tmp = min(0,tmp); // overdamped only if force opose movment + tmp *= -x->mass[i].overdamp; + tmp += 1; + x->mass[i].forceX *= tmp; + x->mass[i].forceY *= tmp; + x->mass[i].forceZ *= tmp; + } + + // compute new velocity thanks to forces. (Forces = M * acceleration) x->mass[i].speedX += x->mass[i].forceX * x->mass[i].invM; x->mass[i].speedY += x->mass[i].forceY * x->mass[i].invM; x->mass[i].speedZ += x->mass[i].forceZ * x->mass[i].invM; + + // no need to reset force to 0, because we compute a new force latter thanks to velocity damping // x->mass[i].forceX = 0; // x->mass[i].forceY = 0; // x->mass[i].forceZ = 0; + + // compute new speed thanks to new velocity x->mass[i].posX += x->mass[i].speedX ; x->mass[i].posY += x->mass[i].speedY ; x->mass[i].posZ += x->mass[i].speedZ ; + + // space limitation if ( (x->mass[i].posX < x->minX) || (x->mass[i].posX > x->maxX) || (x->mass[i].posY < x->minY) || (x->mass[i].posY > x->maxY) || (x->mass[i].posZ < x->minZ) || (x->mass[i].posZ > x->maxZ) ) { @@ -104,9 +123,12 @@ void pmpd3d_bang(t_pmpd3d *x) x->mass[i].posY = tmpY; x->mass[i].posZ = tmpZ; } + // velocity damping of every masse (set a new force) x->mass[i].forceX = -x->mass[i].D2 * x->mass[i].speedX; x->mass[i].forceY = -x->mass[i].D2 * x->mass[i].speedY; x->mass[i].forceZ = -x->mass[i].D2 * x->mass[i].speedZ; + + // offset on velocity damping (to impose a specific velocity) speed = sqrt(x->mass[i].speedX * x->mass[i].speedX + x->mass[i].speedY * x->mass[i].speedY + x->mass[i].speedZ * x->mass[i].speedZ); if (speed != 0) { x->mass[i].forceX += x->mass[i].D2offset * (x->mass[i].speedX/speed); @@ -186,6 +208,7 @@ void pmpd3d_mass(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv) x->mass[x->nb_mass].num = x->nb_mass; x->mass[x->nb_mass].D2 = 0; x->mass[x->nb_mass].D2offset = 0; + x->mass[x->nb_mass].overdamp = 0; x->nb_mass++ ; x->nb_mass = min ( nb_max_mass -1, x->nb_mass ); diff --git a/pmpd3d_set.c b/pmpd3d_set.c index 3577613..1e5dddc 100644 --- a/pmpd3d_set.c +++ b/pmpd3d_set.c @@ -677,3 +677,27 @@ void pmpd3d_posZ(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv) } } + +void pmpd3d_overdamp(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv) +{ +// set the overdamped factor to a mass + t_int tmp, i; + + if ( (argc == 2) && ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) ) + { + tmp = atom_getfloatarg(0, argc, argv); + tmp = max(0, min( x->nb_mass-1, tmp)); + x->mass[tmp].overdamp = atom_getfloatarg(1, argc, argv); + } + if ( (argc == 2) && ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) ) + { + for (i=0; i< x->nb_mass; i++) + { + if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id) + { + x->mass[i].overdamp = atom_getfloatarg(1, argc, argv); + } + } + } +} + -- cgit v1.2.1