mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-04-07 00:06:12 +00:00
implement biome pipeline config loader
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package com.dfsek.terra.biome;
|
||||
|
||||
import com.dfsek.tectonic.exception.ConfigException;
|
||||
import com.dfsek.terra.api.math.vector.Vector2;
|
||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||
import com.dfsek.terra.biome.pipeline.BiomeHolder;
|
||||
@@ -11,11 +12,10 @@ import net.jafama.FastMath;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class StandardBiomeProvider implements BiomeProvider {
|
||||
private final BiomePipeline pipeline;
|
||||
private final LoadingCache<Vector2, BiomeHolder> cache = CacheBuilder.newBuilder()
|
||||
private final LoadingCache<Vector2, BiomeHolder> holderCache = CacheBuilder.newBuilder()
|
||||
.maximumSize(1024)
|
||||
.build(
|
||||
new CacheLoader<Vector2, BiomeHolder>() {
|
||||
@@ -25,6 +25,22 @@ public class StandardBiomeProvider implements BiomeProvider {
|
||||
}
|
||||
}
|
||||
);
|
||||
private final LoadingCache<Vector2, TerraBiome> biomeCache = CacheBuilder.newBuilder()
|
||||
.maximumSize(1024)
|
||||
.build(
|
||||
new CacheLoader<Vector2, TerraBiome>() {
|
||||
@Override
|
||||
public TerraBiome load(@NotNull Vector2 key) throws ExecutionException {
|
||||
int x = FastMath.floorToInt(key.getX());
|
||||
int z = FastMath.floorToInt(key.getZ());
|
||||
x /= resolution;
|
||||
z /= resolution;
|
||||
int fdX = FastMath.floorDiv(x, pipeline.getSize());
|
||||
int fdZ = FastMath.floorDiv(z, pipeline.getSize());
|
||||
return holderCache.get(new Vector2(fdX, fdZ)).getBiome(x - fdX * pipeline.getSize(), z - fdZ * pipeline.getSize());
|
||||
}
|
||||
}
|
||||
);
|
||||
private int resolution = 4;
|
||||
|
||||
protected StandardBiomeProvider(BiomePipeline pipeline) {
|
||||
@@ -33,10 +49,8 @@ public class StandardBiomeProvider implements BiomeProvider {
|
||||
|
||||
@Override
|
||||
public TerraBiome getBiome(int x, int z) {
|
||||
x /= resolution;
|
||||
z /= resolution;
|
||||
try {
|
||||
return cache.get(new Vector2(FastMath.floorDiv(x, pipeline.getSize()), FastMath.floorDiv(z, pipeline.getSize()))).getBiome(FastMath.floorMod(x, pipeline.getSize()), FastMath.floorMod(z, pipeline.getSize()));
|
||||
return biomeCache.get(new Vector2(x, z));
|
||||
} catch(ExecutionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -50,16 +64,24 @@ public class StandardBiomeProvider implements BiomeProvider {
|
||||
this.resolution = resolution;
|
||||
}
|
||||
|
||||
public static final class StandardBiomeProviderBuilder implements BiomeProviderBuilder {
|
||||
private final Function<Long, BiomePipeline> pipelineBuilder;
|
||||
public interface ExceptionalFunction<I, O> {
|
||||
O apply(I in) throws ConfigException;
|
||||
}
|
||||
|
||||
public StandardBiomeProviderBuilder(Function<Long, BiomePipeline> pipelineBuilder) {
|
||||
public static final class StandardBiomeProviderBuilder implements BiomeProviderBuilder {
|
||||
private final ExceptionalFunction<Long, BiomePipeline> pipelineBuilder;
|
||||
|
||||
public StandardBiomeProviderBuilder(ExceptionalFunction<Long, BiomePipeline> pipelineBuilder) {
|
||||
this.pipelineBuilder = pipelineBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StandardBiomeProvider build(long seed) {
|
||||
return new StandardBiomeProvider(pipelineBuilder.apply(seed));
|
||||
try {
|
||||
return new StandardBiomeProvider(pipelineBuilder.apply(seed));
|
||||
} catch(ConfigException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import com.dfsek.terra.config.files.FolderLoader;
|
||||
import com.dfsek.terra.config.files.Loader;
|
||||
import com.dfsek.terra.config.files.ZIPLoader;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
import com.dfsek.terra.config.loaders.config.BiomeProviderBuilderLoader;
|
||||
import com.dfsek.terra.config.loaders.config.biome.BiomeProviderBuilderLoader;
|
||||
import com.dfsek.terra.config.templates.AbstractableTemplate;
|
||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||
import com.dfsek.terra.config.templates.CarverTemplate;
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.dfsek.terra.config.loaders;
|
||||
import com.dfsek.terra.api.math.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.platform.block.MaterialData;
|
||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||
import com.dfsek.terra.api.world.flora.Flora;
|
||||
import com.dfsek.terra.api.world.palette.Palette;
|
||||
import com.dfsek.terra.api.world.tree.Tree;
|
||||
@@ -21,6 +22,7 @@ public final class Types {
|
||||
public static final Type BLOCK_DATA_PROBABILITY_COLLECTION_TYPE;
|
||||
public static final Type FLORA_PROBABILITY_COLLECTION_TYPE;
|
||||
public static final Type TREE_PROBABILITY_COLLECTION_TYPE;
|
||||
public static final Type TERRA_BIOME_PROBABILITY_COLLECTION_TYPE;
|
||||
|
||||
static {
|
||||
MATERIAL_SET_TYPE = getType("materialSet");
|
||||
@@ -29,6 +31,7 @@ public final class Types {
|
||||
BLOCK_DATA_PROBABILITY_COLLECTION_TYPE = getType("blockDataProbabilityCollection");
|
||||
FLORA_PROBABILITY_COLLECTION_TYPE = getType("floraProbabilityCollection");
|
||||
TREE_PROBABILITY_COLLECTION_TYPE = getType("treeProbabilityCollection");
|
||||
TERRA_BIOME_PROBABILITY_COLLECTION_TYPE = getType("terraBiomeProbabilityCollection");
|
||||
}
|
||||
|
||||
private Set<MaterialData> materialSet;
|
||||
@@ -37,6 +40,7 @@ public final class Types {
|
||||
private ProbabilityCollection<BlockData> blockDataProbabilityCollection;
|
||||
private ProbabilityCollection<Flora> floraProbabilityCollection;
|
||||
private ProbabilityCollection<Tree> treeProbabilityCollection;
|
||||
private ProbabilityCollection<TerraBiome> terraBiomeProbabilityCollection;
|
||||
|
||||
private static Type getType(String dummyFieldName) {
|
||||
try {
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
package com.dfsek.terra.config.loaders.config;
|
||||
|
||||
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.FastNoiseLite;
|
||||
import com.dfsek.terra.api.math.noise.samplers.NoiseSampler;
|
||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||
import com.dfsek.terra.biome.BiomeProvider;
|
||||
import com.dfsek.terra.biome.StandardBiomeProvider;
|
||||
import com.dfsek.terra.biome.pipeline.BiomePipeline;
|
||||
import com.dfsek.terra.biome.pipeline.expand.FractalExpander;
|
||||
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.base.ConfigPack;
|
||||
import net.jafama.FastMath;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public class BiomeProviderBuilderLoader implements TypeLoader<BiomeProvider.BiomeProviderBuilder> {
|
||||
private final ConfigPack pack;
|
||||
|
||||
public BiomeProviderBuilderLoader(ConfigPack pack) {
|
||||
this.pack = pack;
|
||||
}
|
||||
|
||||
private static NoiseSampler whiteNoise(int seed) {
|
||||
FastNoiseLite noiseLite = new FastNoiseLite(seed);
|
||||
noiseLite.setNoiseType(FastNoiseLite.NoiseType.WhiteNoise);
|
||||
return noiseLite;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeProvider.BiomeProviderBuilder load(Type t, Object c, ConfigLoader loader) {
|
||||
|
||||
|
||||
return new StandardBiomeProvider.StandardBiomeProviderBuilder(seed -> {
|
||||
ProbabilityCollection<TerraBiome> biomes = new ProbabilityCollection<>();
|
||||
|
||||
biomes.add(pack.getBiome("PLAINS"), 1)
|
||||
.add(pack.getBiome("SAVANNA"), 2);
|
||||
BiomePipeline pipeline = new BiomePipeline.BiomePipelineBuilder(2)
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(FastMath.toInt(seed)))))
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(FastMath.toInt(seed + 1)))))
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(FastMath.toInt(seed + 2)))))
|
||||
.addStage(new MutatorStage(new SmoothMutator(whiteNoise(FastMath.toInt(seed + 3)))))
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(FastMath.toInt(seed + 4)))))
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(FastMath.toInt(seed + 5)))))
|
||||
.build(new RandomSource(biomes, whiteNoise(FastMath.toInt(seed) + 4)));
|
||||
System.out.println(pipeline.getSize());
|
||||
return pipeline;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.dfsek.terra.config.loaders.config.biome;
|
||||
|
||||
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.FastNoiseLite;
|
||||
import com.dfsek.terra.api.math.noise.samplers.NoiseSampler;
|
||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||
import com.dfsek.terra.biome.BiomeProvider;
|
||||
import com.dfsek.terra.biome.StandardBiomeProvider;
|
||||
import com.dfsek.terra.biome.pipeline.BiomePipeline;
|
||||
import com.dfsek.terra.biome.pipeline.expand.FractalExpander;
|
||||
import com.dfsek.terra.biome.pipeline.mutator.ReplaceMutator;
|
||||
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.base.ConfigPack;
|
||||
import com.dfsek.terra.config.loaders.Types;
|
||||
import com.dfsek.terra.config.loaders.config.NoiseBuilderLoader;
|
||||
import com.dfsek.terra.generation.config.NoiseBuilder;
|
||||
import net.jafama.FastMath;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class BiomeProviderBuilderLoader implements TypeLoader<BiomeProvider.BiomeProviderBuilder> {
|
||||
private final ConfigPack pack;
|
||||
|
||||
public BiomeProviderBuilderLoader(ConfigPack pack) {
|
||||
this.pack = pack;
|
||||
}
|
||||
|
||||
private static NoiseSampler whiteNoise(int seed) {
|
||||
FastNoiseLite noiseLite = new FastNoiseLite(seed);
|
||||
noiseLite.setNoiseType(FastNoiseLite.NoiseType.WhiteNoise);
|
||||
return noiseLite;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeProvider.BiomeProviderBuilder load(Type t, Object c, ConfigLoader loader) {
|
||||
Map<String, Object> map = (Map<String, Object>) c;
|
||||
|
||||
return new StandardBiomeProvider.StandardBiomeProviderBuilder(seed -> {
|
||||
Map<String, Object> source = (Map<String, Object>) map.get("source");
|
||||
ProbabilityCollection<TerraBiome> sourceBiomes = (ProbabilityCollection<TerraBiome>) loader.loadType(Types.TERRA_BIOME_PROBABILITY_COLLECTION_TYPE, source.get("biomes"));
|
||||
NoiseSampler sourceNoise = new NoiseBuilderLoader().load(NoiseBuilder.class, source.get("noise"), loader).build(FastMath.toInt(seed));
|
||||
|
||||
List<Map<String, Object>> stages = (List<Map<String, Object>>) map.get("pipeline");
|
||||
BiomePipeline.BiomePipelineBuilder pipelineBuilder = new BiomePipeline.BiomePipelineBuilder(2);
|
||||
for(Map<String, Object> stage : stages) {
|
||||
for(Map.Entry<String, Object> entry : stage.entrySet()) {
|
||||
Map<String, Object> mutator = (Map<String, Object>) entry.getValue();
|
||||
NoiseSampler mutatorNoise = new NoiseBuilderLoader().load(NoiseBuilder.class, mutator.get("noise"), loader).build(FastMath.toInt(seed));
|
||||
|
||||
if(entry.getKey().equals("expand")) {
|
||||
if(mutator.get("type").equals("FRACTAL"))
|
||||
pipelineBuilder.addStage(new ExpanderStage(new FractalExpander(mutatorNoise)));
|
||||
else throw new LoadException("No such expander \"" + mutator.get("type"));
|
||||
} else if(entry.getKey().equals("mutate")) {
|
||||
if(mutator.get("type").equals("SMOOTH"))
|
||||
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"));
|
||||
pipelineBuilder.addStage(new MutatorStage(new ReplaceMutator(fromTag, replaceBiomes, mutatorNoise)));
|
||||
} else throw new LoadException("No such mutator type \"" + mutator.get("type"));
|
||||
} else throw new LoadException("No such mutator \"" + entry.getKey() + "\"");
|
||||
}
|
||||
}
|
||||
return pipelineBuilder.build(new RandomSource(sourceBiomes, sourceNoise));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -9,11 +9,14 @@ import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||
import com.dfsek.terra.biome.pipeline.BiomeHolder;
|
||||
import com.dfsek.terra.biome.pipeline.BiomePipeline;
|
||||
import com.dfsek.terra.biome.pipeline.expand.FractalExpander;
|
||||
import com.dfsek.terra.biome.pipeline.mutator.BorderMutator;
|
||||
import com.dfsek.terra.biome.pipeline.mutator.ReplaceMutator;
|
||||
import com.dfsek.terra.biome.pipeline.mutator.SmoothMutator;
|
||||
import com.dfsek.terra.biome.pipeline.source.BiomeSource;
|
||||
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.google.common.collect.Sets;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -41,7 +44,7 @@ public class BiomeTest {
|
||||
|
||||
ProbabilityCollection<TerraBiome> climate = new ProbabilityCollection<>();
|
||||
climate.add(ocean, 1);
|
||||
climate.add(land, 3);
|
||||
climate.add(land, 2);
|
||||
|
||||
|
||||
oceanBiomes.add(new TestBiome(Color.BLUE, "OCEAN"), 10);
|
||||
@@ -61,9 +64,13 @@ public class BiomeTest {
|
||||
|
||||
BiomePipeline pipeline = new BiomePipeline.BiomePipelineBuilder(20)
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(1))))
|
||||
.addStage(new MutatorStage(new ReplaceMutator("OCEAN_TEMP", oceanBiomes, whiteNoise(243))))
|
||||
.addStage(new MutatorStage(new ReplaceMutator("LAND_TEMP", landBiomes, whiteNoise(243))))
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(2))))
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(2))))
|
||||
.addStage(new MutatorStage(new SmoothMutator(whiteNoise(3))))
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(4))))
|
||||
.addStage(new MutatorStage(new BorderMutator(Sets.newHashSet("OCEAN"), "LAND", whiteNoise(1234), beachBiomes)))
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(5))))
|
||||
.addStage(new MutatorStage(new SmoothMutator(whiteNoise(6))))
|
||||
.build(source);
|
||||
@@ -73,25 +80,6 @@ public class BiomeTest {
|
||||
BiomeHolder holder3 = pipeline.getBiomes(0, 1);
|
||||
BiomeHolder holder4 = pipeline.getBiomes(1, 1);
|
||||
|
||||
//holder = holder.expand(new FractalExpander(whiteNoise(4)));
|
||||
|
||||
//holder.mutate(new ReplaceMutator("OCEAN_TEMP", oceanBiomes, whiteNoise(234)));
|
||||
//holder.mutate(new ReplaceMutator("LAND_TEMP", landBiomes, whiteNoise(235)));
|
||||
|
||||
//holder = holder.expand(new FractalExpander(whiteNoise(3)));
|
||||
//holder = holder.expand(new FractalExpander(whiteNoise(2)));
|
||||
|
||||
//holder.mutate(new SmoothMutator(whiteNoise(34)));
|
||||
|
||||
//holder = holder.expand(new FractalExpander(whiteNoise(5)));
|
||||
//holder = holder.expand(new FractalExpander(whiteNoise(7)));
|
||||
|
||||
//holder.mutate(new BorderMutator(Sets.newHashSet("OCEAN"), "LAND", whiteNoise(2356), beachBiomes));
|
||||
|
||||
//holder = holder.expand(new FractalExpander(whiteNoise(6)));
|
||||
|
||||
//holder.mutate(new SmoothMutator(whiteNoise(35)));
|
||||
|
||||
long e = System.nanoTime();
|
||||
|
||||
int size = pipeline.getSize();
|
||||
|
||||
Reference in New Issue
Block a user