completely redo noise config loading (mostly keeps parity with old configs)

This commit is contained in:
dfsek
2021-01-29 01:52:12 -07:00
parent dddf644c34
commit 02d61d0764
28 changed files with 261 additions and 181 deletions
@@ -1,8 +1,8 @@
package com.dfsek.terra.api.math.noise; package com.dfsek.terra.api.math.noise;
import com.dfsek.terra.api.math.noise.samplers.NoiseSampler; import com.dfsek.terra.api.math.noise.samplers.NoiseSampler;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.util.hash.HashMapDoubleDouble; import com.dfsek.terra.util.hash.HashMapDoubleDouble;
import com.dfsek.terra.world.generation.config.NoiseBuilder;
import parsii.eval.Expression; import parsii.eval.Expression;
import java.util.List; import java.util.List;
@@ -11,8 +11,8 @@ public class NoiseFunction2 implements NoiseFunction {
private final NoiseSampler gen; private final NoiseSampler gen;
private final Cache cache = new Cache(); private final Cache cache = new Cache();
public NoiseFunction2(long seed, NoiseBuilder builder) { public NoiseFunction2(long seed, NoiseSeeded builder) {
this.gen = builder.build((int) seed); this.gen = builder.apply(seed);
} }
@Override @Override
@@ -1,7 +1,7 @@
package com.dfsek.terra.api.math.noise; package com.dfsek.terra.api.math.noise;
import com.dfsek.terra.api.math.noise.samplers.NoiseSampler; import com.dfsek.terra.api.math.noise.samplers.NoiseSampler;
import com.dfsek.terra.world.generation.config.NoiseBuilder; import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import parsii.eval.Expression; import parsii.eval.Expression;
import java.util.List; import java.util.List;
@@ -9,8 +9,8 @@ import java.util.List;
public class NoiseFunction3 implements NoiseFunction { public class NoiseFunction3 implements NoiseFunction {
private final NoiseSampler gen; private final NoiseSampler gen;
public NoiseFunction3(long seed, NoiseBuilder builder) { public NoiseFunction3(long seed, NoiseSeeded builder) {
this.gen = builder.build((int) seed); this.gen = builder.apply(seed);
} }
@Override @Override
@@ -32,6 +32,6 @@ public abstract class Normalizer implements NoiseSampler {
} }
public enum NormalType { public enum NormalType {
LINEAR, NONE, NORMAL LINEAR, NORMAL
} }
} }
@@ -3,7 +3,7 @@ package com.dfsek.terra.api.math.noise.samplers;
import com.dfsek.terra.api.math.noise.NoiseFunction2; import com.dfsek.terra.api.math.noise.NoiseFunction2;
import com.dfsek.terra.api.math.noise.NoiseFunction3; import com.dfsek.terra.api.math.noise.NoiseFunction3;
import com.dfsek.terra.api.math.parsii.RandomFunction; import com.dfsek.terra.api.math.parsii.RandomFunction;
import com.dfsek.terra.world.generation.config.NoiseBuilder; import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import parsii.eval.Expression; import parsii.eval.Expression;
import parsii.eval.Parser; import parsii.eval.Parser;
import parsii.eval.Scope; import parsii.eval.Scope;
@@ -21,7 +21,7 @@ public class ExpressionSampler implements NoiseSampler {
private final Variable y; private final Variable y;
private final Variable z; private final Variable z;
public ExpressionSampler(String equation, Scope parent, long seed, Map<String, NoiseBuilder> functions) throws ParseException { public ExpressionSampler(String equation, Scope parent, long seed, Map<String, NoiseSeeded> functions) throws ParseException {
Parser parser = new Parser(); Parser parser = new Parser();
Scope scope = new Scope().withParent(parent); Scope scope = new Scope().withParent(parent);
@@ -9,14 +9,14 @@ public interface NoiseSampler {
* <p> * <p>
* Noise output bounded between -1...1 * Noise output bounded between -1...1
*/ */
double getNoise(/*FNLdouble*/ double x, /*FNLdouble*/ double y); double getNoise(double x, double y);
/** /**
* 3D noise at given position using current settings * 3D noise at given position using current settings
* <p> * <p>
* Noise output bounded between -1...1 * Noise output bounded between -1...1
*/ */
double getNoise(/*FNLdouble*/ double x, /*FNLdouble*/ double y, /*FNLdouble*/ double z); double getNoise(double x, double y, double z);
default double getNoise(Vector3 vector3) { default double getNoise(Vector3 vector3) {
return getNoise(vector3.getX(), vector3.getY(), vector3.getZ()); return getNoise(vector3.getX(), vector3.getY(), vector3.getZ());
@@ -0,0 +1,10 @@
package com.dfsek.terra.api.util.seeded;
import com.dfsek.terra.api.math.noise.samplers.NoiseSampler;
public interface NoiseSeeded extends SeededBuilder<NoiseSampler> {
@Override
NoiseSampler apply(Long seed);
int getDimensions();
}
@@ -0,0 +1,7 @@
package com.dfsek.terra.api.util.seeded;
import java.util.function.Function;
public interface SeededBuilder<T> extends Function<Long, T> {
}
@@ -2,8 +2,8 @@ package com.dfsek.terra.biome.pipeline;
import com.dfsek.terra.api.math.vector.Vector2; import com.dfsek.terra.api.math.vector.Vector2;
import com.dfsek.terra.api.util.GlueList; import com.dfsek.terra.api.util.GlueList;
import com.dfsek.terra.api.util.seeded.SeededBuilder;
import com.dfsek.terra.biome.pipeline.source.BiomeSource; import com.dfsek.terra.biome.pipeline.source.BiomeSource;
import com.dfsek.terra.biome.pipeline.stages.SeededBuilder;
import com.dfsek.terra.biome.pipeline.stages.Stage; import com.dfsek.terra.biome.pipeline.stages.Stage;
import java.util.List; import java.util.List;
@@ -51,7 +51,7 @@ public class BiomePipeline {
} }
public BiomePipeline build(BiomeSource source, long seed) { public BiomePipeline build(BiomeSource source, long seed) {
List<Stage> stagesBuilt = stages.stream().map(stageBuilder -> stageBuilder.build(seed)).collect(Collectors.toList()); List<Stage> stagesBuilt = stages.stream().map(stageBuilder -> stageBuilder.apply(seed)).collect(Collectors.toList());
for(Stage stage : stagesBuilt) { for(Stage stage : stagesBuilt) {
if(stage.isExpansion()) expand = expand * 2 - 1; if(stage.isExpansion()) expand = expand * 2 - 1;
@@ -1,15 +0,0 @@
package com.dfsek.terra.biome.pipeline.stages;
import java.util.function.Function;
public class SeededBuilder<T> {
private final Function<Long, T> builder;
public SeededBuilder(Function<Long, T> builder) {
this.builder = builder;
}
public T build(long seed) {
return builder.apply(seed);
}
}
@@ -4,10 +4,10 @@ import com.dfsek.tectonic.exception.ConfigException;
import com.dfsek.terra.api.core.TerraPlugin; import com.dfsek.terra.api.core.TerraPlugin;
import com.dfsek.terra.api.math.noise.samplers.NoiseSampler; import com.dfsek.terra.api.math.noise.samplers.NoiseSampler;
import com.dfsek.terra.api.math.vector.Vector2; import com.dfsek.terra.api.math.vector.Vector2;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.biome.TerraBiome; import com.dfsek.terra.biome.TerraBiome;
import com.dfsek.terra.biome.pipeline.BiomeHolder; import com.dfsek.terra.biome.pipeline.BiomeHolder;
import com.dfsek.terra.biome.pipeline.BiomePipeline; import com.dfsek.terra.biome.pipeline.BiomePipeline;
import com.dfsek.terra.world.generation.config.NoiseBuilder;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
@@ -65,7 +65,7 @@ public class StandardBiomeProvider implements BiomeProvider {
private final TerraPlugin main; private final TerraPlugin main;
private int resolution = 1; private int resolution = 1;
private int noiseAmp = 2; private int noiseAmp = 2;
private NoiseBuilder builder = new NoiseBuilder(); private NoiseSeeded builder;
public StandardBiomeProviderBuilder(ExceptionalFunction<Long, BiomePipeline> pipelineBuilder, TerraPlugin main) { public StandardBiomeProviderBuilder(ExceptionalFunction<Long, BiomePipeline> pipelineBuilder, TerraPlugin main) {
this.pipelineBuilder = pipelineBuilder; this.pipelineBuilder = pipelineBuilder;
@@ -76,7 +76,7 @@ public class StandardBiomeProvider implements BiomeProvider {
this.resolution = resolution; this.resolution = resolution;
} }
public void setBlender(NoiseBuilder builder) { public void setBlender(NoiseSeeded builder) {
this.builder = builder; this.builder = builder;
} }
@@ -87,7 +87,7 @@ public class StandardBiomeProvider implements BiomeProvider {
@Override @Override
public StandardBiomeProvider build(long seed) { public StandardBiomeProvider build(long seed) {
try { try {
StandardBiomeProvider provider = new StandardBiomeProvider(pipelineBuilder.apply(seed), main, builder.build((int) seed), builder.build((int) (seed + 1)), noiseAmp); StandardBiomeProvider provider = new StandardBiomeProvider(pipelineBuilder.apply(seed), main, builder.apply(seed), builder.apply((seed + 1)), noiseAmp);
provider.setResolution(resolution); provider.setResolution(resolution);
return provider; return provider;
} catch(ConfigException e) { } catch(ConfigException e) {
@@ -7,6 +7,8 @@ import com.dfsek.terra.api.math.GridSpawn;
import com.dfsek.terra.api.math.ProbabilityCollection; import com.dfsek.terra.api.math.ProbabilityCollection;
import com.dfsek.terra.api.math.Range; import com.dfsek.terra.api.math.Range;
import com.dfsek.terra.api.math.noise.normalizer.Normalizer; import com.dfsek.terra.api.math.noise.normalizer.Normalizer;
import com.dfsek.terra.api.math.noise.samplers.FastNoiseLite;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.api.world.palette.holder.PaletteHolder; import com.dfsek.terra.api.world.palette.holder.PaletteHolder;
import com.dfsek.terra.api.world.palette.holder.PaletteLayerHolder; import com.dfsek.terra.api.world.palette.holder.PaletteLayerHolder;
import com.dfsek.terra.config.loaders.MaterialSetLoader; import com.dfsek.terra.config.loaders.MaterialSetLoader;
@@ -14,14 +16,13 @@ import com.dfsek.terra.config.loaders.ProbabilityCollectionLoader;
import com.dfsek.terra.config.loaders.RangeLoader; import com.dfsek.terra.config.loaders.RangeLoader;
import com.dfsek.terra.config.loaders.config.FloraLayerLoader; import com.dfsek.terra.config.loaders.config.FloraLayerLoader;
import com.dfsek.terra.config.loaders.config.GridSpawnLoader; import com.dfsek.terra.config.loaders.config.GridSpawnLoader;
import com.dfsek.terra.config.loaders.config.NoiseBuilderLoader;
import com.dfsek.terra.config.loaders.config.OreConfigLoader; import com.dfsek.terra.config.loaders.config.OreConfigLoader;
import com.dfsek.terra.config.loaders.config.OreHolderLoader; import com.dfsek.terra.config.loaders.config.OreHolderLoader;
import com.dfsek.terra.config.loaders.config.TreeLayerLoader; import com.dfsek.terra.config.loaders.config.TreeLayerLoader;
import com.dfsek.terra.config.loaders.config.sampler.NoiseSamplerBuilderLoader;
import com.dfsek.terra.config.loaders.palette.PaletteHolderLoader; import com.dfsek.terra.config.loaders.palette.PaletteHolderLoader;
import com.dfsek.terra.config.loaders.palette.PaletteLayerLoader; import com.dfsek.terra.config.loaders.palette.PaletteLayerLoader;
import com.dfsek.terra.util.MaterialSet; import com.dfsek.terra.util.MaterialSet;
import com.dfsek.terra.world.generation.config.NoiseBuilder;
import com.dfsek.terra.world.population.items.flora.FloraLayer; import com.dfsek.terra.world.population.items.flora.FloraLayer;
import com.dfsek.terra.world.population.items.flora.TerraFlora; import com.dfsek.terra.world.population.items.flora.TerraFlora;
import com.dfsek.terra.world.population.items.ores.Ore; import com.dfsek.terra.world.population.items.ores.Ore;
@@ -46,11 +47,18 @@ public class GenericLoaders implements LoaderRegistrar {
.registerLoader(FloraLayer.class, new FloraLayerLoader()) .registerLoader(FloraLayer.class, new FloraLayerLoader())
.registerLoader(Ore.Type.class, (t, o, l) -> Ore.Type.valueOf(o.toString())) .registerLoader(Ore.Type.class, (t, o, l) -> Ore.Type.valueOf(o.toString()))
.registerLoader(OreConfig.class, new OreConfigLoader()) .registerLoader(OreConfig.class, new OreConfigLoader())
.registerLoader(NoiseBuilder.class, new NoiseBuilderLoader())
.registerLoader(TreeLayer.class, new TreeLayerLoader()) .registerLoader(TreeLayer.class, new TreeLayerLoader())
.registerLoader(MaterialSet.class, new MaterialSetLoader()) .registerLoader(MaterialSet.class, new MaterialSetLoader())
.registerLoader(OreHolder.class, new OreHolderLoader()) .registerLoader(OreHolder.class, new OreHolderLoader())
.registerLoader(FastNoiseLite.NoiseType.class, (t, object, cf) -> FastNoiseLite.NoiseType.valueOf((String) object))
.registerLoader(FastNoiseLite.FractalType.class, (t, object, cf) -> FastNoiseLite.FractalType.valueOf((String) object))
.registerLoader(FastNoiseLite.DomainWarpType.class, (t, object, cf) -> FastNoiseLite.DomainWarpType.valueOf((String) object))
.registerLoader(FastNoiseLite.RotationType3D.class, (t, object, cf) -> FastNoiseLite.RotationType3D.valueOf((String) object))
.registerLoader(FastNoiseLite.CellularReturnType.class, (t, object, cf) -> FastNoiseLite.CellularReturnType.valueOf((String) object))
.registerLoader(FastNoiseLite.CellularDistanceFunction.class, (t, object, cf) -> FastNoiseLite.CellularDistanceFunction.valueOf((String) object))
.registerLoader(Normalizer.NormalType.class, (t, o, l) -> Normalizer.NormalType.valueOf(o.toString().toUpperCase()))
.registerLoader(TerraFlora.Search.class, (t, o, l) -> TerraFlora.Search.valueOf(o.toString())) .registerLoader(TerraFlora.Search.class, (t, o, l) -> TerraFlora.Search.valueOf(o.toString()))
.registerLoader(Normalizer.NormalType.class, (t, o, l) -> Normalizer.NormalType.valueOf(o.toString().toUpperCase())); .registerLoader(Normalizer.NormalType.class, (t, o, l) -> Normalizer.NormalType.valueOf(o.toString().toUpperCase()))
.registerLoader(NoiseSeeded.class, new NoiseSamplerBuilderLoader());
} }
} }
@@ -3,9 +3,9 @@ package com.dfsek.terra.config.builder;
import com.dfsek.terra.api.math.noise.samplers.ConstantSampler; import com.dfsek.terra.api.math.noise.samplers.ConstantSampler;
import com.dfsek.terra.api.math.noise.samplers.ExpressionSampler; import com.dfsek.terra.api.math.noise.samplers.ExpressionSampler;
import com.dfsek.terra.api.math.noise.samplers.NoiseSampler; import com.dfsek.terra.api.math.noise.samplers.NoiseSampler;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.api.world.palette.holder.PaletteHolder; import com.dfsek.terra.api.world.palette.holder.PaletteHolder;
import com.dfsek.terra.world.generation.WorldGenerator; import com.dfsek.terra.world.generation.WorldGenerator;
import com.dfsek.terra.world.generation.config.NoiseBuilder;
import parsii.eval.Scope; import parsii.eval.Scope;
import parsii.tokenizer.ParseException; import parsii.tokenizer.ParseException;
@@ -24,7 +24,7 @@ public class GeneratorBuilder {
private Scope varScope; private Scope varScope;
private Map<String, NoiseBuilder> noiseBuilderMap; private Map<String, NoiseSeeded> noiseBuilderMap;
private PaletteHolder palettes; private PaletteHolder palettes;
@@ -34,7 +34,7 @@ public class GeneratorBuilder {
private boolean interpolateElevation; private boolean interpolateElevation;
private NoiseBuilder biomeNoise; private NoiseSeeded biomeNoise;
private double elevationWeight; private double elevationWeight;
@@ -57,7 +57,7 @@ public class GeneratorBuilder {
} catch(ParseException e) { } catch(ParseException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
return new WorldGenerator(palettes, slantPalettes, noise, elevation, carving, biomeNoise.build((int) seed), elevationWeight, blendDistance, blendStep, blendWeight); return new WorldGenerator(palettes, slantPalettes, noise, elevation, carving, biomeNoise.apply(seed), elevationWeight, blendDistance, blendStep, blendWeight);
}); });
} }
} }
@@ -74,7 +74,7 @@ public class GeneratorBuilder {
this.blendDistance = blendDistance; this.blendDistance = blendDistance;
} }
public void setBiomeNoise(NoiseBuilder biomeNoise) { public void setBiomeNoise(NoiseSeeded biomeNoise) {
this.biomeNoise = biomeNoise; this.biomeNoise = biomeNoise;
} }
@@ -102,11 +102,7 @@ public class GeneratorBuilder {
this.varScope = varScope; this.varScope = varScope;
} }
public Map<String, NoiseBuilder> getNoiseBuilderMap() { public void setNoiseBuilderMap(Map<String, NoiseSeeded> noiseBuilderMap) {
return noiseBuilderMap;
}
public void setNoiseBuilderMap(Map<String, NoiseBuilder> noiseBuilderMap) {
this.noiseBuilderMap = noiseBuilderMap; this.noiseBuilderMap = noiseBuilderMap;
} }
@@ -10,7 +10,7 @@ import com.dfsek.terra.config.templates.PaletteTemplate;
public class PaletteFactory implements TerraFactory<PaletteTemplate, Palette<BlockData>> { public class PaletteFactory implements TerraFactory<PaletteTemplate, Palette<BlockData>> {
@Override @Override
public Palette<BlockData> build(PaletteTemplate config, TerraPlugin main) { public Palette<BlockData> build(PaletteTemplate config, TerraPlugin main) {
NoisePalette<BlockData> palette = new NoisePalette<>(config.getNoise().build(2403), config.getNoise().getDimensions() == 2); NoisePalette<BlockData> palette = new NoisePalette<>(config.getNoise().apply(2403L), config.getNoise().getDimensions() == 2);
for(PaletteLayerHolder layer : config.getPalette()) { for(PaletteLayerHolder layer : config.getPalette()) {
palette.add(layer.getLayer(), layer.getSize(), layer.getSampler()); palette.add(layer.getLayer(), layer.getSize(), layer.getSampler());
} }
@@ -7,6 +7,7 @@ import com.dfsek.tectonic.loading.TypeLoader;
import com.dfsek.terra.api.math.ProbabilityCollection; import com.dfsek.terra.api.math.ProbabilityCollection;
import com.dfsek.terra.api.math.Range; import com.dfsek.terra.api.math.Range;
import com.dfsek.terra.api.math.noise.samplers.FastNoiseLite; import com.dfsek.terra.api.math.noise.samplers.FastNoiseLite;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.api.world.flora.Flora; import com.dfsek.terra.api.world.flora.Flora;
import com.dfsek.terra.config.loaders.Types; import com.dfsek.terra.config.loaders.Types;
import com.dfsek.terra.world.generation.config.NoiseBuilder; import com.dfsek.terra.world.generation.config.NoiseBuilder;
@@ -25,19 +26,19 @@ public class FloraLayerLoader implements TypeLoader<FloraLayer> {
if(range == null) throw new LoadException("Flora range unspecified"); if(range == null) throw new LoadException("Flora range unspecified");
ProbabilityCollection<Flora> items = (ProbabilityCollection<Flora>) configLoader.loadType(Types.FLORA_PROBABILITY_COLLECTION_TYPE, map.get("items")); ProbabilityCollection<Flora> items = (ProbabilityCollection<Flora>) configLoader.loadType(Types.FLORA_PROBABILITY_COLLECTION_TYPE, map.get("items"));
NoiseBuilder sampler; NoiseSeeded sampler;
if(map.containsKey("distribution")) { if(map.containsKey("distribution")) {
try { try {
sampler = new NoiseBuilderLoader().load(NoiseBuilder.class, map.get("distribution"), configLoader); sampler = (NoiseSeeded) configLoader.loadType(NoiseSeeded.class, map.get("distribution"));
} catch(ConfigException e) { } catch(ConfigException e) {
throw new LoadException("Unable to load noise", e); throw new LoadException("Unable to load noise", e);
} }
return new FloraLayer(density, range, items, sampler.build(2403)); return new FloraLayer(density, range, items, sampler.apply(2403L));
} }
sampler = new NoiseBuilder(); NoiseBuilder def = new NoiseBuilder();
sampler.setType(FastNoiseLite.NoiseType.WhiteNoise); def.setType(FastNoiseLite.NoiseType.WhiteNoise);
sampler.setDimensions(3); def.setDimensions(3);
return new FloraLayer(density, range, items, sampler.build(2403)); return new FloraLayer(density, range, items, def.build(2403));
} }
} }
@@ -1,40 +0,0 @@
package com.dfsek.terra.config.loaders.config;
import com.dfsek.tectonic.config.Configuration;
import com.dfsek.tectonic.exception.ConfigException;
import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.tectonic.loading.TypeLoader;
import com.dfsek.terra.api.math.noise.normalizer.Normalizer;
import com.dfsek.terra.api.math.noise.samplers.FastNoiseLite;
import com.dfsek.terra.world.generation.config.NoiseBuilder;
import java.lang.reflect.Type;
import java.util.Map;
@SuppressWarnings("unchecked")
public class NoiseBuilderLoader implements TypeLoader<NoiseBuilder> {
private static final ConfigLoader LOADER = new ConfigLoader();
static {
LOADER.registerLoader(FastNoiseLite.NoiseType.class, (t, object, cf) -> FastNoiseLite.NoiseType.valueOf((String) object))
.registerLoader(FastNoiseLite.FractalType.class, (t, object, cf) -> FastNoiseLite.FractalType.valueOf((String) object))
.registerLoader(FastNoiseLite.DomainWarpType.class, (t, object, cf) -> FastNoiseLite.DomainWarpType.valueOf((String) object))
.registerLoader(FastNoiseLite.RotationType3D.class, (t, object, cf) -> FastNoiseLite.RotationType3D.valueOf((String) object))
.registerLoader(FastNoiseLite.CellularReturnType.class, (t, object, cf) -> FastNoiseLite.CellularReturnType.valueOf((String) object))
.registerLoader(FastNoiseLite.CellularDistanceFunction.class, (t, object, cf) -> FastNoiseLite.CellularDistanceFunction.valueOf((String) object))
.registerLoader(NoiseBuilder.class, new NoiseBuilderLoader())
.registerLoader(Normalizer.NormalType.class, (t, o, l) -> Normalizer.NormalType.valueOf(o.toString().toUpperCase()));
}
@Override
public NoiseBuilder load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
NoiseBuilder builder = new NoiseBuilder();
try {
LOADER.load(builder, new Configuration((Map<String, Object>) o));
} catch(ConfigException e) {
throw new LoadException("Could not load noise", e);
}
return builder;
}
}
@@ -4,18 +4,17 @@ import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.tectonic.loading.ConfigLoader; import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.tectonic.loading.TypeLoader; import com.dfsek.tectonic.loading.TypeLoader;
import com.dfsek.terra.api.core.TerraPlugin; import com.dfsek.terra.api.core.TerraPlugin;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.api.util.seeded.SeededBuilder;
import com.dfsek.terra.biome.TerraBiome; import com.dfsek.terra.biome.TerraBiome;
import com.dfsek.terra.biome.pipeline.BiomePipeline; import com.dfsek.terra.biome.pipeline.BiomePipeline;
import com.dfsek.terra.biome.pipeline.source.BiomeSource; import com.dfsek.terra.biome.pipeline.source.BiomeSource;
import com.dfsek.terra.biome.pipeline.stages.SeededBuilder;
import com.dfsek.terra.biome.provider.BiomeProvider; import com.dfsek.terra.biome.provider.BiomeProvider;
import com.dfsek.terra.biome.provider.ImageBiomeProvider; import com.dfsek.terra.biome.provider.ImageBiomeProvider;
import com.dfsek.terra.biome.provider.SingleBiomeProvider; import com.dfsek.terra.biome.provider.SingleBiomeProvider;
import com.dfsek.terra.biome.provider.StandardBiomeProvider; import com.dfsek.terra.biome.provider.StandardBiomeProvider;
import com.dfsek.terra.config.fileloaders.Loader; import com.dfsek.terra.config.fileloaders.Loader;
import com.dfsek.terra.config.loaders.config.NoiseBuilderLoader;
import com.dfsek.terra.registry.TerraRegistry; import com.dfsek.terra.registry.TerraRegistry;
import com.dfsek.terra.world.generation.config.NoiseBuilder;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
@@ -65,7 +64,7 @@ public class BiomeProviderBuilderLoader implements TypeLoader<BiomeProvider.Biom
if(!pipeline.containsKey("source")) throw new LoadException("Biome Source not defined!"); if(!pipeline.containsKey("source")) throw new LoadException("Biome Source not defined!");
SeededBuilder<BiomeSource> source = new SourceBuilderLoader().load(BiomeSource.class, pipeline.get("source"), loader); SeededBuilder<BiomeSource> source = new SourceBuilderLoader().load(BiomeSource.class, pipeline.get("source"), loader);
BiomePipeline biomePipeline = pipelineBuilder.build(source.build(seed), seed); BiomePipeline biomePipeline = pipelineBuilder.build(source.apply(seed), seed);
main.getDebugLogger().info("Biome Pipeline scale factor: " + biomePipeline.getSize()); main.getDebugLogger().info("Biome Pipeline scale factor: " + biomePipeline.getSize());
return biomePipeline; return biomePipeline;
}, main); }, main);
@@ -75,7 +74,7 @@ public class BiomeProviderBuilderLoader implements TypeLoader<BiomeProvider.Biom
Map<String, Object> blend = (Map<String, Object>) map.get("blend"); Map<String, Object> blend = (Map<String, Object>) map.get("blend");
if(blend.containsKey("amplitude")) builder.setNoiseAmp(Integer.parseInt(blend.get("amplitude").toString())); if(blend.containsKey("amplitude")) builder.setNoiseAmp(Integer.parseInt(blend.get("amplitude").toString()));
if(blend.containsKey("noise")) if(blend.containsKey("noise"))
builder.setBlender(new NoiseBuilderLoader().load(NoiseBuilder.class, blend.get("noise"), loader)); builder.setBlender((NoiseSeeded) loader.loadType(NoiseSeeded.class, blend.get("noise")));
} }
return builder; return builder;
} else if(map.get("type").equals("IMAGE")) { } else if(map.get("type").equals("IMAGE")) {
@@ -4,13 +4,12 @@ import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.tectonic.loading.ConfigLoader; import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.tectonic.loading.TypeLoader; import com.dfsek.tectonic.loading.TypeLoader;
import com.dfsek.terra.api.math.ProbabilityCollection; import com.dfsek.terra.api.math.ProbabilityCollection;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.api.util.seeded.SeededBuilder;
import com.dfsek.terra.biome.TerraBiome; import com.dfsek.terra.biome.TerraBiome;
import com.dfsek.terra.biome.pipeline.source.BiomeSource; import com.dfsek.terra.biome.pipeline.source.BiomeSource;
import com.dfsek.terra.biome.pipeline.source.RandomSource; import com.dfsek.terra.biome.pipeline.source.RandomSource;
import com.dfsek.terra.biome.pipeline.stages.SeededBuilder;
import com.dfsek.terra.config.loaders.Types; import com.dfsek.terra.config.loaders.Types;
import com.dfsek.terra.config.loaders.config.NoiseBuilderLoader;
import com.dfsek.terra.world.generation.config.NoiseBuilder;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Map; import java.util.Map;
@@ -25,8 +24,8 @@ public class SourceBuilderLoader implements TypeLoader<SeededBuilder<BiomeSource
if("NOISE".equals(type)) { if("NOISE".equals(type)) {
ProbabilityCollection<TerraBiome> sourceBiomes = (ProbabilityCollection<TerraBiome>) loader.loadType(Types.TERRA_BIOME_PROBABILITY_COLLECTION_TYPE, source.get("biomes")); ProbabilityCollection<TerraBiome> sourceBiomes = (ProbabilityCollection<TerraBiome>) loader.loadType(Types.TERRA_BIOME_PROBABILITY_COLLECTION_TYPE, source.get("biomes"));
NoiseBuilder sourceNoise = new NoiseBuilderLoader().load(NoiseBuilder.class, source.get("noise"), loader); NoiseSeeded sourceNoise = (NoiseSeeded) loader.loadType(NoiseSeeded.class, source.get("noise"));
return new SeededBuilder<>(seed -> new RandomSource(sourceBiomes, sourceNoise.build((int) seed.longValue()))); return seed -> new RandomSource(sourceBiomes, sourceNoise.apply(seed));
} }
throw new LoadException("No such loader type: " + type); throw new LoadException("No such loader type: " + type);
} }
@@ -4,6 +4,8 @@ import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.tectonic.loading.ConfigLoader; import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.tectonic.loading.TypeLoader; import com.dfsek.tectonic.loading.TypeLoader;
import com.dfsek.terra.api.math.ProbabilityCollection; import com.dfsek.terra.api.math.ProbabilityCollection;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.api.util.seeded.SeededBuilder;
import com.dfsek.terra.biome.TerraBiome; import com.dfsek.terra.biome.TerraBiome;
import com.dfsek.terra.biome.pipeline.expand.FractalExpander; import com.dfsek.terra.biome.pipeline.expand.FractalExpander;
import com.dfsek.terra.biome.pipeline.mutator.BorderListMutator; import com.dfsek.terra.biome.pipeline.mutator.BorderListMutator;
@@ -13,12 +15,9 @@ import com.dfsek.terra.biome.pipeline.mutator.ReplaceMutator;
import com.dfsek.terra.biome.pipeline.mutator.SmoothMutator; import com.dfsek.terra.biome.pipeline.mutator.SmoothMutator;
import com.dfsek.terra.biome.pipeline.stages.ExpanderStage; import com.dfsek.terra.biome.pipeline.stages.ExpanderStage;
import com.dfsek.terra.biome.pipeline.stages.MutatorStage; import com.dfsek.terra.biome.pipeline.stages.MutatorStage;
import com.dfsek.terra.biome.pipeline.stages.SeededBuilder;
import com.dfsek.terra.biome.pipeline.stages.Stage; import com.dfsek.terra.biome.pipeline.stages.Stage;
import com.dfsek.terra.config.loaders.SelfProbabilityCollectionLoader; import com.dfsek.terra.config.loaders.SelfProbabilityCollectionLoader;
import com.dfsek.terra.config.loaders.Types; import com.dfsek.terra.config.loaders.Types;
import com.dfsek.terra.config.loaders.config.NoiseBuilderLoader;
import com.dfsek.terra.world.generation.config.NoiseBuilder;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.HashMap; import java.util.HashMap;
@@ -31,23 +30,23 @@ public class StageBuilderLoader implements TypeLoader<SeededBuilder<Stage>> {
Map.Entry<String, Object> entry = (Map.Entry<String, Object>) c; Map.Entry<String, Object> entry = (Map.Entry<String, Object>) c;
Map<String, Object> mutator = (Map<String, Object>) entry.getValue(); Map<String, Object> mutator = (Map<String, Object>) entry.getValue();
NoiseBuilder mutatorNoise = new NoiseBuilderLoader().load(NoiseBuilder.class, mutator.get("noise"), loader); NoiseSeeded mutatorNoise = (NoiseSeeded) loader.loadType(NoiseSeeded.class, mutator.get("noise"));
if(entry.getKey().equals("expand")) { if(entry.getKey().equals("expand")) {
if(mutator.get("type").equals("FRACTAL")) if(mutator.get("type").equals("FRACTAL"))
return new SeededBuilder<>(seed -> new ExpanderStage(new FractalExpander(mutatorNoise.build((int) seed.longValue())))); return seed -> new ExpanderStage(new FractalExpander(mutatorNoise.apply(seed)));
else throw new LoadException("No such expander \"" + mutator.get("type")); else throw new LoadException("No such expander \"" + mutator.get("type"));
} else if(entry.getKey().equals("mutate")) { } else if(entry.getKey().equals("mutate")) {
switch(mutator.get("type").toString()) { switch(mutator.get("type").toString()) {
case "SMOOTH": { case "SMOOTH": {
return new SeededBuilder<>(seed -> new MutatorStage(new SmoothMutator(mutatorNoise.build((int) seed.longValue())))); return seed -> new MutatorStage(new SmoothMutator(mutatorNoise.apply(new Long(seed))));
} }
case "REPLACE": { case "REPLACE": {
String fromTag = mutator.get("from").toString(); String fromTag = mutator.get("from").toString();
ProbabilityCollection<TerraBiome> replaceBiomes = new SelfProbabilityCollectionLoader<TerraBiome>().load(Types.TERRA_BIOME_PROBABILITY_COLLECTION_TYPE, mutator.get("to"), loader); ProbabilityCollection<TerraBiome> replaceBiomes = new SelfProbabilityCollectionLoader<TerraBiome>().load(Types.TERRA_BIOME_PROBABILITY_COLLECTION_TYPE, mutator.get("to"), loader);
return new SeededBuilder<>(seed -> new MutatorStage(new ReplaceMutator(fromTag, replaceBiomes, mutatorNoise.build((int) seed.longValue())))); return seed -> new MutatorStage(new ReplaceMutator(fromTag, replaceBiomes, mutatorNoise.apply(seed)));
} }
case "REPLACE_LIST": { case "REPLACE_LIST": {
String fromTag = mutator.get("default-from").toString(); String fromTag = mutator.get("default-from").toString();
@@ -58,14 +57,14 @@ public class StageBuilderLoader implements TypeLoader<SeededBuilder<Stage>> {
replace.put((TerraBiome) loader.loadType(TerraBiome.class, e.getKey()), new SelfProbabilityCollectionLoader<TerraBiome>().load(Types.TERRA_BIOME_PROBABILITY_COLLECTION_TYPE, e.getValue(), loader)); replace.put((TerraBiome) loader.loadType(TerraBiome.class, e.getKey()), new SelfProbabilityCollectionLoader<TerraBiome>().load(Types.TERRA_BIOME_PROBABILITY_COLLECTION_TYPE, e.getValue(), loader));
} }
return new SeededBuilder<>(seed -> new MutatorStage(new ReplaceListMutator(replace, fromTag, replaceBiomes, mutatorNoise.build((int) seed.longValue())))); return seed -> new MutatorStage(new ReplaceListMutator(replace, fromTag, replaceBiomes, mutatorNoise.apply(seed)));
} }
case "BORDER": { case "BORDER": {
String fromTag = mutator.get("from").toString(); String fromTag = mutator.get("from").toString();
String replaceTag = mutator.get("replace").toString(); String replaceTag = mutator.get("replace").toString();
ProbabilityCollection<TerraBiome> replaceBiomes = new SelfProbabilityCollectionLoader<TerraBiome>().load(Types.TERRA_BIOME_PROBABILITY_COLLECTION_TYPE, mutator.get("to"), loader); ProbabilityCollection<TerraBiome> replaceBiomes = new SelfProbabilityCollectionLoader<TerraBiome>().load(Types.TERRA_BIOME_PROBABILITY_COLLECTION_TYPE, mutator.get("to"), loader);
return new SeededBuilder<>(seed -> new MutatorStage(new BorderMutator(fromTag, replaceTag, mutatorNoise.build((int) seed.longValue()), replaceBiomes))); return seed -> new MutatorStage(new BorderMutator(fromTag, replaceTag, mutatorNoise.apply(seed), replaceBiomes));
} }
case "BORDER_LIST": { case "BORDER_LIST": {
String fromTag = mutator.get("from").toString(); String fromTag = mutator.get("from").toString();
@@ -77,7 +76,7 @@ public class StageBuilderLoader implements TypeLoader<SeededBuilder<Stage>> {
replace.put((TerraBiome) loader.loadType(TerraBiome.class, e.getKey()), new SelfProbabilityCollectionLoader<TerraBiome>().load(Types.TERRA_BIOME_PROBABILITY_COLLECTION_TYPE, e.getValue(), loader)); replace.put((TerraBiome) loader.loadType(TerraBiome.class, e.getKey()), new SelfProbabilityCollectionLoader<TerraBiome>().load(Types.TERRA_BIOME_PROBABILITY_COLLECTION_TYPE, e.getValue(), loader));
} }
return new SeededBuilder<>(seed -> new MutatorStage(new BorderListMutator(replace, fromTag, replaceTag, mutatorNoise.build((int) seed.longValue()), replaceBiomes))); return seed -> new MutatorStage(new BorderListMutator(replace, fromTag, replaceTag, mutatorNoise.apply(seed), replaceBiomes));
} }
default: default:
throw new LoadException("No such mutator type \"" + mutator.get("type")); throw new LoadException("No such mutator type \"" + mutator.get("type"));
@@ -0,0 +1,107 @@
package com.dfsek.terra.config.loaders.config.sampler;
import com.dfsek.tectonic.config.Configuration;
import com.dfsek.tectonic.exception.ConfigException;
import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.tectonic.loading.TypeLoader;
import com.dfsek.terra.api.math.noise.normalizer.LinearNormalizer;
import com.dfsek.terra.api.math.noise.normalizer.NormalNormalizer;
import com.dfsek.terra.api.math.noise.normalizer.Normalizer;
import com.dfsek.terra.api.math.noise.samplers.NoiseSampler;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.world.generation.config.NoiseBuilder;
import java.lang.reflect.Type;
import java.util.Map;
@SuppressWarnings("unchecked")
public class NoiseSamplerBuilderLoader implements TypeLoader<NoiseSeeded> {
@Override
public NoiseSeeded load(Type t, Object c, ConfigLoader loader) throws LoadException {
Map<String, Object> map = (Map<String, Object>) c;
String samplerType = "NOISE";
int dimensions = map.containsKey("dimensions")
? Integer.parseInt(map.get("dimensions").toString())
: 2;
if(map.containsKey("sampler-type")) {
samplerType = map.get("sampler-type").toString();
}
if(samplerType.equals("NOISE")) {
NoiseBuilder builder = new NoiseBuilder();
try {
loader.load(builder, new Configuration(map));
} catch(ConfigException e) {
throw new LoadException("Failed to load noise function", e);
}
return new NoiseSeeded() {
@Override
public NoiseSampler apply(Long seed) {
return builder.build(seed);
}
@Override
public int getDimensions() {
return dimensions;
}
};
} else if(samplerType.equals("NORMALIZER")) {
Normalizer.NormalType normalType = (Normalizer.NormalType) loader.loadType(Normalizer.NormalType.class, map.get("type"));
NoiseBuilder builder = new NoiseBuilder();
try {
loader.load(builder, new Configuration((Map<String, Object>) map.get("function")));
} catch(ConfigException e) {
throw new LoadException("Failed to load noise function", e);
}
switch(normalType) {
case LINEAR: {
if(!map.containsKey("max")) throw new LoadException("Max unspecified.");
if(!map.containsKey("min")) throw new LoadException("Min unspecified.");
int min = Integer.parseInt(map.get("min").toString());
int max = Integer.parseInt(map.get("max").toString());
return new NoiseSeeded() {
@Override
public NoiseSampler apply(Long seed) {
return new LinearNormalizer(builder.build(seed), min, max);
}
@Override
public int getDimensions() {
return dimensions;
}
};
}
case NORMAL: {
if(!map.containsKey("mean")) throw new LoadException("Mean unspecified.");
if(!map.containsKey("standard-deviation")) throw new LoadException("Standard Deviation unspecified.");
if(!map.containsKey("groups")) throw new LoadException("Groups unspecified.");
double mean = Double.parseDouble(map.get("mean").toString());
double stdDev = Double.parseDouble(map.get("standard-deviation").toString());
int groups = Integer.parseInt(map.get("groups").toString());
return new NoiseSeeded() {
@Override
public NoiseSampler apply(Long seed) {
return new NormalNormalizer(builder.build(seed), groups, mean, stdDev);
}
@Override
public int getDimensions() {
return dimensions;
}
};
}
}
}
throw new LoadException("No such noise sampler type \"" + samplerType + "\"");
}
}
@@ -0,0 +1,4 @@
package com.dfsek.terra.config.loaders.config.sampler;
public class NormalizerLoader {
}
@@ -6,10 +6,9 @@ import com.dfsek.tectonic.loading.TypeLoader;
import com.dfsek.terra.api.math.ProbabilityCollection; import com.dfsek.terra.api.math.ProbabilityCollection;
import com.dfsek.terra.api.math.noise.samplers.NoiseSampler; import com.dfsek.terra.api.math.noise.samplers.NoiseSampler;
import com.dfsek.terra.api.platform.block.BlockData; import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.api.world.palette.holder.PaletteLayerHolder; import com.dfsek.terra.api.world.palette.holder.PaletteLayerHolder;
import com.dfsek.terra.config.loaders.Types; import com.dfsek.terra.config.loaders.Types;
import com.dfsek.terra.config.loaders.config.NoiseBuilderLoader;
import com.dfsek.terra.world.generation.config.NoiseBuilder;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Map; import java.util.Map;
@@ -23,7 +22,7 @@ public class PaletteLayerLoader implements TypeLoader<PaletteLayerHolder> {
NoiseSampler sampler = null; NoiseSampler sampler = null;
if(map.containsKey("noise")) { if(map.containsKey("noise")) {
sampler = new NoiseBuilderLoader().load(NoiseBuilder.class, map.get("noise"), configLoader).build(2403); sampler = ((NoiseSeeded) configLoader.loadType(NoiseSeeded.class, map.get("noise"))).apply(2403L);
} }
if(collection == null) throw new LoadException("Collection is null: " + map.get("materials")); if(collection == null) throw new LoadException("Collection is null: " + map.get("materials"));
@@ -3,8 +3,8 @@ package com.dfsek.terra.config.pack;
import com.dfsek.tectonic.annotations.Default; import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value; import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.config.ConfigTemplate; import com.dfsek.tectonic.config.ConfigTemplate;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.biome.provider.BiomeProvider; import com.dfsek.terra.biome.provider.BiomeProvider;
import com.dfsek.terra.world.generation.config.NoiseBuilder;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@@ -15,7 +15,7 @@ public class ConfigPackTemplate implements ConfigTemplate {
private String id; private String id;
@Value("noise") @Value("noise")
private Map<String, NoiseBuilder> noiseBuilderMap; private Map<String, NoiseSeeded> noiseBuilderMap;
@Value("variables") @Value("variables")
@Default @Default
@@ -112,7 +112,7 @@ public class ConfigPackTemplate implements ConfigTemplate {
return vanillaStructures; return vanillaStructures;
} }
public Map<String, NoiseBuilder> getNoiseBuilderMap() { public Map<String, NoiseSeeded> getNoiseBuilderMap() {
return noiseBuilderMap; return noiseBuilderMap;
} }
@@ -8,11 +8,13 @@ import com.dfsek.tectonic.exception.ValidationException;
import com.dfsek.terra.api.core.TerraPlugin; import com.dfsek.terra.api.core.TerraPlugin;
import com.dfsek.terra.api.math.ProbabilityCollection; import com.dfsek.terra.api.math.ProbabilityCollection;
import com.dfsek.terra.api.math.noise.samplers.FastNoiseLite; import com.dfsek.terra.api.math.noise.samplers.FastNoiseLite;
import com.dfsek.terra.api.math.noise.samplers.NoiseSampler;
import com.dfsek.terra.api.math.parsii.BlankFunction; import com.dfsek.terra.api.math.parsii.BlankFunction;
import com.dfsek.terra.api.platform.block.BlockData; import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.block.MaterialData; import com.dfsek.terra.api.platform.block.MaterialData;
import com.dfsek.terra.api.platform.world.Biome; import com.dfsek.terra.api.platform.world.Biome;
import com.dfsek.terra.api.util.GlueList; import com.dfsek.terra.api.util.GlueList;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.api.world.palette.Palette; import com.dfsek.terra.api.world.palette.Palette;
import com.dfsek.terra.api.world.palette.SinglePalette; import com.dfsek.terra.api.world.palette.SinglePalette;
import com.dfsek.terra.api.world.palette.holder.PaletteHolder; import com.dfsek.terra.api.world.palette.holder.PaletteHolder;
@@ -69,7 +71,7 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf
@Value("biome-noise") @Value("biome-noise")
@Default @Default
@Abstractable @Abstractable
private NoiseBuilder biomeNoise = new NoiseBuilder(); private NoiseSeeded biomeNoise;
@Value("blend.distance") @Value("blend.distance")
@Abstractable @Abstractable
@@ -224,11 +226,23 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf
public BiomeTemplate(ConfigPack pack, TerraPlugin main) { public BiomeTemplate(ConfigPack pack, TerraPlugin main) {
this.pack = pack; this.pack = pack;
biomeNoise.setType(FastNoiseLite.NoiseType.WhiteNoise); NoiseBuilder builder = new NoiseBuilder();
builder.setType(FastNoiseLite.NoiseType.Constant);
biomeNoise = new NoiseSeeded() {
@Override
public NoiseSampler apply(Long seed) {
return builder.build(seed);
}
@Override
public int getDimensions() {
return 2;
}
};
oceanPalette = new SinglePalette<>(main.getWorldHandle().createBlockData("minecraft:water")); oceanPalette = new SinglePalette<>(main.getWorldHandle().createBlockData("minecraft:water"));
} }
public NoiseBuilder getBiomeNoise() { public NoiseSeeded getBiomeNoise() {
return biomeNoise; return biomeNoise;
} }
@@ -4,6 +4,8 @@ import com.dfsek.tectonic.annotations.Abstractable;
import com.dfsek.tectonic.annotations.Default; import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value; import com.dfsek.tectonic.annotations.Value;
import com.dfsek.terra.api.math.noise.samplers.FastNoiseLite; import com.dfsek.terra.api.math.noise.samplers.FastNoiseLite;
import com.dfsek.terra.api.math.noise.samplers.NoiseSampler;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.api.world.palette.holder.PaletteLayerHolder; import com.dfsek.terra.api.world.palette.holder.PaletteLayerHolder;
import com.dfsek.terra.world.generation.config.NoiseBuilder; import com.dfsek.terra.world.generation.config.NoiseBuilder;
@@ -14,7 +16,7 @@ public class PaletteTemplate extends AbstractableTemplate {
@Value("noise") @Value("noise")
@Abstractable @Abstractable
@Default @Default
private NoiseBuilder noise = new NoiseBuilder(); private NoiseSeeded noise;
@Value("id") @Value("id")
private String id; private String id;
@@ -24,8 +26,20 @@ public class PaletteTemplate extends AbstractableTemplate {
private List<PaletteLayerHolder> palette; private List<PaletteLayerHolder> palette;
public PaletteTemplate() { public PaletteTemplate() {
noise.setType(FastNoiseLite.NoiseType.WhiteNoise); NoiseBuilder builder = new NoiseBuilder();
noise.setDimensions(3); builder.setType(FastNoiseLite.NoiseType.WhiteNoise);
builder.setDimensions(3);
this.noise = new NoiseSeeded() {
@Override
public NoiseSampler apply(Long seed) {
return builder.build(seed);
}
@Override
public int getDimensions() {
return 3;
}
};
} }
public String getID() { public String getID() {
@@ -36,7 +50,7 @@ public class PaletteTemplate extends AbstractableTemplate {
return palette; return palette;
} }
public NoiseBuilder getNoise() { public NoiseSeeded getNoise() {
return noise; return noise;
} }
} }
@@ -3,11 +3,9 @@ package com.dfsek.terra.world.generation.config;
import com.dfsek.tectonic.annotations.Default; import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value; import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.config.ConfigTemplate; import com.dfsek.tectonic.config.ConfigTemplate;
import com.dfsek.terra.api.math.noise.normalizer.LinearNormalizer;
import com.dfsek.terra.api.math.noise.normalizer.NormalNormalizer;
import com.dfsek.terra.api.math.noise.normalizer.Normalizer;
import com.dfsek.terra.api.math.noise.samplers.FastNoiseLite; import com.dfsek.terra.api.math.noise.samplers.FastNoiseLite;
import com.dfsek.terra.api.math.noise.samplers.NoiseSampler; import com.dfsek.terra.api.math.noise.samplers.NoiseSampler;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
@SuppressWarnings("FieldMayBeFinal") @SuppressWarnings("FieldMayBeFinal")
public class NoiseBuilder implements ConfigTemplate { public class NoiseBuilder implements ConfigTemplate {
@@ -69,7 +67,7 @@ public class NoiseBuilder implements ConfigTemplate {
@Value("domain-warp.function") @Value("domain-warp.function")
@Default @Default
private NoiseBuilder domainWarp; private NoiseSeeded domainWarp;
@Value("rotation-type") @Value("rotation-type")
@Default @Default
@@ -81,31 +79,11 @@ public class NoiseBuilder implements ConfigTemplate {
@Value("cellular.lookup") @Value("cellular.lookup")
@Default @Default
private NoiseBuilder lookup; private NoiseSeeded lookup;
@Value("normalize.type")
@Default
private Normalizer.NormalType normalType = Normalizer.NormalType.NONE;
@Value("normalize.linear.min")
@Default
private double linearMin = -1D;
@Value("normalize.linear.max")
@Default
private double linearMax = 1D;
@Value("normalize.normal.mean")
@Default
private double mean = 0D;
@Value("normalize.normal.standard-deviation")
@Default
private double stdDev = 0.75D;
public NoiseSampler build(int seed) { public NoiseSampler build(long seed) {
FastNoiseLite noise = new FastNoiseLite(seed + seedOffset); FastNoiseLite noise = new FastNoiseLite((int) (seed + seedOffset));
if(!fractalType.equals(FastNoiseLite.FractalType.None)) { if(!fractalType.equals(FastNoiseLite.FractalType.None)) {
noise.setFractalType(fractalType); noise.setFractalType(fractalType);
noise.setFractalOctaves(octaves); noise.setFractalOctaves(octaves);
@@ -118,20 +96,18 @@ public class NoiseBuilder implements ConfigTemplate {
noise.setCellularDistanceFunction(cellularDistanceFunction); noise.setCellularDistanceFunction(cellularDistanceFunction);
noise.setCellularReturnType(cellularReturnType); noise.setCellularReturnType(cellularReturnType);
noise.setCellularJitter(cellularJitter); noise.setCellularJitter(cellularJitter);
if(lookup != null) noise.setCellularNoiseLookup(lookup.build(seed)); if(lookup != null) noise.setCellularNoiseLookup(lookup.apply(seed));
} }
noise.setNoiseType(type); noise.setNoiseType(type);
noise.setDomainWarpType(domainWarpType); noise.setDomainWarpType(domainWarpType);
noise.setDomainWarpAmp(domainWarpAmp); noise.setDomainWarpAmp(domainWarpAmp);
if(domainWarp != null) noise.setDomainWarpFunction(domainWarp.build(seed)); if(domainWarp != null) noise.setDomainWarpFunction(domainWarp.apply(seed));
noise.setRotationType3D(rotationType3D); noise.setRotationType3D(rotationType3D);
noise.setFrequency(frequency); noise.setFrequency(frequency);
if(normalType.equals(Normalizer.NormalType.LINEAR)) return new LinearNormalizer(noise, linearMin, linearMax);
else if(normalType.equals(Normalizer.NormalType.NORMAL)) return new NormalNormalizer(noise, 16384, mean, stdDev);
return noise; return noise;
} }
+14 -15
View File
@@ -16,7 +16,6 @@ import com.dfsek.terra.biome.pipeline.source.BiomeSource;
import com.dfsek.terra.biome.pipeline.source.RandomSource; import com.dfsek.terra.biome.pipeline.source.RandomSource;
import com.dfsek.terra.biome.pipeline.stages.ExpanderStage; import com.dfsek.terra.biome.pipeline.stages.ExpanderStage;
import com.dfsek.terra.biome.pipeline.stages.MutatorStage; import com.dfsek.terra.biome.pipeline.stages.MutatorStage;
import com.dfsek.terra.biome.pipeline.stages.SeededBuilder;
import com.dfsek.terra.biome.provider.BiomeProvider; import com.dfsek.terra.biome.provider.BiomeProvider;
import com.dfsek.terra.biome.provider.StandardBiomeProvider; import com.dfsek.terra.biome.provider.StandardBiomeProvider;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@@ -64,20 +63,20 @@ public class BiomeTest {
BiomeProvider provider = new StandardBiomeProvider.StandardBiomeProviderBuilder((seed) -> new BiomePipeline.BiomePipelineBuilder(2) BiomeProvider provider = new StandardBiomeProvider.StandardBiomeProviderBuilder((seed) -> new BiomePipeline.BiomePipelineBuilder(2)
.addStage(new SeededBuilder<>(s -> new MutatorStage(new ReplaceMutator("LAND_TEMP", landBiomes, whiteNoise(243))))) .addStage(s -> new MutatorStage(new ReplaceMutator("LAND_TEMP", landBiomes, whiteNoise(243))))
.addStage(new SeededBuilder<>(s -> new ExpanderStage(new FractalExpander(whiteNoise(2))))) .addStage(s -> new ExpanderStage(new FractalExpander(whiteNoise(2))))
.addStage(new SeededBuilder<>(s -> new MutatorStage(new ReplaceMutator("OCEAN_TEMP", oceanBiomes, whiteNoise(243))))) .addStage(s -> new MutatorStage(new ReplaceMutator("OCEAN_TEMP", oceanBiomes, whiteNoise(243))))
.addStage(new SeededBuilder<>(s -> new ExpanderStage(new FractalExpander(whiteNoise(2))))) .addStage(s -> new ExpanderStage(new FractalExpander(whiteNoise(2))))
.addStage(new SeededBuilder<>(s -> new ExpanderStage(new FractalExpander(whiteNoise(2))))) .addStage(s -> new ExpanderStage(new FractalExpander(whiteNoise(2))))
.addStage(new SeededBuilder<>(s -> new MutatorStage(new SmoothMutator(whiteNoise(3))))) .addStage(s -> new MutatorStage(new SmoothMutator(whiteNoise(3))))
.addStage(new SeededBuilder<>(s -> new ExpanderStage(new FractalExpander(whiteNoise(4))))) .addStage(s -> new ExpanderStage(new FractalExpander(whiteNoise(4))))
.addStage(new SeededBuilder<>(s -> new MutatorStage(new SmoothMutator(whiteNoise(6))))) .addStage(s -> new MutatorStage(new SmoothMutator(whiteNoise(6))))
.addStage(new SeededBuilder<>(s -> new ExpanderStage(new FractalExpander(whiteNoise(4))))) .addStage(s -> new ExpanderStage(new FractalExpander(whiteNoise(4))))
.addStage(new SeededBuilder<>(s -> new ExpanderStage(new FractalExpander(whiteNoise(4))))) .addStage(s -> new ExpanderStage(new FractalExpander(whiteNoise(4))))
.addStage(new SeededBuilder<>(s -> new MutatorStage(new BorderMutator("OCEAN", "LAND", whiteNoise(1234), beachBiomes)))) .addStage(s -> new MutatorStage(new BorderMutator("OCEAN", "LAND", whiteNoise(1234), beachBiomes)))
.addStage(new SeededBuilder<>(s -> new ExpanderStage(new FractalExpander(whiteNoise(4))))) .addStage(s -> new ExpanderStage(new FractalExpander(whiteNoise(4))))
.addStage(new SeededBuilder<>(s -> new MutatorStage(new SmoothMutator(whiteNoise(6))))) .addStage(s -> new MutatorStage(new SmoothMutator(whiteNoise(6))))
.addStage(new SeededBuilder<>(s -> new MutatorStage(new SmoothMutator(whiteNoise(6))))) .addStage(s -> new MutatorStage(new SmoothMutator(whiteNoise(6))))
.build(source, seed), null).build(0); .build(source, seed), null).build(0);
@@ -2,15 +2,15 @@ package noise;
import com.dfsek.tectonic.annotations.Value; import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.config.ConfigTemplate; import com.dfsek.tectonic.config.ConfigTemplate;
import com.dfsek.terra.world.generation.config.NoiseBuilder; import com.dfsek.terra.api.util.seeded.NoiseSeeded;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class NoiseConfigTemplate implements ConfigTemplate { public class NoiseConfigTemplate implements ConfigTemplate {
@Value(".") @Value(".")
private NoiseBuilder builder; private NoiseSeeded builder;
public NoiseBuilder getBuilder() { public NoiseSeeded getBuilder() {
return builder; return builder;
} }
} }
+8 -5
View File
@@ -4,9 +4,10 @@ import com.dfsek.tectonic.exception.ConfigException;
import com.dfsek.tectonic.loading.ConfigLoader; import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.terra.api.math.ProbabilityCollection; import com.dfsek.terra.api.math.ProbabilityCollection;
import com.dfsek.terra.api.math.noise.samplers.NoiseSampler; import com.dfsek.terra.api.math.noise.samplers.NoiseSampler;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.config.GenericLoaders;
import com.dfsek.terra.config.loaders.ProbabilityCollectionLoader; import com.dfsek.terra.config.loaders.ProbabilityCollectionLoader;
import com.dfsek.terra.config.loaders.config.NoiseBuilderLoader; import com.dfsek.terra.config.loaders.config.sampler.NoiseSamplerBuilderLoader;
import com.dfsek.terra.world.generation.config.NoiseBuilder;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import javax.swing.*; import javax.swing.*;
@@ -90,8 +91,10 @@ public class NoiseTool {
long s = System.nanoTime(); long s = System.nanoTime();
ConfigLoader loader = new ConfigLoader(); ConfigLoader loader = new ConfigLoader();
loader.registerLoader(NoiseBuilder.class, new NoiseBuilderLoader()) loader.registerLoader(NoiseSeeded.class, new NoiseSamplerBuilderLoader())
.registerLoader(ProbabilityCollection.class, new ProbabilityCollectionLoader()); .registerLoader(ProbabilityCollection.class, new ProbabilityCollectionLoader());
new GenericLoaders(null).register(loader);
NoiseConfigTemplate template = new NoiseConfigTemplate(); NoiseConfigTemplate template = new NoiseConfigTemplate();
File file = new File("./config.yml"); File file = new File("./config.yml");
@@ -117,7 +120,7 @@ public class NoiseTool {
ProbabilityCollection<Integer> colorCollection = color.getColors(); ProbabilityCollection<Integer> colorCollection = color.getColors();
loader.load(template, new FileInputStream(file)); loader.load(template, new FileInputStream(file));
NoiseSampler noise = template.getBuilder().build(seed); NoiseSampler noise = template.getBuilder().apply((long) seed);
int size = 1024; int size = 1024;
@@ -132,7 +135,7 @@ public class NoiseTool {
for(int x = 0; x < noiseVals.length; x++) { for(int x = 0; x < noiseVals.length; x++) {
for(int z = 0; z < noiseVals[x].length; z++) { for(int z = 0; z < noiseVals[x].length; z++) {
double n = template.getBuilder().getDimensions() == 2 ? noise.getNoise(x, z) : noise.getNoise(x, 0, z); double n = noise.getNoise(x, z);
noiseVals[x][z] = n; noiseVals[x][z] = n;
max = Math.max(n, max); max = Math.max(n, max);
min = Math.min(n, min); min = Math.min(n, min);