Procedural City

Blitz3D Forums/Blitz3D Beginners Area/Procedural City

Nexus6(Posted 2012) [#1]
Hi,I havent used Blitz in years and ive forgotten more than ive learned, but ive had this idea for creating a procedural city in my head for some time and I now find i have some spare time to have a go at creating it.

The buildings will be created by stacking varying sizes of primitive cubes on top of each other and other buildings will be created by creating intersecting cubes of different heights.

Each building will be randomly generated so will each be different and will be textured with a random co-ordinate from one of 4 1024x1024 textures(im also looking at creating the texture at runtime too).

I havent coded anything yet,,,, I like to think of all the possible problems that im likely to encounter before starting to code, and the biggest one that jumps out at me is speed.

With a city full of unique buildings made up of several primitives, i think this is going to be a performance hit.

I remember lots of talk about copying entities and single surface stuff but havent got a clue what its about or even if it will help me in this instance.

Im not after any code, I just want a gentle shove in the right direction on how i should tackle this.

I was also wondering if its possible, or even worth trying to weld the primitives together once a building was complete and work out a way to remove the hidden full/partial faces.

I feel like a Blitz virgin again, so dumb it down as much as possible.


Ross C(Posted 2012) [#2]
Well, your first problem is the vertex limit which i believe stands at 65536 or 65535 i forget...

1024 x 1024 (if you doing a city grid, equals 1048576 different vertices), which rules that out, unless you split your city into multiple sections.

Your maybe best to create a flat mesh for the ground, then create another mesh solely for the building. You could keep it single surface too.

I would avoid welding anything. Just create a cube, and scale it to a multiple of it's size.

Would you have roads, like in a grid set up? This project has intrigued me :D I might knock a little something up.


Nexus6(Posted 2012) [#3]
Hi Ross,

The idea is a complete rip-off, and came about after reading this Blog http://www.shamusyoung.com/twentysidedtale/?p=2940

The results look great, and after reading it about a month or two ago, ive been itching to have a go myself.


Ross C(Posted 2012) [#4]
Ah righty! I'll have a go at this tomorrow. Too busy baking a cake today!


Ross C(Posted 2012) [#5]
Ok, i've started on this. When you talk about single surface stuff, it means you are creating different collections of vertices and triangles to make your individual shapes, but, using the same mesh surface to hold them in.

When you create a mesh, it's just a container. You need to create a surface to hold the traingles and vertices in.

For example:

;create your mesh and surface
mesh = CreateMesh()
surface = CreateSurface()

; add vertices so they form a square shape
v0 = addvertex(surface,0,0,0)
v1 = addvertex(surface,1,0,0)
v2 = addvertex(surface,0,-1,0)
v3 = addvertex(surface,1,-1,0)

;create triangles using your vertex points
addtriangle(surf,v0,v1,v2)
addtriangle(surf,v2,v1,v3)



That would give you a flat square shape. Now, instead of creating a new mesh, you can just add a new set of vertices and triangles to the existing surface. Blitz won't overwrite any previously created vertices. This would mean when you finish, you will have 2 squares, but they will be part of the same mesh, and be rendered as one.

The only drawback to this method is, you can't use entity commands to move the individual squares around. You need to use the VertexCoords command to move the vertices that make up the squares. To do this painlessly, your best to create a type structure, holding all the start vertex number (blitz keeps an index of all created vertices in a surface) and the numbers of all vertices that shape uses. That way, you can simply find the shape you want to move in the type structure and you have all the information about it in there:


Type ss_object

   Field start_index
   Field vertex_index[7] ; blitz array. The only kind of can use in a type field. Non resizable. Set to higher if you intend to use complex object

End Type



I don't think there is much more you need to store about the object. When you want to move it, simple move each vertex the desired amount. Rotation is more of a pain, but you won't need it for your project. Also, about the array in the type field. Since your only create simple cubes, you can limit the array size to 8 (0 to 7). That will cut down memory requirement.

What you will need to do though, is keep track of how many vertices your creating in a surface, to make sure you don't go over the limit. Assuming 8 vertices for each structure:

65536 / 8 = 8192

You'll be able to build 8192 blocks with it. Remember as well, you'll need to manually set the vertices texture co-ords. You do this upon creating the vertices. Again a slight problem will arise when modifying the height of the buildings after they are created(if you intend to do that), as you will have to adujst the vertex texture coords to start the texture stretching. You can help by laying out your texture properly, so that moving the texture coords up on the texture, the texture has additional building texturing above that point. You could even dedicate an entire row to this, to allow tiling.

I hope some of this information helps. I'm going to go away and put this into practice and see what comes out.


RemiD(Posted 2012) [#6]
I have tried to generate a procedural city some months ago.

The example made by Shamus is not too difficult to achieve because it is positionned on a grid. Also the buildings have no purpose to the Player, it is only a demo.

I have tried several approaches and one thing that i have learned, if you want to use your city for a video game, is to create the roads for cars and for humans first.

This way you can create the waypoints at the same time and then fill the empty space with buildings and/or parks.

Concerning the numbers of vertices, tris, surfaces, textures used without consuming too many ressources, a technique is to use different zones and different lod (or background images) depending on the active zone.

Also another possible optimisation is to merge all static surfaces and textures of a zone and to use invisible meshes to activate the doors and the objects in the game.

No easy task, Good luck !

Last edited 2012


Ross C(Posted 2012) [#7]
Good point about the roads. I am using a grid system here, so creating the road structure would be better. I'm thinking of using a texture to base it one. So RBG (50,50,50) could be a road etc


Ross C(Posted 2012) [#8]
Ok man, I have a basic city generator:

http://www.rcsolutions.webspace.virginmedia.com/city_generator.zip

It does the following:

Lets you choose a map size (maximum 45 by 45 because of vertex limit)
Let you choose how populated you want it.
Let you choose if you want a greater percentage of the various building sizes.
Lets you choose the grid structure of the roads (how far apart they are)
Automatically textures the city buildings based on their height, so the texture doesn't stretch.

Use the mouse and arrow keys to fly. Mouse buttons move back and forward.

I still have to finish the vertex texture co-ords so the side of the building are textured.

You can use this for whatever you want. Just don't say you coded it ;) I'm away shopping, but i'll finish it off more when I get back.

Last edited 2012


Drak(Posted 2012) [#9]
I like it!


Ross C(Posted 2012) [#10]
Thanks :) The only problem I have is the buildings inside the perimeter of the city blocks. I think i'll hollow out the inside.


Nexus6(Posted 2012) [#11]
Cheers Ross, this is exactly the start that im after. Been busy all day and havent had a chance to get online (not baking cakes though,,,,, ran out of flour).

I'll have a play around with this when i get home. One question I wanted to ask, what are the benefits of a single surface system over createcube(), copymesh()


Ross C(Posted 2012) [#12]
Well, for me, it's the texturing, plus i don't need to make a bottom to the cube, so i save myself 4 vertices per building. I can texture each side individually too, which you can't do with a cube.

You could create a cube in a modelling app, remove the bottom and texture all 5 sides differently and set the UV co-ords that way though!

The code is a bit messy. I'll clean it up. Oh, and sorry to hear about your flour situation...


EDIT - I forgot to thank sswift for his calculate_normals() function. Much better function than the blitz one in this case!

Last edited 2012


Ross C(Posted 2012) [#13]
Dam bleeding textures. Bare in mind if your using the one texture for all of your texturing, the edges will bleed over from the tiles. Pain in the butt. I think adding a 2 pixel border helps.


Nexus6(Posted 2012) [#14]
OMG my brain aches!!!!!

I was up half the night trying to figure this out, im like a zombie in work today.

I really wanted to avoid all those vertices, surface to air missiles, triangles and other pointy stuff, and keep things nice and simple. Last night i started coding a routine using copyentity() to make random interesting buildings out of primitive cubes. Everything was going great, i was so pleased with myself :D <--- that was me. Then i thought id have a look what they looked like textured. I threw on a sample texture,,,, im still smiling at this point, i try to move the texture co-ords on one segment of the building to avoid repetition :( <---- that was me. Whenever i moved the texture on one building, or one part of the building, it moved it on all the others AAAAARRRGGGHHH.

Is there anyway i can use the same texture but at different cordinates on several cubes.

Failing that, would it work If i created individual cubes using copymesh()and then applied the texture, then converted them into a single surface afterwards.

I think i need more coffee


RemiD(Posted 2012) [#15]

Dam bleeding textures. Bare in mind if your using the one texture for all of your texturing, the edges will bleed over from the tiles. Pain in the butt. I think adding a 2 pixel border helps.



Ross>>Have you tried to load the texture with the parameters 16+32 ?


Ross C(Posted 2012) [#16]
Nope, i'm afraid not. It only helps when the texture is tiling over. You can't easily disable bi-linear filtering in blitz... I sorted it though by bordering each tile area with a pixel worth of similar coloured pixels. Thanks though!

@ Nexus, I can create you a cube, with one texture, but use different parts of the texture for each side if you want?


Nexus6(Posted 2012) [#17]
@ Ross, PLEASE


Ross C(Posted 2012) [#18]
http://www.rcsolutions.webspace.virginmedia.com/cube.zip

I can create one where all the sides have their own textures, save you buggering about with UV co-ords?


Nexus6(Posted 2012) [#19]
Thanks for all your help Ross. If you didnt mind, then a cube with separately textured sides would be a great help.

Im still unsure of how to display different parts of the same texture without it affecting all instances of the texture.


Ross C(Posted 2012) [#20]
Fari enough! I'll knock up a 6 sided textured cube.


Ross C(Posted 2012) [#21]
Ok man:

http://www.rcsolutions.webspace.virginmedia.com/cube6.zip

I have included code to find the children and assign them.

You can do one of two things:

1. Copy the children of the mesh and use these for your cube, or,

2. Copy the original mesh, and extract the children everytime you copy it.

You can now apply any texture you want, to any part of the cube. You will have 6 surfaces per cube though, so you may experience slowdown.


Nexus6(Posted 2012) [#22]
Thanks again Ross :) I really appreciate your help. However Ive decided im gonna have to bite the bullet and learn those verts and surfaces stuff. I picked your code apart for hours last night and i think im beginning to understand how it works and how to apply textures. Hopefully I'll get some more time tonight to have a play with it.

Thanks again


Ross C(Posted 2012) [#23]
No bother man. If you need any help, give me a shout. I'm going to clean up the code and package things into a function, so you simply select the tile on the texture (x,y) and the code converts the co-ords into UV's.


Ross C(Posted 2012) [#24]
Hows it coming along?


Nexus6(Posted 2012) [#25]
Slowly, Ive had a rush of work on lately and have been working way past midnight for over a week. Hopefully I can get some time to work on it on Sunday. Ive finally got my head around the single surface stuff, I think that was my biggest stumbling block, im now working on a road layout system, I dont want the classic grid system, I want it to be a bit more authentic. Cheers again mate, I couldnt of got started without your help.


Guy Fawkes(Posted 2012) [#26]
O, don't mind me. Just hijacking ur thread. :) "LOL!" :)


Ginger Tea(Posted 2012) [#27]
Hardly call that hijacking.
Tell me though, how goes your circle problem, I trust you understood what Drak posted about recently.

That's thread jacking

Your's Queen Ginger Tea III

Edit:
Back on topic, the OP's link to the other guys stuff was a fun read and a nice video, the only thing missing was a voice over by Sip's with his (now RIP) Toaster Mic.

Regarding the grid formation, I thought American cities were formed using grid layouts since nigh on the founding fathers, so they would look natural, over here in Europe where cities have grown over centuries our roads can and do weave around creating jilted vistas.

Last edited 2012


Ross C(Posted 2012) [#28]
Cities like Glasgow are based on a grid layout. Newer towns like the one I am from doesn't seem to have a layout. It just goes all over the place. I am thinking of creating a game based on this. Well, starting one at least :)


O, don't mind me



You don't help yourself.


Ginger Tea(Posted 2012) [#29]
There already is a game, it's called Pipeworks ;)

"Quick there's a car comming, hand me another piece of road" looks at piece "Another cross road, that's 3 in a row you've given me now."


Ross C(Posted 2012) [#30]
lol