From 373d75609a73bf737457ad12c31040a80a73a2bb Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Fri, 1 Nov 2019 04:27:47 -0400 Subject: [PATCH] f --- src/main/java/ninja/bytecode/iris/Iris.java | 2 +- .../ninja/bytecode/iris/IrisGenerator.java | 142 +++++++++++------- .../java/ninja/bytecode/iris/Settings.java | 4 +- .../java/ninja/bytecode/iris/biome/CBI.java | 54 ++++--- .../bytecode/iris/gen/GenLayerBiome.java | 54 ++----- .../bytecode/iris/util/MaxingGenerator.java | 111 ++++++++++++++ 6 files changed, 253 insertions(+), 114 deletions(-) create mode 100644 src/main/java/ninja/bytecode/iris/util/MaxingGenerator.java diff --git a/src/main/java/ninja/bytecode/iris/Iris.java b/src/main/java/ninja/bytecode/iris/Iris.java index c06a5ccf7..40fcc4591 100644 --- a/src/main/java/ninja/bytecode/iris/Iris.java +++ b/src/main/java/ninja/bytecode/iris/Iris.java @@ -150,7 +150,7 @@ public class Iris extends JavaPlugin implements Listener else if(p.startsWith("^")) { - double c = M.percentRange(value, -11, 37); + double c = M.lerpInverse(-11, 37, value); double f = 32 + (c * (1.8)); v = F.f(c, Integer.valueOf(p.substring(1))) + " \u00B0C / " + F.f(f, Integer.valueOf(p.substring(1))) + " \u00B0F"; } diff --git a/src/main/java/ninja/bytecode/iris/IrisGenerator.java b/src/main/java/ninja/bytecode/iris/IrisGenerator.java index ea54b864e..ae0775ff3 100644 --- a/src/main/java/ninja/bytecode/iris/IrisGenerator.java +++ b/src/main/java/ninja/bytecode/iris/IrisGenerator.java @@ -3,94 +3,144 @@ package ninja.bytecode.iris; import java.util.List; import java.util.Random; -import org.bukkit.BlockChangeDelegate; -import org.bukkit.Location; import org.bukkit.Material; -import org.bukkit.TreeType; import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.generator.BlockPopulator; +import org.bukkit.util.Vector; import ninja.bytecode.iris.biome.CBI; import ninja.bytecode.iris.gen.GenLayerBase; import ninja.bytecode.iris.gen.GenLayerBiome; -import ninja.bytecode.iris.gen.IGenLayer; -import ninja.bytecode.iris.util.PolygonGenerator; +import ninja.bytecode.iris.util.MaxingGenerator; import ninja.bytecode.shuriken.collections.GList; import ninja.bytecode.shuriken.collections.GMap; +import ninja.bytecode.shuriken.execution.ChronoLatch; +import ninja.bytecode.shuriken.format.F; import ninja.bytecode.shuriken.logging.L; import ninja.bytecode.shuriken.math.M; import ninja.bytecode.shuriken.math.RNG; public class IrisGenerator extends ParallelChunkGenerator { + private GMap heightCache; private MB WATER = new MB(Material.STATIONARY_WATER); private MB BEDROCK = new MB(Material.BEDROCK); - private GList genLayers; private GenLayerBase glBase; private GenLayerBiome glBiome; - private GMap trees; private RNG rng; private World world; - private PolygonGenerator g; @Override public void onInit(World world, Random random) { this.world = world; - trees = new GMap<>(); - genLayers = new GList<>(); + heightCache = new GMap<>(); rng = new RNG(world.getSeed()); - genLayers.add(glBase = new GenLayerBase(this, world, random, rng.nextRNG())); - genLayers.add(glBiome = new GenLayerBiome(this, world, random, rng.nextRNG())); - g = new PolygonGenerator(rng, 16, 0.01, 1, (c) -> c); + glBase = new GenLayerBase(this, world, random, rng.nextRNG()); + glBiome = new GenLayerBiome(this, world, random, rng.nextRNG()); + } + + public int getHeight(double h) + { + double height = M.clip(h, 0D, 1D); + + return (int) (height * 253); } public int getHeight(double dx, double dz) { - double height = M.clip(getRawHeight(dx, dz), 0D, 1D); - - return (int) (height * 253); + return getHeight(getRawHeight(dx, dz)); } public double getRawHeight(double dx, double dz) { double noise = 0 + Iris.settings.gen.baseHeight; - for(IGenLayer i : genLayers) - { - noise = i.generateLayer(noise, dx, dz); - } - return M.clip(noise, 0D, 1D); } @Override public Biome genColumn(int wxx, int wzx, int x, int z) { - if(true) - { - for(int i = 0; i < 1; i++) - { - setBlock(x, i, z, Material.CONCRETE, (byte) g.getIndex(wxx, wzx)); - } - - return Biome.PLAINS; - } - - else - { - return genBaseColumn(wxx, wzx, x, z); - } + return genBaseColumn(wxx, wzx, x, z); } + private double lerp(double a, double b, double f) + { + return a + (f * (b - a)); + } + + private double blerp(double a, double b, double c, double d, double tx, double ty) + { + return lerp(lerp(a, b, tx), lerp(c, d, tx), ty); + } + + private double getBiomedHeight(int x, int z) + { + Vector v = new Vector(x, z, x * z); + if(heightCache.containsKey(v)) + { + return heightCache.get(v); + } + + int wx = (int) Math.round((double) x * Iris.settings.gen.horizontalZoom); + int wz = (int) Math.round((double) z * Iris.settings.gen.horizontalZoom); + CBI biome = glBiome.getBiome(wx * Iris.settings.gen.biomeScale, wz * Iris.settings.gen.biomeScale); + double h = Iris.settings.gen.baseHeight + biome.getHeight(); + h += (glBase.getHeight(wx, wz) * biome.getAmp()) - (0.33 * biome.getAmp()); + heightCache.put(v, h); + + return h; + } + + private double getBilinearNoise(int x, int z) + { + int h = 3; + int fx = x >> h; + int fz = z >> h; + int xa = (fx << h) - 2; + int za = (fz << h) - 2; + int xb = ((fx + 1) << h) + 2; + int zb = ((fz + 1) << h) + 2; + double na = getBiomedHeight(xa, za); + double nb = getBiomedHeight(xa, zb); + double nc = getBiomedHeight(xb, za); + double nd = getBiomedHeight(xb, zb); + double px = M.rangeScale(0, 1, xa, xb, x); + double pz = M.rangeScale(0, 1, za, zb, z); + + return blerp(na, nc, nb, nd, px, pz); + } + + private double getBicubicNoise(int x, int z) + { + int h = 3; + int fx = x >> h; + int fz = z >> h; + int xa = (fx << h); + int za = (fz << h); + int xb = ((fx + 1) << h); + int zb = ((fz + 1) << h); + double na = getBilinearNoise(xa, za); + double nb = getBilinearNoise(xa, zb); + double nc = getBilinearNoise(xb, za); + double nd = getBilinearNoise(xb, zb); + double px = M.rangeScale(0, 1, xa, xb, x); + double pz = M.rangeScale(0, 1, za, zb, z); + + return blerp(na, nc, nb, nd, px, pz); + } + + private Biome genBaseColumn(int wxx, int wzx, int x, int z) { int seaLevel = Iris.settings.gen.seaLevel; int wx = (int) Math.round((double) wxx * Iris.settings.gen.horizontalZoom); int wz = (int) Math.round((double) wzx * Iris.settings.gen.horizontalZoom); CBI biome = glBiome.getBiome(wx * Iris.settings.gen.biomeScale, wz * Iris.settings.gen.biomeScale); - int height = getHeight(wx, wz) + 25; + double hv = getBicubicNoise(wxx, wzx); + int height = getHeight(hv); for(int i = 0; i < Math.max(height, seaLevel); i++) { @@ -124,17 +174,6 @@ public class IrisGenerator extends ParallelChunkGenerator } } } - - if(height < 240 && height >= seaLevel) - { - TreeType s = biome.getTreeChanceSingle(); - - if(s != null) - { - setBlock(x, i + 1, z, Material.AIR); - trees.put(new Location(world, x, i + 1, z), s); - } - } } if(Iris.settings.gen.flatBedrock ? i == 0 : i < glBase.scatterInt(x, i, z, 3)) @@ -169,17 +208,12 @@ public class IrisGenerator extends ParallelChunkGenerator @Override public void onInitChunk(World world, int x, int z, Random random) { - + heightCache.clear(); } @Override public void onPostChunk(World world, int x, int z, Random random) { - - } - - public double getBiomeBorder(double dx, double dz) - { - return glBiome.getCenterPercent(dx, dz); + } } \ No newline at end of file diff --git a/src/main/java/ninja/bytecode/iris/Settings.java b/src/main/java/ninja/bytecode/iris/Settings.java index 02ad45031..344502842 100644 --- a/src/main/java/ninja/bytecode/iris/Settings.java +++ b/src/main/java/ninja/bytecode/iris/Settings.java @@ -14,7 +14,7 @@ public class Settings public static class GeneratorSettings { - public double horizontalZoom = 1.325; // 1.856 2.556 + public double horizontalZoom = 2.225; // 1.856 2.556 public double heightFracture = 155; public double heightMultiplier = 1.154; public double heightExponentBase = 1; @@ -22,7 +22,7 @@ public class Settings public double heightScale = 1; public double superHeightScale = 0.65; public double altBiomeScale = 1; - public double baseHeight = 0.3415; + public double baseHeight = 0.22; public double superSamplerRadius = 32; public int superSamplerIterations = 14; public int superSamples = 12; diff --git a/src/main/java/ninja/bytecode/iris/biome/CBI.java b/src/main/java/ninja/bytecode/iris/biome/CBI.java index 10a21c597..591949711 100644 --- a/src/main/java/ninja/bytecode/iris/biome/CBI.java +++ b/src/main/java/ninja/bytecode/iris/biome/CBI.java @@ -16,10 +16,15 @@ import ninja.bytecode.shuriken.math.RNG; public class CBI { //@builder + public static final CBI RIVER = new CBI("River", Biome.RIVER) + .surface(MB.of(Material.SAND)) + .height(0.085); public static final CBI OCEAN = new CBI("Ocean", Biome.OCEAN) - .surface(MB.of(Material.SAND)); + .surface(MB.of(Material.SAND)) + .height(-0.07); public static final CBI DEEP_OCEAN = new CBI("Deep Ocean", Biome.DEEP_OCEAN) - .surface(MB.of(Material.SAND)); + .surface(MB.of(Material.SAND)) + .height(-0.07); public static final CBI DESERT = new CBI("Desert", Biome.DESERT) .surface(MB.of(Material.SAND)) .scatter(MB.of(Material.DEAD_BUSH, 0), 0.08) @@ -35,6 +40,7 @@ public class CBI .simplexSurface(); public static final CBI DESERT_HILLS = new CBI("Desert Hills", Biome.DESERT_HILLS) .surface(MB.of(Material.SAND)) + .amp(0.75) .scatter(MB.of(Material.DEAD_BUSH, 0), 0.08) .dirt(MB.of(Material.SANDSTONE)); public static final CBI MESA = new CBI("Mesa", Biome.MESA) @@ -46,18 +52,21 @@ public class CBI .tree(TreeType.ACACIA, 0.2); public static final CBI SAVANNA_HILLS = new CBI("Savanna Hills", Biome.SAVANNA_ROCK) .scatter(MB.of(Material.LONG_GRASS, 1), 0.18) + .amp(0.75) .tree(TreeType.ACACIA, 0.2); public static final CBI JUNGLE = new CBI("Jungle", Biome.JUNGLE) .scatter(MB.of(Material.LONG_GRASS, 1), 0.58) .scatter(MB.of(Material.LONG_GRASS, 2), 0.13); public static final CBI JUNGLE_HILLS = new CBI("Jungle Hills", Biome.JUNGLE_HILLS) .scatter(MB.of(Material.LONG_GRASS, 1), 0.58) + .amp(0.75) .scatter(MB.of(Material.LONG_GRASS, 2), 0.13); public static final CBI SWAMP = new CBI("Swamp", Biome.SWAMPLAND) .scatter(MB.of(Material.LONG_GRASS, 1), 0.04) .scatter(MB.of(Material.LONG_GRASS, 2), 0.03); public static final CBI PLAINS = new CBI("Plains", Biome.PLAINS) .scatter(MB.of(Material.LONG_GRASS, 1), 0.38) + .amp(0.4) .scatter(MB.of(Material.LONG_GRASS, 2), 0.03); public static final CBI DECAYING_PLAINS = new CBI("Decaying Plains", Biome.PLAINS) .surface(MB.of(Material.GRASS_PATH), MB.of(Material.GRASS)) @@ -68,12 +77,14 @@ public class CBI .scatter(MB.of(Material.LONG_GRASS, 2), 0.13); public static final CBI FOREST_HILLS = new CBI("Forest Hills", Biome.FOREST_HILLS) .scatter(MB.of(Material.LONG_GRASS, 1), 0.23) + .amp(0.75) .scatter(MB.of(Material.LONG_GRASS, 2), 0.13); public static final CBI BIRCH_FOREST = new CBI("Birch Forest", Biome.BIRCH_FOREST) .scatter(MB.of(Material.LONG_GRASS, 1), 0.23) .scatter(MB.of(Material.LONG_GRASS, 2), 0.13); public static final CBI BIRCH_FOREST_HILLS = new CBI("Birch Forest Hills", Biome.BIRCH_FOREST_HILLS) .scatter(MB.of(Material.LONG_GRASS, 1), 0.23) + .amp(0.75) .scatter(MB.of(Material.LONG_GRASS, 2), 0.13); public static final CBI ROOFED_FOREST = new CBI("Roofed Forest", Biome.ROOFED_FOREST) .scatter(MB.of(Material.LONG_GRASS, 1), 0.23) @@ -83,21 +94,25 @@ public class CBI public static final CBI EXTREME_HILLS = new CBI("Extreme Hills", Biome.EXTREME_HILLS) .scatter(MB.of(Material.LONG_GRASS, 2), 0.04); public static final CBI EXTREME_HILLS_TREES = new CBI("Extreme Hills +", Biome.EXTREME_HILLS_WITH_TREES) - .scatter(MB.of(Material.LONG_GRASS, 2), 0.09); + .scatter(MB.of(Material.LONG_GRASS, 2), 0.09) + .amp(1.25); public static final CBI TAIGA_COLD = new CBI("Taiga Cold", Biome.TAIGA_COLD) .scatter(MB.of(Material.LONG_GRASS, 2), 0.04); - public static final CBI TAIGA_COLD_HILLS = new CBI("Taiga Cold Hills", Biome.TAIGA_COLD_HILLS); + public static final CBI TAIGA_COLD_HILLS = new CBI("Taiga Cold Hills", Biome.TAIGA_COLD_HILLS) + .amp(0.75); public static final CBI ICE_FLATS = new CBI("Ice Flats", Biome.ICE_FLATS); - public static final CBI ICE_MOUNTAINS = new CBI("Ice Mountains", Biome.ICE_MOUNTAINS); + public static final CBI ICE_MOUNTAINS = new CBI("Ice Mountains", Biome.ICE_MOUNTAINS) + .amp(1.45); public static final CBI REDWOOD_TAIGA = new CBI("Redwood Taiga", Biome.REDWOOD_TAIGA) .surface(MB.of(Material.DIRT, 2), MB.of(Material.DIRT, 1)) .simplexSurface(); public static final CBI REDWOOD_TAIGA_HILLS = new CBI("Redwood Taiga Hills", Biome.REDWOOD_TAIGA_HILLS) .surface(MB.of(Material.DIRT, 2), MB.of(Material.DIRT, 1)) + .amp(0.75) .simplexSurface(); //@done - + private String name; private Biome realBiome; private double height; @@ -114,26 +129,26 @@ public class CBI this.name = name; this.realBiome = realBiome; this.height = 0.125; - this.amp = 0; + this.amp = 0.5; scatterChance = new GMap<>(); treeChance = new GMap<>(); surface(new MB(Material.GRASS)).dirt(new MB(Material.DIRT), new MB(Material.DIRT, 1)); } - + public CBI scatter(MB mb, Double chance) { scatterChance.put(mb, chance); - + return this; } - + public CBI tree(TreeType t, Double chance) { treeChance.put(t, chance); - + return this; } - + public CBI simplexSurface() { simplexScatter = true; @@ -200,17 +215,18 @@ public class CBI { if(poly == null) { - poly = new PolygonGenerator.EnumPolygonGenerator(rng, 0.05, 12, getSurface().toArray(new MB[getSurface().size()]), (g) -> { + poly = new PolygonGenerator.EnumPolygonGenerator(rng, 0.05, 12, getSurface().toArray(new MB[getSurface().size()]), (g) -> + { return g.fractureWith(new CNG(rng.nextRNG(), 1D, 2).scale(0.155), 24); }); } - + return poly.getChoice(wx, wz); } - + return getSurface().getRandom(); } - + public MB getDirt(int wx, int wz) { return getDirt().getRandom(); @@ -230,10 +246,10 @@ public class CBI return i; } } - + return MB.of(Material.AIR); } - + public GMap getTreeChance() { return treeChance; @@ -248,7 +264,7 @@ public class CBI return i; } } - + return null; } } diff --git a/src/main/java/ninja/bytecode/iris/gen/GenLayerBiome.java b/src/main/java/ninja/bytecode/iris/gen/GenLayerBiome.java index 582919062..1e6deb3be 100644 --- a/src/main/java/ninja/bytecode/iris/gen/GenLayerBiome.java +++ b/src/main/java/ninja/bytecode/iris/gen/GenLayerBiome.java @@ -8,35 +8,23 @@ import org.bukkit.World; import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.IrisGenerator; import ninja.bytecode.iris.biome.CBI; -import ninja.bytecode.iris.util.PolygonGenerator; -import ninja.bytecode.iris.util.PolygonGenerator.EnumPolygonGenerator; -import ninja.bytecode.shuriken.collections.GList; +import ninja.bytecode.iris.util.MaxingGenerator.EnumMaxingGenerator; import ninja.bytecode.shuriken.math.CNG; import ninja.bytecode.shuriken.math.RNG; public class GenLayerBiome extends GenLayer { - private CNG fractures2; - private CNG fractures4; - private PolygonGenerator.EnumPolygonGenerator biomeGenerator; + private EnumMaxingGenerator biomeGenerator; private Function factory; - private double closest; + private CNG riverCheck; public GenLayerBiome(IrisGenerator iris, World world, Random random, RNG rng) { //@builder super(iris, world, random, rng); - double scale = 1.25D; - factory = (g) -> g - .fractureWith(new CNG(g.nextRNG().nextRNG(), 1D, 32) - .scale(0.2112) - .fractureWith(new CNG(g.nextRNG(), 1D, 16) - .scale(0.132), - 333), 588); - fractures2 = new CNG(rng.nextRNG(), 1, 32).scale(0.02); - fractures4 = new CNG(rng.nextRNG(), 1, 16).scale(0.12); - - biomeGenerator = new PolygonGenerator.EnumPolygonGenerator(rng.nextRNG(), 0.00755 * Iris.settings.gen.biomeScale, 1, + factory = (g) -> g.fractureWith(new CNG(rng.nextRNG(), 1D, 4).scale(0.02), 56); + riverCheck = new CNG(rng.nextRNG(), 1D, 2).scale(0.00096); + biomeGenerator = new EnumMaxingGenerator(rng.nextRNG(), 0.00755 * Iris.settings.gen.biomeScale, 1, new CBI[] { CBI.DESERT, CBI.DESERT_HILLS, @@ -71,30 +59,20 @@ public class GenLayerBiome extends GenLayer public CBI getBiome(double x, double z) { - double scram2 = fractures2.noise(x, z) * 188.35; - double scram4 = fractures4.noise(x, z) * 47; - double a = x - scram2 - scram4; - double b = z + scram2 + scram4; - a += Math.sin(b) * 12; - b += Math.cos(a) * 12; - return biomeGenerator.getChoice(a, b); - } - - public double getCenterPercent(double x, double z) - { - double scram2 = fractures2.noise(x, z) * 188.35; - double scram4 = fractures4.noise(x, z) * 47; - double a = x - scram2 - scram4; - double b = z + scram2 + scram4; - a += Math.sin(b) * 12; - b += Math.cos(a) * 12; - return biomeGenerator.getClosestNeighbor(a, b); + if(riverCheck.noise(x, z) > 0.75) + { + if(biomeGenerator.hasBorder(3, 3 + Math.pow(riverCheck.noise(x, z), 1.25) * 16, x, z)) + { + return CBI.RIVER; + } + } + + return biomeGenerator.getChoice(x, z); } @Override public double generateLayer(double noise, double dx, double dz) { - CBI biome = getBiome(dx, dz); - return ((1D + (biome.getAmp())) * noise) + (biome.getHeight() / 3D); + return noise; } } diff --git a/src/main/java/ninja/bytecode/iris/util/MaxingGenerator.java b/src/main/java/ninja/bytecode/iris/util/MaxingGenerator.java new file mode 100644 index 000000000..c4a431cfe --- /dev/null +++ b/src/main/java/ninja/bytecode/iris/util/MaxingGenerator.java @@ -0,0 +1,111 @@ +package ninja.bytecode.iris.util; + +import java.util.function.Function; + +import ninja.bytecode.shuriken.math.CNG; +import ninja.bytecode.shuriken.math.RNG; + +public class MaxingGenerator +{ + private CNG[] gen; + private int possibilities; + + public MaxingGenerator(RNG rng, int possibilities, double scale, int octaves, Function factory) + { + this.possibilities = possibilities; + gen = new CNG[possibilities]; + + for(int i = 0; i < possibilities; i++) + { + gen[i] = new CNG(rng.nextRNG(), 1D, 1).scale(scale); + gen[i] = factory.apply(gen[i]); + } + } + + public double getEdge(double... dim) + { + double b = 0; + + for(int i = 0; i < gen.length; i++) + { + double g = Math.pow(gen[i].noise(dim), gen.length); + + if(g > b) + { + b = g; + } + } + + return b; + } + + public int getIndex(double... dim) + { + double b = 0; + int index = 0; + + for(int i = 0; i < gen.length; i++) + { + double g = Math.pow(gen[i].noise(dim), gen.length); + + if(g > b) + { + b = g; + index = i; + } + } + + return index % possibilities; + } + + public boolean hasBorder(int checks, double distance, double... dims) + { + int current = getIndex(dims); + double ajump = 360D / (double)checks; + + if(dims.length == 2) + { + for(int i = 0; i < checks; i++) + { + double dx = Math.sin(Math.toRadians(ajump * i)); + double dz = Math.cos(Math.toRadians(ajump * i)); + if(current != getIndex((dx * distance) + dims[0], (dz * distance) + dims[1])) + { + return true; + } + } + } + + if(dims.length == 3) + { + for(int i = 0; i < checks; i++) + { + double dx = Math.sin(Math.toRadians(ajump * i)); + double dz = Math.cos(Math.toRadians(ajump * i)); + double dy = Math.tan(Math.toRadians(ajump * i)); + if(current != getIndex((dx * distance) + dims[0], (dz * distance) + dims[1], (dy * distance) + dims[2])) + { + return true; + } + } + } + + return false; + } + + public static class EnumMaxingGenerator extends MaxingGenerator + { + private T[] choices; + + public EnumMaxingGenerator(RNG rng, double scale, int octaves, T[] choices, Function factory) + { + super(rng, choices.length, scale / (double) choices.length, octaves, factory); + this.choices = choices; + } + + public T getChoice(double... dim) + { + return choices[super.getIndex(dim)]; + } + } +}