Biome generator change in way of caching island info.

Biome cache now stores a 4 biome values: current, main, shore, and shallow.
This commit is contained in:
Harrison Deng 2020-04-28 23:14:37 -05:00
parent 9c8dd377dd
commit 8595ab0c4e
4 changed files with 50 additions and 36 deletions

View File

@ -27,5 +27,5 @@ public interface BiomeGenerator {
* @param biomeCache Cache for biomes. * @param biomeCache Cache for biomes.
* @param chunkGenCache Cache for whether or not the chunk is generated. * @param chunkGenCache Cache for whether or not the chunk is generated.
*/ */
public void generateBiomeColumn(Biome[][] biomesArray, World world, int chunkX, int chunkZ, int localX, int localZ, IslandWorldMapper mapper, BiomeSelector biomeSelector, TemperatureMapGenerator tempGenerator, Cache<Point2, Biome> biomeCache, Cache<Point2, Boolean> chunkGenCache); public void generateBiomeColumn(Biome[][] biomesArray, World world, int chunkX, int chunkZ, int localX, int localZ, IslandWorldMapper mapper, BiomeSelector biomeSelector, TemperatureMapGenerator tempGenerator, Cache<Point2, Biome[]> biomeCache, Cache<Point2, Boolean> chunkGenCache);
} }

View File

