mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2025-07-18 10:32:30 +00:00
Implement Elevation
This commit is contained in:
parent
48e45dfe23
commit
922f971c8e
@ -19,6 +19,6 @@ public final class FailoverGenerator extends UserDefinedGenerator {
|
||||
}
|
||||
|
||||
public FailoverGenerator() throws ParseException {
|
||||
super("0", Collections.emptyList(), palette, false);
|
||||
super("0", null, Collections.emptyList(), palette, false);
|
||||
}
|
||||
}
|
||||
|
@ -168,9 +168,12 @@ public class BiomeConfig extends TerraConfig {
|
||||
}
|
||||
}
|
||||
|
||||
String elevation = getString("elevation-equation", null);
|
||||
|
||||
try {
|
||||
// Get UserDefinedBiome instance representing this config.
|
||||
this.biome = new UserDefinedBiome(vanillaBiome, dec, new UserDefinedGenerator(eq, Collections.emptyList(), palette.getPaletteMap(), getBoolean("prevent-smooth", false)), getBoolean("erodible", false), biomeID);
|
||||
UserDefinedGenerator gen = new UserDefinedGenerator(eq, elevation, Collections.emptyList(), palette.getPaletteMap(), getBoolean("prevent-smooth", false));
|
||||
this.biome = new UserDefinedBiome(vanillaBiome, dec, gen, getBoolean("erodible", false), biomeID);
|
||||
} catch(ParseException e) {
|
||||
e.printStackTrace();
|
||||
throw new ConfigException("Unable to parse noise equation!", getID());
|
||||
|
@ -0,0 +1,35 @@
|
||||
package com.dfsek.terra.generation;
|
||||
|
||||
import com.dfsek.terra.math.NoiseFunction2;
|
||||
import org.polydev.gaea.math.FastNoiseLite;
|
||||
import parsii.eval.Expression;
|
||||
import parsii.eval.Parser;
|
||||
import parsii.eval.Scope;
|
||||
import parsii.eval.Variable;
|
||||
import parsii.tokenizer.ParseException;
|
||||
|
||||
public class ElevationEquation {
|
||||
private static final Object noiseLock = new Object();
|
||||
private final Expression delegate;
|
||||
private final Scope s = new Scope();
|
||||
private final NoiseFunction2 n2 = new NoiseFunction2();
|
||||
|
||||
private final Variable xVar = s.getVariable("x");
|
||||
private final Variable zVar = s.getVariable("z");
|
||||
|
||||
public ElevationEquation(String equation) throws ParseException {
|
||||
Parser p = new Parser();
|
||||
p.registerFunction("noise2", n2);
|
||||
delegate = p.parse(equation, s);
|
||||
}
|
||||
|
||||
public double getNoise(double x, double z, FastNoiseLite noiseLite) {
|
||||
synchronized(noiseLock) {
|
||||
xVar.setValue(x);
|
||||
zVar.setValue(z);
|
||||
|
||||
n2.setNoise(noiseLite);
|
||||
return delegate.evaluate();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package com.dfsek.terra.generation;
|
||||
|
||||
import com.dfsek.terra.biome.TerraBiomeGrid;
|
||||
import org.bukkit.World;
|
||||
import org.polydev.gaea.biome.Generator;
|
||||
import org.polydev.gaea.generation.GenerationPhase;
|
||||
import org.polydev.gaea.math.FastNoiseLite;
|
||||
import org.polydev.gaea.math.Interpolator;
|
||||
|
||||
public class ElevationInterpolator {
|
||||
private final UserDefinedGenerator[][] gens = new UserDefinedGenerator[7][7];
|
||||
private final double[][] values = new double[16][16];
|
||||
private final FastNoiseLite noise;
|
||||
private final int xOrigin;
|
||||
private final int zOrigin;
|
||||
|
||||
public ElevationInterpolator(World w, int chunkX, int chunkZ, TerraBiomeGrid grid, FastNoiseLite noise) {
|
||||
this.xOrigin = chunkX << 4;
|
||||
this.zOrigin = chunkZ << 4;
|
||||
this.noise = noise;
|
||||
|
||||
for(int x = -1; x < 6; x++) {
|
||||
for(int z = -1; z < 6; z++) {
|
||||
gens[x + 1][z + 1] = (UserDefinedGenerator) grid.getBiome(xOrigin + x * 4, zOrigin + z * 4, GenerationPhase.BASE).getGenerator();
|
||||
}
|
||||
}
|
||||
|
||||
for(byte x = 0; x < 16; x++) {
|
||||
for(byte z = 0; z < 16; z++) {
|
||||
if(compareGens((x / 4) + 1, (z / 4) + 1)) {
|
||||
Interpolator interpolator = new Interpolator(biomeAvg(x / 4, z / 4),
|
||||
biomeAvg((x / 4) + 1, z / 4),
|
||||
biomeAvg(x / 4, (z / 4) + 1),
|
||||
biomeAvg((x / 4) + 1, (z / 4) + 1),
|
||||
Interpolator.Type.LINEAR);
|
||||
values[x][z] = interpolator.bilerp((double) (x % 4) / 4, (double) (z % 4) / 4);
|
||||
} else values[x][z] = elevate(gens[x / 4][z / 4], xOrigin + x, zOrigin + z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean compareGens(int x, int z) {
|
||||
Generator comp = gens[x][z];
|
||||
if(!comp.equals(gens[x + 1][z])) return true;
|
||||
|
||||
if(!comp.equals(gens[x][z + 1])) return true;
|
||||
|
||||
if(!comp.equals(gens[x - 1][z])) return true;
|
||||
|
||||
if(!comp.equals(gens[x][z - 1])) return true;
|
||||
|
||||
if(!comp.equals(gens[x + 1][z + 1])) return true;
|
||||
|
||||
if(!comp.equals(gens[x - 1][z - 1])) return true;
|
||||
|
||||
if(!comp.equals(gens[x + 1][z - 1])) return true;
|
||||
|
||||
return !comp.equals(gens[x - 1][z + 1]);
|
||||
}
|
||||
|
||||
private double biomeAvg(int x, int z) {
|
||||
return (elevate(gens[x + 2][z + 1], x * 4 + 4 + xOrigin, z * 4 + zOrigin)
|
||||
+ elevate(gens[x][z + 1], x * 4 - 4 + xOrigin, z * 4 + zOrigin)
|
||||
+ elevate(gens[x + 1][z + 2], x * 4 + xOrigin, z * 4 + 4 + zOrigin)
|
||||
+ elevate(gens[x + 1][z], x * 4 + xOrigin, z * 4 - 4 + zOrigin)
|
||||
+ elevate(gens[x + 1][z + 1], x * 4 + xOrigin, z * 4 + zOrigin)) / 5D;
|
||||
}
|
||||
|
||||
private double elevate(UserDefinedGenerator g, int x, int z) {
|
||||
if(g.getElevationEquation() != null) return g.getElevationEquation().getNoise(x, z, noise);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double getElevation(int x, int z) {
|
||||
return values[x][z];
|
||||
}
|
||||
}
|
@ -80,19 +80,19 @@ public class TerraChunkGenerator extends GaeaChunkGenerator {
|
||||
popMan.attachProfiler(p);
|
||||
}
|
||||
|
||||
private static Palette<BlockData> getPalette(int x, int y, int z, BiomeConfig c, ChunkInterpolator interpolator) {
|
||||
private static Palette<BlockData> getPalette(int x, int y, int z, BiomeConfig c, ChunkInterpolator interpolator, int elevate) {
|
||||
Palette<BlockData> slant = c.getSlant();
|
||||
if(slant != null) {
|
||||
double xzOffset = c.getXZSlantOffset();
|
||||
boolean north = interpolator.getNoise(x, y, z + xzOffset) > 0;
|
||||
boolean south = interpolator.getNoise(x, y, z - xzOffset) > 0;
|
||||
boolean east = interpolator.getNoise(x + xzOffset, y, z) > 0;
|
||||
boolean west = interpolator.getNoise(x - xzOffset, y, z) > 0;
|
||||
boolean north = interpolator.getNoise(x, y + elevate, z + xzOffset) > 0;
|
||||
boolean south = interpolator.getNoise(x, y + elevate, z - xzOffset) > 0;
|
||||
boolean east = interpolator.getNoise(x + xzOffset, y + elevate, z) > 0;
|
||||
boolean west = interpolator.getNoise(x - xzOffset, y + elevate, z) > 0;
|
||||
|
||||
double ySlantOffsetTop = c.getYSlantOffsetTop();
|
||||
double ySlantOffsetBottom = c.getYSlantOffsetBottom();
|
||||
boolean top = interpolator.getNoise(x, y + ySlantOffsetTop, z) > 0;
|
||||
boolean bottom = interpolator.getNoise(x, y - ySlantOffsetBottom, z) > 0;
|
||||
boolean top = interpolator.getNoise(x, y + ySlantOffsetTop + elevate, z) > 0;
|
||||
boolean bottom = interpolator.getNoise(x, y - ySlantOffsetBottom + elevate, z) > 0;
|
||||
|
||||
if((top && bottom) && (north || south || east || west) && (!(north && south && east && west))) return slant;
|
||||
}
|
||||
@ -141,19 +141,27 @@ public class TerraChunkGenerator extends GaeaChunkGenerator {
|
||||
int xOrig = (chunkX << 4);
|
||||
int zOrig = (chunkZ << 4);
|
||||
org.polydev.gaea.biome.BiomeGrid grid = getBiomeGrid(world);
|
||||
|
||||
ElevationInterpolator elevationInterpolator = new ElevationInterpolator(world, chunkX, chunkZ, tw.getGrid(), getNoiseGenerator());
|
||||
|
||||
for(byte x = 0; x < 16; x++) {
|
||||
for(byte z = 0; z < 16; z++) {
|
||||
int paletteLevel = 0;
|
||||
|
||||
int cx = xOrig + x;
|
||||
int cz = zOrig + z;
|
||||
|
||||
Biome b = grid.getBiome(xOrig + x, zOrig + z, GenerationPhase.PALETTE_APPLY);
|
||||
BiomeConfig c = config.getBiome((UserDefinedBiome) b);
|
||||
|
||||
int elevate = (int) elevationInterpolator.getElevation(x, z);
|
||||
|
||||
BiomeSlabConfig slab = c.getSlabs();
|
||||
int sea = c.getOcean().getSeaLevel();
|
||||
Palette<BlockData> seaPalette = c.getOcean().getOcean();
|
||||
for(int y = world.getMaxHeight() - 1; y >= 0; y--) {
|
||||
if(interpolator.getNoise(x, y, z) > 0) {
|
||||
BlockData data = getPalette(x, y, z, c, interpolator).get(paletteLevel, cx, cz);
|
||||
if(interpolator.getNoise(x, y - elevate, z) > 0) {
|
||||
BlockData data = getPalette(x, y, z, c, interpolator, elevate).get(paletteLevel, cx, cz);
|
||||
chunk.setBlock(x, y, z, data);
|
||||
if(paletteLevel == 0 && slab != null && y < 255) {
|
||||
prepareBlockPart(data, chunk.getBlockData(x, y + 1, z), chunk, new Vector(x, y + 1, z), slab.getSlabs(),
|
||||
|
@ -1,10 +1,12 @@
|
||||
package com.dfsek.terra.generation;
|
||||
|
||||
import com.dfsek.terra.Debug;
|
||||
import com.dfsek.terra.math.NoiseFunction2;
|
||||
import com.dfsek.terra.math.NoiseFunction3;
|
||||
import com.dfsek.terra.util.DataUtil;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.polydev.gaea.biome.Generator;
|
||||
import org.polydev.gaea.math.FastNoiseLite;
|
||||
import org.polydev.gaea.math.Interpolator;
|
||||
@ -30,10 +32,11 @@ public class UserDefinedGenerator extends Generator {
|
||||
private final Palette<BlockData>[] palettes = new Palette[256];
|
||||
private final NoiseFunction2 n2 = new NoiseFunction2();
|
||||
private final NoiseFunction3 n3 = new NoiseFunction3();
|
||||
private final ElevationEquation elevationEquation;
|
||||
private final boolean preventSmooth;
|
||||
|
||||
|
||||
public UserDefinedGenerator(String equation, List<Variable> userVariables, Map<Integer, Palette<BlockData>> paletteMap, boolean preventSmooth)
|
||||
public UserDefinedGenerator(String equation, @Nullable String elevateEquation, List<Variable> userVariables, Map<Integer, Palette<BlockData>> paletteMap, boolean preventSmooth)
|
||||
throws ParseException {
|
||||
Parser p = new Parser();
|
||||
p.registerFunction("noise2", n2);
|
||||
@ -48,6 +51,10 @@ public class UserDefinedGenerator extends Generator {
|
||||
}
|
||||
palettes[y] = d;
|
||||
}
|
||||
if(elevateEquation != null) {
|
||||
Debug.info("Using elevation equation");
|
||||
this.elevationEquation = new ElevationEquation(elevateEquation);
|
||||
} else this.elevationEquation = null;
|
||||
this.noiseExp = p.parse(equation, s);
|
||||
this.preventSmooth = preventSmooth;
|
||||
}
|
||||
@ -112,4 +119,8 @@ public class UserDefinedGenerator extends Generator {
|
||||
public Interpolator.Type getInterpolationType() {
|
||||
return Interpolator.Type.LINEAR;
|
||||
}
|
||||
|
||||
public ElevationEquation getElevationEquation() {
|
||||
return elevationEquation;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
noise-equation: "((-((y / 64)^2)) + 1) + min(floor(((|noise2(x/2.5, z/2.5)|) + 0.1)*4), 3)/2.5 + |noise2(x/2.5, z/2.5)|"
|
||||
noise-equation: "((-((y / 64)^2)) + 1) + |noise2(x/2.5, z/2.5)|"
|
||||
elevation-equation: "min(floor(((|noise2(x/2.5, z/2.5)|) + 0.1)*4)*5, 15)"
|
||||
|
||||
id: "ARID_MOUNTAINS"
|
||||
extends: "BASIC_ORES"
|
||||
|
17
src/test/java/NoiseInstancePerformanceTest.java
Normal file
17
src/test/java/NoiseInstancePerformanceTest.java
Normal file
@ -0,0 +1,17 @@
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.polydev.gaea.math.FastNoiseLite;
|
||||
|
||||
public class NoiseInstancePerformanceTest {
|
||||
@Test
|
||||
public void performance() {
|
||||
FastNoiseLite noiseLite = new FastNoiseLite(2403);
|
||||
long l = System.nanoTime();
|
||||
for(int i = 0; i < 10000000; i++) noiseLite.getNoise(i, i);
|
||||
System.out.println("No instantiation: " + (System.nanoTime() - l) / 1000000 + "ms");
|
||||
for(int i = 0; i < 10000000; i++) {
|
||||
FastNoiseLite noiseLite1 = new FastNoiseLite(2403);
|
||||
noiseLite1.getNoise(i, i);
|
||||
}
|
||||
System.out.println("Instantiation: " + (System.nanoTime() - l) / 1000000 + "ms");
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user