00001 #ifndef PH_JOINT_H
00002 #define PH_JOINT_H
00003
00004
00005 #include <Base/BaseUtility.h>
00006 #include <Base/TinyVec.h>
00007 #include <Base/TinyMat.h>
00008 #include <FileIO/FIDocScene.h>
00009 #include <SceneGraph/SGScene.h>
00010 #include <Physics/PHSolid.h>
00011 #include <WinBasis/WBPreciseTimer.h>
00012 #include <float.h>
00013
00014
00015 #define PHJOINT_MAX_VELOCITY (1000*M_PI)
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 namespace Spr{;
00027
00028
00029
00030
00031
00032
00033
00034 typedef PTM::TVector<6, double> SpVec6d;
00035 typedef PTM::TSubVector<3, SpVec6d::desc> SpSubVec3d;
00036 typedef PTM::TMatrixCol<6, 6, double> SpMatrix6d;
00037 typedef PTM::TSubMatrixCol<3, 3, SpMatrix6d::desc> SpSubMatrix3d;
00038
00039
00040 typedef Vec3f Vector;
00041 typedef Matrix3f Matrix3x3;
00042 DEF_RECORD(XJointBase, {
00043 GUID Guid(){ return WBGuid("23F6D545-8987-4aa6-BBE1-2FE32C096D5A"); }
00044 Matrix3x3 pRj;
00045 Vector prj;
00046 Matrix3x3 cRj;
00047 Vector crj;
00048 });
00049
00050
00051 class PHJointBase : public UTTreeNode<PHJointBase>, public SGObject{
00052 public:
00053 typedef std::vector<UTRef<PHJointBase> > array_type;
00054 friend class PHJointEngine;
00055 friend class PHJointClearForce;
00056 friend class PHJointLoader;
00057 friend class CRHuman;
00058 public:
00059 SGOBJECTDEFABST(PHJointBase);
00060
00061 enum IntType{
00062 SYMPLETIC,
00063 ANALYTIC,
00064 }intType;
00065
00066 UTRef<PHSolid> solid;
00067 UTRef<SGFrame> frame;
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 Matrix3d pRj, cRj;
00093 Vec3d prj, crj;
00094
00095 protected:
00096 Vec3d prc;
00097 Matrix3d pRc, cRp;
00098 Matrix3d R;
00099 Quaterniond quat;
00100 Vec3d p;
00101 Vec3d v, v_abs;
00102 Vec3d w, w_abs;
00103 Vec3d pvc, pwc;
00104 SpMatrix6d Ii;
00105 SpMatrix6d Ia;
00106 SpVec6d Za;
00107 SpVec6d c;
00108 SpVec6d a;
00109
00110
00111
00112 Matrix3d rcross, rpcross, rcross_cRp, rpcross_pRc;
00113 SpVec6d a_p, Ia_c, Z_plus_Ia_c;
00114 public:
00115
00116 PHJointBase();
00117
00118 void Loaded(SGScene* scene);
00119
00120 PHJointBase* Search(PHSolid*);
00121
00122 Affinef GetPostureFromParent(){ Affinef rv; rv.Pos()=prj; rv.Rot()=pRj; return rv; }
00123
00124 Affinef GetPostureFromChild(){ Affinef rv; rv.Pos()=crj; rv.Rot()=cRj; return rv; }
00125
00126 Vec3f GetSolidAngularAccel(){ return solid->GetRotation() * a.sub_vector(0, Vec3f()); }
00127
00128 Vec3f GetSolidAccel(){ return solid->GetRotation() * a.sub_vector(3, Vec3f()); }
00129
00130 Vec3f GetSolidAngularVelocity(){ return w_abs; }
00131
00132 Vec3f GetSolidVelocity(){ return v_abs; }
00133
00134 Matrix3d GetOrientation(){return R;}
00135
00136
00137 virtual int GetJointDof()=0;
00138
00139 virtual double GetJointPosition(int i)=0;
00140
00141 virtual double GetJointVelocity(int i)=0;
00142
00143 virtual double GetJointAccel(int i)=0;
00144
00145 virtual double GetJointTorque(int i)=0;
00146
00147 virtual void SetJointTorque(double v, int i)=0;
00148
00149 virtual void AddJointTorque(double v, int i)=0;
00150
00151
00152
00153
00154 void CompCoriolisAccelRecursive(double dt);
00155
00156 virtual void CompArticulatedInertia(double dt);
00157
00158 virtual void Integrate(SGScene* scene);
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 virtual void CalcAccel(double dt)=0;
00174
00175
00176
00177 virtual size_t NChildObjects();
00178
00179 virtual SGObject* ChildObject(size_t i);
00180
00181 virtual size_t NReferenceObjects();
00182
00183 virtual SGObject* ReferenceObject(size_t i);
00184
00185 virtual bool AddChildObject(SGObject* o, SGScene* s);
00186
00187 virtual bool DelChildObject(SGObject* o, SGScene* s);
00188
00189 virtual const UTTypeInfo** ChildCandidates();
00190
00191 void SaveX(XJointBase& x) const;
00192 void LoadX(const XJointBase& x);
00193
00194
00195 virtual void LimitAngle(double& d){}
00196 protected:
00197
00198 template <class T> T& OfParent(T PHJointBase::* member){
00199 return GetParent()->*member;
00200 }
00201
00202 inline SpMatrix6d pXc_Mat_cXp(SpMatrix6d& m);
00203 inline SpVec6d pXc_Vec(SpVec6d& v);
00204 inline SpVec6d cXp_Vec(SpVec6d& v);
00205
00206 virtual void CompJointAxis()=0;
00207 virtual void CompRelativePosition()=0;
00208 virtual void CompRelativeVelocity()=0;
00209 virtual void CompCoriolisAccel()=0;
00210 void UpdateSolid();
00211 void UpdateJointPosture();
00212 void PropagateState();
00213 virtual void ClearTorqueRecursive();
00214 virtual void ClearForce();
00215
00216
00217
00218 virtual void Reset();
00219 virtual void LoadState(const SGBehaviorStates& states);
00220 virtual void SaveState(SGBehaviorStates& states) const;
00221 virtual double MassFactor(){ return 0; }
00222 };
00223
00224 class PHJointRoot:public PHJointBase{
00225 public:
00226 SGOBJECTDEF(PHJointRoot);
00227 virtual void Reset();
00228 virtual void CalcAccel(double dt);
00229 virtual void CompJointAxis(){}
00230 virtual void CompRelativePosition(){}
00231 virtual void CompRelativeVelocity(){}
00232 virtual void CompCoriolisAccel(){}
00233 virtual void Integrate(SGScene* scene);
00234
00235 virtual void LoadState(const SGBehaviorStates& states);
00236
00237 virtual void SaveState(SGBehaviorStates& states) const;
00238 protected:
00239 virtual int GetJointDof(){ return 0; }
00240 virtual double GetJointPosition(int i){ return 0; }
00241 virtual double GetJointVelocity(int i){ return 0; }
00242 virtual double GetJointAccel(int i){ return 0; }
00243 virtual double GetJointTorque(int i){ return 0; }
00244 virtual void SetJointTorque(double v, int i){}
00245 virtual void AddJointTorque(double v, int i){}
00246 };
00247
00248
00249
00250
00251
00252 class PHJointEngine : public PHSolverBase{
00253 public:
00254 SGOBJECTDEF(PHJointEngine);
00255 typedef PHJointBase::array_type array_type;
00256 UTRef<PHJointBase> root;
00257 void ClearForce(){ root->ClearForce(); }
00258 typedef std::set< UTRef<PHSolid> > PHSolidSet;
00259 PHSolidSet solids;
00260
00261
00262 WBPreciseTimer timer;
00263
00264
00265 int GetPriority() const {return SGBP_JOINTENGINE;}
00266 void Step (SGScene* s);
00267 void Loaded(SGScene* scene);
00268 void Clear(SGScene* s){}
00269 PHJointEngine::PHJointEngine(){}
00270
00271
00272 virtual size_t NChildObjects();
00273
00274 virtual SGObject* ChildObject(size_t i);
00275
00276 virtual bool AddChildObject(SGObject* o, SGScene* s);
00277
00278 virtual bool DelChildObject(SGObject* o, SGScene* s);
00279
00280 virtual const UTTypeInfo** ChildCandidates();
00281
00282 bool Has(SGObject*);
00283
00284
00285 virtual void LoadState(const SGBehaviorStates& states);
00286
00287 virtual void SaveState(SGBehaviorStates& states) const;
00288
00289
00290 template <class CT> void EnumJoint(CT& ct){
00291 typedef void (PHJointEngine::*Func)(PHJointBase* b, CT& ct);
00292 Func func = &PHJointEngine::EnumJointFunc;
00293 root->MemberTraverse(this, func, ct);
00294 }
00295 protected:
00296 template <class CT> void EnumJointFunc(PHJointBase* p, CT& ct){
00297 CT::value_type v = DCASTP(CT::value_type, p);
00298 if (v) ct.push_back(v);
00299 }
00300 };
00301
00302
00303 class PHJointClearForce:public SGBehaviorEngine{
00304 SGOBJECTDEF(PHJointClearForce);
00305 public:
00306 UTRef<PHJointEngine> je;
00307
00308 virtual void Step(SGScene* s);
00309 virtual int GetPriority() const { return SGBP_CLEARFORCE; }
00310 };
00311
00312
00313
00314
00315
00316 inline SpSubVec3d& svitem(SpVec6d& v, int i){
00317 return *(SpSubVec3d*)((double*)&v + i*3);
00318 }
00319 inline SpSubMatrix3d& smitem(SpMatrix6d& m, int i, int j){
00320 return m.sub_matrix(i * 3, j * 3, PTM::TMatDim<3, 3>());
00321 }
00322
00323 inline double svdot(const SpVec6d& v1, const SpVec6d& v2){
00324 return
00325 v1[0] * v2[3] + v1[1] * v2[4] + v1[2] * v2[5] +
00326 v1[3] * v2[0] + v1[4] * v2[1] + v1[5] * v2[2];
00327 }
00328
00329
00330 inline Matrix3d mat(const Vec3d& v1, const Vec3d& v2){
00331 return Matrix3d(
00332 v1[0] * v2[0], v1[0] * v2[1], v1[0] * v2[2],
00333 v1[1] * v2[0], v1[1] * v2[1], v1[1] * v2[2],
00334 v1[2] * v2[0], v1[2] * v2[1], v1[2] * v2[2]);
00335 }
00336 inline SpMatrix6d svmat(const SpVec6d& v1, const SpVec6d& v2){
00337 PTM::TVecDim<3> dim3;
00338 const SpSubVec3d& v11 = v1.sub_vector(0, dim3), v12 = v1.sub_vector(3, PTM::TVecDim<3>());
00339 const SpSubVec3d& v21 = v2.sub_vector(0, dim3), v22 = v2.sub_vector(3, PTM::TVecDim<3>());
00340 SpMatrix6d y;
00341 y.sub_matrix(0, 0, PTM::TMatDim<3, 3>()) = mat(v11, v22);
00342 y.sub_matrix(0, 3, PTM::TMatDim<3, 3>()) = mat(v11, v21);
00343 y.sub_matrix(3, 0, PTM::TMatDim<3, 3>()) = mat(v12, v22);
00344 y.sub_matrix(3, 3, PTM::TMatDim<3, 3>()) = mat(v12, v21);
00345 return y;
00346 }
00347 SpMatrix6d PHJointBase::pXc_Mat_cXp(SpMatrix6d& m){
00348 static Matrix3d pRc_m11_cRp, pRc_m12_cRp, pRc_m21_cRp, pRc_m22_cRp, tmp;
00349 pRc_m11_cRp = pRc * smitem(m, 0, 0) * cRp;
00350 pRc_m12_cRp = pRc * smitem(m, 0, 1) * cRp;
00351 pRc_m21_cRp = pRc * smitem(m, 1, 0) * cRp;
00352 pRc_m22_cRp = pRc * smitem(m, 1, 1) * cRp;
00353 tmp = pRc_m11_cRp - pRc * smitem(m, 0, 1) * rcross_cRp;
00354 SpMatrix6d y;
00355 smitem(y, 0, 0) = tmp;
00356 smitem(y, 0, 1) = pRc_m12_cRp;
00357 smitem(y, 1, 0) = rpcross * tmp + pRc_m21_cRp - pRc * smitem(m, 1, 1) * rcross_cRp;
00358 smitem(y, 1, 1) = rpcross * pRc_m12_cRp + pRc_m22_cRp;
00359 return y;
00360 }
00361
00362 SpVec6d PHJointBase::pXc_Vec(SpVec6d& v){
00363 Vec3d pRc_v1 = pRc * svitem(v, 0);
00364 SpVec6d y;
00365 svitem(y, 0) = pRc_v1;
00366 svitem(y, 1) = rpcross * pRc_v1 + pRc * svitem(v, 1);
00367 return y;
00368 }
00369
00370 SpVec6d PHJointBase::cXp_Vec(SpVec6d& v){
00371 Vec3d cRp_v1 = cRp * svitem(v, 0);
00372 SpVec6d y;
00373 svitem(y, 0) = cRp_v1;
00374 svitem(y, 1) = -rcross * cRp_v1 + cRp * svitem(v, 1);
00375 return y;
00376 }
00377
00378
00379 }
00380
00381 #endif