- tweak filters

- option to extend template bases downwards
This commit is contained in:
dags- 2020-01-18 15:29:30 +00:00
parent e652eb6330
commit 8e33b8ce17
11 changed files with 96 additions and 96 deletions

@ -1 +1 @@
Subproject commit 1597178d4717ad684b67fcb23b3222feae1e3ee0
Subproject commit 6f24e74b7b08c25d5da7db4862319418fdd7fb04

View File

@ -2,7 +2,9 @@ package com.terraforged.core.filter;
import com.terraforged.core.cell.Cell;
import com.terraforged.core.settings.Settings;
import com.terraforged.core.util.PosIterator;
import com.terraforged.core.world.heightmap.Levels;
import me.dags.noise.util.NoiseUtil;
import java.util.Random;
@ -19,12 +21,12 @@ public class Erosion implements Filter {
private int maxDropletLifetime = 30;
private float initialWaterVolume = 1;
private float initialSpeed = 1;
private final Random random = new Random();
private final TerrainPos gradient = new TerrainPos();
private int[][] erosionBrushIndices = new int[0][];
private float[][] erosionBrushWeights = new float[0][];
private final Modifier modifier;
private final Random random = new Random();
public Erosion(Settings settings, Levels levels) {
erodeSpeed = settings.filters.erosion.erosionRate;
@ -33,18 +35,64 @@ public class Erosion implements Filter {
}
@Override
public void setSeed(long seed) {
random.setSeed(seed);
public void apply(Filterable<?> map, int seedX, int seedZ, int iterations) {
if (erosionBrushIndices.length != map.getRawSize()) {
init(map.getRawSize(), erosionRadius);
}
applyMain(map, seedX, seedZ, iterations, random);
}
@Override
public void apply(Filterable<?> cellMap) {
int size = cellMap.getRawWidth();
Cell<?>[] cells = cellMap.getBacking();
private int nextCoord(Filterable<?> map, Random random) {
return random.nextInt(map.getRawSize() - 1);
}
// Create water droplet at random point on map
float posX = random.nextInt(size - 1);
float posY = random.nextInt(size - 1);
private void applyMain(Filterable<?> map, int seedX, int seedZ, int iterations, Random random) {
random.setSeed(NoiseUtil.seed(seedX, seedZ));
while (iterations-- > 0) {
int posX = nextCoord(map, random);
int posZ = nextCoord(map, random);
try {
apply(map.getBacking(), posX, posZ, map.getRawSize());
} catch (Throwable t) {
System.out.println(posX + ":" + posZ + "(" + map.getRawSize() + ")");
throw t;
}
}
}
private void applyNeighbours(Filterable<?> map, int centerX, int centerZ, int iterations, Random random) {
PosIterator regions = PosIterator.area(-1, -1, 3, 3);
while (regions.next()) {
int dx = regions.x();
int dz = regions.z();
if (dx == 0 && dz == 0) {
continue;
}
int rx = centerX + dx;
int rz = centerZ + dz;
random.setSeed(NoiseUtil.seed(rx, rz));
applyNeighbour(map, dx, dz, iterations, random);
}
}
private void applyNeighbour(Filterable<?> map, int deltaX, int deltaZ, int iterations, Random random) {
int max = map.getRawSize() - 1;
int offsetX = deltaX * map.getRawSize();
int offsetZ = deltaZ * map.getRawSize();
while (iterations-- > 0) {
int posX = nextCoord(map, random);
int posZ = nextCoord(map, random);
int relX = posX + offsetX;
int relZ = posZ + offsetZ;
if (relX >= 0 && relX < max && relZ >= 0 && relZ < max) {
apply(map.getBacking(), relX, relZ, map.getRawSize());
}
}
}
private void apply(Cell<?>[] cells, float posX, float posY, int size) {
float dirX = 0;
float dirY = 0;
float speed = initialSpeed;
@ -132,17 +180,6 @@ public class Erosion implements Filter {
}
}
@Override
public void apply(Filterable<?> map, int iterations) {
if (erosionBrushIndices.length != map.getRawWidth()) {
init(map.getRawWidth(), erosionRadius);
}
while (iterations-- > 0) {
apply(map);
}
}
private void init(int size, int radius) {
erosionBrushIndices = new int[size * size][];
erosionBrushWeights = new float[size * size][];
@ -191,13 +228,13 @@ public class Erosion implements Filter {
}
}
private void deposit(Cell cell, float amount) {
private void deposit(Cell<?> cell, float amount) {
float change = modifier.modify(cell, amount);
cell.value += change;
cell.sediment += change;
}
private void erode(Cell cell, float amount) {
private void erode(Cell<?> cell, float amount) {
float change = modifier.modify(cell, amount);
cell.value -= change;
cell.erosion -= change;
@ -208,7 +245,7 @@ public class Erosion implements Filter {
private float gradientX;
private float gradientY;
private TerrainPos update(Cell[] nodes, int mapSize, float posX, float posY) {
private TerrainPos update(Cell<?>[] nodes, int mapSize, float posX, float posY) {
int coordX = (int) posX;
int coordY = (int) posY;

View File

@ -4,23 +4,13 @@ import com.terraforged.core.cell.Cell;
public interface Filter {
void apply(Filterable<?> cellMap);
void apply(Filterable<?> map, int seedX, int seedZ, int iterations);
default void setSeed(long seed) {
}
default void apply(Filterable<?> cellMap, int iterations) {
while (iterations-- > 0) {
apply(cellMap);
}
}
default void iterate(Filterable<?> cellMap, Visitor visitor) {
for (int dz = 0; dz < cellMap.getRawHeight(); dz++) {
for (int dx = 0; dx < cellMap.getRawWidth(); dx++) {
Cell<?> cell = cellMap.getCellRaw(dx, dz);
visitor.visit(cellMap, cell, dx, dz);
default void iterate(Filterable<?> map, Visitor visitor) {
for (int dz = 0; dz < map.getRawSize(); dz++) {
for (int dx = 0; dx < map.getRawSize(); dx++) {
Cell<?> cell = map.getCellRaw(dx, dz);
visitor.visit(map, cell, dx, dz);
}
}
}

View File

@ -5,11 +5,9 @@ import com.terraforged.core.cell.Tag;
public interface Filterable<T extends Tag> {
int getRawWidth();
int getRawHeight();
Cell<T> getCellRaw(int x, int z);
int getRawSize();
Cell<T>[] getBacking();
Cell<T> getCellRaw(int x, int z);
}

View File

@ -20,12 +20,18 @@ public class Smoothing implements Filter {
}
@Override
public void apply(Filterable<?> cellMap) {
int maxZ = cellMap.getRawHeight() - radius;
int maxX = cellMap.getRawWidth() - radius;
public void apply(Filterable<?> map, int seedX, int seedZ, int iterations) {
while (iterations-- > 0) {
apply(map);
}
}
private void apply(Filterable<?> cellMap) {
int maxZ = cellMap.getRawSize() - radius;
int maxX = cellMap.getRawSize() - radius;
for (int z = radius; z < maxZ; z++) {
for (int x = radius; x < maxX; x++) {
Cell cell = cellMap.getCellRaw(x, z);
Cell<?> cell = cellMap.getCellRaw(x, z);
float total = 0;
float weights = 0;

View File

@ -20,7 +20,7 @@ public class Steepness implements Filter, Filter.Visitor {
}
@Override
public void apply(Filterable<?> cellMap) {
public void apply(Filterable<?> cellMap, int seedX, int seedZ, int iterations) {
iterate(cellMap, this);
}

View File

@ -308,12 +308,7 @@ public class Region implements Extent {
private class FilterRegion implements Filterable<Terrain> {
@Override
public int getRawWidth() {
return blockSize.total;
}
@Override
public int getRawHeight() {
public int getRawSize() {
return blockSize.total;
}

View File

@ -1,12 +1,10 @@
package com.terraforged.core.region;
import com.terraforged.core.filter.Filterable;
import com.terraforged.core.util.concurrent.ObjectPool;
import com.terraforged.core.util.concurrent.ThreadPool;
import com.terraforged.core.world.WorldGenerator;
import com.terraforged.core.world.WorldGeneratorFactory;
import com.terraforged.core.world.heightmap.RegionExtent;
import com.terraforged.core.world.terrain.Terrain;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
@ -69,11 +67,7 @@ public class RegionGenerator implements RegionExtent {
}
private void postProcess(Region region, WorldGenerator generator) {
Filterable<Terrain> filterable = region.filterable();
generator.getFilters().setRegion(region.getRegionX(), region.getRegionZ());
generator.getFilters().getErosion().apply(filterable, generator.getFilters().getSettings().erosion.iterations);
generator.getFilters().getSmoothing().apply(filterable, generator.getFilters().getSettings().smoothing.iterations);
generator.getFilters().getSteepness().apply(filterable);
generator.getFilters().apply(region);
region.decorate(generator.getDecorators().getDecorators());
}
@ -91,15 +85,9 @@ public class RegionGenerator implements RegionExtent {
}
private void postProcess(Region region, WorldGenerator generator, float centerX, float centerZ, float zoom, boolean filter) {
Filterable<Terrain> filterable = region.filterable();
if (filter) {
generator.getFilters().setRegion(region.getRegionX(), region.getRegionZ());
generator.getFilters().getErosion().apply(filterable, generator.getFilters().getSettings().erosion.iterations);
generator.getFilters().getSmoothing().apply(filterable, generator.getFilters().getSettings().smoothing.iterations);
generator.getFilters().apply(region);
}
generator.getFilters().getSteepness().apply(filterable);
// region.decorateZoom(generator.getDecorators().getDecorators(), centerX, centerZ, zoom);
}

View File

@ -1,10 +1,12 @@
package com.terraforged.core.world;
import me.dags.noise.util.NoiseUtil;
import com.terraforged.core.filter.Erosion;
import com.terraforged.core.filter.Filterable;
import com.terraforged.core.filter.Smoothing;
import com.terraforged.core.filter.Steepness;
import com.terraforged.core.region.Region;
import com.terraforged.core.settings.FilterSettings;
import com.terraforged.core.world.terrain.Terrain;
public class WorldFilters {
@ -21,26 +23,10 @@ public class WorldFilters {
this.steepness = new Steepness(1, 10F, context.terrain);
}
public void setRegion(int regionX, int regionZ) {
long seed = NoiseUtil.seed(regionX, regionZ);
getErosion().setSeed(seed);
getSmoothing().setSeed(seed);
getSteepness().setSeed(seed);
}
public FilterSettings getSettings() {
return settings;
}
public Erosion getErosion() {
return erosion;
}
public Smoothing getSmoothing() {
return smoothing;
}
public Steepness getSteepness() {
return steepness;
public void apply(Region region) {
Filterable<Terrain> map = region.filterable();
erosion.apply(map, region.getRegionX(), region.getRegionZ(), settings.erosion.iterations);
smoothing.apply(map, region.getRegionX(), region.getRegionZ(), settings.smoothing.iterations);
steepness.apply(map, region.getRegionX(), region.getRegionZ(), 1);
}
}

View File

@ -34,8 +34,8 @@ public class LandForms {
private final float seaLevel;
public LandForms(Levels levels) {
terrainHorizontalScale = 1F;
terrainVerticalScale = 0.9775F;
terrainHorizontalScale = 1.025F;
terrainVerticalScale = 1F;
groundLevel = levels.ground;
seaLevel = levels.water;
}

@ -1 +1 @@
Subproject commit b7e1b7fc5f20ac8d5e6f1675a187fbd4198075cf
Subproject commit f76fe1fde7ef92ce920113550b42f6254918b538