Tuesday, December 27, 2016

libgdx - How do I destroy a Box2D body on contact without getting an IsLocked assertion error?


I get this error when attempting to remove a body from the world:



java: /var/lib/hudson/jobs/libgdx/workspace/trunk/gdx/jni/Box2D/Dynamics/b2World.cpp:134: void b2World::DestroyBody(b2Body*): Assertion 'IsLocked() == false' failed.



What am I doing wrong?



Answer



From my little experience with box2d in libgdx, it can sometimes be difficult to isolate and resolve issues with exceptions which was only worsened by the latest port. Pre 2.2.1, I could easily remove bodies from the world without synchronization issues like you are experiencing but after migrating to the libgdx build that supported 2.2.1, I started seeing the same issues. The workaround for me, which was suggested by several people was that you cannot remove bodies from the world while the world is possibly being simulated.


Is there a possibility that you are attempting to remove a body from the world when the world is being stepped? Basically, if you try to do this, box2d doesn't like it so what you have to do is remove bodies outside of the world.step. What I did was added a utility class for the body's .userData with a bool isFlaggedForDelete which would get checked outside the world.step method.



public void sweepDeadBodies() {
for (Iterator iter = CURRENT_WORLD.getBodies(); iter.hasNext();) {
Body body = iter.next();
if(body!=null) {
YourCustomUserData data = (YourCustomUserData) body.getUserData();
if(data.isFlaggedForDelete) {
CURRENT_WORLD.destroyBody(body);
body.setUserData(null);
body = null;
}

}
}

If you run something like this right after your world.step, it should work. In your code where you are trying to destroy the body, just set it's .isFlaggedForDelete to true and it will get removed before the next world.step.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...