2
votes

Box2d polygon box doesn't collide accurately. I use Box2ddebug renderer and reused Polygonshape several times. When boxshape is on a ground body (static) there is a gap between these bodies. Can anyone help me with this?

public class BoxShape extends Shape implements ShapeAccessor {

private DotShape a, b, c, d;
private Rectangle rect;
private Vector2 temp = new Vector2();
private float hw = 0, hh = 0;

public BoxShape(float x, float y, float u, float v) {
    a = new DotShape(x, y, this);
    b = new DotShape(u, y, this);
    c = new DotShape(u, v, this);
    d = new DotShape(x, v, this);
    hw = u - x;
    hh = y - v;
    rect = new Rectangle(d.getX(), d.getY(), hw, hh);
    rect.getCenter(temp);
    center = new DotShape(temp.x, temp.y, this);
    center.setColor(Color.MAGENTA);
    bodyDef.position.set(temp.x * Assets.ws, temp.y * Assets.ws);
    this.setColor(Color.BLUE);
}
@Override
public Body createBody(World world) {
    Body b = world.createBody(bodyDef);
    b.setUserData(new Data(getName()));
    return b;
}

@Override
public Fixture createFixture(Body body) {
    Assets.p.setAsBox(((rect.width / 2) * Assets.ws),
            ((rect.height / 2) * Assets.ws));//ws does scaling. world ranges from 0.1 to 20 meter
    fixtureDef.shape = Assets.p;
    return body.createFixture(fixtureDef);
}
      ........................
      ........................

Then the bodies and fixture are made by:

public void createWorld(World world) {
    for (Shape s : shapes) {
        Body b=s.createBody(world);
        s.createFixture(b);
    }
    for (JointShape j : joints) {
        j.createJoint(world);
    }
}
1
I know nothing about the library, but my suspicion is that you'll need to provide code to have any chance of getting an answer.Jonathan Leffler

1 Answers

2
votes

Are your shapes very very small? You may need to scale your world so that common shapes are around 1 unit in size.

When fixtures overlap they are pushed apart so that they don't overlap, but many cases (particularly with stacked objects) make it difficult to keep this situation stable. The box on top moves down due to gravity and touches the box underneath, then gets pushed back up, and so on, forever. Apart from looking terrible from all the jittering around, this will never stabilize and wastes computing time since the bodies will never be able to sleep.

To address this problem there is a tiny space around fixtures which is used as a buffer, in which two adjacent fixtures can agree that they are touching, but there is no overlap so no correction needs to be made - they can smile at each other and relax. The size of this buffer is a value in b2Settings, and while you can change it (b2_linearSlop) you should really know what you are doing before you do. (Remember this is a #define constant used thoughout Box2D so you'll need to recompile the library itself to make the change take effect fully.) I would recommend scaling your world to use larger sizes instead.

http://www.iforce2d.net/b2dtut/gotchas#smallgap