mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2025-07-04 00:45:57 +00:00
basic framework
This commit is contained in:
parent
1ee2b180d4
commit
883124d8ab
@ -91,6 +91,10 @@ public final class MathUtil {
|
|||||||
return Math.sqrt(((xVal2 - xVal1) * (xVal2 - xVal1)) + ((zVal2 - zVal1) * (zVal2 - zVal1)) + ((yVal2 - yVal1) * (yVal2 - yVal1)));
|
return Math.sqrt(((xVal2 - xVal1) * (xVal2 - xVal1)) + ((zVal2 - zVal1) * (zVal2 - zVal1)) + ((yVal2 - yVal1) * (yVal2 - yVal1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int normalizeIndex(double val, int size) {
|
||||||
|
return FastMath.max(FastMath.min(FastMath.floorToInt(((val + 1D) / 2D) * size), size - 1), 0);
|
||||||
|
}
|
||||||
|
|
||||||
public static long squash(int first, int last) {
|
public static long squash(int first, int last) {
|
||||||
return (((long) first) << 32) | (last & 0xffffffffL);
|
return (((long) first) << 32) | (last & 0xffffffffL);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.dfsek.terra.api.math;
|
package com.dfsek.terra.api.math;
|
||||||
|
|
||||||
import com.dfsek.terra.api.math.noise.samplers.NoiseSampler;
|
import com.dfsek.terra.api.math.noise.samplers.NoiseSampler;
|
||||||
import net.jafama.FastMath;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
@ -29,24 +28,14 @@ public class ProbabilityCollection<E> {
|
|||||||
return (E) array[r.nextInt(array.length)];
|
return (E) array[r.nextInt(array.length)];
|
||||||
}
|
}
|
||||||
|
|
||||||
private static double getNoise(double x, double y, double z, NoiseSampler sampler) {
|
|
||||||
double n = sampler.getNoise(x, y, z);
|
|
||||||
return FastMath.min(FastMath.max(n, -1), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static double getNoise(double x, double z, NoiseSampler sampler) {
|
|
||||||
double n = sampler.getNoise(x, z);
|
|
||||||
return FastMath.min(FastMath.max(n, -1), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public E get(NoiseSampler n, double x, double y, double z) {
|
public E get(NoiseSampler n, double x, double y, double z) {
|
||||||
if(array.length == 0) return null;
|
if(array.length == 0) return null;
|
||||||
return (E) array[FastMath.min(FastMath.floorToInt(((getNoise(x, y, z, n) + 1D) / 2D) * array.length), array.length - 1)];
|
return (E) array[MathUtil.normalizeIndex(n.getNoise(x, y, z), array.length)];
|
||||||
}
|
}
|
||||||
|
|
||||||
public E get(NoiseSampler n, double x, double z) {
|
public E get(NoiseSampler n, double x, double z) {
|
||||||
if(array.length == 0) return null;
|
if(array.length == 0) return null;
|
||||||
return (E) array[FastMath.min(FastMath.floorToInt(((getNoise(x, z, n) + 1D) / 2D) * array.length), array.length - 1)];
|
return (E) array[MathUtil.normalizeIndex(n.getNoise(x, z), array.length)];
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTotalProbability() {
|
public int getTotalProbability() {
|
||||||
|
@ -22,4 +22,6 @@ public interface Biome {
|
|||||||
* @return BiomeTerrain - The terrain generation instance.
|
* @return BiomeTerrain - The terrain generation instance.
|
||||||
*/
|
*/
|
||||||
Generator getGenerator(World w);
|
Generator getGenerator(World w);
|
||||||
|
|
||||||
|
int getColor();
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ public class UserDefinedBiome implements Biome {
|
|||||||
private final BiomeTemplate config;
|
private final BiomeTemplate config;
|
||||||
private final ConfigPack pack;
|
private final ConfigPack pack;
|
||||||
private UserDefinedBiome erode;
|
private UserDefinedBiome erode;
|
||||||
|
private int color;
|
||||||
|
|
||||||
|
|
||||||
public UserDefinedBiome(com.dfsek.terra.api.platform.world.Biome vanilla, GeneratorBuilder gen, BiomeTemplate config, ConfigPack pack) {
|
public UserDefinedBiome(com.dfsek.terra.api.platform.world.Biome vanilla, GeneratorBuilder gen, BiomeTemplate config, ConfigPack pack) {
|
||||||
@ -25,6 +26,7 @@ public class UserDefinedBiome implements Biome {
|
|||||||
this.id = config.getID();
|
this.id = config.getID();
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.pack = pack;
|
this.pack = pack;
|
||||||
|
this.color = config.getColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,4 +60,9 @@ public class UserDefinedBiome implements Biome {
|
|||||||
public Generator getGenerator(World w) {
|
public Generator getGenerator(World w) {
|
||||||
return gen.build(w.getSeed());
|
return gen.build(w.getSeed());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.dfsek.terra.biome.pipeline;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
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 interface BiomeHolder {
|
||||||
|
void expand(BiomeExpander expander);
|
||||||
|
|
||||||
|
void mutate(BiomeMutator mutator);
|
||||||
|
|
||||||
|
void fill(BiomeSource source);
|
||||||
|
|
||||||
|
Biome getBiome(int x, int z);
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.dfsek.terra.biome.pipeline;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.math.vector.Vector2;
|
||||||
|
|
||||||
|
public class Position {
|
||||||
|
private final int x;
|
||||||
|
private final int y;
|
||||||
|
|
||||||
|
public Position(int x, int y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2 getAsVector() {
|
||||||
|
return new Vector2(x, y);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package com.dfsek.terra.biome.pipeline;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
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 Biome[][] biomes;
|
||||||
|
|
||||||
|
public TerraBiomeHolder(int width, Position original) {
|
||||||
|
this.width = width;
|
||||||
|
biomes = new Biome[width][width];
|
||||||
|
this.original = original;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void expand(BiomeExpander expander) {
|
||||||
|
Biome[][] old = biomes;
|
||||||
|
int oldWidth = width;
|
||||||
|
|
||||||
|
width = 2 * width - 1;
|
||||||
|
|
||||||
|
biomes = new Biome[width][width];
|
||||||
|
for(int x = 0; x < oldWidth; x++) {
|
||||||
|
for(int z = 0; z < oldWidth; 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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mutate(BiomeMutator mutator) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Biome getBiome(int x, int z) {
|
||||||
|
return biomes[x][z];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.dfsek.terra.biome.pipeline.expand;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
import com.dfsek.terra.biome.pipeline.Position;
|
||||||
|
|
||||||
|
public interface BiomeExpander {
|
||||||
|
Biome getBetween(Position center, Biome... others);
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
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.Biome;
|
||||||
|
import com.dfsek.terra.biome.pipeline.Position;
|
||||||
|
|
||||||
|
public class FractalExpander implements BiomeExpander {
|
||||||
|
private final NoiseSampler sampler;
|
||||||
|
|
||||||
|
public FractalExpander(NoiseSampler sampler) {
|
||||||
|
this.sampler = sampler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Biome getBetween(Position center, Biome... others) {
|
||||||
|
return others[MathUtil.normalizeIndex(sampler.getNoise(center.getAsVector()), others.length)];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
package com.dfsek.terra.biome.pipeline.mutator;
|
||||||
|
|
||||||
|
public interface BiomeMutator {
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.dfsek.terra.biome.pipeline.source;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
|
||||||
|
public interface BiomeSource {
|
||||||
|
Biome getBiome(int x, int z);
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package com.dfsek.terra.biome.pipeline.source;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.math.ProbabilityCollection;
|
||||||
|
import com.dfsek.terra.api.math.noise.samplers.NoiseSampler;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
|
||||||
|
public class RandomSource implements BiomeSource {
|
||||||
|
private final ProbabilityCollection<Biome> biomes;
|
||||||
|
private final NoiseSampler sampler;
|
||||||
|
|
||||||
|
public RandomSource(ProbabilityCollection<Biome> biomes, NoiseSampler sampler) {
|
||||||
|
this.biomes = biomes;
|
||||||
|
this.sampler = sampler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Biome getBiome(int x, int z) {
|
||||||
|
return biomes.get(sampler, x, z);
|
||||||
|
}
|
||||||
|
}
|
@ -133,6 +133,14 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf
|
|||||||
@Default
|
@Default
|
||||||
private boolean interpolateElevation = true;
|
private boolean interpolateElevation = true;
|
||||||
|
|
||||||
|
@Value("color")
|
||||||
|
@Default
|
||||||
|
private int color = 0;
|
||||||
|
|
||||||
|
public int getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean interpolateElevation() {
|
public boolean interpolateElevation() {
|
||||||
return interpolateElevation;
|
return interpolateElevation;
|
||||||
}
|
}
|
||||||
|
105
common/src/test/java/biome/BiomeTest.java
Normal file
105
common/src/test/java/biome/BiomeTest.java
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
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.platform.world.World;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
import com.dfsek.terra.api.world.biome.Generator;
|
||||||
|
import com.dfsek.terra.biome.pipeline.Position;
|
||||||
|
import com.dfsek.terra.biome.pipeline.TerraBiomeHolder;
|
||||||
|
import com.dfsek.terra.biome.pipeline.expand.FractalExpander;
|
||||||
|
import com.dfsek.terra.biome.pipeline.source.BiomeSource;
|
||||||
|
import com.dfsek.terra.biome.pipeline.source.RandomSource;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
|
public class BiomeTest {
|
||||||
|
@Test
|
||||||
|
public static void main(String... args) {
|
||||||
|
ProbabilityCollection<Biome> testBiomes = new ProbabilityCollection<>();
|
||||||
|
testBiomes.add(new TestBiome(Color.BLUE), 1);
|
||||||
|
testBiomes.add(new TestBiome(Color.GREEN), 1);
|
||||||
|
testBiomes.add(new TestBiome(Color.CYAN), 1);
|
||||||
|
testBiomes.add(new TestBiome(Color.MAGENTA), 1);
|
||||||
|
testBiomes.add(new TestBiome(Color.ORANGE), 1);
|
||||||
|
|
||||||
|
FastNoiseLite sourceSampler = new FastNoiseLite(123);
|
||||||
|
sourceSampler.setNoiseType(FastNoiseLite.NoiseType.WhiteNoise);
|
||||||
|
|
||||||
|
BiomeSource source = new RandomSource(testBiomes, sourceSampler);
|
||||||
|
|
||||||
|
int size = 20;
|
||||||
|
int expand = 6;
|
||||||
|
|
||||||
|
TerraBiomeHolder holder = new TerraBiomeHolder(size, new Position(0, 0));
|
||||||
|
|
||||||
|
holder.fill(source);
|
||||||
|
holder.expand(new FractalExpander(whiteNoise(4)));
|
||||||
|
holder.expand(new FractalExpander(whiteNoise(3)));
|
||||||
|
holder.expand(new FractalExpander(whiteNoise(2)));
|
||||||
|
holder.expand(new FractalExpander(whiteNoise(5)));
|
||||||
|
holder.expand(new FractalExpander(whiteNoise(7)));
|
||||||
|
holder.expand(new FractalExpander(whiteNoise(6)));
|
||||||
|
|
||||||
|
for(int i = 0; i < expand; i++) size = size * 2 - 1;
|
||||||
|
|
||||||
|
BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println(size);
|
||||||
|
|
||||||
|
for(int x = 0; x < size; x++) {
|
||||||
|
for(int z = 0; z < size; z++) {
|
||||||
|
image.setRGB(x, z, holder.getBiome(x, z).getColor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JFrame frame = new JFrame("Biome Viewer");
|
||||||
|
|
||||||
|
|
||||||
|
frame.setResizable(false);
|
||||||
|
frame.add(new JLabel(new ImageIcon(image)));
|
||||||
|
frame.pack();
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println("Done");
|
||||||
|
|
||||||
|
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||||
|
|
||||||
|
frame.setVisible(true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static NoiseSampler whiteNoise(int seed) {
|
||||||
|
FastNoiseLite noiseLite = new FastNoiseLite(seed);
|
||||||
|
noiseLite.setNoiseType(FastNoiseLite.NoiseType.WhiteNoise);
|
||||||
|
return noiseLite;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static class TestBiome implements Biome {
|
||||||
|
private final Color color;
|
||||||
|
|
||||||
|
private TestBiome(Color color) {
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public com.dfsek.terra.api.platform.world.Biome getVanillaBiome() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Generator getGenerator(World w) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getColor() {
|
||||||
|
return color.getRGB();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user