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

CDCollisionEngine.h

00001 #ifndef CDCOLLISIONENGINE_H
00002 #define CDCOLLISIONENGINE_H
00003 
00004 #pragma once
00005 #include <SceneGraph/SGBehaviorEngine.h>
00006 #include <Collision/CDFramePair.h>
00007 #include <Collision/CDDetectorImp.h>
00008 #include <WinBasis/WBPreciseTimer.h>
00009 
00010 namespace Spr{;
00011 
00012 
00013 /// 衝突時のリスナー(コールバック)クラス.
00014 class CDCollisionListener{
00015 public:
00016     /// すべての前に一度呼び出させるコールバック.
00017     virtual void BeforeAll(SGScene* scene){}
00018 
00019     /// 衝突判定後,解析前に呼び出されるコールバック.接触しているフレーム対の数だけ呼び出される.
00020     virtual void Before(SGScene* scene, CDFramePairWithRecord* fr){}
00021     /// 解析直後,交差部の面や頂点が有効なときに,接触している凸形状対の数だけ呼び出されるコールバック.
00022     virtual void Analyzed(SGScene* scene, CDFramePairWithRecord* fr, CDGeometryPair* geom, CDConvexPairWithRecord* conv, CDContactAnalysis* analyzer){}
00023     /// 解析後に呼び出されるコールバック.接触しているフレーム対の数だけ呼び出される.
00024     virtual void After(SGScene* scene, CDFramePairWithRecord* fr){}
00025 
00026     /// すべての後に一度呼び出させるコールバック.
00027     virtual void AfterAll(SGScene* scene){}
00028 };
00029 /// リスナのvector
00030 class CDCollisionListeners:public std::vector<CDCollisionListener*>{
00031 public:
00032     /// 衝突判定前に一度呼び出させるコールバック.
00033     void BeforeAll(SGScene* scene){
00034         for(unsigned  i=0; i<size(); ++i){
00035             at(i)->BeforeAll(scene);
00036         }
00037     }
00038     /// 衝突判定後,解析前に呼び出されるコールバック.接触しているフレーム対の数だけ呼び出される.
00039     void Before(SGScene* scene, CDFramePairWithRecord* fr){
00040         for(unsigned  i=0; i<size(); ++i){
00041             if (fr->IsActive(i)) begin()[i]->Before(scene, fr);
00042         }
00043     }
00044     /// 解析直後,交差部の面や頂点が有効なときに,接触している凸形状対の数だけ呼び出されるコールバック.
00045     void Analyzed(SGScene* scene, CDFramePairWithRecord* fr, CDGeometryPair* geom, CDConvexPairWithRecord* conv, CDContactAnalysis* analyzer){
00046         for(unsigned  i=0; i<size(); ++i){
00047             if (fr->IsActive(i)) begin()[i]->Analyzed(scene, fr, geom, conv, analyzer);
00048         }
00049     }
00050     /// 解析後に呼び出されるコールバック.接触しているフレーム対の数だけ呼び出される.
00051     void After(SGScene* scene, CDFramePairWithRecord* fr){
00052         for(unsigned  i=0; i<size(); ++i){
00053             if (fr->IsActive(i)) begin()[i]->After(scene, fr);
00054         }
00055     }
00056     void AfterAll(SGScene* scene){
00057         for(unsigned  i=0; i<size(); ++i){
00058             at(i)->AfterAll(scene);
00059         }
00060     }
00061 };
00062 
00063 /** 衝突判定エンジン.
00064     衝突しているペアを見つけ,衝突判定を行い,コールバックを呼び出す.  */
00065 class CDCollisionEngine: public SGBehaviorEngine
00066 {
00067 protected:
00068     /// アクティブ/非アクティブなリスナの指定
00069     struct ActivePair{
00070         int pos;        ///<    リスナの番号
00071         int frame[2];   ///<    フレームのペア
00072     };
00073     typedef std::vector<ActivePair> TActivePairs;
00074     TActivePairs activeList;    ///<    衝突判定を行う(リスナを呼び出す)ペアのリスト(デフォルトでは行わない)
00075     TActivePairs inactiveList;  ///<    衝突判定を行わない(リスナを呼びさない)ペアのリスト(デフォルトでは行う)
00076     std::vector<bool> defaults; ///<    デフォルトで衝突判定を行う(リスナを呼び出す)かどうかのフラグ
00077     
00078     /// 衝突判定の一覧.item(i,j) (i<j) でアクセスする.
00079     CDFramePairWithRecords pairs;
00080     /// 接触解析エンジン.交差部の面や頂点の情報を持っている.
00081     CDContactAnalysis analyzer;
00082     /// フレームごとのユーザレコードの数
00083     int nFrameRecords;
00084     /// フレームペアごとのユーザレコードの数
00085     int nFramePairRecords;
00086     /// 凸形状のペアごとのユーザレコードの数
00087     int nConvexPairRecords;
00088     /// 判定対象フレームのコンテナ型
00089     typedef std::vector< UTRef<CDFrame> > Frames;
00090     /// 衝突判定対象のフレーム
00091     Frames frames;
00092     /// 衝突のリスナ
00093     CDCollisionListeners listeners;
00094     /// フレームとフレーム番号の対応表
00095 
00096     void Render(GRRender* render, SGScene* scene);
00097     
00098     std::map<SGFrame*, int> frameMap;
00099 
00100 public:
00101     /// フレーム対のためのイタレータ
00102     typedef CDFramePairWithRecords::iterator TFrameIt;
00103 
00104     struct GetGeom{
00105         CDGeometryPairs* operator()(TFrameIt it){ return *it ? &(*it)->geometryPairs : NULL; }
00106     };
00107     /// ジオメトリ対のためのイタレータ
00108     class TGeometryIt: public UTComposedIterator<CDGeometryPair*, TFrameIt, CDGeometryPairs::iterator, GetGeom>{
00109         friend class CDCollisionEngine;
00110         friend class TConvexIt;
00111     public:
00112         TGeometryIt(){}
00113         TGeometryIt(CDFramePairWithRecords::iterator b, CDFramePairWithRecords::iterator e, CDGeometryPairs::iterator g){
00114             Init(b, e, g);
00115         }
00116     };
00117 
00118     
00119     struct GetConv{
00120         CDConvexPairs* operator()(TGeometryIt it){ return &it->convexPairs; }
00121     };
00122     /// 凸形状対のためのイタレータ
00123     class TConvexIt: public UTComposedIterator<CDConvexPairWithRecord*, TGeometryIt, CDConvexPairs::iterator, GetConv>{
00124         friend class CDCollisionEngine;
00125         TConvexIt(){}
00126         TConvexIt(TGeometryIt b, TGeometryIt e, CDConvexPairs::iterator c){
00127             Init(b, e, c);
00128         }
00129     };
00130 
00131 public:
00132     WBPreciseTimer timerGjk, timerQhull, timerNormal;
00133     ///
00134     SGOBJECTDEF(CDCollisionEngine);
00135     ///
00136     CDCollisionEngine();
00137 
00138     ///@name    BehaviorEngineをオーバーライド
00139     //{
00140     ///
00141     int GetPriority() const { return SGBP_COLLISIONENGINE; }
00142     /// 時間を dt 進める
00143     virtual void Step(SGScene* s);
00144     /// 判定対象のフレームをクリアする.
00145     virtual void Clear(SGScene* s);
00146     /// 初期化(frames から pairsを作る)
00147     void Init();
00148     //}
00149 
00150     //@name リスナや判定対象のフレームと関連付けられたデータのアクセス
00151     //@{
00152     /// リスナを返す.
00153     CDCollisionListener* GetListener(int pos){ return listeners[pos]; }
00154     /// リスナの数
00155     size_t NListener(){ return listeners.size(); }
00156 
00157     /// フレームの番号を返す.
00158     int GetFrameID(SGFrame* fr){ return frameMap[fr]; }
00159     /// フレーム対を返す.f1 < f2 でなければならない.
00160     CDFramePairWithRecord* GetFramePair(int f1, int f2){
00161         return pairs.item(f1, f2);
00162     }
00163     /// フレーム対を返す.(f1,f2)と(f2,f1)どちらは向こう.
00164     CDFramePairWithRecord* GetFramePair(SGFrame* f1, SGFrame*f2){ return GetFramePair(GetFrameID(f1), GetFrameID(f2)); }
00165     /// フレームIDからフレームを返す.
00166     SGFrame* GetFrame(int id){ return frames[id]->frame; }
00167     /// フレームIDとレコードの位置(ReserveFrameRecord()の返り値)からレコードを返す.
00168     CDUserRecord* GetFrameRecord(int id, int pos){ return frames[id]->records[pos]; }
00169 #if defined _MSC_VER && _MSC_VER >= 1300
00170     /// フレーム対のイタレータの始点
00171     TFrameIt FramePairBegin() const { return (TFrameIt&)pairs.begin(); }
00172     /// フレーム対のイタレータの終点
00173     TFrameIt FramePairEnd() const { return (TFrameIt&)pairs.end(); }
00174 #else
00175     /// フレーム対のイタレータの始点
00176     TFrameIt FramePairBegin() const { return (TFrameIt)pairs.begin(); }
00177     /// フレーム対のイタレータの終点
00178     TFrameIt FramePairEnd() const { return (TFrameIt)pairs.end(); }
00179 #endif
00180     /// ジオメトリ対のイタレータの始点
00181     TGeometryIt GeometryPairBegin() const{
00182         TGeometryIt rv;
00183         rv.InitAsBegin(FramePairBegin(), FramePairEnd());
00184         return rv;
00185     }
00186     /// ジオメトリ対のイタレータの終点
00187     TGeometryIt GeometryPairEnd() const{
00188         TGeometryIt rv;
00189         rv.InitAsEnd(FramePairBegin(), FramePairEnd());
00190         return rv;
00191     }
00192     /// 凸形状対のイタレータの始点
00193     TConvexIt ConvexPairBegin() const {
00194         TConvexIt rv;
00195         rv.InitAsBegin(GeometryPairBegin(), GeometryPairEnd());
00196         return rv;
00197     }
00198     /// 凸形状対のイタレータの終点
00199     TConvexIt ConvexPairEnd() const{
00200         TConvexIt rv;
00201         rv.InitAsEnd(GeometryPairBegin(), GeometryPairEnd());
00202         return rv;
00203     }
00204     //}
00205     
00206     ///@name    登録,追加系のメソッド
00207     //{
00208     /// 判定対象フレームを追加.すべての判定対象フレームは同階層になければならない.
00209     void AddFrame(SGFrame* frame, CDUserRecord* rec=NULL, int pos=-1);
00210     /// フレームの数
00211     size_t NFrame(){ return frames.size(); }
00212     /// リスナーの登録
00213     int AddListener(CDCollisionListener* l);
00214     /// 衝突判定をしないペアを登録(デフォルトでは衝突判定する)
00215     bool AddInactive(int f1, int f2, int pos);
00216     /// 衝突判定をしないペアを登録(デフォルトでは衝突判定する)
00217     bool AddInactive(SGFrame* f1, SGFrame* f2, int pos){ return AddInactive(GetFrameID(f1), GetFrameID(f2), pos); }
00218     /// posのリスナについて判定しないように登録したペア(InactiveList)をクリアする
00219     int ClearInactive(int pos);
00220     /// 衝突判定をするペアを登録(pos のリスナについては,デフォルトでは判定しなくなる.)
00221     bool AddActive(int f1, int f2, int pos);
00222     /// 衝突判定をするペアを登録(pos のリスナについては,デフォルトでは判定しなくなる.)
00223     bool AddActive(SGFrame* f1, SGFrame* f2, int pos){ return AddActive(GetFrameID(f1), GetFrameID(f2), pos); }
00224     /// posのリスナについて判定するように登録したペア(activeList)をクリアする
00225     int ClearActive(int pos);
00226     /// フレーム(CDFrame) ごとのユーザレコード(records) の場所取り.
00227     int ReserveFrameRecord();
00228     /// フレームのペア(CDFramePairWithRecord) ごとのユーザレコード(records) の場所取り.
00229     int ReserveFramePairRecord();
00230     /// 凸形状のペア(CDConvexPairWithRecord) ごとのユーザレコードの場所取り.
00231     int ReserveConvexPairRecord();
00232     //}
00233 
00234     void RayCheck(Vec3f from, Vec3f dir);
00235     
00236     /// 状態の読み出し
00237     virtual void LoadState(const SGBehaviorStates& states);
00238     /// 状態の保存
00239     virtual void SaveState(SGBehaviorStates& states) const;
00240 };
00241 
00242 }
00243 
00244 #endif
00245 

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