Minecraft style terrain performance is suffering...

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
team23
Posts: 4
Joined: Sun Feb 26, 2012 7:42 am

Minecraft style terrain performance is suffering...

Post by team23 »

So I'm working on a minecraft style game using BEPU physics. All was well when I was the only thing roaming aroud my terrain, but I've started adding enemies and its going downhill quickly. Before I went off and randomly tried stuff to improve performance I figured I'd ask here.

Roughly what I'm doing:
Player/enemy is a capsule
Each player/enemy has an array of Boxes (Total 36 boxes, 3 wide, 3 deep, 4 high) that it uses to represent the terrain in the physics engine (Rather than load all of the terrain into the engine and then regen when modified)
Each frame we move boxes as needed to surround the capsule with the terrain. If a box is not needed (No block at its location) I move it out of the way (As an easy way to avoid collisions).

Questions:
Would using collision groups to link the capsule to only its terrain blocks for collision improve performance? Basically I don't want a terrain block to ever collide with another terrain block or another player/enemy.
Would loading the terrain into the engine be better than doing this conveyor belt style system?
Are there other things I could do in this type of enviroment to improve perf?

Any help would be appreciated.
team23
Posts: 4
Joined: Sun Feb 26, 2012 7:42 am

Re: Minecraft style terrain performance is suffering...

Post by team23 »

Ok, so it looks like at least a significant part of the problem was my hack for moving unused blocks away. I've replaced that with Add/Removing from the space and thats sped things up considerably. Still wondering if the CollisionGroups could help performance more...
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Minecraft style terrain performance is suffering...

Post by Norbo »

Would using collision groups to link the capsule to only its terrain blocks for collision improve performance? Basically I don't want a terrain block to ever collide with another terrain block or another player/enemy.
It would only help a little when you walked on or near another character's blocks. If there's no collision rule, you'll have a few extraneous collisions which don't meaningfully change the simulation. However, because collision rules work on the leaf level, it doesn't stop costs associated with acceleration structure traversal.
Ok, so it looks like at least a significant part of the problem was my hack for moving unused blocks away. I've replaced that with Add/Removing from the space and thats sped things up considerably. Still wondering if the CollisionGroups could help performance more...
Given this, it sounds like there were a lot of objects in the broad phase, possibly all overlapping. Even if they didn't produce contact by virtue of all being kinematic (which gets pruned by the default configuration of collision rules), the broad phase still has to look at each overlapping pair. 10 overlapping boxes have 55 overlapping pairs, 20 overlapping boxes have 210 overlapping pairs, 30 overlapping boxes have 465 overlapping pairs, and so on.

Even if they aren't all overlapping, a bunch of individual boxes will pollute the broad phase. So,
Would loading the terrain into the engine be better than doing this conveyor belt style system?
Yes and no. If it were implemented as a bunch of individual boxes, it would be far worse. There would likely be many thousands of completely unused boxes bogging down the broad phase.

However, there are ways of making it work. It's possible to use meshes or compound bodies to represent chunks of terrain. Chunks are necessary as meshes and compounds aren't designed to be modified constantly and so modification is a bit slow.

A much more elegant and computationally fast approach is to create a custom collidable. Examples of Collidables include the Terrain, StaticMesh, and InstancedMesh (among other things like the entity collidables). However, instead of using triangles as primitives, you can use BoxShapes. Chances are, the terrain has some extremely regular geometry (e.g. a 3d grid) which allows you to use implicit acceleration structures to speed up queries to find the boxes that could possibly collide with any other object. Once the queries locate the relevant box shapes, you can use existing systems to create contact points. Since the acceleration structure is implicit, there is practically no modification cost. I believe a couple of blockworldy games that use BEPUphysics do this.

There is a downside, of course- to implement the custom collidable requires a good bit of development effort. My last post in this thread describes the process in more detail: viewtopic.php?f=4&t=1383&p=8311
team23
Posts: 4
Joined: Sun Feb 26, 2012 7:42 am

Re: Minecraft style terrain performance is suffering...

Post by team23 »

Ahh, so they weren't overlapping per se, but they were "sharing" faces (1.0 width on a 1.0 grid). By making the cubes slightly smaller I got another bump of speed!

I'll take a look at that thread and see if going down that path makes sense for my project.

Thanks!
team23
Posts: 4
Joined: Sun Feb 26, 2012 7:42 am

Re: Minecraft style terrain performance is suffering...

Post by team23 »

Actually one more question.

Would having one space per chunk be better than including everything in one massive space? Granted the cost of coding some kind of handoff between them.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Minecraft style terrain performance is suffering...

Post by Norbo »

Multiple spaces is less efficient usually, since every space update has a little overhead. Multithreading in particular will suffer. If objects need to switch from space to space, things will get iffy- the transition isn't an easy/robust operation (e.g. something is in the way). If there are simulations which truly cannot interact in any way, it's a good option.
Post Reply