From 4b21fcd80ae8dfdf28af3d2c5fe4bf9b1a458227 Mon Sep 17 00:00:00 2001 From: dfsek Date: Sun, 17 Jan 2021 21:55:08 -0700 Subject: [PATCH] add elevation weight, add "self" biome opt --- .../terra/api/math/ProbabilityCollection.java | 44 ++++++++++++++++ .../terra/api/world/biome/Generator.java | 4 ++ .../pipeline/mutator/ReplaceMutator.java | 6 ++- .../config/builder/GeneratorBuilder.java | 8 ++- .../terra/config/factories/BiomeFactory.java | 1 + .../loaders/ProbabilityCollectionLoader.java | 51 ++----------------- .../SelfProbabilityCollectionLoader.java | 51 +++++++++++++++++++ .../biome/BiomeProviderBuilderLoader.java | 3 +- .../terra/config/templates/BiomeTemplate.java | 9 ++++ .../generation/config/WorldGenerator.java | 16 +++--- .../interpolation/ElevationInterpolator.java | 9 ++-- 11 files changed, 141 insertions(+), 61 deletions(-) create mode 100644 common/src/main/java/com/dfsek/terra/config/loaders/SelfProbabilityCollectionLoader.java diff --git a/common/src/main/java/com/dfsek/terra/api/math/ProbabilityCollection.java b/common/src/main/java/com/dfsek/terra/api/math/ProbabilityCollection.java index 6cc021032..04cdd0c65 100644 --- a/common/src/main/java/com/dfsek/terra/api/math/ProbabilityCollection.java +++ b/common/src/main/java/com/dfsek/terra/api/math/ProbabilityCollection.java @@ -2,6 +2,7 @@ package com.dfsek.terra.api.math; import com.dfsek.terra.api.math.noise.samplers.NoiseSampler; +import java.util.Collections; import java.util.HashSet; import java.util.Random; import java.util.Set; @@ -49,4 +50,47 @@ public class ProbabilityCollection { public Set getContents() { return new HashSet<>(cont); } + + public static final class Singleton extends ProbabilityCollection { + private final T single; + + public Singleton(T single) { + this.single = single; + } + + @Override + public ProbabilityCollection add(T item, int probability) { + throw new UnsupportedOperationException(); + } + + @Override + public T get(Random r) { + return single; + } + + @Override + public T get(NoiseSampler n, double x, double y, double z) { + return single; + } + + @Override + public T get(NoiseSampler n, double x, double z) { + return single; + } + + @Override + public int getTotalProbability() { + return 1; + } + + @Override + public int size() { + return 1; + } + + @Override + public Set getContents() { + return Collections.singleton(single); + } + } } diff --git a/common/src/main/java/com/dfsek/terra/api/world/biome/Generator.java b/common/src/main/java/com/dfsek/terra/api/world/biome/Generator.java index 908bf01f0..2b7026d1a 100644 --- a/common/src/main/java/com/dfsek/terra/api/world/biome/Generator.java +++ b/common/src/main/java/com/dfsek/terra/api/world/biome/Generator.java @@ -15,6 +15,8 @@ public interface Generator { */ double getNoise(int x, int y, int z); + double getElevation(int x, int z); + /** * Gets the BlocPalette to generate the biome with. * @@ -27,4 +29,6 @@ public interface Generator { double get2dBase(); NoiseSampler getBiomeNoise(); + + double getElevationWeight(); } diff --git a/common/src/main/java/com/dfsek/terra/biome/pipeline/mutator/ReplaceMutator.java b/common/src/main/java/com/dfsek/terra/biome/pipeline/mutator/ReplaceMutator.java index 59ba81056..2224ac456 100644 --- a/common/src/main/java/com/dfsek/terra/biome/pipeline/mutator/ReplaceMutator.java +++ b/common/src/main/java/com/dfsek/terra/biome/pipeline/mutator/ReplaceMutator.java @@ -17,6 +17,10 @@ public class ReplaceMutator implements BiomeMutator { @Override public TerraBiome mutate(ViewPoint viewPoint, double x, double z) { - return viewPoint.getBiome(0, 0).getTags().contains(replaceableTag) ? replace.get(sampler, x, z) : viewPoint.getBiome(0, 0); + if(viewPoint.getBiome(0, 0).getTags().contains(replaceableTag)) { + TerraBiome biome = replace.get(sampler, x, z); + return biome == null ? viewPoint.getBiome(0, 0) : biome; + } + return viewPoint.getBiome(0, 0); } } diff --git a/common/src/main/java/com/dfsek/terra/config/builder/GeneratorBuilder.java b/common/src/main/java/com/dfsek/terra/config/builder/GeneratorBuilder.java index 4b56dd61c..fe0dbaae8 100644 --- a/common/src/main/java/com/dfsek/terra/config/builder/GeneratorBuilder.java +++ b/common/src/main/java/com/dfsek/terra/config/builder/GeneratorBuilder.java @@ -34,10 +34,12 @@ public class GeneratorBuilder { private NoiseBuilder biomeNoise; + private double elevationWeight; + public WorldGenerator build(long seed) { synchronized(gens) { - return gens.computeIfAbsent(seed, k -> new WorldGenerator(seed, noiseEquation, elevationEquation, varScope, noiseBuilderMap, palettes, slantPalettes, interpolateElevation, noise2d, base, biomeNoise.build((int) seed))); + return gens.computeIfAbsent(seed, k -> new WorldGenerator(seed, noiseEquation, elevationEquation, varScope, noiseBuilderMap, palettes, slantPalettes, interpolateElevation, noise2d, base, biomeNoise.build((int) seed), elevationWeight)); } } @@ -61,6 +63,10 @@ public class GeneratorBuilder { this.base = base; } + public void setElevationWeight(double elevationWeight) { + this.elevationWeight = elevationWeight; + } + public String getNoiseEquation() { return noiseEquation; } diff --git a/common/src/main/java/com/dfsek/terra/config/factories/BiomeFactory.java b/common/src/main/java/com/dfsek/terra/config/factories/BiomeFactory.java index 69fc23c35..a0bd7aa2d 100644 --- a/common/src/main/java/com/dfsek/terra/config/factories/BiomeFactory.java +++ b/common/src/main/java/com/dfsek/terra/config/factories/BiomeFactory.java @@ -25,6 +25,7 @@ public class BiomeFactory implements TerraFactory> { @@ -32,11 +28,12 @@ public class ProbabilityCollectionLoader implements TypeLoader> map = (List>) o; for(Map l : map) { for(Map.Entry entry : l.entrySet()) { - collection.add(configLoader.loadType(generic, entry.getKey()), entry.getValue()); + Object val = configLoader.loadType(generic, entry.getKey()); + collection.add(val, entry.getValue()); } } } else if(o instanceof String) { - return new Singleton<>(configLoader.loadType(generic, o)); + return new ProbabilityCollection.Singleton<>(configLoader.loadType(generic, o)); } else { throw new LoadException("Malformed Probability Collection: " + o); } @@ -46,46 +43,4 @@ public class ProbabilityCollectionLoader implements TypeLoader extends ProbabilityCollection { - private final T single; - - private Singleton(T single) { - this.single = single; - } - - @Override - public ProbabilityCollection add(T item, int probability) { - throw new UnsupportedOperationException(); - } - - @Override - public T get(Random r) { - return single; - } - - @Override - public T get(NoiseSampler n, double x, double y, double z) { - return single; - } - - @Override - public T get(NoiseSampler n, double x, double z) { - return single; - } - - @Override - public int getTotalProbability() { - return 1; - } - - @Override - public int size() { - return 1; - } - - @Override - public Set getContents() { - return Collections.singleton(single); - } - } } diff --git a/common/src/main/java/com/dfsek/terra/config/loaders/SelfProbabilityCollectionLoader.java b/common/src/main/java/com/dfsek/terra/config/loaders/SelfProbabilityCollectionLoader.java new file mode 100644 index 000000000..6561ef08d --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/config/loaders/SelfProbabilityCollectionLoader.java @@ -0,0 +1,51 @@ +package com.dfsek.terra.config.loaders; + +import com.dfsek.tectonic.exception.LoadException; +import com.dfsek.tectonic.loading.ConfigLoader; +import com.dfsek.tectonic.loading.TypeLoader; +import com.dfsek.terra.api.math.ProbabilityCollection; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.List; +import java.util.Map; + +@SuppressWarnings("unchecked") +public class SelfProbabilityCollectionLoader implements TypeLoader> { + + @Override + public ProbabilityCollection load(Type type, Object o, ConfigLoader loader) throws LoadException { + ProbabilityCollection collection = new ProbabilityCollection<>(); + + if(type instanceof ParameterizedType) { + ParameterizedType pType = (ParameterizedType) type; + Type generic = pType.getActualTypeArguments()[0]; + if(o instanceof Map) { + Map map = (Map) o; + addItems(loader, collection, generic, map); + } else if(o instanceof List) { + List> map = (List>) o; + for(Map l : map) { + addItems(loader, collection, generic, l); + } + } else if(o instanceof String) { + return new ProbabilityCollection.Singleton<>((T) loader.loadType(generic, o)); + } else { + throw new LoadException("Malformed Probability Collection: " + o); + } + } else throw new LoadException("Unable to load config! Could not retrieve parameterized type: " + type); + + + return collection; + } + + private void addItems(ConfigLoader loader, ProbabilityCollection collection, Type generic, Map l) throws LoadException { + for(Map.Entry entry : l.entrySet()) { + if(entry.getKey().toString().equals("SELF")) { + collection.add(null, entry.getValue()); // hmm maybe replace this with something better later + continue; + } + collection.add((T) loader.loadType(generic, entry.getKey()), entry.getValue()); + } + } +} diff --git a/common/src/main/java/com/dfsek/terra/config/loaders/config/biome/BiomeProviderBuilderLoader.java b/common/src/main/java/com/dfsek/terra/config/loaders/config/biome/BiomeProviderBuilderLoader.java index 6f414b6b1..af56a4dd4 100644 --- a/common/src/main/java/com/dfsek/terra/config/loaders/config/biome/BiomeProviderBuilderLoader.java +++ b/common/src/main/java/com/dfsek/terra/config/loaders/config/biome/BiomeProviderBuilderLoader.java @@ -17,6 +17,7 @@ import com.dfsek.terra.biome.pipeline.mutator.SmoothMutator; import com.dfsek.terra.biome.pipeline.source.RandomSource; import com.dfsek.terra.biome.pipeline.stages.ExpanderStage; import com.dfsek.terra.biome.pipeline.stages.MutatorStage; +import com.dfsek.terra.config.loaders.SelfProbabilityCollectionLoader; import com.dfsek.terra.config.loaders.Types; import com.dfsek.terra.config.loaders.config.NoiseBuilderLoader; import com.dfsek.terra.debug.Debug; @@ -65,7 +66,7 @@ public class BiomeProviderBuilderLoader implements TypeLoader replaceBiomes = (ProbabilityCollection) loader.loadType(Types.TERRA_BIOME_PROBABILITY_COLLECTION_TYPE, mutator.get("to")); + ProbabilityCollection replaceBiomes = new SelfProbabilityCollectionLoader().load(Types.TERRA_BIOME_PROBABILITY_COLLECTION_TYPE, mutator.get("to"), loader); pipelineBuilder.addStage(new MutatorStage(new ReplaceMutator(fromTag, replaceBiomes, mutatorNoise))); } else if(mutator.get("type").equals("BORDER")) { String fromTag = mutator.get("from").toString(); diff --git a/common/src/main/java/com/dfsek/terra/config/templates/BiomeTemplate.java b/common/src/main/java/com/dfsek/terra/config/templates/BiomeTemplate.java index 73463451c..f4e4b898e 100644 --- a/common/src/main/java/com/dfsek/terra/config/templates/BiomeTemplate.java +++ b/common/src/main/java/com/dfsek/terra/config/templates/BiomeTemplate.java @@ -103,6 +103,11 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf @Abstractable private String elevationEquation = null; + @Value("elevation.weight") + @Default + @Abstractable + private double elevationWeight = 1; + @Value("flora") @Abstractable @Default @@ -266,6 +271,10 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf return noise2dBase; } + public double getElevationWeight() { + return elevationWeight; + } + @Override public boolean validate() throws ValidationException { color |= 0x1fe00000; // Alpha adjustment diff --git a/common/src/main/java/com/dfsek/terra/generation/config/WorldGenerator.java b/common/src/main/java/com/dfsek/terra/generation/config/WorldGenerator.java index 232afcfc6..193787a6c 100644 --- a/common/src/main/java/com/dfsek/terra/generation/config/WorldGenerator.java +++ b/common/src/main/java/com/dfsek/terra/generation/config/WorldGenerator.java @@ -33,8 +33,9 @@ public class WorldGenerator implements Generator { private final boolean noise2d; private final double base; private final NoiseSampler biomeNoise; + private final double elevationWeight; - public WorldGenerator(long seed, String equation, String elevateEquation, Scope vScope, Map noiseBuilders, PaletteHolder palettes, PaletteHolder slantPalettes, boolean elevationInterpolation, boolean noise2d, double base, NoiseSampler biomeNoise) { + public WorldGenerator(long seed, String equation, String elevateEquation, Scope vScope, Map noiseBuilders, PaletteHolder palettes, PaletteHolder slantPalettes, boolean elevationInterpolation, boolean noise2d, double base, NoiseSampler biomeNoise, double elevationWeight) { this.palettes = palettes; this.slantPalettes = slantPalettes; @@ -42,6 +43,7 @@ public class WorldGenerator implements Generator { this.noise2d = noise2d; this.base = base; this.biomeNoise = biomeNoise; + this.elevationWeight = elevationWeight; Parser p = new Parser(); p.registerFunction("rand", new RandomFunction()); @@ -85,6 +87,7 @@ public class WorldGenerator implements Generator { } } + @Override public synchronized double getElevation(int x, int z) { if(elevationExp == null) return 0; elevationXVar.setValue(x); @@ -125,13 +128,12 @@ public class WorldGenerator implements Generator { return biomeNoise; } + @Override + public double getElevationWeight() { + return elevationWeight; + } + public Palette getSlantPalette(int y) { return slantPalettes.getPalette(y); } - - - public boolean interpolateElevation() { - return elevationInterpolation; - } - } diff --git a/common/src/main/java/com/dfsek/terra/generation/math/interpolation/ElevationInterpolator.java b/common/src/main/java/com/dfsek/terra/generation/math/interpolation/ElevationInterpolator.java index 62b92a6ae..dcfa846cf 100644 --- a/common/src/main/java/com/dfsek/terra/generation/math/interpolation/ElevationInterpolator.java +++ b/common/src/main/java/com/dfsek/terra/generation/math/interpolation/ElevationInterpolator.java @@ -1,9 +1,9 @@ package com.dfsek.terra.generation.math.interpolation; import com.dfsek.terra.api.platform.world.World; +import com.dfsek.terra.api.world.biome.Generator; import com.dfsek.terra.biome.BiomeProvider; import com.dfsek.terra.generation.config.WorldGenerator; -import net.jafama.FastMath; public class ElevationInterpolator { private final double[][] values = new double[18][18]; @@ -24,12 +24,15 @@ public class ElevationInterpolator { for(int x = -1; x <= 16; x++) { for(int z = -1; z <= 16; z++) { double noise = 0; + double div = 0; for(int xi = -smooth; xi <= smooth; xi++) { for(int zi = -smooth; zi <= smooth; zi++) { - noise += gens[x + 1 + smooth + xi][z + 1 + smooth + zi].getElevation(xOrigin + x, zOrigin + z); + Generator gen = gens[x + 1 + smooth + xi][z + 1 + smooth + zi]; + noise += gen.getElevation(xOrigin + x, zOrigin + z) * gen.getElevationWeight(); + div += gen.getElevationWeight(); } } - values[x + 1][z + 1] = noise / FastMath.pow2(smooth * 2 + 1); + values[x + 1][z + 1] = noise / div; } } }