This is a continuation of my previous question, asking about edge shapes, located here:
http://box2d.org/forum/viewtopic.php?f=9&t=7254However, I'm going to summarize it for clarity's sake.
I'm working on a tile based game, and I'm using Box2D for the physics implementation. The most recent version of my code splits areas of the world into chunks and traces out the edges of solid tiles using a Marching Squares algorithm. My algorithm then returns a set of paths around the chunk, which I feed into box2d. Right now, I'm using a series of two vertex edge shapes, as recommended by toucansam. These perform quite admirably, and as long as I unload old chunks, I experience basically no drop in framerate during gameplay. However, when I load new chunks, the shapes must be recreated, and this takes a long time, causing noticeable lag spikes when the player crosses a load boundary. I've narrowed this down to the Body.createFixture() function. I don't mean to draw blame away from my own code, but the createFixture() function takes 9 times longer than the MarchingSquares algorithm to execute a full trace, so that's where I'm starting.
Going deeper into the profiler results, the most intensive parts of the code are:
+ Body.createFixture()
+-- Fixture.createProxy()
+---- BroadPhase.createProxy()
+------ DynamicTree.createProxy()
+-------- DynamicTree.computeHeight()
+---------- DynamicTree.computeHeight()
+------------ (This recursion continues for some time, ending on the same function, with the percentage of function time taken not dwindling significantly until about half-way down.)
I'm using the following code (with some modifications for clarity of the example) to convert the MS path to physics data. The important part of the code is marked near the bottom. (The first few lines are just iterator stuff.)
Code:
Contour[] contours = solver.findAllContours(); //get all the contours for the chunk.
Body bodyRef = world.createChunkBody(); //create a body to attach fixtures to.
//for each contour...
for (int i = 0; i < contours.length; i++) {
IntPoint[] path = contours[i].path; //each contour contains a path, which is a list of points
//for each element of the path..
for (int j = 0; j < path.length; j++) {
if (path.length < 4) ; //short path check here.
IPoint p0 = path[j]; //grab first point
IPoint p1 = path[(j+1)%path.length]; //grab second point, wrapping over if needed
//figure out the fixture and other properties to use for the body
FixtureDef fixDef = getWorldFixtureDef();
// ***** Where the shape is created. Ideally, this would be replaced with edge shapes, but they're unavailable. *****
PolygonShape poly = new PolygonShape(); //create a shape
shape.setAsEdge(new Vec2(p0.x, p0.y), new Vec2(p1.x, p1.y)); //set up the shape
fixDef.shape = poly; //attach shape to polydef
// ***** This is where my bottleneck lies. This operation takes forever. *****
bodyRef.createFixture(fixDef);
}
}
So I have the following questions: Is there some way I can optimize creating the fixtures? Am I using createFixtures() wrong? It feels to me like this isn't really the right way to be doing things. I feel like there should be some way to create all the shapes, then build all the fixtures at once.