vrsode/src/PhysicsBody.cpp

Go to the documentation of this file.
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     // no sync if there is nothing to see, except for force sync
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     // TODO: maybe there is a way without violating const
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 }

Generated on Fri May 11 21:01:58 2007 for Random Racer by  doxygen 1.5.1