Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import peasy.*;
- float tileSize = 5;
- int worldWidth;
- int worldLength;
- float waterInCloud;
- boolean raining;
- ArrayList<Tile> tiles;
- PeasyCam cam;
- long bNoise;
- long pNoise;
- long sNoise;
- long tNoise;
- long oNoise;
- void setup() {
- fullScreen(P3D);
- initUI();
- generate();
- float cameraZ = ((height/2.0) / tan(PI*60.0/360.0));
- perspective(PI/3.0, (width/1.0)/(height/1.0), 0.1, cameraZ*10.0);
- cam = new PeasyCam(this, 500);
- cam.lookAt(worldWidth*tileSize/2.0, 0, worldLength*tileSize/2.0);
- cam.setDistance(1000);
- cam.setMinimumDistance(-100);
- cam.setRotations(cam.getRotations()[0], 0, 0);
- worldWidth = 100;
- worldLength = 10;
- }
- void draw() {
- translate(width/2 - ((worldWidth*tileSize)/2.0), height/2 +((worldLength*tileSize)/2.0), 0);
- translate(0, ((worldLength*tileSize)/2.0), 0);
- cam.setRotations(cam.getRotations()[0], cam.getRotations()[1], cam.getRotations()[2]);
- if (!raining) {
- if (waterInCloud >= worldWidth*worldLength*6) {
- raining = true;
- }
- }
- for (Tile t : tiles) {
- t.move();
- }
- background(200);
- lights();
- for (Tile t : tiles) {
- t.show();
- }
- for (Tile t : tiles) {
- t.calculate();
- }
- cam.setActive(true);
- showUI();
- dragging = false;
- }
- void generate() {
- worldWidth = int(wWidth.value);
- worldLength = int(wDepth.value);
- rainfallRate = new Slider(0.01, wWidth.value*wDepth.value*6, wWidth.value*wDepth.value*6/500.0, width/4.0, height/40.0, width/4.0, height/40.0*38.0, true, "Rainfall Rate", false);
- bNoise = int(random(1000000));
- pNoise = int(random(1000000));
- sNoise = int(random(1000000));
- tNoise = int(random(1000000));
- oNoise = int(random(1000000));
- waterInCloud = worldWidth*worldLength*8;
- tiles = new ArrayList<Tile>();
- for (int i = 0; i < worldWidth; i++) {
- for (int j = 0; j < worldLength; j++) {
- noiseSeed(bNoise);
- float bn = noise(i/20.0, j/20.0)*200*tileSize/2.0;
- noiseSeed(pNoise);
- float pn = noise(i/10.0, j/10.0)*50*tileSize/3.0;
- noiseSeed(sNoise);
- float sn = noise(i/5.0, j/5.0)*25*tileSize/4.0;
- noiseSeed(tNoise);
- float tn = noise(i/2.5, j/2.5)*12.5*tileSize/5.0;
- noiseSeed(oNoise);
- float on = noise(i/1.25, j/1.25)*6.25*tileSize/6.0;
- tiles.add(new Tile(i, j, bn, pn, sn, tn, on));
- }
- }
- }
- boolean toggle = false;
- boolean dragging;
- float angleX = 0;
- float angleY = 0;
- void keyPressed() {
- if (key == 'w' || key == 'W') {
- toggle = !toggle;
- }
- if (keyCode == ENTER) {
- generate();
- }
- }
- void mouseDragged() {
- dragging = true;
- }
- Tile getLowestWaterNeighbor(Tile t) {
- Tile temp = t;
- float minHeight = 100000;
- for (Tile ts : tiles) {
- if ((ts.x == t.x-1 && ts.y == t.y)
- || (ts.x == t.x+1 && ts.y == t.y)
- || (ts.x == t.x && ts.y == t.y-1)
- || (ts.x == t.x && ts.y == t.y+1)
- || (ts.x == t.x && ts.y == t.y)) {
- if (ts.totalHeightWithWater() < minHeight) {
- minHeight = ts.totalHeightWithWater();
- temp = ts;
- }
- }
- }
- return temp;
- }
- Tile getLowestLandNeighbor(Tile t) {
- Tile temp = null;
- float minHeight = 100000;
- for (Tile ts : tiles) {
- if (ts.x >= t.x-1 && ts.x <= t.x+1 && ts.y >= t.y-1 && ts.y <= t.y+1) {
- if (ts.totalHeightWithOutWater() < minHeight) {
- minHeight = ts.totalHeightWithOutWater();
- temp = ts;
- }
- }
- }
- return temp;
- }
- float log10(float x) {
- return (log(x) / log(10));
- }
- class Tile {
- int x;
- int y;
- float sBedrock;
- float sParentrock;
- float sSubsoil;
- float sTopsoil;
- float sOrganic;
- float tBedrock;
- float tParentrock;
- float tSubsoil;
- float tTopsoil;
- float tOrganic;
- float bedrock;
- float parentrock;
- float subsoil;
- float topsoil;
- float organic;
- float water;
- float waterToAdd;
- float waterToSubtract;
- float organicToAdd;
- float organicToSubtract;
- float topsoilToAdd;
- float topsoilToSubtract;
- float subsoilToAdd;
- float subsoilToSubtract;
- float parentrockToAdd;
- float parentrockToSubtract;
- Tile(int x_, int y_, float b_, float p_, float s_, float t_, float o_) {
- x=x_;
- y=y_;
- sBedrock = b_;
- sParentrock = p_;
- sSubsoil = s_;
- sTopsoil = t_;
- sOrganic = o_;
- bedrock = b_;
- parentrock = p_;
- subsoil = s_;
- topsoil = t_;
- organic = o_;
- water = 0;
- }
- void show() {
- float cumulativeTranslation = 0;
- noStroke();
- translate(x*tileSize, 0, y*tileSize);
- translate(0, -bedrock/2, 0);
- cumulativeTranslation += -bedrock/2;
- if (bedrock > 0) {
- fill(80, 80, 80);
- box(tileSize, bedrock, tileSize);
- }
- translate(0, -bedrock/2-parentrock/2, 0);
- cumulativeTranslation += -bedrock/2-parentrock/2;
- if (parentrock > 0) {
- fill(120, 120, 120);
- box(tileSize, parentrock, tileSize);
- }
- translate(0, -parentrock/2-subsoil/2, 0);
- cumulativeTranslation += -parentrock/2-subsoil/2;
- if (subsoil > 0) {
- fill(172, 107, 83);
- box(tileSize, subsoil, tileSize);
- }
- translate(0, -subsoil/2-topsoil/2, 0);
- cumulativeTranslation += -subsoil/2-topsoil/2;
- if (topsoil > 0) {
- fill(118, 96, 83);
- box(tileSize, topsoil, tileSize);
- }
- translate(0, -topsoil/2-organic/2, 0);
- cumulativeTranslation += -topsoil/2-organic/2;
- if (organic > 0) {
- fill(108, 147, 92);
- box(tileSize, organic, tileSize);
- }
- translate(0, -organic/2-water/2, 0);
- cumulativeTranslation += -organic/2-water/2;
- if (water > 0) {
- fill(100, 200, 255, 100);
- box(tileSize, -water, tileSize);
- }
- translate(x*-tileSize, -cumulativeTranslation, y*-tileSize);
- }
- float totalHeightWithWater() {
- return bedrock + parentrock + subsoil + topsoil + organic + water;
- }
- float totalHeightWithOutWater() {
- return bedrock + parentrock + subsoil + topsoil + organic;
- }
- void calculate() {
- //if (!center) {
- // if (toggle) {
- // if (intermittent) {
- // if (frameCount % 100 < 25) {
- // if (random(worldWidth*worldLength) < worldWidth*worldLength/5.0) {
- // water += 1;
- // }
- // }
- // } else {
- // if (random(worldWidth*worldLength) < worldWidth*worldLength/5.0) {
- // water += 1;
- // }
- // }
- // }
- //} else {
- // if (x == worldWidth/2 && y == worldLength/2) {
- // water += 5;
- // }
- //}
- if (toggle) {
- if (raining) {
- if (random(worldWidth*worldLength) < worldWidth*worldLength/100.0) {
- float deduct = min(waterInCloud, rainfallRate.value);
- water += deduct;
- waterInCloud -= deduct;
- if (waterInCloud == 0) {
- raining = false;
- }
- }
- }
- }
- Tile temp = getLowestWaterNeighbor(this);
- float movingWater = min(5, water, (totalHeightWithWater()-temp.totalHeightWithWater())/2.0);
- temp.waterToAdd += movingWater;
- waterToSubtract -= movingWater;
- if (temp.totalHeightWithOutWater() < totalHeightWithOutWater()) {
- float movingLand = min(movingWater, (totalHeightWithOutWater()-temp.totalHeightWithOutWater())/2.0);
- float oVal = constrain(4*erosionRate.value, 0, 4);
- float tVal = constrain(2*erosionRate.value, 0, 4);
- float sVal = constrain(1*erosionRate.value, 0, 4);
- float pVal = constrain(0.5*erosionRate.value, 0, 4);
- float movingOrganic = min(oVal, organic, movingLand/(5/oVal));
- movingLand = max(movingLand - movingOrganic*(5/oVal), 0);
- temp.organicToAdd += movingOrganic;
- organicToSubtract -= movingOrganic;
- float movingTopSoil = min(tVal, topsoil, movingLand/(5/tVal));
- movingLand = max(movingLand - movingTopSoil*(5/tVal), 0);
- temp.topsoilToAdd += movingTopSoil;
- topsoilToSubtract -= movingTopSoil;
- float movingSubSoil = min(sVal, subsoil, movingLand/(5/sVal));
- movingLand = max(movingLand - movingSubSoil*(5/sVal), 0);
- temp.subsoilToAdd += movingSubSoil;
- subsoilToSubtract -= movingSubSoil;
- float movingParentRock = min(pVal, parentrock, movingLand/(5/pVal));
- movingLand = max(movingLand - movingParentRock*(5/pVal), 0);
- temp.parentrockToAdd += movingParentRock;
- parentrockToSubtract -= movingParentRock;
- }
- }
- void move() {
- water += waterToAdd + waterToSubtract;
- float evaporate = min(water, evaporationRate.value);
- water -= evaporate;
- waterInCloud += evaporate;
- organic += organicToAdd + organicToSubtract;
- topsoil += topsoilToAdd + topsoilToSubtract;
- subsoil += subsoilToAdd + subsoilToSubtract;
- parentrock += parentrockToAdd + parentrockToSubtract;
- waterToAdd = 0;
- waterToSubtract = 0;
- organicToAdd = 0;
- organicToSubtract = 0;
- topsoilToAdd = 0;
- topsoilToSubtract = 0;
- subsoilToAdd = 0;
- subsoilToSubtract = 0;
- parentrockToAdd = 0;
- parentrockToSubtract = 0;
- if (water == 0) {
- adjustLayerDry();
- } else {
- adjustLayerWet();
- }
- }
- void adjustLayerDry() {
- float cTotal = parentrock + subsoil + topsoil + organic;
- if (cTotal > 0) {
- float oTotal = sParentrock + sSubsoil + sTopsoil + sOrganic;
- //float tbP = sBedrock / oTotal;
- float tpP = sParentrock / oTotal;
- float tsP = sSubsoil / oTotal;
- float ttP = sTopsoil / oTotal;
- float toP = sOrganic / oTotal;
- //float cB = (bedrock / (totalHeightWithOutWater()-bedrock));
- float cP = parentrock / cTotal;
- float cS = subsoil / cTotal;
- float cT = topsoil / cTotal;
- float cO = organic / cTotal;
- //bedrock = (cB + (tbP-cB) * 0.01) * (totalHeightWithOutWater()-bedrock);
- parentrock = (cP + (tpP-cP) * 0.001) * cTotal;
- subsoil = (cS + (tsP-cS) * 0.001) * cTotal;
- topsoil = (cT + (ttP-cT) * 0.001) * cTotal;
- organic = (cO + (toP-cO) * 0.001) * cTotal;
- }
- }
- void adjustLayerWet() {
- float cTotal = parentrock + subsoil + topsoil + organic;
- if (cTotal > 0) {
- float oTotal = sParentrock + sSubsoil + sTopsoil;
- //float tbP = sBedrock / oTotal;
- float tpP = sParentrock / oTotal;
- float tsP = sSubsoil / oTotal;
- float ttP = sTopsoil / oTotal;
- float toP = 0;
- //float cB = (bedrock / (totalHeightWithOutWater()-bedrock));
- float cP = parentrock / cTotal;
- float cS = subsoil / cTotal;
- float cT = topsoil / cTotal;
- float cO = organic / cTotal;
- //bedrock = (cB + (tbP-cB) * 0.01) * (totalHeightWithOutWater()-bedrock);
- parentrock = (cP + (tpP-cP) * 0.001) * cTotal;
- subsoil = (cS + (tsP-cS) * 0.001) * cTotal;
- topsoil = (cT + (ttP-cT) * 0.001) * cTotal;
- organic = (cO + (toP-cO) * 0.001) * cTotal;
- }
- }
- }
- Slider rainfallRate;
- Slider evaporationRate;
- Slider erosionRate;
- Slider wWidth;
- Slider wDepth;
- class Slider {
- float minValue;
- float maxValue;
- float value;
- float w;
- float h;
- float innerW;
- PVector pos;
- boolean log;
- SliderKnob sk;
- String name;
- boolean round;
- color col;
- Slider(float miV, float maV, float cV, float w_, float h_, float x, float y, boolean log_, String s, boolean round_) {
- round = round_;
- minValue = min(miV, maV);
- maxValue = max(miV, maV);
- value = constrain(cV, min(minValue, maxValue), max(minValue, maxValue));
- println(value);
- w = w_;
- h = h_;
- pos = new PVector(x, y);
- log = log_;
- innerW = w - h;
- float skX = 0;
- if (log) {
- skX = (log(1+abs(value-minValue)) / log(1+abs(maxValue-minValue)))*w + pos.x - w/2.0-(w-innerW)/2;
- } else {
- skX = ((value-minValue) / (maxValue-minValue))*(w-h) + pos.x - innerW/2.0;
- }
- sk = new SliderKnob(skX, pos.y, h);
- name = s;
- col = color(0);
- }
- void show() {
- if (mouseOver()) cam.setActive(false);
- listenDrag();
- noFill();
- stroke(0);
- strokeWeight(2);
- rect(pos.x, pos.y, w, h);
- fill(0);
- noStroke();
- rect(pos.x, pos.y, w-h, h/2.0);
- stroke(col);
- fill(col);
- textAlign(LEFT, CENTER);
- textSize(h);
- String valueString;
- if (round) {
- valueString = "" + int(value);
- } else {
- valueString = "" + round(value*1000)/1000.0;
- }
- text(name + ": " + valueString, pos.x - innerW / 2.0, pos.y - h*1.5);
- sk.show();
- }
- void listenDrag() {
- if (dragging && mouseOver()) {
- sk.pos.x = constrain(mouseX, pos.x - innerW/2.0, pos.x + innerW/2.0);
- value = newValue();
- }
- }
- float newValue() {
- if (log) {
- float xMin = pos.x-innerW/2.0;
- float xMax = pos.x+innerW/2.0;
- float xDiff = xMax - xMin;
- float screenXPerc = (sk.pos.x-xMin)/(xMax-xMin);
- float logMin = log10(minValue + 1);
- float logMax = log10(maxValue + 1);
- float logDiff = logMax - logMin;
- float logCurrent = logDiff * screenXPerc;
- float finalLog = logMin + logCurrent;
- if (round) {
- return round(pow(10, finalLog)-1);
- } else {
- return pow(10, finalLog)-1;
- }
- } else {
- float perc = (sk.pos.x - (pos.x-innerW/2.0))/innerW;
- if (round) {
- return round((maxValue - minValue)*perc + minValue);
- } else {
- return (maxValue - minValue)*perc + minValue;
- }
- }
- }
- boolean mouseOver() {
- return (mouseX > pos.x - w/2.0) && (mouseX < pos.x + w/2.0) && (mouseY > pos.y - h/2.0) && (mouseY < pos.y + h/2.0);
- }
- }
- class SliderKnob {
- PVector pos;
- float r;
- SliderKnob(float x, float y, float r_) {
- pos = new PVector(x, y);
- r = r_;
- }
- void show() {
- fill(127);
- stroke(0);
- strokeWeight(2);
- ellipse(pos.x, pos.y, r, r);
- }
- }
- void initUI() {
- rectMode(CENTER);
- wWidth = new Slider(1, 400, 100, width/8.0, height/40.0, width/12.0, height/40.0*32.0, true, "World Width", true);
- wDepth = new Slider(1, 100, 10, width/8.0, height/40.0, width/12.0, height/40.0*35.0, true, "World Depth", true);
- rainfallRate = new Slider(0.01, wWidth.value*wDepth.value*6, wWidth.value*wDepth.value*6/500.0, width/4.0, height/40.0, width/4.0, height/40.0*38.0, true, "Rainfall Rate", false);
- evaporationRate = new Slider(0.001, 5, 0.2, width/4.0, height/40.0, width/2.0, height/40.0*38.0, true, "Evaporation Rate", false);
- erosionRate = new Slider(0.001, 4, 0.5, width/4.0, height/40.0, width/4.0*3.0, height/40.0*38.0, true, "Erosion Rate", false);
- }
- void showUI() {
- cam.beginHUD();
- float minWH = min(width, height);
- float maxRVal = minWH*0.13;
- float maxArea = worldWidth*worldLength*6;
- float maxR = sqrt(maxArea/PI);
- float currentR = sqrt(waterInCloud/PI);
- float currentRVal = maxRVal / maxR * currentR;
- fill(255);
- noStroke();
- ellipse(width*0.9, height*0.1, currentRVal, currentRVal);
- stroke(0);
- strokeWeight(minWH/500.0);
- noFill();
- ellipse(width*0.9, height*0.1, maxRVal*1.05, maxRVal*1.05);
- rainfallRate.show();
- evaporationRate.show();
- erosionRate.show();
- if (wWidth.value * wDepth.value > 20000) {
- wWidth.col = color(120, 0, 120);
- wDepth.col = color(120, 0, 120);
- } else if (wWidth.value * wDepth.value > 10000) {
- wWidth.col = color(220, 25, 25);
- wDepth.col = color(220, 25, 25);
- } else if ((wWidth.value * wDepth.value > 4000)) {
- wWidth.col = color(170, 170, 50);
- wDepth.col = color(170, 170, 50);
- } else {
- wWidth.col = color(50, 150, 50);
- wDepth.col = color(50, 150, 50);
- }
- wWidth.show();
- wDepth.show();
- fill(255, 127);
- stroke(0);
- rectMode(CENTER);
- rect(width/12.0, height/2, width/7, height/3);
- fill(0);
- textAlign(CENTER, CENTER);
- textSize(width/60);
- text("Controls", width/12.0, height/8*3);
- text("W: Toggle Rain", width/12.0, height/8*3+height/20);
- text("Enter: Regenerate", width/12.0, height/8*3+height/20*2);
- text("LMB + Drag: Rotate", width/12.0, height/8*3+height/20*3);
- text("MMB + Drag: Pan", width/12.0, height/8*3+height/20*4);
- text("Scroll: Zoom", width/12.0, height/8*3+height/20*5);
- cam.endHUD();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement