UnilateralInteractionConstraint.inl

Go to the documentation of this file.
00001 #ifndef SOFA_COMPONENT_CONSTRAINT_UNILATERALINTERACTIONCONSTRAINT_INL
00002 #define SOFA_COMPONENT_CONSTRAINT_UNILATERALINTERACTIONCONSTRAINT_INL
00003 
00004 #include <sofa/component/constraint/UnilateralInteractionConstraint.h>
00005 #include <sofa/defaulttype/Vec.h>
00006 #include <sofa/helper/gl/template.h>
00007 namespace sofa
00008 {
00009 
00010 namespace component
00011 {
00012 
00013 namespace constraint
00014 {
00015 
00016 template<class DataTypes>
00017 void UnilateralInteractionConstraint<DataTypes>::addContact(double mu, Deriv norm, Coord P, Coord Q, Real contactDistance, int m1, int m2, Coord Pfree, Coord Qfree, long id)
00018 {
00019     // compute dt and delta
00020     Real delta = dot(P-Q, norm) - contactDistance; 
00021     Real deltaFree = dot(Pfree-Qfree, norm) - contactDistance;
00022     Real dt;
00023     int i = contacts.size();
00024     contacts.resize(i+1);
00025     Contact& c = contacts[i];
00026 
00027 // for visu
00028     c.P = P;
00029     c.Q = Q;
00030     c.Pfree = Pfree;
00031     c.Qfree = Qfree;
00032 //
00033     c.m1 = m1;
00034     c.m2 = m2;
00035     c.norm = norm;
00036     c.delta = delta;
00037     c.t = Deriv(norm.z(), norm.x(), norm.y());
00038     c.s = cross(norm,c.t);
00039     c.s = c.s / c.s.norm();
00040     c.t = cross((-norm), c.s);
00041     c.mu = mu;
00042     c.contactId = id;
00043     
00044 
00045     if (rabs(delta - deltaFree) > 0.001 * delta)
00046     {
00047         dt = delta / (delta - deltaFree);
00048         if (dt > 0.0 && dt < 1.0  ){
00049             sofa::defaulttype::Vector3 Qt, Pt;
00050             Qt = Q*(1-dt) + Qfree*dt;
00051             Pt = P*(1-dt) + Pfree*dt;
00052             c.dfree = deltaFree;// dot(Pfree-Pt, c.norm) - dot(Qfree-Qt, c.norm);
00053             c.dfree_t = dot(Pfree-Pt, c.t) - dot(Qfree-Qt, c.t);
00054             c.dfree_s = dot(Pfree-Pt, c.s) - dot(Qfree-Qt, c.s);
00055             //printf("\n ! dt = %f, c.dfree = %f, deltaFree=%f, delta = %f", dt, c.dfree, deltaFree, delta);
00056         }
00057         else
00058         {
00059             if (deltaFree < 0.0)
00060             {
00061                 dt=0.0;
00062                 c.dfree = deltaFree; // dot(Pfree-P, c.norm) - dot(Qfree-Q, c.norm);
00063                 //printf("\n dt = %f, c.dfree = %f, deltaFree=%f, delta = %f", dt, c.dfree, deltaFree, delta);
00064                 c.dfree_t = dot(Pfree-P, c.t) - dot(Qfree-Q, c.t);
00065                 c.dfree_s = dot(Pfree-P, c.s) - dot(Qfree-Q, c.s);
00066             }
00067             else
00068             {
00069                 dt=1.0;
00070                 c.dfree = deltaFree;
00071                 c.dfree_t = 0;
00072                 c.dfree_s = 0;
00073             }
00074         }
00075     }
00076     else
00077     {
00078         dt = 0;
00079         c.dfree = deltaFree;
00080         c.dfree_t = 0;
00081         c.dfree_s = 0;
00082         //printf("\n dt = %f, c.dfree = %f, deltaFree=%f, delta = %f", dt, c.dfree, deltaFree, delta);
00083     }
00084 }
00085 
00086 
00087 template<class DataTypes>
00088 void UnilateralInteractionConstraint<DataTypes>::applyConstraint(unsigned int &contactId, double &mu)
00089 {
00090     assert(this->object1);
00091     assert(this->object2);
00092 
00093     VecConst& c1 = *this->object1->getC();
00094     VecConst& c2 = *this->object2->getC();
00095 
00096     for (unsigned int i=0; i<contacts.size(); i++)
00097     {
00098         Contact& c = contacts[i];
00099 
00100         mu = c.mu;
00101         //c.mu = mu;
00102         c.id = contactId++;
00103 
00104         SparseVecDeriv svd1;
00105         SparseVecDeriv svd2;
00106 
00107         this->object1->setConstraintId(c.id);
00108         svd1.push_back(SparseDeriv(c.m1, -c.norm));
00109         c1.push_back(svd1);
00110 
00111         this->object2->setConstraintId(c.id);
00112         svd2.push_back(SparseDeriv(c.m2, c.norm));
00113         c2.push_back(svd2);
00114         
00115         if (c.mu > 0.0)
00116         {
00117             contactId += 2;
00118             this->object1->setConstraintId(c.id+1);
00119             svd1[0] = SparseDeriv(c.m1, -c.t);
00120             c1.push_back(svd1);
00121 
00122             this->object1->setConstraintId(c.id+2);
00123             svd1[0] = SparseDeriv(c.m1, -c.s);
00124             c1.push_back(svd1);
00125 
00126             this->object2->setConstraintId(c.id+1);
00127             svd2[0] = SparseDeriv(c.m2, c.t);
00128             c2.push_back(svd2);
00129 
00130             this->object2->setConstraintId(c.id+2);
00131             svd2[0] = SparseDeriv(c.m2, c.s);
00132             c2.push_back(svd2);
00133         }
00134     }
00135 }
00136 
00137 template<class DataTypes>
00138 void UnilateralInteractionConstraint<DataTypes>::getConstraintValue(defaulttype::BaseVector * v)
00139 {
00140     for (unsigned int i=0; i<contacts.size(); i++)
00141     {
00142         Contact& c = contacts[i]; // get each contact detected
00143         v->set(c.id,c.dfree); 
00144         if (c.mu > 0.0)
00145         {
00146             v->set(c.id+1,c.dfree_t); // dfree_t & dfree_s are added to v to compute the friction 
00147             v->set(c.id+2,c.dfree_s);
00148         }
00149     }
00150 }
00151 
00152 template<class DataTypes>
00153 void UnilateralInteractionConstraint<DataTypes>::getConstraintValue(double * v)
00154 {
00155     for (unsigned int i=0; i<contacts.size(); i++)
00156     {
00157         Contact& c = contacts[i]; // get each contact detected
00158         v[c.id] = c.dfree; 
00159         if (c.mu > 0.0)
00160         {
00161             v[c.id+1] = c.dfree_t; // dfree_t & dfree_s are added to v to compute the friction 
00162             v[c.id+2] = c.dfree_s;
00163         }
00164     }
00165 }
00166 
00167 template<class DataTypes>
00168 void UnilateralInteractionConstraint<DataTypes>::getConstraintId(long* id, unsigned int &offset)
00169 {
00170     if (!yetIntegrated)
00171     {
00172         for (unsigned int i=0; i<contacts.size(); i++)
00173         {
00174             Contact& c = contacts[i];
00175             id[offset++] = -c.contactId;
00176         }
00177 
00178         yetIntegrated = true;
00179     }
00180     else
00181     {
00182         for (unsigned int i=0; i<contacts.size(); i++)
00183         {
00184             Contact& c = contacts[i];
00185             id[offset++] = c.contactId; 
00186         }
00187     }
00188 }
00189 
00190 
00191 template<class DataTypes>
00192 void UnilateralInteractionConstraint<DataTypes>::draw()
00193 {
00194     if (!getContext()->getShowInteractionForceFields()) return;
00195 
00196     glDisable(GL_LIGHTING);
00197     glBegin(GL_LINES);
00198     glColor4f(1,0,0,1);
00199     for (unsigned int i=0; i<contacts.size(); i++)
00200     {
00201         glLineWidth(1);
00202         glColor4f(1,0,0,1);
00203         const Contact& c = contacts[i];
00204         helper::gl::glVertexT(c.P);
00205         helper::gl::glVertexT(c.Q);
00206         glColor4f(1,1,0,1);
00207         helper::gl::glVertexT(c.P);
00208         helper::gl::glVertexT(c.P+c.norm*(c.dfree));
00209         helper::gl::glVertexT(c.Q);
00210         helper::gl::glVertexT(c.Q-c.norm*(c.dfree));
00211 
00212         if (c.dfree < 0)
00213         {
00214             glLineWidth(5);
00215             glColor4f(0,1,0,1);
00216             helper::gl::glVertexT(c.Pfree);
00217             helper::gl::glVertexT(c.Qfree);
00218         }
00219     }
00220     glEnd();
00221 }
00222 
00223 } // namespace constraint
00224 
00225 } // namespace component
00226 
00227 } // namespace sofa
00228 
00229 #endif

Generated on Sun Nov 23 02:48:31 2008 for Sofa by  doxygen 1.5.7.1