From d826f968b5ee06a76f1f011faec3b21a1d0650e7 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 2 Aug 2021 01:12:40 -0400 Subject: [PATCH] Cavern json objects --- .../iris/engine/object/IrisCarveLayer.java | 23 +++++++- .../iris/engine/object/IrisCavernZone.java | 13 ++++ .../iris/engine/object/IrisCaverns.java | 59 ++++++++++--------- 3 files changed, 65 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/volmit/iris/engine/object/IrisCarveLayer.java b/src/main/java/com/volmit/iris/engine/object/IrisCarveLayer.java index 072efb680..3c8f64212 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisCarveLayer.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisCarveLayer.java @@ -25,6 +25,8 @@ import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.MaxNumber; import com.volmit.iris.engine.object.annotations.MinNumber; import com.volmit.iris.engine.object.annotations.Required; +import com.volmit.iris.engine.stream.ProceduralStream; +import com.volmit.iris.engine.stream.interpolation.Interpolated; import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.RNG; import lombok.AllArgsConstructor; @@ -62,6 +64,8 @@ public class IrisCarveLayer { @Desc("The threshold used as: \n\ncarved = noise(x,y,z) > threshold") private double threshold = 0.5; + private final transient AtomicCache> streamCache = new AtomicCache<>(); + private final transient AtomicCache> rawStreamCache = new AtomicCache<>(); private final transient AtomicCache cng = new AtomicCache<>(); public boolean isCarved(RNG rng, double x, double y, double z) { @@ -70,7 +74,24 @@ public class IrisCarveLayer { } double opacity = Math.pow(IrisInterpolation.sinCenter(M.lerpInverse(getMinHeight(), getMaxHeight(), y)), 4); - return cng.aquire(() -> getStyle().create(rng.nextParallelRNG(-2340 * getMaxHeight() * getMinHeight()))).fitDouble(0D, 1D, x, y, z) * opacity > getThreshold(); + return getCng(rng).fitDouble(0D, 1D, x, y, z) * opacity > getThreshold(); + } + + public ProceduralStream stream(RNG rng) + { + return streamCache.aquire(() -> ProceduralStream.of((x,y,z) -> isCarved(rng, x,y,z), Interpolated.BOOLEAN)); + } + + public ProceduralStream rawStream(RNG rng) + { + return rawStreamCache.aquire(() -> ProceduralStream.of((x,y,z) -> { + return getCng(rng).fitDouble(0D, 1D, x, y, z) * Math.pow(IrisInterpolation.sinCenter(M.lerpInverse(getMinHeight(), getMaxHeight(), y)), 4); + }, Interpolated.DOUBLE)); + } + + public CNG getCng(RNG rng) + { + return cng.aquire(() -> getStyle().create(rng.nextParallelRNG(-2340 * getMaxHeight() * getMinHeight()))); } public boolean isCarved2(RNG rng, double x, double y, double z) { diff --git a/src/main/java/com/volmit/iris/engine/object/IrisCavernZone.java b/src/main/java/com/volmit/iris/engine/object/IrisCavernZone.java index 5565f5199..3d8b7a670 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisCavernZone.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisCavernZone.java @@ -18,11 +18,13 @@ package com.volmit.iris.engine.object; +import com.volmit.iris.engine.cache.AtomicCache; import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.MaxNumber; import com.volmit.iris.engine.object.annotations.MinNumber; import com.volmit.iris.engine.object.common.IRare; +import com.volmit.iris.engine.stream.ProceduralStream; import com.volmit.iris.util.math.RNG; import lombok.AllArgsConstructor; import lombok.Data; @@ -48,6 +50,8 @@ public class IrisCavernZone implements IRare { @MaxNumber(100) private int rarity = 1; + private AtomicCache> carveCache = new AtomicCache<>(); + public boolean isCarved(RNG rng, double xx, double yy, double zz) { if(carver != null) { @@ -56,4 +60,13 @@ public class IrisCavernZone implements IRare { return false; } + + public double getCarved(RNG rng, double xx, double yy, double zz) { + if(carver != null) + { + return carver.rawStream(rng).get(xx,yy,zz) / (carver.getThreshold() * 2); + } + + return -1; + } } diff --git a/src/main/java/com/volmit/iris/engine/object/IrisCaverns.java b/src/main/java/com/volmit/iris/engine/object/IrisCaverns.java index d681d2567..a8d9bd2eb 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisCaverns.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisCaverns.java @@ -22,10 +22,9 @@ import com.volmit.iris.engine.cache.AtomicCache; import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.interpolation.IrisInterpolation; import com.volmit.iris.engine.object.annotations.*; -import com.volmit.iris.engine.object.common.IRare; import com.volmit.iris.engine.stream.ProceduralStream; +import com.volmit.iris.engine.stream.interpolation.Interpolated; import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.RNG; import lombok.AllArgsConstructor; import lombok.Data; @@ -54,7 +53,11 @@ public class IrisCaverns { @Desc("Threshold defined") private double topBleed = 16; + @Desc("If set to true (default) iris will interpolate the noise before checking if it meets the threshold.") + private boolean preThresholdInterpolation = true; + private transient AtomicCache> zonesRarity = new AtomicCache<>(); + private transient AtomicCache> streamCache = new AtomicCache<>(); public IrisCavernZone getZone(double x, double y, double z, RNG rng) { @@ -62,36 +65,34 @@ public class IrisCaverns { .stream().selectRarity(getZones())).get(x,y,z); } - private double threshold(double y, double th) + private double threshold(double y) { - double m = 0; - double a = 0; - double top = th - topBleed; - double bot = 0 + bottomBleed; - - if(y >= top && y <= th) - { - m++; - a+= IrisInterpolation.lerpBezier(1, 0, M.lerpInverse(top, th, y)); - } - - if(y <= bottomBleed && y >= 0) - { - m++; - a+= IrisInterpolation.lerpBezier(1, 0, M.lerpInverse(top, th, y)); - } - - return m==0 ? 1 : (a/m); + return 0.5; } - public void apply(double ox, double oy, double oz, Hunk hunk, T cave, RNG rng, ProceduralStream height) + public ProceduralStream stream(RNG rng) { - hunk.iterateSync((x,y,z) -> { - if(getInterpolator().interpolate(ox+x,oy+y,oz+z,(xx,yy,zz) - -> getZone(xx,yy,zz, rng).isCarved(rng, xx,yy,zz) ? 1 : 0) > threshold(y + oy, height.get(ox + x, oz + z))) - { - hunk.set(x,y,z,cave); - } - }); + if(preThresholdInterpolation) + { + return streamCache.aquire(() -> ProceduralStream.of((xx,yy,zz) + -> (getZone(xx, yy, zz, rng) + .getCarved(rng, xx,yy,zz)), Interpolated.DOUBLE) + .cache3D(65535)); + } + + return streamCache.aquire(() -> ProceduralStream.of((xx,yy,zz) + -> (getZone(xx, yy, zz, rng) + .isCarved(rng, xx,yy,zz) ? 1D : 0D), Interpolated.DOUBLE) + .cache3D(65535)); + } + + public boolean isCavern(RNG rng, double x, double y, double z, double height) { + if(zones.isEmpty()) + { + return false; + } + + return getInterpolator().interpolate(x, y, z, (xx, yy, zz) + -> stream(rng).get(xx,yy,zz)) > threshold(height); } }