diff options
author | N.N. <nimon@users.sourceforge.net> | 2010-09-09 16:01:37 +0000 |
---|---|---|
committer | N.N. <nimon@users.sourceforge.net> | 2010-09-09 16:01:37 +0000 |
commit | 523126a054dfdee92a8a406fe5bee1161cace43e (patch) | |
tree | 52b3eafac7e64f48ff217a0134b22e53457dd9e0 /msd/src | |
parent | 9b8e2098faf60ee901b2a1a61a6c17760260954b (diff) |
svn path=/trunk/externals/nusmuk/; revision=14024
Diffstat (limited to 'msd/src')
-rwxr-xr-x | msd/src/build.sh | 4 | ||||
-rw-r--r-- | msd/src/msd.h | 264 |
2 files changed, 225 insertions, 43 deletions
diff --git a/msd/src/build.sh b/msd/src/build.sh index 869e17c..4f3b3d3 100755 --- a/msd/src/build.sh +++ b/msd/src/build.sh @@ -16,8 +16,8 @@ UNAME=`uname -s` if [ $UNAME = "Darwin" ] then mv ../msd/pd-darwin/release-single/msd.pd_darwin ../msd/msd.pd_darwin - mv ../msd2D/pd-darwin/release-single/msd2D.pd_darwin ../msd/msd2D.pd_darwin - mv ../msd3D/pd-darwin/release-single/msd3D.pd_darwin ../msd/msd3D.pd_darwin + mv ../msd2D/pd-darwin/release-single/msd2D.pd_darwin ../msd2D/msd2D.pd_darwin + mv ../msd3D/pd-darwin/release-single/msd3D.pd_darwin ../msd3D/msd3D.pd_darwin fi if [ $UNAME = "Linux" ] diff --git a/msd/src/msd.h b/msd/src/msd.h index 1e1b6f2..dac7533 100644 --- a/msd/src/msd.h +++ b/msd/src/msd.h @@ -56,10 +56,9 @@ #define DELARR(var) ((void)0) #endif - +// Maths functions inline t_float sqr(t_float x) { return x*x; } - template<int N> class Link; template<int N> @@ -163,7 +162,11 @@ public: }; template<int N> -class Link { +class Link +//public flext_base +{ +// FLEXT_HEADER(Link,flext_base) + public: t_int nbr; const t_symbol *Id; @@ -174,12 +177,17 @@ public: t_float puissance; t_int link_type; //0 : no, 1 : tangential, 2 : normal t_float tdirection1[N], tdirection2[N]; + const t_symbol *k_tabname, *d_tabname; + flext::buffer *k_tab, *d_tab; + t_float l_tab; - Link(t_int n,const t_symbol *id,Mass<N> *m1,Mass<N> *m2,t_float k1,t_float d1, t_int o=0, t_float tangent[N]=NULL,t_float pow=1, t_float lmin = 0,t_float lmax = 1e10) + Link(t_int n,const t_symbol *id,Mass<N> *m1,Mass<N> *m2,t_float k1,t_float d1, t_int o=0, t_float tangent[N]=NULL,t_float pow=1, t_float lmin = 0,t_float lmax = 1e10,const t_symbol *ktab=NULL,const t_symbol *dtab=NULL, t_int ltab=1) : nbr(n),Id(id) , mass1(m1),mass2(m2) , K1(k1),D1(d1),D2(0),link_type(o),puissance(pow) , long_min(lmin),long_max(lmax) + , k_tabname(ktab), d_tabname(dtab), l_tab(ltab) + , k_tab(NULL),d_tab(NULL) { for (int i=0; i<N; i++) { tdirection1[i] = 0; @@ -201,6 +209,23 @@ public: distance_old = sqrt(distance_old); longueur = distance_old; } + else if (link_type == 3) { // TAB LINK + distance_old = longueur = Mass<N>::dist(*mass1,*mass2); + if (k_tabname) { + if(k_tab) + delete k_tab; + k_tab = new flext::buffer(k_tabname); + if(!k_tab->Ok()) + post("warning: buffer is currently not valid!"); + } + if (d_tabname) { + if(d_tab) + delete d_tab; + d_tab = new flext::buffer(d_tabname); + if(!d_tab->Ok()) + post("warning: buffer is currently not valid!"); + } + } /*else if (link_type == 2) { // NORMAL LINK 2D if (N >= 2) { const t_float norme = sqrt(sqr(xa)+sqr(ya)); @@ -242,6 +267,23 @@ public: mass2->links.erase(this); } + inline t_float interp_buf(t_float indexf, flext::buffer *buf, t_float factor) { + t_int size_buf=buf->Frames(); + t_float index_factor = indexf*(size_buf-1)/factor; + if (index_factor > size_buf - 1) + return buf->Data()[(int)floor(indexf)]; + else if (index_factor < 0) + return buf->Data()[0]; + else { + t_int index = floor(index_factor); + t_float interp = index_factor - (float)index; + if (index=index_factor) + return buf->Data()[index]; + else + return interp * buf->Data()[index] + (1-interp) * buf->Data()[index+1]; + } + } + // compute link forces inline void compute() { @@ -249,9 +291,7 @@ public: t_float F; Mass<N> *m1 = mass1,*m2 = mass2; // cache locally if (m1->invM || m2->invM) { - if (link_type == 0) - distance = Mass<N>::dist(*m1,*m2); - else if (link_type == 1) { + if (link_type == 1) { for(int i = 0; i < N; ++i) distance += sqr((m1->pos[i]-m2->pos[i])*tdirection1[i]); distance = sqrt(distance); @@ -261,7 +301,9 @@ public: distance += sqr((m1->pos[i]-m2->pos[i])*(tdirection1[i] +tdirection2[i])); distance = sqrt(distance); } - + else + distance = Mass<N>::dist(*m1,*m2); + if (distance < long_min || distance > long_max || distance == 0) { // for(int i = 0; i < N; ++i) { // m1->force[i] -= D2 * m1->speed[i]; // Fx1[n] = -Fx, Fx1[n] = Fx1[n] - D2 * vx1[n-1] @@ -270,28 +312,42 @@ public: } else { // Lmin < L < Lmax // F[n] = k1 (L[n] - L[0])/L[n] + D1 (L[n] - L[n-1])/L[n] - if ((distance - longueur)>0) - F = (K1 * pow(distance - longueur,puissance) + D1 * (distance - distance_old))/distance ; - else - F = (-K1 * pow(longueur - distance,puissance) + D1 * (distance - distance_old))/distance ; - if (link_type == 0) - for(int i = 0; i < N; ++i) { - const t_float Fn = F * (m1->pos[i] - m2->pos[i]); // Fx = F * Lx[n]/L[n] - m1->force[i] -= Fn + D2 * m1->speed[i]; // Fx1[n] = -Fx, Fx1[n] = Fx1[n] - D2 * vx1[n-1] - m2->force[i] += Fn - D2 * m2->speed[i]; // Fx2[n] = Fx, Fx2[n] = Fx2[n] - D2 * vx2[n-1] - } - else if (link_type == 1 || (link_type == 2 && N == 2)) - for(int i = 0; i < N; ++i) { - const t_float Fn = F * (m1->pos[i] - m2->pos[i])*tdirection1[i]; // Fx = F * Lx[n]/L[n] - m1->force[i] -= Fn + D2 * m1->speed[i]; // Fx1[n] = -Fx, Fx1[n] = Fx1[n] - D2 * vx1[n-1] - m2->force[i] += Fn - D2 * m2->speed[i]; // Fx2[n] = Fx, Fx2[n] = Fx2[n] - D2 * vx2[n-1] - } - else if (link_type == 2 && N == 3) - for(int i = 0; i < N; ++i) { - const t_float Fn = F * (m1->pos[i] - m2->pos[i])*(tdirection1[i] +tdirection2[i]); // Fx = F * Lx[n]/L[n] - m1->force[i] -= Fn + D2 * m1->speed[i]; // Fx1[n] = -Fx, Fx1[n] = Fx1[n] - D2 * vx1[n-1] - m2->force[i] += Fn - D2 * m2->speed[i]; // Fx2[n] = Fx, Fx2[n] = Fx2[n] - D2 * vx2[n-1] + if (link_type == 3) { // tabLink + t_float k_temp = 1; + if (k_tabname) { + k_temp = interp_buf(distance,k_tab,l_tab); + } + t_float d_temp = 1; + if (d_tabname) { + d_temp = interp_buf(distance-distance_old,d_tab,l_tab); } + F = K1*k_temp + D1*d_temp/distance; + } + else { + if ((distance - longueur)>0) + F = (K1 * pow(distance - longueur,puissance) + D1 * (distance - distance_old))/distance ; + else + F = (-K1 * pow(longueur - distance,puissance) + D1 * (distance - distance_old))/distance ; + } + if (link_type == 1 || (link_type == 2 && N == 2)) // tangential + for(int i = 0; i < N; ++i) { + const t_float Fn = F * (m1->pos[i] - m2->pos[i])*tdirection1[i]; // Fx = F * Lx[n]/L[n] + m1->force[i] -= Fn + D2 * m1->speed[i]; // Fx1[n] = -Fx, Fx1[n] = Fx1[n] - D2 * vx1[n-1] + m2->force[i] += Fn - D2 * m2->speed[i]; // Fx2[n] = Fx, Fx2[n] = Fx2[n] - D2 * vx2[n-1] + } + else if (link_type == 2 && N == 3) // deprecated + for(int i = 0; i < N; ++i) { + const t_float Fn = F * (m1->pos[i] - m2->pos[i])*(tdirection1[i] +tdirection2[i]); // Fx = F * Lx[n]/L[n] + m1->force[i] -= Fn + D2 * m1->speed[i]; // Fx1[n] = -Fx, Fx1[n] = Fx1[n] - D2 * vx1[n-1] + m2->force[i] += Fn - D2 * m2->speed[i]; // Fx2[n] = Fx, Fx2[n] = Fx2[n] - D2 * vx2[n-1] + } + else // usual link + for(int i = 0; i < N; ++i) { + const t_float Fn = F * (m1->pos[i] - m2->pos[i]); // Fx = F * Lx[n]/L[n] + m1->force[i] -= Fn + D2 * m1->speed[i]; // Fx1[n] = -Fx, Fx1[n] = Fx1[n] - D2 * vx1[n-1] + m2->force[i] += Fn - D2 * m2->speed[i]; // Fx2[n] = Fx, Fx2[n] = Fx2[n] - D2 * vx2[n-1] + } + } distance_old = distance; // L[n-1] = L[n] @@ -762,7 +818,8 @@ protected: 0,NULL, argc >= 6?GetFloat(argv[5]):1, // power argc >= 7?GetFloat(argv[6]):0, - argc >= 8?GetFloat(argv[7]):1e10 + argc >= 8?GetFloat(argv[7]):1e10, + NULL,NULL,1 ); linkids.insert(l); link.insert(id_link++,l); @@ -784,7 +841,8 @@ protected: 0,NULL, argc >= 6?GetFloat(argv[5]):1, // power argc >= 7?GetFloat(argv[6]):0, - argc >= 8?GetFloat(argv[7]):1e10 + argc >= 8?GetFloat(argv[7]):1e10, + NULL,NULL,1 ); linkids.insert(l); link.insert(id_link++,l); @@ -805,7 +863,8 @@ protected: 0,NULL, argc >= 6?GetFloat(argv[5]):1, // power argc >= 7?GetFloat(argv[6]):0, - argc >= 8?GetFloat(argv[7]):1e10 + argc >= 8?GetFloat(argv[7]):1e10, + NULL,NULL,1 ); linkids.insert(l); link.insert(id_link++,l); @@ -830,7 +889,8 @@ protected: 0,NULL, argc >= 6?GetFloat(argv[5]):1, // power argc >= 7?GetFloat(argv[6]):0, // Lmin - argc >= 8?GetFloat(argv[7]):1e10// Lmax + argc >= 8?GetFloat(argv[7]):1e10,// Lmax + NULL,NULL,1 ); linkids.insert(l); @@ -862,7 +922,8 @@ protected: 0,NULL, argc >= 6?GetFloat(argv[5]):1, // power argc >= 7?GetFloat(argv[6]):0, - argc >= 8?GetFloat(argv[7]):1e10 + argc >= 8?GetFloat(argv[7]):1e10, + NULL,NULL,1 ); linkids.insert(l); @@ -899,7 +960,8 @@ protected: tangent, argc >= 6+N?GetFloat(argv[5+N]):1, // power argc >= 7+N?GetFloat(argv[6+N]):0, // Lmin - argc >= 8+N?GetFloat(argv[7+N]):1e10 // Lmax + argc >= 8+N?GetFloat(argv[7+N]):1e10, // Lmax + NULL,NULL,1 ); linkids.insert(l); link.insert(id_link++,l); @@ -922,7 +984,8 @@ protected: tangent, argc >= 6+N?GetFloat(argv[5+N]):1, // power argc >= 7+N?GetFloat(argv[6+N]):0, // Lmin - argc >= 8+N?GetFloat(argv[7+N]):1e10 // Lmax + argc >= 8+N?GetFloat(argv[7+N]):1e10, // Lmax + NULL,NULL,1 ); linkids.insert(l); link.insert(id_link++,l); @@ -944,7 +1007,8 @@ protected: tangent, // tangential argc >= 6+N?GetFloat(argv[5+N]):1, // power argc >= 7+N?GetFloat(argv[6+N]):0, // Lmin - argc >= 8+N?GetFloat(argv[7+N]):1e10 // Lmax + argc >= 8+N?GetFloat(argv[7+N]):1e10, // Lmax + NULL,NULL,1 ); linkids.insert(l); link.insert(id_link++,l); @@ -969,7 +1033,8 @@ protected: tangent, // tangential argc >= 6+N?GetFloat(argv[5+N]):1, // power argc >= 7+N?GetFloat(argv[6+N]):0, // Lmin - argc >= 8+N?GetFloat(argv[7+N]):1e10 // Lmax + argc >= 8+N?GetFloat(argv[7+N]):1e10, // Lmax + NULL,NULL,1 ); linkids.insert(l); link.insert(id_link++,l); @@ -977,6 +1042,119 @@ protected: } } + // add a tab link + // Id, *mass1, *mass2, k_tabname, d_tabname, l_tab + void m_tablink(int argc,t_atom *argv) + { + if (argc != 6) { + error("%s - %s Syntax : Id No/Idmass1 No/Idmass2 ktab dtab ltab",thisName(),GetString(thisTag())); + return; + } + if (IsSymbol(argv[1]) && IsSymbol(argv[2])) { // ID & ID + typename IDMap<t_mass *>::iterator it1,it2,it; + it1 = massids.find(GetSymbol(argv[1])); + it2 = massids.find(GetSymbol(argv[2])); + for(; it1; ++it1) { + for(it = it2; it; ++it) { + t_link *l = new t_link( + id_link, + GetSymbol(argv[0]), // ID + it1.data(),it.data(), // pointer to mass1, mass2 + IsSymbol(argv[3])?1:GetAFloat(argv[3]), // K1 = 1 if buffer + IsSymbol(argv[4])?1:GetAFloat(argv[4]), // D1 + 3,NULL, + 1, // power + 0, // Lmin + 1e10, // Lmax + IsSymbol(argv[3])?GetSymbol(argv[3]):NULL, // k_tabname + IsSymbol(argv[4])?GetSymbol(argv[4]):NULL, // d_tabname + GetAFloat(argv[5]) // l_tab + ); + linkids.insert(l); + link.insert(id_link++,l); + outlink(S_tabLink,l); + } + } + } + else if (IsSymbol(argv[1])==0 && IsSymbol(argv[2])) { // No & ID + typename IDMap<t_mass *>::iterator it2,it; + t_mass *mass1 = mass.find(GetAInt(argv[1])); + it2 = massids.find(GetSymbol(argv[2])); + for(it = it2; it; ++it) { + t_link *l = new t_link( + id_link, + GetSymbol(argv[0]), // ID + mass1,it.data(), // pointer to mass1, mass2 + IsSymbol(argv[3])?1:GetAFloat(argv[3]), // K1 = 1 if buffer + IsSymbol(argv[4])?1:GetAFloat(argv[4]), // D1 + 3,NULL, + 1, // power + 0, // Lmin + 1e10, // Lmax + IsSymbol(argv[3])?GetSymbol(argv[3]):NULL, // k_tabname + IsSymbol(argv[4])?GetSymbol(argv[4]):NULL, // d_tabname + GetAFloat(argv[5]) // l_tab + ); + linkids.insert(l); + link.insert(id_link++,l); + outlink(S_tabLink,l); + } + } + else if (IsSymbol(argv[1]) && IsSymbol(argv[2])==0) { // ID & No + typename IDMap<t_mass *>::iterator it1,it; + it1 = massids.find(GetSymbol(argv[1])); + t_mass *mass2 = mass.find(GetAInt(argv[2])); + for(it = it1; it; ++it) { + t_link *l = new t_link( + id_link, + GetSymbol(argv[0]), // ID + it1.data(),mass2, // pointer to mass1, mass2 + IsSymbol(argv[3])?1:GetAFloat(argv[3]), // K1 = 1 if buffer + IsSymbol(argv[4])?1:GetAFloat(argv[4]), // D1 + 3,NULL, + 1, // power + 0, // Lmin + 1e10, // Lmax + IsSymbol(argv[3])?GetSymbol(argv[3]):NULL, // k_tabname + IsSymbol(argv[4])?GetSymbol(argv[4]):NULL, // d_tabname + GetAFloat(argv[5]) // l_tab + ); + linkids.insert(l); + link.insert(id_link++,l); + outlink(S_tabLink,l); + } + } + else { // No & No + t_mass *mass1 = mass.find(GetAInt(argv[1])); + t_mass *mass2 = mass.find(GetAInt(argv[2])); + + if(!mass1 || !mass2) { + error("%s - %s : Index not found",thisName(),GetString(thisTag())); + return; + } + + t_link *l = new t_link( + id_link, + GetSymbol(argv[0]), // ID + mass1,mass2, // pointer to mass1, mass2 + IsSymbol(argv[3])?1:GetAFloat(argv[3]), // K1 = 1 if buffer + IsSymbol(argv[4])?1:GetAFloat(argv[4]), // D1 + 3,NULL, + 1, // power + 0, // Lmin + 1e10, // Lmax + IsSymbol(argv[3])?GetSymbol(argv[3]):NULL, // k_tabname + IsSymbol(argv[4])?GetSymbol(argv[4]):NULL, // d_tabname + GetAFloat(argv[5]) // l_tab + ); + + linkids.insert(l); + link.insert(id_link++,l); + outlink(S_tabLink,l); + } + } + + // add a normal link // Id, *mass1, *mass2, K1, D1, D2, (Lmin,Lmax) void m_nlink(int argc,t_atom *argv) @@ -1765,9 +1943,8 @@ private: SetSymbol((sortie[1]),l->Id); SetInt((sortie[2]),l->mass1->nbr); SetInt((sortie[3]),l->mass2->nbr); - SetFloat((sortie[4]),l->K1); - SetFloat((sortie[5]),l->D1); - + l->k_tabname?SetSymbol(sortie[4],l->k_tabname):SetFloat((sortie[4]),l->K1); + l->d_tabname?SetSymbol(sortie[5],l->d_tabname):SetFloat((sortie[5]),l->D1); if (l->link_type == 1 ||(l->link_type == 2 && N ==2)) { for (int i=0; i<N; i++) SetFloat((sortie[6+i]),l->tdirection1[i]); @@ -1812,6 +1989,7 @@ private: const static t_symbol *S_iLink; const static t_symbol *S_tLink; const static t_symbol *S_nLink; + const static t_symbol *S_tabLink; const static t_symbol *S_Mass_deleted; const static t_symbol *S_Link_deleted; const static t_symbol *S_massesPos; @@ -1855,6 +2033,7 @@ private: S_iLink = MakeSymbol("iLink"); S_tLink = MakeSymbol("tLink"); S_nLink = MakeSymbol("nLink"); + S_tabLink = MakeSymbol("tabLink"); S_Mass_deleted = MakeSymbol("Mass deleted"); S_Link_deleted = MakeSymbol("Link deleted"); S_massesPos = MakeSymbol("massesPos"); @@ -1942,6 +2121,7 @@ private: FLEXT_CADDMETHOD_(c,0,"iLink",m_ilink); FLEXT_CADDMETHOD_(c,0,"tLink",m_tlink); FLEXT_CADDMETHOD_(c,0,"nLink",m_nlink); + FLEXT_CADDMETHOD_(c,0,"tabLink",m_tablink); FLEXT_CADDMETHOD_(c,0,"get",m_get); FLEXT_CADDMETHOD_(c,0,"deleteLink",m_delete_link); FLEXT_CADDMETHOD_(c,0,"deleteMass",m_delete_mass); @@ -1965,6 +2145,7 @@ private: FLEXT_CALLBACK_V(m_ilink) FLEXT_CALLBACK_V(m_tlink) FLEXT_CALLBACK_V(m_nlink) + FLEXT_CALLBACK_V(m_tablink) FLEXT_CALLBACK_V(m_Xmax) FLEXT_CALLBACK_V(m_Xmin) FLEXT_CALLBACK_V(m_forceX) @@ -2004,6 +2185,7 @@ template<int N> const t_symbol *msdN<N>::S_Link; template<int N> const t_symbol *msdN<N>::S_iLink; template<int N> const t_symbol *msdN<N>::S_tLink; template<int N> const t_symbol *msdN<N>::S_nLink; +template<int N> const t_symbol *msdN<N>::S_tabLink; template<int N> const t_symbol *msdN<N>::S_Mass_deleted; template<int N> const t_symbol *msdN<N>::S_Link_deleted; template<int N> const t_symbol *msdN<N>::S_massesPos; |