package{ import flash.display.Sprite; import flash.events.*; import flash.utils.*; import org.papervision3d.core.geom.Lines3D; import org.papervision3d.core.geom.renderables.Vertex3D; import org.papervision3d.materials.special.LineMaterial; public class Tree extends Sprite { private var lm:LineMaterial = new LineMaterial(0x805500,1); public var subDivs:Array = [3, 9, 27, 81, 243];//this is an array of constants essentially containing the number of vertices for each level in sequence public var tVertices:Array = new Array(); public var v0:Vertex3D = new Vertex3D();//initial node start of line public var v1:Vertex3D = new Vertex3D(0,40,0);//initial node end of line - the first line is the trunk public var level:uint = 0;//create a variable to hold the level public var numNodes:uint = 0;//create a variable to hold the number of nodes on a level of the tree public var currNode:uint = 0;//create a variable to hold the value of the index of each vertex for a level of the tree public var lThick:uint = 10; //This is the thickness of the lines (branches) private var lines3D:Lines3D = new Lines3D(lm,"lines3d");//This is the container for a full tree of lines generated at runtime public var newLines3D:Lines3D = new Lines3D(lm,"newLines3D");//This is the container for lines which will go to the FLAR container for viewing each frame private var treeTimer:Timer = new Timer(150,500);// Create a new Timer object with a delay of 500 ms and a count of however many branches are required public function Tree():void { init(); } public function init():void { lines3D.addNewLine(20,v0.x,v0.y,v0.z,v1.x,v1.y,v1.z);//Add the trunk to the lines3D container tVertices[0] = v1; //initialises the first value in an tree array with the base vertex at the top of the trunk genLevels();//Calls the first iteration of a for loop (essentially three nested for loops) treeTimer.addEventListener(TimerEvent.TIMER,treeGrow);//adds the event listener to the timer to call the function that adds lines from the full lines3D to newLines3D treeTimer.start();//starts the timer...of course! } public function treeGrow(e:Event):void{ newLines3D.addLine(lines3D.lines[treeTimer.currentCount-1]);//takes lines one by one from lines3D and adds them to newLines3D on each tick of the timer } public function genLevels():void { for (level = 0; level < 5; level++){//level is the level of branches generated in the tree genBranches(); } } public function genBranches():void { for(numNodes = 0; numNodes < subDivs[level]; numNodes++){//makes sure that the function is called for every node at a certain level of the tree v0 = tVertices[currNode];//assigns the current vertex(node) to add branches to currNode++;//advance the node count for the next v0 vertex genNodes();//calls the function to generate three branches for the above node (v0) } } public function genNodes():void { for (var nodes:uint = 0; nodes < 3; nodes++) { lThick -= (level + 2);//sets the thickness of the branch based on the level of the tree we are creating var v1:Vertex3D = new Vertex3D();//creates a new vertex v1.x = v0.x + Math.floor(Math.random() * -30 + 30 / (level * 5 + 1)); //These are arbitrary values which generate random values which affect the tree growth and shape v1.y = v0.y + Math.floor(Math.random() * 20 + 10 + 20 / (level * 0.5 + 1));//they calculate the new x,y and z co-ordinates for a branch vertex (v1) v1.z = v0.z + Math.floor(Math.random() * -30 + 30 / (level * 5 + 1));//based on the previous node (v0) tVertices.push(v1);//adds the latest nodes generated, to the tVertices array. This is used after the iteration to acquire the new v0 lines3D.addNewLine(lThick,v0.x,v0.y,v0.z,v1.x,v1.y,v1.z);//adds the new line to the lines3D container } } } }