Noise generator in separate class
This commit is contained in:
@@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -80,7 +80,7 @@ public class SeedBasedWorldGenerator implements WorldGenerator {
|
|||||||
return 40960 + x;
|
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());
|
log.debug("Starting generating region [{}, {}] for world '{}' with seed '{}'", region.getX(), region.getZ(), world.getWorldId(), world.getSeed());
|
||||||
|
|
||||||
noiseGenerator = new NoiseGenerator(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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user