mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2025-07-18 10:32:30 +00:00
User defined noise functions
This commit is contained in:
parent
9125590a02
commit
022c95a862
@ -19,6 +19,6 @@ public final class FailoverGenerator extends UserDefinedGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public FailoverGenerator() throws ParseException {
|
public FailoverGenerator() throws ParseException {
|
||||||
super("0", null, new HashMap<>(), palette, new TreeMap<>(), false);
|
super("0", null, new HashMap<>(), palette, new TreeMap<>(), new HashMap<>(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ import com.dfsek.terra.config.genconfig.PaletteConfig;
|
|||||||
import com.dfsek.terra.config.genconfig.TreeConfig;
|
import com.dfsek.terra.config.genconfig.TreeConfig;
|
||||||
import com.dfsek.terra.config.genconfig.biome.AbstractBiomeConfig;
|
import com.dfsek.terra.config.genconfig.biome.AbstractBiomeConfig;
|
||||||
import com.dfsek.terra.config.genconfig.biome.BiomeConfig;
|
import com.dfsek.terra.config.genconfig.biome.BiomeConfig;
|
||||||
|
import com.dfsek.terra.config.genconfig.noise.NoiseConfig;
|
||||||
import com.dfsek.terra.config.genconfig.structure.StructureConfig;
|
import com.dfsek.terra.config.genconfig.structure.StructureConfig;
|
||||||
import com.dfsek.terra.config.lang.LangUtil;
|
import com.dfsek.terra.config.lang.LangUtil;
|
||||||
import com.dfsek.terra.registry.FloraRegistry;
|
import com.dfsek.terra.registry.FloraRegistry;
|
||||||
@ -56,8 +57,6 @@ public class ConfigPack extends YamlConfiguration {
|
|||||||
public final int blendAmp;
|
public final int blendAmp;
|
||||||
public final boolean biomeBlend;
|
public final boolean biomeBlend;
|
||||||
public final double blendFreq;
|
public final double blendFreq;
|
||||||
public final int octaves;
|
|
||||||
public final double frequency;
|
|
||||||
public final boolean vanillaCaves;
|
public final boolean vanillaCaves;
|
||||||
public final boolean vanillaStructures;
|
public final boolean vanillaStructures;
|
||||||
public final boolean vanillaDecoration;
|
public final boolean vanillaDecoration;
|
||||||
@ -76,9 +75,11 @@ public class ConfigPack extends YamlConfiguration {
|
|||||||
private final FloraRegistry floraRegistry = new FloraRegistry();
|
private final FloraRegistry floraRegistry = new FloraRegistry();
|
||||||
private final Set<StructureConfig> allStructures = new HashSet<>();
|
private final Set<StructureConfig> allStructures = new HashSet<>();
|
||||||
private final Map<String, Double> definedVariables = new HashMap<>();
|
private final Map<String, Double> definedVariables = new HashMap<>();
|
||||||
|
private final Map<String, NoiseConfig> noiseBuilders = new HashMap<>();
|
||||||
private final File dataFolder;
|
private final File dataFolder;
|
||||||
private final String id;
|
private final String id;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public ConfigPack(File file) throws IOException, InvalidConfigurationException {
|
public ConfigPack(File file) throws IOException, InvalidConfigurationException {
|
||||||
long l = System.nanoTime();
|
long l = System.nanoTime();
|
||||||
load(new File(file, "pack.yml"));
|
load(new File(file, "pack.yml"));
|
||||||
@ -87,6 +88,12 @@ public class ConfigPack extends YamlConfiguration {
|
|||||||
if(!contains("id")) throw new ConfigException("No ID specified!", "null");
|
if(!contains("id")) throw new ConfigException("No ID specified!", "null");
|
||||||
this.id = getString("id");
|
this.id = getString("id");
|
||||||
|
|
||||||
|
Map<String, Object> noise = Objects.requireNonNull(getConfigurationSection("noise")).getValues(false);
|
||||||
|
for(Map.Entry<String, Object> entry : noise.entrySet()) {
|
||||||
|
noiseBuilders.put(entry.getKey(), new NoiseConfig((ConfigurationSection) entry.getValue()));
|
||||||
|
Debug.info("Loaded noise function " + entry.getKey());
|
||||||
|
}
|
||||||
|
|
||||||
ores = ConfigLoader.load(new File(file, "ores").toPath(), this, OreConfig.class);
|
ores = ConfigLoader.load(new File(file, "ores").toPath(), this, OreConfig.class);
|
||||||
|
|
||||||
palettes = ConfigLoader.load(new File(file, "palettes").toPath(), this, PaletteConfig.class);
|
palettes = ConfigLoader.load(new File(file, "palettes").toPath(), this, PaletteConfig.class);
|
||||||
@ -141,9 +148,6 @@ public class ConfigPack extends YamlConfiguration {
|
|||||||
erosionThresh = getDouble("erode.threshold", 0.04);
|
erosionThresh = getDouble("erode.threshold", 0.04);
|
||||||
erosionOctaves = getInt("erode.octaves", 3);
|
erosionOctaves = getInt("erode.octaves", 3);
|
||||||
|
|
||||||
octaves = getInt("noise.octaves", 4);
|
|
||||||
frequency = getDouble("noise.frequency", 1f / 96);
|
|
||||||
|
|
||||||
erosionName = getString("erode.grid");
|
erosionName = getString("erode.grid");
|
||||||
|
|
||||||
vanillaCaves = getBoolean("vanilla.caves", false);
|
vanillaCaves = getBoolean("vanilla.caves", false);
|
||||||
@ -210,6 +214,10 @@ public class ConfigPack extends YamlConfiguration {
|
|||||||
return grids.get(id);
|
return grids.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, NoiseConfig> getNoiseBuilders() {
|
||||||
|
return noiseBuilders;
|
||||||
|
}
|
||||||
|
|
||||||
public static synchronized void loadAll(JavaPlugin main) {
|
public static synchronized void loadAll(JavaPlugin main) {
|
||||||
configs.clear();
|
configs.clear();
|
||||||
File file = new File(main.getDataFolder(), "packs");
|
File file = new File(main.getDataFolder(), "packs");
|
||||||
|
@ -171,7 +171,7 @@ public class BiomeConfig extends TerraConfig {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// Get UserDefinedBiome instance representing this config.
|
// Get UserDefinedBiome instance representing this config.
|
||||||
UserDefinedGenerator gen = new UserDefinedGenerator(eq, elevation, config.getDefinedVariables(), palette.getPaletteMap(), slant, getBoolean("prevent-smooth", false));
|
UserDefinedGenerator gen = new UserDefinedGenerator(eq, elevation, config.getDefinedVariables(), palette.getPaletteMap(), slant, config.getNoiseBuilders(), getBoolean("prevent-smooth", false));
|
||||||
gen.setElevationInterpolation(doElevationInterpolation);
|
gen.setElevationInterpolation(doElevationInterpolation);
|
||||||
this.biome = new UserDefinedBiome(vanillaBiome, dec, gen, getBoolean("erodible", false), biomeID);
|
this.biome = new UserDefinedBiome(vanillaBiome, dec, gen, getBoolean("erodible", false), biomeID);
|
||||||
} catch(ParseException e) {
|
} catch(ParseException e) {
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
package com.dfsek.terra.config.genconfig.noise;
|
||||||
|
|
||||||
|
import com.dfsek.terra.config.exception.ConfigException;
|
||||||
|
import com.dfsek.terra.generation.config.NoiseBuilder;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.polydev.gaea.math.FastNoiseLite;
|
||||||
|
|
||||||
|
public class NoiseConfig {
|
||||||
|
private final NoiseBuilder builder;
|
||||||
|
private final int dimensions;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public NoiseConfig(ConfigurationSection section) throws ConfigException {
|
||||||
|
NoiseBuilder builder = new NoiseBuilder();
|
||||||
|
try {
|
||||||
|
builder.setType(FastNoiseLite.NoiseType.valueOf((String) section.get("type")));
|
||||||
|
builder.setFrequency(section.getDouble("frequency", 0.02D));
|
||||||
|
|
||||||
|
dimensions = section.getInt("dimensions", 3);
|
||||||
|
if(dimensions != 2 && dimensions != 3)
|
||||||
|
throw new ConfigException("Invalid number of dimensions: " + dimensions, "Noise");
|
||||||
|
|
||||||
|
builder.setRotationType3D(FastNoiseLite.RotationType3D.valueOf(section.getString("rotation", "None")));
|
||||||
|
|
||||||
|
if(section.contains("fractal")) {
|
||||||
|
builder.setFractalType(FastNoiseLite.FractalType.valueOf(section.getString("fractal.type", "FBm")));
|
||||||
|
builder.setOctaves(section.getInt("fractal.octaves", 1));
|
||||||
|
builder.setFractalGain(section.getDouble("fractal.gain", 0.5D));
|
||||||
|
builder.setFractalLacunarity(section.getDouble("fractal.lacunarity", 2.0D));
|
||||||
|
builder.setPingPong(section.getDouble("fractal.ping-pong", 2.0D));
|
||||||
|
builder.setWeightedStrength(section.getDouble("fractal.weighted-strength", 0.0D));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(section.contains("cellular")) {
|
||||||
|
builder.setCellularDistanceFunction(FastNoiseLite.CellularDistanceFunction.valueOf(section.getString("cellular.distance", "EuclideanSq")));
|
||||||
|
builder.setCellularReturnType(FastNoiseLite.CellularReturnType.valueOf(section.getString("cellular.return", "Distance")));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(section.contains("warp")) {
|
||||||
|
builder.setDomainWarpType(FastNoiseLite.DomainWarpType.valueOf(section.getString("warp.type", "OpenSimplex2")));
|
||||||
|
builder.setDomainWarpAmp(section.getDouble("warp.amplitude", 1.0D));
|
||||||
|
}
|
||||||
|
this.builder = builder;
|
||||||
|
} catch(IllegalArgumentException | ClassCastException e) {
|
||||||
|
throw new ConfigException(e.getMessage(), "Noise");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public NoiseBuilder getBuilder() {
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDimensions() {
|
||||||
|
return dimensions;
|
||||||
|
}
|
||||||
|
}
|
@ -1,35 +1,65 @@
|
|||||||
package com.dfsek.terra.generation;
|
package com.dfsek.terra.generation;
|
||||||
|
|
||||||
|
import com.dfsek.terra.config.genconfig.noise.NoiseConfig;
|
||||||
|
import com.dfsek.terra.math.NoiseFunction;
|
||||||
import com.dfsek.terra.math.NoiseFunction2;
|
import com.dfsek.terra.math.NoiseFunction2;
|
||||||
import org.polydev.gaea.math.FastNoiseLite;
|
import com.dfsek.terra.math.NoiseFunction3;
|
||||||
|
import org.bukkit.World;
|
||||||
import parsii.eval.Expression;
|
import parsii.eval.Expression;
|
||||||
import parsii.eval.Parser;
|
import parsii.eval.Parser;
|
||||||
import parsii.eval.Scope;
|
import parsii.eval.Scope;
|
||||||
import parsii.eval.Variable;
|
import parsii.eval.Variable;
|
||||||
import parsii.tokenizer.ParseException;
|
import parsii.tokenizer.ParseException;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class ElevationEquation {
|
public class ElevationEquation {
|
||||||
private static final Object noiseLock = new Object();
|
private static final Object noiseLock = new Object();
|
||||||
private final Expression delegate;
|
private final Expression delegate;
|
||||||
private final Scope s = new Scope();
|
private final Scope s = new Scope();
|
||||||
private final NoiseFunction2 n2 = new NoiseFunction2();
|
|
||||||
|
|
||||||
private final Variable xVar = s.getVariable("x");
|
private final Variable xVar = s.getVariable("x");
|
||||||
private final Variable zVar = s.getVariable("z");
|
private final Variable zVar = s.getVariable("z");
|
||||||
|
|
||||||
public ElevationEquation(String equation) throws ParseException {
|
private final List<NoiseFunction> noiseFunctions = new ArrayList<>();
|
||||||
|
private boolean set = true;
|
||||||
|
|
||||||
|
public ElevationEquation(String equation, Map<String, NoiseConfig> noiseBuilders) throws ParseException {
|
||||||
Parser p = new Parser();
|
Parser p = new Parser();
|
||||||
p.registerFunction("noise2", n2);
|
for(Map.Entry<String, NoiseConfig> e : noiseBuilders.entrySet()) {
|
||||||
|
switch(e.getValue().getDimensions()) {
|
||||||
|
case 2:
|
||||||
|
NoiseFunction2 function2 = new NoiseFunction2(e.getValue().getBuilder());
|
||||||
|
noiseFunctions.add(function2);
|
||||||
|
p.registerFunction(e.getKey(), function2);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
NoiseFunction3 function3 = new NoiseFunction3(e.getValue().getBuilder());
|
||||||
|
noiseFunctions.add(function3);
|
||||||
|
p.registerFunction(e.getKey(), function3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
delegate = p.parse(equation, s);
|
delegate = p.parse(equation, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getNoise(double x, double z, FastNoiseLite noiseLite) {
|
public double getNoise(double x, double z, World w) {
|
||||||
synchronized(noiseLock) {
|
synchronized(noiseLock) {
|
||||||
xVar.setValue(x);
|
xVar.setValue(x);
|
||||||
zVar.setValue(z);
|
zVar.setValue(z);
|
||||||
|
setNoise(w.getSeed());
|
||||||
n2.setNoise(noiseLite);
|
|
||||||
return delegate.evaluate();
|
return delegate.evaluate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setNoise(long seed) {
|
||||||
|
if(set) {
|
||||||
|
set = false;
|
||||||
|
for(NoiseFunction n : noiseFunctions) {
|
||||||
|
n.setNoise(seed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,21 +3,18 @@ package com.dfsek.terra.generation;
|
|||||||
import com.dfsek.terra.biome.grid.TerraBiomeGrid;
|
import com.dfsek.terra.biome.grid.TerraBiomeGrid;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.polydev.gaea.generation.GenerationPhase;
|
import org.polydev.gaea.generation.GenerationPhase;
|
||||||
import org.polydev.gaea.math.FastNoiseLite;
|
|
||||||
import org.polydev.gaea.math.Interpolator;
|
import org.polydev.gaea.math.Interpolator;
|
||||||
|
|
||||||
public class ElevationInterpolator {
|
public class ElevationInterpolator {
|
||||||
private final UserDefinedGenerator[][] gens = new UserDefinedGenerator[10][10];
|
private final UserDefinedGenerator[][] gens = new UserDefinedGenerator[10][10];
|
||||||
private final double[][] values = new double[18][18];
|
private final double[][] values = new double[18][18];
|
||||||
private final FastNoiseLite noise;
|
|
||||||
private final int xOrigin;
|
private final int xOrigin;
|
||||||
private final int zOrigin;
|
private final int zOrigin;
|
||||||
private final TerraBiomeGrid grid;
|
private final TerraBiomeGrid grid;
|
||||||
|
|
||||||
public ElevationInterpolator(World w, int chunkX, int chunkZ, TerraBiomeGrid grid, FastNoiseLite noise) {
|
public ElevationInterpolator(World w, int chunkX, int chunkZ, TerraBiomeGrid grid) {
|
||||||
this.xOrigin = chunkX << 4;
|
this.xOrigin = chunkX << 4;
|
||||||
this.zOrigin = chunkZ << 4;
|
this.zOrigin = chunkZ << 4;
|
||||||
this.noise = noise;
|
|
||||||
this.grid = grid;
|
this.grid = grid;
|
||||||
|
|
||||||
for(int x = -2; x < 8; x++) {
|
for(int x = -2; x < 8; x++) {
|
||||||
@ -30,13 +27,13 @@ public class ElevationInterpolator {
|
|||||||
for(byte z = -1; z <= 16; z++) {
|
for(byte z = -1; z <= 16; z++) {
|
||||||
UserDefinedGenerator generator = getGenerator(x, z);
|
UserDefinedGenerator generator = getGenerator(x, z);
|
||||||
if(compareGens((x / 4), (z / 4)) && generator.interpolateElevation()) {
|
if(compareGens((x / 4), (z / 4)) && generator.interpolateElevation()) {
|
||||||
Interpolator interpolator = new Interpolator(biomeAvg(x / 4, z / 4),
|
Interpolator interpolator = new Interpolator(biomeAvg(x / 4, z / 4, w),
|
||||||
biomeAvg((x / 4) + 1, z / 4),
|
biomeAvg((x / 4) + 1, z / 4, w),
|
||||||
biomeAvg(x / 4, (z / 4) + 1),
|
biomeAvg(x / 4, (z / 4) + 1, w),
|
||||||
biomeAvg((x / 4) + 1, (z / 4) + 1),
|
biomeAvg((x / 4) + 1, (z / 4) + 1, w),
|
||||||
Interpolator.Type.LINEAR);
|
Interpolator.Type.LINEAR);
|
||||||
values[x + 1][z + 1] = interpolator.bilerp((double) (x % 4) / 4, (double) (z % 4) / 4);
|
values[x + 1][z + 1] = interpolator.bilerp((double) (x % 4) / 4, (double) (z % 4) / 4);
|
||||||
} else values[x + 1][z + 1] = elevate(generator, xOrigin + x, zOrigin + z);
|
} else values[x + 1][z + 1] = elevate(generator, xOrigin + x, zOrigin + z, w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,20 +57,20 @@ public class ElevationInterpolator {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private double biomeAvg(int x, int z) {
|
private double biomeAvg(int x, int z, World w) {
|
||||||
return (elevate(getStoredGen(x + 1, z), x * 4 + 4 + xOrigin, z * 4 + zOrigin)
|
return (elevate(getStoredGen(x + 1, z), x * 4 + 4 + xOrigin, z * 4 + zOrigin, w)
|
||||||
+ elevate(getStoredGen(x - 1, z), x * 4 - 4 + xOrigin, z * 4 + zOrigin)
|
+ elevate(getStoredGen(x - 1, z), x * 4 - 4 + xOrigin, z * 4 + zOrigin, w)
|
||||||
+ elevate(getStoredGen(x, z + 1), x * 4 + xOrigin, z * 4 + 4 + zOrigin)
|
+ elevate(getStoredGen(x, z + 1), x * 4 + xOrigin, z * 4 + 4 + zOrigin, w)
|
||||||
+ elevate(getStoredGen(x, z - 1), x * 4 + xOrigin, z * 4 - 4 + zOrigin)
|
+ elevate(getStoredGen(x, z - 1), x * 4 + xOrigin, z * 4 - 4 + zOrigin, w)
|
||||||
+ elevate(getStoredGen(x, z), x * 4 + xOrigin, z * 4 + zOrigin)
|
+ elevate(getStoredGen(x, z), x * 4 + xOrigin, z * 4 + zOrigin, w)
|
||||||
+ elevate(getStoredGen(x - 1, z - 1), x * 4 + xOrigin, z * 4 + zOrigin)
|
+ elevate(getStoredGen(x - 1, z - 1), x * 4 + xOrigin, z * 4 + zOrigin, w)
|
||||||
+ elevate(getStoredGen(x - 1, z + 1), x * 4 + xOrigin, z * 4 + zOrigin)
|
+ elevate(getStoredGen(x - 1, z + 1), x * 4 + xOrigin, z * 4 + zOrigin, w)
|
||||||
+ elevate(getStoredGen(x + 1, z - 1), x * 4 + xOrigin, z * 4 + zOrigin)
|
+ elevate(getStoredGen(x + 1, z - 1), x * 4 + xOrigin, z * 4 + zOrigin, w)
|
||||||
+ elevate(getStoredGen(x + 1, z + 1), x * 4 + xOrigin, z * 4 + zOrigin)) / 9D;
|
+ elevate(getStoredGen(x + 1, z + 1), x * 4 + xOrigin, z * 4 + zOrigin, w)) / 9D;
|
||||||
}
|
}
|
||||||
|
|
||||||
private double elevate(UserDefinedGenerator g, int x, int z) {
|
private double elevate(UserDefinedGenerator g, int x, int z, World w) {
|
||||||
if(g.getElevationEquation() != null) return g.getElevationEquation().getNoise(x, z, noise);
|
if(g.getElevationEquation() != null) return g.getElevationEquation().getNoise(x, z, w);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ public class TerraChunkGenerator extends GaeaChunkGenerator {
|
|||||||
|
|
||||||
ElevationInterpolator elevationInterpolator;
|
ElevationInterpolator elevationInterpolator;
|
||||||
try(ProfileFuture ignore = TerraProfiler.fromWorld(world).measure("ElevationTime")) {
|
try(ProfileFuture ignore = TerraProfiler.fromWorld(world).measure("ElevationTime")) {
|
||||||
elevationInterpolator = new ElevationInterpolator(world, chunkX, chunkZ, tw.getGrid(), getNoiseGenerator());
|
elevationInterpolator = new ElevationInterpolator(world, chunkX, chunkZ, tw.getGrid());
|
||||||
}
|
}
|
||||||
|
|
||||||
for(byte x = 0; x < 16; x++) {
|
for(byte x = 0; x < 16; x++) {
|
||||||
@ -203,12 +203,12 @@ public class TerraChunkGenerator extends GaeaChunkGenerator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNoiseOctaves(World world) {
|
public int getNoiseOctaves(World world) {
|
||||||
return configPack.octaves;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getNoiseFrequency(World world) {
|
public double getNoiseFrequency(World world) {
|
||||||
return configPack.frequency;
|
return 0.02;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package com.dfsek.terra.generation;
|
package com.dfsek.terra.generation;
|
||||||
|
|
||||||
import com.dfsek.terra.Debug;
|
import com.dfsek.terra.Debug;
|
||||||
|
import com.dfsek.terra.config.genconfig.noise.NoiseConfig;
|
||||||
|
import com.dfsek.terra.math.NoiseFunction;
|
||||||
import com.dfsek.terra.math.NoiseFunction2;
|
import com.dfsek.terra.math.NoiseFunction2;
|
||||||
import com.dfsek.terra.math.NoiseFunction3;
|
import com.dfsek.terra.math.NoiseFunction3;
|
||||||
import com.dfsek.terra.util.DataUtil;
|
import com.dfsek.terra.util.DataUtil;
|
||||||
@ -17,6 +19,8 @@ import parsii.eval.Scope;
|
|||||||
import parsii.eval.Variable;
|
import parsii.eval.Variable;
|
||||||
import parsii.tokenizer.ParseException;
|
import parsii.tokenizer.ParseException;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
@ -31,21 +35,35 @@ public class UserDefinedGenerator extends Generator {
|
|||||||
private final Palette<BlockData>[] palettes = new Palette[256];
|
private final Palette<BlockData>[] palettes = new Palette[256];
|
||||||
@SuppressWarnings({"unchecked", "rawtypes", "RedundantSuppression"})
|
@SuppressWarnings({"unchecked", "rawtypes", "RedundantSuppression"})
|
||||||
private final Palette<BlockData>[] slantPalettes = new Palette[256];
|
private final Palette<BlockData>[] slantPalettes = new Palette[256];
|
||||||
private final NoiseFunction2 n2 = new NoiseFunction2();
|
|
||||||
private final NoiseFunction3 n3 = new NoiseFunction3();
|
|
||||||
private final ElevationEquation elevationEquation;
|
private final ElevationEquation elevationEquation;
|
||||||
private final boolean preventSmooth;
|
private final boolean preventSmooth;
|
||||||
private boolean elevationInterpolation;
|
private boolean elevationInterpolation;
|
||||||
|
private final List<NoiseFunction> noiseFunctions = new ArrayList<>();
|
||||||
|
private boolean set = true;
|
||||||
|
|
||||||
|
|
||||||
public UserDefinedGenerator(String equation, @Nullable String elevateEquation, Map<String, Double> userVariables, Map<Integer, Palette<BlockData>> paletteMap, Map<Integer, Palette<BlockData>> slantPaletteMap, boolean preventSmooth)
|
public UserDefinedGenerator(String equation, @Nullable String elevateEquation, Map<String, Double> userVariables, Map<Integer, Palette<BlockData>> paletteMap, Map<Integer, Palette<BlockData>> slantPaletteMap, Map<String, NoiseConfig> noiseBuilders, boolean preventSmooth)
|
||||||
throws ParseException {
|
throws ParseException {
|
||||||
for(Map.Entry<String, Double> entry : userVariables.entrySet()) {
|
for(Map.Entry<String, Double> entry : userVariables.entrySet()) {
|
||||||
s.getVariable(entry.getKey()).setValue(entry.getValue()); // Define all user variables.
|
s.getVariable(entry.getKey()).setValue(entry.getValue()); // Define all user variables.
|
||||||
}
|
}
|
||||||
Parser p = new Parser();
|
Parser p = new Parser();
|
||||||
p.registerFunction("noise2", n2);
|
|
||||||
p.registerFunction("noise3", n3);
|
for(Map.Entry<String, NoiseConfig> e : noiseBuilders.entrySet()) {
|
||||||
|
switch(e.getValue().getDimensions()) {
|
||||||
|
case 2:
|
||||||
|
NoiseFunction2 function2 = new NoiseFunction2(e.getValue().getBuilder());
|
||||||
|
noiseFunctions.add(function2);
|
||||||
|
p.registerFunction(e.getKey(), function2);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
NoiseFunction3 function3 = new NoiseFunction3(e.getValue().getBuilder());
|
||||||
|
noiseFunctions.add(function3);
|
||||||
|
p.registerFunction(e.getKey(), function3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(int y = 0; y < 256; y++) {
|
for(int y = 0; y < 256; y++) {
|
||||||
Palette<BlockData> d = DataUtil.BLANK_PALETTE;
|
Palette<BlockData> d = DataUtil.BLANK_PALETTE;
|
||||||
for(Map.Entry<Integer, Palette<BlockData>> e : paletteMap.entrySet()) {
|
for(Map.Entry<Integer, Palette<BlockData>> e : paletteMap.entrySet()) {
|
||||||
@ -66,12 +84,21 @@ public class UserDefinedGenerator extends Generator {
|
|||||||
}
|
}
|
||||||
if(elevateEquation != null) {
|
if(elevateEquation != null) {
|
||||||
Debug.info("Using elevation equation");
|
Debug.info("Using elevation equation");
|
||||||
this.elevationEquation = new ElevationEquation(elevateEquation);
|
this.elevationEquation = new ElevationEquation(elevateEquation, noiseBuilders);
|
||||||
} else this.elevationEquation = null;
|
} else this.elevationEquation = null;
|
||||||
this.noiseExp = p.parse(equation, s);
|
this.noiseExp = p.parse(equation, s);
|
||||||
this.preventSmooth = preventSmooth;
|
this.preventSmooth = preventSmooth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setNoise(long seed) {
|
||||||
|
if(set) {
|
||||||
|
set = false;
|
||||||
|
for(NoiseFunction n : noiseFunctions) {
|
||||||
|
n.setNoise(seed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the 2D noise at a pair of coordinates using the provided FastNoiseLite instance.
|
* Gets the 2D noise at a pair of coordinates using the provided FastNoiseLite instance.
|
||||||
*
|
*
|
||||||
@ -86,8 +113,7 @@ public class UserDefinedGenerator extends Generator {
|
|||||||
xVar.setValue(x);
|
xVar.setValue(x);
|
||||||
yVar.setValue(0);
|
yVar.setValue(0);
|
||||||
zVar.setValue(z);
|
zVar.setValue(z);
|
||||||
n2.setNoise(gen);
|
setNoise(w.getSeed());
|
||||||
n3.setNoise(gen);
|
|
||||||
return noiseExp.evaluate();
|
return noiseExp.evaluate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -107,8 +133,7 @@ public class UserDefinedGenerator extends Generator {
|
|||||||
xVar.setValue(x);
|
xVar.setValue(x);
|
||||||
yVar.setValue(y);
|
yVar.setValue(y);
|
||||||
zVar.setValue(z);
|
zVar.setValue(z);
|
||||||
n2.setNoise(gen);
|
setNoise(w.getSeed());
|
||||||
n3.setNoise(gen);
|
|
||||||
return noiseExp.evaluate();
|
return noiseExp.evaluate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,109 @@
|
|||||||
|
package com.dfsek.terra.generation.config;
|
||||||
|
|
||||||
|
import org.polydev.gaea.math.FastNoiseLite;
|
||||||
|
|
||||||
|
public class NoiseBuilder {
|
||||||
|
private FastNoiseLite.NoiseType type = FastNoiseLite.NoiseType.OpenSimplex2;
|
||||||
|
private int octaves = 1;
|
||||||
|
private FastNoiseLite.FractalType fractalType = FastNoiseLite.FractalType.None;
|
||||||
|
private double frequency = 0.02D;
|
||||||
|
private double fractalGain = 0.5D;
|
||||||
|
private double fractalLacunarity = 2.0D;
|
||||||
|
private double pingPong = 2.0D;
|
||||||
|
private double weightedStrength = 0.0D;
|
||||||
|
|
||||||
|
private FastNoiseLite.CellularDistanceFunction cellularDistanceFunction = FastNoiseLite.CellularDistanceFunction.EuclideanSq;
|
||||||
|
private FastNoiseLite.CellularReturnType cellularReturnType = FastNoiseLite.CellularReturnType.Distance;
|
||||||
|
private double cellularJitter = 1.0D;
|
||||||
|
|
||||||
|
private FastNoiseLite.DomainWarpType domainWarpType = FastNoiseLite.DomainWarpType.OpenSimplex2;
|
||||||
|
private double domainWarpAmp = 1.0D;
|
||||||
|
|
||||||
|
private FastNoiseLite.RotationType3D rotationType3D = FastNoiseLite.RotationType3D.None;
|
||||||
|
|
||||||
|
public FastNoiseLite build(int seed) {
|
||||||
|
FastNoiseLite noise = new FastNoiseLite(seed);
|
||||||
|
if(!fractalType.equals(FastNoiseLite.FractalType.None)) {
|
||||||
|
noise.setFractalType(fractalType);
|
||||||
|
noise.setFractalOctaves(octaves);
|
||||||
|
noise.setFractalGain(fractalGain);
|
||||||
|
noise.setFractalLacunarity(fractalLacunarity);
|
||||||
|
if(fractalType.equals(FastNoiseLite.FractalType.PingPong)) noise.setFractalPingPongStrength(pingPong);
|
||||||
|
noise.setFractalWeightedStrength(weightedStrength);
|
||||||
|
}
|
||||||
|
if(type.equals(FastNoiseLite.NoiseType.Cellular)) {
|
||||||
|
noise.setCellularDistanceFunction(cellularDistanceFunction);
|
||||||
|
noise.setCellularReturnType(cellularReturnType);
|
||||||
|
noise.setCellularJitter(cellularJitter);
|
||||||
|
}
|
||||||
|
|
||||||
|
noise.setDomainWarpType(domainWarpType);
|
||||||
|
noise.setDomainWarpAmp(domainWarpAmp);
|
||||||
|
|
||||||
|
noise.setRotationType3D(rotationType3D);
|
||||||
|
|
||||||
|
noise.setFrequency(frequency);
|
||||||
|
return noise;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFrequency(double frequency) {
|
||||||
|
this.frequency = frequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFractalGain(double fractalGain) {
|
||||||
|
this.fractalGain = fractalGain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFractalLacunarity(double fractalLacunarity) {
|
||||||
|
this.fractalLacunarity = fractalLacunarity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFractalType(FastNoiseLite.FractalType fractalType) {
|
||||||
|
this.fractalType = fractalType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOctaves(int octaves) {
|
||||||
|
this.octaves = octaves;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPingPong(double pingPong) {
|
||||||
|
this.pingPong = pingPong;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWeightedStrength(double weightedStrength) {
|
||||||
|
this.weightedStrength = weightedStrength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FastNoiseLite.NoiseType getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(FastNoiseLite.NoiseType type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCellularDistanceFunction(FastNoiseLite.CellularDistanceFunction cellularDistanceFunction) {
|
||||||
|
this.cellularDistanceFunction = cellularDistanceFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCellularReturnType(FastNoiseLite.CellularReturnType cellularReturnType) {
|
||||||
|
this.cellularReturnType = cellularReturnType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCellularJitter(double cellularJitter) {
|
||||||
|
this.cellularJitter = cellularJitter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDomainWarpAmp(double domainWarpAmp) {
|
||||||
|
this.domainWarpAmp = domainWarpAmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDomainWarpType(FastNoiseLite.DomainWarpType domainWarpType) {
|
||||||
|
this.domainWarpType = domainWarpType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRotationType3D(FastNoiseLite.RotationType3D rotationType3D) {
|
||||||
|
this.rotationType3D = rotationType3D;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
7
src/main/java/com/dfsek/terra/math/NoiseFunction.java
Normal file
7
src/main/java/com/dfsek/terra/math/NoiseFunction.java
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package com.dfsek.terra.math;
|
||||||
|
|
||||||
|
import parsii.eval.Function;
|
||||||
|
|
||||||
|
public interface NoiseFunction extends Function {
|
||||||
|
void setNoise(long seed);
|
||||||
|
}
|
@ -1,15 +1,20 @@
|
|||||||
package com.dfsek.terra.math;
|
package com.dfsek.terra.math;
|
||||||
|
|
||||||
import com.dfsek.terra.config.base.ConfigUtil;
|
import com.dfsek.terra.config.base.ConfigUtil;
|
||||||
|
import com.dfsek.terra.generation.config.NoiseBuilder;
|
||||||
import org.polydev.gaea.math.FastNoiseLite;
|
import org.polydev.gaea.math.FastNoiseLite;
|
||||||
import parsii.eval.Expression;
|
import parsii.eval.Expression;
|
||||||
import parsii.eval.Function;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class NoiseFunction2 implements Function {
|
public class NoiseFunction2 implements NoiseFunction {
|
||||||
private final Cache cache = new Cache();
|
private final Cache cache = new Cache();
|
||||||
private FastNoiseLite gen;
|
private FastNoiseLite gen;
|
||||||
|
private final NoiseBuilder builder;
|
||||||
|
|
||||||
|
public NoiseFunction2(NoiseBuilder builder) {
|
||||||
|
this.builder = builder;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNumberOfArguments() {
|
public int getNumberOfArguments() {
|
||||||
@ -26,8 +31,9 @@ public class NoiseFunction2 implements Function {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNoise(FastNoiseLite gen) {
|
@Override
|
||||||
this.gen = gen;
|
public void setNoise(long seed) {
|
||||||
|
this.gen = builder.build((int) seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class Cache {
|
private final class Cache {
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
package com.dfsek.terra.math;
|
package com.dfsek.terra.math;
|
||||||
|
|
||||||
|
import com.dfsek.terra.generation.config.NoiseBuilder;
|
||||||
import org.polydev.gaea.math.FastNoiseLite;
|
import org.polydev.gaea.math.FastNoiseLite;
|
||||||
import parsii.eval.Expression;
|
import parsii.eval.Expression;
|
||||||
import parsii.eval.Function;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class NoiseFunction3 implements Function {
|
public class NoiseFunction3 implements NoiseFunction {
|
||||||
private FastNoiseLite gen;
|
private FastNoiseLite gen;
|
||||||
|
private final NoiseBuilder builder;
|
||||||
|
|
||||||
|
public NoiseFunction3(NoiseBuilder builder) {
|
||||||
|
this.builder = builder;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNumberOfArguments() {
|
public int getNumberOfArguments() {
|
||||||
@ -24,7 +29,8 @@ public class NoiseFunction3 implements Function {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNoise(FastNoiseLite gen) {
|
@Override
|
||||||
this.gen = gen;
|
public void setNoise(long seed) {
|
||||||
|
this.gen = builder.build((int) seed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user