I’m wondering, what could be the most efficient method for applying physics (or some type of pseudo-physics) to a block based voxel game, such as a minecraft style game?
I’m still learning how to use Panda3D and experimenting with its features, but the first thing I’d like to look at when approaching the concept of this game is the physics. Which physics library do you think would be the most efficient for this type of game?
I have prior experience with Bullet, though I have also had a look at the section in the manual on Panda’s built in physics as well as ODE.
I’m not sure whether I would have better luck with just writing my own ‘fake’ physics based on simple collisions and rays, or using one of the supplied engines.
I tested out a small scene with some generated blocks and the player with Bullet. The blocks had rigid body boxes with a mass of 0 parented to them, and the player was a capsule object. This dropped the fps down to 10, which is really not what I’m looking for, especially in a scene with just 8x8x4 blocks.
Perhaps some pseudo-physics code using rays could do the trick for collision.
Any suggestions would be great.
In short, I’d say you have two main options.
- Build your own physics/collision detection. Since you already have voxel data, you could most likely tap into that pretty easily. Find the height of the ground at the brick below the player, then slowly move the player down with accumulative force, for gravity. Once the player hits the ground you could stop applying the gravity force, and check to see if the player is jumping, then apply a small force upwards for a set period of time. That handles gravity and jumping.
Then you need to handle collision with walls, as well as roofs most likely. For roofs take into account the height of the brick above the player’s head, and then account for the height of the player, and bam. For walls, since you’re using square bricks (I assume) it’s simple, when the player requests to move in a specific direction (+0.1x, +0.1y) for instance, find each block to the side of the player, if that block is of a greater height than the block the player is standing on, then allow no movement in that direction. Now that’d seem kinda ‘fixed’ so you have to account for some leeway room (based off how wide your character supposedly is)
- Use Bullet or some other physics/collision library, and only feed it the blocks that are within 10 units of the player, for instance. IMO this could be easier or harder, depending on how you have access to the voxel data.
Hope this helps,
Thanks, powerpup. The first option actually seems to be the best; it would probably be more integrated with the world that way. One problem with that, though, would be to get the player to collide with the blocks as if they had cube-shaped bounds, rather than stopping movement by just distance alone (which would indicate spherical physical bounds).
I imagine that the way to do that would be to test not by distance between centres, but rather by comparing differences in coordinates - that is to say, differences in x, y and z.
For example, if you have a cube at position (x, y, z) 1, 2, 3, with size 4 (I’m presuming that this is indeed a cube, and thus that all sides are of equal length), then a player with x > -1, x < 3, y > 0, y < 4, z > 1 and z < 5 (that is, each coordinate + and - size/2) has collided with the cube.
As suggested above, I believe, it might be a good idea to account for the size of the player (or other object being tested against a given cube); for these purposes considering your objects’ collision boundaries to be rectangular prisms might be more useful than capsules.
Thanks Thaumaturge. I had the same idea in mind as well. I’ve been giving this a try and it seems to be working pretty well so far.
What I’m afraid of doing is relying too much on this system, because maybe at some point I will need to invest in more complex physical shapes for collision, such as stairs or ramps, or just irregular collision shapes in general. I’ll have to look into a more optimal implementation of Bullet or one of the other physics libraries.
Fair enough; you might well be able to use a hybrid approach, using more complex collision where called for, but the integration of the systems might prove tricky.