DefaultContactManager.cpp
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 #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
00055
00056
00057
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
00075
00076
00077
00078
00079
00080
00081
00082
00083
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
00088 while (outputsIt!=outputsMap.end() || contactIt!=contactMap.end())
00089 {
00090 if (outputsIt!=outputsMap.end() && (contactIt == contactMap.end() || outputsIt->first < contactIt->first))
00091 {
00092
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 {
00115
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 {
00135 contactIt->second->setDetectionOutputs(outputsIt->second);
00136 ++nbContact;
00137 ++outputsIt;
00138 ++contactIt;
00139 }
00140 }
00141
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
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 }
00178
00179 }
00180
00181 }
00182