Bepu and complex dynamicaly generated terrain.

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
s33m3
Posts: 3
Joined: Wed Sep 28, 2011 9:50 am

Bepu and complex dynamicaly generated terrain.

Post by s33m3 »

Hello,

Just some question on the possibility to use Bepu with our game.

Right now, we generate a "voxel" terrain landscape (aka minecraft like) on demand (when player move, the terrain is procedurally generated).
This terrain, can, and will be able to by modified. Knowing that you could have entities living everywhere on this terrain.
A rendering terrain area (surrending player zone) is composed of an average of 2000000 triangles that are composing the visible part of the terrain only.
Do you think BEPU engine could be use to manage Entities vs Terrain physic interaction ?

Terrain could be composed of cave, convex form, concave form, ... all sort of things.

I see that all object composing the simulation must be inside a Space objects container. How could we passed in our terrain ? (Knowing that it could be modified with high frenquency) ?

Tx you for answer ! :)

s33m3
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Bepu and complex dynamicaly generated terrain.

Post by Norbo »

Off the top of my head, there's two primary ways in which this could be approached.
1) Create a mesh-based representation of the terrain and use StaticMesh(es).
2) Create Boxes representing the terrain.

If using mesh-based terrain:
-A single gigantic StaticMesh would have prohibitively long reconstruction times when it changes. Segmenting the world into physics chunks (which you probably already do in some way) and creating the meshes for each independently would be much faster. Be sure to only include the surface triangles in the mesh.
-Depending on the target platform and other performance considerations, you may need to have a smaller physics simulation radius than render radius.
-While you won't be adding and removing very many static meshes compared to the number of blocks you'd manage in the other approach, you may still need to buffer static mesh creation/removal when the character is walking around in new areas to avoid framerate jerks.
-StaticMesh reconstruction generates garbage when building a new hierarchy which must be done if the mesh topology changes. If you're on a platform where GC pressure is extremely important, you'll have to manage this somehow.

If using actual blocks:
-The physical terrain will need to be the surface blocks alone. The broadphase weight of many thousands of unnecessary boxes would be noticeable.
-Depending on the target platform and other performance considerations, you may need to have a smaller physics simulation radius than render radius.
-Adding objects to the Space is very quick. Removing objects from the space is still pretty quick, but slower than additions. It'll probably be a good idea to buffer removals over multiple frames if you end up having to instantly remove hundreds of objects.
-You could create a custom 'BoxGroup' collidable which batches together a bunch of boxes in an efficient representation for collision and addition/removal. This would require deeper familiarity with the engine and collision detection in general.
-Pooling and re-using the entities will be needed to avoid piling up garbage.
Do you think BEPU engine could be use to manage Entities vs Terrain physic interaction ?
So yes, minecrafty terrain can definitely be done. I know that at least one other box-voxel game has used BEPUphysics.
Terrain could be composed of cave, convex form, concave form, ... all sort of things.
Does this imply that the terrain is not actually cube-voxels, but rather tessellated with marching cubes or something similar? That would complicate things, though the mesh-based method with chunks could still work. If you just mean that the cube voxels form a variety of terrains, then that's no problem.
s33m3
Posts: 3
Joined: Wed Sep 28, 2011 9:50 am

Re: Bepu and complex dynamicaly generated terrain.

Post by s33m3 »

Tx you for the answer.

We have internaly already a really fast way to travel the array. I can easily do Collision testing against the visible landscape.
In fact our landscape on client is stored inside a single big "3D Array".
From a world point (Vector3), I can easily find if its inside a block or not. (With function like : GetBlockAt(X,Y,Z), that is returning the Material of the block at this location).
Thats really fast (in fact I only need to compute the array index of the big 3d array).

Testing collision directly against our virtual representation of the terrain, could be a nice trick, and really fast one.

What interface a mesh require to be able to be used inside a Space container ?

I see :
- public override bool RayCast(...)
- public override bool ConvexCast(...)
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Bepu and complex dynamicaly generated terrain.

Post by Norbo »

The StaticMesh provides an example of what would be needed. It inherits Collidable and implements ISpaceObject.

The harder part is building the collision pair handlers. The pair handlers govern the interaction between two collidables. You can see the full list in the BEPUphysics.NarrowPhaseSystems.Pairs namespace. The StaticMeshPairHandler and other existing pairs will help guide a custom pair's development.

