add elevation weight, add "self" biome opt

This commit is contained in:
dfsek
2021-01-17 21:55:08 -07:00
parent af5b316326
commit 4b21fcd80a
11 changed files with 141 additions and 61 deletions

View File

@@ -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<E> {
public Set<E> getContents() {
return new HashSet<>(cont);
}
public static final class Singleton<T> extends ProbabilityCollection<T> {
private final T single;
public Singleton(T single) {
this.single = single;
}
@Override
public ProbabilityCollection<T> 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<T> getContents() {
return Collections.singleton(single);
}
}
}

View File

@@ -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();
}

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -25,6 +25,7 @@ public class BiomeFactory implements TerraFactory<BiomeTemplate, UserDefinedBiom
generatorBuilder.setInterpolateElevation(template.interpolateElevation());
generatorBuilder.setNoise2d(template.isNoise2d());
generatorBuilder.setBase(template.getNoise2dBase());
generatorBuilder.setElevationWeight(template.getElevationWeight());
generatorBuilder.setBiomeNoise(template.getBiomeNoise());

View File

@@ -4,15 +4,11 @@ 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 com.dfsek.terra.api.math.noise.samplers.NoiseSampler;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
@SuppressWarnings("unchecked")
public class ProbabilityCollectionLoader implements TypeLoader<ProbabilityCollection<Object>> {
@@ -32,11 +28,12 @@ public class ProbabilityCollectionLoader implements TypeLoader<ProbabilityCollec
List<Map<Object, Integer>> map = (List<Map<Object, Integer>>) o;
for(Map<Object, Integer> l : map) {
for(Map.Entry<Object, Integer> 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<ProbabilityCollec
return collection;
}
private static final class Singleton<T> extends ProbabilityCollection<T> {
private final T single;
private Singleton(T single) {
this.single = single;
}
@Override
public ProbabilityCollection<T> 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<T> getContents() {
return Collections.singleton(single);
}
}
}

View File

@@ -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<T> implements TypeLoader<ProbabilityCollection<T>> {
@Override
public ProbabilityCollection<T> load(Type type, Object o, ConfigLoader loader) throws LoadException {
ProbabilityCollection<T> collection = new ProbabilityCollection<>();
if(type instanceof ParameterizedType) {
ParameterizedType pType = (ParameterizedType) type;
Type generic = pType.getActualTypeArguments()[0];
if(o instanceof Map) {
Map<Object, Integer> map = (Map<Object, Integer>) o;
addItems(loader, collection, generic, map);
} else if(o instanceof List) {
List<Map<Object, Integer>> map = (List<Map<Object, Integer>>) o;
for(Map<Object, Integer> 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<T> collection, Type generic, Map<Object, Integer> l) throws LoadException {
for(Map.Entry<Object, Integer> 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());
}
}
}

View File

@@ -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<BiomeProvider.Biom
pipelineBuilder.addStage(new MutatorStage(new SmoothMutator(mutatorNoise)));
else if(mutator.get("type").equals("REPLACE")) {
String fromTag = mutator.get("from").toString();
ProbabilityCollection<TerraBiome> replaceBiomes = (ProbabilityCollection<TerraBiome>) loader.loadType(Types.TERRA_BIOME_PROBABILITY_COLLECTION_TYPE, mutator.get("to"));
ProbabilityCollection<TerraBiome> replaceBiomes = new SelfProbabilityCollectionLoader<TerraBiome>().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();

View File

@@ -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

View File

@@ -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<String, NoiseBuilder> noiseBuilders, PaletteHolder palettes, PaletteHolder slantPalettes, boolean elevationInterpolation, boolean noise2d, double base, NoiseSampler biomeNoise) {
public WorldGenerator(long seed, String equation, String elevateEquation, Scope vScope, Map<String, NoiseBuilder> 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<BlockData> getSlantPalette(int y) {
return slantPalettes.getPalette(y);
}
public boolean interpolateElevation() {
return elevationInterpolation;
}
}

View File

@@ -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;
}
}
}