00001
00002 #include "PhysicsBody.h"
00003 #include "PhysicsManager.h"
00004 #include "random_utils/LogManager.h"
00005
00006 #include <ode/ode.h>
00007
00008 #include <vrs/container/iterator.h>
00009 #include <vrs/sg/scenething.h>
00010
00011 #include <vrs/rotation.h>
00012 #include <vrs/translation.h>
00013
00014 namespace vrsode
00015 {
00016
00017 PhysicsBody::PhysicsBody(VRS::SO<VRS::SceneThing> p_sceneThing,
00018 CollisionShape p_collisionShape, bool p_forceSync)
00019 : CollisionBody(p_sceneThing, p_collisionShape, false)
00020 {
00021 m_forceSync = p_forceSync;
00022 m_highSpeedRotationMode = false;
00023 m_highSpeedRotationAxis = VRS::Vector();
00024
00025 dWorldID worldId = PhysicsManager::get()->worldId();
00026
00027 m_bodyId = dBodyCreate(worldId);
00028
00029 if(geomId())
00030 dGeomSetBody(geomId(), m_bodyId);
00031
00032 PhysicsManager::get()->registerPhysicsBody(this);
00033
00034 assert(!geomId() || dGeomGetBody(geomId()) == m_bodyId);
00035
00036 setMass(1);
00037 }
00038
00039 PhysicsBody::PhysicsBody(VRS::SO<VRS::SceneThing> p_sceneThing,
00040 VRS::SO<Shape> p_shape, bool p_forceSync)
00041 : CollisionBody(p_sceneThing, p_shape, false)
00042 {
00043 m_forceSync = p_forceSync;
00044 m_highSpeedRotationMode = false;
00045 m_highSpeedRotationAxis = VRS::Vector();
00046
00047 dWorldID worldId = PhysicsManager::get()->worldId();
00048
00049 m_bodyId = dBodyCreate(worldId);
00050
00051 if(geomId())
00052 dGeomSetBody(geomId(), m_bodyId);
00053
00054 PhysicsManager::get()->registerPhysicsBody(this);
00055
00056 assert(!geomId() || dGeomGetBody(geomId()) == m_bodyId);
00057
00058 setMass(1);
00059 }
00060
00061 PhysicsBody::~PhysicsBody()
00062 {
00063 }
00064
00065 void
00066 PhysicsBody::destroy()
00067 {
00068 PhysicsManager::get()->unregisterCollisionBody(this);
00069 dBodyDestroy(bodyId());
00070 dGeomDestroy(geomId());
00071 }
00072
00073 dBodyID
00074 PhysicsBody::bodyId()
00075 {
00076 return m_bodyId;
00077 }
00078
00079 double
00080 PhysicsBody::mass()
00081 {
00082 dMass mass;
00083 dBodyGetMass(m_bodyId, &mass);
00084 return mass.mass;
00085 }
00086
00087 void
00088 PhysicsBody::setMass(double p_massValue, VRS::Vector p_center)
00089 {
00090 dMass mass;
00091 dMassSetZero(&mass);
00092
00093 dMassSetParameters(&mass, p_massValue,
00094 p_center[0], p_center[1], p_center[2],
00095 0,0,0,0,0,0);
00096
00097 dMassCheck(&mass);
00098 dBodySetMass(m_bodyId, &mass);
00099 }
00100
00101 void
00102 PhysicsBody::setHighSpeedRotationMode(bool p_mode)
00103 {
00104 m_highSpeedRotationMode = p_mode;
00105 dBodySetFiniteRotationMode(m_bodyId, !p_mode);
00106
00107 if(p_mode)
00108 dBodySetFiniteRotationAxis(m_bodyId,
00109 m_highSpeedRotationAxis[0],
00110 m_highSpeedRotationAxis[1],
00111 m_highSpeedRotationAxis[2]);
00112 }
00113
00114 void
00115 PhysicsBody::setHighSpeedRotationAxis(double p_x, double p_y, double p_z)
00116 {
00117 m_highSpeedRotationAxis[0] = p_x;
00118 m_highSpeedRotationAxis[1] = p_y;
00119 m_highSpeedRotationAxis[2] = p_z;
00120 }
00121
00122 void
00123 PhysicsBody::setHighSpeedRotationAxis(VRS::Vector p_vector)
00124 {
00125 setHighSpeedRotationAxis(p_vector[0], p_vector[1], p_vector[2]);
00126 }
00127
00128 void
00129 PhysicsBody::setIgnoreGravity(bool p_ignore)
00130 {
00131 dBodySetGravityMode(m_bodyId, !p_ignore);
00132 }
00133
00134 void
00135 PhysicsBody::update()
00136 {
00137 CollisionBody::update();
00138
00139 if(m_highSpeedRotationMode)
00140 setHighSpeedRotationMode(true);
00141 }
00142
00143 void
00144 PhysicsBody::syncTransformationsToODE()
00145 {
00146 dMatrix3 rot;
00147 VRS::Matrix matrix;
00148
00149 if(odeShape())
00150 matrix = rotation() * odeShape()->offsetRotation()->matrix();
00151 else
00152 matrix = rotation();
00153
00154 rot[ 0] = matrix.element(0, 0);
00155 rot[ 1] = matrix.element(0, 1);
00156 rot[ 2] = matrix.element(0, 2);
00157 rot[ 3] = matrix.element(3, 0);
00158 rot[ 4] = matrix.element(1, 0);
00159 rot[ 5] = matrix.element(1, 1);
00160 rot[ 6] = matrix.element(1, 2);
00161 rot[ 7] = matrix.element(3, 1);
00162 rot[ 8] = matrix.element(2, 0);
00163 rot[ 9] = matrix.element(2, 1);
00164 rot[10] = matrix.element(2, 2);
00165 rot[11] = matrix.element(3, 2);
00166
00167 dBodySetRotation(m_bodyId, rot);
00168
00169 VRS::Vector offset;
00170 if(odeShape())
00171 offset = odeShape()->offsetCenter();
00172
00173 VRS::Vector pos = position() + offset;
00174 dBodySetPosition(m_bodyId, pos[0], pos[1], pos[2]);
00175 }
00176
00177 void
00178 PhysicsBody::syncTransformationsToVRS()
00179 {
00180
00181 if(!m_forceSync)
00182 if((!vrsShape() && !debugNode()))
00183 return;
00184
00185 const dReal* pos = dBodyGetPosition(m_bodyId);
00186 translationNode()->setTranslate(VRS::Vector(pos[0], pos[1], pos[2]));
00187
00188
00189 const dReal* rot = dBodyGetRotation(m_bodyId);
00190 VRS::Matrix* matrix = const_cast<VRS::Matrix*>(&(rotation()));
00191
00192 VRS::SO<VRS::Rotation> undoOffsetRotation = new VRS::Rotation();
00193 undoOffsetRotation->setAngle(odeShape()->offsetRotation()->getAngle() * -1);
00194 undoOffsetRotation->setAxis(odeShape()->offsetRotation()->getAxis());
00195 undoOffsetRotation->setCenter(odeShape()->offsetRotation()->getCenter());
00196
00197 VRS::Matrix odeMatrix;
00198 odeMatrix.setElement(0, 0, rot[ 0]);
00199 odeMatrix.setElement(0, 1, rot[ 1]);
00200 odeMatrix.setElement(0, 2, rot[ 2]);
00201 odeMatrix.setElement(1, 0, rot[ 4]);
00202 odeMatrix.setElement(1, 1, rot[ 5]);
00203 odeMatrix.setElement(1, 2, rot[ 6]);
00204 odeMatrix.setElement(2, 0, rot[ 8]);
00205 odeMatrix.setElement(2, 1, rot[ 9]);
00206 odeMatrix.setElement(2, 2, rot[10]);
00207
00208 VRS::Matrix vrsMatrix;
00209 vrsMatrix = odeMatrix * undoOffsetRotation->matrix();
00210
00211 matrix->setElement(0, 0, vrsMatrix.element(0, 0));
00212 matrix->setElement(0, 1, vrsMatrix.element(0, 1));
00213 matrix->setElement(0, 2, vrsMatrix.element(0, 2));
00214 matrix->setElement(1, 0, vrsMatrix.element(1, 0));
00215 matrix->setElement(1, 1, vrsMatrix.element(1, 1));
00216 matrix->setElement(1, 2, vrsMatrix.element(1, 2));
00217 matrix->setElement(2, 0, vrsMatrix.element(2, 0));
00218 matrix->setElement(2, 1, vrsMatrix.element(2, 1));
00219 matrix->setElement(2, 2, vrsMatrix.element(2, 2));
00220 }
00221
00222 bool
00223 PhysicsBody::isEnabled() const
00224 {
00225 return dBodyIsEnabled(m_bodyId);
00226 }
00227
00228 void
00229 PhysicsBody::setEnabled(bool p_enable)
00230 {
00231 p_enable ? dBodyEnable(m_bodyId) : dBodyDisable(m_bodyId);
00232 }
00233
00234 void
00235 PhysicsBody::setAutoDisableMode(bool p_autoDisable)
00236 {
00237 dBodySetAutoDisableFlag(m_bodyId, p_autoDisable);
00238 }
00239
00240 void
00241 PhysicsBody::setAutoDisableLinearThreshold(double p_threshold)
00242 {
00243 dBodySetAutoDisableLinearThreshold(m_bodyId, p_threshold);
00244 }
00245
00246 void
00247 PhysicsBody::setAutoDisableAngularThreshold(double p_threshold)
00248 {
00249 dBodySetAutoDisableAngularThreshold(m_bodyId, p_threshold);
00250 }
00251
00252 void
00253 PhysicsBody::setAutoDisableTime(double p_time)
00254 {
00255 dBodySetAutoDisableTime(m_bodyId, p_time);
00256 }
00257
00258 void
00259 PhysicsBody::setAutoDisableSteps(unsigned int p_steps)
00260 {
00261 dBodySetAutoDisableSteps(m_bodyId, p_steps);
00262 }
00263
00264 void
00265 PhysicsBody::setAngularVelocity(VRS::Vector p_velocity)
00266 {
00267 dBodySetAngularVel(m_bodyId,
00268 p_velocity[0], p_velocity[0], p_velocity[0]);
00269 }
00270
00271 void
00272 PhysicsBody::setLinearVelocity(VRS::Vector p_velocity)
00273 {
00274 dBodySetLinearVel(m_bodyId,
00275 p_velocity[0], p_velocity[0], p_velocity[0]);
00276 }
00277
00278 VRS::Vector
00279 PhysicsBody::angularVelocity()
00280 {
00281 const dReal* velocity = dBodyGetAngularVel(m_bodyId);
00282 return VRS::Vector(velocity[0], velocity[1], velocity[2]);
00283 }
00284
00285 VRS::Vector
00286 PhysicsBody::linearVelocity()
00287 {
00288 const dReal* velocity = dBodyGetLinearVel(m_bodyId);
00289 return VRS::Vector(velocity[0], velocity[1], velocity[2]);
00290 }
00291
00292 void
00293 PhysicsBody::addForce(VRS::Vector p_force)
00294 {
00295 dBodyAddForce(m_bodyId, p_force[0], p_force[1], p_force[2]);
00296 }
00297
00298 void
00299 PhysicsBody::addTorque(VRS::Vector p_torque)
00300 {
00301 dBodyAddTorque(m_bodyId, p_torque[0], p_torque[1], p_torque[2]);
00302 }
00303
00304 void
00305 PhysicsBody::addRelativeForce(VRS::Vector p_force)
00306 {
00307 dBodyAddRelForce(m_bodyId, p_force[0], p_force[1], p_force[2]);
00308 }
00309
00310 void
00311 PhysicsBody::addRelativeTorque(VRS::Vector p_torque)
00312 {
00313 dBodyAddRelTorque(m_bodyId, p_torque[0], p_torque[1], p_torque[2]);
00314 }
00315
00316 void
00317 PhysicsBody::addForceAtPosition(VRS::Vector p_force, VRS::Vector p_position)
00318 {
00319 dBodyAddForceAtPos(m_bodyId, p_force[0], p_force[1], p_force[2],
00320 p_position[0], p_position[1], p_position[2]);
00321 }
00322
00323 void
00324 PhysicsBody::addRelativeForceAtPosition(VRS::Vector p_force,
00325 VRS::Vector p_position)
00326 {
00327 dBodyAddRelForceAtPos(m_bodyId, p_force[0], p_force[1], p_force[2],
00328 p_position[0], p_position[1], p_position[2]);
00329 }
00330
00331 void
00332 PhysicsBody::addForceAtRelativePosition(VRS::Vector p_force,
00333 VRS::Vector p_position)
00334 {
00335 dBodyAddForceAtRelPos(m_bodyId, p_force[0], p_force[1], p_force[2],
00336 p_position[0], p_position[1], p_position[2]);
00337 }
00338
00339 void
00340 PhysicsBody::addRelativeForceAtRelativePosition(VRS::Vector p_force,
00341 VRS::Vector p_position)
00342 {
00343 dBodyAddRelForceAtRelPos(m_bodyId, p_force[0], p_force[1], p_force[2],
00344 p_position[0], p_position[1], p_position[2]);
00345 }
00346
00347 }