Procedural-Terrain / Procedural_Terrain / Terrain.pde
Terrain.pde
Raw
class Terrain
{
  ArrayList<PVector> vertices;
  ArrayList<Integer> triIndexes;
  PImage heightMap;

  int rows, cols;
  float gridSize;

  color snow = color(255, 255, 255);
  color grass = color(143, 170, 64);
  color rock = color(135, 135, 135);
  color dirt = color(160, 126, 84);
  color water = color(0, 75, 200);
  color vertColor = 0;

  Terrain(int _rows, int _cols, float terrSize, PImage image)
  {
    vertices = new ArrayList<PVector>();
    triIndexes = new ArrayList<Integer>();
    heightMap = image;

    rows = _rows;
    cols = _cols;
    gridSize = terrSize;

    for (float i = -(gridSize / 2); i < (gridSize / 2) + 0.0001; i += (gridSize / rows))
    {
      for (float j = -(gridSize / 2); j < (gridSize / 2) + 0.0001; j += (gridSize / cols))
      {
        vertices.add(new PVector(j, 0, i));
      }
    }

    for (int i = 0; i < rows; i++)
    {
      for (int j = 0; j < cols; j++)
      {
        int startIndex = i * (cols + 1) + j;
        triIndexes.add(startIndex);
        triIndexes.add(startIndex + 1);
        triIndexes.add(startIndex + cols + 1);

        triIndexes.add(startIndex + 1);
        triIndexes.add(startIndex + cols + 2);
        triIndexes.add(startIndex + cols + 1);
      }
    }

    if (heightMap != null)
    {
      for (int i = 0; i <= rows; i++)
      {
        for (int j = 0; j <= cols; j++)
        {
          int xIndex = (int) map(j, 0, cols + 1, 0, heightMap.width);
          int yIndex = (int) map(i, 0, rows + 1, 0, heightMap.height);
          color c = heightMap.get(xIndex, yIndex);
          float heightFromColor = map(red(c), 0, 255, 0, 1.0);
          int vertIndex = i * (cols + 1) + j;
          vertices.get(vertIndex).y = heightFromColor;
        }
      }
    }
  }

  void drawGrid(float heightMod, float snowThresh, boolean Stroke, boolean isColor, boolean blend)
  {
    if (Stroke)
    {
      strokeWeight(1);
      stroke(0);
    } 
    else
      noStroke();

    beginShape(TRIANGLES);
    for (int i = 0; i < triIndexes.size(); i++)
    {
      int vertIndex = triIndexes.get(i);
      PVector vert = vertices.get(vertIndex);

      if (heightMap != null && isColor)
      {
        float relativeHeight = abs(vert.y) * heightMod / snowThresh;
        float ratio = 0;
        if (relativeHeight < 0.2)
        {
          if (blend)
          {
            ratio = relativeHeight / 0.2;
            vertColor = lerpColor(water, dirt, ratio);
          } else
            vertColor = water;
        } else if (relativeHeight < 0.4)
        {
          if (blend)
          {
            ratio = (relativeHeight - 0.2) / 0.2;
            vertColor = lerpColor(dirt, grass, ratio);
          } else
            vertColor = grass;
        } else if (relativeHeight < 0.8)
        {
          if (blend)
          {
            ratio = (relativeHeight - 0.4) / 0.4;
            vertColor = lerpColor(grass, rock, ratio);
          } else
            vertColor = rock;
        } else
        {
          if (blend)
          {
            ratio = (relativeHeight - 0.8) / 0.2;
            vertColor = lerpColor(rock, snow, ratio);
          } else
            vertColor = snow;
        }
      } else
        vertColor = color(255);

      fill(vertColor);
      vertex(vert.x, vert.y * -heightMod, vert.z);
    }
    endShape();
  }
}