DefaultPipeline.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/DefaultPipeline.h>
00026 #include <sofa/core/CollisionModel.h>
00027 #include <sofa/simulation/tree/GNode.h>
00028 #include <sofa/core/ObjectFactory.h>
00029
00030 #include <sofa/helper/system/gl.h>
00031
00032 #define VERBOSE(a) if (bVerbose.getValue()) a; else {}
00033
00034 namespace sofa
00035 {
00036
00037 namespace component
00038 {
00039
00040 namespace collision
00041 {
00042
00043 using namespace core;
00044 using namespace core::objectmodel;
00045 using namespace core::componentmodel::collision;
00046 using namespace sofa::defaulttype;
00047
00048 SOFA_DECL_CLASS(DefaultPipeline)
00049
00050 int DefaultPipelineClass = core::RegisterObject("The default collision detection and modeling pipeline")
00051 .add< DefaultPipeline >()
00052 .addAlias("CollisionPipeline")
00053 ;
00054
00055 DefaultPipeline::DefaultPipeline()
00056 : bVerbose(initData(&bVerbose, false, "verbose","Display current step information"))
00057 , bDraw(initData(&bDraw, false, "draw","Draw detected collisions"))
00058 , depth(initData(&depth, 6, "depth","Max depth of bounding trees"))
00059 {
00060 }
00061
00062 typedef simulation::tree::GNode::ctime_t ctime_t;
00063
00064 void DefaultPipeline::doCollisionReset()
00065 {
00066 core::objectmodel::BaseContext* scene = getContext();
00067 simulation::tree::GNode* node = dynamic_cast<simulation::tree::GNode*>(scene);
00068 if (node && !node->getLogTime()) node=NULL;
00069 ctime_t t0 = 0;
00070 const std::string category = "collision";
00071
00072 VERBOSE(std::cout << "DefaultPipeline::doCollisionReset, Reset collisions"<<std::endl);
00073
00074 if (contactManager!=NULL)
00075 {
00076 const sofa::helper::vector<Contact*>& contacts = contactManager->getContacts();
00077 for (sofa::helper::vector<Contact*>::const_iterator it = contacts.begin(); it!=contacts.end(); it++)
00078 {
00079 (*it)->removeResponse();
00080 }
00081 }
00082
00083 if (groupManager!=NULL)
00084 {
00085 if (node) t0 = node->startTime();
00086 groupManager->clearGroups(scene);
00087 if (node) t0 = node->endTime(t0, category, groupManager, this);
00088 }
00089 }
00090
00091 void DefaultPipeline::doCollisionDetection(const sofa::helper::vector<core::CollisionModel*>& collisionModels)
00092 {
00093
00094
00095 core::objectmodel::BaseContext* scene = getContext();
00096 simulation::Node* node = dynamic_cast<simulation::Node*>(scene);
00097 if (node && !node->getLogTime()) node=NULL;
00098 ctime_t t0 = 0;
00099 const std::string category = "collision";
00100
00101 VERBOSE(std::cout << "DefaultPipeline::doCollisionDetection, Compute Bounding Trees"<<std::endl);
00102
00103
00104
00105 sofa::helper::vector<CollisionModel*> vectBoundingVolume;
00106 {
00107 if (node) t0 = node->startTime();
00108 const bool continuous = intersectionMethod->useContinuous();
00109 const double dt = getContext()->getDt();
00110
00111 sofa::helper::vector<CollisionModel*>::const_iterator it = collisionModels.begin();
00112 sofa::helper::vector<CollisionModel*>::const_iterator itEnd = collisionModels.end();
00113 int nActive = 0;
00114 for (; it != itEnd; it++)
00115 {
00116 VERBOSE(std::cout << "DefaultPipeline::doCollisionDetection, consider model "<<(*it)->getName()<<std::endl);
00117 if (!(*it)->isActive()) continue;
00118 if (continuous)
00119 (*it)->computeContinuousBoundingTree(dt, depth.getValue());
00120 else
00121 (*it)->computeBoundingTree(depth.getValue());
00122 vectBoundingVolume.push_back ((*it)->getFirst());
00123 ++nActive;
00124 }
00125 if (node) t0 = node->endTime(t0, "collision/bbox", this);
00126 VERBOSE(std::cout << "DefaultPipeline::doCollisionDetection, Computed "<<nActive<<" BBoxs"<<std::endl);
00127 }
00128
00129 if (broadPhaseDetection==NULL) return;
00130 VERBOSE(std::cout << "DefaultPipeline::doCollisionDetection, BroadPhaseDetection "<<broadPhaseDetection->getName()<<std::endl);
00131 if (node) t0 = node->startTime();
00132 broadPhaseDetection->beginBroadPhase();
00133 broadPhaseDetection->addCollisionModels(vectBoundingVolume);
00134 broadPhaseDetection->endBroadPhase();
00135 if (node) t0 = node->endTime(t0, category, broadPhaseDetection, this);
00136
00137
00138 if (narrowPhaseDetection==NULL) return;
00139 VERBOSE(std::cout << "DefaultPipeline::doCollisionDetection, NarrowPhaseDetection "<<narrowPhaseDetection->getName()<<std::endl);
00140 if (node) t0 = node->startTime();
00141 narrowPhaseDetection->beginNarrowPhase();
00142 sofa::helper::vector<std::pair<CollisionModel*, CollisionModel*> >& vectCMPair = broadPhaseDetection->getCollisionModelPairs();
00143 VERBOSE(std::cout << "DefaultPipeline::doCollisionDetection, "<< vectCMPair.size()<<" colliding model pairs"<<std::endl);
00144 narrowPhaseDetection->addCollisionPairs(vectCMPair);
00145 narrowPhaseDetection->endNarrowPhase();
00146 if (node) t0 = node->endTime(t0, category, narrowPhaseDetection, this);
00147 }
00148
00149 void DefaultPipeline::doCollisionResponse()
00150 {
00151 core::objectmodel::BaseContext* scene = getContext();
00152 simulation::tree::GNode* node = dynamic_cast<simulation::tree::GNode*>(scene);
00153 if (node && !node->getLogTime()) node=NULL;
00154 ctime_t t0 = 0;
00155 const std::string category = "collision";
00156
00157
00158 if (contactManager==NULL) return;
00159 VERBOSE(std::cout << "Create Contacts "<<contactManager->getName()<<std::endl);
00160 if (node) t0 = node->startTime();
00161 contactManager->createContacts(narrowPhaseDetection->getDetectionOutputs());
00162 if (node) t0 = node->endTime(t0, category, contactManager, this);
00163
00164
00165
00166 const sofa::helper::vector<Contact*>& contacts = contactManager->getContacts();
00167
00168
00169 sofa::helper::vector<Contact*> notStaticContacts;
00170
00171 for (sofa::helper::vector<Contact*>::const_iterator it = contacts.begin(); it!=contacts.end(); it++)
00172 {
00173 Contact* c = *it;
00174 if (!c->getCollisionModels().first->isSimulated())
00175 {
00176 c->createResponse(c->getCollisionModels().second->getContext());
00177 }
00178 else if (!c->getCollisionModels().second->isSimulated())
00179 {
00180 c->createResponse(c->getCollisionModels().first->getContext());
00181 }
00182 else
00183 notStaticContacts.push_back(c);
00184 }
00185
00186
00187 if (groupManager==NULL)
00188 {
00189 VERBOSE(std::cout << "Linking all contacts to Scene"<<std::endl);
00190 for (sofa::helper::vector<Contact*>::const_iterator it = notStaticContacts.begin(); it!=notStaticContacts.end(); it++)
00191 {
00192 (*it)->createResponse(scene);
00193 }
00194 }
00195 else
00196 {
00197 VERBOSE(std::cout << "Create Groups "<<groupManager->getName()<<std::endl);
00198 if (node) t0 = node->startTime();
00199 groupManager->createGroups(scene, notStaticContacts);
00200 if (node) t0 = node->endTime(t0, category, groupManager, this);
00201 }
00202 }
00203
00204 void DefaultPipeline::draw()
00205 {
00206 if (!bDraw.getValue()) return;
00207 if (!narrowPhaseDetection) return;
00208 glDisable(GL_LIGHTING);
00209 glLineWidth(2);
00210 glBegin(GL_LINES);
00211 DetectionOutputMap& outputsMap = narrowPhaseDetection->getDetectionOutputs();
00212 for (DetectionOutputMap::iterator it = outputsMap.begin(); it!=outputsMap.end(); it++)
00213 {
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 }
00228 glEnd();
00229 glLineWidth(1);
00230 }
00231 }
00232
00233 }
00234
00235 }
00236