slant palette things

This commit is contained in:
dfsek 2021-07-15 17:57:54 -07:00
parent 319df9e638
commit 2cd71cdcd3
12 changed files with 126 additions and 43 deletions

View File

@ -16,9 +16,11 @@ import com.dfsek.terra.api.world.biome.Generator;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.generator.ChunkData;
import com.dfsek.terra.api.world.generator.Palette;
import com.dfsek.terra.api.world.generator.Sampler;
import com.dfsek.terra.api.world.generator.TerraChunkGenerator;
import com.dfsek.terra.api.world.generator.TerraGenerationStage;
import net.jafama.FastMath;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@ -30,9 +32,12 @@ public class NoiseChunkGenerator3D implements TerraChunkGenerator {
private final TerraPlugin main;
private final List<TerraGenerationStage> blockPopulators = new ArrayList<>();
private final BlockState air;
public NoiseChunkGenerator3D(ConfigPack c, TerraPlugin main) {
this.configPack = c;
this.main = main;
this.air = main.getWorldHandle().air();
c.getStages().forEach(stage -> blockPopulators.add(stage.newInstance(c)));
}
@ -148,4 +153,26 @@ public class NoiseChunkGenerator3D implements TerraChunkGenerator {
public List<TerraGenerationStage> getGenerationStages() {
return blockPopulators;
}
@Override
public BlockState getBlock(World world, int x, int y, int z) {
TerraWorld terraWorld = main.getWorld(world);
BiomeProvider provider = terraWorld.getBiomeProvider();
TerraBiome biome = provider.getBiome(x, z);
Palette palette = biome.getGenerator(world).getPaletteSettings().getPalette(y);
Sampler sampler = terraWorld.getConfig().getSamplerCache().get(x, z);
int fdX = FastMath.floorMod(x, 16);
int fdZ = FastMath.floorMod(z, 16);
double noise = sampler.sample(fdX, y, fdZ);
if(noise > 0) {
int level = 0;
for(int yi = world.getMaxHeight() - 1; yi > y; yi--) {
if(sampler.sample(fdX, yi, fdZ) > 0) level++;
else level = 0;
}
return palette.get(level, x, y, z);
} /* else if(y <= biome.getConfig().getSeaLevel()) {
return biome.getConfig().getOceanPalette().get(biome.getConfig().getSeaLevel() - y, x, y, z);
} */ else return air;
}
}

View File

@ -0,0 +1,22 @@
package com.dfsek.terra.addons.chunkgenerator.palette;
import com.dfsek.terra.api.world.generator.Palette;
public class PaletteHolder {
private final Palette[] palettes;
private final int offset;
protected PaletteHolder(Palette[] palettes, int offset) {
this.palettes = palettes;
this.offset = offset;
}
public Palette getPalette(int y) {
int index = y + offset;
return index >= 0
? index < palettes.length
? palettes[index]
: palettes[palettes.length - 1]
: palettes[0];
}
}

View File

@ -0,0 +1,36 @@
package com.dfsek.terra.addons.chunkgenerator.palette;
import com.dfsek.terra.api.world.generator.Palette;
import net.jafama.FastMath;
import java.util.Map;
import java.util.TreeMap;
public class PaletteHolderBuilder {
private final TreeMap<Integer, Palette> paletteMap = new TreeMap<>();
public PaletteHolderBuilder add(int y, Palette palette) {
paletteMap.put(y, palette);
return this;
}
public PaletteHolder build() {
int min = FastMath.min(paletteMap.keySet().stream().min(Integer::compareTo).orElse(0), 0);
int max = FastMath.max(paletteMap.keySet().stream().max(Integer::compareTo).orElse(255), 255);
Palette[] palettes = new Palette[paletteMap.lastKey() + 1 - min];
for(int y = min; y <= FastMath.max(paletteMap.lastKey(), max); y++) {
Palette d = null;
for(Map.Entry<Integer, Palette> e : paletteMap.entrySet()) {
if(e.getKey() >= y) {
d = e.getValue();
break;
}
}
if(d == null) throw new IllegalArgumentException("No palette for Y=" + y);
palettes[y - min] = d;
}
return new PaletteHolder(palettes, -min);
}
}

View File

@ -0,0 +1,25 @@
package com.dfsek.terra.addons.chunkgenerator.palette;
import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.tectonic.loading.TypeLoader;
import com.dfsek.terra.api.world.generator.Palette;
import java.lang.reflect.AnnotatedType;
import java.util.List;
import java.util.Map;
public class PaletteHolderLoader implements TypeLoader<PaletteHolder> {
@SuppressWarnings("unchecked")
@Override
public PaletteHolder load(AnnotatedType type, Object o, ConfigLoader configLoader) throws LoadException {
List<Map<String, Integer>> palette = (List<Map<String, Integer>>) o;
PaletteHolderBuilder builder = new PaletteHolderBuilder();
for(Map<String, Integer> layer : palette) {
for(Map.Entry<String, Integer> entry : layer.entrySet()) {
builder.add(entry.getValue(), configLoader.loadType(Palette.class, entry.getKey()));
}
}
return builder.build();
}
}

View File

@ -1,6 +1,5 @@
package com.dfsek.terra.addons.biome.slant;
package com.dfsek.terra.addons.chunkgenerator.palette;
import com.dfsek.terra.addons.biome.holder.PaletteHolder;
import java.util.TreeMap;

View File

@ -2,7 +2,6 @@ package com.dfsek.terra.addons.biome;
import com.dfsek.terra.addons.biome.holder.PaletteHolder;
import com.dfsek.terra.addons.biome.holder.PaletteHolderLoader;
import com.dfsek.terra.addons.biome.slant.SlantHolder;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.addon.TerraAddon;
import com.dfsek.terra.api.addon.annotations.Addon;
@ -26,7 +25,6 @@ public class BiomeConfigAddon extends TerraAddon implements EventListener {
public void onPackLoad(ConfigPackPreLoadEvent event) {
event.getPack().registerConfigType(new BiomeConfigType(event.getPack()), "BIOME", 5);
event.getPack().applyLoader(PaletteHolder.class, new PaletteHolderLoader())
.applyLoader(SlantHolder.class, (t, o, l) -> null);
event.getPack().applyLoader(PaletteHolder.class, new PaletteHolderLoader());
}
}

View File

@ -8,18 +8,15 @@ import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.config.ValidatedConfigTemplate;
import com.dfsek.tectonic.exception.ValidationException;
import com.dfsek.terra.addons.biome.holder.PaletteHolder;
import com.dfsek.terra.addons.biome.slant.SlantHolder;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.block.BlockType;
import com.dfsek.terra.api.config.AbstractableTemplate;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.structure.ConfiguredStructure;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.api.world.generator.Palette;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@ -51,10 +48,6 @@ public class BiomeTemplate implements AbstractableTemplate, ValidatedConfigTempl
@Value("palette")
private PaletteHolder palette;
@Value("slant")
@Default
private SlantHolder slant = null;
@Value("vanilla")
private ProbabilityCollection<Biome> vanilla;
@ -161,10 +154,6 @@ public class BiomeTemplate implements AbstractableTemplate, ValidatedConfigTempl
return interpolateElevation;
}
public SlantHolder getSlant() {
return slant;
}
public double getSlabThreshold() {
return slabThreshold;
}

