Archived
0

Merge tag 'WG-1' into develop

World Generator Gen1
This commit is contained in:
2018-08-07 21:42:24 +03:00
3 changed files with 103 additions and 158 deletions

View File

@@ -0,0 +1,57 @@
package mc.world.generated_world.generator;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import static mc.world.generated_world.WorldConstants.WORLD_REGION_SIZE;
@Slf4j
@RequiredArgsConstructor
public class NoiseGenerator {
private int[] perm = new int[WORLD_REGION_SIZE];
private double[] gradsX = new double[WORLD_REGION_SIZE];
private double[] gradsY = new double[WORLD_REGION_SIZE];
private final int seed;
void init() {
for (int i = 0; i < WORLD_REGION_SIZE; ++i) {
int other = rand(i) % (i + 1);
if (i > other)
perm[i] = perm[other];
perm[other] = i;
gradsX[i] = Math.cos(2.0f * Math.PI * i / WORLD_REGION_SIZE);
gradsY[i] = Math.sin(2.0f * Math.PI * i / WORLD_REGION_SIZE);
}
log.debug("Noise generator is initialized");
}
double f(double t) {
t = Math.abs(t);
return t >= 1.0f ? 0.0f : 1.0f -
(3.0f - 2.0f * t) * t * t;
}
private double surflet(double x, double y, double gradX, double gradY) {
return f(x) * f(y) * (gradX * x + gradY * y);
}
double noise(double x, double y) {
float result = 0.0f;
int cellX = (int)(x);
int cellY = (int)(y);
int mask = WORLD_REGION_SIZE - 1;
for (int gridY = cellY; gridY <= cellY + 1; ++gridY)
for (int gridX = cellX; gridX <= cellX + 1; ++gridX) {
int hash = perm[(perm[gridX & mask] + gridY) & mask];
result += surflet(x - gridX, y - gridY,
gradsX[hash], gradsY[hash]);
}
return (result + 1) / 2;
}
private int rand(int i) {
int x = (i * i) % WORLD_REGION_SIZE;
int y = (i + i * x) % WORLD_REGION_SIZE;
return (int) (Integer.MAX_VALUE * SeedRandomGenerator.random(x, y, seed));
}
}

View File

