// Method for generating a plant object
    public GameObject generatePlant(string leafColor)
    {
        // Clear segment list
        segments = new List <Segment>();

        startSegment(new Vector3(0f, 0f, 0f), 1, 1);

        // Grow segments
        for (int i = 0; i < growthCycles; i++)
        {
            // List of new nodes being made
            List <Node> newNodes = new List <Node>();

            // Grow each segment
            foreach (Segment seg in segments)
            {
                List <Node> segNodes = seg.getNodes();
                Bud         tipBud   = segNodes[segNodes.Count - 1].getTipBud();

                int tipBudAge = tipBud.getAge();

                // Check if bud should die -> if so then set bud to die
                // If it should not die, check if its already dead or should pause growth
                float deathValue = Random.value;
                if (deathValue <= tipBud.getDiePob() + (0.015f * tipBudAge))
                {
                    //string message = deathValue.ToString() + ", " + (tipBud.getDiePob() + (0.015f * tipBudAge)).ToString();
                    //Debug.Log(message);
                    tipBud.setDead();
                }
                if (!tipBud.getIsDead() && Random.value > tipBud.getPause())
                {
                    Node newNode = seg.grow();
                    newNodes.Add(newNode);
                }
            }

            //print(newNodes[0].getTipBud().getOrder());

            // Start new segments at new nodes' side buds
            foreach (Node newNode in newNodes)
            {
                foreach (Bud sidebud in newNode.getSideBuds())
                {
                    startSegment(sidebud.getPos(), sidebud.getAge(), sidebud.getOrder());
                }
            }
        }

        GameObject plant = new GameObject();

        plant.name = "Plant";

        // Create the segment objects
        foreach (Segment seg in segments)
        {
            GameObject segment = new GameObject();
            segment.name = "Segment";
            segment.AddComponent <MeshFilter>();
            segment.AddComponent <MeshRenderer>();
            segment.GetComponent <MeshFilter>().mesh = seg.getMesh();
            Renderer rend = segment.GetComponent <Renderer>();
            rend.material.color      = new Color(0.5f, 0.2f, 0.05f, 1.0f); // bark color
            segment.transform.parent = plant.transform;

            // Create leaf spheres at the end of each segment
            List <Node> segNodes  = seg.getNodes();
            Bud         segTipBud = segNodes[segNodes.Count - 1].getTipBud();
            if (segTipBud.getOrder() > 3)
            {
                GameObject leaf = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                leaf.transform.position = segTipBud.getPos();
                //leaf.transform.localScale = new Vector3(5f / segTipBud.getOrder(), 5f / segTipBud.getOrder(), 5f / segTipBud.getOrder());
                leaf.transform.localScale = new Vector3(2.5f, 2.5f, 2.5f);

                // Set leaf color
                Color color = new Color(1f, 1f, 1f);
                if (leafColor == "Green")
                {
                    color = new Color(0f, Random.value, 0f, 1f);                                     // light green
                }
                else if (leafColor == "Autumn")
                {
                    color = new Color(0.3f + Random.value, Random.value - 0.5f, 0f, 1f);     // autumn colors
                }
                else if (leafColor == "Sakura")
                {
                    float pinkRandom = Random.Range(0.5f, 0.8f);
                    color = new Color(1f, pinkRandom, pinkRandom, 1f);                                   // pink
                }
                leaf.GetComponent <Renderer>().material.color = color;
                leaf.transform.parent = plant.transform;
            }
        }

        return(plant);
    }
        // Grows the segment by adding a new node in the direction
        // of the tipNode's tipBud
        // Returns the new tipNode
        public Node grow()
        {
            Node tipNode  = nodes[nodes.Count - 1];
            Bud  tipBud   = tipNode.getTipBud();
            int  segOrder = tipBud.getOrder();
            int  age      = tipBud.getAge();

            Vector3 oldTipPos = tipBud.getPos();
            Vector3 growthDir = tipBud.getDir();

            // Get segment's vertices and triangles of mesh
            Vector3[] oldVerts = segMesh.vertices;
            int[]     oldTris  = segMesh.triangles;

            int oldVertLength = oldVerts.Length;
            int oldTriLength  = oldTris.Length;

            // Create new lists of vertices and tris
            Vector3[] newVerts = new Vector3[oldVertLength + 7];
            int[]     newTris  = new int[oldTriLength + (18 * 3)];

            // Check if segment is not just a cylinder base in mesh
            // If it is multiple cylinders, "cut off" the top cap of the mesh
            int stopCopyIndex = (oldVertLength > 7) ? oldTriLength - 18 - 1 : oldTriLength - 1;

            for (int v = 0; v < oldVertLength; v++)
            {
                newVerts[v] = oldVerts[v];
            }
            for (int t = 0; t <= stopCopyIndex; t++)
            {
                newTris[t] = oldTris[t];
            }

            // Calculate new vertices
            Vector3 T = growthDir.normalized;
            Vector3 V = (T.x == 1f) ? new Vector3(0f, 1f, 0f) : new Vector3(1f, 0f, 0f);
            Vector3 N = -1f * (Vector3.Cross(T, V)).normalized;
            Vector3 B = Vector3.Cross(T, N);

            Vector3 newTipPos = oldTipPos + (T * growthLength);

            //newVerts[oldVertLength] = newTipPos;
            //newVerts[oldVertLength + 1] = newTipPos + new Vector3(Mathf.Cos(Mathf.Deg2Rad * 0f), 0f, Mathf.Sin(Mathf.Deg2Rad * 0f));
            //newVerts[oldVertLength + 2] = newTipPos + new Vector3(Mathf.Cos(Mathf.Deg2Rad * 60f), 0f, Mathf.Sin(Mathf.Deg2Rad * 60f));
            //newVerts[oldVertLength + 3] = newTipPos + new Vector3(Mathf.Cos(Mathf.Deg2Rad * 120f), 0f, Mathf.Sin(Mathf.Deg2Rad * 120f));
            //newVerts[oldVertLength + 4] = newTipPos + new Vector3(Mathf.Cos(Mathf.Deg2Rad * 180f), 0f, Mathf.Sin(Mathf.Deg2Rad * 180f));
            //newVerts[oldVertLength + 5] = newTipPos + new Vector3(Mathf.Cos(Mathf.Deg2Rad * 240f), 0f, Mathf.Sin(Mathf.Deg2Rad * 240f));
            //newVerts[oldVertLength + 6] = newTipPos + new Vector3(Mathf.Cos(Mathf.Deg2Rad * 300f), 0f, Mathf.Sin(Mathf.Deg2Rad * 300f));

            newVerts[oldVertLength]     = newTipPos;
            newVerts[oldVertLength + 1] = newTipPos + (((N * Mathf.Cos(Mathf.Deg2Rad * 0f)) + (B * Mathf.Sin(Mathf.Deg2Rad * 0f))) / ((segOrder + age) * 1f / 2f));
            newVerts[oldVertLength + 2] = newTipPos + (((N * Mathf.Cos(Mathf.Deg2Rad * 60f)) + (B * Mathf.Sin(Mathf.Deg2Rad * 60f))) / ((segOrder + age) * 1f / 2f));
            newVerts[oldVertLength + 3] = newTipPos + (((N * Mathf.Cos(Mathf.Deg2Rad * 120f)) + (B * Mathf.Sin(Mathf.Deg2Rad * 120f))) / ((segOrder + age) * 1f / 2f));
            newVerts[oldVertLength + 4] = newTipPos + (((N * Mathf.Cos(Mathf.Deg2Rad * 180f)) + (B * Mathf.Sin(Mathf.Deg2Rad * 180f))) / ((segOrder + age) * 1f / 2f));
            newVerts[oldVertLength + 5] = newTipPos + (((N * Mathf.Cos(Mathf.Deg2Rad * 240f)) + (B * Mathf.Sin(Mathf.Deg2Rad * 240f))) / ((segOrder + age) * 1f / 2f));
            newVerts[oldVertLength + 6] = newTipPos + (((N * Mathf.Cos(Mathf.Deg2Rad * 300f)) + (B * Mathf.Sin(Mathf.Deg2Rad * 300f))) / ((segOrder + age) * 1f / 2f));

            int newVertsLength = newVerts.Length;

            // Calculate new tris
            // Sides
            newTris[oldTriLength]     = newVertsLength - 13;
            newTris[oldTriLength + 1] = newVertsLength - 12;
            newTris[oldTriLength + 2] = newVertsLength - 6;

            newTris[oldTriLength + 3] = newVertsLength - 12;
            newTris[oldTriLength + 4] = newVertsLength - 5;
            newTris[oldTriLength + 5] = newVertsLength - 6;

            newTris[oldTriLength + 6] = newVertsLength - 12;
            newTris[oldTriLength + 7] = newVertsLength - 11;
            newTris[oldTriLength + 8] = newVertsLength - 5;

            newTris[oldTriLength + 9]  = newVertsLength - 11;
            newTris[oldTriLength + 10] = newVertsLength - 4;
            newTris[oldTriLength + 11] = newVertsLength - 5;

            newTris[oldTriLength + 12] = newVertsLength - 11;
            newTris[oldTriLength + 13] = newVertsLength - 10;
            newTris[oldTriLength + 14] = newVertsLength - 4;

            newTris[oldTriLength + 15] = newVertsLength - 10;
            newTris[oldTriLength + 16] = newVertsLength - 3;
            newTris[oldTriLength + 17] = newVertsLength - 4;

            newTris[oldTriLength + 18] = newVertsLength - 10;
            newTris[oldTriLength + 19] = newVertsLength - 9;
            newTris[oldTriLength + 20] = newVertsLength - 3;

            newTris[oldTriLength + 21] = newVertsLength - 9;
            newTris[oldTriLength + 22] = newVertsLength - 2;
            newTris[oldTriLength + 23] = newVertsLength - 3;

            newTris[oldTriLength + 24] = newVertsLength - 9;
            newTris[oldTriLength + 25] = newVertsLength - 8;
            newTris[oldTriLength + 26] = newVertsLength - 2;

            newTris[oldTriLength + 27] = newVertsLength - 8;
            newTris[oldTriLength + 28] = newVertsLength - 1;
            newTris[oldTriLength + 29] = newVertsLength - 2;

            newTris[oldTriLength + 30] = newVertsLength - 8;
            newTris[oldTriLength + 31] = newVertsLength - 13;
            newTris[oldTriLength + 32] = newVertsLength - 1;

            newTris[oldTriLength + 33] = newVertsLength - 13;
            newTris[oldTriLength + 34] = newVertsLength - 6;
            newTris[oldTriLength + 35] = newVertsLength - 1;

            // New cap
            newTris[oldTriLength + 36] = newVertsLength - 7;
            newTris[oldTriLength + 37] = newVertsLength - 6;
            newTris[oldTriLength + 38] = newVertsLength - 5;

            newTris[oldTriLength + 39] = newVertsLength - 7;
            newTris[oldTriLength + 40] = newVertsLength - 5;
            newTris[oldTriLength + 41] = newVertsLength - 4;

            newTris[oldTriLength + 42] = newVertsLength - 7;
            newTris[oldTriLength + 43] = newVertsLength - 4;
            newTris[oldTriLength + 44] = newVertsLength - 3;

            newTris[oldTriLength + 45] = newVertsLength - 7;
            newTris[oldTriLength + 46] = newVertsLength - 3;
            newTris[oldTriLength + 47] = newVertsLength - 2;

            newTris[oldTriLength + 48] = newVertsLength - 7;
            newTris[oldTriLength + 49] = newVertsLength - 2;
            newTris[oldTriLength + 50] = newVertsLength - 1;

            newTris[oldTriLength + 51] = newVertsLength - 7;
            newTris[oldTriLength + 52] = newVertsLength - 1;
            newTris[oldTriLength + 53] = newVertsLength - 6;

            // Make new new tipBud and new tipNode and add it to segment's node list
            //Vector3 newTipDir = new Vector3((Random.value * 2f) - 1f, 1f + Random.value, (Random.value * 2f) - 1f);
            Vector3 newTipDir  = new Vector3(Random.value - 0.5f, 0.25f + Random.value, Random.value - 0.5f);
            Bud     newTipBud  = new Bud(newTipPos, newTipDir, age + 1, segOrder);
            Node    newTipNode = new Node(newTipPos, newTipBud);

            // Add a number of branches at the new node
            int numBranches = Random.Range(0, maxSideBudsPerNode);

            for (int i = 0; i < numBranches; i++)
            {
                Vector3 dir        = new Vector3((Random.value * 2f) - 1f, Random.value / 4f, (Random.value * 2f) - 1f);
                Vector3 sideBudPos = newTipPos - T;
                Bud     sideBud    = new Bud(sideBudPos, dir, age, segOrder + 1);
                newTipNode.addSideBud(sideBud);
            }

            nodes.Add(newTipNode);

            // Set the new vertices and triangles for the mesh
            segMesh.vertices  = newVerts;
            segMesh.triangles = newTris;
            segMesh.RecalculateNormals();

            return(newTipNode);
        }