00001 #ifndef CDDETECTOR_H
00002 #define CDDETECTOR_H
00003 #include "CDConvex.h"
00004 #include <SceneGraph/SGFrame.h>
00005 #include <Base/Combination.h>
00006 #include "CDQuickHull3D.h"
00007
00008 namespace Spr {;
00009
00010 template <class T, class ITI, class ITJ, class GetContainer>
00011 class UTComposedIterator{
00012 public:
00013 typedef UTComposedIterator<T, ITI, ITJ, GetContainer> self_type;
00014 protected:
00015 ITI iti, iEnd;
00016 ITJ itj;
00017 public:
00018 self_type(){}
00019 T operator->(){ return (T&)*itj; }
00020 T operator*(){ return (T&)*itj; }
00021 self_type& operator ++(int){ Next(); return *this; }
00022 self_type operator ++(){ self_type rv(*this); Next(); return rv; }
00023 bool operator ==(const self_type& i) const{ return i.iti == iti && i.itj == itj; }
00024 bool operator !=(const self_type& i) const {return !(i==*this);}
00025 void Init(ITI b, ITI e, ITJ j){
00026 while (b!=e && !GetContainer()(b)) ++b;
00027 iti = b;
00028 iEnd = e;
00029 itj = j;
00030 }
00031 void InitAsBegin(ITI b, ITI e){
00032 Init(b, e, NULL);
00033 if (b!=e) itj = GetContainer()(iti)->begin();
00034 else return;
00035 while (itj==GetContainer()(iti)->end()){
00036 do{
00037 ++iti;
00038 if (iti == iEnd){
00039 itj=NULL;
00040 break;
00041 }
00042 } while(!GetContainer()(iti));
00043 itj=GetContainer()(iti)->begin();
00044 }
00045 }
00046 void InitAsEnd(ITI b, ITI e){
00047 Init(e, e, 0);
00048 }
00049 void Next(){
00050 assert(itj != NULL);
00051 ++itj;
00052 if (itj == GetContainer()(iti)->end()){
00053 do{
00054 ++iti;
00055 }while(iti != iEnd && (!GetContainer()(iti) || !GetContainer()(iti)->size()));
00056 if (iti != iEnd){
00057 itj = GetContainer()(iti)->begin();
00058 }else{
00059 itj = NULL;
00060 }
00061 }
00062 }
00063 };
00064
00065
00066
00067 class CDConvexPair:public UTRefCount{
00068 public:
00069 virtual ~CDConvexPair(){}
00070 UTRef<CDConvex> convex[2];
00071 Vec3d closestPoint[2];
00072 Vec3d commonPoint;
00073 unsigned int lastContactCount;
00074 enum State{
00075 NEW,
00076 CONTINUE,
00077 } state;
00078 void Set(CDConvex* c1, CDConvex* c2){
00079 convex[0] = c1;
00080 convex[1] = c2;
00081 }
00082 CDConvexPair():lastContactCount(-2){}
00083 };
00084
00085 class CDConvexPairs:public UTCombination< UTRef<CDConvexPair> >{
00086 public:
00087 };
00088 class CDFramePair;
00089
00090 class CDGeometryPair:public UTRefCount{
00091 public:
00092 UTRef<CDGeometry> geometry[2];
00093 UTRef<SGFrame> frame[2];
00094 Affinef posture[2];
00095 CDConvexPairs convexPairs;
00096 void Set(CDFramePair* fp, CDGeometry* g1, SGFrame* f1, CDGeometry* g2, SGFrame* f2);
00097 virtual ~CDGeometryPair(){}
00098 };
00099
00100 class CDGeometryPairs:public UTCombination< UTRef<CDGeometryPair> >{
00101 public:
00102 };
00103
00104
00105 class CDIntersection{
00106 public:
00107 CDConvexPair* convexPair;
00108 CDGeometryPair* geometryPair;
00109 CDIntersection(CDConvexPair* cp, CDGeometryPair* gp): convexPair(cp), geometryPair(gp){}
00110 };
00111
00112 class CDIntersections:public std::vector<CDIntersection>{
00113 };
00114
00115
00116
00117 typedef SGObject CDUserRecord;
00118
00119
00120 class CDUserRecords:public std::vector< UTRef<CDUserRecord> >{
00121 public:
00122 };
00123
00124 class CDFrame:public UTRefCount{
00125 public:
00126 CDFrame(){}
00127 CDFrame(SGFrame* f): frame(f){}
00128 CDUserRecords records;
00129 UTRef<SGFrame> frame;
00130 };
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 class CDFramePair{
00145 public:
00146
00147 class CDIsActive: public std::vector<bool>{
00148 bool bOr;
00149 public:
00150 void Update(){
00151 bOr = false;
00152 for(unsigned i=0; i<size(); ++i){
00153 bOr |= at(i);
00154 }
00155 }
00156 bool GetOr(){ return bOr; }
00157 };
00158 struct GetConv{
00159 CDConvexPairs* operator()(CDGeometryPairs::iterator it){ return *it ? &(*it)->convexPairs : NULL; }
00160 };
00161
00162 struct CDConvexPairIt: UTComposedIterator<CDConvexPair*, CDGeometryPairs::iterator, CDConvexPairs::iterator, GetConv>{
00163 friend class CDCollisionEngine;
00164 CDConvexPairIt(){}
00165 CDConvexPairIt(CDGeometryPairs::iterator b, CDGeometryPairs::iterator e, CDConvexPairs::iterator c){
00166 Init(b, e, c);
00167 }
00168 };
00169
00170
00171 unsigned lastContactCount;
00172
00173 CDIsActive isActive;
00174
00175 UTRef<CDFrame> frame[2];
00176
00177 CDIntersections intersections;
00178
00179 CDGeometryPairs geometryPairs;
00180
00181
00182 CDFramePair();
00183
00184 void Set(CDFrame* f1, CDFrame* f2);
00185
00186 bool IsActive(){ return isActive.GetOr(); }
00187
00188 bool IsActive(int i){ return isActive[i]; }
00189
00190 void Clear(){
00191 frame[0] = frame[1] = NULL;
00192 geometryPairs.clear();
00193 }
00194
00195 bool Detect(int count);
00196
00197 bool IsContact(SGScene* scene);
00198
00199
00200 CDConvexPairIt ConvexPairBegin(){
00201 CDConvexPairIt rv;
00202 rv.InitAsBegin(geometryPairs.begin(), geometryPairs.end());
00203 return rv;
00204 }
00205 CDConvexPairIt ConvexPairEnd(){
00206 CDConvexPairIt rv;
00207 rv.InitAsEnd(geometryPairs.begin(), geometryPairs.end());
00208 return rv;
00209 }
00210 protected:
00211
00212
00213 virtual void Found(CDConvexPair& cp, CDGeometryPair& gp){
00214 intersections.push_back(CDIntersection(&cp, &gp));
00215 }
00216
00217
00218
00219 virtual CDConvexPair* CreateConvexPair(){
00220 return new CDConvexPair;
00221 }
00222
00223
00224
00225 virtual CDGeometryPair* CreateGeometryPair(){
00226 return new CDGeometryPair;
00227 }
00228 private:
00229
00230 void EnumGeometry(SGFrames& frames, CDGeometries& geoms, SGFrame* f);
00231 friend class CDGeometryPair;
00232 };
00233
00234 class CDConvexPairWithNormal: public CDConvexPair{
00235 public:
00236 Vec3d normal;
00237 Vec3d iNormal;
00238 Vec3d center;
00239 double depth;
00240 };
00241
00242 class CDFramePairWithNormal :public CDFramePair{
00243 protected:
00244 virtual CDConvexPair* CreateConvexPair(){
00245 return new CDConvexPairWithNormal;
00246 }
00247 };
00248
00249
00250 class CDConvexPairWithRecord: public CDConvexPairWithNormal{
00251 public:
00252 CDUserRecords records;
00253 };
00254
00255 class CDFramePairWithRecord :public CDFramePairWithNormal, public UTRefCount{
00256 public:
00257 CDUserRecords records;
00258 protected:
00259 virtual CDConvexPair* CreateConvexPair(){
00260 return new CDConvexPairWithRecord;
00261 }
00262 };
00263
00264 class CDFramePairWithRecords: public UTCombination< UTRef<CDFramePairWithRecord> >{
00265 public:
00266 };
00267
00268 }
00269 #endif