moving RigibBodies from one physics world to another

jackskelyton
Posts: 32
Joined: Mon Nov 05, 2007 3:52 pm

moving RigibBodies from one physics world to another

Post by jackskelyton »

We're having a curious bug in our game code.. we divide levels into "scenes" with private physics worlds (btDiscreetDynamicsWorlds). When we move actors from one scene to another -- the character, for example -- we want to get his physics data in the form of his btRigidBody, load it into the new scene's physics world, and delete it from the world in the previous scene. We can't destroy the old scene's world because we want to be able to move back. We've set it up like so:

To change scenes:

Code: Select all

void SceneSystem::SetCurrentScene(Scene* scene) {

      // Loop through the current scene and pull actors
      // out that transfer over
      if (mCurrentScene) {
      . . .
         }
      }

      mCurrentScene = scene;
      GAME->GetPhysicsSystem()->SetPhysicsWorld(mCurrentScene->GetPhysicsWorld());
      mCurrentScene->OnLoad();
   }
}
SetPhysicsWorld just reassigns the pointer in our updating PhysicsSystem world from the former scene's world to the present one (we use a wrapper class, PhysicsWorld, to hold all the bullet objects):

Code: Select all

void PhysicsSystem::SetPhysicsWorld(PhysicsWorld* physicsWorld) {
   mPhysicsWorld = physicsWorld->GetPhysicsWorld();
}
The actors get moved in an AddActor and RemoveActor call, and these just call the relevant bullet methods to add and remove a btRigidBody, like so:

Code: Select all

bool PhysicsWorld::RemovePhysicsObject(PhysicsObject* object) {
   if (!object) {
      return 0;
   }

   mPhysicsWorld->removeRigidBody(object->GetBTRigidBody());
   return 1;
}
The funny thing is, if we comment out the line that deletes the actor from the old world, everything appears to work fine: the new scene loads, the new physics world is up and running with the transferred actors right there. I've stepped through the code and all the objects are valid all the way through. But if we call that remove method, all the Actor and btRigidBody data will still appear to be good, but the code breaks when we attempt stepSimulation on the new world. Any ideas?
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: moving RigibBodies from one physics world to another

Post by Erwin Coumans »

You should first remove the rigidbody from the first world, and later add the rigidbody to the other.

You cannot reorder the remove/addRigidBody, because during removal from the btDynamicsWorld, internally the broadphase handle is invalidated. When adding to a new world, it will re-create a new broadphase handle.

>> but the code breaks when we attempt stepSimulation on the new world.
Where does it break, any callstack?

Thanks,
Erwin
jackskelyton
Posts: 32
Joined: Mon Nov 05, 2007 3:52 pm

Re: moving RigibBodies from one physics world to another

Post by jackskelyton »

Aha, excellent. That was indeed the problem. We've still got a few problems but they appear to be internal, proprietary code -- not Bullet. Thanks.