| Zombie simulator: buildings |
|
| Tuesday, 29 December 2009 07:59 |
|
Well, now that the roads are in, it's time to add some buildings. Taking my usual organic approach to development, this means that first of all I'm going to construct the walls, then worry about details such as doors, windows, different textures etc. Identifying buildingsBuildings are defined by blocks of coloured pixels on the map. Rather than simply construct one huge building for every coloured block, I'm going to divide up large areas of colour into a series of smaller buildings. The process is quite simple: scan across each row of the map looking for one of the building colours. When one is found, scan down and across the map from the starting point to find the largest horizontal and vertical rectangle that's the same colour, then, if the block is large enough to hold a building, simply store a building definition in an array and clear out the corresponding pixels on the map covered by the area of the building. Keep scanning the rest of the map. A separate list is constructed for each of the different colours that identify buildings. That's the easy part. The next bit is actually constructing the building. Constructing buildingsThere's not many cities that have only single floor buildings, so I'm going to need to handle multiple floors. Additionally, I want the walls of the buildings to be destructible, so I'll need a list of walls that each buliding is constructed from. To handle all this, I've created a series of classes to store the information.
From the Irrlicht perspective, I've decided (for now) to create one Mesh per building, with each floor defined as a separate Mesh Buffer, which will (hopefully) permit individual floors to be rebuilt on the fly as the walls get damaged by the surrounding battles with the zombie hordes. Modeling the wallsI initially toyed with the idea of manually generating the wall models from with C++, but it quickly became obvious that it would be necessary to use a 3D modeling tool to create the models then load them at run time. Ignoring doors/windows/etc., I had to build six wall pieces, one for each of the corners and one for both the horizontal and vertical walls, so I broke out Blender and got to work. It turns out that 1 unit in Blender equals one unit in the Irrlicht environment, which means that in order to create a wall that's 256 units in size, the model had to be absolutely massive in Blender (the default cube in Blender is 1 unit in size)! To get around this, I'm working at 1/10th scale in Blender, then scaling the object up to full size in Irrlicht.
The image above is a screen shot taken in Blender showing the six separate wall models after they've been textured. Since Irrlicht can't read Blender files, I had to export them in .X (Direct X) format. After my first attempt at reading them into Irrlicht, I found a few issues in the way the exported data is arranged.
To get around this, I wrote a function that basically created a new mesh from the imported one and fixes all of these problems, in particular the last one with excessive vertices. The reson why there are so many extras must be the way that Blender internally stores the data. Each triangle has a unique list of vertices, which means, for example, a square plane, composed of two triangles with only four corners actually has 6 vertices, two of which are duplicates. In some situations you do want duplicates as it will allow you to have unique texture coordinates for two polygons that share common vertices, but most of the time it's just a waste of resources. One other little optimisation I performed was to delete the back faces from the wall models. Because the camera's location is fixed facing one direction, there's no need for the hidden walls to be included in the mesh. I've attached a rear-view of the walls to show you what I've deleted, which has about halved the number of triangles needed to render the walls.
A work in progressHere's a couple of shots from the zombie world with the walls up. It's still very much a work in progress, so all I've done is colour code the wall pieces to show what the type of building it is. The end product will have a larger variety of wall textures and designs, but for now this will be sufficient to allow me to move on.
Because I've rendered the walls as separate pieces, the amount of data points required to generate the entire map is pretty large, resulting in about 15,000 triangles for the entire map above. This runs fine on my mediocre box, but it really needs to be better, so for my next installment, I'll go into some specific optimisations that I've done that have drastically improved the frame rate. blog comments powered by Disqus |




