#ifndef COLLISION_DETECTION #define COLLISION_DETECTION #include #include #include template class Collision_Detector{ public: typedef typename ContSimplex::value_type SimplexType; typedef typename ContSimplex::value_type* SimplexPointer; typedef typename ContSimplex::iterator SimplexIterator; typedef typename SimplexType::CoordType Point3x; typedef typename Point3x::ScalarType ScalarType; typedef SpatialHashTable HashingTable; Collision_Detector(ContSimplex & r_):_simplex(r_){}; ~Collision_Detector(){}; ContSimplex & _simplex; HashingTable *HTable; std::set vactive; int active; //control if two faces share an edge bool ShareEdge(SimplexType *f0,SimplexType *f1) { assert((!f0->IsD())&&(!f1->IsD())); for (int i=0;i<3;i++) if (f0->FFp(i)==f1) return (true); return(false); } ///initialize the box for collision detection and the dimension of a cell void Init(Point3x _min,Point3x _max,ScalarType _l) { HTable=new HashingTable(); HTable->Init(_min,_max,_l); } //control if two faces share a vertex bool ShareVertex(SimplexType *f0,SimplexType *f1) { assert((!f0->IsD())&&(!f1->IsD())); for (int i=0;i<3;i++) for (int j=0;j<3;j++) if (f0->V(i)==f1->V(j)) return (true); return(false); } //test real intersection between faces bool TestRealIntersection(SimplexType *f0,SimplexType *f1) { if ((f0->IsD())||(f1->IsD())||((!f0->IsActive())&&(!f1->IsActive()))) return false; //no adiacent faces if ((f0!=f1)&& (!ShareEdge(f0,f1)) && (!ShareVertex(f0,f1))) return (vcg::Intersection((*f0),(*f1))); return false; } ///refresh all the elements of spatial hashing table void RefreshElements() { HTable->Clear(); vactive.clear();///new for (SimplexIterator si=_simplex.begin();si<_simplex.end();++si) { if (!(*si).IsD()) { if (!(*si).IsActive()) HTable->addSimplex(&*si); ///new now else { std::vector cells=HTable->addSimplex(&*si); for(std::vector::iterator it=cells.begin();it cells=HTable->addSimplex(&*si); // for(std::vector::iterator it=cells.begin();it void UpdateStep(Container_Type &simplex) { vactive.clear(); for (Container_Type::iterator si=simplex.begin();si cells=HTable->addSimplex(&*si); for(std::vector::iterator it=cells.begin();itaddSimplex(&*newSimplex); ///new now else { std::vector cells=HTable->addSimplex(&*newSimplex); for(std::vector::iterator it=cells.begin();it computeSelfIntersection() { std::vector ret; std::set::iterator act; for (act=vactive.begin();act!=vactive.end();act++) { Point3i p=*act; if (HTable->numElemCell(p)>=2) { std::vector inCell=HTable->getAtCell(p); int nelem=inCell.size(); if (nelem>=2) { //test combinations of elements for (int i=0;iIsD())&&(!inCell[j]->IsD())&&(TestRealIntersection(inCell[i],inCell[j]))) { ret.push_back(inCell[i]); ret.push_back(inCell[j]); } } } } return ret; } }; #endif