00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef PHY_JOINT_H
00028 #define PHY_JOINT_H
00029
00030 #include <ode/ode.h>
00031 #include <PVLE/Physics/Converters.h>
00032 #include <PVLE/Physics/Contact.h>
00033 #include <PVLE/Export.h>
00034 #include <PVLE/Util/Util.h>
00035 #include <PVLE/Util/TracedException.h>
00036
00037 #include <set>
00038 #include <osg/ref_ptr>
00039 #include <osg/Vec3>
00040 #include <osg/Referenced>
00041
00042 namespace Physics {
00043
00044
00045 class World;
00046 class Body;
00047 class Visitor;
00048
00051 class JointFeedback : protected dJointFeedback {
00052 public:
00053 osg::Vec3 getF1() const { return toGraphVec3(f1); }
00054 osg::Vec3 getT1() const { return toGraphVec3(t1); }
00055 osg::Vec3 getF2() const { return toGraphVec3(f2); }
00056 osg::Vec3 getT2() const { return toGraphVec3(t2); }
00057
00058 friend class Joint;
00059 };
00060
00061
00072 class PVLE_EXPORT Joint : public osg::Referenced {
00073 public:
00076 enum EJointType {
00077 BALL = dJointTypeBall,
00078 HINGE = dJointTypeHinge,
00079 HINGE2 = dJointTypeHinge2,
00080 UNIVERSAL = dJointTypeUniversal,
00081
00082 SLIDER = dJointTypeSlider,
00083 PRISMATIC_ROTOIDE = dJointTypePR,
00084 FIXED = dJointTypeFixed,
00085
00086 CONTACT = dJointTypeContact,
00087
00088 ANGULAR_MOTOR = dJointTypeAMotor,
00089 LINEAR_MOTOR = dJointTypeLMotor,
00090
00091 PLANE2D = dJointTypePlane2D
00092 };
00093
00095 enum EAnchoredTo {
00096 GLOBAL = 0,
00097 BODY1 = 1,
00098 BODY2 = 2
00099 };
00100
00102 enum EAMotorMode {
00103 ANGULAR_MOTOR_USER = dAMotorUser,
00104 ANGULAR_MOTOR_EULER = dAMotorEuler
00105 };
00106
00108 Joint(World * pWorld, EJointType type);
00110 Joint(World * pWorld, Contact * pContact = NULL);
00112 Joint(const Joint & v);
00113
00114 ~Joint() { if (id) dJointDestroy(id); }
00115
00117 inline EJointType getType() const { return static_cast<EJointType>(dJointGetType(id)); }
00119 void attach(Body * pBody1, Body * pBody2);
00120
00122 Body * getBody1();
00124 Body * getBody2();
00125
00127 const Body * getBody1() const;
00129 const Body * getBody2() const;
00130
00132 UINT getNumBodies() const { return static_cast<UINT>(dJointGetNumBodies(id)); }
00133
00136 void setFeedback(JointFeedback * pJointFeedback) { dJointSetFeedback(id, pJointFeedback); }
00138 inline JointFeedback * getFeedback() { return static_cast<JointFeedback *>(dJointGetFeedback(id)); }
00140 inline const JointFeedback * getFeedback() const { return static_cast<const JointFeedback *>(dJointGetFeedback(id)); }
00141
00147
00150 void setPos(const osg::Vec3 & pos);
00153 osg::Vec3 getPosBody1() const;
00156 osg::Vec3 getPosBody2() const;
00157
00160 void setAxis1(const osg::Vec3 & axis);
00162 osg::Vec3 getAxis1() const;
00165 void setAxis2(const osg::Vec3 & axis);
00167 osg::Vec3 getAxis2() const;
00168
00170 void setAMotorMode(EAMotorMode mode);
00172 EAMotorMode getAMotorMode() const;
00175 void setNumAxes(UCHAR num);
00178 UCHAR getNumAxes() const;
00180
00182 void setMotorAxis(UCHAR num, EAnchoredTo frame, const osg::Vec3 & axis);
00185 osg::Vec3 getMotorAxis(UCHAR num) const;
00188 EAnchoredTo getAxisFrameAMotor(UCHAR num) const;
00191 void setAxisAngleAMotor(UCHAR num, dReal angle);
00194 dReal getAxisAngleAMotor(UCHAR num) const;
00197 dReal getAxisAngleRateAMotor(UCHAR num) const;
00198
00201 dReal getRelAngleAxis1() const;
00204 dReal getRelAngleRateAxis1() const;
00206 dReal getRelAngleRateAxis2() const;
00207
00210 dReal getRelPosAxis1() const;
00213 dReal getRelPosRateAxis1() const;
00214
00216
00217
00220
00222 void setCFM(dReal val, UINT axis=0) { ASSERT(axis<=3); getODESetParamFuncPt()(id, dParamCFM + dParamGroup*axis, val); }
00223 dReal getCFM(UINT axis=0) const { ASSERT(axis<=3); return getODEGetParamFuncPt()(id, dParamCFM + dParamGroup*axis); }
00225
00231
00233 void setLoStop(dReal val, UINT axis=0) { ASSERT(axis<=3); getODESetParamFuncPt()(id, dParamLoStop + dParamGroup*axis, val); }
00234 dReal getLoStop(UINT axis=0) const { ASSERT(axis<=3); return getODEGetParamFuncPt()(id, dParamLoStop + dParamGroup*axis); }
00235
00237 void setHiStop(dReal val, UINT axis=0) { ASSERT(axis<=3); getODESetParamFuncPt()(id, dParamHiStop + dParamGroup*axis, val); }
00238 dReal getHiStop(UINT axis=0) const { ASSERT(axis<=3); return getODEGetParamFuncPt()(id, dParamHiStop + dParamGroup*axis); }
00239
00241 void setStopBouncyness(dReal val, UINT axis=0) { ASSERT(axis<=3); getODESetParamFuncPt()(id, dParamBounce + dParamGroup*axis, val); }
00242 dReal getStopBouncyness(UINT axis=0) const { ASSERT(axis<=3); return getODEGetParamFuncPt()(id, dParamBounce + dParamGroup*axis); }
00243
00245 void setStopERP(dReal val, UINT axis=0) { ASSERT(axis<=3); getODESetParamFuncPt()(id, dParamStopERP + dParamGroup*axis, val); }
00246 dReal getStopERP(UINT axis=0) const { ASSERT(axis<=3); return getODEGetParamFuncPt()(id, dParamStopERP + dParamGroup*axis); }
00247
00249 void setStopCFM(dReal val, UINT axis=0) { ASSERT(axis<=3); getODESetParamFuncPt()(id, dParamStopCFM + dParamGroup*axis, val); }
00250 dReal getStopCFM(UINT axis=0) const { ASSERT(axis<=3); return getODEGetParamFuncPt()(id, dParamStopCFM + dParamGroup*axis); }
00252
00256
00257 void setMotorVel(dReal val, UINT axis=0) { ASSERT(axis<=3); getODESetParamFuncPt()(id, dParamVel + dParamGroup*axis, val); }
00258 dReal getMotorVel(UINT axis=0) const { ASSERT(axis<=3); return getODEGetParamFuncPt()(id, dParamVel + dParamGroup*axis); }
00259
00260 void setMotorMaxForce(dReal val, UINT axis=0) { ASSERT(axis<=3); getODESetParamFuncPt()(id, dParamFMax + dParamGroup*axis, val); }
00261 dReal getMotorMaxForce(UINT axis=0) const { ASSERT(axis<=3); return getODEGetParamFuncPt()(id, dParamFMax + dParamGroup*axis); }
00262
00264 void setMotorFudgeFactor(dReal val, UINT axis=0) { ASSERT(axis<=3); getODESetParamFuncPt()(id, dParamFudgeFactor + dParamGroup*axis, val); }
00265 dReal getMotorFudgeFactor(UINT axis=0) const { ASSERT(axis<=3); return getODEGetParamFuncPt()(id, dParamFudgeFactor + dParamGroup*axis); }
00267
00270
00272 void copyParameters(const Joint & v);
00273
00274
00275
00276
00277
00278
00279
00281
00285
00286 void translate(const osg::Vec3 & vec);
00287
00288
00289
00290 void rotate(const osg::Quat & quat);
00292 void rotate(const osg::Quat & quat, const osg::Vec3 & center);
00293
00295
00296 virtual void accept(Visitor & v);
00297
00298
00299 protected:
00300 friend class JointGroup;
00301 mutable dJointID id;
00302 dWorldID worldId;
00303
00304 Joint(World * pWorld, EJointType type, dJointGroupID joinGroup);
00305 Joint(World * pWorld, Contact * pContact, dJointGroupID joinGroup);
00306
00307 void init(EJointType type, dContact * pContact = NULL, dJointGroupID joinGroup = NULL);
00308
00309
00310 typedef void(*TFuncODESetParam)(dJointID, int, dReal);
00311 typedef dReal(*TFuncODEGetParam)(dJointID, int);
00312
00313 TFuncODESetParam getODESetParamFuncPt() const;
00314 TFuncODEGetParam getODEGetParamFuncPt() const;
00315 };
00316
00317
00319 class JointGroup : public osg::Referenced {
00320 public:
00321 JointGroup() { id = dJointGroupCreate(0); }
00322
00323 Joint * createAndAdd(World * pWorld, Joint::EJointType type) {
00324 Joint * pJ = new Joint(pWorld, type, id);
00325 vJoints.insert(pJ);
00326 return pJ;
00327 }
00328
00329 Joint * createAndAdd(World * pWorld, Contact * pContact) {
00330 Joint * pJ = new Joint(pWorld, pContact, id);
00331 vJoints.insert(pJ);
00332 return pJ;
00333 }
00334
00336 void clear() { vJoints.clear(); dJointGroupEmpty(id); }
00337
00338 protected:
00339 mutable dJointGroupID id;
00340 std::set<osg::ref_ptr<Joint> > vJoints;
00341
00344 virtual ~JointGroup() { dJointGroupDestroy(id); }
00345 };
00346
00347 }
00348
00349 #endif // PHY_JOINT_H
00350