| Zombie simulator: destructible buildings |
|
|
|
| Monday, 18 January 2010 19:45 |
|
Well, that was a lot of hard work. I've spent the last couple of days trying several different methods for implementing a way of destroying buildings that looked "reasonable". The most obvious one to start with was simply to duplicate each wall piece and remodel it so that it was missing a piece. Nope, didn't look so good, especially with a row of walls all having duplicate holes and each wall piece needing to be able to be joined to the next. The next step was to try to break up each wall piece into the four corners so that, for example, if a wall is missing to the right of one that's been damaged, then the upper and lower right hand pieces wouldn't have to be drawn. Nope, still didn't look so good, plus it was a lot of work, especially dealing with the corner pieces which needed six sections, then I had to deal with the roof, the floor... it was all getting too complicated. So, I went back to the drawing board. While browsing the web looking for ideas, I stumbled across some Blender building collapse videos. These videos are demonstrations of the physics modeling that the Blender 3D package is capable of. A little bit of research revealed that Blender was actually using a 3rd part open source physics package called Bullet Physics. Back to the Irrlicht forums, and there's no shortage of physics classes, and many of them use Bullet, such as this one, so I downloaded it to poke around under the hood. The Physics implementation was quite straightforward, but I couldn't use one of these Irrlicht classes because they revolve around using an ISceneNode as the base physics object. Each of my buildings is a single IMesh, with each floor in the building represented by a single IMeshBuffer. Floors are assembled by simply mergine individual wall meshes together, so I needed some way to represent each wall piece as an individual object for the physics engine to work on. Handily, Bullet Physics has just the object: btBoxShape. Now, obviously, not all my wall pieces are rectangular, so what I did was to go back to Blender, duplicate the existing wall pieces, then colour code and simplify them so that they could be broken down into rectangular shapes. I'd already written the code to remove a wall piece when I selected it and hit delete, so I simply modified that code to pass an array of bounding boxes representing the colour coded wall pieces to the physics library and let it do it's thing. Then, once per frame, I manually draw the mesh buffers that make up the pieces where Bullet says they should be.
And here's the result. Dim lights Embed Embed this video on your site Easy. It does slow down once a few buildings have been knocked down and you've got a few hundred building pieces strewn around. I've done a bit of testing and I believe I can get away with about 60 pieces flying without affecting performance noticeably, so in future, when a building explodes or collapses, I'll see to it that there's no more than 60 pieces moving by simply removing the excess pieces and hiding the missing bits behind special effects like sprite based debris or smoke and dust. Once the pieces have settled, I'll create a mesh out of the parts on the ground and release the physics objects so that they no longer consume resources, allowing the next building to fall down. There's still a lot to do. The building shouldn't actually explode. That's caused by slight overlaps in the bounding boxes for the parts, causing the physics engine to throw the bits violently away from each other. Nice effect though. I also need to add the nearby buildings as physics objects - just the bounding boxes mind you. That'll stop pieces of building passing through them. And I should probably also rough up the broken pieces a bit - they're a little too neat at the moment, but that should just mean altering the texture and adding a few extra vertices. The videoYes, it's pretty small, but at least it's smooth. I had a lot of trouble finding a method of recording a graphics screen in real time under Linux - it seems there's nothing that can do it faster than a few frames per second. Eventually, with some suggestions from the Irrlicht forum, I ended up writing out each frame as a single 800x600 bitmap snapshot, then used ffmpeg to convert all the separate images into a .flv file, which I then uploaded to YouTube. I figure I can probably improve the quality if I write out the snapshots to a ram drive, rather than the /tmp folder. Though at about 1GB per 30 seconds, I'll never be able to do a long video with only 4GB of RAM. I'll keep working to improve the quality of future videos. blog comments powered by Disqus |



