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

PHContactEngine.h

00001 #pragma once
00002 #ifndef PHCONTACTENGINE_H
00003 #define PHCONTACTENGINE_H
00004 
00005 #include "PHSolid.h"
00006 #include <SceneGraph/SGScene.h>
00007 #include <Physics/PHConvexPair.h>
00008 #include <Collision/CDCollisionEngine.h>
00009 #include <Collision/CDPolyhedron.h>
00010 #include <float.h>
00011 
00012 namespace Spr{;
00013 
00014 
00015 /** 接触力計算エンジン.    */
00016 class PHContactEngine:public SGBehaviorEngine, CDCollisionListener{
00017 public:
00018     /// 判定対象フレームごとのデータ
00019     class FrameRecord:public CDUserRecord{
00020     public:
00021         ///@name    UpdateChacheで更新する変数
00022         //@{
00023         /** 最後に接触した時刻 = キャッシュパラメータを最後に更新した時刻.
00024             接触時に,キャッシュを更新するので,count が現在の時刻と等しければ
00025             衝突が起きたことを意味する.    */
00026         unsigned count;
00027         //  フレーム(剛体)単位のパラメータ
00028         Vec3f cog, vel, angVel;         ///<    重心,速度,角速度
00029         Vec3f pos, lastPos;             ///<    位置,最後の位置
00030         Quaternionf ori, lastOri;       ///<    向き,前回の向き
00031         //@}
00032         void UpdateCache(int c);        ///<    キャッシュ変数を剛体などから取ってくる.
00033         PHSolid* solid;                 ///<    判定対象剛体
00034         FrameRecord(){ count = -1; }    ///<    s
00035     };
00036     /// 判定対象フレーム対ごとのデータ
00037     class FramePairRecord:public CDUserRecord{
00038     public:
00039         Vec3f cocog;                    ///<    2剛体の重心の中点(絶対系)
00040         Vec3f reflexForce;              ///<    抗力
00041         Vec3f reflexTorque;             ///<    抗力によるトルク(cocog系)
00042         Vec3f frictionForce;            ///<    摩擦力
00043         Vec3f frictionTorque;           ///<    摩擦力によるトルク(cocog系)
00044         ///@name    絶対系での読み出し
00045         //@{
00046         /// 抗力
00047         Vec3f GetReflexForce(){ return reflexForce; }
00048         /// 抗力のトルク
00049         Vec3f GetReflexTorque(){ return reflexTorque + (cocog^reflexForce); }
00050         /// 摩擦力
00051         Vec3f GetFrictionForce(){ return frictionForce; }
00052         /// 摩擦力のトルク
00053         Vec3f GetFrictionTorque(){ return frictionTorque + (cocog^frictionForce); }
00054         //@}
00055         
00056         /// データのクリア.
00057         void Clear(){
00058             reflexForce = reflexTorque = frictionForce = frictionTorque = Vec3f();
00059         }
00060         /// 力の最大値を制約する.
00061         void LimitForces(){
00062             bool b = false;
00063             b |= LimitForce(reflexForce);
00064             b |= LimitForce(frictionForce);
00065             b |= LimitForce(reflexTorque);
00066             b |= LimitForce(frictionTorque);
00067             if (b){
00068                 reflexForce = frictionForce = reflexTorque = frictionTorque = Vec3f();
00069             }
00070         }
00071     protected:
00072         bool LimitForce(Vec3f& f){
00073             float sq = f.square();
00074             const float MF = 200000;
00075             if (!(sq < MF*MF)){
00076                 return true;
00077             }
00078             return false;
00079         }
00080     };
00081     /// 凸形状対ごとのデータ
00082     class ConvexPairRecord:public CDUserRecord{
00083     public:
00084         ///@name    抗力の計算
00085         //@{
00086         float area;                         ///<    交差部の面積
00087         Vec3f reflexSpringForce;            ///<    ばねによる抗力
00088         Vec3f reflexDamperForce;            ///<    ダンパーによる抗力
00089         Vec3f reflexSpringTorque;           ///<    ばねによる抗トルク(commonPoint系)
00090         Vec3f reflexDamperTorque;           ///<    ダンパーによる抗トルク(commonPoint系)
00091         Vec3f reflexForcePoint;             ///<    抗力の作用点(commonPoint系)
00092         //@}
00093 
00094         ///@name摩擦の計算
00095         //@{
00096         Vec3f transFrictionBase[2];         ///<    並進静止摩擦用バネの端点(ローカルフレーム系)
00097         float rotSpring;                    ///<    回転ばねの伸び(ラジアン)
00098         Vec3f dynaFric;                     ///<    動摩擦力
00099         Vec3f dynaFricMom;                  ///<    動摩擦力のモーメント(commonPoint系)
00100         Vec3f frictionForce;                ///<    摩擦力
00101         Vec3f frictionTorque;               ///<    摩擦トルク(摩擦力の作用点 = (reflexForcePoint+commonPoint)系)
00102         enum FrictionState{ STATIC, DYNAMIC };
00103         FrictionState frictionState;        ///<    摩擦の状態
00104         //@}
00105         ///@name    絶対座標系での読み出し
00106         //@{
00107         /// バネによる抗力の作用点
00108         Vec3f GetReflexForcePoint(CDConvexPair* cp){ return reflexForcePoint + cp->commonPoint;}
00109         /// バネによる抗力
00110         Vec3f GetReflexSpringForce(){ return reflexSpringForce;}
00111         /// ダンパによる抗力
00112         Vec3f GetReflexDamperForce(){ return reflexDamperForce;}
00113         /// 抗力
00114         Vec3f GetReflexForce(){ return reflexSpringForce + reflexDamperForce;}
00115 
00116         /// 摩擦力
00117         Vec3f GetFrictionForce(){ return frictionForce; }
00118         /// 摩擦トルク
00119         Vec3f GetFrictionTorque(CDConvexPair* cp){ return frictionTorque + (GetReflexForcePoint(cp)^frictionForce); }
00120         //@}
00121     };
00122 private:
00123     bool firstLoadedCall;                   ///<    Loadedで複数回初期化をしないようにするためのフラグ
00124     float area;                             ///<    衝突部分の面積
00125     float convertedMass;                    ///<    換算質量
00126     float reflexSpring;                     ///<    バネ計数
00127     float reflexDamper;                     ///<    ダンパ計数
00128     float frictionSpring;                   ///<    摩擦のバネ係数
00129     float frictionDamper;                   ///<    摩擦のダンパ係数
00130     float staticFriction;                   ///<    静止摩擦係数
00131     float dynamicFriction;                  ///<    動摩擦係数
00132 protected:
00133     int listenerPos;                        ///<    CDContactEngineの中でのリスナの位置
00134     int frameRecordPos;                     ///<    CDContactEngineの中でのフレーム単位のユーザレコードの位置
00135     int framePairRecordPos;                 ///<    CDContactEngineの中でのフレーム対単位のユーザレコードの位置
00136     int convexPairRecordPos;                ///<    CDContactEngineの中での凸形状対単位のユーザレコードの位置
00137     std::vector< std::pair<DWORD, DWORD> > inactiveList;
00138                                             ///<    非アクティブなペア一覧(ロード時にだけ使用)
00139 
00140     UTRef<CDCollisionEngine> collisionEngine;///<   衝突判定エンジン
00141 public: 
00142     SGOBJECTDEF(PHContactEngine);
00143     std::vector< std::vector<DWORD> > inactiveListBackups;
00144                                             //<     セーブに備えて覚えておく
00145     PHSolids solids;                        ///<    ペナルティ法の対象の剛体
00146     size_t nSolidsInitilized;               ///<    solidsのうちどこまでが初期化済みかを示す.
00147     ///
00148     PHContactEngine();
00149     CDCollisionEngine* GetCollisionEngine(){ return collisionEngine; }
00150     /// 子オブジェクトの追加
00151     virtual bool AddChildObject(SGObject* o, SGScene* s);
00152     int GetListenerPos(){ return listenerPos; }
00153     /// FrameRecordのCDCollisionEngineの中での位置
00154     int GetFrameRecordPos(){ return frameRecordPos; }
00155     /// FramePairRecordのCDCollisionEngineの中での位置
00156     int GetFramePairRecordPos(){ return framePairRecordPos; }
00157     /// ConvexPairRecordのCDCollisionEngineの中での位置
00158     int GetConvexPairRecordPos(){ return convexPairRecordPos; }
00159     /// FrameRecordの取得
00160     FrameRecord* GetFrameRecord(SGFrame* fr){
00161         return (FrameRecord*)collisionEngine->GetFrameRecord(collisionEngine->GetFrameID(fr), frameRecordPos);
00162     }
00163     /** FramePairRecordの取得
00164         FramePairRecordはフレームの対ごとに1つ.
00165         (fr1,fr2)と(fr2,fr1)で読んだ場合,どちらか片方はNULLを返す.
00166         (fr1,fr2)で値が得られたならば,FramePairRecordはf1に加わった力を持つ.
00167     */
00168     FramePairRecord* GetFramePairRecord(SGFrame* fr1, SGFrame* fr2){
00169         CDFramePairWithRecord* fp = collisionEngine->GetFramePair(fr1, fr2);
00170         if (fp) return UTRef<FramePairRecord>(fp->records[framePairRecordPos]);
00171         return NULL;
00172     }
00173     /// アクティブでないフレーム対を追加
00174     void AddInactive(int f1, int f2);
00175 
00176     /// ロード完了時の処理,CollisionEngine にコールバックを登録する.CollisionEngineがなければ作る.ユーザが呼び出すことはない.
00177     virtual void Loaded(SGScene* scene);
00178     /// 初期化処理、Loadedが呼ぶ
00179     virtual void Init(SGScene* scene);
00180     /// 接触力の描画
00181     void Render(GRRender* r, SGScene* s);
00182 protected:
00183     ///
00184     int GetPriority() const { return SGBP_CONTACTENGINE; }
00185     /// 時間を dt 進める.(何もしない,Listener の Collide がすべての処理をする.)
00186     virtual void Step(SGScene* s){}
00187     /// solidsをクリアする.
00188     virtual void Clear(SGScene* s);
00189     /// フレーム同士が衝突している場合,接触解析の前に呼び出される.抗力計算の準備を行う.
00190     void Before(SGScene* scene, CDFramePairWithRecord* fr);
00191     /** フレーム同士が衝突している場合,接触解析の直後に凸形状対ごとに呼び出される.
00192         接触面積と抗力の計算を行う.*/
00193     virtual void Analyzed(SGScene* scene, CDFramePairWithRecord* fr, CDGeometryPair* geom, CDConvexPairWithRecord* conv, CDContactAnalysis* analyzer);
00194     /** フレーム同士が衝突している場合,衝突解析が終わってからフレーム対につき1度呼び出される.
00195         抗力の調整,摩擦力計算を行う    */
00196     void After(SGScene* scene, CDFramePairWithRecord* fr);
00197     /// 抗力計算
00198     void CalcReflexForce(PHContactEngine::FrameRecord** fr, CDConvexPairWithRecord* cp,
00199         PHContactEngine::ConvexPairRecord* rec, CDContactAnalysis* analyzer);
00200     /// 3角形単位の抗力計算
00201     void CalcTriangleReflexForce(CDConvexPairWithRecord* cp, PHContactEngine::ConvexPairRecord* rec,
00202         Vec3f p0, Vec3f p1, Vec3f p2, Vec3f cog, Vec3f vel, Vec3f angVel);
00203     void CalcFriction(PHContactEngine::FrameRecord** fr, PHContactEngine::FramePairRecord* fpr, CDConvexPairWithNormal* cp,
00204         PHContactEngine::ConvexPairRecord* rec);
00205     void DrawForce(CDConvexPair& cp, PHContactEngine::ConvexPairRecord& cpr, Affinef afw, GRRender* render, SGScene* scene);
00206 
00207     /// 状態の読み出し
00208     virtual void LoadState(const SGBehaviorStates& states);
00209     /// 状態の保存
00210     virtual void SaveState(SGBehaviorStates& states) const;
00211 };
00212 
00213 
00214 }
00215 #endif
00216 

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