vrsode/src/CollisionBody.cpp

Go to the documentation of this file.
00001 
00002 #include "CollisionBody.h"
00003 #include "PhysicsManager.h"
00004 #include "BoxShape.h"
00005 #include "CylinderShape.h"
00006 #include "SphereShape.h"
00007 #include "NoShape.h"
00008 #include "PlaneShape.h"
00009 
00010 #include "random_utils/LogManager.h"
00011 // #include "random_utils/AutoLocker.h"
00012 
00013 #include <ode/ode.h>
00014 
00015 #include <vrs/container/iterator.h>
00016 #include <vrs/sg/scenething.h>
00017 
00018 #include <vrs/box.h>
00019 #include <vrs/colorattribute.h>
00020 #include <vrs/constantdetail.h>
00021 #include <vrs/facestyle.h>
00022 #include <vrs/plane.h>
00023 #include <vrs/rotation.h>
00024 #include <vrs/shape.h>
00025 #include <vrs/sphere.h>
00026 #include <vrs/translation.h>
00027 
00028 namespace vrsode
00029 {
00030 
00031 CollisionBody::CollisionBody(VRS::SO<VRS::SceneThing> p_sceneThing,
00032                              CollisionShape p_collisionShape, bool p_register)
00033 {
00034     m_cleanedUp         = false;
00035     m_reportCollision   = false;
00036     m_wantToDestroy     = false;
00037     m_sceneThing        = p_sceneThing;
00038     m_collisionShape    = p_collisionShape;
00039 
00040     setupTransformationNodes();
00041 
00042     VRS::Bounds boundingBox = m_sceneThing->boundingBox(0);
00043 
00044     switch(m_collisionShape)
00045     {
00046         case CS_Sphere:
00047             m_odeShape = new SphereShape(boundingBox);
00048             m_geomId = m_odeShape->geomId();
00049         break;
00050         case CS_Box:
00051             m_odeShape = new BoxShape(boundingBox);
00052             m_geomId = m_odeShape->geomId();
00053         break;
00054         case CS_None:
00055             m_odeShape = new NoShape();
00056             m_geomId = m_odeShape->geomId();
00057         break;
00058         default:
00059             rErr("NOT IMPLEMENTED: Provided CollisionShape cannot be "
00060                  "generated, please provide a pre created shape.");
00061             m_odeShape = 0;
00062             m_geomId = 0;
00063         break;
00064     }
00065 
00066     if(m_geomId)
00067     {
00068         dSpaceAdd(PhysicsManager::get()->spaceId(), m_geomId);
00069         dGeomSetData(m_geomId, this);
00070         syncTransformationsToODE();
00071         setSurface(new Surface());
00072         if(p_register)
00073             PhysicsManager::get()->registerCollisionBody(this);
00074     }
00075 }
00076 
00077 CollisionBody::CollisionBody(VRS::SO<VRS::SceneThing> p_sceneThing,
00078               VRS::SO<Shape> p_shape, bool p_register)
00079 {
00080     m_cleanedUp         = false;
00081     m_reportCollision   = false;
00082     m_wantToDestroy     = false;
00083     m_sceneThing        = p_sceneThing;
00084     m_collisionShape    = p_shape->collisionShape();
00085     m_sceneNodeLock     = new SceneNodeLock;
00086 
00087     setupTransformationNodes();
00088 
00089     m_odeShape          = p_shape;
00090     m_geomId            = p_shape->geomId();
00091 
00092     if(m_geomId)
00093     {
00094         dSpaceAdd(PhysicsManager::get()->spaceId(), m_geomId);
00095         dGeomSetData(m_geomId, this);
00096         syncTransformationsToODE();
00097         setSurface(new Surface());
00098         if(p_register)
00099             PhysicsManager::get()->registerCollisionBody(this);
00100     }
00101 }
00102 
00103 CollisionBody::~CollisionBody()
00104 {
00105     // if(!m_cleanedUp)
00106     //     destroy();
00107 }
00108 
00109 void
00110 CollisionBody::destroy()
00111 {
00112     PhysicsManager::get()->unregisterCollisionBody(this);
00113     dGeomDestroy(geomId());
00114     m_cleanedUp = true;
00115 }
00116 
00117 bool
00118 CollisionBody::cleanedUp()
00119 {
00120     return m_cleanedUp;
00121 }
00122 
00123 void
00124 CollisionBody::setCleanedUp(bool p_cleanedUp)
00125 {
00126     m_cleanedUp = p_cleanedUp;
00127 }
00128 
00129 VRS::SO<VRS::SceneThing>
00130 CollisionBody::sceneThing() const
00131 {
00132     return m_sceneThing;
00133 }
00134 
00135 const dGeomID
00136 CollisionBody::geomId() const
00137 {
00138     return m_geomId;
00139 }
00140 
00141 const CollisionShape
00142 CollisionBody::collisionShape() const
00143 {
00144     return m_collisionShape;
00145 }
00146 
00147 void
00148 CollisionBody::setupTransformationNodes()
00149 {
00150     if(!m_sceneThing)
00151     {
00152         rErr("Tried to setup a PhysicsBody which does not have a SceneThing "
00153              "associated. Nothing done!");
00154         return;
00155     }
00156 
00157     // find the shape object
00158     m_vrsShape = 0;
00159     for(int i = 0; i < m_sceneThing->objects(); i++)
00160         if(m_vrsShape = dynamic_cast<VRS::Shape*>(m_sceneThing->object(i)))
00161            break;
00162 
00163     // check for rotation object
00164     VRS::Iterator<VRS::SO<VRS::SharedObj> >* rotationItr =
00165             m_sceneThing->find(VRS::Rotation::ClassNameVRS());
00166 
00167     // if no rotation node is present, add one.
00168     if(rotationItr->size() == 0)
00169     {
00170         m_rotation = new VRS::Rotation();
00171         m_sceneThing->prepend(m_rotation);
00172     }
00173     else
00174     {
00175         // TODO: handle already existing rotations.
00176         rErr("Handling already existing rotations is not yet implemented!");
00177         return;
00178     }
00179 
00180     // check for translation object
00181     VRS::Iterator<VRS::SO<VRS::SharedObj> >* translationItr =
00182             m_sceneThing->find(VRS::Translation::ClassNameVRS());
00183 
00184     // if no translation node was found, add one.
00185     if(translationItr->size() == 0)
00186     {
00187         m_translation = new VRS::Translation(0, 0, 0);
00188         m_sceneThing->prepend(m_translation);
00189     }
00190     else
00191     {
00192         // TODO: handle already existing translations.
00193         rErr("Handling already existing translations is not yet implemented!");
00194         return;
00195     }
00196 
00197     // locker object not needed anymore since we have "ThreadSafeCanvas"
00198     // insertLocker();
00199 }
00200 
00201 void
00202 CollisionBody::insertLocker()
00203 {
00204     while(m_sceneThing->objects())
00205     {
00206         m_sceneNodeLock->append(m_sceneThing->object(0));
00207         m_sceneThing->remove(0);
00208     }
00209 
00210     m_sceneThing->append(m_sceneNodeLock);
00211 }
00212 
00213 const VRS::Vector
00214 CollisionBody::position() const
00215 {
00216     return m_translation->getTranslate();
00217 }
00218 
00219 void
00220 CollisionBody::setPosition(double p_x, double p_y, double p_z)
00221 {
00222     setPosition(VRS::Vector(p_x, p_y, p_z));
00223 }
00224 
00225 void
00226 CollisionBody::setPosition(VRS::Vector p_position)
00227 {
00228     // RU_SYNCHRONIZE(PhysicsManager::get());
00229     m_translation->setTranslate(p_position);
00230 
00231     syncTransformationsToODE();
00232 }
00233 
00234 const VRS::Matrix&
00235 CollisionBody::rotation() const
00236 {
00237     return m_rotation->matrix();
00238 }
00239 
00240 
00241 void
00242 CollisionBody::setRotation(double p_axisX, double p_axisY, double p_axisZ,
00243                            double p_angle)
00244 {
00245     setRotation(VRS::Vector(p_axisX, p_axisY, p_axisZ), p_angle);
00246 }
00247 
00248 void
00249 CollisionBody::setRotation(VRS::Vector p_axis, double p_angle)
00250 {
00251     // RU_SYNCHRONIZE(PhysicsManager::get());
00252 
00253     VRS::Vector offset;
00254     if(m_odeShape)
00255         offset = m_odeShape->offsetCenter();
00256 
00257     m_rotation->setAxis(p_axis);
00258     m_rotation->setCenter(offset);
00259     m_rotation->setAngle(p_angle);
00260 
00261     syncTransformationsToODE();
00262 }
00263 
00264 void
00265 CollisionBody::syncTransformationsToODE()
00266 {
00267     if(dGeomGetClass(m_geomId) == dPlaneClass)
00268         return;
00269 
00270     dMatrix3 rot;
00271     VRS::Matrix matrix;
00272     
00273     if(m_odeShape)
00274         matrix = rotation() * m_odeShape->offsetRotation()->matrix();
00275     else
00276         matrix = rotation();
00277 
00278     rot[ 0] = matrix.element(0, 0);
00279     rot[ 1] = matrix.element(0, 1);
00280     rot[ 2] = matrix.element(0, 2);
00281     rot[ 3] = matrix.element(3, 0);
00282     rot[ 4] = matrix.element(1, 0);
00283     rot[ 5] = matrix.element(1, 1);
00284     rot[ 6] = matrix.element(1, 2);
00285     rot[ 7] = matrix.element(3, 1);
00286     rot[ 8] = matrix.element(2, 0);
00287     rot[ 9] = matrix.element(2, 1);
00288     rot[10] = matrix.element(2, 2);
00289     rot[11] = matrix.element(3, 2);
00290 
00291     dGeomSetRotation(m_geomId, rot);
00292 
00293     VRS::Vector offset;
00294     if(m_odeShape)
00295         offset = m_odeShape->offsetCenter();
00296 
00297     VRS::Vector pos = position() + offset;
00298     dGeomSetPosition(m_geomId, pos[0], pos[1], pos[2]);
00299 }
00300 
00301 void
00302 CollisionBody::setDebugNode(bool p_debugNode)
00303 {
00304     if(!m_odeShape)
00305         return;
00306 
00307     if(m_odeShape->debugNodeActive() == p_debugNode)
00308         return;
00309         
00310     m_odeShape->activateDebugNode(p_debugNode);
00311     
00312     if(p_debugNode)
00313         m_sceneThing->append(m_odeShape->debugNode());
00314     else
00315         m_sceneThing->remove(m_odeShape->debugNode());
00316 }
00317 
00318 VRS::SO<VRS::Translation>
00319 CollisionBody::translationNode()
00320 {
00321     return m_translation;
00322 }
00323 
00324 VRS::SO<VRS::Rotation>
00325 CollisionBody::rotationNode()
00326 {
00327     return m_rotation;
00328 }
00329 
00330 VRS::SO<VRS::Shape>
00331 CollisionBody::vrsShape()
00332 {
00333     return m_vrsShape;
00334 }
00335 
00336 void
00337 CollisionBody::handleCollision(VRS::SO<CollisionBody> p_partner)
00338 {
00339     if(m_reportCollision)
00340         std::cout << this << " collided with " << p_partner << std::endl;
00341 }
00342 
00343 void
00344 CollisionBody::setSurface(VRS::SO<Surface> p_surface)
00345 {
00346     m_surface = p_surface;
00347 }
00348 
00349 VRS::SO<Surface>
00350 CollisionBody::surface()
00351 {
00352     return m_surface;
00353 }
00354 
00355 VRS::SO<Shape>
00356 CollisionBody::odeShape()
00357 {
00358     return m_odeShape;
00359 }
00360 
00361 bool
00362 CollisionBody::debugNode()
00363 {
00364     if(m_odeShape)
00365         return m_odeShape->debugNodeActive();
00366     return false;
00367 }
00368 
00369 void
00370 CollisionBody::setCollisionCategory(unsigned int p_value)
00371 {
00372 //     // RU_SYNCHRONIZE(PhysicsManager::get());
00373     if(m_geomId)
00374         dGeomSetCategoryBits(m_geomId, p_value);
00375 }
00376 
00377 unsigned int
00378 CollisionBody::collisionCategory()
00379 {
00380     if(!m_geomId)
00381         return 0;
00382 
00383 //     // RU_SYNCHRONIZE(PhysicsManager::get());
00384     return dGeomGetCategoryBits(m_geomId);
00385 }
00386 
00387 void
00388 CollisionBody::setCollisionPartnerCategories(unsigned int p_value)
00389 {
00390 //     // RU_SYNCHRONIZE(PhysicsManager::get());
00391     if(m_geomId)
00392         dGeomSetCollideBits(m_geomId, p_value);
00393 }
00394 
00395 unsigned int
00396 CollisionBody::collisionPartnerCategories()
00397 {
00398     if(!m_geomId)
00399         return 0;
00400 
00401 //     // RU_SYNCHRONIZE(PhysicsManager::get());
00402     return dGeomGetCollideBits(m_geomId);
00403 }
00404 
00405 VRS::SO<SceneNodeLock>
00406 CollisionBody::sceneNodeLock()
00407 {
00408     return m_sceneNodeLock;
00409 }
00410 
00411 void
00412 CollisionBody::setReportCollision(bool p_report)
00413 {
00414     m_reportCollision = p_report;
00415 }
00416 
00417 void
00418 CollisionBody::wantToDestroy()
00419 {
00420     m_wantToDestroy = true;
00421 }
00422 
00423 void
00424 CollisionBody::update()
00425 {
00426     if(m_wantToDestroy)
00427         destroy();
00428 }
00429 
00430 }

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