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_BODY_H
00028 #define PHY_BODY_H
00029
00030
00031 #ifndef ENABLE_PHYSICS_BASIC_WRAPPING
00032
00033 #endif
00034 #ifndef ENABLE_PHYSICS_EXTRA_WRAPPING
00035
00036 #endif
00037
00038 #include <ode/ode.h>
00039 #include <PVLE/Physics/Converters.h>
00040 #include <PVLE/Export.h>
00041 #include <PVLE/Util/Util.h>
00042 #include <osg/Vec3>
00043 #include <osg/Quat>
00044 #include <osg/Matrix>
00045 #include <osg/Referenced>
00046
00047 namespace Physics {
00048
00049
00053 class Mass : private dMass {
00054 public:
00055 enum EAxis {
00056 X_AXIS = 1,
00057 Y_AXIS = 2,
00058 Z_AXIS = 3,
00059 };
00060
00061 enum EDirectInit {
00062 SPHERE,
00063 SPHERE_TOTAL,
00064 BOX,
00065 BOX_TOTAL,
00066 CYLINDER,
00067 CYLINDER_TOTAL,
00068 CAPSULE,
00069 CAPSULE_TOTAL
00070 };
00071
00073 Mass() : idBody(0) {}
00075 Mass(EDirectInit init_mode, dReal value, const osg::Vec3 & size);
00077 Mass(EDirectInit init_mode, dReal value, dReal radius);
00079 Mass(EDirectInit init_mode, dReal value, EAxis axis, dReal radius, dReal length);
00080
00081 Mass & operator= (const Mass & v) {
00082
00083 static_cast<dMass>(*this) = static_cast<dMass>(v); return *this;
00084 }
00085
00086 dReal getMass() const { return mass; }
00087 osg::Matrix getInertiaTensor() const { return toGraphMatInertia(I); }
00089 osg::Vec3 getCenter() { return osg::Vec3(c[0], c[1], c[2]); }
00091 osg::Vec3 centerMass() { osg::Vec3 translation(-c[0], -c[1], -c[2]); translateMass(translation); return translation; }
00092
00094 void adjust(dReal mass) { dMassAdjust(this, mass); if (idBody) dBodySetMass(idBody, this); }
00096 void addMass(const Mass & m2) { dMassAdd(this, &m2); if (idBody) dBodySetMass(idBody, this); }
00098 Mass & operator+=(const Mass & m2) { dMassAdd(this, &m2); if (idBody) dBodySetMass(idBody, this); return *this; }
00099
00100 void translateMass(const osg::Vec3 & vec) { dMassTranslate(this, vec.x(), vec.y(), vec.z()); if (idBody) dBodySetMass(idBody, this); }
00101 void rotateMass(const osg::Quat & q) { dMatrix3 mat; toPhyMatRotation(osg::Matrix(q), mat); dMassRotate(this, mat); if (idBody) dBodySetMass(idBody, this); }
00102 void rotateMass(const osg::Matrix & m) { dMatrix3 mat; toPhyMatRotation(m, mat); dMassRotate(this, mat); if (idBody) dBodySetMass(idBody, this); }
00103
00105 void setSphere(dReal density, dReal radius) { dMassSetSphere(this, density, radius); if (idBody) dBodySetMass(idBody, this); }
00107 void setSphereTotal(dReal totalMass, dReal radius) { dMassSetSphereTotal(this, totalMass, radius); if (idBody) dBodySetMass(idBody, this); }
00108
00109 void setBox(dReal density, const osg::Vec3 & size) { dMassSetBox(this, density, size.x(), size.y(), size.z()); if (idBody) dBodySetMass(idBody, this); }
00110 void setBoxTotal(dReal totalMass, const osg::Vec3 & size) { dMassSetBoxTotal(this, totalMass, size.x(), size.y(), size.z()); if (idBody) dBodySetMass(idBody, this); }
00111
00112 void setCylinder(dReal density, EAxis axis, dReal radius, dReal length) { dMassSetCylinder(this, density, axis, radius, length); if (idBody) dBodySetMass(idBody, this); }
00113 void setCylinderTotal(dReal totalMass, EAxis axis, dReal radius, dReal length) { dMassSetCylinderTotal(this, totalMass, axis, radius, length); if (idBody) dBodySetMass(idBody, this); }
00114
00115 void setCapsule(dReal density, EAxis axis, dReal radius, dReal length) { dMassSetCapsule(this, density, axis, radius, length); if (idBody) dBodySetMass(idBody, this); }
00116 void setCapsuleTotal (dReal totalMass, EAxis axis, dReal radius, dReal length) { dMassSetCapsuleTotal(this, totalMass, axis, radius, length); if (idBody) dBodySetMass(idBody, this); }
00117
00118
00119
00120
00122 void setZero() { dMassSetZero(this); }
00123
00124 protected:
00125 friend class Body;
00126 operator dMass() { return *this; }
00127
00128 dBodyID idBody;
00129 };
00130
00131
00132
00133
00134
00135 inline void dBodySetFiniteRotationAxis(dBodyID id, const osg::Vec3f & axis) { dBodySetFiniteRotationAxis(id, axis.x(), axis.y(), axis.z()); }
00136 inline osg::Vec3 dBodyGetFiniteRotationAxisV(dBodyID id) { dVector3 res; dBodyGetFiniteRotationAxis(id, res); return toGraphVec3(res); }
00137 inline void dBodySetPosition(dBodyID id, const osg::Vec3 & pos) { dBodySetPosition(id, pos.x(), pos.y(), pos.z()); }
00138 inline osg::Vec3 dBodyGetPositionV(dBodyID id) { return toGraphVec3(dBodyGetPosition(id)); }
00139 inline void dBodySetQuaternion(dBodyID id, const osg::Quat & quat) { dQuaternion q; toPhyQuat(quat, q); dBodySetQuaternion(id, q); }
00140 inline osg::Quat dBodyGetQuaternionV(dBodyID id) { return toGraphQuat(dBodyGetQuaternion(id));}
00141 inline void dBodySetRotation(dBodyID id, const osg::Matrix & matrix) { dMatrix3 rot; toPhyMatRotation(matrix, rot); dBodySetRotation(id, rot); }
00142 inline osg::Matrix dBodyGetRotationV(dBodyID id, const osg::Matrix & matrix) { return toGraphMatRotation(dBodyGetRotation(id)); }
00143
00144 inline void dBodySetLinearVel(dBodyID id, const osg::Vec3 & vel) { dBodySetLinearVel(id, vel.x(), vel.y(), vel.z()); }
00145 inline osg::Vec3 dBodyGetLinearVelV(dBodyID id) { return toGraphVec3(dBodyGetLinearVel(id)); }
00146 inline void dBodySetAngularVel(dBodyID id, const osg::Vec3 & angularVel) { dBodySetAngularVel(id, angularVel.x(), angularVel.y(), angularVel.z()); }
00147 inline osg::Vec3 dBodyGetAngularVelV(dBodyID id) { return toGraphVec3(dBodyGetAngularVel(id)); }
00148
00149 inline void dBodySetForce (dBodyID id, const osg::Vec3 & f) { dBodySetForce (id, f.x(), f.y(), f.z()); }
00150 inline void dBodySetTorque(dBodyID id, const osg::Vec3 & f) { dBodySetTorque(id, f.x(), f.y(), f.z()); }
00151 inline osg::Vec3 dBodyGetForceV (dBodyID id) { return toGraphVec3(dBodyGetForce (id)); }
00152 inline osg::Vec3 dBodyGetTorqueV(dBodyID id) { return toGraphVec3(dBodyGetTorque(id)); }
00153 inline void dBodyAddForce (dBodyID id, const osg::Vec3 & f) { dBodyAddForce (id, f.x(), f.y(), f.z()); }
00154 inline void dBodyAddTorque(dBodyID id, const osg::Vec3 & f) { dBodyAddTorque(id, f.x(), f.y(), f.z()); }
00155 inline void dBodyAddRelForce (dBodyID id, const osg::Vec3 & f) { dBodyAddRelForce (id, f.x(), f.y(), f.z()); }
00156 inline void dBodyAddRelTorque(dBodyID id, const osg::Vec3 & f) { dBodyAddRelTorque(id, f.x(), f.y(), f.z()); }
00157 inline void dBodyAddForceAtPos(dBodyID id, const osg::Vec3 & f, const osg::Vec3 & pos) { dBodyAddForceAtPos(id, f.x(), f.y(), f.z(), pos.x(), pos.y(), pos.z()); }
00158 inline void dBodyAddForceAtRelPos(dBodyID id, const osg::Vec3 & f, const osg::Vec3 & pos) { dBodyAddForceAtRelPos(id, f.x(), f.y(), f.z(), pos.x(), pos.y(), pos.z()); }
00159 inline void dBodyAddRelForceAtPos(dBodyID id, const osg::Vec3 & f, const osg::Vec3 & pos) { dBodyAddRelForceAtPos(id, f.x(), f.y(), f.z(), pos.x(), pos.y(), pos.z()); }
00160 inline void dBodyAddRelForceAtRelPos(dBodyID id, const osg::Vec3 & f, const osg::Vec3 & pos) { dBodyAddRelForceAtRelPos(id, f.x(), f.y(), f.z(), pos.x(), pos.y(), pos.z()); }
00161
00162 inline osg::Vec3 dBodyGetRelPointPosV (dBodyID id, const osg::Vec3 & p) { dVector3 v; dBodyGetRelPointPos (id, p.x(), p.y(), p.z(), v); return toGraphVec3(v); }
00163 inline osg::Vec3 dBodyGetPosRelPointV (dBodyID id, const osg::Vec3 & p) { dVector3 v; dBodyGetPosRelPoint (id, p.x(), p.y(), p.z(), v); return toGraphVec3(v); }
00164 inline osg::Vec3 dBodyVectorToWorldV (dBodyID id, const osg::Vec3 & p) { dVector3 v; dBodyVectorToWorld (id, p.x(), p.y(), p.z(), v); return toGraphVec3(v); }
00165 inline osg::Vec3 dBodyVectorFromWorldV(dBodyID id, const osg::Vec3 & p) { dVector3 v; dBodyVectorFromWorld(id, p.x(), p.y(), p.z(), v); return toGraphVec3(v); }
00166 inline osg::Vec3 dBodyGetRelPointVelV (dBodyID id, const osg::Vec3 & p) { dVector3 v; dBodyGetRelPointVel (id, p.x(), p.y(), p.z(), v); return toGraphVec3(v); }
00167 inline osg::Vec3 dBodyGetPointVelV (dBodyID id, const osg::Vec3 & p) { dVector3 v; dBodyGetPointVel (id, p.x(), p.y(), p.z(), v); return toGraphVec3(v); }
00168
00169
00170 class World;
00171 class Joint;
00172 class Visitor;
00173
00178 class PVLE_EXPORT Body : public osg::Referenced {
00179 public:
00180 Body(const World * pWorld);
00182 Body(const Body & v);
00183 ~Body() { if (id) dBodyDestroy(id); }
00184
00187
00188 #ifdef ENABLE_PHYSICS_EXTRA_WRAPPING
00189
00191 void enable() { dBodyEnable(id); }
00193 void disable() { dBodyDisable(id); }
00195 bool isEnabled() const { return dBodyIsEnabled(id) != 0; }
00196
00197 void setAutoDisableFlag(bool flag) { dBodySetAutoDisableFlag(id, flag ? 1 : 0); }
00198 bool getAutoDisableFlag() const { return dBodyGetAutoDisableFlag(id) != 0; }
00199
00200 void setAutoDisableLinearThreshold(dReal threshold) { dBodySetAutoDisableLinearThreshold(id, threshold); }
00201 dReal getAutoDisableLinearThreshold() const { return dBodyGetAutoDisableLinearThreshold(id); }
00202
00203 void setAutoDisableAngularThreshold(dReal threshold) { dBodySetAutoDisableAngularThreshold(id, threshold); }
00204 dReal getAutoDisableAngularThreshold() const { return dBodyGetAutoDisableAngularThreshold(id); }
00205
00207 void setAutoDisableSteps(UINT steps) { dBodySetAutoDisableSteps(id, steps); }
00208 UINT getAutoDisableSteps() const { return dBodyGetAutoDisableSteps(id); }
00209
00211 void setAutoDisableTime(dReal time) { dBodySetAutoDisableTime(id, time); }
00212 dReal getAutoDisableTime() const { return dBodyGetAutoDisableTime(id); }
00213
00214 void setAutoDisableAverageSamplesCount(UINT value) { dBodySetAutoDisableAverageSamplesCount(id, value); }
00215 dReal getAutoDisableAverageSamplesCount() const { return dBodyGetAutoDisableAverageSamplesCount(id); }
00216
00218 void resetAutoDisableParameters() { dBodySetAutoDisableDefaults(id); }
00220
00224 void setHighSpeedRotationMode(bool enable, const osg::Vec3 & axis = osg::Vec3()) {
00225 if (enable) {
00226 dBodySetFiniteRotationMode(id, 1);
00227 dBodySetFiniteRotationAxis(id, axis);
00228 }
00229 else dBodySetFiniteRotationMode(id, 0);
00230 }
00231 bool getHighSpeedRotationMode() const { return dBodyGetFiniteRotationMode(id) != 0; }
00232 #endif
00233
00234 const Mass & getMassData() const { return massData; }
00235 Mass & getMassData() { return massData; }
00236
00239
00240 #ifdef ENABLE_PHYSICS_BASIC_WRAPPING
00241 void setPos(const osg::Vec3 & pos) { dBodySetPosition(id, pos); }
00242 osg::Vec3 getPos() const { return dBodyGetPositionV(id); }
00243 #endif
00244 void translate(const osg::Vec3 & vec) { const dReal * v = dBodyGetPosition(id); dBodySetPosition(id, v[0] + vec.x(), v[1] + vec.y(), v[2] + vec.z()); }
00245
00246 #ifdef ENABLE_PHYSICS_BASIC_WRAPPING
00247 void setQuaternion(const osg::Quat & quat) { dBodySetQuaternion(id, quat); }
00248 osg::Quat getQuaternion() const { return dBodyGetQuaternionV(id); }
00249 #endif
00250 void rotate(const osg::Quat & quat) { dBodySetQuaternion(id, dBodyGetQuaternionV(id) * quat); }
00252 void rotate(const osg::Quat & quat, const osg::Vec3 & center) {
00253 setMatrix(getMatrix() * osg::Matrix::translate(-center) * osg::Matrix::rotate(quat) * osg::Matrix::translate(center));
00254 }
00255
00257 void setMatrix(const osg::Matrix & matrix) {
00258 dBodySetPosition(id, matrix.getTrans());
00259 dBodySetRotation(id, matrix);
00260 }
00262 osg::Matrix getMatrix() const { return toGraphMatRotationPosition(dBodyGetRotation(id), dBodyGetPosition(id)); }
00263
00264 #ifdef ENABLE_PHYSICS_BASIC_WRAPPING
00265 void setLinearVel(const osg::Vec3 & vel) { dBodySetLinearVel(id, vel.x(), vel.y(), vel.z()); }
00266 osg::Vec3 getLinearVel() const { return toGraphVec3(dBodyGetLinearVel(id)); }
00267
00268 void setAngularVel(const osg::Vec3 & angularVel) { dBodySetAngularVel(id, angularVel.x(), angularVel.y(), angularVel.z()); }
00269 osg::Vec3 getAngularVel() const { return toGraphVec3(dBodyGetAngularVel(id)); }
00270 #endif
00271
00272 #ifdef ENABLE_PHYSICS_EXTRA_WRAPPING
00273 void setMaxAngularVel(dReal maxAngularVel) { dBodySetMaxAngularSpeed(id, maxAngularVel); }
00274 dReal getMaxAngularVel() const { return dBodyGetMaxAngularSpeed(id); }
00275 #endif
00276
00278
00279
00281
00282 #ifdef ENABLE_PHYSICS_BASIC_WRAPPING
00285 void setForce(const osg::Vec3 & f) { dBodySetForce(id, f.x(), f.y(), f.z()); }
00288 void setTorque(const osg::Vec3 & f) { dBodySetTorque(id, f.x(), f.y(), f.z()); }
00289
00291 osg::Vec3 getForce() const { return toGraphVec3(dBodyGetForce (id)); }
00293 osg::Vec3 getTorque() const { return toGraphVec3(dBodyGetTorque(id)); }
00294
00295 void addForce(const osg::Vec3 & f) { dBodyAddForce(id, f.x(), f.y(), f.z()); }
00296 void addTorque(const osg::Vec3 & f) { dBodyAddTorque(id, f.x(), f.y(), f.z()); }
00298 void addRelForce(const osg::Vec3 & f) { dBodyAddRelForce(id, f.x(), f.y(), f.z()); }
00299 void addRelTorque(const osg::Vec3 & f) { dBodyAddRelTorque(id, f.x(), f.y(), f.z()); }
00300
00302 void addForceAtPos(const osg::Vec3 & f, const osg::Vec3 & pos) { dBodyAddForceAtPos(id, f.x(), f.y(), f.z(), pos.x(), pos.y(), pos.z()); }
00304 void addForceAtRelPos(const osg::Vec3 & f, const osg::Vec3 & pos) { dBodyAddForceAtRelPos(id, f.x(), f.y(), f.z(), pos.x(), pos.y(), pos.z()); }
00306 void addRelForceAtPos(const osg::Vec3 & f, const osg::Vec3 & pos) { dBodyAddRelForceAtPos(id, f.x(), f.y(), f.z(), pos.x(), pos.y(), pos.z()); }
00308 void addRelForceAtRelPos(const osg::Vec3 & f, const osg::Vec3 & pos) { dBodyAddRelForceAtRelPos(id, f.x(), f.y(), f.z(), pos.x(), pos.y(), pos.z()); }
00309 #endif
00310
00312 dReal getWindFactor() const { return windFactor; }
00314 void setWindFactor(dReal factor) { windFactor = factor; }
00316
00317
00318 #ifdef ENABLE_PHYSICS_BASIC_WRAPPING
00320 osg::Vec3 getPointPosLTW(const osg::Vec3 & p) const { dVector3 v; dBodyGetRelPointPos(id, p.x(), p.y(), p.z(), v); return toGraphVec3(v); }
00322 osg::Vec3 getPointPosWTL(const osg::Vec3 & p) const { dVector3 v; dBodyGetPosRelPoint(id, p.x(), p.y(), p.z(), v); return toGraphVec3(v); }
00323
00325 osg::Vec3 getVectorLTW(const osg::Vec3 & p) const { dVector3 v; dBodyVectorToWorld(id, p.x(), p.y(), p.z(), v); return toGraphVec3(v); }
00327 osg::Vec3 getVectorWTL(const osg::Vec3 & p) const { dVector3 v; dBodyVectorFromWorld(id, p.x(), p.y(), p.z(), v); return toGraphVec3(v); }
00328
00330 osg::Vec3 getRelPointVel(const osg::Vec3 & p) const { dVector3 v; dBodyGetRelPointVel(id, p.x(), p.y(), p.z(), v); return toGraphVec3(v); }
00332 osg::Vec3 getPointVel(const osg::Vec3 & p) const { dVector3 v; dBodyGetPointVel(id, p.x(), p.y(), p.z(), v); return toGraphVec3(v); }
00333 #endif
00334
00335 #ifdef ENABLE_PHYSICS_EXTRA_WRAPPING
00336 UINT getNbJoints() const { return dBodyGetNumJoints(id); }
00337 #endif
00338 Joint * getJoint(UINT index);
00339 const Joint * getJoint(UINT index) const;
00340
00341 void setInfluencedByGravity(bool flag) { dBodySetGravityMode(id, flag ? 1 : 0); }
00342 bool isInfluencedByGravity() const { return dBodyGetGravityMode(id) != 0; }
00343
00344 #ifdef ENABLE_PHYSICS_EXTRA_WRAPPING
00345 bool isConnectedTo(Body * pBody) const;
00346 #endif
00347 bool isConnectedToExcludingContact(Body * pBody) const;
00348
00354 void setAllowCollideWithJointBodies(bool flag) { allowCollideWithJointBodies = flag; }
00355 bool getAllowCollideWithJointBodies() const { return allowCollideWithJointBodies; }
00356
00357 const World * getWorld() const { return pWorld; }
00358
00360 std::vector<osg::Vec3> contactPos;
00361
00362 virtual void accept(Visitor & v);
00363 virtual void traverse(Visitor & v);
00364
00365 operator dBodyID() { return id; }
00366 operator const dBodyID() const { return id; }
00367
00368 protected:
00369 friend class Geom;
00370 friend class Joint;
00371 mutable dBodyID id;
00372 Mass massData;
00373 dReal windFactor;
00374
00375 const World * pWorld;
00376 bool allowCollideWithJointBodies;
00377 };
00378
00379
00380 }
00381
00382 #endif // PHY_BODY_H