Sign in to follow this  
jmakitalo

Advanced heightfields in Bullet physics

Recommended Posts

At the moment I'm using Bullet for physics and collision detection with a basic heightfield terrain. The heightmap is 2048*2048 and so cannot yield very high resolution for my roughly 8 km x 8 km terrain.

 

I'm using a vertex shader for some portions of the terrain, which locally masks another heightmap, which is repeated 100 times, over the terrain. The heightmaps and mask are read in vertex shader to displace the terrain grid. The grid itself can be quite dense, so that the additional information from the masked heightmap is visibly utilized. This way I can achieve nice bumpy appearance for, e.g., forests and fields.

 

The problem is communicating this masked heightfield to the physics part of the game. My quick hack was to make a higher resolution map, say 4096x4096, where the two heightmaps are combined, and pass it to the Bullet physics. Of course this has still insufficient resolution in some cases and it wastes memory.

 

I started wondering if it would be easy to modify Bullet's btHeightfieldTerrainShape.cpp module to allow for such additional masked heightmap. A quick look gave me the idea that Bullet just samples the given heightmap on demand and doesn't do any costly pre-processing or caching. This suggests that I could add my masked heightmap easily by modifying getRawHeightFieldValue function and storing the other heightmap and mask in btHeightfieldTerrainShape. Can anyone confirm this?

 

Another related topic is that in the future, I may want to divide my terrain into, say 1 km x 1 km blocks that have their own heightmaps. The heightmaps would then be stored at varying resolutions and streamed from the disk. I would need to be able to update the Bullet heightfield quickly after a stream is complete and this requires that Bullet does not do any heavy processing on heightfield updates. Has anyone experience with anything similar?

 

Thank you in advance.

Share this post


Link to post
Share on other sites

The Bullet HeightField is a pretty very simple collision object really/ It's usually added as a static object, and it's bounding box doesn't change through simulationSteps so there shouldn't be any performance issues from the bullet library as such.  As you saw all that bullet really does is call back to the HeightMap for processTriangles and getRawHeightFieldValue., if then does a normal Triangle v CollisionShape test for each of the Triangles that the HeightMap gives it. Obvioulsy the finer the resolution in a given area the more triangles it would provide, and the performance hit would be larger.

 

You could fairly simply modify the body of the class, or create your own version of HeightMap that uses masks or whatever. If the AABB of the heightfield doesn't change, you could even do something like lodding with the underlying data for 'far away' sections of your terrian.

I created a version in my xna port of bullet that allowed me to get averaged height values for a given point, and also to modify the underlying data to provide deformable terrain and it all just sat happily in the normal Bullet libraries 

Share this post


Link to post
Share on other sites

The Bullet HeightField is a pretty very simple collision object really/ It's usually added as a static object, and it's bounding box doesn't change through simulationSteps so there shouldn't be any performance issues from the bullet library as such.  As you saw all that bullet really does is call back to the HeightMap for processTriangles and getRawHeightFieldValue., if then does a normal Triangle v CollisionShape test for each of the Triangles that the HeightMap gives it. Obvioulsy the finer the resolution in a given area the more triangles it would provide, and the performance hit would be larger.

 

You could fairly simply modify the body of the class, or create your own version of HeightMap that uses masks or whatever. If the AABB of the heightfield doesn't change, you could even do something like lodding with the underlying data for 'far away' sections of your terrian.

I created a version in my xna port of bullet that allowed me to get averaged height values for a given point, and also to modify the underlying data to provide deformable terrain and it all just sat happily in the normal Bullet libraries 

Thanks for the input.

 

Regarding the masking of repeating heightmap, I realized that the input of getRawHeightFieldValue is some sort of quantized index, which is bound to the resolution of the given main heightmap. I would have to somehow locally refine this sampling for the masked areas and this would probably be difficult. I guess this masking is the kind of effect that is easily done on the graphics side, but pretty inconvenient for physics.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this