@@ -7,9 +7,6 @@ import mc.core.world.block.BlockType;
import mc.core.world.*;
import mc.core.world.chunk.Chunk;
import mc.world.generated_world.region.RegionImpl;
import mc.world.generated_world.serialization.ChunkSerializer;
import mc.world.generated_world.serialization.RegionReaderWriter;
import mc.world.generated_world.serialization.WorldReaderWriter;
import mc.world.generated_world.world.CubicWorld;
import mc.world.generated_world.world.Temperature;
import mc.world.generated_world.world.Wetness;
@@ -17,6 +14,7 @@ import mc.world.generated_world.world.Wetness;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
import static mc.world.generated_world.WorldConstants.*;
@@ -27,24 +25,26 @@ public class SeedBasedWorldGenerator implements WorldGenerator {
public static void main(String[] args) throws Exception{
WorldGenerator worldGenerator = new SeedBasedWorldGenerator();
World world = new CubicWorld(UUID.fromString("00000000-0000-0000-C000-000000000046"), 2626949);
Region region = worldGenerator.generateRegion(0, 0, world);
/*Region region = worldGenerator.generateRegion(0, 0, world);
region.save(new ChunkSerializer(), new RegionReaderWriter(new File("worlds", world.getWorldId().toString())));
new WorldReaderWriter(new File("worlds")).writeWorldInfo(world);
/*worldGenerator.generateRegion(1, 0, world);
worldGenerator.generateRegion(-1, 0, world);
worldGenerator.generateRegion(0, 1, world);
worldGenerator.generateRegion(0, -1, world);
worldGenerator.generateRegion(-1, -1, world);
worldGenerator.generateRegion(1, -1, world);
worldGenerator.generateRegion(-1, 1, world);
worldGenerator.generateRegion(1, 1, world);
new WorldReaderWriter(new File("worlds")).writeWorldInfo(world);*/
createBigImage(worldGenerator, world);
}
private static void createBigImage (WorldGenerator worldGenerator, World world) throws IOException {
BufferedImage image = new BufferedImage(3 * 256, 3 * 256, BufferedImage.TYPE_INT_RGB);
BufferedImage currentImage;
int shiftX;
int shiftY;
currentImage = ImageIO.read(new File("out/0.0", "biomeMap.png"));
shiftX = 1;
shiftY = 1;
for (int x = 0; x <= 2; x ++) {
for (int z = 0; z <= 2; z ++) {
worldGenerator.generateRegion(x - 1, z - 1, world);
addToBigImage(x, z, image);
}
}
ImageIO.write(image, "png", new File("out", "merged.png"));
}
private static void addToBigImage (int shiftX, int shiftY, BufferedImage image) throws IOException{
BufferedImage currentImage = ImageIO.read(new File("out/" + (shiftX - 1) + "." + (shiftY - 1), "biomeMap.png"));
for (int x = 0; x < 256; x ++){
for (int y = 0; y < 256; y ++){
int tx = 256 * shiftX + x;
@@ -52,87 +52,6 @@ public class SeedBasedWorldGenerator implements WorldGenerator {
image.setRGB(tx, ty, currentImage.getRGB(x, y));
}
}
currentImage = ImageIO.read(new File("out/0.1", "biomeMap.png"));
shiftX = 1;
shiftY = 2;
for (int x = 0; x < 256; x ++){
for (int y = 0; y < 256; y ++){
int tx = 256 * shiftX + x;
int ty = 256 * shiftY + y;
image.setRGB(tx, ty, currentImage.getRGB(x, y));
}
}
currentImage = ImageIO.read(new File("out/1.0", "biomeMap.png"));
shiftX = 2;
shiftY = 1;
for (int x = 0; x < 256; x ++){
for (int y = 0; y < 256; y ++){
int tx = 256 * shiftX + x;
int ty = 256 * shiftY + y;
image.setRGB(tx, ty, currentImage.getRGB(x, y));
}
}
currentImage = ImageIO.read(new File("out/-1.0", "biomeMap.png"));
shiftX = 0;
shiftY = 1;
for (int x = 0; x < 256; x ++){
for (int y = 0; y < 256; y ++){
int tx = 256 * shiftX + x;
int ty = 256 * shiftY + y;
image.setRGB(tx, ty, currentImage.getRGB(x, y));
}
}
currentImage = ImageIO.read(new File("out/0.-1", "biomeMap.png"));
shiftX = 1;
shiftY = 0;
for (int x = 0; x < 256; x ++){
for (int y = 0; y < 256; y ++){
int tx = 256 * shiftX + x;
int ty = 256 * shiftY + y;
image.setRGB(tx, ty, currentImage.getRGB(x, y));
}
}
currentImage = ImageIO.read(new File("out/-1.-1", "biomeMap.png"));
shiftX = 0;
shiftY = 0;
for (int x = 0; x < 256; x ++){
for (int y = 0; y < 256; y ++){
int tx = 256 * shiftX + x;
int ty = 256 * shiftY + y;
image.setRGB(tx, ty, currentImage.getRGB(x, y));
}
}
currentImage = ImageIO.read(new File("out/1.-1", "biomeMap.png"));
shiftX = 2;
shiftY = 0;
for (int x = 0; x < 256; x ++){
for (int y = 0; y < 256; y ++){
int tx = 256 * shiftX + x;
int ty = 256 * shiftY + y;
image.setRGB(tx, ty, currentImage.getRGB(x, y));
}
}
currentImage = ImageIO.read(new File("out/1.1", "biomeMap.png"));
shiftX = 2;
shiftY = 2;
for (int x = 0; x < 256; x ++){
for (int y = 0; y < 256; y ++){
int tx = 256 * shiftX + x;
int ty = 256 * shiftY + y;
image.setRGB(tx, ty, currentImage.getRGB(x, y));
}
}
currentImage = ImageIO.read(new File("out/-1.1", "biomeMap.png"));
shiftX = 0;
shiftY = 2;
for (int x = 0; x < 256; x ++){
for (int y = 0; y < 256; y ++){
int tx = 256 * shiftX + x;
int ty = 256 * shiftY + y;
image.setRGB(tx, ty, currentImage.getRGB(x, y));
}
}
ImageIO.write(image, "png", new File("out", "merged.png"));*/
}
@Override
@@ -162,7 +81,7 @@ public class SeedBasedWorldGenerator implements WorldGenerator {
return 40960 + x;
}
public void generate() {
private void generate() {
log.debug("Starting generating region [{}, {}] for world '{}' with seed '{}'", region.getX(), region.getZ(), world.getWorldId(), world.getSeed());
noiseGenerator = new NoiseGenerator(world.getSeed());
@@ -381,7 +300,7 @@ public class SeedBasedWorldGenerator implements WorldGenerator {
if (temperature == Temperature.FROST) {
if (wetness == Wetness.DRIEST || wetness == Wetness.DRY) {
return Biome.TUNDRA;
return Biome.COLD_TAIGA;
} else {
if (height > HILLS_HEIGHT) {
return Biome.ICE_MOUNTAINS;
@@ -435,7 +354,7 @@ public class SeedBasedWorldGenerator implements WorldGenerator {
return Biome.FOREST;
}
} else {
return Biome.SAVANNA_FOREST;
return Biome.SAVANNA_PLATO;
}
}
@@ -470,54 +389,4 @@ public class SeedBasedWorldGenerator implements WorldGenerator {
}
}
@RequiredArgsConstructor
private class NoiseGenerator {
int mask = WORLD_REGION_SIZE - 1;
int[] perm = new int[WORLD_REGION_SIZE];
double[] gradsX = new double[WORLD_REGION_SIZE];
double[] gradsY = new double[WORLD_REGION_SIZE];
private final int seed;
void init() {
for (int i = 0; i < WORLD_REGION_SIZE; ++i) {
int other = rand(i) % (i + 1);
if (i > other)
perm[i] = perm[other];
perm[other] = i;
gradsX[i] = Math.cos(2.0f * Math.PI * i / WORLD_REGION_SIZE);
gradsY[i] = Math.sin(2.0f * Math.PI * i / WORLD_REGION_SIZE);
}
log.debug("Noise generator is initialized");
}
double f(double t) {
t = Math.abs(t);
return t >= 1.0f ? 0.0f : 1.0f -
(3.0f - 2.0f * t) * t * t;
}
double surflet(double x, double y, double gradX, double gradY) {
return f(x) * f(y) * (gradX * x + gradY * y);
}
double noise(double x, double y) {
float result = 0.0f;
int cellX = (int)(x);
int cellY = (int)(y);
for (int gridY = cellY; gridY <= cellY + 1; ++gridY)
for (int gridX = cellX; gridX <= cellX + 1; ++gridX) {
int hash = perm[(perm[gridX & mask] + gridY) & mask];
result += surflet(x - gridX, y - gridY,
gradsX[hash], gradsY[hash]);
}
return (result + 1) / 2;
}
int rand(int i) {
int x = (i * i) % WORLD_REGION_SIZE;
int y = (i + i * x) % WORLD_REGION_SIZE;
return (int) (Integer.MAX_VALUE * SeedRandomGenerator.random(x, y, seed));
}
}
}