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 #include <PVLE/Physics/Body.h>
00028 #include <PVLE/Physics/World.h>
00029 #include <PVLE/Physics/Joint.h>
00030 #include <PVLE/Physics/Visitor.h>
00031 #include <PVLE/Util/Assert.h>
00032
00033 namespace Physics {
00034
00035 Mass::Mass(EDirectInit init_mode, dReal value, const osg::Vec3 & size) : idBody(0) {
00036 if (init_mode == BOX) setBox(value, size);
00037 else if (init_mode == BOX_TOTAL) setBoxTotal(value, size);
00038 else THROW_TRACED_EXCEPTION("Bad argument (illegal mode)");
00039 }
00040 Mass::Mass(EDirectInit init_mode, dReal value, dReal radius) : idBody(0) {
00041 if (init_mode == SPHERE) setSphere(value, radius);
00042 else if (init_mode == SPHERE_TOTAL) setSphereTotal(value, radius);
00043 else THROW_TRACED_EXCEPTION("Bad argument (illegal mode)");
00044 }
00045 Mass::Mass(EDirectInit init_mode, dReal value, EAxis axis, dReal radius, dReal length) : idBody(0) {
00046 if (init_mode == CAPSULE) setCapsule(value, axis, radius, length);
00047 else if (init_mode == CAPSULE_TOTAL) setCapsuleTotal(value, axis, radius, length);
00048 else if (init_mode == CYLINDER) setCylinder(value, axis, radius, length);
00049 else if (init_mode == CYLINDER_TOTAL) setCylinderTotal(value, axis, radius, length);
00050 else THROW_TRACED_EXCEPTION("Bad argument (illegal mode)");
00051 }
00052
00053
00054
00055
00056 Body::Body(const World * pWorld) : pWorld(pWorld), allowCollideWithJointBodies(false), windFactor(1) {
00057 ASSERT(pWorld);
00058 id = dBodyCreate(pWorld->id);
00059 dBodySetData(id, this);
00060
00061 dBodySetFiniteRotationMode(id, 0);
00062 setInfluencedByGravity(true);
00063
00064
00065 massData.idBody = id;
00066 massData.setSphere(1, 1);
00067 }
00068
00069 Body::Body(const Body & v) : pWorld(v.pWorld), allowCollideWithJointBodies(v.allowCollideWithJointBodies), massData(v.massData), windFactor(1) {
00070 id = dBodyCreate(pWorld->id);
00071 dBodySetData(id, this);
00072
00073 if (dBodyIsEnabled(v)) dBodyEnable(*this); else dBodyDisable(*this);
00074 dBodySetAutoDisableFlag(*this, dBodyGetAutoDisableFlag(v));
00075 dBodySetAutoDisableLinearThreshold(*this, dBodyGetAutoDisableLinearThreshold(v));
00076 dBodySetAutoDisableAngularThreshold(*this, dBodyGetAutoDisableAngularThreshold(v));
00077 dBodySetAutoDisableSteps(*this, dBodyGetAutoDisableSteps(v));
00078 dBodySetAutoDisableTime(*this, dBodyGetAutoDisableTime(v));
00079 dBodySetAutoDisableAverageSamplesCount(*this, dBodyGetAutoDisableAverageSamplesCount(v));
00080
00081 dBodySetFiniteRotationMode(*this, dBodyGetFiniteRotationMode(v));
00082 dVector3 finiteRotAxis;
00083 dBodyGetFiniteRotationAxis(v, finiteRotAxis);
00084 ::dBodySetFiniteRotationAxis(*this, finiteRotAxis[0], finiteRotAxis[1], finiteRotAxis[2]);
00085
00086 setInfluencedByGravity(v.isInfluencedByGravity());
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 const dReal * pos = dBodyGetPosition(v);
00099 ::dBodySetPosition(*this, pos[0], pos[1], pos[2]);
00100 dQuaternion rot;
00101 dBodyCopyQuaternion(v, rot);
00102 ::dBodySetQuaternion(*this, rot);
00103
00104 const dReal * vel = dBodyGetLinearVel(v);
00105 ::dBodySetLinearVel(*this, vel[0], vel[1], vel[2]);
00106 const dReal * avel = dBodyGetAngularVel(v);
00107 ::dBodySetAngularVel(*this, avel[0], avel[1], avel[2]);
00108
00109 const dReal * force = dBodyGetForce(v);
00110 ::dBodySetForce(*this, force[0], force[1], force[2]);
00111 const dReal * torque = dBodyGetTorque(v);
00112 ::dBodySetTorque(*this, torque[0], torque[1], torque[2]);
00113
00114
00115 massData.idBody = id;
00116 massData = v.massData;
00117 }
00118
00119 Joint * Body::getJoint(UINT index) {
00120 dJointID jId = dBodyGetJoint(id, index);
00121 return jId ? static_cast<Joint *>(dJointGetData(jId)) : NULL;
00122 }
00123
00124 const Joint * Body::getJoint(UINT index) const {
00125 dJointID jId = dBodyGetJoint(id, index);
00126 return jId ? static_cast<Joint *>(dJointGetData(jId)) : NULL;
00127 }
00128
00129
00130 #ifdef ENABLE_PHYSICS_EXTRA_WRAPPING
00131 bool Body::isConnectedTo(Body * pBody) const { return dAreConnected(id, pBody->id) !=0; }
00132 #endif
00133 bool Body::isConnectedToExcludingContact(Body * pBody) const { return dAreConnectedExcluding(id, pBody->id, Joint::CONTACT) !=0; }
00134
00135 void Body::accept(Visitor & v) { v.apply(*this); }
00136 void Body::traverse(Visitor & v) {
00137 UINT nbJoints = dBodyGetNumJoints(id);
00138 for(UINT i=0, iEnd=nbJoints; i<iEnd; ++i) v.apply(*getJoint(i));
00139 }
00140
00141 }