@ -21,7 +21,7 @@ import ca.recrown.islandsurvivalcraft.world.shaders.WorldHeightShader;
public class IslandWorldChunkGenerator extends ChunkGenerator implements Listener { public class IslandWorldChunkGenerator extends ChunkGenerator implements Listener {
private final Cache<Point2, Double> blockValueCache = new Cache<>(102400); private final Cache<Point2, Double> blockValueCache = new Cache<>(102400);
private final Cache<Point2, Biome> biomeCache = new Cache<>(102400); private final Cache<Point2, Biome[]> biomeCache = new Cache<>(102400);
private final Cache<Point2, Boolean> chunkExistenceCache = new Cache<>(16384); private final Cache<Point2, Boolean> chunkExistenceCache = new Cache<>(16384);
private volatile World currentWorld; private volatile World currentWorld;

View File

@ -15,22 +15,24 @@ import ca.recrown.islandsurvivalcraft.world.IslandWorldMapper;
public class UniBiomeIslandGenerator implements BiomeGenerator { public class UniBiomeIslandGenerator implements BiomeGenerator {
@Override @Override
public void generateBiomeColumn(Biome[][] biomes, World world, int chunkX, int chunkZ, int localX, int localZ, IslandWorldMapper mapper, BiomeSelector biomeSelector, TemperatureMapGenerator tempGen, Cache<Point2, Biome> biomeCache, Cache<Point2, Boolean> chunkGenCache) { public void generateBiomeColumn(Biome[][] biomes, World world, int chunkX, int chunkZ, int localX, int localZ, IslandWorldMapper mapper, BiomeSelector biomeSelector, TemperatureMapGenerator tempGen, Cache<Point2, Biome[]> biomeCache, Cache<Point2, Boolean> chunkGenCache) {
int worldX = 16 * chunkX + localX; int worldX = 16 * chunkX + localX;
int worldZ = 16 * chunkZ + localZ; int worldZ = 16 * chunkZ + localZ;
Point2 chunkCoords = Utilities.worldToChunkCoordinates(new Point2(worldX, worldZ)); Point2 chunkCoords = Utilities.worldToChunkCoordinates(new Point2(worldX, worldZ));
chunkGenCache.set(chunkCoords, false); chunkGenCache.set(chunkCoords, false);
//Check if we can just give it something in cache. //Check if we can just give it something in cache.
Biome biome = getSavedBiome(world, worldX, worldZ, biomeCache, chunkGenCache); Biome[] biomeSet = attemptGetBiomeSet(world, worldX, worldZ, biomeCache, chunkGenCache);
if (biome != null) { if (biomeSet != null) {
biomes[localX][localZ] = biome; biomes[localX][localZ] = biomeSet[0];
return; return;
} }
//Fine, check if it's ocean. //Fine, check if it's ocean.
if (!mapper.isIsland(worldX, worldZ)) { if (!mapper.isIsland(worldX, worldZ)) {
setCacheBiome(worldX, worldZ, biomeSelector.getOceanBiome(tempGen.getTemperature(worldX, worldZ)), biomes, biomeCache); biomeSet = new Biome[4];
biomeSet[0] = biomeSelector.getOceanBiome(tempGen.getTemperature(worldX, worldZ));
setCacheBiome(worldX, worldZ, biomeSet, biomes, biomeCache);
return; return;
} }
@ -52,9 +54,9 @@ public class UniBiomeIslandGenerator implements BiomeGenerator {
flooder.start(); flooder.start();
} }
private Biome getSavedBiome(World world, int worldX, int worldZ, Cache<Point2, Biome> biomeCache, Cache<Point2, Boolean> existenceCache) { private Biome[] attemptGetBiomeSet(World world, int worldX, int worldZ, Cache<Point2, Biome[]> biomeCache, Cache<Point2, Boolean> existenceCache) {
Point2 worldCoords = new Point2(worldX, worldZ); Point2 worldCoords = new Point2(worldX, worldZ);
Biome res = null; Biome[] res = null;
res = biomeCache.get(worldCoords); res = biomeCache.get(worldCoords);
@ -68,29 +70,30 @@ public class UniBiomeIslandGenerator implements BiomeGenerator {
} }
if (chunkExists) { if (chunkExists) {
res = world.getBiome(worldX, 0, worldZ); res = new Biome[4];
res[0] = world.getBiome(worldX, 0, worldZ);
biomeCache.set(worldCoords, res); biomeCache.set(worldCoords, res);
} }
return res; return res;
} }
private void setCacheBiome(int worldX, int worldZ, Biome biome, Biome[][] localBiomes, Cache<Point2, Biome> biomeCache) { private void setCacheBiome(int worldX, int worldZ, Biome[] biomeSet, Biome[][] localBiomes, Cache<Point2, Biome[]> biomeCache) {
Point2 worldCoords = new Point2(worldX, worldZ); Point2 worldCoords = new Point2(worldX, worldZ);
if (localBiomes != null) { if (localBiomes != null) {
Point2 localCoords = Utilities.worldToLocalChunkCoordinates(worldCoords); Point2 localCoords = Utilities.worldToLocalChunkCoordinates(worldCoords);
localBiomes[localCoords.x][localCoords.y] = biome; localBiomes[localCoords.x][localCoords.y] = biomeSet[0];
} }
biomeCache.set(worldCoords, biome); biomeCache.set(worldCoords, biomeSet);
} }
private class IslandInfo implements CoordinateTargetValidatable { private class IslandInfo implements CoordinateTargetValidatable {
public final IslandWorldMapper mapper; public final IslandWorldMapper mapper;
public final World world; public final World world;
private final Cache<Point2, Biome> biomeCache; private final Cache<Point2, Biome[]> biomeCache;
private final Cache<Point2, Boolean> chunkGenCache; private final Cache<Point2, Boolean> chunkGenCache;
public Biome main, shore, shallow; public Biome main, shore, shallow;
public IslandInfo(IslandWorldMapper mapper, World world, Cache<Point2, Biome> biomeCache, Cache<Point2, Boolean> chunkGenCache) { public IslandInfo(IslandWorldMapper mapper, World world, Cache<Point2, Biome[]> biomeCache, Cache<Point2, Boolean> chunkGenCache) {
this.mapper = mapper; this.mapper = mapper;
this.world = world; this.world = world;
this.biomeCache = biomeCache; this.biomeCache = biomeCache;
@ -99,14 +102,20 @@ public class UniBiomeIslandGenerator implements BiomeGenerator {
@Override @Override
public boolean isCoordinateTarget(int x, int y) { public boolean isCoordinateTarget(int x, int y) {
if (mapper.isLand(x, y)) { Biome[] biomeSet = attemptGetBiomeSet(world, x, y, biomeCache, chunkGenCache);
if (mapper.isShore(x, y)) { if (biomeSet != null) {
shore = getSavedBiome(world, x, y, biomeCache, chunkGenCache); main = biomeSet[1];
} else { shore = biomeSet[2];
main = getSavedBiome(world, x, y, biomeCache, chunkGenCache); shallow = biomeSet[3];
if ((main == null || shore == null) && mapper.isLand(x, y)) {
if (shore == null && mapper.isShore(x, y)) {
main = biomeSet[0];
} else {
shore = biomeSet[0];
}
} else if (shallow == null) {
shallow = biomeSet[0];
} }
} else {
shallow = getSavedBiome(world, x, y, biomeCache, chunkGenCache);
} }
return main != null && shore != null && shallow != null; return main != null && shore != null && shallow != null;
} }
@ -117,9 +126,9 @@ public class UniBiomeIslandGenerator implements BiomeGenerator {
private final Biome[][] biomes; private final Biome[][] biomes;
private final Point2 chunkCoords; private final Point2 chunkCoords;
private final IslandWorldMapper mapper; private final IslandWorldMapper mapper;
private final Cache<Point2, Biome> biomeCache; private final Cache<Point2, Biome[]> biomeCache;
public PropagatorInfo(IslandInfo islandInfo, Biome[][] biomes, Point2 chunkCoords, IslandWorldMapper mapper, Cache<Point2, Biome> biomeCache) { public PropagatorInfo(IslandInfo islandInfo, Biome[][] biomes, Point2 chunkCoords, IslandWorldMapper mapper, Cache<Point2, Biome[]> biomeCache) {
this.shallow = islandInfo.shallow; this.shallow = islandInfo.shallow;
this.shore = islandInfo.shore; this.shore = islandInfo.shore;
this.main = islandInfo.main; this.main = islandInfo.main;
@ -135,16 +144,21 @@ public class UniBiomeIslandGenerator implements BiomeGenerator {
if (!this.chunkCoords.fastEquals(chunkCoords) || !mapper.validate(point.x, point.y)) return false; if (!this.chunkCoords.fastEquals(chunkCoords) || !mapper.validate(point.x, point.y)) return false;
int x = point.x; int x = point.x;
int y = point.y; int y = point.y;
Biome[] biomeSet = new Biome[4];
biomeSet[1] = main;
biomeSet[2] = shore;
biomeSet[3] = shallow;
if (mapper.isLand(x, y)) { if (mapper.isLand(x, y)) {
if (mapper.isShore(x, y)) { if (mapper.isShore(x, y)) {
setCacheBiome(x, y, shore, biomes, biomeCache); biomeSet[0] = shore;
} else { } else {
setCacheBiome(x, y, main, biomes, biomeCache); biomeSet[0] = main;
} }
} else { } else {
setCacheBiome(x, y, shallow, biomes, biomeCache); biomeSet[0] = shallow;
} }
setCacheBiome(x, y, biomeSet, biomes, biomeCache);
return true; return true;
} }

View File

@ -24,7 +24,7 @@ public class UniBiomeIslandGeneratorTest {
private final int SEED = 249398015; private final int SEED = 249398015;
private final DummyWorld dummyWorld = new DummyWorld(); private final DummyWorld dummyWorld = new DummyWorld();
private final Cache<Point2, Double> blockValueCache = new Cache<>(102400); private final Cache<Point2, Double> blockValueCache = new Cache<>(102400);
private final Cache<Point2, Biome> biomeCache = new Cache<>(102400); private final Cache<Point2, Biome[]> biomeCache = new Cache<>(102400);
private final Cache<Point2, Boolean> chunkExistenceCache = new Cache<>(16384); private final Cache<Point2, Boolean> chunkExistenceCache = new Cache<>(16384);
private final Random rand = new Random(SEED); private final Random rand = new Random(SEED);
@ -68,13 +68,13 @@ public class UniBiomeIslandGeneratorTest {
@Test @Test
public void testBiomeGenerationMultithread1608Chunks() { public void testBiomeGenerationMultithread1608Chunks() {
int chunksToDo = 268; int chunksToDoEach = 268;
Runnable g1 = new BiomeGenTask(chunksToDo, 0); Runnable g1 = new BiomeGenTask(chunksToDoEach, 0);
Runnable g2 = new BiomeGenTask(chunksToDo, 1); Runnable g2 = new BiomeGenTask(chunksToDoEach, 1);
Runnable g3 = new BiomeGenTask(chunksToDo, 2); Runnable g3 = new BiomeGenTask(chunksToDoEach, 2);
Runnable g4 = new BiomeGenTask(chunksToDo, 3); Runnable g4 = new BiomeGenTask(chunksToDoEach, 3);
Runnable g5 = new BiomeGenTask(chunksToDo, 4); Runnable g5 = new BiomeGenTask(chunksToDoEach, 4);
Runnable g6 = new BiomeGenTask(chunksToDo, 5); Runnable g6 = new BiomeGenTask(chunksToDoEach, 5);
ExecutorService ex = Executors.newFixedThreadPool(6); ExecutorService ex = Executors.newFixedThreadPool(6);
ex.execute(g1); ex.execute(g1);