Best way to handle physics for voxel based terrain?
Posted: Fri Jul 10, 2015 4:53 am
Hi,
It's me again (I asked a question a few days ago about the ModelDrawer). You were so helpful with my other question I thought I'd bother you again
So a recap, my friend and I are writing a voxel based game like minecraft much much more so like an RPG. We have decided that most terrain will not be changeable though, just the area a users "home" is and "Cave instances"
Here is what I tried so far:
Had a one layer thick 40x40 square of cubes, even have a nice texture loaded on all of them. Used the fantastic BEPU CharacterController for movement and collision handling, wrote a basic nice camera and all of the cubes for the floor were kinematic entities of the Box type in the prefabEntites namespace. this worked fine for 40x40=1600 cubes. However I noticed that up scaling to 80x80=6400 started to lag seriously bad.
Second I re looked over all of the tutorials to see if i could find a better way since they all had lots of objects with collision and rendered just fine. I thought my problem might be because even though the boxes are kinematic since they are all touching if I step on one it has to do collisions for all of them. I also figured when looking at the code in Space.Add() that the Box prefab implemented way more functionality then I needed for terrain, since all I really need is collision detection so the entities don't fall though. I saw the collision filtering demo and thought about setting it up so none of the boxes did Broad Phase collision with any other terrain boxes but after looking at the code implementation this seemed unfeasible since every box would have to have a collision rule pair for every other box, or maybe just the ones directly next to it? But still this didn't solve the issue of each call to Space.Update doing way more things then it needed to for an entity that never moves and basically is just a floor. I'm not sure which if any of my assumptions were correct but either way it seemed like the prefab box was the wrong way to go.
Then I saw the tutorial for Compound entities and I was inspired. basically I could just create all of my grass blocks and for each one create a corresponding CompoundShapeEntry and the create a parent CompoundShape. This worked fairly well but I immediately noticed that the children collection seems to be immutable. So for the areas that users can place and remove blocks Id need to either not use CompoundShapes at all or destroy and recreate the parent compound with every change, which sounds expensive.
I know almost nothing about static meshes but the use of the word static makes it sound like it is optimized for this type of purpose. and then I would use that for the non changing areas and a different solution for the areas that can be changed.
I figured that it had gotten to the point where I should probably ask you how you would handle each situation if you were the one writing this application. In code all of my blocks are in a large array currently and then my blocks basically inherit from the base physics types I need, not sure if that's correct either or if I should just instantiate the type and keep it as a property. To summarize I basically have a static terrain built out of boxes that could some time later become a dynamic terrain but not often and then some randomly generated caves that are built completely out of boxes that can be added and removed. So should I be using the prefab Box, the BoxShape in a CompoundShape, a StaticMesh, or is there some other even better way? especially if all of the default terrain will be pre-designed by me before the launch of the game.
Sorry I got so verbose, and again thanks for any help and for the great engine!
It's me again (I asked a question a few days ago about the ModelDrawer). You were so helpful with my other question I thought I'd bother you again
So a recap, my friend and I are writing a voxel based game like minecraft much much more so like an RPG. We have decided that most terrain will not be changeable though, just the area a users "home" is and "Cave instances"
Here is what I tried so far:
Had a one layer thick 40x40 square of cubes, even have a nice texture loaded on all of them. Used the fantastic BEPU CharacterController for movement and collision handling, wrote a basic nice camera and all of the cubes for the floor were kinematic entities of the Box type in the prefabEntites namespace. this worked fine for 40x40=1600 cubes. However I noticed that up scaling to 80x80=6400 started to lag seriously bad.
Second I re looked over all of the tutorials to see if i could find a better way since they all had lots of objects with collision and rendered just fine. I thought my problem might be because even though the boxes are kinematic since they are all touching if I step on one it has to do collisions for all of them. I also figured when looking at the code in Space.Add() that the Box prefab implemented way more functionality then I needed for terrain, since all I really need is collision detection so the entities don't fall though. I saw the collision filtering demo and thought about setting it up so none of the boxes did Broad Phase collision with any other terrain boxes but after looking at the code implementation this seemed unfeasible since every box would have to have a collision rule pair for every other box, or maybe just the ones directly next to it? But still this didn't solve the issue of each call to Space.Update doing way more things then it needed to for an entity that never moves and basically is just a floor. I'm not sure which if any of my assumptions were correct but either way it seemed like the prefab box was the wrong way to go.
Then I saw the tutorial for Compound entities and I was inspired. basically I could just create all of my grass blocks and for each one create a corresponding CompoundShapeEntry and the create a parent CompoundShape. This worked fairly well but I immediately noticed that the children collection seems to be immutable. So for the areas that users can place and remove blocks Id need to either not use CompoundShapes at all or destroy and recreate the parent compound with every change, which sounds expensive.
I know almost nothing about static meshes but the use of the word static makes it sound like it is optimized for this type of purpose. and then I would use that for the non changing areas and a different solution for the areas that can be changed.
I figured that it had gotten to the point where I should probably ask you how you would handle each situation if you were the one writing this application. In code all of my blocks are in a large array currently and then my blocks basically inherit from the base physics types I need, not sure if that's correct either or if I should just instantiate the type and keep it as a property. To summarize I basically have a static terrain built out of boxes that could some time later become a dynamic terrain but not often and then some randomly generated caves that are built completely out of boxes that can be added and removed. So should I be using the prefab Box, the BoxShape in a CompoundShape, a StaticMesh, or is there some other even better way? especially if all of the default terrain will be pre-designed by me before the launch of the game.
Sorry I got so verbose, and again thanks for any help and for the great engine!