From 2ce1bb9c3f4ed5d0875523d34ac8fa086400d802 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Sat, 24 Jul 2021 11:18:45 -0400 Subject: [PATCH] Parallax features working with biomes! --- .../com/volmit/iris/engine/IrisComplex.java | 34 ++++++++++++- .../framework/EngineParallaxManager.java | 29 +++++++---- .../iris/engine/object/IrisFeature.java | 16 +++--- .../engine/object/IrisFeaturePositional.java | 51 ++++++++++++------- 4 files changed, 95 insertions(+), 35 deletions(-) diff --git a/src/main/java/com/volmit/iris/engine/IrisComplex.java b/src/main/java/com/volmit/iris/engine/IrisComplex.java index 495668395..af60f2f53 100644 --- a/src/main/java/com/volmit/iris/engine/IrisComplex.java +++ b/src/main/java/com/volmit/iris/engine/IrisComplex.java @@ -39,6 +39,7 @@ import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; @Data public class IrisComplex implements DataProvider { @@ -215,10 +216,39 @@ public class IrisComplex implements DataProvider { }); trueBiomeStream = focus != null ? ProceduralStream.of((x, y) -> focus, Interpolated.of(a -> 0D, - b -> focus)) : heightStream + 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)).cache2D(cacheSize); + 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); trueBiomeDerivativeStream = trueBiomeStream.convert(IrisBiome::getDerivative).cache2D(cacheSize); heightFluidStream = heightStream.max(fluidHeight).cache2D(cacheSize); maxHeightStream = ProceduralStream.ofDouble((x, z) -> height); 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 5fcb03094..bc2ba5c9c 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineParallaxManager.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineParallaxManager.java @@ -212,10 +212,21 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { return; } + for (IrisFeaturePositional ipf : forEachFeature(x, z)) { + f.accept(ipf); + } + } + + @BlockCoordinates + default KList forEachFeature(double x, double z) { KList pos = new KList<>(); + if (!getEngine().getDimension().hasFeatures(getEngine())) { + return pos; + } + for (IrisFeaturePositional i : getEngine().getDimension().getSpecificFeatures()) { - if (i.shouldFilter(x, z)) { + if (i.shouldFilter(x, z, getEngine().getFramework().getComplex().getRng())) { pos.add(i); } } @@ -231,7 +242,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { try { for (IrisFeaturePositional k : m.getFeatures()) { - if (k.shouldFilter(x, z)) { + if (k.shouldFilter(x, z, getEngine().getFramework().getComplex().getRng())) { pos.add(k); } } @@ -243,9 +254,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { } } - for (IrisFeaturePositional ipf : pos) { - f.accept(ipf); - } + return pos; } @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") @@ -261,7 +270,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { int i, j; KList after = new KList<>(); int bs = (int) Math.pow((s * 2) + 1, 2); - BurstExecutor burst = getEngine().getTarget().getParallaxBurster().burst(bs); + BurstExecutor burst = getEngine().getTarget().getBurster().burst(bs); for (i = -s; i <= s; i++) { for (j = -s; j <= s; j++) { int xx = i + x; @@ -283,7 +292,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { burst.complete(); if (getEngine().getDimension().isPlaceObjects()) { - burst = getEngine().getTarget().getParallaxBurster().burst(bs); + burst = getEngine().getTarget().getBurster().burst(bs); for (i = -s; i <= s; i++) { int ii = i; @@ -299,7 +308,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { } burst.complete(); - burst = getEngine().getTarget().getParallaxBurster().burst(bs); + burst = getEngine().getTarget().getBurster().burst(bs); for (i = -s; i <= s; i++) { int ii = i; @@ -312,7 +321,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { burst.complete(); } - getEngine().getTarget().getParallaxBurster().burst(after); + getEngine().getTarget().getBurster().burst(after); getParallaxAccess().setChunkGenerated(x, z); p.end(); getEngine().getMetrics().getParallax().put(p.getMilliseconds()); @@ -666,7 +675,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { } Iris.verbose("Checking sizes for " + Form.f(objects.size()) + " referenced objects."); - BurstExecutor e = getEngine().getTarget().getParallaxBurster().burst(objects.size()); + BurstExecutor e = getEngine().getTarget().getBurster().burst(objects.size()); KMap sizeCache = new KMap<>(); for (String i : objects) { e.queue(() -> { diff --git a/src/main/java/com/volmit/iris/engine/object/IrisFeature.java b/src/main/java/com/volmit/iris/engine/object/IrisFeature.java index ea37b9ff1..07ecdeed0 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisFeature.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisFeature.java @@ -22,10 +22,7 @@ import com.google.gson.Gson; import com.volmit.iris.engine.cache.AtomicCache; import com.volmit.iris.engine.interpolation.InterpolationMethod; import com.volmit.iris.engine.interpolation.IrisInterpolation; -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.object.annotations.*; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -49,6 +46,15 @@ public class IrisFeature { @Desc("The chance an object that should be place actually will place. Set to below 1 to affect objects in this zone") private double objectChance = 1; + @RegistryListBiome + @Desc("Apply a custom biome here") + private String customBiome = null; + + @MinNumber(0) + @MaxNumber(1) + @Desc("How much strength before the biome is applied.") + private double biomeStrengthThreshold = 0.75; + @Desc("The interpolation radius of this zone") private double interpolationRadius = 7; @@ -78,8 +84,6 @@ public class IrisFeature { private transient AtomicCache actualRadius = new AtomicCache<>(); public double getActualRadius() { - - return actualRadius.aquire(() -> { double o = 0; diff --git a/src/main/java/com/volmit/iris/engine/object/IrisFeaturePositional.java b/src/main/java/com/volmit/iris/engine/object/IrisFeaturePositional.java index 0abc95050..1b31cf943 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisFeaturePositional.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisFeaturePositional.java @@ -22,6 +22,8 @@ import com.google.gson.Gson; import com.volmit.iris.engine.cache.AtomicCache; import com.volmit.iris.engine.interpolation.IrisInterpolation; 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.util.function.NoiseProvider; import com.volmit.iris.util.math.M; @@ -45,17 +47,14 @@ public class IrisFeaturePositional { } @Required - @Desc("The x coordinate of this zone") private int x; @Required - @Desc("The z coordinate of this zone") private int z; @Required - @Desc("The Terrain Feature to apply") private IrisFeature feature; @@ -70,9 +69,9 @@ public class IrisFeaturePositional { s.writeUTF(new Gson().toJson(this)); } - public boolean shouldFilter(double x, double z) { + public boolean shouldFilter(double x, double z, RNG rng) { double actualRadius = getFeature().getActualRadius(); - double dist2 = distance2(x, z); + double dist2 = distance2(x, z, rng); if (getFeature().isInvertZone()) { if (dist2 < Math.pow(getFeature().getBlockRadius() - actualRadius, 2)) { @@ -85,16 +84,14 @@ public class IrisFeaturePositional { public double getStrength(double x, double z, RNG rng) { double actualRadius = getFeature().getActualRadius(); - double mul = getFeature().getFractureRadius() != null ? getFeature().getFractureRadius().getMultiplier()/2 : 1; - double mod = getFeature().getFractureRadius() != null ? getFeature().getFractureRadius().create(rng).fitDouble(-mul, mul, x, z) : 0; - double dist2 = distance2(x, z) + mod; + double dist2 = distance2(x, z, rng); if (getFeature().isInvertZone()) { if (dist2 < Math.pow(getFeature().getBlockRadius() - actualRadius, 2)) { return 0; } - NoiseProvider d = provider.aquire(this::getNoiseProvider); + NoiseProvider d = provider.aquire(() -> getNoiseProvider(rng)); double s = IrisInterpolation.getNoise(getFeature().getInterpolator(), (int) x, (int) z, getFeature().getInterpolationRadius(), d); if (s <= 0) { @@ -107,7 +104,7 @@ public class IrisFeaturePositional { return 0; } - NoiseProvider d = provider.aquire(this::getNoiseProvider); + NoiseProvider d = provider.aquire(() -> getNoiseProvider(rng)); double s = IrisInterpolation.getNoise(getFeature().getInterpolator(), (int) x, (int) z, getFeature().getInterpolationRadius(), d); if (s <= 0) { @@ -126,6 +123,21 @@ public class IrisFeaturePositional { return M.lerp(1, getFeature().getObjectChance(), getStrength(x, z, rng)); } + public IrisBiome filter(double x, double z, IrisBiome biome, RNG rng) + { + if(getFeature().getCustomBiome() != null) + { + if(getStrength(x, z, rng) >= getFeature().getBiomeStrengthThreshold()) + { + IrisBiome b = biome.getLoader().getBiomeLoader().load(getFeature().getCustomBiome()); + b.setInferredType(biome.getInferredType()); + return b; + } + } + + return null; + } + public double filter(double x, double z, double noise, RNG rng) { double s = getStrength(x, z, rng); @@ -145,19 +157,24 @@ public class IrisFeaturePositional { return M.lerp(noise, fx, s); } - public double distance(double x, double z) { - return Math.sqrt(Math.pow(this.x - x, 2) + Math.pow(this.z - z, 2)); + public double distance(double x, double z, RNG rng) { + double mul = getFeature().getFractureRadius() != null ? getFeature().getFractureRadius().getMultiplier()/2 : 1; + double mod = getFeature().getFractureRadius() != null ? getFeature().getFractureRadius().create(rng).fitDouble(-mul, mul, x, z) : 0; + return Math.sqrt(Math.pow(this.x - (x + mod), 2) + Math.pow(this.z - (z + mod), 2)); } - public double distance2(double x, double z) { - return Math.pow(this.x - x, 2) + Math.pow(this.z - z, 2); + public double distance2(double x, double z, RNG rng) { + double mul = getFeature().getFractureRadius() != null ? getFeature().getFractureRadius().getMultiplier()/2 : 1; + double mod = getFeature().getFractureRadius() != null ? getFeature().getFractureRadius().create(rng).fitDouble(-mul, mul, x, z) : 0; + + return Math.pow(this.x - (x+mod), 2) + Math.pow(this.z - (z+mod), 2); } - private NoiseProvider getNoiseProvider() { + private NoiseProvider getNoiseProvider(RNG rng) { if (getFeature().isInvertZone()) { - return (x, z) -> distance(x, z) > getFeature().getBlockRadius() ? 1D : 0D; + return (x, z) -> distance(x, z, rng) > getFeature().getBlockRadius() ? 1D : 0D; } else { - return (x, z) -> distance(x, z) < getFeature().getBlockRadius() ? 1D : 0D; + return (x, z) -> distance(x, z, rng) < getFeature().getBlockRadius() ? 1D : 0D; } } }