3
votes

I'm making a game in which the floor is a randomly generated non-convex polygon.

The vertices of the polygon are passed to the following (pseudocode) method:

private void createPolygon (FloatArray vertices) {
        short[] triangleIndices = new EarClippingTriangulator()
                                            .computeTriangles(vertices)
                                                .items;
        myPolygon = new PolygonSprite(
                            new PolygonRegion(textureRegion, vertices.items, triangleIndices));
        //  myPolygon is correctly rendered
        //  now I want to create a Box2D static body with this shape
        PolygonShape myShape = new PolygonShape();
        Array<Vector2> vect = toVector2Array(vertices);
        for (int i = 0; i < triangleIndices.length / 3; i++) {
            // Error!
            myShape.set(new float[] {
                    vect.get(triangleIndices[3 * i + 0]).x,
                    vect.get(triangleIndices[3 * i + 0]).y,
                    vect.get(triangleIndices[3 * i + 1]).x,
                    vect.get(triangleIndices[3 * i + 1]).y,
                    vect.get(triangleIndices[3 * i + 2]).x,
                    vect.get(triangleIndices[3 * i + 2]).y });
            myBody.createFixture(myShape, 0);
        }
        
    }

Usually the method works well, but sometimes the game crashes:

AL lib: (EE) alc_cleanup: 1 device not closed
Assertion failed!
Program: C:\Program Files\Java\jre1.8.0_25\bin\javaw.exe
File: /var/lib/jenkins/workspace/libgdx/extensions/gdx-box2d/gdx-box2d/jni/Box2D/Collision/Shapes/b2PolygonShape.cpp, Line 158
or 223

Expression: false

or

Expression: area > 1.19209289550781250000e-7F

The float [] passed to "myShape.set ()" contains (when it crashes):

- x1: -1061.4121;
- y1: -2178.179;
- x2: 888.95154;
- y2: -154.1218;
- x3: 888.98663;
- y3: -154.08865;

If I understand correctly, this is because the triangle is too small. What can I do to avoid this problem, or to leave out these small triangles? Thanks in advance

2
You have to disallow creating tiny polygons. The area can be determined with trigonometry (or look in the box2d sources). The problem isn't just too small triangles but ones with tiny areas, for instance if you have these three points that would make a triangle with a tiny area: 0,0 - 400,0.1 - 800,0 (almost a line segment)LearnCocos2D

2 Answers

3
votes

Point #2 and #3 are really close, maybe this is what the library did not like.

Perhaps, you can improve your random point generator to avoid two points to be too close.

0
votes

A crude but effective way to get around this is just use the same check that Box2D does to trigger that assert. Look at the code inside the function in b2PolygonShape.cpp that decides whether to trigger this assert. Copy (or port) that code into your own program so you can pre-emptively check if the assert would trigger. If it will trigger, don't create that fixture :)