Quote:
Zoning is fine, but just dropping buildings is dumb. I want to "grow" cities that follow the terrain so they look a bit more organic. The algorithm I settled on for an initial test (but never implemented) was to give each building an amount of population that it consumed, and then right at the start determine the population of the city. Then we walk out from a point or set of points (eg the starport) in all eight directions, looking at the terrain around it. If the terrain is too steep, is water, already has a building, etc we don't go that direction. We place buildings at all remain points and then recursively walk out to each building we placed and do it again. Each time a building is placed, we consume its amount of population from the total, and stop when we run out. This should create cities with a heavy central area and thinning out the further out you go. It should also follow ridges, rivers, etc in a "natural" way.I want roads too and bridges too. Maybe roads are just a special type of building? Bridges are - they just have two "bases", which must be on similar heights, and preferably spanning some terrain that is radically different in height (water, ravine, etc).
I don't think that roads make sense as buildings, zoning, population, and following the terrain all seem like parts of the same thing. You can't really consider them in isolation.Lets take a look at how one other example I've read handles this, I think it's similar to the cancelled "SubVersion" project:1) generate heightmap,2) generate habitability map - i.e. water = 0, mountain slope = 1, marsh land = 2, flat solid land = 3, etc.3) generate population map - starting point is the highest value on the habitabilty map that's nearest to the city centre, add more points based on overall desired city size, then turn these into a Vornoi map with a value dropoff say starting at 255 at the centre to 0 at the edges.4) generate highways - the above Voronoi map generates a lot of edges around population density points, you can connect these density points directly (as major roads) and then use the edge list from the Voronoi map as smaller roads.5) generate lots - major population areas have now been nicely divided up, break up the resulting blob areas into smaller building lots of whatever shape you like, a grid based approach is probably ok at this resolution and it's quick.6) the edges of the lots above can now become minor roads, i.e. one and two way streets,7) buildings are placed at one corner of each lot facing the road (either) and then the rest of the buildings can be placed around the lot one after the other with a little bit of buffer spacing - the choice of building is based on the habitability and population density maps we created earlier, higher population = taller building but constraints applied by habitability because you can't have a skyscraper on a mountain slope etc.If you want defined economic type zones or instanced building types then they get injected as other maps or parameters of the vornoi zones etc. Inserting a large spaceport of example would add an extra major highway to be drawn during the "generate highways" process and put a large exclusion area into the lot generation which all naturally filter down into the following stages.Hmm, I should program more and think less sometimes

Quote:
Looking at the "steepness" of the terrain for placement is fine, but on gentle slopes its still possible to have the building bases do the wrong thing. Placement needs to be able to modify the underlying terrain slightly to flatten it - call it excavation if you like. I don't know what the performance hit will be as we have to compute the terrain height at the four corners of each building instead of just the centre, so naively our height computation during city generation quadruples. There's optimisations that can be done - take the central point for one building and interpolate to the known centre point of the previously-placed building, but its still heavier. It may not be a problem, but I don't currently trust our heightmap generators for speed
Instead of thinking of this as a problem with generating terrain, derive the heightmap from the buildings and the city itself.We have the heightmap, lets say it's a greyscale heightmap in traditional 2d, we don't need to re-generate anything, we just paint the building footprint into the heightmap plus the centre height. That would have the effect of raising the lower heights and lowering the higher bits without calling the terrain generation.When the terrain is generated it only _reads_ the information from this heightmap, no additional noise or processing required because all terrain directly under the centre of the city comes _from_ that city heightmap

Quote:
So now we have a generated, static city heightmap that we have to use in place of the dynamic heightmap. Blending may not actually be necessary. The city heightmap was originally based on the dynamic terrain, so perhaps it can just be used in its place. Probably some blending is necessary though, as its going to be a fairly low-res map compared to the higher detail levels coming from the generator.Blending on the GPU would be incredible simple - sample two (or multiple) heightmap textures, blend them, adjust mesh positions. I'm not so sure about on the CPU. I guess its the same, its just that GeoSphere.cpp scares me right now.
Blending is possibly the wrong usage by me, my fault, what I had in mind was something simpler.Currently we generate the terrain using noise, what I'm suggesting is that near a city the cities local heightmap overrides the terrain generation algorithm. This would be "ok" because of two features: the 1st is that we'd have used the terrain generation as an input for the city heightmap anyway so it wouldn't be too different, the 2nd is that when we generate the terrain mesh we'll linearly interpolate between the height from the planet noise and the city heightmap depending on the distance between the inner and out extent boundaries.I'll try and write a quite example of the 3 cases:1) Outside the city entirely, terrain mesh height = planet_noise(x,y,z)2) 50% of the distance between outer and inner city extents, pn = planet_noise(x,y,z)ch = city_height(x,y,z)// result is a point 50% of the distance between points "pn" and "ch"terrain mesh height = ((pn) + (0.5) * ((ch) - (pn)))3) completely within city inner boundary, terrain mesh height = city_height(x,y,z)No actual "blending" needs to be done anywhere as it's done at mesh generation time.Of course this is based on thinking about how our current terrain system works :)Right, can't post anymore right now, got washing to do and then going for lunch
