diff --git a/src/main/java/com/volmit/iris/object/IrisBiome.java b/src/main/java/com/volmit/iris/object/IrisBiome.java index c94699543..edfcb44db 100644 --- a/src/main/java/com/volmit/iris/object/IrisBiome.java +++ b/src/main/java/com/volmit/iris/object/IrisBiome.java @@ -41,7 +41,7 @@ public class IrisBiome extends IrisRegistrant implements IRare { @DontObfuscate @DependsOn({ "biomeStyle", "biomeZoom", "biomeScatter" }) @Desc("This changes the dispersion of the biome colors if multiple derivatives are chosen.") - private NoiseStyle biomeStyle = NoiseStyle.SIMPLEX; + private IrisGeneratorStyle biomeStyle = NoiseStyle.SIMPLEX.style(); @MinNumber(0.0001) @DontObfuscate @@ -82,7 +82,7 @@ public class IrisBiome extends IrisRegistrant implements IRare { @DontObfuscate @DependsOn({ "children" }) @Desc("If this biome has children biomes, and the gen layer chooses one of this biomes children, How will it be shaped?") - private NoiseStyle childStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE; + private IrisGeneratorStyle childStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); @ArrayType(min = 1, type = String.class) @DontObfuscate diff --git a/src/main/java/com/volmit/iris/object/IrisBiomeDecorator.java b/src/main/java/com/volmit/iris/object/IrisBiomeDecorator.java index c7abc70c5..ba312dcf5 100644 --- a/src/main/java/com/volmit/iris/object/IrisBiomeDecorator.java +++ b/src/main/java/com/volmit/iris/object/IrisBiomeDecorator.java @@ -23,16 +23,16 @@ import lombok.Data; public class IrisBiomeDecorator { @DontObfuscate @Desc("The varience dispersion is used when multiple blocks are put in the palette. Scatter scrambles them, Wispy shows streak-looking varience") - private NoiseStyle variance = NoiseStyle.STATIC; + private IrisGeneratorStyle variance = NoiseStyle.STATIC.style(); @DontObfuscate @Desc("Dispersion is used to pick places to spawn. Scatter randomly places them (vanilla) or Wispy for a streak like patch system.") - private NoiseStyle dispersion = NoiseStyle.STATIC; + private IrisGeneratorStyle dispersion = NoiseStyle.STATIC.style(); @DependsOn({"stackMin", "stackMax"}) @DontObfuscate @Desc("If this decorator has a height more than 1 this changes how it picks the height between your maxes. Scatter = random, Wispy = wavy heights") - private NoiseStyle heightVariance = NoiseStyle.STATIC; + private IrisGeneratorStyle heightVariance = NoiseStyle.STATIC.style(); @DontObfuscate @Desc("Tells iris where this decoration is a part of. I.e. SHORE_LINE or SEA_SURFACE") diff --git a/src/main/java/com/volmit/iris/object/IrisBiomePaletteLayer.java b/src/main/java/com/volmit/iris/object/IrisBiomePaletteLayer.java index 845a248ee..9414e81eb 100644 --- a/src/main/java/com/volmit/iris/object/IrisBiomePaletteLayer.java +++ b/src/main/java/com/volmit/iris/object/IrisBiomePaletteLayer.java @@ -22,7 +22,7 @@ import lombok.Data; public class IrisBiomePaletteLayer { @DontObfuscate @Desc("The style of noise") - private NoiseStyle style = NoiseStyle.STATIC; + private IrisGeneratorStyle style = NoiseStyle.STATIC.style(); @DependsOn({"minHeight", "maxHeight"}) @MinNumber(0) diff --git a/src/main/java/com/volmit/iris/object/IrisDimension.java b/src/main/java/com/volmit/iris/object/IrisDimension.java index 957833359..4ed3a1f61 100644 --- a/src/main/java/com/volmit/iris/object/IrisDimension.java +++ b/src/main/java/com/volmit/iris/object/IrisDimension.java @@ -59,11 +59,15 @@ public class IrisDimension extends IrisRegistrant { @DontObfuscate @Desc("The placement style of regions") - private NoiseStyle regionStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE; + private IrisGeneratorStyle regionStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); @DontObfuscate @Desc("The placement style of land/sea") - private NoiseStyle continentalStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE; + private IrisGeneratorStyle continentalStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); + + @DontObfuscate + @Desc("The placement style of land/sea") + private IrisGeneratorStyle coordinateFracture = NoiseStyle.FLAT.style(); @MinNumber(-256) @MaxNumber(256) @@ -234,11 +238,11 @@ public class IrisDimension extends IrisRegistrant { @DontObfuscate @Desc("The noise style for rock types") - private NoiseStyle rockStyle = NoiseStyle.STATIC; + private IrisGeneratorStyle rockStyle = NoiseStyle.STATIC.style(); @DontObfuscate @Desc("The noise style for fluid types") - private NoiseStyle fluidStyle = NoiseStyle.STATIC; + private IrisGeneratorStyle fluidStyle = NoiseStyle.STATIC.style(); @MinNumber(0.0001) @MaxNumber(512) diff --git a/src/main/java/com/volmit/iris/object/IrisGenerator.java b/src/main/java/com/volmit/iris/object/IrisGenerator.java index b7d553f96..21694a935 100644 --- a/src/main/java/com/volmit/iris/object/IrisGenerator.java +++ b/src/main/java/com/volmit/iris/object/IrisGenerator.java @@ -1,11 +1,14 @@ package com.volmit.iris.object; +import java.util.List; + import com.volmit.iris.Iris; import com.volmit.iris.gen.atomics.AtomicCache; import com.volmit.iris.noise.CellGenerator; import com.volmit.iris.util.ArrayType; import com.volmit.iris.util.Desc; import com.volmit.iris.util.DontObfuscate; +import com.volmit.iris.util.IRare; import com.volmit.iris.util.IrisInterpolation; import com.volmit.iris.util.KList; import com.volmit.iris.util.MaxNumber; @@ -19,8 +22,7 @@ import lombok.EqualsAndHashCode; @Desc("Represents a composite generator of noise gens") @Data @EqualsAndHashCode(callSuper = false) -public class IrisGenerator extends IrisRegistrant -{ +public class IrisGenerator extends IrisRegistrant { @MinNumber(0.001) @DontObfuscate @Desc("The zoom or frequency.") @@ -99,25 +101,125 @@ public class IrisGenerator extends IrisRegistrant private transient AtomicCache cellGen = new AtomicCache<>(); - public double getMax() - { + public IrisGenerator() { + + } + + public double getMax() { return opacity; } - public boolean hasCliffs() - { + public boolean hasCliffs() { return cliffHeightMax > 0; } - public CellGenerator getCellGenerator(long seed) - { + public CellGenerator getCellGenerator(long seed) { return cellGen.aquire(() -> new CellGenerator(new RNG(seed + 239466))); } - public double getHeight(double rx, double rz, long superSeed) - { - if(composite.isEmpty()) - { + public T fitRarity(KList b, long superSeed, double rx, double rz) { + if (b.size() == 0) { + return null; + } + + if (b.size() == 1) { + return b.get(0); + } + + KList rarityMapped = new KList<>(); + boolean o = false; + int max = 1; + for (T i : b) { + if (i.getRarity() > max) { + max = i.getRarity(); + } + } + + max++; + + for (T i : b) { + for (int j = 0; j < max - i.getRarity(); j++) { + if (o = !o) { + rarityMapped.add(i); + } + + else { + rarityMapped.add(0, i); + } + } + } + + if (rarityMapped.size() == 1) { + return rarityMapped.get(0); + } + + if (rarityMapped.isEmpty()) { + throw new RuntimeException("BAD RARITY MAP! RELATED TO: " + b.toString(", or possibly ")); + } + + return fit(rarityMapped, superSeed, rx, rz); + } + + public T fit(T[] v, long superSeed, double rx, double rz) { + if (v.length == 0) { + return null; + } + + if (v.length == 1) { + return v[0]; + } + + return v[fit(0, v.length - 1, superSeed, rx, rz)]; + } + + public T fit(List v, long superSeed, double rx, double rz) { + if (v.size() == 0) { + return null; + } + + if (v.size() == 1) { + return v.get(0); + } + + return v.get(fit(0, v.size() - 1, superSeed, rx, rz)); + } + + public int fit(int min, int max, long superSeed, double rx, double rz) { + if (min == max) { + return min; + } + + double noise = getHeight(rx, rz, superSeed); + + return (int) Math.round(IrisInterpolation.lerp(min, max, noise)); + } + + public int fit(double min, double max, long superSeed, double rx, double rz) { + if (min == max) { + return (int) Math.round(min); + } + + double noise = getHeight(rx, rz, superSeed); + + return (int) Math.round(IrisInterpolation.lerp(min, max, noise)); + } + + public double fitDouble(double min, double max, long superSeed, double rx, double rz) { + if (min == max) { + return min; + } + + double noise = getHeight(rx, rz, superSeed); + + return IrisInterpolation.lerp(min, max, noise); + } + + public double getHeight(double rx, double rz, long superSeed) { + return getHeight(rx, 0, rz, superSeed); + } + + public double getHeight(double rx, double ry, double rz, long superSeed) { + if (composite.isEmpty()) { Iris.warn("Useless Generator: Composite is empty in " + getLoadKey()); return 0; } @@ -126,17 +228,16 @@ public class IrisGenerator extends IrisRegistrant double h = 0; double tp = 0; - for(IrisNoiseGenerator i : composite) - { + for (IrisNoiseGenerator i : composite) { tp += i.getOpacity(); h += i.getNoise(seed + superSeed + hc, (rx + offsetX) / zoom, (rz + offsetZ) / zoom); } double v = (h / tp) * opacity; - if(Double.isNaN(v)) - { - Iris.warn("Nan value on gen: " + getLoadKey() + ": H = " + h + " TP = " + tp + " OPACITY = " + opacity + " ZOOM = " + zoom); + if (Double.isNaN(v)) { + Iris.warn("Nan value on gen: " + getLoadKey() + ": H = " + h + " TP = " + tp + " OPACITY = " + opacity + + " ZOOM = " + zoom); } v = hasCliffs() ? cliff(rx, rz, v, superSeed + 294596 + hc) : v; @@ -145,27 +246,30 @@ public class IrisGenerator extends IrisRegistrant return v; } - public double cell(double rx, double rz, double v, double superSeed) - { + public double cell(double rx, double rz, double v, double superSeed) { getCellGenerator(seed + 46222).setShuffle(getCellFractureShuffle()); - return getCellGenerator(seed + 46222).getDistance(rx / getCellFractureZoom(), rz / getCellFractureZoom()) > getCellPercentSize() ? (v * getCellFractureHeight()) : v; + return getCellGenerator(seed + 46222).getDistance(rx / getCellFractureZoom(), + rz / getCellFractureZoom()) > getCellPercentSize() ? (v * getCellFractureHeight()) : v; } - private boolean hasCellCracks() - { + private boolean hasCellCracks() { return getCellFractureHeight() != 0; } - public double getCliffHeight(double rx, double rz, double superSeed) - { + public double getCliffHeight(double rx, double rz, double superSeed) { int hc = (int) ((cliffHeightMin * 10) + 10 + cliffHeightMax + interpolationScale * seed + offsetX + offsetZ); - double h = cliffHeightGenerator.getNoise((long) (seed + superSeed + hc), (rx + offsetX) / zoom, (rz + offsetZ) / zoom); + double h = cliffHeightGenerator.getNoise((long) (seed + superSeed + hc), (rx + offsetX) / zoom, + (rz + offsetZ) / zoom); return IrisInterpolation.lerp(cliffHeightMin, cliffHeightMax, h); } - public double cliff(double rx, double rz, double v, double superSeed) - { + public double cliff(double rx, double rz, double v, double superSeed) { double cliffHeight = getCliffHeight(rx, rz, superSeed - 34857); return (Math.round((v * 255D) / cliffHeight) * cliffHeight) / 255D; } + + public IrisGenerator rescale(double scale) { + zoom /= scale; + return this; + } } diff --git a/src/main/java/com/volmit/iris/object/IrisGeneratorStyle.java b/src/main/java/com/volmit/iris/object/IrisGeneratorStyle.java new file mode 100644 index 000000000..6cc8c9c96 --- /dev/null +++ b/src/main/java/com/volmit/iris/object/IrisGeneratorStyle.java @@ -0,0 +1,64 @@ +package com.volmit.iris.object; + +import com.volmit.iris.gen.atomics.AtomicCache; +import com.volmit.iris.noise.CNG; +import com.volmit.iris.util.Desc; +import com.volmit.iris.util.DontObfuscate; +import com.volmit.iris.util.MaxNumber; +import com.volmit.iris.util.MinNumber; +import com.volmit.iris.util.RNG; +import com.volmit.iris.util.Required; + +import lombok.Data; + +@Desc("A gen style") +@Data +public class IrisGeneratorStyle { + + @Required + @DontObfuscate + @Desc("The chance is 1 in CHANCE per interval") + private NoiseStyle style = NoiseStyle.IRIS; + + @DontObfuscate + @MinNumber(0.00001) + @Desc("The zoom of this style") + private double zoom = 1; + + @DontObfuscate + @MinNumber(0.00001) + @Desc("The Output multiplier. Only used if parent is fracture.") + private double multiplier = 1; + + @DontObfuscate + @Desc("Apply a generator to the coordinate field fed into this parent generator. I.e. Distort your generator with another generator.") + private IrisGeneratorStyle fracture = null; + + @DontObfuscate + @MinNumber(0.01562) + @MaxNumber(64) + @Desc("The exponent") + private double exponent = 1; + + private final transient AtomicCache cng = new AtomicCache(); + + public IrisGeneratorStyle() { + + } + + public IrisGeneratorStyle(NoiseStyle s) { + this.style = s; + } + + public CNG create(RNG rng) { + return cng.aquire(() -> { + CNG cng = style.create(rng).bake().scale(1D / zoom).pow(exponent).bake(); + + if (fracture != null) { + cng.fractureWith(fracture.create(rng.nextParallelRNG(2934)), fracture.getMultiplier()); + } + + return cng; + }); + } +} diff --git a/src/main/java/com/volmit/iris/object/IrisNoiseGenerator.java b/src/main/java/com/volmit/iris/object/IrisNoiseGenerator.java index 1d22f15ea..ef26ac602 100644 --- a/src/main/java/com/volmit/iris/object/IrisNoiseGenerator.java +++ b/src/main/java/com/volmit/iris/object/IrisNoiseGenerator.java @@ -71,7 +71,7 @@ public class IrisNoiseGenerator @Required @DontObfuscate @Desc("The Noise Style") - private NoiseStyle style = NoiseStyle.IRIS; + private IrisGeneratorStyle style = NoiseStyle.IRIS.style(); @MinNumber(1) @DontObfuscate diff --git a/src/main/java/com/volmit/iris/object/IrisStructure.java b/src/main/java/com/volmit/iris/object/IrisStructure.java index 7a22cd6e5..8a77cd011 100644 --- a/src/main/java/com/volmit/iris/object/IrisStructure.java +++ b/src/main/java/com/volmit/iris/object/IrisStructure.java @@ -19,8 +19,7 @@ import lombok.EqualsAndHashCode; @Desc("Represents a structure in iris.") @Data @EqualsAndHashCode(callSuper = false) -public class IrisStructure extends IrisRegistrant -{ +public class IrisStructure extends IrisRegistrant { @MinNumber(2) @Required @DontObfuscate @@ -66,46 +65,37 @@ public class IrisStructure extends IrisRegistrant private transient AtomicCache wallGenerator = new AtomicCache<>(); - public TileResult getTile(RNG rng, double x, double y, double z) - { + public TileResult getTile(RNG rng, double x, double y, double z) { KList walls = new KList<>(); boolean floor = isWall(rng, x, y, z, StructureTileFace.DOWN); boolean ceiling = isWall(rng, x, y, z, StructureTileFace.UP); - if(isWall(rng, x, y, z, StructureTileFace.NORTH)) - { + if (isWall(rng, x, y, z, StructureTileFace.NORTH)) { walls.add(StructureTileFace.NORTH); } - if(isWall(rng, x, y, z, StructureTileFace.SOUTH)) - { + if (isWall(rng, x, y, z, StructureTileFace.SOUTH)) { walls.add(StructureTileFace.SOUTH); } - if(isWall(rng, x, y, z, StructureTileFace.EAST)) - { + if (isWall(rng, x, y, z, StructureTileFace.EAST)) { walls.add(StructureTileFace.EAST); } - if(isWall(rng, x, y, z, StructureTileFace.WEST)) - { + if (isWall(rng, x, y, z, StructureTileFace.WEST)) { walls.add(StructureTileFace.WEST); } int rt = 0; - for(int cx = 0; cx < 4; cx++) - { - for(IrisStructureTile i : tiles) - { - if(i.likeAGlove(floor, ceiling, walls)) - { + for (int cx = 0; cx < 4; cx++) { + for (IrisStructureTile i : tiles) { + if (i.likeAGlove(floor, ceiling, walls)) { return new TileResult(i, rt); } } - if(cx < 3) - { + if (cx < 3) { rotate(walls); rt += 90; } @@ -114,18 +104,14 @@ public class IrisStructure extends IrisRegistrant return null; } - public void rotate(KList faces) - { - for(int i = 0; i < faces.size(); i++) - { + public void rotate(KList faces) { + for (int i = 0; i < faces.size(); i++) { faces.set(i, faces.get(i).rotate90CW()); } } - public boolean isWall(RNG rng, double x, double y, double z, StructureTileFace face) - { - if((face == StructureTileFace.DOWN || face == StructureTileFace.UP) && maxLayers == 1) - { + public boolean isWall(RNG rng, double x, double y, double z, StructureTileFace face) { + if ((face == StructureTileFace.DOWN || face == StructureTileFace.UP) && maxLayers == 1) { return true; } @@ -133,30 +119,25 @@ public class IrisStructure extends IrisRegistrant return (getWallGenerator(rng).fitDouble(0, 1, p.getX(), p.getY(), p.getZ()) < getWallChance()); } - public int getTileHorizon(double v) - { + public int getTileHorizon(double v) { return (int) Math.floor(v / gridSize); } - public BlockPosition asTileHorizon(BlockPosition b, StructureTileFace face) - { + public BlockPosition asTileHorizon(BlockPosition b, StructureTileFace face) { b.setX((int) (Math.floor((b.getX() * 2) / gridSize) + face.x())); b.setY((int) (Math.floor((b.getY() * 2) / gridHeight) + face.y())); b.setZ((int) (Math.floor((b.getZ() * 2) / gridSize) + face.z())); return b; } - public CNG getWallGenerator(RNG rng) - { - return wallGenerator.aquire(() -> - { + public CNG getWallGenerator(RNG rng) { + return wallGenerator.aquire(() -> { RNG rngx = rng.nextParallelRNG((int) (name.hashCode() + gridHeight - gridSize + maxLayers + tiles.size())); return CNG.signature(rngx).scale(0.8); }); } - public IrisStructure() - { + public IrisStructure() { } } diff --git a/src/main/java/com/volmit/iris/object/NoiseStyle.java b/src/main/java/com/volmit/iris/object/NoiseStyle.java index 79c308ade..88afc63c9 100644 --- a/src/main/java/com/volmit/iris/object/NoiseStyle.java +++ b/src/main/java/com/volmit/iris/object/NoiseStyle.java @@ -391,7 +391,7 @@ public enum NoiseStyle { @Desc("Vascular noise gets higher as the position nears a cell border.") @DontObfuscate VASCULAR(rng -> new CNG(rng, NoiseType.VASCULAR, 1D, 1)), - + @Desc("It always returns 0.5") @DontObfuscate FLAT(rng -> new CNG(rng, NoiseType.FLAT, 1D, 1)), @@ -422,4 +422,8 @@ public enum NoiseStyle { public CNG create(RNG seed) { return f.create(seed).bake(); } + + public IrisGeneratorStyle style() { + return new IrisGeneratorStyle(this); + } }