GuilhE
GuilhE

Reputation: 11861

Box2d collisions assert error

I'm using AndEngine anchor-center branch so I can't use PhysicsEditor to create bodies/fixtures since the only parser PhysicsEditor-AndEngine it's a bit out of date and doesn't support anchor-center, so I thought I could use R.U.B.E instead and it's AndEngineRubeLoaderExtension. So far so good, I can create my bodies with all their complex fixtures because RUBE will divide them into convex polygons (automatically).

The parser works great and I've my body. but I'm running into some collision errors:

A/libc﹕ jni/Box2D/Dynamics/Contacts/b2ContactSolver.cpp:72: b2ContactSolver::b2ContactSolver(b2ContactSolverDef*): assertion "pointCount > 0" failed

A/libc﹕ Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 32158 (UpdateThread)

The body it's an airplane. If I use RUBE model I get this exception when I collide with multiple objects (the user has to catch some coins and diverge from enemies (RUBE models too)), instead, if I use a BoxBody everything works great.

Makes me wonder if it isn't related to non convex polygons witch compose the body (even though RUBE creates them correctly)... Happened to anyone?

Thanks.

EDIT: I forgot to say that I'm creating my bodies with RUBE but I'm not using the world created by RUBE when I was creating that body, so here's the code I use to create that body inside my world:

private Body createPolygonBody(PhysicsWorld pPhysicsWorld, IShape pShape, BodyDef.BodyType pBodyType, FixtureDef pFixtureDef, Jb2dJsonLoader jsonLoader, String fixtureName) {
        BodyDef boxBodyDef = new BodyDef();
        boxBodyDef.type = pBodyType;

        float[] sceneCenterCoordinates = pShape.getSceneCenterCoordinates();
        boxBodyDef.position.x = sceneCenterCoordinates[Constants.VERTEX_INDEX_X] / PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT;
        boxBodyDef.position.y = sceneCenterCoordinates[Constants.VERTEX_INDEX_Y] / PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT;

        Body rubeBody = jsonLoader.getBodyByName(fixtureName);
        Body boxBody = pPhysicsWorld.createBody(boxBodyDef);
        // boxBody.setTransform(rubeBody.getPosition(), rubeBody.getAngle());
        boxBody.setLinearVelocity(rubeBody.getLinearVelocity());
        boxBody.setLinearDamping(rubeBody.getLinearDamping());
        boxBody.setAngularVelocity(rubeBody.getAngularVelocity());
        boxBody.setAngularDamping(rubeBody.getAngularDamping());
        boxBody.setSleepingAllowed(rubeBody.isSleepingAllowed());
        boxBody.setAwake(rubeBody.isAwake());
        boxBody.setFixedRotation(rubeBody.isFixedRotation());
        boxBody.setBullet(rubeBody.isBullet());
        boxBody.setActive(rubeBody.isActive());
        boxBody.setMassData(rubeBody.getMassData());

        Fixture[] bodyFixtures = jsonLoader.getFixturesByName(fixtureName);
        for (int i = 0; i < bodyFixtures.length; i++) {
            FixtureDef fixtureDef = pFixtureDef;
            fixtureDef.shape = bodyFixtures[i].getShape();
            boxBody.createFixture(fixtureDef);
        }
        return boxBody;
    }

And maybe here lies the problem. Am I doing everything correct?

EDIT2: So I've replaced this code:

private void performCoinCollision(boolean coinIsBodyA, Contact contact) {
    if (coinIsBodyA) {
       contact.getFixtureA().setSensor(true);
    } else {
       contact.getFixtureB().setSensor(true);
    }
    contact.setEnabled(false);
    ...
}

with:

private void performCoinCollision(boolean coinIsBodyA, Contact contact) {
    if (coinIsBodyA) {
       elementsToBeRemoved.add(contact.getFixtureA().getBody());
    } else {
       elementsToBeRemoved.add(contact.getFixtureB().getBody());
    }
    contact.setEnabled(false);
...
}

and added this onUpdate to physicWorld:

@Override
public void onUpdate(float pSecondsElapsed) {
    if (elementsToBeRemoved != null) {
        for (Body body : elementsToBeRemoved) {
            if (body != null) {
                physicsWorld.destroyBody(body);
            }
        }
    }
    elementsToBeRemoved.clear();
}

The problem still persists.

Upvotes: 2

Views: 327

Answers (1)

GuilhE
GuilhE

Reputation: 11861

I've followed iforce2d advice, which is the correct procedure, and now it's working:

private void performCoinCollision(boolean coinIsBodyA, Contact contact) {
    if (coinIsBodyA) {
       elementsToBeRemoved.add(contact.getFixtureA());
    } else {
       elementsToBeRemoved.add(contact.getFixtureB());
    }
    contact.setEnabled(false);
...
}

...

@Override
public void onUpdate(float pSecondsElapsed) {
    if (elementsToBeRemoved != null) {
        for (Fixture fixture : elementsToBeRemoved) {
             fixture.setSensor(true);
        }
    }
    elementsToBeRemoved.clear();
}

Note: in my EDIT2 I'm doing the same approach but instead of setSensor(true) I'm trying to remove the body. That approach was failing too, don't know why.

EDIT: Problem was that I was trying to destroy an already destroyed body. The solution is to make sure that elementsToBeRemoved has no duplicated bodies

Upvotes: 1

Related Questions