- improve how terrain is cut out above village pieces

- further refinements to transition points
- fix incorrect preset jsons
- improve accuracy of biome lookups
This commit is contained in:
dags- 2020-06-30 12:16:42 +01:00
parent a73058062c
commit 2edc791a3d
18 changed files with 112 additions and 47 deletions

2
Engine

@ -1 +1 @@
Subproject commit d9dee330393aa0bce3bc69920734d80617c82be2
Subproject commit b4fd74c174412ca08d72c694dad5ee85e1e95d9e

View File

@ -109,8 +109,8 @@ classes {
dependsOn(collectLibs)
}
jar {
finalizedBy("reobfJar")
build {
dependsOn("reobfJar")
}
publishing {

View File

@ -52,6 +52,19 @@ public interface ColumnDecorator {
}
}
default void fillDownSolid(DecoratorContext context, IChunk chunk, int x, int z, int from, int to, BlockState state) {
for (int dy = from; dy > to; dy--) { ;
replaceSolid(chunk, context.pos.setPos(x, dy, z), state);
}
}
static void replaceSolid(IChunk chunk, BlockPos pos, BlockState state) {
if (chunk.getBlockState(pos).isAir(chunk, pos)) {
return;
}
chunk.setBlockState(pos, state, false);
}
static float getNoise(float x, float z, int seed, float scale, float bias) {
return (variance.getValue(x, z, seed) * scale) + bias;
}

View File

@ -38,7 +38,7 @@ public interface BiomeMap {
Biome getBeach(Cell cell);
Biome getCoast(Cell cell, Biome current);
Biome getCoast(Cell cell);
Biome getRiver(Cell cell);

View File

@ -54,6 +54,7 @@ public class SimpleBiomeMap implements BiomeMap {
}
}
@Override
public Biome provideBiome(Cell cell, Levels levels) {
TerrainType type = cell.terrain.getType();
if (type.isSubmerged() && cell.value > levels.water) {
@ -78,7 +79,7 @@ public class SimpleBiomeMap implements BiomeMap {
}
@Override
public Biome getCoast(Cell cell, Biome current) {
public Biome getCoast(Cell cell) {
int inland = land.getSize(cell);
Biome[] coastal = coast.getSet(cell);
int total = inland + coastal.length;
@ -86,7 +87,7 @@ public class SimpleBiomeMap implements BiomeMap {
if (index >= inland) {
return coastal[index - inland];
}
return current;
return DefaultBiomes.NONE;
}
@Override

View File

@ -28,6 +28,7 @@ package com.terraforged.mod.biome.modifier;
import com.terraforged.api.biome.modifier.BiomeModifier;
import com.terraforged.core.cell.Cell;
import com.terraforged.mod.biome.map.BiomeMap;
import com.terraforged.mod.biome.map.defaults.DefaultBiomes;
import com.terraforged.mod.chunk.TerraContext;
import com.terraforged.world.terrain.Terrains;
import net.minecraft.world.biome.Biome;
@ -57,7 +58,10 @@ public class CoastModifier implements BiomeModifier {
@Override
public Biome modify(Biome in, Cell cell, int x, int z) {
if (cell.terrain.isCoast()) {
return biomeMap.getCoast(cell, in);
Biome coast = biomeMap.getCoast(cell);
if (coast != DefaultBiomes.NONE) {
return coast;
}
}
return in;
}

View File

@ -69,6 +69,12 @@ public class TerraBiomeProvider extends BiomeProvider {
return getWorldLookup().getCell(x, z);
}
public Biome getBiome(int x, int z) {
try (Resource<Cell> resource = getWorldLookup().getCell(x, z, true)) {
return getBiome(resource.get(), x, z);
}
}
@Override
public Biome getNoiseBiome(int x, int y, int z) {
x = (x << 2);

View File

@ -96,7 +96,7 @@ public class ErosionDecorator implements ColumnDecorator {
erodeRock(context, chunk, x, y, z);
return;
} else {
fillDown(context, chunk, x, z, y, y - 4, material);
fillDownSolid(context, chunk, x, z, y, y - 4, material);
}
}
placeScree(chunk, context, x, y, z);
@ -105,7 +105,7 @@ public class ErosionDecorator implements ColumnDecorator {
protected void erodeRock(DecoratorContext context, IChunk chunk, int dx, int y, int dz) {
int depth = 32;
BlockState material = Blocks.GRAVEL.getDefaultState();
BlockState material = States.GRAVEL.get();
// find the uppermost layer of rock & record it's depth
for (int dy = 3; dy < 32; dy++) {
context.pos.setPos(dx, y - dy, dz);
@ -119,8 +119,7 @@ public class ErosionDecorator implements ColumnDecorator {
// fill downwards to the first rock layer
for (int dy = 0; dy < depth; dy++) {
context.pos.setPos(dx, y - dy, dz);
chunk.setBlockState(context.pos, material, false);
ColumnDecorator.replaceSolid(chunk, context.pos.setPos(dx, y - dy, dz), material);
}
}
@ -133,7 +132,7 @@ public class ErosionDecorator implements ColumnDecorator {
float sediment = context.cell.sediment * SEDIMENT_MODIFIER;
float noise = context.climate.getRand().getValue(x, z, seed3) * SEDIMENT_NOISE;
if (sediment + noise > SCREE_VALUE) {
fillDown(context, chunk, x, z, y, y - 2, States.GRAVEL.get());
fillDownSolid(context, chunk, x, z, y, y - 2, States.GRAVEL.get());
}
}

View File

@ -48,8 +48,7 @@ public class GeologyDecorator implements ColumnDecorator {
public void decorate(ChunkSurfaceBuffer buffer, DecoratorContext context, int x, int y, int z) {
int top = buffer.getSurfaceBottom();
geology.getGeology(context.biome).getStrata(x, z).downwards(x, top, z, context.depthBuffer.get(), (py, state) -> {
context.pos.setPos(x, py, z);
buffer.getDelegate().setBlockState(context.pos, state, false);
ColumnDecorator.replaceSolid(buffer.getDelegate(), context.pos.setPos(x, py, z), state);
return true;
});
}

View File

@ -26,7 +26,7 @@ public class TerrainGenerator implements Generator.Terrain {
this.levels = generator.getContext().levels;
this.terrain = generator.getContext().terrain;
this.climate = generator.getContext().factory.getClimate();
this.terrainHelper = new TerrainHelper(0.75F);
this.terrainHelper = new TerrainHelper(0.75F, 4F);
}
@Override

View File

@ -31,6 +31,28 @@ public class SettingsHelper {
}
}
public static TerraSettings loadSettings(File file) {
TerraSettings settings = new TerraSettings();
try (Reader reader = new BufferedReader(new FileReader(file))) {
JsonElement data = new JsonParser().parse(reader);
CompoundNBT nbt = NBTHelper.fromJson(data);
if (NBTHelper.deserialize(nbt, settings)) {
return settings;
}
} catch (IOException e) {
e.printStackTrace();
}
try (Writer writer = new BufferedWriter(new FileWriter(file))) {
CompoundNBT tag = NBTHelper.serializeCompact(settings);
JsonElement json = NBTHelper.toJson(tag);
GSON.toJson(json, writer);
} catch (IOException e) {
e.printStackTrace();
}
return settings;
}
public static void exportDefaults(TerraSettings settings) {
CompoundNBT tag = NBTHelper.serializeCompact(settings);
JsonElement json = NBTHelper.toJson(tag);
@ -51,18 +73,10 @@ public class SettingsHelper {
}
public static TerraSettings readDefaults() {
TerraSettings settings = new TerraSettings();
if (DEFAULTS_FILE.exists()) {
try (Reader reader = new BufferedReader(new FileReader(DEFAULTS_FILE))) {
Log.info("Loading generator settings from json");
JsonElement json = new JsonParser().parse(reader);
CompoundNBT root = NBTHelper.fromJson(json);
NBTHelper.deserialize(root, settings);
} catch (Throwable t) {
t.printStackTrace();
}
return loadSettings(DEFAULTS_FILE);
}
return settings;
return new TerraSettings();
}
public static TerraSettings getSettings(WorldInfo info) {

View File

@ -3,20 +3,16 @@ package com.terraforged.mod.chunk.settings.preset;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.terraforged.mod.Log;
import com.terraforged.mod.chunk.settings.SettingsHelper;
import com.terraforged.mod.chunk.settings.TerraSettings;
import com.terraforged.mod.util.nbt.NBTHelper;
import net.minecraft.nbt.CompoundNBT;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
@ -127,15 +123,8 @@ public class PresetManager implements Iterable<Preset> {
}
String name = file.getName().substring(0, file.getName().length() - 5);
try (Reader reader = new BufferedReader(new FileReader(file))) {
JsonElement data = new JsonParser().parse(reader);
CompoundNBT nbt = NBTHelper.fromJson(data);
TerraSettings settings = new TerraSettings();
NBTHelper.deserialize(nbt, settings);
presets.add(new Preset(name, file, settings));
} catch (IOException e) {
e.printStackTrace();
}
TerraSettings settings = SettingsHelper.loadSettings(file);
presets.add(new Preset(name, file, settings));
}
return new PresetManager(presets);

View File

@ -11,7 +11,7 @@ public class TerraBoundSlider extends TerraSlider.Float {
private final String upper;
public TerraBoundSlider(String name, CompoundNBT value) {
this(name, value, 0.01F);
this(name, value, 0.005F);
}
public TerraBoundSlider(String name, CompoundNBT value, float pad) {

View File

@ -40,6 +40,7 @@ import com.terraforged.mod.util.nbt.NBTHelper;
import com.terraforged.n2d.util.NoiseUtil;
import com.terraforged.world.GeneratorContext;
import com.terraforged.world.continent.MutableVeci;
import com.terraforged.world.continent.SpawnType;
import com.terraforged.world.heightmap.Levels;
import com.terraforged.world.terrain.Terrains;
import net.minecraft.client.Minecraft;
@ -204,7 +205,9 @@ public class Preview extends Button {
GeneratorContext context = GeneratorContext.createNoCache(Terrains.create(settings), settings);
MutableVeci center = new MutableVeci();
context.factory.getHeightmap().getContinent().getNearestCenter(offsetX, offsetZ, center);
if (settings.world.properties.spawnType == SpawnType.CONTINENT_CENTER) {
context.factory.getHeightmap().getContinent().getNearestCenter(offsetX, offsetZ, center);
}
TileGenerator renderer = TileGenerator.builder()
.pool(threadPool)

View File

@ -59,9 +59,15 @@ public class TerrainHelper {
);
private final float radius;
private final float overhang;
private final float overhang2;
public TerrainHelper(float radius) {
this.radius = radius;
// base - the size of the base built up around a piece as a percentage of its bounding box size
// overhang - the amount of overhead overhang to be cut out
public TerrainHelper(float base, float cutout) {
this.radius = base;
this.overhang = cutout;
this.overhang2 = cutout * cutout;
}
public void flatten(IWorld world, IChunk chunk) {
@ -148,7 +154,22 @@ public class TerrainHelper {
if (highest != null) {
MutableBoundingBox bounds = highest.getBoundingBox();
for (int dy = bounds.minY + highestOffset; dy <= surface; dy++) {
int minY = bounds.minY + highestOffset;
int maxY = minY + bounds.getYSize();
if (maxY <= surface) {
// gets weaker the further from the center of the piece
float dist = getCenterDistance2(x, z, bounds);
float distAlpha = 1F - NoiseUtil.clamp(dist / overhang2, 0, 1);
// gets weaker the more material is overhead creating the inverse cutout (ie overhang)
float depth = surface - maxY;
float depthAlpha = 1F - NoiseUtil.clamp(depth / overhang, 0, 1);
maxY += NoiseUtil.round(depthAlpha * distAlpha * overhang);
}
for (int dy = minY; dy <= maxY; dy++) {
pos.setPos(dx, dy, dz);
chunk.setBlockState(pos, Blocks.AIR.getDefaultState(), false);
}
@ -164,6 +185,14 @@ public class TerrainHelper {
return NoiseUtil.lerp(surface, level, alpha);
}
private float getCenterDistance2(int x, int z, MutableBoundingBox bounds) {
float cx = bounds.minX + (bounds.getXSize() / 2F);
float cz = bounds.minZ + (bounds.getZSize() / 2F);
float dx = cx - x;
float dz = cz - z;
return dx * dx + dz * dz;
}
private static void collectPiece(StructurePiece structurepiece, List<StructurePiece> list) {
if (structurepiece instanceof AbstractVillagePiece) {
AbstractVillagePiece piece = (AbstractVillagePiece) structurepiece;

View File

@ -132,7 +132,11 @@ public class TerraCommand {
try (Resource<Cell> cell = biomeProvider.lookupPos(pos.getX(), pos.getZ())) {
Biome biome = biomeProvider.getBiome(cell.get(), pos.getX(), pos.getZ());
context.getSource().sendFeedback(
new StringTextComponent("Terrain=" + cell.get().terrain.getName() + ", Biome=" + biome.getRegistryName()),
new StringTextComponent(
"Terrain=" + cell.get().terrain.getName()
+ ", Biome=" + biome.getRegistryName()
+ ", BiomeType=" + cell.get().biomeType.name()
),
false
);
}

View File

@ -27,6 +27,9 @@ public class BiomeSearchTask extends ChunkGeneratorSearch {
@Override
public boolean test(BlockPos pos) {
biomeProvider.getWorldLookup().applyCell(cell, pos.getX(), pos.getZ());
return biomeProvider.getBiome(cell, pos.getX(), pos.getZ()) == biome;
if (biomeProvider.getBiome(cell, pos.getX(), pos.getZ()) == biome) {
return biomeProvider.getBiome(pos.getX(), pos.getZ()) == biome;
}
return false;
}
}

View File

@ -114,12 +114,13 @@ public class NBTHelper {
return tag;
}
public static void deserialize(CompoundNBT settings, Object object) {
public static boolean deserialize(CompoundNBT settings, Object object) {
try {
NBTReader reader = new NBTReader(settings);
reader.writeTo(object);
return reader.writeTo(object);
} catch (Throwable e) {
e.printStackTrace();
return false;
}
}
}