00001 #ifndef PHSOLID_H
00002 #define PHSOLID_H
00003
00004 #include <FileIO/FIDocScene.h>
00005 #include <SceneGraph/SGScene.h>
00006 #include <Base/TQuaternion.h>
00007
00008 namespace Spr{;
00009
00010 class SGFrame;
00011
00012 enum PHIntegrationMode{
00013 PHINT_NONE,
00014 PHINT_ARISTOTELIAN,
00015 PHINT_EULER,
00016 PHINT_SIMPLETIC,
00017 PHINT_ANALYTIC,
00018 PHINT_RUNGEKUTTA2,
00019 PHINT_RUNGEKUTTA4
00020 };
00021
00022
00023 class PHSolid : public SGObject{
00024 Vec3d _angvel[4];
00025 Vec3d _angacc[4];
00026 protected:
00027 double mass;
00028 Matrix3d inertia;
00029 Matrix3d inertia_inv;
00030 Vec3d force;
00031 Vec3d torque;
00032 Vec3d velocity;
00033 Vec3d angVelocity;
00034 Vec3d center;
00035 Quaterniond quat;
00036
00037
00038
00039
00040 UTRef<SGFrame> frame;
00041
00042
00043 PHIntegrationMode integrationMode;
00044
00045
00046
00047 Vec3d Euler(const Matrix3d& I, const Vec3d& t, const Vec3d& w){
00048 return Vec3d(
00049 (t[0] - (I[2][2] - I[1][1]) * w.Y() * w.Z()) / I[0][0],
00050 (t[1] - (I[0][0] - I[2][2]) * w.Z() * w.X()) / I[1][1],
00051 (t[2] - (I[1][1] - I[0][0]) * w.X() * w.Y()) / I[2][2]);
00052 }
00053 public:
00054 SGOBJECTDEF(PHSolid);
00055 PHSolid();
00056
00057 bool AddChildObject(SGObject* o, SGScene* s);
00058 size_t NReferenceObjects();
00059 SGObject* ReferenceObject(size_t i);
00060 void Loaded(SGScene* scene);
00061 void Step(SGScene* s);
00062
00063 void AddForce(Vec3d f);
00064 void AddTorque(Vec3d t){ torque += t; }
00065 void AddForce(Vec3d f, Vec3d r);
00066
00067
00068 void ClearForce();
00069 Vec3d GetForce() const {return force;}
00070 Vec3d GetTorque() const {return torque;}
00071 void SetForce(Vec3d f){force = f;}
00072 void SetTorque(Vec3d t){torque = t;}
00073
00074 SGFrame* GetFrame(){ return frame; }
00075 void SetFrame(SGFrame* f){ frame = f; }
00076 double GetMass(){return mass;}
00077 double GetMassInv(){return 1.0 / mass;}
00078 void SetMass(double m){mass = m;}
00079 void SetMassInv(double minv){mass = 1.0 / minv;}
00080
00081 Matrix3d GetInertia(){return inertia;}
00082 Matrix3d GetInertiaInv(){return inertia_inv;}
00083 void SetInertia(const Matrix3d& I){
00084 inertia = I;
00085 inertia_inv = I.inv();
00086 }
00087 void SetInertiaInv(const Matrix3d& Iinv){
00088 inertia_inv = Iinv;
00089
00090 }
00091
00092
00093 PHIntegrationMode GetIntegrationMode(){ return integrationMode; }
00094
00095 void SetIntegrationMode(PHIntegrationMode m){ integrationMode=m; }
00096
00097 Vec3d GetFramePosition() const {return frame->GetPosition();}
00098 void SetFramePosition(const Vec3d& p){frame->SetPosition(p);}
00099 Vec3d GetCenterPosition() const {return frame->GetPosture()*center;}
00100
00101 void SetCenterPosition(const Vec3d& p){
00102 frame->SetPosition(p - frame->GetRotation()*center);
00103 }
00104
00105
00106 Matrix3d GetRotation() const { Matrix3d rv; quat.to_matrix(rv); return rv; }
00107
00108 void SetRotation(const Matrix3d& r){
00109 quat.from_matrix(r);
00110 frame->SetRotation(r);
00111 }
00112
00113
00114 Quaterniond GetOrientation() const {return quat;}
00115
00116 void SetOrientation(const Quaterniond& q){
00117 quat = q;
00118 Matrix3f m;
00119 quat.to_matrix(m);
00120 frame->SetRotation(m);
00121 }
00122
00123
00124 Vec3d GetVelocity() const {return velocity;}
00125
00126 void SetVelocity(const Vec3d& v){velocity = v;}
00127
00128
00129 Vec3d GetAngularVelocity() const {return angVelocity;}
00130
00131 void SetAngularVelocity(const Vec3d& av){angVelocity = av;}
00132
00133
00134 Vec3d GetCenter() const {return center;}
00135
00136 void SetCenter(const Vec3d& c){center = c;}
00137
00138
00139 virtual void LoadState(const SGBehaviorStates& states);
00140
00141 virtual void SaveState(SGBehaviorStates& states) const;
00142 };
00143
00144 class PHSolids:public std::vector< UTRef<PHSolid> >{
00145 public:
00146 UTRef<PHSolid> Erase(const UTRef<PHSolid>& s){
00147 iterator it = std::find(begin(), end(), s);
00148 if (it == end()) return NULL;
00149 UTRef<PHSolid> rv = *it;
00150 erase(it);
00151 return *it;
00152 }
00153 UTRef<PHSolid>* Find(const UTRef<PHSolid>& s){
00154 iterator it = std::find(begin(), end(), s);
00155 if (it == end()) return NULL;
00156 else return &*it;
00157 }
00158 UTRef<PHSolid>* Find(const UTRef<PHSolid>& s) const {
00159 return ((PHSolids*)this)->Find(s);
00160 }
00161 };
00162
00163
00164 class PHSolverBase:public SGBehaviorEngine{
00165 SGOBJECTDEFABST(PHSolverBase);
00166 public:
00167 virtual void ClearForce()=0;
00168 };
00169
00170
00171 class PHSolidContainer:public PHSolverBase{
00172 SGOBJECTDEF(PHSolidContainer);
00173 public:
00174 PHSolids solids;
00175 bool AddChildObject(SGObject* o, SGScene* s);
00176 bool DelChildObject(SGObject* o, SGScene* s);
00177
00178 int GetPriority() const {return SGBP_SOLIDCONTAINER;}
00179
00180 virtual void Step(SGScene* s);
00181
00182 virtual void ClearForce();
00183
00184 virtual void Loaded(SGScene* scene);
00185 virtual void Clear(SGScene* s){ solids.clear(); }
00186
00187 virtual size_t NChildObjects(){ return solids.size(); }
00188
00189 virtual SGObject* ChildObject(size_t i){ return solids[i]; }
00190
00191
00192 virtual void LoadState(const SGBehaviorStates& states);
00193
00194 virtual void SaveState(SGBehaviorStates& states) const;
00195 };
00196
00197
00198 class PHSolidClearForce:public SGBehaviorEngine{
00199 SGOBJECTDEF(PHSolidClearForce);
00200 public:
00201 typedef std::vector< UTRef<PHSolverBase> > PHSolvers;
00202 PHSolvers solvers;
00203
00204 virtual void Step(SGScene* s);
00205 virtual int GetPriority() const { return SGBP_CLEARFORCE; }
00206 };
00207
00208 struct SolidInfo{
00209 float mass;
00210 Matrix3f inertia;
00211 Vec3f velocity;
00212 Vec3f angularVelocity;
00213 Vec3f center;
00214 };
00215
00216 }
00217 #endif