The Tree System
Here you will learn how to use the tree system.
There’s a file in the demo-project named SimpleTreeTest. There’s a method in it named setupForester() where you can see how a tree system is set up. If you haven’t already done so, you might also want to check out the SimpleGrassTest.java file, because it contains a lot more information on certain other, important topics regarding the forester lib in general.
The basic procedure is this:
1) Create a Forester object, and initialize it.
2) Use it to create a tree-loader.
3) Use the treeloader to create a map-provider.
4) Use the treeloader to create one tree-layer for each type of tree.
5) Tweak everything until it fits your app.
6) Make sure you call forester.update() each frame.
There’s another file in the demo project called PhysicsTest.java. In that file you can see how collision-shapes are added to the trees.
When you create a tree-layer through treeLoader.createTreeLayer(Spatial spat, boolean usePhysics), you supply the model and a boolean whether or not to use physics. If you want to enable collision physics, look in that file how it’s done.
There are some general principles:
1) In order to enable collision physics at all, you first need to set up a physics space. There’s a great tutorial available in the tutorials section of the jME wiki: jme3:beginner:hello_physics.
2) If you want to enable physics with the forester, you need to provide the physics space to the Forester object. This is shown in the PhysicsTest.java file.
3) Once that is done, you need to provide a collision shape with your model, obviously. This can be done in several ways. You can do it through the jMP scene composer, or programatically.
When a model is supplied to a tree-layer, and physics is enabled, the model will be checked for collision shapes. The shape is then removed from the model, and added to the tree-layer instead.
The reason for this is that the trees are lumped together in a process called geometry-batching. It is commonly used to reduce the number of drawing-calls for groups of objects that are very similar.
What this means in practice is that your model is not just duplicated and spread out across the scene, they are in fact baked together into one single mesh (per “block”). This process is also used for collision shapes. They are all compounded into one large collision shape, then added to this newly created clump of vertices. Basically.
In short - there are a couple of instances when the collision physics system may fail:
If you do not supply a physics space to the forester, no physics will be enabled.
If you do not check “true” for enable physics when creating the tree-layer.
If you do not supply a collision mesh to the model.
At the core of tree placement is the class TreeData. It contains five floats representing a tree - x,y,z-coords, rotation, scale. This means a tree-layer just needs to keep one copy of the model, rather then many instances that differ only in transformation.
Tree data is stored in TreeDataLists, which are basically arraylists.
Using tree data
In the SimpleTreeTest.java is an example of how to set up a treeloader to use density maps to generate tree-data through the MapGrid data-provider. You do not have to worry about this stuff if you use density maps.
There will be info here on how to use the alternative DataGrid data-provider later.