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
00026
00027 #ifndef SOFA_CORE_COLLISIONMODEL_H
00028 #define SOFA_CORE_COLLISIONMODEL_H
00029
00030 #include <vector>
00031 #include <sofa/core/objectmodel/BaseObject.h>
00032 #include <sofa/core/CollisionElement.h>
00033
00034
00035 namespace sofa
00036 {
00037
00038 namespace core
00039 {
00040
00063 class CollisionModel : public virtual objectmodel::BaseObject
00064 {
00065 public:
00066
00067 typedef CollisionElementIterator Iterator;
00068 typedef componentmodel::topology::BaseMeshTopology Topology;
00069
00071 CollisionModel()
00072 : bActive(initData(&bActive, true, "active", "flag indicating if this collision model is active and should be included in default collision detections"))
00073 , bMoving(initData(&bMoving, true, "moving", "flag indicating if this object is changing position between iterations"))
00074 , bSimulated(initData(&bSimulated, true, "simulated", "flag indicating if this object is controlled by a simulation"))
00075 , bSelfCollision(initData(&bSelfCollision, false, "selfCollision", "flag indication if the object can self collide"))
00076 , proximity(initData(&proximity, 0.0, "proximity", "Distance to the actual (visual) surface"))
00077 , contactStiffness(initData(&contactStiffness, 10.0, "contactStiffness", "Default contact stiffness"))
00078 , contactFriction(initData(&contactFriction, 0.01, "contactFriction", "Default contact friction (damping) coefficient"))
00079 , contactResponse(initData(&contactResponse, "contactResponse", "if set, indicate to the ContactManager that this model should use the given class of contacts.\nNote that this is only indicative, and in particular if both collision models specify a different class it is up to the manager to choose."))
00080 , group(initData(&group, 0, "group", "If not zero, ID of a group containing this model. No collision can occur between collision models of the same group (allowing the same object to have multiple collision models)"))
00081 , color(initData(&color, defaulttype::Vec4f(1,0,0,1), "color", "color used to display the collision model if requested"))
00082 , size(0), previous(NULL) , next(NULL), numberOfContacts(0)
00083 {
00084 }
00085
00086 virtual void bwdInit()
00087 {
00088 getColor4f();
00089 }
00091 virtual ~CollisionModel() { }
00092
00094 bool empty() const
00095 {
00096 return size==0;
00097 }
00098
00100 int getSize() const
00101 {
00102 return size;
00103 }
00104
00106 int getNumberOfContacts() const
00107 {
00108 return numberOfContacts;
00109 }
00110
00112 void setNumberOfContacts(int i)
00113 {
00114 numberOfContacts = i;
00115 }
00116
00118 virtual void resize(int s)
00119 {
00120 size = s;
00121 }
00122
00124 Iterator begin()
00125 {
00126 return Iterator(this,0);
00127 }
00128
00130 Iterator end()
00131 {
00132 return Iterator(this,size);
00133 }
00134
00136 CollisionModel* getNext()
00137 {
00138 return next;
00139 }
00140
00142 CollisionModel* getPrevious()
00143 {
00144 return previous;
00145 }
00146
00148 void setNext(CollisionModel* val)
00149 {
00150 next = val;
00151 }
00152
00154 void setPrevious(CollisionModel* val)
00155 {
00156 previous = val;
00157 }
00158
00162 virtual bool isActive() const { return bActive.getValue() && getContext()->isActive(); }
00163
00165 virtual void setActive(bool val=true) { bActive.setValue(val); }
00166
00171 virtual bool isMoving() const { return bMoving.getValue(); }
00172
00175 virtual void setMoving(bool val=true) { bMoving.setValue(val); }
00176
00182 virtual bool isSimulated() const { return bSimulated.getValue(); }
00183
00185 virtual void setSimulated(bool val=true) { bSimulated.setValue(val); }
00186
00188 virtual void computeBoundingTree(int maxDepth=0) = 0;
00189
00194 virtual void computeContinuousBoundingTree(double , int maxDepth=0) { computeBoundingTree(maxDepth); }
00195
00206 virtual std::pair<CollisionElementIterator,CollisionElementIterator> getInternalChildren(int ) const
00207 {
00208 return std::make_pair(CollisionElementIterator(),CollisionElementIterator());
00209 }
00210
00218 virtual std::pair<CollisionElementIterator,CollisionElementIterator> getExternalChildren(int ) const
00219 {
00220 return std::make_pair(CollisionElementIterator(),CollisionElementIterator());
00221 }
00222
00223
00228 virtual bool isLeaf( int ) const
00229 {
00230 return true;
00231 }
00232
00233
00244 virtual bool canCollideWith(CollisionModel* model)
00245 {
00246 if (model != this && this->group.getValue() != 0 && this->group.getValue() == model->group.getValue())
00247 return false;
00248 else if (model->getContext() != this->getContext())
00249 return true;
00250 else return bSelfCollision.getValue();
00251 }
00252
00253
00261 virtual bool canCollideWithElement(int , CollisionModel* , int ) { return true; }
00262
00263
00265 virtual void draw(int ) {}
00266
00268 virtual void draw() {}
00269
00271 CollisionModel* getFirst()
00272 {
00273 CollisionModel *cm = this;
00274 CollisionModel *cm2;
00275 while ((cm2 = cm->getPrevious())!=NULL)
00276 cm = cm2;
00277 return cm;
00278 }
00279
00281 CollisionModel* getLast()
00282 {
00283 CollisionModel *cm = this;
00284 CollisionModel *cm2;
00285 while ((cm2 = cm->getNext())!=NULL)
00286 cm = cm2;
00287 return cm;
00288 }
00289
00290
00292 template<class DerivedModel>
00293 DerivedModel* createPrevious()
00294 {
00295 DerivedModel* pmodel = dynamic_cast<DerivedModel*>(previous);
00296 if (pmodel == NULL)
00297 {
00298 if (previous != NULL)
00299 delete previous;
00300 pmodel = new DerivedModel();
00301 pmodel->setContext(getContext());
00302 pmodel->setMoving(isMoving());
00303 pmodel->setSimulated(isSimulated());
00304 pmodel->proximity.setValue(proximity.getValue());
00305 pmodel->group.setValue(group.getValue());
00306 previous = pmodel;
00307 pmodel->setNext(this);
00308 }
00309 return pmodel;
00310 }
00311
00314
00316 double getProximity() { return proximity.getValue(); }
00317
00319 double getContactStiffness(int ) { return contactStiffness.getValue(); }
00321 void setContactStiffness(double stiffness) { contactStiffness.setValue(stiffness); }
00322
00324 double getContactFriction(int ) { return contactFriction.getValue(); }
00326 void setContactFriction(double friction) { contactFriction.setValue(friction); }
00327
00329 std::string getContactResponse() { return contactResponse.getValue(); }
00330
00332
00334 virtual Topology* getTopology() { return getContext()->getMeshTopology(); }
00335
00337 virtual sofa::core::componentmodel::topology::BaseMeshTopology* getMeshTopology() { return getContext()->getMeshTopology(); }
00338
00340 const float* getColor4f();
00342 void setColor4f(const float *c){color.setValue(defaulttype::Vec4f(c[0],c[1],c[2],c[3]));};
00343 protected:
00346 Data<bool> bActive;
00348 Data<bool> bMoving;
00350 Data<bool> bSimulated;
00352 Data<bool> bSelfCollision;
00354 Data<double> proximity;
00356 Data<double> contactStiffness;
00358 Data<double> contactFriction;
00362 Data<std::string> contactResponse;
00365 Data<int> group;
00367 Data<defaulttype::Vec4f> color;
00368
00370 int size;
00371
00373 CollisionModel* previous;
00374
00376 CollisionModel* next;
00377
00379 int numberOfContacts;
00380
00381 };
00382
00383 }
00384
00385 }
00386
00387 #endif