diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/NoiseChunkGenerator3DAddon.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/NoiseChunkGenerator3DAddon.java index c0a4fb934..45d2a6520 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/NoiseChunkGenerator3DAddon.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/NoiseChunkGenerator3DAddon.java @@ -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.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.PaletteInfo; import com.dfsek.terra.addons.chunkgenerator.config.palette.SlantLayer; import com.dfsek.terra.addons.chunkgenerator.generation.NoiseChunkGenerator3D; 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.functional.FunctionalEventHandler; 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.chunk.generation.util.provider.ChunkGeneratorProvider; @@ -32,6 +36,8 @@ public class NoiseChunkGenerator3DAddon implements AddonInitializer { @Override public void initialize() { + PropertyKey paletteInfoPropertyKey = Context.create(PaletteInfo.class); + PropertyKey noisePropertiesPropertyKey = Context.create(BiomeNoiseProperties.class); platform.getEventManager() .getHandler(FunctionalEventHandler.class) .register(addon, ConfigPackPreLoadEvent.class) @@ -43,7 +49,8 @@ public class NoiseChunkGenerator3DAddon implements AddonInitializer { .getOrCreateRegistry(ChunkGeneratorProvider.class) .register(addon.key("NOISE_3D"), 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() .applyLoader(SlantLayer.class, SlantLayer::new); }) @@ -54,8 +61,8 @@ public class NoiseChunkGenerator3DAddon implements AddonInitializer { .register(addon, ConfigurationLoadEvent.class) .then(event -> { if(event.is(Biome.class)) { - event.getLoadedObject(Biome.class).getContext().put(event.load(new BiomePaletteTemplate(platform)).get()); - event.getLoadedObject(Biome.class).getContext().put(event.load(new BiomeNoiseConfigTemplate()).get()); + event.getLoadedObject(Biome.class).getContext().put(paletteInfoPropertyKey, event.load(new BiomePaletteTemplate(platform)).get()); + event.getLoadedObject(Biome.class).getContext().put(noisePropertiesPropertyKey, event.load(new BiomeNoiseConfigTemplate()).get()); } }) .failThrough(); diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/NoiseChunkGenerator3D.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/NoiseChunkGenerator3D.java index 8cabf55ef..7d6ae9841 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/NoiseChunkGenerator3D.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/NoiseChunkGenerator3D.java @@ -8,6 +8,7 @@ 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.generation.math.PaletteUtil; 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.block.state.BlockState; 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.world.biome.Biome; import com.dfsek.terra.api.world.biome.generation.BiomeProvider; @@ -44,10 +45,13 @@ public class NoiseChunkGenerator3D implements ChunkGenerator { private final NoiseSampler paletteBlendSampler; private final double paletteBlendAmplitude; + private final PropertyKey paletteInfoPropertyKey; + private final PropertyKey noisePropertiesKey; public NoiseChunkGenerator3D(Platform platform, int elevationBlend, int carverHorizontalResolution, int carverVerticalResolution, int paletteRes, NoiseSampler paletteBlendSampler, - double paletteBlendAmplitude) { + double paletteBlendAmplitude, PropertyKey noisePropertiesKey, + PropertyKey paletteInfoPropertyKey) { this.platform = platform; this.air = platform.getWorldHandle().air(); this.carverHorizontalResolution = carverHorizontalResolution; @@ -55,7 +59,9 @@ public class NoiseChunkGenerator3D implements ChunkGenerator { this.paletteRes = paletteRes; this.paletteBlendSampler = paletteBlendSampler; 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) { @@ -88,7 +94,7 @@ public class NoiseChunkGenerator3D implements ChunkGenerator { chunkX, chunkZ, world.getMaxHeight(), - world.getMinHeight(), + noisePropertiesKey, world.getMinHeight(), carverHorizontalResolution, carverVerticalResolution, seed); @@ -105,7 +111,7 @@ public class NoiseChunkGenerator3D implements ChunkGenerator { for(int y = world.getMaxHeight() - 1; y >= world.getMinHeight(); y--) { 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(); Palette seaPalette = paletteInfo.ocean(); @@ -139,7 +145,7 @@ public class NoiseChunkGenerator3D implements ChunkGenerator { Biome biome = biomeProvider.getBiome(x, y, z, world.getSeed()); 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 fdZ = FastMath.floorMod(z, 16); @@ -160,7 +166,7 @@ public class NoiseChunkGenerator3D implements ChunkGenerator { @Override 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() { diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/ChunkInterpolator.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/ChunkInterpolator.java index 1b4e10879..c674253c0 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/ChunkInterpolator.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/ChunkInterpolator.java @@ -8,6 +8,7 @@ package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation; 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 net.jafama.FastMath; @@ -32,7 +33,7 @@ public class ChunkInterpolator { * @param min * @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 noisePropertiesKey) { this.min = min; this.max = max; @@ -57,7 +58,7 @@ public class ChunkInterpolator { int scaledY = (y << 2) + min; BiomeNoiseProperties generationSettings = provider.getBiome(absoluteX, scaledY, absoluteZ, seed) .getContext() - .get(BiomeNoiseProperties.class); + .get(noisePropertiesKey); int step = generationSettings.blendStep(); int blend = generationSettings.blendDistance(); @@ -70,7 +71,7 @@ public class ChunkInterpolator { BiomeNoiseProperties properties = provider .getBiome(absoluteX + (xi * step), scaledY, absoluteZ + (zi * step), seed) .getContext() - .get(BiomeNoiseProperties.class); + .get(noisePropertiesKey); double sample = properties.noiseHolder().getNoise(properties.base(), absoluteX, scaledY, absoluteZ, seed); runningNoise += sample * properties.blendWeight(); runningDiv += properties.blendWeight(); diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/ElevationInterpolator.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/ElevationInterpolator.java index 352ea7d1c..d4664673b 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/ElevationInterpolator.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/ElevationInterpolator.java @@ -8,13 +8,15 @@ package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation; 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; public class ElevationInterpolator { 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 noisePropertiesKey) { int xOrigin = chunkX << 4; int zOrigin = chunkZ << 4; @@ -30,7 +32,7 @@ public class ElevationInterpolator { .getBaseBiome(bx, bz, seed) .orElseGet(() -> provider.getBiome(bx, 0, bz, seed)) // kind of a hack .getContext() - .get(BiomeNoiseProperties.class); + .get(noisePropertiesKey); } } diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/LazilyEvaluatedInterpolator.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/LazilyEvaluatedInterpolator.java index acec30493..be72fb42f 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/LazilyEvaluatedInterpolator.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/LazilyEvaluatedInterpolator.java @@ -1,5 +1,7 @@ package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation; +import com.dfsek.terra.api.properties.PropertyKey; + import net.jafama.FastMath; import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties; @@ -18,13 +20,16 @@ public class LazilyEvaluatedInterpolator { private final int verticalRes; private final BiomeProvider biomeProvider; + private final PropertyKey noisePropertiesKey; private final long seed; private final int min; 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 noisePropertiesKey, int min, int horizontalRes, int verticalRes, long seed) { + this.noisePropertiesKey = noisePropertiesKey; int hSamples = FastMath.ceilToInt(16.0 / horizontalRes); int vSamples = FastMath.ceilToInt((double) (max - min) / verticalRes); this.zMul = (hSamples + 1); @@ -49,7 +54,7 @@ public class LazilyEvaluatedInterpolator { sample = biomeProvider .getBiome(xi, y, zi, seed) .getContext() - .get(BiomeNoiseProperties.class) + .get(noisePropertiesKey) .carving() .noise(seed, xi, oy, zi); samples[index] = sample; diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/samplers/Sampler3D.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/samplers/Sampler3D.java index ea98b0af6..1bca2d4a5 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/samplers/Sampler3D.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/samplers/Sampler3D.java @@ -7,6 +7,9 @@ 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 com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.ChunkInterpolator; @@ -18,10 +21,10 @@ public class Sampler3D { private final ChunkInterpolator interpolator; 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 noisePropertiesKey) { this.interpolator = new ChunkInterpolator(seed, x, z, provider, - minHeight, maxHeight); - this.elevationInterpolator = new ElevationInterpolator(seed, x, z, provider, elevationSmooth); + minHeight, maxHeight, noisePropertiesKey); + this.elevationInterpolator = new ElevationInterpolator(seed, x, z, provider, elevationSmooth, noisePropertiesKey); } public double sample(double x, double y, double z) { diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/samplers/SamplerProvider.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/samplers/SamplerProvider.java index 30fcb016a..7a8ca167e 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/samplers/SamplerProvider.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/samplers/SamplerProvider.java @@ -17,6 +17,9 @@ 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.CacheBuilder; import net.jafama.FastMath; @@ -31,10 +34,12 @@ import com.dfsek.terra.api.world.info.WorldProperties; public class SamplerProvider { private final Cache cache; private final int elevationSmooth; + private final PropertyKey noisePropertiesKey; - public SamplerProvider(Platform platform, int elevationSmooth) { + public SamplerProvider(Platform platform, int elevationSmooth, PropertyKey noisePropertiesKey) { this.elevationSmooth = elevationSmooth; cache = CacheBuilder.newBuilder().maximumSize(platform.getTerraConfig().getSamplerCache()).build(); + this.noisePropertiesKey = noisePropertiesKey; } public Sampler3D get(int x, int z, WorldProperties world, BiomeProvider provider) { @@ -48,7 +53,7 @@ public class SamplerProvider { try { return cache.get(context, () -> new Sampler3D(context.cx, context.cz, context.seed, context.minHeight, context.maxHeight, provider, - elevationSmooth)); + elevationSmooth, noisePropertiesKey)); } catch(ExecutionException e) { throw new RuntimeException(e); } diff --git a/common/api/src/main/java/com/dfsek/terra/api/properties/Context.java b/common/api/src/main/java/com/dfsek/terra/api/properties/Context.java index 3b7f1fa40..b5a1f408f 100644 --- a/common/api/src/main/java/com/dfsek/terra/api/properties/Context.java +++ b/common/api/src/main/java/com/dfsek/terra/api/properties/Context.java @@ -9,10 +9,15 @@ package com.dfsek.terra.api.properties; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; public class Context { private final Map, Properties> map = new HashMap<>(); + private final AtomicReference list = new AtomicReference<>(new Properties[size.get()]); + private static final AtomicInteger size = new AtomicInteger(0); + private static final Map, PropertyKey> properties = new HashMap<>(); @SuppressWarnings("unchecked") public T get(Class clazz) { @@ -28,6 +33,26 @@ public class Context { return this; } + @SuppressWarnings("unchecked") + public static PropertyKey create(Class clazz) { + return (PropertyKey) properties.computeIfAbsent(clazz, c -> new PropertyKey<>(size.getAndIncrement(), clazz)); + } + + public Context put(PropertyKey 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 get(PropertyKey key) { + return (T) list.get()[key.key]; + } + public boolean has(Class test) { return map.containsKey(test); } diff --git a/common/api/src/main/java/com/dfsek/terra/api/properties/PropertyKey.java b/common/api/src/main/java/com/dfsek/terra/api/properties/PropertyKey.java new file mode 100644 index 000000000..9c2daefe2 --- /dev/null +++ b/common/api/src/main/java/com/dfsek/terra/api/properties/PropertyKey.java @@ -0,0 +1,15 @@ +package com.dfsek.terra.api.properties; + +public class PropertyKey { + protected final int key; + private final Class clazz; + + protected PropertyKey(int key, Class clazz) { + this.key = key; + this.clazz = clazz; + } + + public Class getTypeClass() { + return clazz; + } +}