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
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
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;
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
00056 }
00057 else
00058 {
00059 if (deltaFree < 0.0)
00060 {
00061 dt=0.0;
00062 c.dfree = deltaFree;
00063
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
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
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];
00143 v->set(c.id,c.dfree);
00144 if (c.mu > 0.0)
00145 {
00146 v->set(c.id+1,c.dfree_t);
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];
00158 v[c.id] = c.dfree;
00159 if (c.mu > 0.0)
00160 {
00161 v[c.id+1] = c.dfree_t;
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 }
00224
00225 }
00226
00227 }
00228
00229 #endif