FrictionContact.inl

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
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     // We need to remove duplicate contacts
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         //std::cout << "Removed " << (outputs.size()-contacts.size()) <<" / " << outputs.size() << " collision points." << std::endl;
00115     }
00116 
00117     if (c==NULL){
00118         // Get the mechanical model from mapper1 to fill the constraint vector
00119         MechanicalState1* mmodel1 = mapper1.createMapping();
00120         // Get the mechanical model from mapper2 to fill the constraints vector 
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(); // - 0.001;
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         //double constraintValue = ((o->point[1] - o->point[0]) * o->normal) - intersectionMethod->getContactDistance();
00141 
00142         // Create mapping for first point
00143         index1 = mapper1.addPoint(o->point[0], index1, r1);
00144         // Create mapping for second point
00145         index2 = mapper2.addPoint(o->point[1], index2, r2);
00146         // Checks if friction is considered
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         // Polynome de Cantor de N� sur N bijectif f(x,y)=((x+y)^2+3x+y)/2
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     // Update mappings
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 } // namespace collision
00195 
00196 } // namespace component
00197 
00198 } // namespace sofa
00199 
00200 #endif

Generated on Sun Nov 23 02:33:46 2008 for Sofa by  doxygen 1.5.7.1