From 03a1b51bd737c6592d2097db3aa5c1e6ca7c127f Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Sat, 31 Jul 2021 08:58:54 -0400 Subject: [PATCH] Fix parallax noise feature artifact holes / spikes It was a really weird caching issue --- .../com/volmit/iris/engine/IrisComplex.java | 60 +++++++++++++++++-- .../framework/EngineParallaxManager.java | 10 ++-- 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/volmit/iris/engine/IrisComplex.java b/src/main/java/com/volmit/iris/engine/IrisComplex.java index cfd982b99..f167eaaf7 100644 --- a/src/main/java/com/volmit/iris/engine/IrisComplex.java +++ b/src/main/java/com/volmit/iris/engine/IrisComplex.java @@ -33,11 +33,13 @@ 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 com.volmit.iris.util.scheduling.J; import lombok.Data; import org.bukkit.Material; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; +import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; @Data @@ -61,8 +63,10 @@ public class IrisComplex implements DataProvider { private ProceduralStream shoreBiomeStream; private ProceduralStream baseBiomeStream; private ProceduralStream trueBiomeStream; + private ProceduralStream trueBiomeStreamNoFeatures; private ProceduralStream trueBiomeDerivativeStream; private ProceduralStream heightStream; + private ProceduralStream heightStreamNoFeatures; private ProceduralStream objectChanceStream; private ProceduralStream maxHeightStream; private ProceduralStream overlayStream; @@ -199,7 +203,11 @@ public class IrisComplex implements DataProvider { .convertAware2D(this::implode).cache2D(cacheSize); heightStream = ProceduralStream.of((x, z) -> { IrisBiome b = focus != null ? focus : baseBiomeStream.get(x, z); - return getHeight(engine, b, x, z, engine.getWorld().seed()); + return getHeight(engine, b, x, z, engine.getWorld().seed(), true); + }, Interpolated.DOUBLE).clamp(0, engine.getHeight()).cache2D(cacheSize); + heightStreamNoFeatures = ProceduralStream.of((x, z) -> { + IrisBiome b = focus != null ? focus : baseBiomeStream.get(x, z); + return getHeight(engine, b, x, z, engine.getWorld().seed(), false); }, Interpolated.DOUBLE).clamp(0, engine.getHeight()).cache2D(cacheSize); slopeStream = heightStream.slope(3).cache2D(cacheSize); objectChanceStream = ProceduralStream.ofDouble((x, z) -> { @@ -246,6 +254,45 @@ public class IrisComplex implements DataProvider { return b; }) .cache2D(cacheSize); + + trueBiomeStream = focus != null ? ProceduralStream.of((x, y) -> focus, Interpolated.of(a -> 0D, + b -> focus)).convertAware2D((b, x, z) -> { + for (IrisFeaturePositional i : engine.getFramework().getEngineParallax().forEachFeature(x, z)) { + IrisBiome bx = i.filter(x, z, b, rng); + + if (bx != null) { + bx.setInferredType(b.getInferredType()); + return bx; + } + } + + return b; + }) + .cache2D(cacheSize) : heightStream + .convertAware2D((h, x, z) -> + fixBiomeType(h, baseBiomeStream.get(x, z), + regionStream.get(x, z), x, z, fluidHeight)) + .convertAware2D((b, x, z) -> { + for (IrisFeaturePositional i : engine.getFramework().getEngineParallax().forEachFeature(x, z)) { + IrisBiome bx = i.filter(x, z, b, rng); + + if (bx != null) { + bx.setInferredType(b.getInferredType()); + return bx; + } + } + + return b; + }) + .cache2D(cacheSize); + + trueBiomeStreamNoFeatures = focus != null ? ProceduralStream.of((x, y) -> focus, Interpolated.of(a -> 0D, + b -> focus)) + : heightStreamNoFeatures + .convertAware2D((h, x, z) -> + fixBiomeType(h, baseBiomeStream.get(x, z), + regionStream.get(x, z), x, z, fluidHeight)) + .cache2D(cacheSize); trueBiomeDerivativeStream = trueBiomeStream.convert(IrisBiome::getDerivative).cache2D(cacheSize); heightFluidStream = heightStream.max(fluidHeight).cache2D(cacheSize); maxHeightStream = ProceduralStream.ofDouble((x, z) -> height); @@ -374,7 +421,7 @@ public class IrisComplex implements DataProvider { return biome; } - private double getHeight(Engine engine, IrisBiome b, double x, double z, long seed) { + private double getHeight(Engine engine, IrisBiome b, double x, double z, long seed, boolean features) { double h = 0; for (IrisGenerator gen : generators) { @@ -413,9 +460,14 @@ public class IrisComplex implements DataProvider { AtomicDouble noise = new AtomicDouble(h + fluidHeight + overlayStream.get(x, z)); - for(IrisFeaturePositional i : engine.getFramework().getEngineParallax().forEachFeature(x, z)) + if(features) { - noise.set(i.filter(x, z, noise.get(), rng)); + List p = engine.getFramework().getEngineParallax().forEachFeature(x, z); + + for(IrisFeaturePositional i : p) + { + noise.set(i.filter(x, z, noise.get(), rng)); + } } return Math.min(engine.getHeight(), Math.max(noise.get(), 0)); diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineParallaxManager.java b/src/main/java/com/volmit/iris/engine/framework/EngineParallaxManager.java index 1f5f4be27..b20c58a52 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineParallaxManager.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineParallaxManager.java @@ -265,7 +265,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { burst.queue(() -> { RNG rng = new RNG(Cache.key(xx, zz) + getEngine().getTarget().getWorld().seed()); IrisRegion region = getComplex().getRegionStream().get(xxx, zzz); - IrisBiome biome = getComplex().getTrueBiomeStream().get(xxx, zzz); + IrisBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xxx, zzz); generateParallaxFeatures(rng, xx, zz, region, biome); }); } @@ -327,7 +327,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { int zz = z << 4; RNG rng = new RNG(Cache.key(x, z)).nextParallelRNG(getEngine().getTarget().getWorld().seed()); IrisRegion region = getComplex().getRegionStream().get(xx + 8, zz + 8); - IrisBiome biome = getComplex().getTrueBiomeStream().get(xx + 8, zz + 8); + IrisBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xx + 8, zz + 8); after.addAll(generateParallaxJigsaw(rng, x, z, biome, region)); generateParallaxSurface(rng, x, z, biome, region, true); generateParallaxMutations(rng, x, z, true); @@ -345,7 +345,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { int zz = z << 4; getParallaxAccess().setParallaxGenerated(x, z); RNG rng = new RNG(Cache.key(x, z)).nextParallelRNG(getEngine().getTarget().getWorld().seed()); - IrisBiome biome = getComplex().getTrueBiomeStream().get(xx + 8, zz + 8); + IrisBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xx + 8, zz + 8); IrisRegion region = getComplex().getRegionStream().get(xx + 8, zz + 8); generateParallaxSurface(rng, x, z, biome, region, false); generateParallaxMutations(rng, x, z, false); @@ -504,8 +504,8 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { searching: for (IrisBiomeMutation k : getEngine().getDimension().getMutations()) { for (int l = 0; l < k.getChecks(); l++) { - IrisBiome sa = getComplex().getTrueBiomeStream().get(((x * 16) + rng.nextInt(16)) + rng.i(-k.getRadius(), k.getRadius()), ((z * 16) + rng.nextInt(16)) + rng.i(-k.getRadius(), k.getRadius())); - IrisBiome sb = getComplex().getTrueBiomeStream().get(((x * 16) + rng.nextInt(16)) + rng.i(-k.getRadius(), k.getRadius()), ((z * 16) + rng.nextInt(16)) + rng.i(-k.getRadius(), k.getRadius())); + IrisBiome sa = getComplex().getTrueBiomeStreamNoFeatures().get(((x * 16) + rng.nextInt(16)) + rng.i(-k.getRadius(), k.getRadius()), ((z * 16) + rng.nextInt(16)) + rng.i(-k.getRadius(), k.getRadius())); + IrisBiome sb = getComplex().getTrueBiomeStreamNoFeatures().get(((x * 16) + rng.nextInt(16)) + rng.i(-k.getRadius(), k.getRadius()), ((z * 16) + rng.nextInt(16)) + rng.i(-k.getRadius(), k.getRadius())); if (sa.getLoadKey().equals(sb.getLoadKey())) { continue;