Simon Verstraete shared a breakdown of a City Builder that works based on the mouse clicks in the viewport of Houdini. The written materials require basic Houdini knowledge.
This article will show you a breakdown of the base setup of a City Builder in Houdini. The tool can make a city based on the mouse clicks in the viewport of Houdini. To be clear, this tool only works inside of Houdini and uses the Python viewer states for this.
Note: This breakdown will require you to have basic Houdini knowledge and would recommend less for people just starting out with Houdini.
The biggest inspiration for this project was Oskar Stålberg. His work is always impressive and it got me wondering if this would be possible in Houdini as well. You could also see my attempt in Houdini as a proof of concept that you could take this idea into other software like Houdini.
The first thing to make is a grid or ground plane that you can use to build the houses on. In theory, this could be anything, like a quad grid, triangles, hexagons, etc.
The easiest way I found to create an interesting quad grid is to use a quad mesher.
Start with a circle node and after that place down an instant mesh node. The instant mesh node is from the Labs tools, so make sure you have them installed.
After that, place an extrude node; this is then used later for extruding the primitives that are selected by the mouse.
The setup now will then be collapsed into an HDA. In the HDA, you will create a parameter to work with in the python code. In this case, you want to control the group parameter of the extrude and fill in primitives that are being clicked on by the mouse.
Python Viewer States
Now you can start with the Python code. If you are new to the viewer states, I wrote a basic intro to it some time ago (Link).
Create a new Viewer state and start with a blank template. This will generate only the piece of code you really need to create a viewer state.
There are a few things you will need to add to it and you could split it into 2 parts:
- Getting the geometry to look at for mouse clicks
- Getting the primitive number when clicking with the mouse
First, let's add the geometry to look at.
In the part with the init, add a new variable for the geometry called self.geometry = None.
Then add the def function OnEnter, this method is called when the state is activated by the user creating a new node or selecting an existing node and pressing Enter in the viewport.
Here, we store the current geometry in the self.geometry. You do this with the node.geometry().
Now you have a link with the geometry.
The next part is then getting the primitive number based on the mouse position when clicking.
For that, create a Def OnMouseEvent, this is processing mouse events (like mouse clicks or mouse pos).
At the beginning of the mouse event, you will need to create variables to work with.
Then gett the intersection with the geometry with the function GeometryIntersector and use the self.geometry in here. I also want to mention that there are multiple ways of getting these intersections and everything is documented here.
From this intersection, you will get the info you want, ask the primitive number and print it out.
If this is correctly created then you will have this:
The last setup here is to then use this prim number in the group parameter you made at the beginning. Replace the print line with a new line, call the group parameter and set the primitive number as value. Notice that it is also converted into a string because the group is a string parameter.
From here you now have this result:
This is the base idea I started out with to create the tool. From here, you will then store the information instead of overwriting it. This setup will give you a base to start and experiment with.
Once you have these cubes, you can do a lot of things with it. I created houses from the cubes.
At this point, you now create a house generator if you want a city. There are tutorials available for house generation, so you can look for them on the internet if you're interested.
Here is then an example of what to do with cubes:
On each side of the cube, a modular wall is copied.
Here is the border which is beveled and unwrapped with UV project.
Performance can be a very important thing here. If you want the tool to work fast so that when you click it instantly places a house, you need to keep it optimized. For that, you can try to use as fewer loop nodes and boolean nodes as possible in the network.
The future the tool
What I want to do with this tool next is to step away from the city and make a level creator tool. The idea is that you can quickly prototype finished levels with a couple of clicks. I got inspired by Hob for this next exploration.
Here is a demo of what I have at the moment:
Thanks a lot for reading!