top of page

SIMULATING PLANTS

Project File DOWNLOAD 

About this project:

There are several ways for doing this kind of simulations in Houdini and over the web there are some amazing examples. You can use wires, grains, bullet.
In my experience wires are amazing and really easy to use when there isn't much going on in terms of collisions.
The main problem using wires for this scene was that they easily got stuck to each other or inside the character while he was falling and rolling. So I had to spent a lot of time changing parameters, trying to find the right values.
Then I remembered that time ago I've seen a project by the great Goran Pavles. He was simulating the collision between a giant character and some trees using bullet (not in Houdini). I decided to try it in Houdini and here is the result.

PART 1: simulating the branches

The first thing I've done after loading the geometry in Houdini, was separating the branches from the leaves.

In Fig.1 the initial geometry. I couldn't have used this as it was, so I converted it to splines inside a “For each loop”.

Inside the “For each loop” (for every branch):

I've fractured the geometry using “voronoi fracture” and scattered points on the surface using a “scatter”. Once it was fractured, I've packed thee pieces and deleted everything except for the points. With an “add” node, I've used the points for creating splines along each branch. The splines have been resampled (and created a curveu attribute), assigned an id and trasformed back again to points. For every point I've copied a sphere and used the curveu attribute created previously for control the pscale. In Fig.2 you can see the result.

This is the proxy geometry that it will be used for doing the first and main simulation of the plant.

original fern branches

Fig.1

tree branch bullet solver

Fig.2

The simulation of the branches isn't complex at all. The main things to note are two.

One is that the constraints are cone twist constraints. The cone twist constraints have already some useful attributes for controlling rotation/twist and their allowed directions.

The second thing to keep an eye on is that the result of this simulation will be the final result. The leaves are attached to this proxy geometry and they will follow it. So for example if in this first simulation the branches start roll in the ground, the leaves will do it too and we don't want it. I've used a “pop drag” near the ground for prevent the branches from rolling. Below a screenshot from the DOP network.

branch_dop.png

Inside the DOP solver there is the condition for break the cone twist constraints based on the attribute "angle".

PART 2: preparing the leaves for the simulation

Now that we have done and cached the simulation of the branches is possible to use the attributes that are automatically created for transfer the correct motion to the leaves. The most important one is “orient”.

 

NB: for the next steps is necessary to know which is the branch that the leaves are attached to. There are different ways to do it. In my model, every leaf's point had at least 3 neighbours points, except for the tips. So I've decided to search the nearest branch from the inner tip point (the one nearest to the branch) and transfer the information to all the other leaf's points.

 

The first thing I've done was saving the inner tip position as an attribute.

Then extruding each leaf and fracturing it in three pieces. In fact most probably the geometry will not be flat (and fake), but it will have some sort of bending. We know that Houdini will read this non-convex geometry as convex geometry, and the collision geometry created during the bullet simulation will not match the original one. It's not a big problem for the approach I've used, but I've noticed that the simulation was faster using the fractured leaves. Every leaf is fractured but then it is packed again in one single piece using the original name.

PART 3: creating the leaves constraints

Now that the leaves are packed, I've moved the pivot of every leaf/packed object to the inner tip position saved previously. This is an important step. I wanted the constraints to connect to the inner tip and not the center of the packed fragment.

I created the constraints and transferred the orient attribute from the branches to the contraint points.

The point connected to the branches need to follow the animation of the proxy/branch geometry. It also needs also an empty name (s@name = “”). This means that during the leaves simulation, this point of the constraint will not follow any RBD object but will follow the movement in world space position we transferred from the branch. If you are new to this, I highly recommend watching this great tutorial 

Leaf rotation axis

I've then duplicated the constraints two times and merged them back together. The first copy is going to be hard positional constraints (s@constraint_name = “pos”) and the second copy is going to be spring rotational constraints (s@constraint_name = “rot”).

For the rotational spring constraint I've assigned the attribute v@condir which is the attribute that specifies the axis that the object can rotate about. This axis is parallel to the branch, see Fig. 3. The red arrow is the direction of the axis I've set.

We need also another attribute called i@condof. If we set it to a value of 2, we specify that we would like the object to rotate around the v@condir axis, like an hinge.

Fig.3

PART 4: Simulating the leaves

This looks a bit more complex but really it isn't. The most important thing is that the leaves are assigned to a group called "detatched" if the constraints are broken. The leaves behave differently if they are members of the group or not.

leaves_dop.png

What I did in the DOP network was first of all to check if the leaves are not connected anymore to their branch. We don't want them to be affected by the wind and turbulence while they are still attached to their branch. In theory they should and we could but in this simulation this is just going to bring instability and probably problems.

 

So what I did with the SOP solver "readGroups" that you can see in the picture was importing the constraints and the leaf geometry. Through the function "findattribval" I checked if the connected constraints (so the constraints which points have the same name attribute as the leaf) are broken. If they are I assigned a group to the packed leaf called "detatched")

All the forces you can see in the picture (popwind, popdrag, pop spin) are groing to affect just the leaves that are in this group by using the Group parameter that you can find at the top of each node. I used three different winds with different frequencies. I applied a spin to the falling leaves. All this forces are not active when the leaves are in the ground. I've also added a very strong drag to the leaves on the ground for making.

 

The collisions between leaves are very expensive. Since we already know the motion that they should follow because we simulated the branches first, I have disabled the collisions between leaves that are still attached to their branches. This made the simulation be really fast as it was running almost in real time.

This also solved some issues that to be solved required an higher substepping, so they were making the simulation even slower to get the same result. 

 

I have finally saved the leaves as points since I don't really need their geometry but just the informations of rotation and position. Then I just instanced the original leaves to this points.

bottom of page