Simulating a tree in Box2D is not as trivial as it sounds.
A tree will sway gently in the wind, spring back into shape after an impact, provide resistance, and break when enough force is applied.
The dynamics of a tree also change depending on where it is interacted with. For example, pushing a tree at the base has a different effect than pushing at the top.
Unfortunately, Box2D does not have a joint that can replicate this complicated behaviour out-of-the-box so we will have to make our own.
Building a Foundation
The core of a tree is the trunk so that is where we will begin. We know the trunk needs to be flexible so we can construct it from a stack of narrow boxes and connect them to each other with
RevoluteJoints. The base of the tree is connected to the static ground object so it will become rooted in place.
The result is a perfectly balanced chain standing end-to-end. While fun to play with, this “tree” is a tad bit flexible for its own good…
Luckily, Box2D provides an easy way to deal with this situation through
enableLimit. It allows us to restrict the rotation of a joint by specifying a
upperAngle (in radians).
By simply restricting the rotational movement we transform (as if my magic) a chain into a wilting tree! While still fun to play with it feels lifeless.
To get our wilted tree back to an equilibrium position we can use motors. In Box2D a motor provides a rotational force to a joint. Once enabled you simply specify a velocity and (optionally) a torque.
Motors provide a constant rotation with each timestep. For this reason, we do not set an initial velocity. If we do the tree will just curl in one direction. Instead, we determine the speed dynamically with each call of
We set the the speed of each joint to the negative of its angle of rotation.
At small angles there will be a small speed, at large angles there will be a large speed. This creates a nice smooth transition. The graph of this function is shown below.
Our wilted tree will now awkwardly right itself before swaying to a never-ending song only it can hear. While awesome, not exactly what we were going for.
Enter the FlexJoint
How can a linear velocity provide such jittery motion? The answer is torque. We are using an arbitrary value for torque which clearly is not enough to support the structure at large angles. The joints are slipping!
We can smooth out the transitions by dynamically calculating torque relative to the angle of the joint at every timestep.
When the angle of a joint is at its maximum value (in our case 30 degrees) we want our torque to be its highest. Essentially we are matching the torque with the amount of friction the joint must overcome. This balance allows our smooth velocity to work as intended.
Joints are each assigned individual torque multipliers. This normalizes the torque to be relative to the amount of load they are moving. The bottom joint must rotate the whole tree structure and will therefore require a higher max torque than the topmost joint which only needs to move one segment.
Our tree now flexes and returns upright naturally with only a few extra calculations.
The constants and algorithms used in our Flex Joints can be tweaked to provide accurate dynamics for different types of trees. Adding branches and overlaying graphics will come soon as the project develops.
Thanks for sticking around. Don’t beat around the bush, leaf your comments before you split.0