From 15b1ff7370528a865bc09bb09118c785abe5cb06 Mon Sep 17 00:00:00 2001 From: Forwolk Date: Sun, 5 Aug 2018 17:15:55 +0300 Subject: [PATCH] Noise generator in separate class --- .../generator/NoiseGenerator.java | 57 +++++++++++++++++++ .../generator/SeedBasedWorldGenerator.java | 52 +---------------- 2 files changed, 58 insertions(+), 51 deletions(-) create mode 100644 generated_world/src/main/java/mc/world/generated_world/generator/NoiseGenerator.java diff --git a/generated_world/src/main/java/mc/world/generated_world/generator/NoiseGenerator.java b/generated_world/src/main/java/mc/world/generated_world/generator/NoiseGenerator.java new file mode 100644 index 0000000..b3c84c7 --- /dev/null +++ b/generated_world/src/main/java/mc/world/generated_world/generator/NoiseGenerator.java @@ -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)); + } +} diff --git a/generated_world/src/main/java/mc/world/generated_world/generator/SeedBasedWorldGenerator.java b/generated_world/src/main/java/mc/world/generated_world/generator/SeedBasedWorldGenerator.java index 3f272b0..f1f63de 100644 --- a/generated_world/src/main/java/mc/world/generated_world/generator/SeedBasedWorldGenerator.java +++ b/generated_world/src/main/java/mc/world/generated_world/generator/SeedBasedWorldGenerator.java @@ -80,7 +80,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()); @@ -388,54 +388,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)); - } - } - } \ No newline at end of file