Skip to content

Instantly share code, notes, and snippets.

@Deamon5550
Created April 12, 2013 03:01
Show Gist options
  • Save Deamon5550/5368984 to your computer and use it in GitHub Desktop.
Save Deamon5550/5368984 to your computer and use it in GitHub Desktop.
terrain
package com.thevoxelbox.generator;
import java.util.Arrays;
import java.util.Random;
public class TerrainGenerator {
Random rand;
int w, h;
public int size;
int[] heightMap;
public TerrainGenerator(Random random, int w, int h) {
rand = random;
//rand.setSeed(31415926535897932l);
this.w = w;
this.h = h;
size = w/32;
heightMap = new int[(w+1) * (h+1)];
Arrays.fill(heightMap, (short) 0);
short[] seedMap = new short[Gen.seedMapSize*Gen.seedMapSize];
Arrays.fill(seedMap, (short) 0);
for(int i = 0; i < Gen.seedbaseNum+rand.nextInt(Gen.seedRandNum); i++) {
int x = rand.nextInt(Gen.seedRange)+(Gen.seedMapSize - Gen.seedRange)/2;
int y = rand.nextInt(Gen.seedRange)+(Gen.seedMapSize - Gen.seedRange)/2;
seedMap[x + y * 64] = Gen.seedStrength;
int steps = rand.nextInt(10) + 12;
int dx = (x < 32? 1 : -1);
int dy = (y < 32? 1 : -1);
int aoe = 1;
int str = Gen.seedStrength + rand.nextInt(70);
for(int s = 0; s < steps ;s++) {
dx = (x < 10? 1 : (x > 54? -1: dx));
dy = (y < 10? 1 : (y > 54? -1: dy));
if(dx == 0 && dy == 0) continue;
x+= dx * rand.nextInt(3);
y+= dy * rand.nextInt(3);
str += rand.nextInt(5);
aoe += (rand.nextInt(3)-1);
aoe = clamp(aoe, 4, 1);
for(int x1 = x - aoe; x1 < x + aoe; x1++) {
for(int y1 = y - aoe; y1 < y + aoe; y1++) {
int ds = (x1-x)*(x1-x) + (y1-y)*(y1-y);
if(ds < aoe*aoe) {
float mult = (1/(ds+1) + 0.5F);
mult = clamp(mult, 1, 0);
if(x1 > 3 && x1 < 61 && y1 > 3 && y1 < 61) seedMap[x1 + y1*65] = (short) (str*mult);
}
}
}
}
}
for(int x = 0; x < 65; x++) {
for(int y = 0; y < 65; y++) {
heightMap[(x*64) + (y*64)*4097] = seedMap[x + y * 65];
}
}
}
public int[] generate() {
int slope = Gen.slope;
while(size >= 1) {
//System.out.println(size);
for(int xn = 0; xn < ((w/2)/size); xn++) {
for(int yn = 0; yn < ((w/2)/size); yn++) {
int heightWeightOffset = rand.nextInt(20) - 10;
int y = size + (2 * size) * yn;
int x = size + (2 * size) * xn;
//System.out.println(slope);
int rOffs = rand.nextInt(slope) - (slope / 2);
int avg = (avgSquareVals(x, y, size, heightMap));
if(avg > 128) rOffs *= Gen.highAltitudeRandomMultiplier;
short height = (short) (avg + rOffs);
if(height > Gen.heightWeightFloor + heightWeightOffset) {
height *= Gen.heightWeightMult;
} else {
height *= 1/Gen.heightWeightMult;
}
height = clamp(height, 255, 0);
heightMap[x + y * w] = height;
}
}
for(int xn = 0; xn < ((w/2)/size); xn++) {
for(int yn = 0; yn < ((w/2)/size); yn++) {
int heightWeightOffset = rand.nextInt(20) - 10;
int y = size + (2 * size) * yn;
int x = size + (2 * size) * xn;
if(heightMap[x-size + y * w] == 0) {
int rOffs = rand.nextInt(slope) - (slope / 2);
int avg = (avgSquareVals(x, y, size, heightMap));
if(avg > 128) rOffs *= Gen.highAltitudeRandomMultiplier;
short height = (short) (avg + rOffs);
if(height > Gen.heightWeightFloor + heightWeightOffset) {
height *= Gen.heightWeightMult;
} else {
height *= 1/Gen.heightWeightMult;
}
height = clamp(height, 255, 0);
heightMap[x-size + y * w] = height;
}
if(heightMap[x+size + y * w] == 0) {
int rOffs = rand.nextInt(slope) - (slope / 2);
int avg = (avgSquareVals(x, y, size, heightMap));
if(avg > 128) rOffs *= Gen.highAltitudeRandomMultiplier;
short height = (short) (avg + rOffs);
if(height > Gen.heightWeightFloor + heightWeightOffset) {
height *= Gen.heightWeightMult;
} else {
height *= 1/Gen.heightWeightMult;
}
height = clamp(height, 255, 0);
heightMap[x+size + y * w] = height;
}
if(heightMap[x + (y-size) * w] == 0) {
int rOffs = rand.nextInt(slope) - (slope / 2);
int avg = (avgSquareVals(x, y, size, heightMap));
if(avg > 128) rOffs *= Gen.highAltitudeRandomMultiplier;
short height = (short) (avg + rOffs);
if(height > Gen.heightWeightFloor + heightWeightOffset) {
height *= Gen.heightWeightMult;
} else {
height *= 1/Gen.heightWeightMult;
}
height = clamp(height, 255, 0);
heightMap[x + (y-size) * w] = height;
}
if(heightMap[x + (y+size) * w] == 0) {
int rOffs = rand.nextInt(slope) - (slope / 2);
int avg = (avgSquareVals(x, y, size, heightMap));
if(avg > 128) rOffs *= Gen.highAltitudeRandomMultiplier;
short height = (short) (avg + rOffs);
if(height > Gen.heightWeightFloor + heightWeightOffset) {
height *= Gen.heightWeightMult;
} else {
height *= 1/Gen.heightWeightMult;
}
height = clamp(height, 255, 0);
heightMap[x + (y+size) * w] = height;
}
}
}
slope *= Gen.slopeDegrader;
slope = clamp(slope, 256, 1);
size /= 2;
}
smooth(heightMap, 4098, 4098, 8);
for(int i = 0; i < heightMap.length; i++) heightMap[i] = (0xFF) << 24 | (heightMap[i]&0xFF) << 16 | (heightMap[i]&0xFF) << 8 | (heightMap[i]&0xFF);
return heightMap;
}
public int avgDiamondVals(int x, int y, int size, int[] fa) {
int x0 = x, y0 = y;
int h1;
x0 = x-size;
if(x0 < 0) {
h1 = 0;
} else {
h1 = fa[x0 + y0 * w];
}
int h2;
x0 = x+size;
if(x0 > w) {
h2 = 0;
} else {
h2 = fa[x0 + y0 * w];
}
x0 = x;
int h3;
y0 = y-size;
if(y0 < 0) {
h3 = 0;
} else {
h3 = fa[x0 + y0 * w];
}
int h4;
y0 = y+size;
if(y0 > h) {
h4 = 0;
} else {
h4 = fa[x0 + y0 * w];
}
short ha = (short) ((h1 + h2 + h3 + h4)/4);
//System.out.println("Diamond " + x + " " + y + " " + size + " " + ha);
return ha;
}
public int avgSquareVals(int x, int y,int size, int[] fa) {
x = clamp(x, size);
y = clamp(y, size);
int h1 = fa[(x-size) + (y-size) * w];
int h2 = fa[(x-size) + (y+size) * w];
int h3 = fa[(x+size) + (y-size) * w];
int h4 = fa[(x+size) + (y+size) * w];
short ha = (short) ((h1 + h2 + h3 + h4)/4);
//System.out.println("Square " + x + " " + y + " " + size + " " + ha);
return ha;
}
public void smooth(int[] heightMap, int w, int h, int passes)
{
int[] tmp = new int[heightMap.length];
while(passes > 0) {
passes--;
for(int x = 0; x < w; x++) {
for(int y = 0; y < h; y++) {
int adj = 0;
int tot = 0;
if ((x - 1) > 0) // Check to left
{
tot += heightMap[(x-1)+ y * w];
adj++;
if ((y - 1) > 0) // Check up and to the left
{
tot += heightMap[(x-1)+ (y-1) * w];
adj++;
}
if ((y + 1) < h) // Check down and to the left
{
tot += heightMap[(x-1)+ (y+1) * w];
adj++;
}
}
if ((x + 1) < w) // Check to right
{
tot += heightMap[(x+1)+ (y) * w];
adj++;
if ((y - 1) > 0) // Check up and to the right
{
tot += heightMap[(x+1)+ (y-1) * w];
adj++;
}
if ((y + 1) < h) // Check down and to the right
{
tot += heightMap[(x+1)+ (y+1) * w];
adj++;
}
}
if ((y - 1) > 0) // Check above
{
tot += heightMap[(x)+ (y-1) * w];
adj++;
}
if ((y + 1) < h) // Check below
{
tot += heightMap[(x)+ (y+1) * w];
adj++;
}
if((x - 2) > 0) {
if ((y + 1) < h) // Check above
{
tot += heightMap[(x-2)+ (y+1) * w];
adj++;
}
tot += heightMap[(x-2)+ (y) * w];
adj++;
if ((y - 1) > 0) // Check above
{
tot += heightMap[(x-2)+ (y-1) * w];
adj++;
}
if ((y - 2) > 0) // Check up and to the right
{
tot += heightMap[(x-2)+ (y-2) * w];
adj++;
}
if ((y + 2) < h) // Check down and to the right
{
tot += heightMap[(x-2)+ (y+2) * w];
adj++;
}
}
if((x + 2) < w) {
if ((y + 1) < h) // Check above
{
tot += heightMap[(x+2)+ (y+1) * w];
adj++;
}
tot += heightMap[(x+2)+ (y) * w];
adj++;
if ((y - 1) > 0) // Check above
{
tot += heightMap[(x+2)+ (y-1) * w];
adj++;
}
if ((y - 2) > 0) // Check up and to the right
{
tot += heightMap[(x+2)+ (y-2) * w];
adj++;
}
if ((y + 2) < h) // Check down and to the right
{
tot += heightMap[(x+2)+ (y+2) * w];
adj++;
}
}
if((y + 2) < h) {
if ((x - 1) > 0) // Check above
{
tot += heightMap[(x-1)+ (y+2) * w];
adj++;
}
tot += heightMap[(x)+ (y+2) * w];
adj++;
if ((x + 1) < w) // Check above
{
tot += heightMap[(x+1)+ (y+2) * w];
adj++;
}
}
if((y - 2) > 0) {
if ((x - 1) > 0) // Check above
{
tot += heightMap[(x-1)+ (y-2) * w];
adj++;
}
tot += heightMap[(x)+ (y-2) * w];
adj++;
if ((x + 1) < w) // Check above
{
tot += heightMap[(x+1)+ (y-2) * w];
adj++;
}
}
tmp[x + y * w] = (int) ((heightMap[x + y * w] + (tot/adj))*0.5f);
}
}
for(int x = 0; x < w; x++) {
for(int y = 0; y < h; y++) {
heightMap[x + y * w] = tmp[x + y * w];
}
}
}
}
public short clamp(short i, int max, int min) {
return (short) (i < min? min : (i > max? max : i));
}
public float clamp(float i, float max, float min) {
return (i < min? min : (i > max? max : i));
}
public int clamp(int i, int max, int min) {
return (i < min? min : (i > max? max : i));
}
public int clamp(int i, int min) {
return (short) (i < min? min : i);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment