From: Markus R. <rol...@us...> - 2007-05-01 13:14:43
|
Update of /cvsroot/simspark/simspark/spark/oxygen/physicsserver In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv18276 Modified Files: space.cpp space.h Log Message: - made HandleSpaceCollide non virtual and protected - made collisionNearCallback a static member function - added member HandleSpaceCollide() that handles collisions between two space geoms - added method OnLink() that registers the Space to the proper parent space - adapted DestroyODEObject() and DestroySpaceObjects() to handle space containing other spaces Index: space.cpp =================================================================== RCS file: /cvsroot/simspark/simspark/spark/oxygen/physicsserver/space.cpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** space.cpp 15 Mar 2007 07:26:27 -0000 1.2 --- space.cpp 1 May 2007 13:14:40 -0000 1.3 *************** *** 29,33 **** using namespace oxygen; ! static void collisionNearCallback (void *data, dGeomID obj1, dGeomID obj2) { Space *space = (Space*)data; --- 29,33 ---- using namespace oxygen; ! void Space::collisionNearCallback (void *data, dGeomID obj1, dGeomID obj2) { Space *space = (Space*)data; *************** *** 64,70 **** } void Space::HandleCollide(dGeomID obj1, dGeomID obj2) { ! // reject collisions between bodies that are connected with joints const dBodyID b1 = dGeomGetBody(obj1); const dBodyID b2 = dGeomGetBody(obj2); --- 64,97 ---- } + void Space::HandleSpaceCollide(dGeomID obj1, dGeomID obj2) + { + // collide all geoms internal to the space(s) + dSpaceCollide2 (obj1,obj2,this,&collisionNearCallback); + + if (dGeomIsSpace (obj1)) + { + dSpaceCollide ((dSpaceID)(obj1),this,&collisionNearCallback); + } + + if (dGeomIsSpace (obj2)) + { + dSpaceCollide ((dSpaceID)(obj2),this,&collisionNearCallback); + } + } + void Space::HandleCollide(dGeomID obj1, dGeomID obj2) { ! if ( ! (dGeomIsSpace (obj1)) || ! (dGeomIsSpace (obj2)) ! ) ! { ! // colliding a space with something ! HandleSpaceCollide(obj1, obj2); ! return; ! } ! ! // colliding two non-space geoms; reject collisions ! // between bodies that are connected with joints const dBodyID b1 = dGeomGetBody(obj1); const dBodyID b2 = dGeomGetBody(obj2); *************** *** 112,129 **** } bool Space::ConstructInternal() { ! // create the ode space, 0 indicates that this space should ! // not be inserted into another space, i.e. we always create a ! // toplevel space object ! mODESpace = dHashSpaceCreate(0); ! // create a joint group for the contacts ! mODEContactGroup = dJointGroupCreate(0); ! return ( ! (mODESpace != 0) && ! (mODEContactGroup != 0) ! ); } --- 139,190 ---- } + void Space::OnLink() + { + ODEObject::OnLink(); + + dSpaceID space = FindSpaceID(); + if ( + (space) && + (space != mODESpace) && + (! dSpaceQuery(space, (dGeomID)mODESpace)) + ) + { + dSpaceAdd(space, (dGeomID)mODESpace); + } + } + + dSpaceID Space::GetParentSpaceID() + { + if (mODESpace == 0) + { + return 0; + } + + return dGeomGetSpace((dGeomID)mODESpace); + } + + bool Space::IsGlobalSpace() + { + return + ( + (mODESpace != 0) && + (GetParentSpaceID() == 0) + ); + } + bool Space::ConstructInternal() { ! // create the ode space, 0 indicates that this space should ! // not be inserted into another space, i.e. we always create a ! // toplevel space object ! mODESpace = dHashSpaceCreate(0); ! // create a joint group for the contacts ! mODEContactGroup = dJointGroupCreate(0); ! return ( ! (mODESpace != 0) && ! (mODEContactGroup != 0) ! ); } *************** *** 136,188 **** void Space::DestroySpaceObjects() { ! shared_ptr<Scene> scene = GetScene(); ! if (scene.get() == 0) ! { ! return; ! } ! TLeafList objects; ! const bool recursive = true; ! scene->ListChildrenSupportingClass<ODEObject>(objects, recursive); ! for ( ! TLeafList::iterator iter = objects.begin(); ! iter != objects.end(); ! ++iter ! ) ! { ! shared_ptr<ODEObject> object = shared_static_cast<ODEObject>(*iter); ! if (object->GetSpaceID() != mODESpace) { ! continue; ! } ! object->DestroyODEObject(); ! } } void Space::DestroyODEObject() { ! static bool recurseLock = false; ! ! if ( ! (recurseLock) || ! (! mODESpace) ! ) ! { ! return; ! } ! ! recurseLock = true; ! ! // make sure that all objects registered to this space are destroyed ! // before this space. Any other order provokes a segfault in ODE. ! DestroySpaceObjects(); ! // release the ODE space ! dSpaceDestroy(mODESpace); ! mODESpace = 0; ! recurseLock = false; } --- 197,254 ---- void Space::DestroySpaceObjects() { ! shared_ptr<Scene> scene = GetScene(); ! if (scene.get() == 0) ! { ! return; ! } ! TLeafList objects; ! const bool recursive = true; ! scene->ListChildrenSupportingClass<ODEObject>(objects, recursive); ! bool globalSpace = IsGlobalSpace(); ! shared_ptr<Space> self = shared_static_cast<Space>(GetSelf().lock()); ! for ( ! TLeafList::iterator iter = objects.begin(); ! iter != objects.end(); ! ++iter ! ) { ! shared_ptr<ODEObject> object = shared_static_cast<ODEObject>(*iter); ! if (object == self) ! { ! continue; ! } ! // destroy objects registered to this space; the top level ! // space object also destroy any other ODE object ! const dSpaceID parentSpace = object->GetParentSpaceID(); ! if ( ! ( ! (globalSpace) && ! (parentSpace == 0) ! ) || ! (parentSpace == mODESpace) ! ) ! { ! object->DestroyODEObject(); ! } ! } } void Space::DestroyODEObject() { ! if (! mODESpace) ! { ! return; ! } ! // make sure that all objects registered to this space are destroyed ! // before this space. Any other order provokes a segfault in ODE. ! DestroySpaceObjects(); ! // release the ODE space ! dSpaceDestroy(mODESpace); ! mODESpace = 0; } Index: space.h =================================================================== RCS file: /cvsroot/simspark/simspark/spark/oxygen/physicsserver/space.h,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** space.h 15 Mar 2007 07:26:27 -0000 1.2 --- space.h 1 May 2007 13:14:40 -0000 1.3 *************** *** 59,72 **** void Collide(); /** callback to handle a potential collision between two contained geoms. It will look up and notify the corresponding colliders for a potential collision. */ ! virtual void HandleCollide(dGeomID obj1, dGeomID obj2); ! /** destroy the managed ODE object */ ! virtual void DestroyODEObject(); - protected: /** creates them managed ODE space and a contact joint group */ virtual bool ConstructInternal(); --- 59,88 ---- void Collide(); + /** destroy the managed ODE object */ + virtual void DestroyODEObject(); + + /** returns the ODE handle ID of the containing parent space */ + virtual dSpaceID GetParentSpaceID(); + + /** returns true if this is the top global, i.e. top level space object */ + bool IsGlobalSpace(); + + protected: + static void collisionNearCallback (void *data, dGeomID obj1, dGeomID obj2); + + /** registers the managed space to the containing parent space */ + virtual void OnLink(); + /** callback to handle a potential collision between two contained geoms. It will look up and notify the corresponding colliders for a potential collision. */ ! void HandleCollide(dGeomID obj1, dGeomID obj2); ! /** handle the collision between two geoms from which at least one ! is a space geom ! */ ! void HandleSpaceCollide(dGeomID obj1, dGeomID obj2); /** creates them managed ODE space and a contact joint group */ virtual bool ConstructInternal(); |