next up previous
Next: Results Up: Implementation Details Previous: Interference Between Polygons

Plant Growing Module

The plant growing module is responsible for the growth of the plants in the environment, and it makes use of the collision detection module for determining when a plant's growth will cause a collision with an object in the environment. Once it has the collision information from the collision detection module, it can make the plant react/grow appropriately.

  
Figure: Basic loop of the plant growing module

Figure gif shows the basic loop of the plant growing module. First, each plant is grown by calling the appropriate growing function. Currently there is only the one type of plant implemented (the vine type), however different types of plants with different generation and growth algorithms can be added. Each plant contains information about itself that defines it and allows it to be grown, and it contains pointers to the objects that actually produce its "physical" representation in the simulation environment. The values of the various data fields (containing the information ) of a plant define the state of the plant, and the growing functions are responsible for updating the state of the plant, ready for the next time frame. This updating also includes updating the objects that represent the plant, and preparing them to be passed to the collision detection module.

Once all the plants have been updated for the next time frame, the database containing all objects (environment objects and plant objects) is passed to the collision detection module. This module will check for any collisions occurring within this time frame (each time frame is defined as the interval ), and will return the time in this interval at which the database is in a valid state with no object interpenetrations occurring. If there is no contact, the time t, returned will be t = 1, otherwise the time returned will be and information about the objects in contact will also be returned.

The global state of the database where all objects are placed in the global reference, defines the scene at this point in time. If required, it is now written out to the output file ready to be processed and displayed (actually only the objects representing the plants are written out because the environment objects don't change and are thus the original .obj files).

Then the loop continues again with the next time frame, where the plants are grown taking into account the information passed back from the collision detection module.

A vine plant (refer to appendix gif plants.h for the type definitions), is made up of a list of growing vine segments, a list of stopped vine segments, a list of growing leaves, a list of stopped leaves, and a list of potential leaves. Vine segments are defined by a starting and ending point, and a scale (they also contain other information useful to creating new vine segments, and growing the vine segment). They are represented physically by a cylinder, with a transform to the global reference frame consisting of scaling, rotation to the required orientation, and movement to the correct position. The vine segment grows from its starting point, to its ending point, and this is achieved by changing the scaling applied to the cylinder at each time step. A vine segment's growth is over once it reaches its end point where it will have achieved its full size. A segment will also stop growing if it comes into contact with something else in the environment. Once it has stopped growing, the segment is moved to the list of stopped segments (which no longer undergo any changes), and an attempt at creating a new segment (starting from the end of the current one) is made. In addition, an entry is added to the potential leaf list, for a leaf to be grown from this segment at a later time period.

  
Figure: Transformations of leaves and cylinders

Leaves are handled in a similar matter --- with a point of attachment in the global frame, and a transformation that orientates it, and growth being achieved via scaling the object that represents the leaf (the object being made up of two back-to-back diamond shaped polygons).

Each vine segment has at most one leaf attached to it, and starts growing (if at all) after a user definable time period has passed since the vine segment stopped growing.

The creation of vine segments is based upon the method by Arvo [AK]. A vine plant is grown by the use of "Environment-Sensitive Automata" (ESA). These are particles that travel through the environment, sensing conditions and reacting according to a set of rules. The skeleton of the plant (upon which the vine segments and leaves are placed) is actually the path that the ESA have traversed through the environment.

The ESA sample the environment by casting a number of random rays, and decide upon their movement based upon the information returned. For example an ESA won't move in a certain direction if it's path is blocked by some obstacle, and it won't head in a direction if there is no surface to "cling" to there.

  
Figure: Outline of algorithm for growing vines

Figure gif is a pseudo code outline of the algorithm used to generate new vine segments. P_k is the end point of the previous segment, and is thus the starting point of this new segment; N_k is the normal of the nearby surface that P_k was generated from; ... are user definable constants.

The algorithm proceeds by first randomly sampling a number of directions in the tangent plane, until we can move to a new position Q without interference (for the purposes of the pseudo code, we can define a function Interfere which is capable of determining this fact). From the point Q we randomly sample directions, looking to create a new point P. Set Intersect to be a function that returns the normal N of the first surface the ray R hits, as well as the distance to this surface ; while Angle is a function that returns the angle between two given vectors.

At this new point P we test to see whether the angle formed between the new vine segment and the previous one from which this one is starting, isn't too large, giving rise to an unnatural looking vine. If it is, then this point P is ignored, and another one is tried. The purpose of the score is to rank the desirability of the trial points P. The three criteria a point is judged on are: closeness to Q, growth towards the Light source, and growth against the direction of gravity. Different growth characteristics can be obtained by changing the weightage applied to each of these three factors.

If the distance from Q to the surface is too large (greater than c_4 ) then a new point Q is tried, otherwise interference between P_k and P_k+1 is checked for. The function TestVineSeg makes sure that the addition of this new vine segment doesn't cause any problems with collision detection (it checks by using the function test4Intersection from the collision detection module). This is needed because new segments cannot start from nothing (a scale of zero) as the inverse transform isn't defined for a matrix with a scale of 0. Thus a new vine segment is added with a small initial size. This addition may violate the collision module's requirement that there be no intersection between any of the objects at t = 0.

 


: ESA movement through the environment

After it goes through all these tests, we now have a new segment which can be added to the vine plant's list of growing vine segments. The constant is the probability that no new segments will be grown from this one, while is the probability that this segment will have two segments grown from it. At this point the collision interest matrix is updated so that this new segment is tested against all other objects in the environment, except for the previous vine segment (the parent), that this one has grown from, and any sibling segment that shares the same parent.

Creation of a leaf involves randomly choosing a face from the parent vine segment, and then rotating it so that it lies along the normal of the chosen face. Then the leaf is rotated again, such that the normal of the leaf is best aligned towards the light source, and then the leaf is finally attached at one of the points on the face. Again, addition of this leaf must be checked to see whether it will cause problems in its current position. If it does, then the leaf is rotated slightly and checked again with this process being carried out times. If this fails, then another face is randomly selected and the testing of the placement of the leaf continues. The program will give up after trying random faces of the vine segment, so this leaf isn't added. Again, the collision interest matrix is updated so the leaf is tested against all other objects except for the vine segment it is attached to.

The values of these growth variables (including the position of the light source, the direction of gravity, delay before growing a leaf and various other factors) are set in the growth configuration file (see appendix gif for details).



next up previous
Next: Results Up: Implementation Details Previous: Interference Between Polygons



William Fang
Mon Dec 4 14:14:02 EST 1995