Tree Generator

This page serves to showcase the Specialization course, which is the last individual course of the second year. The course gives students the opportunity to explore areas of interest and to expand their knowledge in specific areas. The duration for the course is five weeks part time.


Project and Goal

With this project I wanted to explore procedural content generation (pcg), through the implementation of an L-system tree generator. My goal is to create a simple tool for generating and exporting meshes to be used for environment creation, specifically plants.


I chose to use ImGui as my interface and to use the engine from our project group because I wanted a framework I was familiar with, and I also wanted to be able to use this tool for later projects.

All code is written in C++.


Feature Showcase

This is the ImGui interface in all its glory. To the left we have the settings for generation, to the right a brief explanation of symbols and controls, and below that we have the save window.

The Rotations tab defines min and max points for the random offset of angles. Set them to the same value, and the tree will look the same each time it is generated.

The save window will not only save the generated tree as an fbx, but also the settings used to get that result.

The third value of the Rotations tab makes the tree a little bit more interesting. If this value is set to zero, the tree will grow straight up, with straight branches. This "Trunk angle offset" brings the result to life. If the interval is weighted more against either side the tree will naturally lean in that direction.

The Editor class

This section showcases the heart of my tool, namely the class that interprets the ImGui interface, and passes information to helper functions/objects. This is also where everything is initialized.


The most interesting part of this class is the Generate() which iterates the string given in the Premise field and applies the rules specified in the two Rules fields. When the final string is obtained, we send it on to the TurtleGraphics, and get a container with data as a response. This is the data we then use to create the capsules that make up the sections of the tree, through the GeometryGenerator.



The TurtleGraphics class

This one I found a bit funny, and so I stuck with it. As I understand it, you imagine a little robotic turtle that moves on a plane, to which you can give instructions and in that way create shapes on that plane. Here of course we are using a 3D space, but the mentality is still the same.


In this case I only have one command, Run() which takes a string of further instructions. These are then sorted through by a switch/case to determine the proper action to take.

Part of the flow is the ability to return to a previous point, and for this I use a series of stacks. When the load symbol is read, we simply pop the stack back to the previously saved point.

When all is done, it returns a vector of vertices to be used for generating geometry.

The GeometryGenerator

This one is handeling the creating of the shapes I use for rendering my tree, mostly I’m going to focus on capsules. This is also handles the creation of the combined mesh, and saving models.


The CreateCapsule takes in two points and uses a simple rotation algorithm to map the vertex positions of the sphere halves on each end of the shape. I decided to use ten points around the circumference, which makes for a total of 42 vertices.

The algorithm takes an orientation between the two points, rotates it a set amount, and then translates a new point along the x(GetRight) axis of the transform, with the scale set by the Run function of the TurtleGraphics class. On each iteration the transform also tips along the local Y-axis to make for the ring towards the endpoints.

In Retrospect..

I set out to make a more advanced tool than I actually managed to make. I wanted to be able to specify presets for generating realistic trees such as pines or fir, and have them use custom shaders for foliage. The reality is that the exporting using Assimp took a whole lot longer to get up and running than expected. As a result I had to cut that extra bit of functionality from my project.

I am however very pleased with the work I made. It is so awesome to see these shapes and to think that only code made this happen, and in such a short time too!

I am excited to keep developing methods to generate content both as environment, landscapes, and individual things like plants and rocks.

Highlights

A small timeline of the progress I made through these five weeks of development.

The first day I made the interface

Then I managed to draw positions using cubes, the branches are there, but everything is facing the same direction.

Here is how it looked after I got the rotations to work properly

The second week I went nuts with the iterating, and verified the functionality for what I wanted it to be.

Added scale per iteration

The capsule algorithm in play


The capsule as a fbx model. Had some problems with the orientation of faces, but was quickly overcome.

First time generating a tree as a capsule mesh. Here we can see some problems with the capsule vector not matching expectations.

And after I fixed the order I passed the vectors to the mesh function.

Then a splash of color.

And something looking more like a natural tree. Here's the trunk angle offset in play.