#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) { 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) { 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->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 the elemnt of spatial hashing table void RefreshElements() { HTable->Clear(); for (SimplexIterator si=_simplex.begin();si<_simplex.end();++si) { if ((!(*si).IsD())&&(!(*si).IsActive())) HTable->addSimplex(&*si); } UpdateStep(); } ///put active cells on apposite structure void UpdateStep() { vactive.clear(); for (SimplexIterator si=_simplex.begin();si<_simplex.end();++si) { if ((((!(*si).IsD()))&&(*si).IsActive())) { std::vector cells=HTable->addSimplex(&*si); 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