Download source code for this post: PhysicsChunks.zip (190k)
Try out the example app: http://www.kindohm.com/sl/physicschunks/testpage.html
During development of the Turrets game, I've spent time optimizing the time it takes to load a "map". A map is simply the terrain that defines the playing boundaries for turrets, projectiles, or any other physical object in the game. I've found that large geometries, particularly ones that are concave shaped, take a lot of time to load.
My terrain geometry is relatively large and is built to fit a base screen size of 3000 x 2000 pixels. All of this is scaled down depending on the user's screen size, but the large base size is nice because it prevents me from having to use decimal values to get the granular geometry that I want. However, the large base size does increase the complexity of the physics geometries and the computation required for collisions.
In addition, my terrain has cliffs, walls, and other shapes that create concave shapes. An easy way to imagine this is a slab of ground with a bounding wall on the left and a bounding wall on the right. You now have a big, U-shaped, concave bowl.
Here's an example of one map that has a cliff overhang and wall that create a concave, sideways "U" with the ground:
A simple U-Shaped bowl that fits in a 3000x2000 screen takes forever to load by the Farseer engine (using the default collision grid size). This has to do with collision detection computations that happen when geometries are created. In my estimation, the large concave shapes take longer to compute because the center of gravity lies outside of the physical geometry, but that's just a guess. The collision grid for an object has to be small enough to be realistic. You can increase the collision grid size in Farseer to make your objects get built faster, but then you run the risk of collisions being less realistic. In order for my collisions to be realistic enough to satisfy my needs, I needed a small enough collision grid that was causing my terrains to take a terribly long time to load. You can read all of the details of collision grids in the Farseer documentation.
One way to address this long load time is to break down a large geometry into multiple smaller geometries. In the above screen shot, you could potentially break down the terrain into 1) the ground, 2) the right wall and 3) the cliff overhang.
I decided to test this out (unscientifically) in a simple example. I created a Silverlight app to host a Farseer Physics environment and created two "maps" that both defined the exact same shape: a large, U-shaped bowl. The first map used a single Farseer geometry to define all points of the container, and the second map broke it down into three chunks:
For those of you who have used Farseer and are paying attention, I used a collision grid size of .5 in my app for both maps.
In the app, you can choose to load either the single path map or the multi-chunk map. With one test run, here were my results:
- Single Path, Large Geometry: 59.791 seconds to load
- Multiple Chunk Geometry: 7.307 seconds to load
You can try out the app here: http://www.kindohm.com/sl/physicschunks/testpage.html
It's remarkable how much faster multiple, smaller chunks load than the single large geometry.
Again, I'm only speculating that the concave shape also has something to do with the slowness. I haven't come up with a good test that could determine if it doesn't have an effect on the load time.
In summary, try using multiple geometries to break down a larger one if your Farseer geometries are taking a long time to load.