add alternative methods for interacting with Context

This commit is contained in:
dfsek
2022-06-16 01:53:02 -07:00
parent c83924a7a4
commit 80583e1596
9 changed files with 91 additions and 22 deletions
@@ -9,7 +9,9 @@ package com.dfsek.terra.addons.chunkgenerator;
import com.dfsek.terra.addons.chunkgenerator.config.NoiseChunkGeneratorPackConfigTemplate; import com.dfsek.terra.addons.chunkgenerator.config.NoiseChunkGeneratorPackConfigTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseConfigTemplate; import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseConfigTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties;
import com.dfsek.terra.addons.chunkgenerator.config.palette.BiomePaletteTemplate; import com.dfsek.terra.addons.chunkgenerator.config.palette.BiomePaletteTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.palette.PaletteInfo;
import com.dfsek.terra.addons.chunkgenerator.config.palette.SlantLayer; import com.dfsek.terra.addons.chunkgenerator.config.palette.SlantLayer;
import com.dfsek.terra.addons.chunkgenerator.generation.NoiseChunkGenerator3D; import com.dfsek.terra.addons.chunkgenerator.generation.NoiseChunkGenerator3D;
import com.dfsek.terra.addons.manifest.api.AddonInitializer; import com.dfsek.terra.addons.manifest.api.AddonInitializer;
@@ -19,6 +21,8 @@ import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent;
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent; import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent;
import com.dfsek.terra.api.event.functional.FunctionalEventHandler; import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
import com.dfsek.terra.api.inject.annotations.Inject; import com.dfsek.terra.api.inject.annotations.Inject;
import com.dfsek.terra.api.properties.Context;
import com.dfsek.terra.api.properties.PropertyKey;
import com.dfsek.terra.api.world.biome.Biome; import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.api.world.chunk.generation.util.provider.ChunkGeneratorProvider; import com.dfsek.terra.api.world.chunk.generation.util.provider.ChunkGeneratorProvider;
@@ -32,6 +36,8 @@ public class NoiseChunkGenerator3DAddon implements AddonInitializer {
@Override @Override
public void initialize() { public void initialize() {
PropertyKey<PaletteInfo> paletteInfoPropertyKey = Context.create(PaletteInfo.class);
PropertyKey<BiomeNoiseProperties> noisePropertiesPropertyKey = Context.create(BiomeNoiseProperties.class);
platform.getEventManager() platform.getEventManager()
.getHandler(FunctionalEventHandler.class) .getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPreLoadEvent.class) .register(addon, ConfigPackPreLoadEvent.class)
@@ -43,7 +49,8 @@ public class NoiseChunkGenerator3DAddon implements AddonInitializer {
.getOrCreateRegistry(ChunkGeneratorProvider.class) .getOrCreateRegistry(ChunkGeneratorProvider.class)
.register(addon.key("NOISE_3D"), .register(addon.key("NOISE_3D"),
pack -> new NoiseChunkGenerator3D(platform, config.getElevationBlend(), config.getHorizontalRes(), pack -> new NoiseChunkGenerator3D(platform, config.getElevationBlend(), config.getHorizontalRes(),
config.getVerticalRes(), config.getPaletteRes(), config.getPaletteBlendSampler(), config.getPaletteBlendAmplitude())); config.getVerticalRes(), config.getPaletteRes(), config.getPaletteBlendSampler(), config.getPaletteBlendAmplitude(),
noisePropertiesPropertyKey, paletteInfoPropertyKey));
event.getPack() event.getPack()
.applyLoader(SlantLayer.class, SlantLayer::new); .applyLoader(SlantLayer.class, SlantLayer::new);
}) })
@@ -54,8 +61,8 @@ public class NoiseChunkGenerator3DAddon implements AddonInitializer {
.register(addon, ConfigurationLoadEvent.class) .register(addon, ConfigurationLoadEvent.class)
.then(event -> { .then(event -> {
if(event.is(Biome.class)) { if(event.is(Biome.class)) {
event.getLoadedObject(Biome.class).getContext().put(event.load(new BiomePaletteTemplate(platform)).get()); event.getLoadedObject(Biome.class).getContext().put(paletteInfoPropertyKey, event.load(new BiomePaletteTemplate(platform)).get());
event.getLoadedObject(Biome.class).getContext().put(event.load(new BiomeNoiseConfigTemplate()).get()); event.getLoadedObject(Biome.class).getContext().put(noisePropertiesPropertyKey, event.load(new BiomeNoiseConfigTemplate()).get());
} }
}) })
.failThrough(); .failThrough();
@@ -8,6 +8,7 @@
package com.dfsek.terra.addons.chunkgenerator.generation; package com.dfsek.terra.addons.chunkgenerator.generation;
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties;
import com.dfsek.terra.addons.chunkgenerator.config.palette.PaletteInfo; import com.dfsek.terra.addons.chunkgenerator.config.palette.PaletteInfo;
import com.dfsek.terra.addons.chunkgenerator.generation.math.PaletteUtil; import com.dfsek.terra.addons.chunkgenerator.generation.math.PaletteUtil;
import com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.LazilyEvaluatedInterpolator; import com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.LazilyEvaluatedInterpolator;
@@ -16,7 +17,7 @@ import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.SamplerPro
import com.dfsek.terra.api.Platform; import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.block.state.BlockState; import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.noise.NoiseSampler; import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.Column; import com.dfsek.terra.api.properties.PropertyKey;
import com.dfsek.terra.api.util.MathUtil; import com.dfsek.terra.api.util.MathUtil;
import com.dfsek.terra.api.world.biome.Biome; import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
@@ -44,10 +45,13 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
private final NoiseSampler paletteBlendSampler; private final NoiseSampler paletteBlendSampler;
private final double paletteBlendAmplitude; private final double paletteBlendAmplitude;
private final PropertyKey<PaletteInfo> paletteInfoPropertyKey;
private final PropertyKey<BiomeNoiseProperties> noisePropertiesKey;
public NoiseChunkGenerator3D(Platform platform, int elevationBlend, int carverHorizontalResolution, public NoiseChunkGenerator3D(Platform platform, int elevationBlend, int carverHorizontalResolution,
int carverVerticalResolution, int paletteRes, NoiseSampler paletteBlendSampler, int carverVerticalResolution, int paletteRes, NoiseSampler paletteBlendSampler,
double paletteBlendAmplitude) { double paletteBlendAmplitude, PropertyKey<BiomeNoiseProperties> noisePropertiesKey,
PropertyKey<PaletteInfo> paletteInfoPropertyKey) {
this.platform = platform; this.platform = platform;
this.air = platform.getWorldHandle().air(); this.air = platform.getWorldHandle().air();
this.carverHorizontalResolution = carverHorizontalResolution; this.carverHorizontalResolution = carverHorizontalResolution;
@@ -55,7 +59,9 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
this.paletteRes = paletteRes; this.paletteRes = paletteRes;
this.paletteBlendSampler = paletteBlendSampler; this.paletteBlendSampler = paletteBlendSampler;
this.paletteBlendAmplitude = paletteBlendAmplitude; this.paletteBlendAmplitude = paletteBlendAmplitude;
this.samplerCache = new SamplerProvider(platform, elevationBlend); this.paletteInfoPropertyKey = paletteInfoPropertyKey;
this.noisePropertiesKey = noisePropertiesKey;
this.samplerCache = new SamplerProvider(platform, elevationBlend, noisePropertiesKey);
} }
private Biome getBiome(int min, int max, double noiseX, double noiseZ, BiomeProvider biomeProvider, int x, int y, int z, long seed) { private Biome getBiome(int min, int max, double noiseX, double noiseZ, BiomeProvider biomeProvider, int x, int y, int z, long seed) {
@@ -88,7 +94,7 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
chunkX, chunkX,
chunkZ, chunkZ,
world.getMaxHeight(), world.getMaxHeight(),
world.getMinHeight(), noisePropertiesKey, world.getMinHeight(),
carverHorizontalResolution, carverHorizontalResolution,
carverVerticalResolution, carverVerticalResolution,
seed); seed);
@@ -105,7 +111,7 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
for(int y = world.getMaxHeight() - 1; y >= world.getMinHeight(); y--) { for(int y = world.getMaxHeight() - 1; y >= world.getMinHeight(); y--) {
Biome biome = getBiome(min, max, paletteNoiseX, paletteNoiseZ, biomeProvider, cx, y, cz, seed); Biome biome = getBiome(min, max, paletteNoiseX, paletteNoiseZ, biomeProvider, cx, y, cz, seed);
PaletteInfo paletteInfo = biome.getContext().get(PaletteInfo.class); PaletteInfo paletteInfo = biome.getContext().get(paletteInfoPropertyKey);
int sea = paletteInfo.seaLevel(); int sea = paletteInfo.seaLevel();
Palette seaPalette = paletteInfo.ocean(); Palette seaPalette = paletteInfo.ocean();
@@ -139,7 +145,7 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
Biome biome = biomeProvider.getBiome(x, y, z, world.getSeed()); Biome biome = biomeProvider.getBiome(x, y, z, world.getSeed());
Sampler3D sampler = samplerCache.get(x, z, world, biomeProvider); Sampler3D sampler = samplerCache.get(x, z, world, biomeProvider);
PaletteInfo paletteInfo = biome.getContext().get(PaletteInfo.class); PaletteInfo paletteInfo = biome.getContext().get(paletteInfoPropertyKey);
int fdX = FastMath.floorMod(x, 16); int fdX = FastMath.floorMod(x, 16);
int fdZ = FastMath.floorMod(z, 16); int fdZ = FastMath.floorMod(z, 16);
@@ -160,7 +166,7 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
@Override @Override
public Palette getPalette(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) { public Palette getPalette(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) {
return biomeProvider.getBiome(x, y, z, world.getSeed()).getContext().get(PaletteInfo.class).paletteHolder().getPalette(y); return biomeProvider.getBiome(x, y, z, world.getSeed()).getContext().get(paletteInfoPropertyKey).paletteHolder().getPalette(y);
} }
public SamplerProvider samplerProvider() { public SamplerProvider samplerProvider() {
@@ -8,6 +8,7 @@
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation; package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties; import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties;
import com.dfsek.terra.api.properties.PropertyKey;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import net.jafama.FastMath; import net.jafama.FastMath;
@@ -32,7 +33,7 @@ public class ChunkInterpolator {
* @param min * @param min
* @param max * @param max
*/ */
public ChunkInterpolator(long seed, int chunkX, int chunkZ, BiomeProvider provider, int min, int max) { public ChunkInterpolator(long seed, int chunkX, int chunkZ, BiomeProvider provider, int min, int max, PropertyKey<BiomeNoiseProperties> noisePropertiesKey) {
this.min = min; this.min = min;
this.max = max; this.max = max;
@@ -57,7 +58,7 @@ public class ChunkInterpolator {
int scaledY = (y << 2) + min; int scaledY = (y << 2) + min;
BiomeNoiseProperties generationSettings = provider.getBiome(absoluteX, scaledY, absoluteZ, seed) BiomeNoiseProperties generationSettings = provider.getBiome(absoluteX, scaledY, absoluteZ, seed)
.getContext() .getContext()
.get(BiomeNoiseProperties.class); .get(noisePropertiesKey);
int step = generationSettings.blendStep(); int step = generationSettings.blendStep();
int blend = generationSettings.blendDistance(); int blend = generationSettings.blendDistance();
@@ -70,7 +71,7 @@ public class ChunkInterpolator {
BiomeNoiseProperties properties = provider BiomeNoiseProperties properties = provider
.getBiome(absoluteX + (xi * step), scaledY, absoluteZ + (zi * step), seed) .getBiome(absoluteX + (xi * step), scaledY, absoluteZ + (zi * step), seed)
.getContext() .getContext()
.get(BiomeNoiseProperties.class); .get(noisePropertiesKey);
double sample = properties.noiseHolder().getNoise(properties.base(), absoluteX, scaledY, absoluteZ, seed); double sample = properties.noiseHolder().getNoise(properties.base(), absoluteX, scaledY, absoluteZ, seed);
runningNoise += sample * properties.blendWeight(); runningNoise += sample * properties.blendWeight();
runningDiv += properties.blendWeight(); runningDiv += properties.blendWeight();
@@ -8,13 +8,15 @@
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation; package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties; import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties;
import com.dfsek.terra.api.properties.PropertyKey;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class ElevationInterpolator { public class ElevationInterpolator {
private final double[][] values = new double[18][18]; private final double[][] values = new double[18][18];
public ElevationInterpolator(long seed, int chunkX, int chunkZ, BiomeProvider provider, int smooth) { public ElevationInterpolator(long seed, int chunkX, int chunkZ, BiomeProvider provider, int smooth,
PropertyKey<BiomeNoiseProperties> noisePropertiesKey) {
int xOrigin = chunkX << 4; int xOrigin = chunkX << 4;
int zOrigin = chunkZ << 4; int zOrigin = chunkZ << 4;
@@ -30,7 +32,7 @@ public class ElevationInterpolator {
.getBaseBiome(bx, bz, seed) .getBaseBiome(bx, bz, seed)
.orElseGet(() -> provider.getBiome(bx, 0, bz, seed)) // kind of a hack .orElseGet(() -> provider.getBiome(bx, 0, bz, seed)) // kind of a hack
.getContext() .getContext()
.get(BiomeNoiseProperties.class); .get(noisePropertiesKey);
} }
} }
@@ -1,5 +1,7 @@
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation; package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
import com.dfsek.terra.api.properties.PropertyKey;
import net.jafama.FastMath; import net.jafama.FastMath;
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties; import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties;
@@ -18,13 +20,16 @@ public class LazilyEvaluatedInterpolator {
private final int verticalRes; private final int verticalRes;
private final BiomeProvider biomeProvider; private final BiomeProvider biomeProvider;
private final PropertyKey<BiomeNoiseProperties> noisePropertiesKey;
private final long seed; private final long seed;
private final int min; private final int min;
private final int zMul, yMul; private final int zMul, yMul;
public LazilyEvaluatedInterpolator(BiomeProvider biomeProvider, int cx, int cz, int max, int min, int horizontalRes, int verticalRes, public LazilyEvaluatedInterpolator(BiomeProvider biomeProvider, int cx, int cz, int max,
PropertyKey<BiomeNoiseProperties> noisePropertiesKey, int min, int horizontalRes, int verticalRes,
long seed) { long seed) {
this.noisePropertiesKey = noisePropertiesKey;
int hSamples = FastMath.ceilToInt(16.0 / horizontalRes); int hSamples = FastMath.ceilToInt(16.0 / horizontalRes);
int vSamples = FastMath.ceilToInt((double) (max - min) / verticalRes); int vSamples = FastMath.ceilToInt((double) (max - min) / verticalRes);
this.zMul = (hSamples + 1); this.zMul = (hSamples + 1);
@@ -49,7 +54,7 @@ public class LazilyEvaluatedInterpolator {
sample = biomeProvider sample = biomeProvider
.getBiome(xi, y, zi, seed) .getBiome(xi, y, zi, seed)
.getContext() .getContext()
.get(BiomeNoiseProperties.class) .get(noisePropertiesKey)
.carving() .carving()
.noise(seed, xi, oy, zi); .noise(seed, xi, oy, zi);
samples[index] = sample; samples[index] = sample;
@@ -7,6 +7,9 @@
package com.dfsek.terra.addons.chunkgenerator.generation.math.samplers; package com.dfsek.terra.addons.chunkgenerator.generation.math.samplers;
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties;
import com.dfsek.terra.api.properties.PropertyKey;
import net.jafama.FastMath; import net.jafama.FastMath;
import com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.ChunkInterpolator; import com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.ChunkInterpolator;
@@ -18,10 +21,10 @@ public class Sampler3D {
private final ChunkInterpolator interpolator; private final ChunkInterpolator interpolator;
private final ElevationInterpolator elevationInterpolator; private final ElevationInterpolator elevationInterpolator;
public Sampler3D(int x, int z, long seed, int minHeight, int maxHeight, BiomeProvider provider, int elevationSmooth) { public Sampler3D(int x, int z, long seed, int minHeight, int maxHeight, BiomeProvider provider, int elevationSmooth, PropertyKey<BiomeNoiseProperties> noisePropertiesKey) {
this.interpolator = new ChunkInterpolator(seed, x, z, provider, this.interpolator = new ChunkInterpolator(seed, x, z, provider,
minHeight, maxHeight); minHeight, maxHeight, noisePropertiesKey);
this.elevationInterpolator = new ElevationInterpolator(seed, x, z, provider, elevationSmooth); this.elevationInterpolator = new ElevationInterpolator(seed, x, z, provider, elevationSmooth, noisePropertiesKey);
} }
public double sample(double x, double y, double z) { public double sample(double x, double y, double z) {
@@ -17,6 +17,9 @@
package com.dfsek.terra.addons.chunkgenerator.generation.math.samplers; package com.dfsek.terra.addons.chunkgenerator.generation.math.samplers;
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties;
import com.dfsek.terra.api.properties.PropertyKey;
import com.google.common.cache.Cache; import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import net.jafama.FastMath; import net.jafama.FastMath;
@@ -31,10 +34,12 @@ import com.dfsek.terra.api.world.info.WorldProperties;
public class SamplerProvider { public class SamplerProvider {
private final Cache<WorldContext, Sampler3D> cache; private final Cache<WorldContext, Sampler3D> cache;
private final int elevationSmooth; private final int elevationSmooth;
private final PropertyKey<BiomeNoiseProperties> noisePropertiesKey;
public SamplerProvider(Platform platform, int elevationSmooth) { public SamplerProvider(Platform platform, int elevationSmooth, PropertyKey<BiomeNoiseProperties> noisePropertiesKey) {
this.elevationSmooth = elevationSmooth; this.elevationSmooth = elevationSmooth;
cache = CacheBuilder.newBuilder().maximumSize(platform.getTerraConfig().getSamplerCache()).build(); cache = CacheBuilder.newBuilder().maximumSize(platform.getTerraConfig().getSamplerCache()).build();
this.noisePropertiesKey = noisePropertiesKey;
} }
public Sampler3D get(int x, int z, WorldProperties world, BiomeProvider provider) { public Sampler3D get(int x, int z, WorldProperties world, BiomeProvider provider) {
@@ -48,7 +53,7 @@ public class SamplerProvider {
try { try {
return cache.get(context, return cache.get(context,
() -> new Sampler3D(context.cx, context.cz, context.seed, context.minHeight, context.maxHeight, provider, () -> new Sampler3D(context.cx, context.cz, context.seed, context.minHeight, context.maxHeight, provider,
elevationSmooth)); elevationSmooth, noisePropertiesKey));
} catch(ExecutionException e) { } catch(ExecutionException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@@ -9,10 +9,15 @@ package com.dfsek.terra.api.properties;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
public class Context { public class Context {
private final Map<Class<? extends Properties>, Properties> map = new HashMap<>(); private final Map<Class<? extends Properties>, Properties> map = new HashMap<>();
private final AtomicReference<Properties[]> list = new AtomicReference<>(new Properties[size.get()]);
private static final AtomicInteger size = new AtomicInteger(0);
private static final Map<Class<? extends Properties>, PropertyKey<?>> properties = new HashMap<>();
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T extends Properties> T get(Class<T> clazz) { public <T extends Properties> T get(Class<T> clazz) {
@@ -28,6 +33,26 @@ public class Context {
return this; return this;
} }
@SuppressWarnings("unchecked")
public static <T extends Properties> PropertyKey<T> create(Class<T> clazz) {
return (PropertyKey<T>) properties.computeIfAbsent(clazz, c -> new PropertyKey<>(size.getAndIncrement(), clazz));
}
public <T extends Properties> Context put(PropertyKey<T> key, T properties) {
list.updateAndGet(p -> {
if(p.length == size.get()) return p;
Properties[] p2 = new Properties[size.get()];
System.arraycopy(p, 0, p2, 0, p.length);
return p2;
})[key.key] = properties;
return this;
}
@SuppressWarnings("unchecked")
public <T extends Properties> T get(PropertyKey<T> key) {
return (T) list.get()[key.key];
}
public <T extends Properties> boolean has(Class<T> test) { public <T extends Properties> boolean has(Class<T> test) {
return map.containsKey(test); return map.containsKey(test);
} }
@@ -0,0 +1,15 @@
package com.dfsek.terra.api.properties;
public class PropertyKey<T extends Properties> {
protected final int key;
private final Class<T> clazz;
protected PropertyKey(int key, Class<T> clazz) {
this.key = key;
this.clazz = clazz;
}
public Class<T> getTypeClass() {
return clazz;
}
}