//This is where heightmap data is generated for a single vertex
    //The outer loop iterates through each layer, the inner loop iterates
    //through every pass within each layer.
    //x - the x coordinate of the vertex which we need height data for
    //y - the y coordinate of the vertex which we need height data for
    //colorizeVertex - only send color data if this is true, setting this
    //to false allows for getting height data for a single vertex more than
    //once without sending trash color data into the globalColor list
    public float getNoise(float x, float z, bool colorizeVertex)
    {
        //create an array with a size equalling the number of layers
        //this will store the base heights for the vertex for each layer
        float[] origHeight = new float[scale.Count + 1];

        //a way of keeping up with which layer is ultimately displayed in the mesh
        int displayedLayer = 0;

        //We start out with the base layer's color as our final color
        //if the next layer's noise data is higher than the base layer,
        //the color will change to the next layer up.
        //it will continue to bubble up as long as the next layer is higher
        Color finalColor = colorOne [0];

        //initialize a final height which will ultimately be passed to the vertex
        //if a layer's noise data is higher than finalHeight, finalHeight will
        //get that value, otherwise it stays the same, that way the tallest layer
        //at that point of the map gets sent to the vertex
        float finalHeight = 0;

        //will compensate for overheightening with every layer/pass
        float minusScale = 0;

        //The outer loop: iterates through each layer
        for (int layer = 0; layer < scale.Count; layer++)
        {
            //sets a base height for this layer with the brownianNoise method using the height
            //and scale parameters of the layer and its zeroeth pass
            origHeight [layer] = (brownianNoise((x + TerrainRandomizer.getTwoRand(seed [layer] [0]) [0]) / scale [layer] [0], (z + TerrainRandomizer.getTwoRand(seed [layer] [0]) [1]) / scale [layer] [0]) * height [layer] [0]) - offset [layer];

            //aligns he lowest point of the layer with zero by multiplying by masterOffsetMultiplier
            origHeight [layer] -= masterOffsetMultiplier * height [layer] [0];

            //doesn't allow layer to be taller than heightMax parameter
            if (origHeight [layer] > heightMax [layer] [0])
            {
                origHeight [layer] = heightMax [layer] [0];
            }

            //The inner loop: iterates through each pass within each layer of the outer loop
            //Note: this starts at 1, that's because pass 0 is essentially the outer loop's
            //initialization of the layer
            for (int pass = 1; pass < scale[layer].Count; pass++)
            {
                //gets noise for the pass using the passes unique parameters to be added
                //to the layer's base height. This will be repeated for each of the layer's passes
                float noise = (brownianNoise((x + TerrainRandomizer.getTwoRand(seed [layer] [pass]) [0]) / scale [layer] [pass], (z + TerrainRandomizer.getTwoRand(seed [layer] [pass]) [1]) / scale [layer] [pass]) * height [layer] [pass]);

                //the noise is added to the height
                origHeight [layer] += noise - masterOffsetMultiplier * height [layer] [pass];

                //minusScale is incremented for each time this is done and will be subtracted from
                //the total height before it's returned
                minusScale += scale [layer] [pass];
            }

            //Now that all the passes have been iterated over, we check to see if the height generated is
            //above the minimum height for the layer and that it's higher than anything generated so far
            //for previous layers. If the latter is false, the current layer at this point on the map
            //is underneath a previous layer and we default to the previous finalHeight value. If the
            //height didn't meet the minimum requirement for the layer, finalHeight also won't be affected
            //and this layer's data won't represent the height/color for the vertex.
            if (origHeight [layer] > heightMin [layer] [0] && origHeight [layer] > finalHeight)               //supporting only pass 0 now

            //The previously mentioned requirements were met, so the height and color both get pushed up.
            //They could bubble up higher if the succeding layers fit the same requirements on the next
            //iteration of the outer loop(layers)
            //finalColor = (colorOne [layer] + colorTwo[layer]) /
            //	(height[layer][0] /origHeight[layer]); //CURRENTLY NOT ACCOUNTING FOR HEIGHT ADDED BY PASSES OVER THE BASE LEVEL
            {
                finalColor = Color.Lerp(colorOne [layer], colorTwo [layer], (float)((height [layer] [0] - offset [layer]) / (origHeight [layer] * 10)));
                //Debug.Log("color ratio" + (height[layer][0] /(origHeight[layer] *10)));

                finalHeight    = origHeight [layer];
                displayedLayer = layer;
            }

            //Sends diagnostic info to heightDiagnostic
            heightDiagnostic.recordHeight(layer, origHeight [layer]);
        }

        //sends which layer was displayed for this point on the map to the heightDiagnostic class
        heightDiagnostic.recordDisplayedLayer(displayedLayer);

        //If colorizeVertex was set to true, add the final color data to the globalColor list
        if (colorizeVertex)
        {
            //We add the resulting vertex color to a list that will ultimately store
            //three colors to be averaged and then applied evenly to all three vertices
            //additionally, we add the displayed layer to a second list so we know which
            //layer each color belongs to. This will only take place at borders between layers
            colorsForTriangle.Add(finalColor);
            layersForTriangle.Add(displayedLayer);

            //If all three colors were added to the above list, we can go ahead and average them if necessary
            if (colorsForTriangle.Count == 3)
            {
                //if all the colors are equal, this is not a border between layers,
                //we'll just send in the raw colors
                if (colorsForTriangle [0] == colorsForTriangle [1] &&
                    colorsForTriangle [1] == colorsForTriangle [2])
                {
                    globalColor.Add(colorsForTriangle [0]);
                    globalColor.Add(colorsForTriangle [1]);
                    globalColor.Add(colorsForTriangle [2]);
                }

                //this triangle's verteces belong to more than one layer, therefore we know we're at a border
                //now we begin replacing the colors of the lower layers with averages of the highest layer
                else
                {
                    //list of colors that are within the topmost layer displayed in this triangle
                    List <Color> colorsInTopLayer = new List <Color> ();

                    //temp variable holding highest layer displayed of three vertices, assigned with loop
                    int highest = 0;
                    foreach (int element in layersForTriangle)
                    {
                        if (element > highest)
                        {
                            highest = element;
                        }
                    }

                    //add all colors within the highest layer to colorsInTopLayer
                    for (int i = 0; i < 3; i++)
                    {
                        if (layersForTriangle [i] == highest)
                        {
                            colorsInTopLayer.Add(colorsForTriangle [i]);
                        }
                    }

                    //this will be the average of all colors contained in the uppermost layer of the triangle
                    Color colorAverage = colorsInTopLayer [0];

                    //add up colors in the highest layer
                    for (int i = 1; i < colorsInTopLayer.Count; i++)
                    {
                        colorAverage += colorsInTopLayer [i];
                    }

                    //now divide added colors by the number of colors added together
                    colorAverage /= colorsInTopLayer.Count;

                    //find out which colors arent in the uppermost layer and replace
                    //them with the average we just made, then submit color
                    for (int i = 0; i < 3; i++)
                    {
                        if (layersForTriangle [i] != highest)
                        {
                            colorsForTriangle [i] = colorAverage;
                        }

                        globalColor.Add(colorsForTriangle [i]);
                    }
                }

                //now we clear the temporary list of colors for the next batch/triangles
                colorsForTriangle.Clear();
                layersForTriangle.Clear();
            }

            //Debug.Log ("count: " +colorsForTriangle.Count);
        }

        //finally, return the ultimate finalHeight with minusScale subtracted
        return(finalHeight - minusScale / 10);
    }
 //Alternate addLayer method that automatically generates random seed for that layer
 public void addLayer(float scale, float height, float heightMax, float heightMin, float offset, Color colorOne, Color colorTwo)
 {
     addLayer(scale, height, heightMax, heightMin, offset, colorOne, colorTwo, TerrainRandomizer.getMasterSeed());
 }
 //Alternate addLayer method that automatically adds random seed for that layer
 public void addPass(int layer, float scale, float height, float heightMax, float heightMin)
 {
     addPass(layer, scale, height, heightMax, heightMin, TerrainRandomizer.getMasterSeed());
 }
 //Alternate creation method excluding seed input parameter, uses master seed instead
 public void CreateTerrainHeightGenerator(float scale, float height, float heightMax, float heightMin, Color colorOne, Color colorTwo)
 {
     CreateTerrainHeightGenerator(scale, height, heightMax, heightMin, colorOne, colorTwo, TerrainRandomizer.getMasterSeed());
 }