From cf3d92d6e1f3ef744cf74faa93aab1d580ed80e4 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Fri, 27 Aug 2021 09:53:25 -0400 Subject: [PATCH] CAVES AND MORE --- .../volmit/iris/engine/IrisEngineMantle.java | 3 +- .../iris/engine/mantle/MantleWriter.java | 78 +++++---------- .../components/MantleCarvingComponent.java | 2 +- .../engine/object/basic/IrisPosition.java | 8 ++ .../engine/object/carving/IrisCarving.java | 66 ++++++++++++- .../iris/engine/object/carving/IrisCave.java | 43 ++++---- .../engine/object/carving/IrisCavePlacer.java | 39 +++++--- .../engine/object/carving/IrisElipsoid.java | 66 +++++++++++++ .../engine/object/carving/IrisPyramid.java | 58 +++++++++++ .../engine/object/carving/IrisSphere.java | 57 +++++++++++ .../object/noise/IrisGeneratorStyle.java | 44 +++++---- .../engine/object/noise/IrisStyledRange.java | 4 + .../iris/engine/object/noise/IrisWorm.java | 99 ++++++++++++++----- .../java/com/volmit/iris/util/noise/CNG.java | 5 + .../java/com/volmit/iris/util/noise/Worm.java | 40 -------- .../com/volmit/iris/util/noise/Worm2.java | 46 --------- .../com/volmit/iris/util/noise/Worm3.java | 50 ---------- .../volmit/iris/util/noise/WormIterator2.java | 54 ---------- .../volmit/iris/util/noise/WormIterator3.java | 65 ------------ 19 files changed, 431 insertions(+), 396 deletions(-) create mode 100644 src/main/java/com/volmit/iris/engine/object/carving/IrisElipsoid.java create mode 100644 src/main/java/com/volmit/iris/engine/object/carving/IrisPyramid.java create mode 100644 src/main/java/com/volmit/iris/engine/object/carving/IrisSphere.java delete mode 100644 src/main/java/com/volmit/iris/util/noise/Worm.java delete mode 100644 src/main/java/com/volmit/iris/util/noise/Worm2.java delete mode 100644 src/main/java/com/volmit/iris/util/noise/Worm3.java delete mode 100644 src/main/java/com/volmit/iris/util/noise/WormIterator2.java delete mode 100644 src/main/java/com/volmit/iris/util/noise/WormIterator3.java diff --git a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java index f3365893d..894c9d561 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java @@ -23,6 +23,7 @@ import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.mantle.EngineMantle; import com.volmit.iris.engine.mantle.MantleComponent; +import com.volmit.iris.engine.mantle.components.MantleCarvingComponent; import com.volmit.iris.engine.mantle.components.MantleFeatureComponent; import com.volmit.iris.engine.mantle.components.MantleJigsawComponent; import com.volmit.iris.engine.mantle.components.MantleObjectComponent; @@ -62,6 +63,7 @@ public class IrisEngineMantle implements EngineMantle { this.mantle = new Mantle(new File(engine.getWorld().worldFolder(), "mantle"), engine.getTarget().getHeight()); radius = radCache.aquire(this::computeParallaxSize); components = new KList<>(); + registerComponent(new MantleCarvingComponent(this)); registerComponent(new MantleFeatureComponent(this)); registerComponent(new MantleJigsawComponent(this)); registerComponent(new MantleObjectComponent(this)); @@ -175,7 +177,6 @@ public class IrisEngineMantle implements EngineMantle { jig = Math.max(jig, getData().getJigsawStructureLoader().load(getEngine().getDimension().getStronghold()).getMaxDimension()); } catch (Throwable e) { Iris.reportError(e); - Iris.error("THIS IS THE ONE"); e.printStackTrace(); } } diff --git a/src/main/java/com/volmit/iris/engine/mantle/MantleWriter.java b/src/main/java/com/volmit/iris/engine/mantle/MantleWriter.java index 1f9c6bba6..95780ea38 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/MantleWriter.java +++ b/src/main/java/com/volmit/iris/engine/mantle/MantleWriter.java @@ -26,12 +26,14 @@ import com.volmit.iris.engine.object.basic.IrisPosition; import com.volmit.iris.engine.object.common.IObjectPlacer; import com.volmit.iris.engine.object.feature.IrisFeaturePositional; import com.volmit.iris.engine.object.tile.TileData; +import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.mantle.Mantle; import com.volmit.iris.util.mantle.MantleChunk; import com.volmit.iris.util.math.INode; import com.volmit.iris.util.math.KochanekBartelsInterpolation; +import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.PathInterpolation; import com.volmit.iris.util.matter.Matter; import lombok.Data; @@ -91,8 +93,6 @@ public class MantleWriter implements IObjectPlacer { Matter matter = chunk.getOrCreate(y >> 4); matter.slice(matter.getClass(t)).set(x & 15, y & 15, z & 15, t); } - } else { - Iris.error("Mantle Writer[" + this.x + "," + this.z + ",R" + this.radius + "] Tried to access " + x + "," + y + "," + z + " (Chunk " + cx + "," + cz + ") which is OUT OF BOUNDS!"); } } @@ -284,59 +284,6 @@ public class MantleWriter implements IObjectPlacer { } } - /** - * Set a 3d tube spline interpolated with Kochanek Bartels - * - * @param nodevectors the vector points - * @param radius the radius - * @param filled if it should be filled or hollow - * @param data the data to set - */ - public void setSpline(List nodevectors, double radius, boolean filled, T data) { - setSpline(nodevectors, 0, 0, 0, 10, radius, filled, data); - } - - /** - * Set a 3d tube spline interpolated with Kochanek Bartels - * - * @param nodevectors the spline points - * @param tension the tension 0 - * @param bias the bias 0 - * @param continuity the continuity 0 - * @param quality the quality 10 - * @param radius the radius - * @param filled filled or hollow - * @param data the data to set - * @param the type of data to apply to the mantle - */ - public void setSpline(List nodevectors, double tension, double bias, double continuity, double quality, double radius, boolean filled, T data) { - Set vset = new KSet<>(); - List nodes = new ArrayList<>(nodevectors.size()); - PathInterpolation interpol = new KochanekBartelsInterpolation(); - - for (Vector nodevector : nodevectors) { - INode n = new INode(nodevector); - n.setTension(tension); - n.setBias(bias); - n.setContinuity(continuity); - nodes.add(n); - } - - interpol.setNodes(nodes); - double splinelength = interpol.arcLength(0, 1); - for (double loop = 0; loop <= 1; loop += 1D / splinelength / quality) { - Vector tipv = interpol.getPosition(loop); - vset.add(new IrisPosition(tipv.toBlockVector())); - } - - vset = getBallooned(vset, radius); - if (!filled) { - vset = getHollowed(vset); - } - - set(vset, data); - } - /** * Set a 3d line * @@ -577,4 +524,25 @@ public class MantleWriter implements IObjectPlacer { private static double lengthSq(double x, double z) { return (x * x) + (z * z); } + + public boolean isWithin(Vector pos) { + return isWithin(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()); + } + + public boolean isWithin(int x, int y, int z) + { + int cx = x >> 4; + int cz = z >> 4; + + if (y < 0 || y >= mantle.getWorldHeight()) { + return false; + } + + if (cx >= this.x - radius && cx <= this.x + radius + && cz >= this.z - radius && cz <= this.z + radius) { + return true; + } + + return false; + } } diff --git a/src/main/java/com/volmit/iris/engine/mantle/components/MantleCarvingComponent.java b/src/main/java/com/volmit/iris/engine/mantle/components/MantleCarvingComponent.java index 208fc27d2..d8b618c2a 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/components/MantleCarvingComponent.java +++ b/src/main/java/com/volmit/iris/engine/mantle/components/MantleCarvingComponent.java @@ -58,6 +58,6 @@ public class MantleCarvingComponent extends IrisMantleComponent { @ChunkCoordinates private void carve(IrisCarving carving, MantleWriter writer, RNG rng, int cx, int cz) { - carving.doCarving(writer, rng, getEngineMantle().getEngine(), cx << 4, cz << 4); + carving.doCarving(writer, rng, getEngineMantle().getEngine(), cx << 4, -1, cz << 4); } } diff --git a/src/main/java/com/volmit/iris/engine/object/basic/IrisPosition.java b/src/main/java/com/volmit/iris/engine/object/basic/IrisPosition.java index 6e2d9deea..75d44ce6f 100644 --- a/src/main/java/com/volmit/iris/engine/object/basic/IrisPosition.java +++ b/src/main/java/com/volmit/iris/engine/object/basic/IrisPosition.java @@ -80,4 +80,12 @@ public class IrisPosition { public String toString() { return "[" + getX() + "," + getY() + "," + getZ() + "]"; } + + public boolean isLongerThan(IrisPosition s, int maxLength) { + return Math.abs(Math.pow(s.x - x,2) + Math.pow(s.y - y,2) + Math.pow(s.z - z,2)) > maxLength * maxLength; + } + + public Vector toVector() { + return new Vector(x, y, z); + } } diff --git a/src/main/java/com/volmit/iris/engine/object/carving/IrisCarving.java b/src/main/java/com/volmit/iris/engine/object/carving/IrisCarving.java index a38194edc..ba558fa8e 100644 --- a/src/main/java/com/volmit/iris/engine/object/carving/IrisCarving.java +++ b/src/main/java/com/volmit/iris/engine/object/carving/IrisCarving.java @@ -41,13 +41,60 @@ public class IrisCarving { @Desc("Define cave placers") private KList caves = new KList<>(); + @ArrayType(type = IrisElipsoid.class, min = 1) + @Desc("Define elipsoids") + private KList elipsoids = new KList<>(); + + @ArrayType(type = IrisSphere.class, min = 1) + @Desc("Define spheres") + private KList spheres = new KList<>(); + + @ArrayType(type = IrisPyramid.class, min = 1) + @Desc("Define pyramids") + private KList pyramids = new KList<>(); + + + @BlockCoordinates - public void doCarving(MantleWriter writer, RNG rng, Engine engine, int x, int z) { + public void doCarving(MantleWriter writer, RNG rng, Engine engine, int x, int y, int z) { if(caves.isNotEmpty()) { for(IrisCavePlacer i : caves) { - i.generateCave(writer, rng, engine, x, z); + i.generateCave(writer, rng, engine, x, y, z); + } + } + + if(spheres.isNotEmpty()) + { + for(IrisSphere i : spheres) + { + if(rng.nextInt(i.getRarity()) == 0) + { + i.generate(rng, engine, writer, x, y, z); + } + } + } + + if(elipsoids.isNotEmpty()) + { + for(IrisElipsoid i : elipsoids) + { + if(rng.nextInt(i.getRarity()) == 0) + { + i.generate(rng, engine, writer, x, y, z); + } + } + } + + if(pyramids.isNotEmpty()) + { + for(IrisPyramid i : pyramids) + { + if(rng.nextInt(i.getRarity()) == 0) + { + i.generate(rng, engine, writer, x, y, z); + } } } } @@ -60,6 +107,21 @@ public class IrisCarving { max = Math.max(max, i.getSize(data)); } + if(elipsoids.isNotEmpty()) + { + max = (int) Math.max(elipsoids.stream().mapToDouble(IrisElipsoid::maxSize).max().getAsDouble(), max); + } + + if(spheres.isNotEmpty()) + { + max = (int) Math.max(spheres.stream().mapToDouble(IrisSphere::maxSize).max().getAsDouble(), max); + } + + if(pyramids.isNotEmpty()) + { + max = (int) Math.max(pyramids.stream().mapToDouble(IrisPyramid::maxSize).max().getAsDouble(), max); + } + return max; } } diff --git a/src/main/java/com/volmit/iris/engine/object/carving/IrisCave.java b/src/main/java/com/volmit/iris/engine/object/carving/IrisCave.java index 97d4a7d9c..4d5e8e6d8 100644 --- a/src/main/java/com/volmit/iris/engine/object/carving/IrisCave.java +++ b/src/main/java/com/volmit/iris/engine/object/carving/IrisCave.java @@ -25,13 +25,14 @@ import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.mantle.MantleWriter; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.basic.IrisPosition; +import com.volmit.iris.engine.object.basic.IrisRange; +import com.volmit.iris.engine.object.block.IrisBlockData; import com.volmit.iris.engine.object.noise.IrisWorm; +import com.volmit.iris.engine.object.objects.IrisObjectLimit; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.data.B; import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.math.RNG; -import com.volmit.iris.util.noise.Worm3; -import com.volmit.iris.util.noise.WormIterator3; import com.volmit.iris.util.plugin.VolmitSender; import lombok.AllArgsConstructor; import lombok.Data; @@ -39,7 +40,8 @@ import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; import org.bukkit.block.data.BlockData; -import org.bukkit.util.Vector; + +import java.util.List; @EqualsAndHashCode(callSuper = true) @Accessors(chain = true) @@ -48,10 +50,18 @@ import org.bukkit.util.Vector; @Desc("Translate objects") @Data public class IrisCave extends IrisRegistrant { - private static final BlockData CAVE_AIR = B.get("CAVE_AIR"); @Desc("Define the shape of this cave") private IrisWorm worm; + @Desc("Define potential forking features") + private IrisCarving fork = new IrisCarving(); + + @Desc("Change the air block to fill worms with as caves") + private IrisBlockData fill = new IrisBlockData("cave_air"); + + @Desc("Limit the worm from ever getting higher or lower than this range") + private IrisRange verticalRange = new IrisRange(3, 255); + @Override public String getFolderName() { return "caves"; @@ -64,27 +74,18 @@ public class IrisCave extends IrisRegistrant { public void generate(MantleWriter writer, RNG rng, Engine engine, int x, int y, int z) { - IrisData data = engine.getData(); - WormIterator3 w = getWorm().iterate3D(rng, data, x, y, z); - KList points = new KList<>(); - int itr = 0; - while (w.hasNext()) { - itr++; - Worm3 wx = w.next(); - points.add(new Vector(wx.getX().getPosition(), wx.getY().getPosition(), wx.getZ().getPosition())); - } - - - Iris.info(x + " " + y + " " + z + " /." + " POS: " + points.convert((i) -> "[" + i.getBlockX() + "," + i.getBlockY() + "," + i.getBlockZ() + "]").toString(", ")); - - writer.setLine(points.convert(IrisPosition::new), getWorm().getGirth().get(rng, x, z, data), true, CAVE_AIR); - - - // TODO decorate somehow + writer.setLine(getWorm().generate(rng, engine.getData(), writer, verticalRange, x, y, z, + (at) -> fork.doCarving(writer, rng, engine, at.getX(), at.getY(), at.getZ())), + getWorm().getGirth().get(rng, x, z, engine.getData()), true, + fill.getBlockData(engine.getData())); } @Override public void scanForErrors(JSONObject p, VolmitSender sender) { } + + public int getMaxSize(IrisData data) { + return getWorm().getMaxDistance() + fork.getMaxRange(data); + } } diff --git a/src/main/java/com/volmit/iris/engine/object/carving/IrisCavePlacer.java b/src/main/java/com/volmit/iris/engine/object/carving/IrisCavePlacer.java index 6840f4085..7adfa0e04 100644 --- a/src/main/java/com/volmit/iris/engine/object/carving/IrisCavePlacer.java +++ b/src/main/java/com/volmit/iris/engine/object/carving/IrisCavePlacer.java @@ -27,23 +27,15 @@ import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.MinNumber; import com.volmit.iris.engine.object.annotations.RegistryListResource; import com.volmit.iris.engine.object.annotations.Required; -import com.volmit.iris.engine.object.basic.IrisPosition; import com.volmit.iris.engine.object.common.IRare; import com.volmit.iris.engine.object.noise.IrisGeneratorStyle; import com.volmit.iris.engine.object.noise.IrisStyledRange; import com.volmit.iris.engine.object.noise.NoiseStyle; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.data.B; -import com.volmit.iris.util.mantle.Mantle; import com.volmit.iris.util.math.RNG; -import com.volmit.iris.util.noise.Worm3; -import com.volmit.iris.util.noise.WormIterator3; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; -import org.bukkit.block.data.BlockData; -import org.bukkit.util.Vector; import java.util.concurrent.atomic.AtomicBoolean; @@ -54,7 +46,7 @@ import java.util.concurrent.atomic.AtomicBoolean; @Data public class IrisCavePlacer implements IRare { @Required - @Desc("Typically a 1 in RARITY on a per chunk basis") + @Desc("Typically a 1 in RARITY on a per chunk/fork basis") @MinNumber(1) private int rarity = 15; @@ -77,11 +69,16 @@ public class IrisCavePlacer implements IRare { return caveCache.aquire(() -> data.getCaveLoader().load(getCave())); } - public void generateCave(MantleWriter mantle, RNG rng, Engine engine, int x, int z) { + public void generateCave(MantleWriter mantle, RNG rng, Engine engine, int x, int y, int z) { if (fail.get()) { return; } + if(rng.nextInt(rarity) != 0) + { + return; + } + IrisData data = engine.getData(); IrisCave cave = getRealCave(data); @@ -91,12 +88,26 @@ public class IrisCavePlacer implements IRare { return; } - int h = (int) caveStartHeight.get(rng,x, z,data); - int ma = (int) (engine.getComplex().getHeightStream().get(x, z) - 9); - cave.generate(mantle, rng, engine, x, Math.min(h, ma), z); + if(y == -1) + { + int h = (int) caveStartHeight.get(rng,x, z,data); + int ma = breakSurface ? h : (int) (engine.getComplex().getHeightStream().get(x, z) - 9); + y = Math.min(h, ma); + } + + try + { + cave.generate(mantle, rng, engine, x + rng.nextInt(15), y, z + rng.nextInt(15)); + } + + catch(Throwable e) + { + e.printStackTrace(); + fail.set(true); + } } public int getSize(IrisData data) { - return getRealCave(data).getWorm().getMaxDistance(); + return getRealCave(data).getMaxSize(data); } } diff --git a/src/main/java/com/volmit/iris/engine/object/carving/IrisElipsoid.java b/src/main/java/com/volmit/iris/engine/object/carving/IrisElipsoid.java new file mode 100644 index 000000000..4aec740bd --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/carving/IrisElipsoid.java @@ -0,0 +1,66 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.object.carving; + +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.mantle.MantleWriter; +import com.volmit.iris.engine.object.annotations.Desc; +import com.volmit.iris.engine.object.annotations.MinNumber; +import com.volmit.iris.engine.object.annotations.Required; +import com.volmit.iris.engine.object.block.IrisBlockData; +import com.volmit.iris.engine.object.common.IRare; +import com.volmit.iris.engine.object.noise.IrisGeneratorStyle; +import com.volmit.iris.engine.object.noise.IrisStyledRange; +import com.volmit.iris.engine.object.noise.NoiseStyle; +import com.volmit.iris.util.math.RNG; +import lombok.Data; + +@Desc("Represents an procedural eliptical shape") +@Data +public class IrisElipsoid implements IRare +{ + @Required + @Desc("Typically a 1 in RARITY on a per fork basis") + @MinNumber(1) + private int rarity = 1; + + @Desc("Change the air block to fill elipsoids with as caves") + private IrisBlockData fill = new IrisBlockData("cave_air"); + + @Desc("The styled random radius for x") + private IrisStyledRange xRadius = new IrisStyledRange(1, 5, new IrisGeneratorStyle(NoiseStyle.STATIC)); + + @Desc("The styled random radius for y") + private IrisStyledRange yRadius = new IrisStyledRange(1, 5, new IrisGeneratorStyle(NoiseStyle.STATIC)); + + @Desc("The styled random radius for z") + private IrisStyledRange zRadius = new IrisStyledRange(1, 5, new IrisGeneratorStyle(NoiseStyle.STATIC)); + + public void generate(RNG rng, Engine engine, MantleWriter writer, int x, int y, int z) + { + writer.setElipsoid(x, y, z, + xRadius.get(rng, z, y, engine.getData()), + yRadius.get(rng, x, z, engine.getData()), + zRadius.get(rng, y, x, engine.getData()), true, fill.getBlockData(engine.getData())); + } + + public double maxSize() { + return Math.max(xRadius.getMax(), Math.max(yRadius.getMax(), zRadius.getMax())); + } +} diff --git a/src/main/java/com/volmit/iris/engine/object/carving/IrisPyramid.java b/src/main/java/com/volmit/iris/engine/object/carving/IrisPyramid.java new file mode 100644 index 000000000..15eb5cff3 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/carving/IrisPyramid.java @@ -0,0 +1,58 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.object.carving; + +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.mantle.MantleWriter; +import com.volmit.iris.engine.object.annotations.Desc; +import com.volmit.iris.engine.object.annotations.MinNumber; +import com.volmit.iris.engine.object.annotations.Required; +import com.volmit.iris.engine.object.block.IrisBlockData; +import com.volmit.iris.engine.object.common.IRare; +import com.volmit.iris.engine.object.noise.IrisGeneratorStyle; +import com.volmit.iris.engine.object.noise.IrisStyledRange; +import com.volmit.iris.engine.object.noise.NoiseStyle; +import com.volmit.iris.util.math.RNG; +import lombok.Data; + +@Desc("Represents an procedural eliptical shape") +@Data +public class IrisPyramid implements IRare +{ + @Required + @Desc("Typically a 1 in RARITY on a per fork basis") + @MinNumber(1) + private int rarity = 1; + + @Desc("Change the air block to fill elipsoids with as caves") + private IrisBlockData fill = new IrisBlockData("cave_air"); + + @Desc("The styled random radius for x") + private IrisStyledRange baseWidth = new IrisStyledRange(1, 5, new IrisGeneratorStyle(NoiseStyle.STATIC)); + + public void generate(RNG rng, Engine engine, MantleWriter writer, int x, int y, int z) + { + writer.setPyramid(x, y, z, fill.getBlockData(engine.getData()), + (int)baseWidth.get(rng, z, y, engine.getData()), true); + } + + public double maxSize() { + return baseWidth.getMax(); + } +} diff --git a/src/main/java/com/volmit/iris/engine/object/carving/IrisSphere.java b/src/main/java/com/volmit/iris/engine/object/carving/IrisSphere.java new file mode 100644 index 000000000..3bd932e65 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/carving/IrisSphere.java @@ -0,0 +1,57 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.object.carving; + +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.mantle.MantleWriter; +import com.volmit.iris.engine.object.annotations.Desc; +import com.volmit.iris.engine.object.annotations.MinNumber; +import com.volmit.iris.engine.object.annotations.Required; +import com.volmit.iris.engine.object.block.IrisBlockData; +import com.volmit.iris.engine.object.common.IRare; +import com.volmit.iris.engine.object.noise.IrisGeneratorStyle; +import com.volmit.iris.engine.object.noise.IrisStyledRange; +import com.volmit.iris.engine.object.noise.NoiseStyle; +import com.volmit.iris.util.math.RNG; +import lombok.Data; + +@Desc("Represents an procedural eliptical shape") +@Data +public class IrisSphere implements IRare +{ + @Required + @Desc("Typically a 1 in RARITY on a per fork basis") + @MinNumber(1) + private int rarity = 1; + + @Desc("Change the air block to fill elipsoids with as caves") + private IrisBlockData fill = new IrisBlockData("cave_air"); + + @Desc("The styled random radius for x") + private IrisStyledRange radius = new IrisStyledRange(1, 5, new IrisGeneratorStyle(NoiseStyle.STATIC)); + + public void generate(RNG rng, Engine engine, MantleWriter writer, int x, int y, int z) + { + writer.setSphere(x, y, z, radius.get(rng, z, y, engine.getData()),true, fill.getBlockData(engine.getData())); + } + + public double maxSize() { + return radius.getMax(); + } +} diff --git a/src/main/java/com/volmit/iris/engine/object/noise/IrisGeneratorStyle.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisGeneratorStyle.java index a1541c2e9..f8dddb9cc 100644 --- a/src/main/java/com/volmit/iris/engine/object/noise/IrisGeneratorStyle.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisGeneratorStyle.java @@ -75,34 +75,36 @@ public class IrisGeneratorStyle { return this; } - public CNG create(RNG rng, IrisData data) { - return cng.aquire(() -> - { - if (getExpression() != null) { - IrisExpression e = data.getExpressionLoader().load(getExpression()); + public CNG createNoCache(RNG rng, IrisData data) + { + if (getExpression() != null) { + IrisExpression e = data.getExpressionLoader().load(getExpression()); - if (e != null) { - CNG cng = new CNG(rng, new ExpressionNoise(rng, e), 1D, 1) - .bake().scale(1D / zoom).pow(exponent).bake(); - cng.setTrueFracturing(axialFracturing); + if (e != null) { + CNG cng = new CNG(rng, new ExpressionNoise(rng, e), 1D, 1) + .bake().scale(1D / zoom).pow(exponent).bake(); + cng.setTrueFracturing(axialFracturing); - if (fracture != null) { - cng.fractureWith(fracture.create(rng.nextParallelRNG(2934), data), fracture.getMultiplier()); - } - - return cng; + if (fracture != null) { + cng.fractureWith(fracture.create(rng.nextParallelRNG(2934), data), fracture.getMultiplier()); } + + return cng; } + } - CNG cng = style.create(rng).bake().scale(1D / zoom).pow(exponent).bake(); - cng.setTrueFracturing(axialFracturing); + CNG cng = style.create(rng).bake().scale(1D / zoom).pow(exponent).bake(); + cng.setTrueFracturing(axialFracturing); - if (fracture != null) { - cng.fractureWith(fracture.create(rng.nextParallelRNG(2934), data), fracture.getMultiplier()); - } + if (fracture != null) { + cng.fractureWith(fracture.create(rng.nextParallelRNG(2934), data), fracture.getMultiplier()); + } - return cng; - }); + return cng; + } + + public CNG create(RNG rng, IrisData data) { + return cng.aquire(() -> createNoCache(rng, data)); } @SuppressWarnings("BooleanMethodIsAlwaysInverted") diff --git a/src/main/java/com/volmit/iris/engine/object/noise/IrisStyledRange.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisStyledRange.java index a9ea677e7..f5a33292f 100644 --- a/src/main/java/com/volmit/iris/engine/object/noise/IrisStyledRange.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisStyledRange.java @@ -59,4 +59,8 @@ public class IrisStyledRange { public ProceduralStream stream(RNG rng, IrisData data) { return ProceduralStream.of((x, z) -> get(rng, x, z, data), Interpolated.DOUBLE); } + + public boolean isFlat() { + return getMax() == getMin() || style.isFlat(); + } } diff --git a/src/main/java/com/volmit/iris/engine/object/noise/IrisWorm.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisWorm.java index c5836f216..fc7e024e7 100644 --- a/src/main/java/com/volmit/iris/engine/object/noise/IrisWorm.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisWorm.java @@ -18,60 +18,107 @@ package com.volmit.iris.engine.object.noise; +import com.volmit.iris.Iris; import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.data.cache.AtomicCache; +import com.volmit.iris.engine.mantle.MantleWriter; import com.volmit.iris.engine.object.annotations.Desc; +import com.volmit.iris.engine.object.basic.IrisPosition; +import com.volmit.iris.engine.object.basic.IrisRange; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.function.NoiseProvider; import com.volmit.iris.util.math.RNG; -import com.volmit.iris.util.noise.WormIterator2; -import com.volmit.iris.util.noise.WormIterator3; +import com.volmit.iris.util.noise.CNG; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; +import java.util.function.Consumer; + @Accessors(chain = true) @NoArgsConstructor @AllArgsConstructor @Desc("Generate worms") @Data public class IrisWorm { - @Desc("The style used to determine the curvature of this worm") - private IrisGeneratorStyle angleStyle = new IrisGeneratorStyle(NoiseStyle.PERLIN); + @Desc("The style used to determine the curvature of this worm's x") + private IrisShapedGeneratorStyle xStyle = new IrisShapedGeneratorStyle(NoiseStyle.PERLIN, -2, 2); + + @Desc("The style used to determine the curvature of this worm's y") + private IrisShapedGeneratorStyle yStyle = new IrisShapedGeneratorStyle(NoiseStyle.PERLIN, -2, 2); + + @Desc("The style used to determine the curvature of this worm's z") + private IrisShapedGeneratorStyle zStyle = new IrisShapedGeneratorStyle(NoiseStyle.PERLIN, -2, 2); @Desc("The max block distance this worm can travel from its start. This can have performance implications at ranges over 1,000 blocks but it's not too serious, test.") private int maxDistance = 128; - @Desc("The max segments, or iterations this worm can execute on. Setting this to -1 will allow it to run up to the maxDistance's value of iterations (default)") - private int maxSegments = -1; + @Desc("The iterations this worm can make") + private int maxIterations = 512; - @Desc("The distance between segments") - private IrisStyledRange segmentDistance = new IrisStyledRange().setMin(4).setMax(7) - .setStyle(new IrisGeneratorStyle(NoiseStyle.PERLIN)); + @Desc("By default if a worm loops back into itself, it stops at that point and does not continue. This is an optimization, to prevent this turn this option on.") + private boolean allowLoops = false; @Desc("The thickness of the worms. Each individual worm has the same thickness while traveling however, each spawned worm will vary in thickness.") private IrisStyledRange girth = new IrisStyledRange().setMin(3).setMax(5) .setStyle(new IrisGeneratorStyle(NoiseStyle.PERLIN)); - private transient final AtomicCache angleProviderCache = new AtomicCache<>(); + public KList generate(RNG rng, IrisData data, MantleWriter writer, IrisRange verticalRange, int x, int y, int z, Consumer fork) + { + int itr = maxIterations; + double jx, jy, jz; + double cx = x; + double cy = y; + double cz = z; + IrisPosition start = new IrisPosition(x, y, z); + KList pos = new KList<>(); + KSet check = allowLoops ? null : new KSet<>(); + CNG gx = xStyle.getGenerator().createNoCache(new RNG(rng.lmax()), data); + CNG gy = xStyle.getGenerator().createNoCache(new RNG(rng.lmax()), data); + CNG gz = xStyle.getGenerator().createNoCache(new RNG(rng.lmax()), data); - public NoiseProvider getAngleProvider(RNG rng, IrisData data) { - return angleProviderCache.aquire(() -> (xx, zz) -> angleStyle.create(rng, data).fitDouble(-0.5, 0.5, xx, zz) * segmentDistance.get(rng, xx, zz, data)); - } + while(itr-- > 0) + { + IrisPosition current = new IrisPosition(Math.round(cx), Math.round(cy), Math.round(cz)); + fork.accept(current); + pos.add(current); - public WormIterator2 iterate2D(RNG rng, IrisData data, int x, int z) { - return WormIterator2.builder() - .maxDistance(maxDistance) - .maxIterations(maxSegments == -1 ? maxDistance : maxSegments) - .noise(getAngleProvider(rng, data)).x(x).z(z) - .build(); - } + if(check != null) + { + check.add(current); + } - public WormIterator3 iterate3D(RNG rng, IrisData data, int x, int y, int z) { - return WormIterator3.builder() - .maxDistance(maxDistance) - .maxIterations(maxSegments == -1 ? maxDistance : maxSegments) - .noise(getAngleProvider(rng, data)).x(x).z(z).y(y) - .build(); + jx = gx.fitDouble(xStyle.getMin(), xStyle.getMax(), cx, cy, cz); + jy = gy.fitDouble(yStyle.getMin(), yStyle.getMax(), cx, cy, cz); + jz = gz.fitDouble(zStyle.getMin(), zStyle.getMax(), cx, cy, cz); + cx += jx; + cy += jy; + cz += jz; + IrisPosition next = new IrisPosition(Math.round(cx), Math.round(cy), Math.round(cz)); + + if(!verticalRange.contains(next.getY())) + { + break; + } + + if(!writer.isWithin((int)Math.round(cx), (int)Math.round(cy), (int)Math.round(cz))) + { + break; + } + + if(next.isLongerThan(start, maxDistance)) + { + break; + } + + if(check != null && check.contains(next)) + { + break; + } + } + + return pos; } } diff --git a/src/main/java/com/volmit/iris/util/noise/CNG.java b/src/main/java/com/volmit/iris/util/noise/CNG.java index fe8c39c7f..9d9253626 100644 --- a/src/main/java/com/volmit/iris/util/noise/CNG.java +++ b/src/main/java/com/volmit/iris/util/noise/CNG.java @@ -388,6 +388,11 @@ public class CNG { return noise(dim); } + public double noiseSym(double... dim) + { + return (noise(dim) * 2) - 1; + } + public double noise(double... dim) { double n = getNoise(dim); n = power != 1D ? (n < 0 ? -Math.pow(Math.abs(n), power) : Math.pow(n, power)) : n; diff --git a/src/main/java/com/volmit/iris/util/noise/Worm.java b/src/main/java/com/volmit/iris/util/noise/Worm.java deleted file mode 100644 index 02ef9449a..000000000 --- a/src/main/java/com/volmit/iris/util/noise/Worm.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.util.noise; - -import lombok.Data; - -@Data -public class Worm { - private double position; - private double velocity; - - public Worm(double startPosition, double startVelocity) { - this.position = startPosition; - this.velocity = startVelocity; - } - - public void unstep() { - position -= velocity; - } - - public void step() { - position += velocity; - } -} diff --git a/src/main/java/com/volmit/iris/util/noise/Worm2.java b/src/main/java/com/volmit/iris/util/noise/Worm2.java deleted file mode 100644 index 7f72a9881..000000000 --- a/src/main/java/com/volmit/iris/util/noise/Worm2.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.util.noise; - -import lombok.Data; - -@Data -public class Worm2 { - private final Worm x; - private final Worm z; - - public Worm2(Worm x, Worm z) { - this.x = x; - this.z = z; - } - - public Worm2(int x, int z, int vx, int vz) { - this(new Worm(x, vx), new Worm(z, vz)); - } - - public void step() { - x.step(); - z.step(); - } - - public void unstep() { - x.unstep(); - z.unstep(); - } -} diff --git a/src/main/java/com/volmit/iris/util/noise/Worm3.java b/src/main/java/com/volmit/iris/util/noise/Worm3.java deleted file mode 100644 index e173af29f..000000000 --- a/src/main/java/com/volmit/iris/util/noise/Worm3.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.util.noise; - -import lombok.Data; - -@Data -public class Worm3 { - private final Worm x; - private final Worm y; - private final Worm z; - - public Worm3(Worm x, Worm y, Worm z) { - this.x = x; - this.y = y; - this.z = z; - } - - public Worm3(int x, int y, int z, int vx, int vy, int vz) { - this(new Worm(x, vx), new Worm(y, vy), new Worm(z, vz)); - } - - public void step() { - x.step(); - y.step(); - z.step(); - } - - public void unstep() { - x.unstep(); - y.unstep(); - z.unstep(); - } -} diff --git a/src/main/java/com/volmit/iris/util/noise/WormIterator2.java b/src/main/java/com/volmit/iris/util/noise/WormIterator2.java deleted file mode 100644 index f3363e7e7..000000000 --- a/src/main/java/com/volmit/iris/util/noise/WormIterator2.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.util.noise; - -import com.volmit.iris.util.function.NoiseProvider; -import lombok.Builder; -import lombok.Data; - -@Builder -@Data -public class WormIterator2 { - private transient Worm2 worm; - private transient NoiseProvider noise; - private int x; - private int z; - private int maxDistance; - private int maxIterations; - - public boolean hasNext() { - double dist = maxDistance - (Math.max(Math.abs(worm.getX().getVelocity()), Math.abs(worm.getZ().getVelocity())) + 1); - return maxIterations > 0 && - ((x * x) - (worm.getX().getPosition() * worm.getX().getPosition())) - + ((z * z) - (worm.getZ().getPosition() * worm.getZ().getPosition())) < dist * dist; - } - - public Worm2 next() { - if (worm == null) { - worm = new Worm2(x, z, 0, 0); - return worm; - } - - worm.getX().setVelocity(noise.noise(worm.getX().getPosition(), 0)); - worm.getZ().setVelocity(noise.noise(worm.getZ().getPosition(), 0)); - worm.step(); - - return worm; - } -} diff --git a/src/main/java/com/volmit/iris/util/noise/WormIterator3.java b/src/main/java/com/volmit/iris/util/noise/WormIterator3.java deleted file mode 100644 index 8b1083884..000000000 --- a/src/main/java/com/volmit/iris/util/noise/WormIterator3.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.util.noise; - -import com.volmit.iris.util.function.NoiseProvider; -import lombok.Builder; -import lombok.Data; - -@Builder -@Data -public class WormIterator3 { - private transient Worm3 worm; - private int x; - private int y; - private int z; - private transient NoiseProvider noise; - private int maxDistance; - private int maxIterations; - - public boolean hasNext() { - if (worm == null) { - return true; - } - - double dist = maxDistance - (Math.max(Math.max(Math.abs(worm.getX().getVelocity()), - Math.abs(worm.getZ().getVelocity())), - Math.abs(worm.getY().getVelocity())) + 1); - - return maxIterations > 0 && - ((x * x) - (worm.getX().getPosition() * worm.getX().getPosition())) - + ((y * y) - (worm.getY().getPosition() * worm.getY().getPosition())) - + ((z * z) - (worm.getZ().getPosition() * worm.getZ().getPosition())) < dist * dist; - } - - public Worm3 next() { - maxIterations--; - if (worm == null) { - worm = new Worm3(x, y, z, 0, 0, 0); - return worm; - } - - worm.getX().setVelocity(worm.getX().getVelocity() + noise.noise(worm.getX().getPosition() + 10000, 0)); - worm.getY().setVelocity(worm.getY().getVelocity() + noise.noise(worm.getY().getPosition() + 1000, 0)); - worm.getZ().setVelocity(worm.getZ().getVelocity() + noise.noise(worm.getZ().getPosition() - 10000, 0)); - worm.step(); - - return worm; - } -}