Procedural-Terrain / Procedural_Terrain / Procedural_Terrain.pde
Procedural_Terrain.pde
Raw
import controlP5.*;

ControlP5 cp5;
Button startB, smoothB;
Slider rowS, columnS, terrSizeS, heightS, snowS;
Toggle strokeT, colorT, blendT;
Textfield loadFileText;

Camera cam;
Terrain terrain;
PImage heightMap = null;

boolean generate;
boolean Stroke, isColor, blend;
int rows, columns;
float terrSize, heightMod, snowThresh;
String fileName;

void setup()
{
  size(1200, 800, P3D);
  cp5 = new ControlP5(this);

  startB = cp5.addButton("generate").setPosition(10, 80).setSize(100, 30);
  rowS = cp5.addSlider("rows").setPosition(10, 10).setSize(140, 10).setRange(1, 100);
  columnS = cp5.addSlider("columns").setPosition(10, 30).setSize(140, 10).setRange(1, 100);
  terrSizeS = cp5.addSlider("terrSize").setCaptionLabel("Terrain Size").setPosition(10, 50).setSize(140, 10).setRange(20, 50);
  loadFileText = cp5.addTextfield("fileName").setCaptionLabel("Load From File").setPosition(10, 120).setSize(210, 20);
  loadFileText.setAutoClear(false);
  strokeT = cp5.addToggle("Stroke").setPosition(260, 10).setSize(40, 20);
  colorT = cp5.addToggle("isColor").setCaptionLabel("color").setPosition(310, 10).setSize(40, 20);
  blendT = cp5.addToggle("blend").setPosition(360, 10).setSize(40, 20);
  heightS = cp5.addSlider("heightMod").setCaptionLabel("Height Modifier").setPosition(260, 50).setSize(140, 10).setRange(-5.0, 5.0);
  heightS.setValue(1);
  snowS = cp5.addSlider("snowThresh").setCaptionLabel("Snow Threshold").setPosition(260, 70).setSize(140, 10).setRange(1.0, 5.0);
  smoothB = cp5.addButton("smooth").setPosition(500, 10).setSize(100, 20);

  cam = new Camera(70);
  terrain = new Terrain(rows, columns, terrSize, heightMap);
}

void draw()
{
  background(0);
  perspective(radians(90.0f), width/(float)height, 0.1, 1000);
  cam.Update(0, 0);
  
  fileName = loadFileText.getText() + ".png";
  if (!fileName.equals(".png"))
    heightMap = loadImage(fileName);

  terrain.drawGrid(heightMod, snowThresh, Stroke, isColor, blend);

  perspective();
  camera();
}

void generate()
{
  background(0);
  terrain = new Terrain(rows, columns, terrSize, heightMap);
}

void smooth()
{
  ArrayList<PVector> prevVertices = terrain.vertices;
  for (int i = 0; i < prevVertices.size(); i++)
  {
    ArrayList<PVector> neighbors = new ArrayList<PVector>();
    neighbors.add(prevVertices.get(i));
    if (i == 0) // top left corner
    {
      neighbors.add(prevVertices.get(i + 1));
      neighbors.add(prevVertices.get(i + columns + 1));
    }
    else if (i == columns) // top right corner
    {
      neighbors.add(prevVertices.get(i - 1));
      neighbors.add(prevVertices.get(i + columns + 1));
    }
    else if (i == prevVertices.size() - columns - 1) // bottom left corner
    {
      neighbors.add(prevVertices.get(i + 1));
      neighbors.add(prevVertices.get(i - (columns + 1)));
    }
    else if (i == prevVertices.size() - 1) // bottom right corner //<>//
    {
      neighbors.add(prevVertices.get(i - 1));
      neighbors.add(prevVertices.get(i - (columns + 1)));
    }
    else if (i < columns && i != 0) // first row
    {
      neighbors.add(prevVertices.get(i - 1));
      neighbors.add(prevVertices.get(i + 1));
      neighbors.add(prevVertices.get(i + (columns + 1)));
    }
    else if (i < prevVertices.size() - 1 && i > prevVertices.size() - columns - 1) // last row
    {
      neighbors.add(prevVertices.get(i - 1));
      neighbors.add(prevVertices.get(i + 1));
      neighbors.add(prevVertices.get(i - (columns + 1)));
    }
    else if (i % (columns + 1) == 0 && i != 0 && i != prevVertices.size() - columns - 1) // first column
    {
      neighbors.add(prevVertices.get(i + 1));
      neighbors.add(prevVertices.get(i - (columns + 1)));
      neighbors.add(prevVertices.get(i + (columns + 1)));
    }
    else if (i % (columns + 1) == columns && i != columns + 1 && i != prevVertices.size() - 1) // last column
    {
      neighbors.add(prevVertices.get(i - 1));
      neighbors.add(prevVertices.get(i - (columns + 1)));
      neighbors.add(prevVertices.get(i + (columns + 1)));
    }
    else
    {
      neighbors.add(prevVertices.get(i - 1));
      neighbors.add(prevVertices.get(i + 1));
      neighbors.add(prevVertices.get(i - (columns + 1)));
      neighbors.add(prevVertices.get(i + (columns + 1)));
    }
    
    float average = 0;
    for (int j = 0; j < neighbors.size(); j++)
    {
      average += neighbors.get(j).y;
    }
    average /= neighbors.size();
    
    terrain.vertices.get(i).y = average;
  }
}

void mouseDragged()
{
  if (cp5.isMouseOver())
    return;
  float deltaX = (mouseX - pmouseX) * 0.15f;
  float deltaY = (mouseY - pmouseY) * 0.15f;
  cam.Update(deltaX, deltaY);
  perspective();
  camera();
}

void mouseWheel(MouseEvent event)
{
  float e = event.getCount();
  cam.Zoom(e);
}