DefaultContactManager.cpp

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 #include <sofa/component/collision/DefaultContactManager.h>
00026 #include <sofa/core/ObjectFactory.h>
00027 using std::cerr;
00028 using std::endl;
00029 
00030 
00031 namespace sofa
00032 {
00033 
00034 namespace component
00035 {
00036 
00037 namespace collision
00038 {
00039 
00040 SOFA_DECL_CLASS(DefaultContactManager)
00041 
00042 int DefaultContactManagerClass = core::RegisterObject("Default class to create reactions to the collisions")
00043 .add< DefaultContactManager >()
00044 .addAlias("CollisionResponse")
00045 ;
00046 
00047 DefaultContactManager::DefaultContactManager()
00048 : response(initData(&response, std::string("default"), "response", "contact response class"))
00049 {
00050 }
00051 
00052 DefaultContactManager::~DefaultContactManager()
00053 {
00054     // Contacts are now attached to the graph.
00055     // So they will be deleted by the DeleteVisitor
00056     // FIX crash on unload bug. -- J. Allard
00057     //clear();
00058 }
00059 
00060 void DefaultContactManager::clear()
00061 {
00062     for (sofa::helper::vector<core::componentmodel::collision::Contact*>::iterator it=contacts.begin(); it!=contacts.end(); ++it)
00063     {
00064         (*it)->removeResponse();
00065         (*it)->cleanup();
00066         delete *it;
00067     }
00068     contacts.clear();
00069     contactMap.clear();
00070 }
00071 
00072 void DefaultContactManager::createContacts(DetectionOutputMap& outputsMap)
00073 {
00074      //cerr<<"DefaultContactManager::createContacts"<<endl;
00075      
00076     //outputsMap.clear();
00077     //for (sofa::helper::vector<core::componentmodel::collision::DetectionOutput*>::const_iterator it = outputs.begin(); it!=outputs.end(); ++it)
00078     //{
00079     //  core::componentmodel::collision::DetectionOutput* o = *it;
00080     //  outputsMap[std::make_pair(o->elem.first.getCollisionModel(),o->elem.second.getCollisionModel())].push_back(o);
00081     //}
00082     
00083     // Remove any inactive contacts or add any new contact
00084     DetectionOutputMap::iterator outputsIt = outputsMap.begin();
00085     std::map< std::pair<core::CollisionModel*,core::CollisionModel*>, core::componentmodel::collision::Contact* >::iterator contactIt = contactMap.begin();
00086     int nbContact = 0;
00087     //static DetectionOutputVector emptyContacts;
00088     while (outputsIt!=outputsMap.end() || contactIt!=contactMap.end())
00089     {
00090         if (outputsIt!=outputsMap.end() && (contactIt == contactMap.end() || outputsIt->first < contactIt->first))
00091         { // new contact
00092             //std::cout << "Creation new "<<contacttype<<" contact"<<std::endl;
00093                     core::CollisionModel* model1 = outputsIt->first.first;
00094                     core::CollisionModel* model2 = outputsIt->first.second;
00095                     std::string response1 = model1->getContactResponse();
00096                     std::string response2 = model2->getContactResponse();
00097                     std::string responseUsed = response.getValue();
00098                     if (!response1.empty()) responseUsed = response1;
00099                     else if (!response2.empty()) responseUsed = response2;
00100                     core::componentmodel::collision::Contact* contact = core::componentmodel::collision::Contact::Create(responseUsed, model1, model2, intersectionMethod);
00101             if (contact == NULL) std::cerr << "Contact "<<responseUsed<<" between " << model1->getClassName()<<" and "<<model2->getClassName() << " creation failed"<<std::endl;
00102             else
00103             {
00104                 contactMap[std::make_pair(model1, model2)] = contact;
00105                 contact->setName(model1->getName()+std::string("-")+model2->getName());
00106                 contact->f_printLog.setValue(this->f_printLog.getValue());
00107                 contact->init();
00108                 contact->setDetectionOutputs(outputsIt->second);
00109                 ++nbContact;
00110             }
00111             ++outputsIt;
00112         }
00113         else if (contactIt!=contactMap.end() && (outputsIt == outputsMap.end() || contactIt->first < outputsIt->first))
00114         { // inactive contact
00115             //std::cout << "Deleting inactive "<<contacttype<<" contact"<<std::endl;
00116             if (contactIt->second->keepAlive())
00117             {
00118                 contactIt->second->setDetectionOutputs(NULL);
00119                 ++nbContact;
00120                 ++contactIt;
00121             }
00122             else
00123             {
00124                 std::map< std::pair<core::CollisionModel*,core::CollisionModel*>, core::componentmodel::collision::Contact* >::iterator contactIt2 = contactIt;
00125                 ++contactIt2;
00126                 contactIt->second->removeResponse();
00127                 contactIt->second->cleanup();
00128                 delete contactIt->second;
00129                 contactMap.erase(contactIt);
00130                 contactIt = contactIt2;
00131             }
00132         }
00133         else
00134         { // corresponding contact and outputs
00135             contactIt->second->setDetectionOutputs(outputsIt->second);
00136             ++nbContact;
00137             ++outputsIt;
00138             ++contactIt;
00139         }
00140     }
00141     // now update contactVec
00142     contacts.clear();
00143     contacts.reserve(nbContact);
00144     contactIt = contactMap.begin();
00145     while (contactIt!=contactMap.end())
00146     {
00147         contacts.push_back(contactIt->second);
00148         ++contactIt;
00149     }
00150     // compute number of contacts attached to each collision model
00151     std::map<core::CollisionModel*,int> nbContactsMap;
00152     for (unsigned int i=0;i<contacts.size();++i)
00153     {
00154         std::pair< core::CollisionModel*, core::CollisionModel* > cms = contacts[i]->getCollisionModels();
00155         nbContactsMap[cms.first]++;
00156         if (cms.second != cms.first)
00157             nbContactsMap[cms.second]++;
00158     }
00159     sofa::helper::vector<core::CollisionModel*> collisionModels;
00160     simulation::Node* context = dynamic_cast<simulation::Node*>(getContext());
00161     context->getTreeObjects<core::CollisionModel>(&collisionModels);
00162     for (unsigned int i=0;i<collisionModels.size();++i)
00163     {
00164         collisionModels[i]->setNumberOfContacts(nbContactsMap[collisionModels[i]]);
00165     }
00166 }
00167 
00168 void DefaultContactManager::draw()
00169 {
00170     for (sofa::helper::vector<core::componentmodel::collision::Contact*>::iterator it = contacts.begin(); it!=contacts.end(); it++)
00171     {
00172         if ((*it)!=NULL)
00173             (*it)->draw();
00174     }
00175 }
00176 
00177 } // namespace collision
00178 
00179 } // namespace component
00180 
00181 } // namespace sofa
00182 

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