View File

@ -12,7 +12,7 @@ import java.util.Set;
* Class representing a config-defined biome
*/
public class UserDefinedBiome implements TerraBiome {
private final WorldGenerator gen;
private final UserDefinedGenerator gen;
private final ProbabilityCollection<Biome> vanilla;
private final String id;
private final BiomeTemplate config;
@ -20,7 +20,7 @@ public class UserDefinedBiome implements TerraBiome {
private final Set<String> tags;
public UserDefinedBiome(ProbabilityCollection<Biome> vanilla, WorldGenerator gen, BiomeTemplate config) {
public UserDefinedBiome(ProbabilityCollection<Biome> vanilla, UserDefinedGenerator gen, BiomeTemplate config) {
this.vanilla = vanilla;
this.gen = gen;
this.id = config.getID();

View File

@ -24,7 +24,7 @@ public class UserDefinedBiomeBuilder implements BiomeBuilder {
synchronized(biomeMap) {
return biomeMap.computeIfAbsent(seed,
s -> {
WorldGenerator generator = new WorldGenerator(template.getPalette(), template.getSlant(), template.getNoiseEquation().apply(seed), template.getElevationEquation().apply(seed), template.getCarvingEquation().apply(seed), template.getBiomeNoise().apply(seed), template.getElevationWeight(),
UserDefinedGenerator generator = new UserDefinedGenerator(template.getPalette(), template.getNoiseEquation().apply(seed), template.getElevationEquation().apply(seed), template.getCarvingEquation().apply(seed), template.getBiomeNoise().apply(seed), template.getElevationWeight(),
template.getBlendDistance(), template.getBlendStep(), template.getBlendWeight());
return new UserDefinedBiome(template.getVanilla(), generator, template);
}

View File

@ -1,14 +1,12 @@
package com.dfsek.terra.addons.biome;
import com.dfsek.terra.addons.biome.holder.PaletteHolder;
import com.dfsek.terra.addons.biome.slant.SlantHolder;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.world.biome.Generator;
import com.dfsek.terra.api.world.biome.PaletteSettings;
public class WorldGenerator implements Generator {
public class UserDefinedGenerator implements Generator {
private final PaletteSettings paletteSettings;
private final SlantHolder slantPalettes;
private final NoiseSampler noise;
private final NoiseSampler elevation;
@ -20,9 +18,8 @@ public class WorldGenerator implements Generator {
private final int blendStep;
private final double blendWeight;
public WorldGenerator(PaletteHolder palettes, SlantHolder slantPalettes, NoiseSampler noise, NoiseSampler elevation, NoiseSampler carving, NoiseSampler biomeNoise, double elevationWeight, int blendDistance, int blendStep, double blendWeight) {
public UserDefinedGenerator(PaletteHolder palettes, NoiseSampler noise, NoiseSampler elevation, NoiseSampler carving, NoiseSampler biomeNoise, double elevationWeight, int blendDistance, int blendStep, double blendWeight) {
this.paletteSettings = new PaletteSettingsImpl(palettes);
this.slantPalettes = slantPalettes;
this.noise = noise;
this.elevation = elevation;
this.carving = carving;

View File

@ -1,7 +1,9 @@
package com.dfsek.terra.api.world.generator;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.BiomeGrid;
import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
@ -22,4 +24,10 @@ public interface TerraChunkGenerator {
Sampler createSampler(int chunkX, int chunkZ, BiomeProvider provider, World world, int elevationSmooth);
List<TerraGenerationStage> getGenerationStages();
BlockState getBlock(World world, int x, int y, int z);
default BlockState getBlock(World world, Vector3 vector3) {
return getBlock(world, vector3.getBlockX(), vector3.getBlockY(), vector3.getBlockZ());
}
}

View File

@ -18,8 +18,6 @@ public class TerraWorldImpl implements TerraWorld {
private final BiomeProvider provider;
private final WorldConfigImpl config;
private final World world;
private final BlockState air;
public TerraWorldImpl(World w, ConfigPack c, TerraPlugin main) {
if(!w.isTerraWorld()) throw new IllegalArgumentException("World " + w + " is not a Terra World!");
@ -27,7 +25,6 @@ public class TerraWorldImpl implements TerraWorld {
config = (WorldConfigImpl) c.toWorldConfig(this);
this.provider = config.getProvider();
main.getEventManager().callEvent(new TerraWorldLoadEvent(this, c));
this.air = main.getWorldHandle().air();
}
@ -50,22 +47,7 @@ public class TerraWorldImpl implements TerraWorld {
@Override
public BlockState getUngeneratedBlock(int x, int y, int z) {
TerraBiome biome = provider.getBiome(x, z);
Palette palette = biome.getGenerator(world).getPaletteSettings().getPalette(y);
Sampler sampler = config.getSamplerCache().get(x, z);
int fdX = FastMath.floorMod(x, 16);
int fdZ = FastMath.floorMod(z, 16);
double noise = sampler.sample(fdX, y, fdZ);
if(noise > 0) {
int level = 0;
for(int yi = world.getMaxHeight() - 1; yi > y; yi--) {
if(sampler.sample(fdX, yi, fdZ) > 0) level++;
else level = 0;
}
return palette.get(level, x, y, z);
} /* else if(y <= biome.getConfig().getSeaLevel()) {
return biome.getConfig().getOceanPalette().get(biome.getConfig().getSeaLevel() - y, x, y, z);
} */ else return air;
return world.getTerraGenerator().getBlock(world, x, y, z);
}
@Override