import processing.opengl.*; // Set up control variables float xOffset = 10; float yOffset = 20; float zOffset = -150; int gridSize = 150; int iterationsPerDraw = 1000; float rainDamage = 0.03; float noiseScale = .5; float scaleVal = 5; float heightScale = 4; float seaLevel = 15; float fogThickness = 0.0; float[][] meshHeight = new float[gridSize][gridSize]; color[][] meshCol = new color[gridSize][gridSize]; color seaCol = color(111,175,221,255); color currentSeaCol = seaCol; color fogCol = color(203,166,122,255); color earthCol1 = color(99,69,45,255); color earthCol2 = color(118,98,98,255); color earthCol3 = color(78,61,46,255); color earthCol4 = color(46,36,37,255); color earthCol6 = color(176,188,227,255); color earthCol7 = color(163,172,203,255); float maxFogDist = 290; float minFogDist = 275; // Set up grid // Set up viewport void setup() { size(640,320,OPENGL); noStroke(); buildWorld(); } // start draw() void draw() { background(fogCol); // ambientLight(80,80,80); //pointLight(255, 255, 180, 500*cos(frameCount * 0.01), 500*sin(frameCount * 0.01), 0); //pointLight(0, 64, 128, 500*sin(frameCount * 0.01), 500*cos(frameCount * 0.01), 0); // Rotate viewpoint float camXPos = float(gridSize)*2.5 * cos(frameCount * 0.001); float camYPos = 180; float camZPos = float(gridSize)*2.5 * sin(frameCount * 0.001); camera(camXPos, camYPos, camZPos, 0, 0, 0, 0, -1, 0); // iterate erosion for deforming mesh for(int i = 0; i < iterationsPerDraw; i++){ erode(); } for(int x=0;x<(gridSize-1);x++){ beginShape(TRIANGLE_STRIP); for(int z=0; z seaLevel){ fogThickness = fogThickness(camXPos,camYPos,camZPos,xFloat, meshHeight[x][z]*heightScale,zFloat,minFogDist,maxFogDist); fill(lerpColor(meshCol[x][z],fogCol,fogThickness)); //fill(red(meshCol[x][z]), green(meshCol[x][z]), blue(meshCol[x][z]), 255); vertex(xFloat,meshHeight[x][z]*heightScale,zFloat); }else{ fogThickness = fogThickness(camXPos,camYPos,camZPos,xFloat,seaLevel*heightScale,zFloat,minFogDist,maxFogDist); currentSeaCol = seaColDepth(meshHeight[x][z], seaLevel, meshCol[x][z], seaCol); fill(lerpColor(currentSeaCol,fogCol,fogThickness)); vertex(xFloat,seaLevel*heightScale,zFloat); } xFloat = float(x+1); xFloat -= (gridSize * 0.5); xFloat *= scaleVal; // fill(0, int(meshHeight[x+1][z]), 128, 255); if(meshHeight[x][z] > seaLevel){ fogThickness = fogThickness(camXPos,camYPos,camZPos,xFloat, meshHeight[x+1][z]*heightScale,zFloat,minFogDist,maxFogDist); fill(lerpColor(meshCol[x][z],fogCol,fogThickness)); //fill(red(meshCol[x][z]), green(meshCol[x][z]), blue(meshCol[x][z]), 255); vertex(xFloat, meshHeight[x+1][z]*heightScale, zFloat); }else{ fogThickness = fogThickness(camXPos,camYPos,camZPos,xFloat,seaLevel*heightScale,zFloat,minFogDist,maxFogDist); currentSeaCol = seaColDepth(meshHeight[x+1][z], seaLevel, meshCol[x+1][z], seaCol); fill(lerpColor(currentSeaCol,fogCol,fogThickness)); vertex(xFloat,seaLevel*heightScale,zFloat); } } endShape(); } } void erode() { int xPos = int(random(gridSize-2))+1; int zPos = int(random(gridSize-2))+1; float sandLoad = rainDamage; // The amount of eroded material being carried at the current point float currentHeight = meshHeight[xPos][zPos]; color sandCol = meshCol[xPos][zPos]; float mixRatio = 1; float lowestNearHeight = meshHeight[xPos][zPos]; int lowestNearX = xPos; int lowestNearZ = zPos; boolean quitIt = false; while(quitIt == false){ if(xPos > 0){ if(meshHeight[xPos-1][zPos] < lowestNearHeight){ lowestNearHeight = meshHeight[xPos-1][zPos]; lowestNearX = xPos-1; lowestNearZ = zPos; } } if(xPos > 0 && zPos > 0){ if(meshHeight[xPos-1][zPos-1] < lowestNearHeight){ lowestNearHeight = meshHeight[xPos-1][zPos-1]; lowestNearX = xPos-1; lowestNearZ = zPos-1; } } if(xPos > 0 && zPos < gridSize-2){ if(meshHeight[xPos-1][zPos+1] < lowestNearHeight){ lowestNearHeight = meshHeight[xPos-1][zPos+1]; lowestNearX = xPos-1; lowestNearZ = zPos+1; } } if(zPos > 0){ if(meshHeight[xPos][zPos-1] < lowestNearHeight){ lowestNearHeight = meshHeight[xPos][zPos-1]; lowestNearX = xPos; lowestNearZ = zPos-1; } } if(xPos 0){ if(meshHeight[xPos+1][zPos-1] < lowestNearHeight){ lowestNearHeight = meshHeight[xPos+1][zPos-1]; lowestNearX = xPos+1; lowestNearZ = zPos-1; } } if(xPos 5){ diffHeight = 5; } diffHeight /= 5; meshHeight[xPos][zPos] -= rainDamage; sandLoad += rainDamage; meshHeight[xPos][zPos] += (1-diffHeight) * sandLoad; sandLoad *= diffHeight; mixRatio = 1/(sandLoad+rainDamage); float mixRedF = red(meshCol[xPos][zPos])*mixRatio*rainDamage + red(sandCol)*mixRatio*sandLoad; float mixGreenF = green(meshCol[xPos][zPos])*mixRatio*rainDamage + green(sandCol)*mixRatio*sandLoad; float mixBlueF = blue(meshCol[xPos][zPos])*mixRatio*rainDamage + blue(sandCol)*mixRatio*sandLoad; meshCol[xPos][zPos] = color(int(mixRedF),int(mixGreenF),int(mixBlueF)); sandCol = meshCol[xPos][zPos]; xPos = lowestNearX; zPos = lowestNearZ; } } } void buildWorld(){ int time = year() + month() + day() + hour() + minute() + second(); randomSeed(time); noiseSeed(time); float randomGamma = random(1) + 0.5; for(int x=0;x 0){ for(int i = 0; i < randomInt; i++){ int randPosX = int(random(gridSize-5)) + 2; int randPosZ = int(random(gridSize-5)) + 2; if(meshHeight[randPosX][randPosZ] > seaLevel){ addTower1(earthCol4, randPosX, randPosZ); } if(random(6)>5){ addWall1(earthCol3); addWall2(earthCol3); } } } } void mousePressed(){ int setVal = int(random(100)); noiseSeed(setVal); buildWorld(); } float fogThickness(float x1, float y1, float z1, float x2, float y2, float z2, float minDepth, float maxDepth){ float foginess = 1; float lengthVec = sqrt((x1-x2) * (x1-x2) + (y1-y2) * (y1-y2) + (z1-z2) * (z1-z2)); if(lengthVec5){ depth = 5; } depth /= 5; color shallowsCol = lerpColor(landCol,seaCol,0.6); color outCol = lerpColor(shallowsCol,seaCol,depth); return outCol; } float clamp(float inVal, float minVal, float maxVal){ float outVal = inVal; if(outValmaxVal){ outVal = maxVal; } return outVal; } void addWall1(color wallCol){ int x1 = int(random(gridSize)); int x2 = int(random(gridSize)); int z = int(random(gridSize-5))+2; if(x1 != x2){ for(int i=x1;i