Hex map improvements & fixes

This commit is contained in:
paulevsGitch 2021-12-07 18:16:10 +03:00
parent b6875f2c11
commit 6d0b9cbf63
2 changed files with 46 additions and 24 deletions

View file

@ -3,40 +3,47 @@ package ru.bclib.world.generator.map.hex;
import ru.bclib.world.biomes.BCLBiome; import ru.bclib.world.biomes.BCLBiome;
import ru.bclib.world.generator.BiomePicker; import ru.bclib.world.generator.BiomePicker;
import java.util.Arrays;
import java.util.Random; import java.util.Random;
public class HexBiomeChunk { public class HexBiomeChunk {
private static final short SIDE = 32; private static final short SIDE = 32;
private static final byte SIDE_PRE = 4;
private static final short SIZE = SIDE * SIDE; private static final short SIZE = SIDE * SIDE;
private static final short MAX_SIDE = SIZE - SIDE;
private static final byte SCALE_PRE = SIDE / SIDE_PRE;
private static final byte SIZE_PRE = SIDE_PRE * SIDE_PRE;
private static final byte SIDE_MASK = SIDE - 1; private static final byte SIDE_MASK = SIDE - 1;
private static final byte SIDE_PRE_MASK = SIDE_PRE - 1;
private static final byte SIDE_OFFSET = (byte) Math.round(Math.log(SIDE) / Math.log(2)); private static final byte SIDE_OFFSET = (byte) Math.round(Math.log(SIDE) / Math.log(2));
private static final byte SIDE_PRE_OFFSET = (byte) Math.round(Math.log(SIDE_PRE) / Math.log(2));
private static final short[][] NEIGHBOURS; private static final short[][] NEIGHBOURS;
public static final short SCALE = SIDE / 4; private static final BCLBiome[][] BUFFERS = new BCLBiome[2][SIZE];
private final BCLBiome[] biomes; private final BCLBiome[] biomes = new BCLBiome[SIZE];
public HexBiomeChunk(Random random, BiomePicker picker) { public HexBiomeChunk(Random random, BiomePicker picker) {
BCLBiome[][] buffers = new BCLBiome[2][SIZE]; for (BCLBiome[] buffer: BUFFERS) {
Arrays.fill(buffer, null);
byte scale = SIDE / 4; }
for (byte x = 0; x < 4; x++) {
for (byte z = 0; z < 4; z++) { for (byte index = 0; index < SIZE_PRE; index++) {
byte px = (byte) (x * scale + random.nextInt(scale)); byte px = (byte) (index >> SIDE_PRE_OFFSET);
byte pz = (byte) (z * scale + random.nextInt(scale)); byte pz = (byte) (index & SIDE_PRE_MASK);
circle(buffers[0], getIndex(px, pz), picker.getBiome(random), null); px = (byte) (px * SCALE_PRE + random.nextInt(SCALE_PRE));
} pz = (byte) (pz * SCALE_PRE + random.nextInt(SCALE_PRE));
circle(BUFFERS[0], getIndex(px, pz), picker.getBiome(random), null);
} }
short maxSide = SIZE - SIDE;
boolean hasEmptyCells = true; boolean hasEmptyCells = true;
byte bufferIndex = 0; byte bufferIndex = 0;
while (hasEmptyCells) { while (hasEmptyCells) {
BCLBiome[] inBuffer = buffers[bufferIndex]; BCLBiome[] inBuffer = BUFFERS[bufferIndex];
bufferIndex = (byte) ((bufferIndex + 1) & 1); bufferIndex = (byte) ((bufferIndex + 1) & 1);
BCLBiome[] outBuffer = buffers[bufferIndex]; BCLBiome[] outBuffer = BUFFERS[bufferIndex];
hasEmptyCells = false; hasEmptyCells = false;
for (short index = SIDE; index < maxSide; index++) { for (short index = SIDE; index < MAX_SIDE; index++) {
byte z = (byte) (index & SIDE_MASK); byte z = (byte) (index & SIDE_MASK);
if (z == 0 || z == SIDE_MASK) { if (z == 0 || z == SIDE_MASK) {
continue; continue;
@ -55,7 +62,7 @@ public class HexBiomeChunk {
} }
} }
BCLBiome[] outBuffer = buffers[bufferIndex]; BCLBiome[] outBuffer = BUFFERS[bufferIndex];
byte preN = (byte) (SIDE_MASK - 2); byte preN = (byte) (SIDE_MASK - 2);
for (byte index = 0; index < SIDE; index++) { for (byte index = 0; index < SIDE; index++) {
outBuffer[getIndex(index, (byte) 0)] = outBuffer[getIndex(index, (byte) 2)]; outBuffer[getIndex(index, (byte) 0)] = outBuffer[getIndex(index, (byte) 2)];
@ -73,7 +80,7 @@ public class HexBiomeChunk {
} }
} }
this.biomes = outBuffer; System.arraycopy(outBuffer, 0, this.biomes, 0, SIZE);
} }
private void circle(BCLBiome[] buffer, short center, BCLBiome biome, BCLBiome mask) { private void circle(BCLBiome[] buffer, short center, BCLBiome biome, BCLBiome mask) {
@ -113,6 +120,10 @@ public class HexBiomeChunk {
return NEIGHBOURS[z & 1]; return NEIGHBOURS[z & 1];
} }
public static float scaleMap(float size) {
return size / (SIDE >> 2);
}
static { static {
NEIGHBOURS = new short[2][6]; NEIGHBOURS = new short[2][6];

View file

@ -31,7 +31,7 @@ public class HexBiomeMap implements BiomeMap {
public HexBiomeMap(long seed, int size, BiomePicker picker) { public HexBiomeMap(long seed, int size, BiomePicker picker) {
this.picker = picker; this.picker = picker;
this.scale = (float) size / HexBiomeChunk.SCALE; this.scale = HexBiomeChunk.scaleMap(size);
Random random = new Random(seed); Random random = new Random(seed);
noises[0] = new OpenSimplexNoise(random.nextInt()); noises[0] = new OpenSimplexNoise(random.nextInt());
noises[1] = new OpenSimplexNoise(random.nextInt()); noises[1] = new OpenSimplexNoise(random.nextInt());
@ -49,14 +49,25 @@ public class HexBiomeMap implements BiomeMap {
@Override @Override
public BCLBiome getBiome(double x, double z) { public BCLBiome getBiome(double x, double z) {
BCLBiome biome = getRawBiome(x, z); BCLBiome biome = getRawBiome(x, z);
if (biome.getEdge() != null) { BCLBiome edge = biome.getEdge();
float offset = scale * biome.getEdgeSize(); float offset = biome.getEdgeSize();
for (byte i = 0; i < 8; i++) {
if (getRawBiome(x + offset * EDGE_CIRCLE_X[i], z + offset * EDGE_CIRCLE_Z[i]) != biome) { if (edge == null && biome.getParentBiome() != null) {
return biome.getEdge(); edge = biome.getParentBiome().getEdge();
} offset = biome.getParentBiome().getEdgeSize();
}
if (edge == null) {
return biome;
}
offset *= scale;
for (byte i = 0; i < 8; i++) {
if (!getRawBiome(x + offset * EDGE_CIRCLE_X[i], z + offset * EDGE_CIRCLE_Z[i]).isSame(biome)) {
return biome.getEdge();
} }
} }
return biome; return biome;
} }