Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

space.cpp

Go to the documentation of this file.
00001 /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*-
00002 
00003    this file is part of rcssserver3D
00004    Fri May 9 2003
00005    Copyright (C) 2003 Koblenz University
00006    $Id: space.cpp,v 1.8 2004/04/30 14:48:15 rollmark Exp $
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; version 2 of the License.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00020 */
00021 
00022 #include "space.h"
00023 #include "world.h"
00024 #include "collider.h"
00025 #include <oxygen/sceneserver/scene.h>
00026 #include <zeitgeist/logserver/logserver.h>
00027 
00028 using namespace boost;
00029 using namespace oxygen;
00030 
00031 static void collisionNearCallback (void *data, dGeomID obj1, dGeomID obj2)
00032 {
00033     Space *space = (Space*)data;
00034     space->HandleCollide(obj1, obj2);
00035 }
00036 
00037 Space::Space() : mODESpace(0), mODEContactGroup(0)
00038 {
00039 }
00040 
00041 Space::~Space()
00042 {
00043   if (mODEContactGroup)
00044     {
00045       dJointGroupDestroy(mODEContactGroup);
00046       mODEContactGroup = 0;
00047     }
00048 
00049   // release the ODE space
00050   if (mODESpace)
00051     {
00052       dSpaceDestroy(mODESpace);
00053       mODESpace = 0;
00054     }
00055 }
00056 
00057 dSpaceID Space::GetODESpace() const
00058 {
00059   return mODESpace;
00060 }
00061 
00062 dJointGroupID Space::GetODEJointGroup() const
00063 {
00064   return mODEContactGroup;
00065 }
00066 
00067 void Space::Collide()
00068 {
00069     // bind collision callback function to this object
00070     dSpaceCollide(mODESpace, this, collisionNearCallback);
00071 }
00072 
00073 void Space::HandleCollide(dGeomID obj1, dGeomID obj2)
00074 {
00075     // reject collisions between bodies that are connected with joints
00076     const dBodyID b1 = dGeomGetBody(obj1);
00077     const dBodyID b2 = dGeomGetBody(obj2);
00078 
00079     if ((b1) && (b2) && (dAreConnected(b1,b2)))
00080         {
00081             return;
00082         }
00083 
00084     // dSpaceCollide(), is guaranteed to pass all potentially
00085     // intersecting geom pairs to the callback function, but depending
00086     // on the internal algorithms used by the space it may also make
00087     // mistakes and pass non-intersecting pairs. Thus we can not
00088     // expect that dCollide() will return contacts for every pair
00089     // passed to the callback.
00090     static const int nContacts = 6;
00091     static dContact contacts[nContacts];
00092 
00093     int n = dCollide (obj1, obj2, nContacts,
00094                       &contacts[0].geom, sizeof(dContact));
00095 
00096     if (n == 0)
00097     {
00098         return;
00099     }
00100 
00101     // get shared pointers to the two corresponding Collider nodes
00102     shared_ptr<Collider> collider = Collider::GetCollider(obj1);
00103     shared_ptr<Collider> collidee = Collider::GetCollider(obj2);
00104 
00105     if (
00106         (collider.get() == 0) ||
00107         (collidee.get() == 0)
00108         )
00109       {
00110         return;
00111       }
00112 
00113     for (int i=0;i<n;++i)
00114         {
00115             // notify the collider nodes
00116             collider->OnCollision(collidee,contacts[i],Collider::CT_DIRECT);
00117             collidee->OnCollision(collider,contacts[i],Collider::CT_SYMMETRIC);
00118         }
00119 }
00120 
00121 bool Space::ConstructInternal()
00122 {
00123   // create the ode space, 0 indicates that this space should
00124   // not be inserted into another space, i.e. we always create a
00125   // toplevel space object
00126   mODESpace = dHashSpaceCreate(0);
00127 
00128   // create a joint group for the contacts
00129   mODEContactGroup = dJointGroupCreate(0);
00130 
00131   return (
00132           (mODESpace != 0) &&
00133           (mODEContactGroup != 0)
00134           );
00135 }
00136 
00137 void Space::PostPhysicsUpdateInternal()
00138 {
00139     // remove all contact joints
00140     dJointGroupEmpty (mODEContactGroup);
00141 }
00142 

Generated on Thu Apr 6 15:25:40 2006 for rcssserver3d by  doxygen 1.4.4