FrictionContact.inl
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef SOFA_COMPONENT_COLLISION_FRICTIONCONTACT_INL
00026 #define SOFA_COMPONENT_COLLISION_FRICTIONCONTACT_INL
00027
00028 #include <sofa/component/collision/FrictionContact.h>
00029 #include <sofa/component/collision/DefaultContactManager.h>
00030 #include <iostream>
00031
00032 namespace sofa
00033 {
00034
00035 namespace component
00036 {
00037
00038 namespace collision
00039 {
00040
00041 using namespace sofa::defaulttype;
00042 using namespace core::componentmodel::collision;
00043 using simulation::tree::GNode;
00044 using std::cout;
00045 using std::cerr;
00046 using std::endl;
00047
00048 template < class TCollisionModel1, class TCollisionModel2 >
00049 FrictionContact<TCollisionModel1,TCollisionModel2>::FrictionContact(CollisionModel1* model1, CollisionModel2* model2, Intersection* intersectionMethod)
00050 : model1(model1), model2(model2), intersectionMethod(intersectionMethod), c(NULL), parent(NULL)
00051 {
00052 mapper1.setCollisionModel(model1);
00053 mapper2.setCollisionModel(model2);
00054
00055 mu = 0.6;
00056 }
00057
00058 template < class TCollisionModel1, class TCollisionModel2 >
00059 FrictionContact<TCollisionModel1,TCollisionModel2>::~FrictionContact()
00060 {
00061 if (c!=NULL)
00062 {
00063 if (parent!=NULL) parent->removeObject(c);
00064 delete c;
00065 }
00066 }
00067 template < class TCollisionModel1, class TCollisionModel2 >
00068 void FrictionContact<TCollisionModel1,TCollisionModel2>::cleanup()
00069 {
00070 if (c!=NULL)
00071 {
00072 c->cleanup();
00073 if (parent!=NULL)
00074 parent->removeObject(c);
00075 delete c;
00076 parent = NULL;
00077 c = NULL;
00078 mapper1.cleanup();
00079 mapper2.cleanup();
00080 }
00081 }
00082
00083
00084 #ifdef DETECTIONOUTPUT_FREEMOTION
00085 template < class TCollisionModel1, class TCollisionModel2 >
00086 void FrictionContact<TCollisionModel1,TCollisionModel2>::setDetectionOutputs(OutputVector* o)
00087 {
00088 TOutputVector& outputs = *static_cast<TOutputVector*>(o);
00089
00090 const double minDist2 = 0.00000001f;
00091 std::vector<DetectionOutput*> contacts;
00092 contacts.reserve(outputs.size());
00093
00094 int SIZE = outputs.size();
00095
00096 for (int cpt=0; cpt<SIZE; cpt++)
00097 {
00098 DetectionOutput* o = &outputs[cpt];
00099
00100 bool found = false;
00101 for (unsigned int i=0; i<contacts.size() && !found; i++)
00102 {
00103 DetectionOutput* p = contacts[i];
00104 if ((o->point[0]-p->point[0]).norm2()+(o->point[1]-p->point[1]).norm2() < minDist2)
00105 found = true;
00106 }
00107
00108 if (!found)
00109 contacts.push_back(o);
00110 }
00111
00112 if (contacts.size()<outputs.size())
00113 {
00114
00115 }
00116
00117 if (c==NULL){
00118
00119 MechanicalState1* mmodel1 = mapper1.createMapping();
00120
00121 MechanicalState2* mmodel2 = mapper2.createMapping();
00122 c = new constraint::UnilateralInteractionConstraint<Vec3Types>(mmodel1, mmodel2);
00123 }
00124
00125 int size = contacts.size();
00126 c->clear(size);
00127 mapper1.resize(size);
00128 mapper2.resize(size);
00129 int i = 0;
00130 const double d0 = intersectionMethod->getContactDistance() + model1->getProximity() + model2->getProximity();
00131 for (std::vector<DetectionOutput*>::const_iterator it = contacts.begin(); it!=contacts.end(); it++, i++)
00132 {
00133 DetectionOutput* o = *it;
00134 CollisionElement1 elem1(o->elem.first);
00135 CollisionElement2 elem2(o->elem.second);
00136 int index1 = elem1.getIndex();
00137 int index2 = elem2.getIndex();
00138 typename DataTypes1::Real r1 = 0.0;
00139 typename DataTypes2::Real r2 = 0.0;
00140
00141
00142
00143 index1 = mapper1.addPoint(o->point[0], index1, r1);
00144
00145 index2 = mapper2.addPoint(o->point[1], index2, r2);
00146
00147 if (mu < 0.0 || mu > 1.0)
00148 cerr << endl << "Error: mu has to take values between 0.0 and 1.0" << endl;
00149
00150 double distance = d0 + r1 + r2;
00151
00152 long index = cantorPolynomia(cantorPolynomia(index1, index2),id);
00153 c->addContact(mu, o->normal, o->point[1], o->point[0], distance, index1, index2, o->freePoint[1], o->freePoint[0], index);
00154 }
00155
00156 mapper1.update();
00157 mapper2.update();
00158 }
00159 #else
00160 template < class TCollisionModel1, class TCollisionModel2 >
00161 void FrictionContact<TCollisionModel1,TCollisionModel2>::setDetectionOutputs(OutputVector*)
00162 {
00163 cerr << endl << "ERROR: FrictionContact requires DETECTIONOUTPUT_FREEMOTION to be defined in DetectionOutput.h" << endl;
00164 }
00165 #endif
00166
00167 template < class TCollisionModel1, class TCollisionModel2 >
00168 void FrictionContact<TCollisionModel1,TCollisionModel2>::createResponse(core::objectmodel::BaseContext* group)
00169 {
00170 if (c!=NULL)
00171 {
00172 if (parent!=NULL) parent->removeObject(c);
00173 parent = group;
00174 if (parent!=NULL)
00175 {
00176 parent->addObject(c);
00177 }
00178 }
00179 }
00180
00181 template < class TCollisionModel1, class TCollisionModel2 >
00182 void FrictionContact<TCollisionModel1,TCollisionModel2>::removeResponse()
00183 {
00184 if (c!=NULL)
00185 {
00186 if (parent!=NULL)
00187 {
00188 parent->removeObject(c);
00189 }
00190 parent = NULL;
00191 }
00192 }
00193
00194 }
00195
00196 }
00197
00198 }
00199
00200 #endif