メインページ | ネームスペース一覧 | クラス階層 | 構成 | Directories | ファイル一覧 | ネームスペースメンバ | 構成メンバ | ファイルメンバ | 関連ページ

CDFramePair.h

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;      ///<    2つのジオメトリを構成する凸形状のすべてのペア
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 フレームは同じ階層でなければならない(親やそのPostureは考慮しない).
00133 
00134     フレームの所有関係
00135     SGFrame
00136      +-子SGFrame
00137      +-CDMesh
00138             +-CDPolyhedron
00139     フレーム(SGFrame)は,複数のジオメトリ(CDGeometries)と子フレームを持つ.
00140     ジオメトリ(CDGeometry) の中には,複数のジオメトリを持つもの(CDMesh)
00141     と単純な凸形状(CDPolyhedron)がある.
00142     CDMesh は複数のConvexを持つ.
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     /// アクティブかどうかのフラグたち.CDCollisionEngineのリスナの数だけフラグがある.
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     /// リスナ i がアクティブかどうか
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     /** CDConvexPairの派生クラスを使うための仕組み.
00217         このクラスを継承して,この関数をオーバーライドすることで,
00218         CDConvexPairの代わりに派生クラスを使用できる.  */
00219     virtual CDConvexPair* CreateConvexPair(){
00220         return new CDConvexPair;
00221     }
00222     /** CDGeometryPairの派生クラスを使うための仕組み.
00223         このクラスを継承して,この関数をオーバーライドすることで,
00224         CDGeometryPairの代わりに派生クラスを使用できる.    */
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 /// 法線情報つきのConvexPair
00234 class CDConvexPairWithNormal: public CDConvexPair{
00235 public:
00236     Vec3d normal;               ///<    衝突の法線(0から1へ) (Global)
00237     Vec3d iNormal;              ///<    積分による法線
00238     Vec3d center;               ///<    2つの最侵入点の中間の点,CDContactAnalysis::CalcNormal が更新する.
00239     double depth;               ///<    衝突の深さ:最近傍点を求めるために,2物体を動かす距離.
00240 };
00241 /// 法線情報つきのFramePair
00242 class CDFramePairWithNormal :public CDFramePair{
00243 protected:
00244     virtual CDConvexPair* CreateConvexPair(){
00245         return new CDConvexPairWithNormal;
00246     }
00247 };
00248 
00249 /// ユーザレコードと法線を持つConvexPair
00250 class CDConvexPairWithRecord: public CDConvexPairWithNormal{
00251 public:
00252     CDUserRecords records;
00253 };
00254 /// CDConvexPairWithRecordのためのCDFramePair レコードを持つ.
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

Springheadに対してSun Apr 16 01:57:49 2006に生成されました。  doxygen 1.4.1