Mapping Box2D shapes from textures

Pretty soon after getting started with Box2D and having a ball bouncing on the screen the novelty wears off, playing with circles and boxes is not much fun. I wanted more complex shapes and it turns out that creating polygons by hand is boring and error prone and so is approximating a shape from primitives. I needed something that would trace an image and create a  polygon out of it, at run-time if possible. This lead to searching the internets high and low but I could not find anything other that other people asking for the same thing I was looking for.

Eventually I found a piece of code from the Farseer project (a 2d physics engine written in C#) that did exactly what I needed except, well, it was written in C#. The code was contributed by a user going by the alias Sickbattery, he is not listed as a project developer and there is nothing else about him but he deserves the credit for the original C# code.

An hour later I finished translating the C# source to Java, the code is not pretty and exhibits a bit of foreign language accent but it works  pretty well. I will not list the code here, scroll to the end of the article to download it.

There are few static functions that can be called, all of them returning a list of Vec2 vertices almost ready to be used to create Box2D polygons. Another hour and a hard to find post on the Box2D forums later and I finally got the thing working, here are the relevant bits of code.

ImageSprite shape = new ImageSprite("Shape.png", 0, 0);
//get the list of vertices approximating the image
List verts = TextureConverter.createPolygon(shape.getImage().getData(), shape.width.getAsInt(),
shape.height.getAsInt());
//scale the vertices to the world's scale
for (Vec2 v : verts) {
v.mulLocal(1 / scale);
}
//create a polygon from all these vertices
Polygon poly = new Polygon(verts.toArray(new Vec2[] {}));
Polygon tracedPoly = Polygon.traceEdge(poly);
BodyDef bd = new BodyDef();
bd.position.set(x, y);
Body body = world.createBody(bd);
//create a prototype polygon definition that will be used for the characteristics of all shapes
PolygonDef proto = new PolygonDef();
proto.friction = 0.2f;
proto.restitution = 0.8f;
proto.density = 2f;
//decompose the polygon in convex pieces and add them to the body
Polygon.decomposeConvexAndAddTo(tracedPoly, body, proto);
body.setMassFromShapes();

The sample uses the JBox2dD debug drawing classes from a previous post, so you can see the shapes that were generated. Press ‘D’ to toggle debug drawing, press ‘R’ to restart, click to add another shape.

Download the source code, PulpCore and JBox2D not included.

One thought on “Mapping Box2D shapes from textures

  1. GooniSpoon

    thx for your code! in fact i have been working on a hobby project in xna lately and as the game is for tablets, i decided to switch to android 1 week ago (when it came clear that xna was ‘discontinued’ – at least for win 8 tablets).
    as far as my prototype port is concerned, you provided exactly the code i needed: parsing gleed2d levels and porting the farseer shape generation.
    a ton of thx for this! keep it up!!

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>