Performance problems with StaticMesh

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
martin
Posts: 11
Joined: Fri Jan 13, 2012 3:30 pm
Location: Worcester, UK
Contact:

Performance problems with StaticMesh

Post by martin »

Hi.

I'm building a game which has really large procedurally generated environments. At the moment, I'm generating the world in 16m3 cubes and then streaming the geometry of the cube into the graphics engine and the physics engine. So whenever one of these cubes is updated, I do this:

Code: Select all

public override void MeshUpdated(StaticMesh mesh)
{
    //Remove the old version of this mesh
    if (PhysicsMesh != null)
        physics.Remove(PhysicsMesh);

    //Add the new updated mesh to the engine
    PhysicsMesh = mesh;
    physics.Add(PhysicsMesh);
}
I assumed that large numbers of static meshes wouldn't be a problem for the physics engine, but as the world grows I start getting pretty bad performance problems. When geometry is streaming (and the method above is being run) I'm seeing update steps taking 20-30ms, even once streaming is done and it's just a static level with a single FPS character running around I'm seeing Space.Update take a fairly steady ~13ms

Image

I profiled the game loading in a 1Km2 city block, which is ~25000 StaticMesh objects, and got these results:

Image

As you can See, for some reason the Broadphase is taking up a huge amount of time, even once the level has finished loading at no more StaticMesh objects are being created!

Any suggestions for how I can improve performance here?

Thanks :)
martindevans.appspot.com/blog
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Performance problems with StaticMesh

Post by Norbo »

It sounds like there's a pretty massive number of StaticMeshes in the simulation.

Removal of objects from some systems can take linear time. If there's many thousands of objects and multiple removes happening each frame, that will balloon the cost.
As you can See, for some reason the Broadphase is taking up a huge amount of time, even once the level has finished loading at no more StaticMesh objects are being created!
The BroadPhase is a unified, dynamic, general purpose acceleration structure. When there's thousands of BroadPhaseEntry objects in the BroadPhase, the acceleration structure is pretty big. As the BroadPhase has no guarantees about what each object is, it must traverse the structure to find overlaps even if those overlaps turn out to be between two static objects which cannot generate a collision pair with each other.
Any suggestions for how I can improve performance here?
Try to avoid this broad phase pollution. There can be hundreds of thousands of triangles in a StaticMesh, but the BroadPhase only sees a single StaticMesh. The StaticMesh's internal acceleration structure can make assumptions about its contents. For example, the triangles can never collide with each other, so there is no need to perform 'internal' tests. Similarly, a special structure could be created which contains the data which is now stored across thousands of StaticMeshes.

The best approach to reduce broad phase pollution depends on the simulation.

Blockworld games typically benefit hugely from a custom 'voxel grid' collidable which can perform collision based directly on its 3D grid of cubes. The grid provides an implicit data structure that makes modifications possible in constant time and offers a very speedy query to identify which cubes are involved in a collision pair.

For a game with less guarantees about regular geometry, it might be good to create what amounts to an intermediate acceleration structure between the broad phase and static meshes. Some kind of simple hash grid would do the trick if modifications are common (and especially if the geometry is aligned to a grid at any level).

The more assumptions you can build into the structure, the better.

Implementing such a custom structure would amount to creating a new child of the Collidable class, alongside Terrain, StaticMesh, and InstancedMesh. This class would contain the acceleration structures and query support needed to check for colliding geometry and raycasts. Then, create CollidablePairHandler types which handle the collision between the collidable and other objects. Give those pair handler types to the NarrowPhaseHelper.

A more in-depth description of this process can be found in my last post on this thread about a blockworld game:
viewtopic.php?f=4&t=1383

If a "Group of actual StaticMeshes" collidable was used, it will probably end up creating subpairs. The GroupPairHandler (inherited by compound-related pairs) and related classes shows an example of creating subpairs using the NarrowPhaseHelper.
martin
Posts: 11
Joined: Fri Jan 13, 2012 3:30 pm
Location: Worcester, UK
Contact:

Re: Performance problems with StaticMesh

Post by martin »

Thanks for the fast reply Norbo.

I thought that this was probably the case. The game isn't a blockworld game, and has no particular guarantees about the placement of geometry (all the world geometry is created by constructive solid geometry). I'll have a look at how these classes work internally and see what I can do, thanks :)
martindevans.appspot.com/blog
Fe_Yoshi
Posts: 397
Joined: Tue Jul 04, 2006 5:05 pm
Location: New Tower!

Re: Performance problems with StaticMesh

Post by Fe_Yoshi »

I had replied faster, but Norbo [Totally Didn't] delete [Or Edit] my post like a big JEEEEERKKKKK!!
It's simple, just take the hydraulic phase ship emulator and attach it to the photon particle emitter, BAM, new tower!
Post Reply