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
00022
00023
00024
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; }
00035 };
00036
00037 class FramePairRecord:public CDUserRecord{
00038 public:
00039 Vec3f cocog;
00040 Vec3f reflexForce;
00041 Vec3f reflexTorque;
00042 Vec3f frictionForce;
00043 Vec3f frictionTorque;
00044
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
00085
00086 float area;
00087 Vec3f reflexSpringForce;
00088 Vec3f reflexDamperForce;
00089 Vec3f reflexSpringTorque;
00090 Vec3f reflexDamperTorque;
00091 Vec3f reflexForcePoint;
00092
00093
00094
00095
00096 Vec3f transFrictionBase[2];
00097 float rotSpring;
00098 Vec3f dynaFric;
00099 Vec3f dynaFricMom;
00100 Vec3f frictionForce;
00101 Vec3f frictionTorque;
00102 enum FrictionState{ STATIC, DYNAMIC };
00103 FrictionState frictionState;
00104
00105
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;
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;
00134 int frameRecordPos;
00135 int framePairRecordPos;
00136 int convexPairRecordPos;
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;
00147
00148 PHContactEngine();
00149 CDCollisionEngine* GetCollisionEngine(){ return collisionEngine; }
00150
00151 virtual bool AddChildObject(SGObject* o, SGScene* s);
00152 int GetListenerPos(){ return listenerPos; }
00153
00154 int GetFrameRecordPos(){ return frameRecordPos; }
00155
00156 int GetFramePairRecordPos(){ return framePairRecordPos; }
00157
00158 int GetConvexPairRecordPos(){ return convexPairRecordPos; }
00159
00160 FrameRecord* GetFrameRecord(SGFrame* fr){
00161 return (FrameRecord*)collisionEngine->GetFrameRecord(collisionEngine->GetFrameID(fr), frameRecordPos);
00162 }
00163
00164
00165
00166
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
00177 virtual void Loaded(SGScene* scene);
00178
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
00186 virtual void Step(SGScene* s){}
00187
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
00195
00196 void After(SGScene* scene, CDFramePairWithRecord* fr);
00197
00198 void CalcReflexForce(PHContactEngine::FrameRecord** fr, CDConvexPairWithRecord* cp,
00199 PHContactEngine::ConvexPairRecord* rec, CDContactAnalysis* analyzer);
00200
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