Let's start with the StandardPairHandler first. It requires two fundamental things- a contact manifold and a constraint. The contact manifold manages and updates the contacts between two objects. The constraint manages the solver representation of those contacts to support rigid collisions.

Fortunately, there's a lot of collision tests built in, so you don't have to do the hard part. If everything is boxes, it would be a good idea to look at the BoxContactManifold and the BoxBoxCollider. The BoxBoxCollider is a static class which generates contacts from two box shapes. The BoxContactManifold uses those contacts to update its existing contacts. You'll notice that it has persistent contacts rather than replacing everything every frame; this helps with solver stability and some overhead.

You'll have a few options at this point. You could make your own version of the BoxContactManifold which works between the environment voxels and another box and blends contacts together using one of the built in contact reducers, or you can take the (probably easier, possibly better) route of initializing a BoxContactManifold for every active pair. This allows you to re-use as much code as possible.

If you do go down the route of initializing and maintaining a bunch of persistent BoxContactManifolds, the StandardPairHandler no longer fits very well. It's designed for pairs which have a single contact manifold, like convex-convex types and mesh-convex, where the mesh has many contact testers, but only one manifold which combines and reduces the contacts. With multiple manifolds, you could either make a custom 'group manifold' and continue using the StandardPairHandler, or you could make it a 'group pair handler' designed to support multiple manifolds.

The existing GroupPairHandler and MeshGroupPairHandler show examples of how to approach this. They both collect and maintain child CollidablePairHandlers. You could go this route, but it was designed that way to provide a common base for multiple collision types. In your case, it may be best to make a custom version which maintains your bunch of ContactManifolds instead of whole CollidablePairHandlers. The overall design of the GroupPairHandler could still be used, though.

For your constraint, since you could easily end up with more than 4 contacts, you'll probably end up making a ConvexContactManifoldConstraint for each manifold and put them all into a single ContactManifoldConstraintGroup. This is similar to what the GroupPairHandler does.

It's a good idea to try to minimize the number of pair handlers you have to create. For example, if all your objects (environment and everything else) are boxes, you could make a single pair handler for box vs. environment. If there's non-box shapes, you might have to implement a second pair handler for convex vs. environment. As you might guess, it would be quite a pain to go through and have full support for every single shape type. Even though a single pair handler can theoretically cover multiple pair types (like the convex-environment mentioned above), there's just so many different acceleration structures in play for the more complex nonconvex shapes (like mobile meshes) that it would be tedious.

So, to summarize the approaches to making a pair handler for your environment:
1) Use a StandardPairHandler and make a custom group ContactManifold which holds multiple other child ContactManifolds. Use a ContactManifoldConstraintGroup which holds the child ConvexContactManifoldConstraints.
2) Make a fully custom "group" pair handler which manages multiple contact manifolds directly without the need for a contact manifold group. Would still probably use the ContactManifoldConstraintGroup.
3) Make a group pair handler very similar to the existing GroupPairHandler or MeshGroupPairHandler that manages multiple child pair handlers, each with their own way of handling the involved collidables. Your group pair handler would once again use a ContactManifoldConstraintGroup to bundle up every child's contact constraint.
4) Make a contact manifold which uses BoxBoxCollider queries to collect contacts and then uses a built-in contact reducer to bring it down to 4 total contacts. The contact constraint could then just be a NonConvexContactManifoldConstraint. For robustness, you'd want to update old contacts instead of replacing them whenever possible (via matching contact ids+source pairs or just nearby position and similar normals).

Finally, you'll also need to tell the engine to use your pair handler. The engine keeps track of a list of type pairs and their associated pair handler type. You can add/remove pair handlers by doing this:

Code: Select all

NarrowPhaseHelper.CollisionManagers.Add(new TypePair(typeof(Class1), typeof(Class2)), new NarrowPhasePairFactory<YourPairHandler>());
Since most of the existing classes rely on either Collidable or CollisionShape instances, pooling and re-using them will be important to avoid garbage collection. The number of collision pairs will be extremely small relative to the number of blocks in the terrain in any reasonable situation, so memory usage will still be pretty light.
s33m3
Posts: 3
Joined: Wed Sep 28, 2011 9:50 am

Re: Bepu and complex dynamicaly generated terrain.

Post by s33m3 »

Tx you very much for you answer.
Post Reply