implement API for 3d biomes

This commit is contained in:
dfsek
2022-05-27 14:40:50 -07:00
parent ee373bbe4b
commit b6b6cb185d
15 changed files with 72 additions and 37 deletions

View File

@@ -37,7 +37,7 @@ public class ImageBiomeProvider implements BiomeProvider {
}
@Override
public Biome getBiome(int x, int z, long seed) {
public Biome getBiome(int x, int y, int z, long seed) {
x /= resolution;
z /= resolution;
Color color = align.getColor(image, x, z);

View File

@@ -81,7 +81,7 @@ public class BiomePipelineProvider implements BiomeProvider {
}
@Override
public Biome getBiome(int x, int z, long seed) {
public Biome getBiome(int x, int y, int z, long seed) {
x += mutator.noise(seed + 1, x, z) * noiseAmp;
z += mutator.noise(seed + 2, x, z) * noiseAmp;

View File

@@ -21,7 +21,7 @@ public class SingleBiomeProvider implements BiomeProvider {
}
@Override
public Biome getBiome(int x, int z, long seed) {
public Biome getBiome(int x, int y, int z, long seed) {
return biome;
}

View File

@@ -73,7 +73,7 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
int cx = xOrig + x;
int cz = zOrig + z;
Biome biome = biomeProvider.getBiome(cx, cz, seed);
Biome biome = biomeProvider.getBiome(cx, 0, cz, seed);
PaletteInfo paletteInfo = biome.getContext().get(PaletteInfo.class);
@@ -104,7 +104,7 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
@Override
public BlockState getBlock(WorldProperties world, int x, int y, int z, BiomeProvider biomeProvider) {
Biome biome = biomeProvider.getBiome(x, z, world.getSeed());
Biome biome = biomeProvider.getBiome(x, y, z, world.getSeed());
Sampler3D sampler = samplerCache.get(x, z, world, biomeProvider);
PaletteInfo paletteInfo = biome.getContext().get(PaletteInfo.class);
@@ -128,7 +128,7 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
@Override
public Palette getPalette(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) {
return biomeProvider.getBiome(x, z, world.getSeed()).getContext().get(PaletteInfo.class).paletteHolder().getPalette(y);
return biomeProvider.getBiome(x, y, z, world.getSeed()).getContext().get(PaletteInfo.class).paletteHolder().getPalette(y);
}
public SamplerProvider samplerProvider() {

View File

@@ -55,7 +55,7 @@ public class ChunkInterpolator {
for(int x = 0; x < 5; x++) {
for(int z = 0; z < 5; z++) {
BiomeNoiseProperties generationSettings = provider.getBiome(xOrigin + (x << 2), zOrigin + (z << 2), seed)
BiomeNoiseProperties generationSettings = provider.getBiome(xOrigin + (x << 2), 0, zOrigin + (z << 2), seed)
.getContext()
.get(BiomeNoiseProperties.class);
Map<BiomeNoiseProperties, MutableInteger> genMap = new HashMap<>();
@@ -66,7 +66,7 @@ public class ChunkInterpolator {
for(int xi = -blend; xi <= blend; xi++) {
for(int zi = -blend; zi <= blend; zi++) {
genMap.computeIfAbsent(
provider.getBiome(xOrigin + (x << 2) + (xi * step), zOrigin + (z << 2) + (zi * step), seed)
provider.getBiome(xOrigin + (x << 2) + (xi * step), 0, zOrigin + (z << 2) + (zi * step), seed)
.getContext()
.get(BiomeNoiseProperties.class),
g -> new MutableInteger(0)).increment(); // Increment by 1

View File

@@ -23,7 +23,7 @@ public class ElevationInterpolator {
// Precompute generators.
for(int x = -1 - smooth; x <= 16 + smooth; x++) {
for(int z = -1 - smooth; z <= 16 + smooth; z++) {
gens[x + 1 + smooth][z + 1 + smooth] = provider.getBiome(xOrigin + x, zOrigin + z, seed).getContext().get(
gens[x + 1 + smooth][z + 1 + smooth] = provider.getBiome(xOrigin + x, 0, zOrigin + z, seed).getContext().get(
BiomeNoiseProperties.class);
}
}

View File

@@ -48,7 +48,7 @@ public class LazilyEvaluatedInterpolator {
NoiseSampler sampler = samplers[x][z];
if(sampler == null) {
sampler = biomeProvider.getBiome(xi, zi, seed).getContext().get(BiomeNoiseProperties.class).carving();
sampler = biomeProvider.getBiome(xi, y, zi, seed).getContext().get(BiomeNoiseProperties.class).carving();
samplers[x][z] = sampler;
}

View File

@@ -49,7 +49,7 @@ public class FeatureGenerationStage implements GenerationStage, StringIdentifiab
long coordinateSeed = (seed * 31 + tx) * 31 + tz;
world.getBiomeProvider()
.getBiome(tx, tz, seed)
.getBiome(tx, 0, tz, seed)
.getContext()
.get(BiomeFeatures.class)
.getFeatures()

View File

@@ -7,10 +7,17 @@
package com.dfsek.terra.api.world.biome.generation;
import com.dfsek.terra.api.util.vector.Vector2;
import com.dfsek.terra.api.util.vector.Vector3;
import com.dfsek.terra.api.util.vector.Vector3Int;
import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.api.world.info.WorldProperties;
import org.jetbrains.annotations.Contract;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
/**
* Provides locations of biomes in a world.
@@ -20,23 +27,26 @@ public interface BiomeProvider {
* Get the biome at a location.
*
* @param x X coordinate
* @param y
* @param z Z coordinate
* @param seed World seed
*
* @return Biome at the location
*/
Biome getBiome(int x, int z, long seed);
@Contract(pure = true)
Biome getBiome(int x, int y, int z, long seed);
/**
* Get the biome at a location.
*
* @param vector2 Location
* @param vector3 Location
* @param seed World seed
*
* @return Biome at the location
*/
default Biome getBiome(Vector2 vector2, long seed) {
return getBiome(vector2.getBlockX(), vector2.getBlockZ(), seed);
@Contract(pure = true)
default Biome getBiome(Vector3 vector3, long seed) {
return getBiome(vector3.getBlockX(), vector3.getBlockY(), vector3.getBlockZ(), seed);
}
/**
@@ -47,8 +57,9 @@ public interface BiomeProvider {
*
* @return Biome at the location
*/
default Biome getBiome(Vector3 vector3, long seed) {
return getBiome(vector3.getBlockX(), vector3.getBlockZ(), seed);
@Contract(pure = true)
default Biome getBiome(Vector3Int vector3, long seed) {
return getBiome(vector3.getX(), vector3.getY(), vector3.getZ(), seed);
}
/**
@@ -58,9 +69,19 @@ public interface BiomeProvider {
*
* @return {@link Iterable} of all biomes this provider can generate.
*/
@Contract(pure = true)
Iterable<Biome> getBiomes();
default BiomeProvider caching() {
return new CachingBiomeProvider(this);
@Contract(pure = true)
default Stream<Biome> stream() {
return StreamSupport.stream(getBiomes().spliterator(), false);
}
default BiomeProvider caching(int minY, int maxY) {
return new CachingBiomeProvider(this, minY, maxY);
}
default BiomeProvider caching(WorldProperties worldProperties) {
return caching(worldProperties.getMinHeight(), worldProperties.getMaxHeight());
}
}

View File

@@ -1,12 +1,12 @@
package com.dfsek.terra.api.world.biome.generation;
import java.util.HashMap;
import java.util.Map;
import com.dfsek.terra.api.Handle;
import com.dfsek.terra.api.util.MathUtil;
import com.dfsek.terra.api.world.biome.Biome;
import java.util.HashMap;
import java.util.Map;
/**
* A biome provider implementation that lazily evaluates biomes, and caches them.
@@ -15,10 +15,14 @@ import com.dfsek.terra.api.world.biome.Biome;
*/
public class CachingBiomeProvider implements BiomeProvider, Handle {
private final BiomeProvider delegate;
private final Map<Long, Biome> cache = new HashMap<>();
private final int minY;
private final int maxY;
private final Map<Long, Biome[]> cache = new HashMap<>();
protected CachingBiomeProvider(BiomeProvider delegate) {
protected CachingBiomeProvider(BiomeProvider delegate, int minY, int maxY) {
this.delegate = delegate;
this.minY = minY;
this.maxY = maxY;
}
@Override
@@ -27,8 +31,14 @@ public class CachingBiomeProvider implements BiomeProvider, Handle {
}
@Override
public Biome getBiome(int x, int z, long seed) {
return cache.computeIfAbsent(MathUtil.squash(x, z), key -> delegate.getBiome(x, z, seed));
public Biome getBiome(int x, int y, int z, long seed) {
if(y >= maxY || y < minY) throw new IllegalArgumentException("Y out of range: " + y + " (min: " + minY + ", max: " + maxY + ")");
Biome[] biomes = cache.computeIfAbsent(MathUtil.squash(x, z), key -> new Biome[maxY - minY]);
int yi = y - minY;
if(biomes[yi] == null) {
biomes[yi] = delegate.getBiome(x, y, z, seed);
}
return biomes[yi];
}
@Override