fix border issues

This commit is contained in:
dfsek
2021-01-12 21:10:46 -07:00
parent f28759d07a
commit fc46c8bd4d
12 changed files with 98 additions and 64 deletions

View File

@@ -6,7 +6,7 @@ import com.dfsek.terra.biome.pipeline.mutator.BiomeMutator;
import com.dfsek.terra.biome.pipeline.source.BiomeSource;
public interface BiomeHolder {
void expand(BiomeExpander expander);
BiomeHolder expand(BiomeExpander expander);
void mutate(BiomeMutator mutator);

View File

@@ -22,4 +22,12 @@ public class Position {
public Vector2 getAsVector() {
return new Vector2(x, y);
}
public Position newFromAdd(Position other) {
return new Position(x + other.getX(), y + other.getY());
}
public Position newMultiply(int m) {
return new Position(x * m, y * m);
}
}

View File

@@ -1,39 +1,49 @@
package com.dfsek.terra.biome.pipeline;
import com.dfsek.terra.api.math.vector.Vector2;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.biome.pipeline.expand.BiomeExpander;
import com.dfsek.terra.biome.pipeline.mutator.BiomeMutator;
import com.dfsek.terra.biome.pipeline.source.BiomeSource;
public class TerraBiomeHolder implements BiomeHolder {
private final Position original;
private int width;
private final Vector2 origin;
private final int width;
private TerraBiome[][] biomes;
public TerraBiomeHolder(int width, Position original) {
public TerraBiomeHolder(int width, Vector2 origin) {
this.width = width;
biomes = new TerraBiome[width][width];
this.original = original;
this.origin = origin;
}
private TerraBiomeHolder(TerraBiome[][] biomes, Vector2 origin, int width) {
this.biomes = biomes;
this.origin = origin;
this.width = width;
}
@Override
public void expand(BiomeExpander expander) {
public BiomeHolder expand(BiomeExpander expander) {
TerraBiome[][] old = biomes;
int oldWidth = width;
int newWidth = width * 2 - 1;
width = 2 * width - 1;
biomes = new TerraBiome[newWidth][newWidth];
biomes = new TerraBiome[width][width];
for(int x = 0; x < oldWidth; x++) {
for(int z = 0; z < oldWidth; z++) {
System.out.println(biomes.length);
for(int x = 0; x < width; x++) {
for(int z = 0; z < width; z++) {
biomes[x * 2][z * 2] = old[x][z];
if(z != oldWidth - 1) biomes[x * 2][z * 2 + 1] = expander.getBetween(new Position(x, z + 1), old[x][z], old[x][z + 1]);
if(x != oldWidth - 1) biomes[x * 2 + 1][z * 2] = expander.getBetween(new Position(x + 1, z), old[x][z], old[x + 1][z]);
if(x != oldWidth - 1 && z != oldWidth - 1)
biomes[x * 2 + 1][z * 2 + 1] = expander.getBetween(new Position(x + 1, z + 1), old[x][z], old[x + 1][z + 1], old[x][z + 1], old[x + 1][z]);
if(z != width - 1)
biomes[x * 2][z * 2 + 1] = expander.getBetween(x + origin.getX(), z + 1 + origin.getZ(), old[x][z], old[x][z + 1]);
if(x != width - 1)
biomes[x * 2 + 1][z * 2] = expander.getBetween(x + 1 + origin.getX(), z + origin.getZ(), old[x][z], old[x + 1][z]);
if(x != width - 1 && z != width - 1)
biomes[x * 2 + 1][z * 2 + 1] = expander.getBetween(x + 1 + origin.getX(), z + 1 + origin.getZ(), old[x][z], old[x + 1][z + 1], old[x][z + 1], old[x + 1][z]);
}
}
return new TerraBiomeHolder(biomes, origin.setX(origin.getX() * 2 - 1).setZ(origin.getZ() * 2 - 1), newWidth);
}
@Override
@@ -41,11 +51,11 @@ public class TerraBiomeHolder implements BiomeHolder {
for(int x = 0; x < width; x++) {
for(int z = 0; z < width; z++) {
BiomeMutator.ViewPoint viewPoint = new BiomeMutator.ViewPoint(new TerraBiome[][] {
{getBiome(x - 1, z + 1), getBiome(x, z + 1), getBiome(x + 1, z + 1)},
{getBiome(x - 1, z), getBiome(x, z), getBiome(x + 1, z)},
{getBiome(x - 1, z - 1), getBiome(x, z - 1), getBiome(x + 1, z - 1)}
{getBiomeRaw(x - 1, z + 1), getBiomeRaw(x, z + 1), getBiomeRaw(x + 1, z + 1)},
{getBiomeRaw(x - 1, z), getBiomeRaw(x, z), getBiomeRaw(x + 1, z)},
{getBiomeRaw(x - 1, z - 1), getBiomeRaw(x, z - 1), getBiomeRaw(x + 1, z - 1)}
});
biomes[x][z] = mutator.mutate(viewPoint, new Position(x, z));
biomes[x][z] = mutator.mutate(viewPoint, x + origin.getX(), z + origin.getZ());
}
}
}
@@ -54,11 +64,16 @@ public class TerraBiomeHolder implements BiomeHolder {
public void fill(BiomeSource source) {
for(int x = 0; x < width; x++) {
for(int z = 0; z < width; z++) {
biomes[x][z] = source.getBiome(original.getX() + x, original.getY() + z);
biomes[x][z] = source.getBiome(origin.getX() + x, origin.getZ() + z);
}
}
}
private TerraBiome getBiomeRaw(int x, int z) {
if(x >= width || z >= width || x < 0 || z < 0) return null;
return biomes[x][z];
}
@Override
public TerraBiome getBiome(int x, int z) {
if(x >= width || z >= width || x < 0 || z < 0) return null;

View File

@@ -1,8 +1,7 @@
package com.dfsek.terra.biome.pipeline.expand;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.biome.pipeline.Position;
public interface BiomeExpander {
TerraBiome getBetween(Position center, TerraBiome... others);
TerraBiome getBetween(double x, double z, TerraBiome... others);
}

View File

@@ -3,7 +3,6 @@ package com.dfsek.terra.biome.pipeline.expand;
import com.dfsek.terra.api.math.MathUtil;
import com.dfsek.terra.api.math.noise.samplers.NoiseSampler;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.biome.pipeline.Position;
public class FractalExpander implements BiomeExpander {
private final NoiseSampler sampler;
@@ -13,7 +12,7 @@ public class FractalExpander implements BiomeExpander {
}
@Override
public TerraBiome getBetween(Position center, TerraBiome... others) {
return others[MathUtil.normalizeIndex(sampler.getNoise(center.getAsVector()), others.length)];
public TerraBiome getBetween(double x, double z, TerraBiome... others) {
return others[MathUtil.normalizeIndex(sampler.getNoise(x, z), others.length)];
}
}

View File

@@ -1,10 +1,9 @@
package com.dfsek.terra.biome.pipeline.mutator;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.biome.pipeline.Position;
public interface BiomeMutator {
TerraBiome mutate(ViewPoint viewPoint, Position position);
TerraBiome mutate(ViewPoint viewPoint, double x, double z);
class ViewPoint {
private final TerraBiome[][] biomes;

View File

@@ -3,7 +3,6 @@ package com.dfsek.terra.biome.pipeline.mutator;
import com.dfsek.terra.api.math.ProbabilityCollection;
import com.dfsek.terra.api.math.noise.samplers.NoiseSampler;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.biome.pipeline.Position;
import java.util.Set;
@@ -21,16 +20,16 @@ public class BorderMutator implements BiomeMutator {
}
@Override
public TerraBiome mutate(ViewPoint viewPoint, Position position) {
public TerraBiome mutate(ViewPoint viewPoint, double x, double z) {
TerraBiome origin = viewPoint.getBiome(0, 0);
if(origin.getTags().contains(tag)) {
for(int x = -1; x <= 1; x++) {
for(int z = -1; z <= 1; z++) {
if(x == 0 && z == 0) continue;
TerraBiome current = viewPoint.getBiome(x, z);
for(int xi = -1; xi <= 1; xi++) {
for(int zi = -1; zi <= 1; zi++) {
if(xi == 0 && zi == 0) continue;
TerraBiome current = viewPoint.getBiome(xi, zi);
if(current == null) continue;
if(borders.stream().anyMatch(current.getTags()::contains))
return replace.get(noiseSampler, position.getX(), position.getY());
return replace.get(noiseSampler, x, z);
}
}
}

View File

@@ -3,7 +3,6 @@ package com.dfsek.terra.biome.pipeline.mutator;
import com.dfsek.terra.api.math.ProbabilityCollection;
import com.dfsek.terra.api.math.noise.samplers.NoiseSampler;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.biome.pipeline.Position;
public class ReplaceMutator implements BiomeMutator {
private final String replaceableTag;
@@ -17,7 +16,7 @@ public class ReplaceMutator implements BiomeMutator {
}
@Override
public TerraBiome mutate(ViewPoint viewPoint, Position position) {
return viewPoint.getBiome(0, 0).getTags().contains(replaceableTag) ? replace.get(sampler, position.getX(), position.getY()) : viewPoint.getBiome(0, 0);
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);
}
}

View File

@@ -3,7 +3,6 @@ package com.dfsek.terra.biome.pipeline.mutator;
import com.dfsek.terra.api.math.MathUtil;
import com.dfsek.terra.api.math.noise.samplers.NoiseSampler;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.biome.pipeline.Position;
import java.util.Objects;
@@ -16,7 +15,7 @@ public class SmoothMutator implements BiomeMutator {
}
@Override
public TerraBiome mutate(ViewPoint viewPoint, Position position) {
public TerraBiome mutate(ViewPoint viewPoint, double x, double z) {
TerraBiome top = viewPoint.getBiome(1, 0);
TerraBiome bottom = viewPoint.getBiome(-1, 0);
TerraBiome left = viewPoint.getBiome(0, 1);
@@ -27,7 +26,7 @@ public class SmoothMutator implements BiomeMutator {
boolean horiz = Objects.equals(left, right) && left != null;
if(vert && horiz) {
return MathUtil.normalizeIndex(sampler.getNoise(position.getX(), position.getY()), 2) == 0 ? left : top;
return MathUtil.normalizeIndex(sampler.getNoise(x, z), 2) == 0 ? left : top;
}
if(vert) return top;

View File

@@ -3,5 +3,5 @@ package com.dfsek.terra.biome.pipeline.source;
import com.dfsek.terra.api.world.biome.TerraBiome;
public interface BiomeSource {
TerraBiome getBiome(int x, int z);
TerraBiome getBiome(double x, double z);
}

View File

@@ -14,7 +14,7 @@ public class RandomSource implements BiomeSource {
}
@Override
public TerraBiome getBiome(int x, int z) {
public TerraBiome getBiome(double x, double z) {
return biomes.get(sampler, x, z);
}
}

View File

@@ -3,18 +3,15 @@ package biome;
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.math.vector.Vector2;
import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.api.world.biome.Generator;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.biome.pipeline.Position;
import com.dfsek.terra.biome.pipeline.BiomeHolder;
import com.dfsek.terra.biome.pipeline.TerraBiomeHolder;
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.google.common.collect.Sets;
import org.junit.jupiter.api.Test;
import javax.swing.*;
@@ -58,38 +55,52 @@ public class BiomeTest {
BiomeSource source = new RandomSource(climate, sourceSampler);
int size = 20;
int size = 25;
int expand = 6;
TerraBiomeHolder holder = new TerraBiomeHolder(size, new Position(0, 0));
BiomeHolder holder = new TerraBiomeHolder(size, new Vector2(0, 0));
BiomeHolder holder2 = new TerraBiomeHolder(size, new Vector2(24, 0));
BiomeHolder holder3 = new TerraBiomeHolder(size, new Vector2(0, 24));
BiomeHolder holder4 = new TerraBiomeHolder(size, new Vector2(24, 24));
long s = System.nanoTime();
holder.fill(source);
holder.expand(new FractalExpander(whiteNoise(4)));
holder2.fill(source);
holder3.fill(source);
holder4.fill(source);
holder.mutate(new ReplaceMutator("OCEAN_TEMP", oceanBiomes, whiteNoise(234)));
holder.mutate(new ReplaceMutator("LAND_TEMP", landBiomes, whiteNoise(235)));
for(int i = 0; i < 5; i++) {
holder = holder.expand(new FractalExpander(whiteNoise(i)));
holder2 = holder2.expand(new FractalExpander(whiteNoise(i)));
holder3 = holder3.expand(new FractalExpander(whiteNoise(i)));
holder4 = holder4.expand(new FractalExpander(whiteNoise(i)));
size = size * 2 - 1;
}
int og = size;
size *= 2;
//holder = holder.expand(new FractalExpander(whiteNoise(4)));
holder.expand(new FractalExpander(whiteNoise(3)));
holder.expand(new FractalExpander(whiteNoise(2)));
//holder.mutate(new ReplaceMutator("OCEAN_TEMP", oceanBiomes, whiteNoise(234)));
//holder.mutate(new ReplaceMutator("LAND_TEMP", landBiomes, whiteNoise(235)));
holder.mutate(new SmoothMutator(whiteNoise(34)));
//holder = holder.expand(new FractalExpander(whiteNoise(3)));
//holder = holder.expand(new FractalExpander(whiteNoise(2)));
holder.expand(new FractalExpander(whiteNoise(5)));
holder.expand(new FractalExpander(whiteNoise(7)));
//holder.mutate(new SmoothMutator(whiteNoise(34)));
holder.mutate(new BorderMutator(Sets.newHashSet("OCEAN"), "LAND", whiteNoise(2356), beachBiomes));
//holder = holder.expand(new FractalExpander(whiteNoise(5)));
//holder = holder.expand(new FractalExpander(whiteNoise(7)));
holder.expand(new FractalExpander(whiteNoise(6)));
//holder.mutate(new BorderMutator(Sets.newHashSet("OCEAN"), "LAND", whiteNoise(2356), beachBiomes));
holder.mutate(new SmoothMutator(whiteNoise(35)));
//holder = holder.expand(new FractalExpander(whiteNoise(6)));
//holder.mutate(new SmoothMutator(whiteNoise(35)));
long e = System.nanoTime();
double time = e - s;
time /= 1000000;
for(int i = 0; i < expand; i++) size = size * 2 - 1;
System.out.println(time + "ms for " + size + "x" + size);
@@ -100,7 +111,13 @@ public class BiomeTest {
for(int x = 0; x < size; x++) {
for(int z = 0; z < size; z++) {
image.setRGB(x, z, holder.getBiome(x, z).getColor());
if(x < og) {
if(z < og) image.setRGB(x, z, holder.getBiome(x, z).getColor());
else image.setRGB(x, z, holder3.getBiome(x, z - og).getColor());
} else {
if(z < og) image.setRGB(x, z, holder2.getBiome(x - og, z).getColor());
else image.setRGB(x, z, holder4.getBiome(x - og, z - og).getColor());
}
}
}