2

I'm using box2d along with libgdx on a project I'm working on. I'm having a slight problem destroying a body/the fixtures of a body. Essentially, I want to completely destroy the body, which I do by destroying the fixtures of said body. Everything works perfectly fine with a body with one fixture, but when I use two fixtures, only one fixture get's destroyed, leaving the body intact with the other fixture.

Here's two pictures to demonstrate what I mean:

With both fixtures: With both fixtures

With only one fixture: With only one fixture

Here is how I create the body:

BodyDef bodyDef = new BodyDef();
        bodyDef.type = BodyType.DynamicBody;
        bodyDef.position.set(level.character.position);
        Body body = b2world.createBody(bodyDef);
        body.setUserData(level.character);
        level.character.body = body;

        CircleShape polygonShapeHead = new CircleShape();
        origin.x = level.character.circleBoundOrigin.x * 2.0f;
        origin.y = level.character.circleBoundOrigin.y * 3.0f;
        //polygonShapeHead.setAsBox(level.character.circleBoundOrigin.x,
                //level.character.circleBoundOrigin.y, origin, 0);
        polygonShapeHead.setPosition(origin);
        polygonShapeHead.setRadius(level.character.circleBoundOrigin.x);
        FixtureDef fixtureDefHead = new FixtureDef();
        fixtureDefHead.shape = polygonShapeHead;
        fixtureDefHead.friction = level.character.friction.x;
        body.createFixture(fixtureDefHead);

        polygonShapeHead.dispose();

        PolygonShape polygonShapeBod = new PolygonShape();
        origin = level.character.rectBoundOrigin;
        polygonShapeBod.setAsBox(level.character.rectBoundOrigin.x,
                level.character.rectBoundOrigin.y, origin, 0);
        FixtureDef fixtureDefBod = new FixtureDef();
        fixtureDefBod.shape = polygonShapeBod;
        fixtureDefBod.friction = level.character.friction.x;
        body.createFixture(fixtureDefBod);

        polygonShapeBod.dispose();

Here is my code for destroying the bodies:

public static void removeSpecifiedBodies() {
        for (Body body : bodiesToRemoveList) {
            Array<Fixture> fixtures = body.getFixtureList();
            for (Fixture fixture : fixtures) {
                body.destroyFixture(fixture);
            }
        }
        bodiesToRemoveList.clear();
    }

I call this static method after my b2world is stepped. I checked the logging, and the fixtures size is 2, and it is being run twice, but only one fixture is being destroyed. Why is this happening? And what is being destroyed? It runs twice, but I'm only seeing one of them getting destroyed.

Edit: Instead of using that above remove, method, I added

for(Body body : CollisionHandler.bodiesToRemoveList)
            b2world.destroyBody(body);

after b2world.step, but it froze everything. :(

josephoneill
  • 853
  • 2
  • 10
  • 33

3 Answers3

1

GetFixtureList only returns the first fixture. You need to say

var fix = body.GetFixtureList();
while (fix) {
   body.DestroyFixture(fix);
   fix = fix.next();
}
Code Whisperer
  • 22,959
  • 20
  • 67
  • 85
  • Hm... I didn't know that. The javadoc explanation was pretty weird. Thanks, I'll try it! Actually, and maybe its different in java, but getFixtureList returns a list of fixtures, not just a single fixture. – josephoneill Apr 19 '14 at 13:47
  • I'm working from JavaScript Box2D version but as far as I know functions with the exact same name do the same thing in every implementation – Code Whisperer Apr 19 '14 at 13:55
  • I ran some tests and it appears even though my `Array fixtures = body.getFixtureList();` size is 2, my loop only runs once. Did some research and turns out I clear the list of bodies to remove before the loops are done. This doesn't make any sense though. It should only be wiped after it iterates through the entire list of bodies... – josephoneill Apr 19 '14 at 14:06
  • I guess I'll make a new question since it seems my issue isn't with Box2D but with my java – josephoneill Apr 19 '14 at 14:54
  • I don't know about Java, but C++ uses that chained list structure. For instance, I use `for (b2Fixture* f = body->GetFixtureList(); f; f = f->GetNext()) body->DestroyFixture(f); ` – hsandt Sep 03 '17 at 18:59
0

I was having the same problem using LibGDX with Box2d.

this way solved the problem:

int fixtureCount = body.getFixtureList().size;
for(int i=0;i<fixtureCount;i++){
    body.destroyFixture(body.getFixtureList().get(0));
}
0

body.destroyFixturewill modify( see line 130) fixtureList. Try this:

while (body.getFixtureList().size > 0) {
    body.destroyFixture(body.getFixtureList().first());
}
YieldNull
  • 126
  • 1
  • 4