diff --git a/src/main/java/com/volmit/iris/gen/BiomeChunkGenerator.java b/src/main/java/com/volmit/iris/gen/BiomeChunkGenerator.java deleted file mode 100644 index ba2de4812..000000000 --- a/src/main/java/com/volmit/iris/gen/BiomeChunkGenerator.java +++ /dev/null @@ -1,242 +0,0 @@ -package com.volmit.iris.gen; - -import org.bukkit.World; - -import com.volmit.iris.Iris; -import com.volmit.iris.gen.layer.GenLayerBiome; -import com.volmit.iris.noise.CNG; -import com.volmit.iris.object.InferredType; -import com.volmit.iris.object.IrisBiome; -import com.volmit.iris.object.IrisBiomeGeneratorLink; -import com.volmit.iris.object.IrisDimension; -import com.volmit.iris.object.IrisGenerator; -import com.volmit.iris.object.IrisRegion; -import com.volmit.iris.util.BiomeResult; -import com.volmit.iris.util.ChronoLatch; -import com.volmit.iris.util.IrisInterpolation; -import com.volmit.iris.util.IrisLock; -import com.volmit.iris.util.KList; -import com.volmit.iris.util.KMap; -import com.volmit.iris.util.M; -import com.volmit.iris.util.RNG; - -import lombok.Data; -import lombok.EqualsAndHashCode; - -@Data -@EqualsAndHashCode(callSuper = false) -public abstract class BiomeChunkGenerator extends DimensionChunkGenerator -{ - protected IrisLock regLock; - private KMap generators; - private KMap ceilingGenerators; - protected GenLayerBiome glBiome; - protected CNG masterFracture; - protected ChronoLatch cwarn = new ChronoLatch(1000); - - public BiomeChunkGenerator(String dimensionName) - { - super(dimensionName); - generators = new KMap<>(); - ceilingGenerators = new KMap<>(); - regLock = new IrisLock("BiomeChunkGenerator"); - } - - public void onInit(World world, RNG rng) - { - super.onInit(world, rng); - loadGenerators(); - glBiome = new GenLayerBiome(this, masterRandom.nextParallelRNG(1)); - masterFracture = CNG.signature(rng.nextParallelRNG(13)).scale(0.12); - } - - @Override - public void onHotload() - { - super.onHotload(); - loadGenerators(); - glBiome = new GenLayerBiome(this, masterRandom.nextParallelRNG(1)); - } - - public void registerGenerator(IrisGenerator g, IrisDimension dim) - { - KMap generators = dim.isInverted() ? ceilingGenerators : this.generators; - - regLock.lock(); - if(g.getLoadKey() == null || generators.containsKey(g.getLoadKey())) - { - regLock.unlock(); - return; - } - - regLock.unlock(); - generators.put(g.getLoadKey(), g); - } - - protected KMap getGenerators() - { - return getDimension().isInverted() ? ceilingGenerators : generators; - } - - protected double getBiomeHeight(double rx, double rz, int x, int z) - { - double h = 0; - - for(IrisGenerator i : getGenerators().values()) - { - h += interpolateGenerator(rx, rz, i); - } - - return h; - } - - protected double interpolateGenerator(double rx, double rz, IrisGenerator gen) - { - double hi = IrisInterpolation.getNoise(gen.getInterpolationFunction(), (int) Math.round(rx), (int) Math.round(rz), gen.getInterpolationScale(), (xx, zz) -> - { - try - { - IrisBiome b = sampleBiome((int) xx, (int) zz).getBiome(); - - for(IrisBiomeGeneratorLink i : b.getGenerators()) - { - if(i.getGenerator().equals(gen.getLoadKey())) - { - return i.getMax(); - } - } - - } - - catch(Throwable e) - { - e.printStackTrace(); - Iris.warn("Failed to sample hi biome at " + rx + " " + rz + " using the generator " + gen.getLoadKey()); - } - return 0; - }); - - double lo = IrisInterpolation.getNoise(gen.getInterpolationFunction(), (int) Math.round(rx), (int) Math.round(rz), gen.getInterpolationScale(), (xx, zz) -> - { - try - { - IrisBiome b = sampleBiome((int) xx, (int) zz).getBiome(); - - for(IrisBiomeGeneratorLink i : b.getGenerators()) - { - if(i.getGenerator().equals(gen.getLoadKey())) - { - return i.getMin(); - } - } - } - - catch(Throwable e) - { - e.printStackTrace(); - Iris.warn("Failed to sample lo biome at " + rx + " " + rz + " using the generator " + gen.getLoadKey()); - } - - return 0; - }); - - return M.lerp(lo, hi, gen.getHeight(rx, rz, world.getSeed() + 239945)); - } - - protected void loadGenerators() - { - generators.clear(); - ceilingGenerators.clear(); - loadGenerators(((CeilingChunkGenerator) this).getFloorDimension()); - loadGenerators(((CeilingChunkGenerator) this).getCeilingDimension()); - } - - protected void loadGenerators(IrisDimension dim) - { - if(dim == null) - { - return; - } - - KList touch = new KList<>(); - KList loadQueue = new KList<>(); - - for(String i : dim.getRegions()) - { - IrisRegion r = loadRegion(i); - - if(r != null) - { - loadQueue.addAll(r.getLandBiomes()); - loadQueue.addAll(r.getSeaBiomes()); - loadQueue.addAll(r.getShoreBiomes()); - loadQueue.addAll(r.getRidgeBiomeKeys()); - loadQueue.addAll(r.getSpotBiomeKeys()); - } - } - - while(!loadQueue.isEmpty()) - { - String next = loadQueue.pop(); - - if(!touch.contains(next)) - { - touch.add(next); - IrisBiome biome = loadBiome(next); - biome.getGenerators().forEach((i) -> registerGenerator(i.getCachedGenerator(this), dim)); - loadQueue.addAll(biome.getChildren()); - } - } - } - - public IrisRegion sampleRegion(int x, int z) - { - - double wx = getModifiedX(x, z); - double wz = getModifiedZ(x, z); - return glBiome.getRegion(wx, wz); - } - - public BiomeResult sampleBiome(int x, int z) - { - return getCache().getRawBiome(x, z, () -> - { - if(!getDimension().getFocus().equals("")) - { - IrisBiome biome = loadBiome(getDimension().getFocus()); - - for(String i : getDimension().getRegions()) - { - IrisRegion reg = loadRegion(i); - - if(reg.getLandBiomes().contains(biome.getLoadKey())) - { - biome.setInferredType(InferredType.LAND); - break; - } - - if(reg.getSeaBiomes().contains(biome.getLoadKey())) - { - biome.setInferredType(InferredType.SEA); - break; - } - - if(reg.getShoreBiomes().contains(biome.getLoadKey())) - { - biome.setInferredType(InferredType.SHORE); - break; - } - } - - return new BiomeResult(biome, 0); - } - - double wx = getModifiedX(x, z); - double wz = getModifiedZ(x, z); - IrisRegion region = glBiome.getRegion(wx, wz); - BiomeResult res = glBiome.generateRegionData(wx, wz, x, z, region); - - return res; - }); - } -} diff --git a/src/main/java/com/volmit/iris/gen/ParallelChunkGenerator.java b/src/main/java/com/volmit/iris/gen/ParallelChunkGenerator.java index 2cfad7565..1b1fb40bc 100644 --- a/src/main/java/com/volmit/iris/gen/ParallelChunkGenerator.java +++ b/src/main/java/com/volmit/iris/gen/ParallelChunkGenerator.java @@ -17,7 +17,7 @@ import lombok.EqualsAndHashCode; @Data @EqualsAndHashCode(callSuper = false) -public abstract class ParallelChunkGenerator extends BiomeChunkGenerator +public abstract class ParallelChunkGenerator extends DimensionChunkGenerator { private GroupedExecutor accelerant; private int threads; diff --git a/src/main/java/com/volmit/iris/gen/TerrainChunkGenerator.java b/src/main/java/com/volmit/iris/gen/TerrainChunkGenerator.java index a061eb110..a1204c955 100644 --- a/src/main/java/com/volmit/iris/gen/TerrainChunkGenerator.java +++ b/src/main/java/com/volmit/iris/gen/TerrainChunkGenerator.java @@ -7,21 +7,31 @@ import org.bukkit.block.data.Bisected; import org.bukkit.block.data.Bisected.Half; import org.bukkit.block.data.BlockData; +import com.volmit.iris.Iris; import com.volmit.iris.gen.atomics.AtomicSliver; +import com.volmit.iris.gen.layer.GenLayerBiome; import com.volmit.iris.gen.layer.GenLayerCarve; import com.volmit.iris.gen.layer.GenLayerCave; +import com.volmit.iris.noise.CNG; import com.volmit.iris.object.DecorationPart; import com.volmit.iris.object.InferredType; import com.volmit.iris.object.IrisBiome; import com.volmit.iris.object.IrisBiomeDecorator; +import com.volmit.iris.object.IrisBiomeGeneratorLink; import com.volmit.iris.object.IrisDepositGenerator; +import com.volmit.iris.object.IrisDimension; +import com.volmit.iris.object.IrisGenerator; import com.volmit.iris.object.IrisRegion; import com.volmit.iris.util.B; import com.volmit.iris.util.BiomeMap; import com.volmit.iris.util.BiomeResult; import com.volmit.iris.util.CaveResult; +import com.volmit.iris.util.ChronoLatch; import com.volmit.iris.util.HeightMap; +import com.volmit.iris.util.IrisInterpolation; +import com.volmit.iris.util.IrisLock; import com.volmit.iris.util.KList; +import com.volmit.iris.util.KMap; import com.volmit.iris.util.M; import com.volmit.iris.util.RNG; @@ -37,15 +47,28 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator private GenLayerCave glCave; private GenLayerCarve glCarve; private RNG rockRandom; + protected IrisLock regLock; + private KMap generators; + private KMap ceilingGenerators; + protected GenLayerBiome glBiome; + protected CNG masterFracture; + protected ChronoLatch cwarn = new ChronoLatch(1000); public TerrainChunkGenerator(String dimensionName, int threads) { super(dimensionName, threads); + generators = new KMap<>(); + ceilingGenerators = new KMap<>(); + regLock = new IrisLock("BiomeChunkGenerator"); } + @Override public void onInit(World world, RNG rng) { super.onInit(world, rng); + loadGenerators(); + glBiome = new GenLayerBiome(this, masterRandom.nextParallelRNG(1)); + masterFracture = CNG.signature(rng.nextParallelRNG(13)).scale(0.12); rockRandom = getMasterRandom().nextParallelRNG(2858678); glCave = new GenLayerCave(this, rng.nextParallelRNG(238948)); glCarve = new GenLayerCarve(this, rng.nextParallelRNG(968346576)); @@ -549,10 +572,14 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator return sampleTrueBiome(x, z, getTerrainHeight(x, z)); } - @Override public IrisRegion sampleRegion(int x, int z) { - return getCache().getRegion(x, z, () -> super.sampleRegion(x, z)); + return getCache().getRegion(x, z, () -> + { + double wx = getModifiedX(x, z); + double wz = getModifiedZ(x, z); + return glBiome.getRegion(wx, wz); + }); } public BiomeResult sampleTrueBiome(int x, int z, double noise) @@ -616,4 +643,190 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator { return Math.max(getTerrainHeight(x, z), getFluidHeight()); } + + //////////////////// + // BIOME METHODS + /////////////////// + + @Override + public void onHotload() + { + super.onHotload(); + loadGenerators(); + glBiome = new GenLayerBiome(this, masterRandom.nextParallelRNG(1)); + } + + public void registerGenerator(IrisGenerator g, IrisDimension dim) + { + KMap generators = dim.isInverted() ? ceilingGenerators : this.generators; + + regLock.lock(); + if(g.getLoadKey() == null || generators.containsKey(g.getLoadKey())) + { + regLock.unlock(); + return; + } + + regLock.unlock(); + generators.put(g.getLoadKey(), g); + } + + protected KMap getGenerators() + { + return getDimension().isInverted() ? ceilingGenerators : generators; + } + + protected double getBiomeHeight(double rx, double rz, int x, int z) + { + double h = 0; + + for(IrisGenerator i : getGenerators().values()) + { + h += interpolateGenerator(rx, rz, i); + } + + return h; + } + + protected double interpolateGenerator(double rx, double rz, IrisGenerator gen) + { + double hi = IrisInterpolation.getNoise(gen.getInterpolationFunction(), (int) Math.round(rx), (int) Math.round(rz), gen.getInterpolationScale(), (xx, zz) -> + { + try + { + IrisBiome b = sampleBiome((int) xx, (int) zz).getBiome(); + + for(IrisBiomeGeneratorLink i : b.getGenerators()) + { + if(i.getGenerator().equals(gen.getLoadKey())) + { + return i.getMax(); + } + } + + } + + catch(Throwable e) + { + e.printStackTrace(); + Iris.warn("Failed to sample hi biome at " + rx + " " + rz + " using the generator " + gen.getLoadKey()); + } + return 0; + }); + + double lo = IrisInterpolation.getNoise(gen.getInterpolationFunction(), (int) Math.round(rx), (int) Math.round(rz), gen.getInterpolationScale(), (xx, zz) -> + { + try + { + IrisBiome b = sampleBiome((int) xx, (int) zz).getBiome(); + + for(IrisBiomeGeneratorLink i : b.getGenerators()) + { + if(i.getGenerator().equals(gen.getLoadKey())) + { + return i.getMin(); + } + } + } + + catch(Throwable e) + { + e.printStackTrace(); + Iris.warn("Failed to sample lo biome at " + rx + " " + rz + " using the generator " + gen.getLoadKey()); + } + + return 0; + }); + + return M.lerp(lo, hi, gen.getHeight(rx, rz, world.getSeed() + 239945)); + } + + protected void loadGenerators() + { + generators.clear(); + ceilingGenerators.clear(); + loadGenerators(((CeilingChunkGenerator) this).getFloorDimension()); + loadGenerators(((CeilingChunkGenerator) this).getCeilingDimension()); + } + + protected void loadGenerators(IrisDimension dim) + { + if(dim == null) + { + return; + } + + KList touch = new KList<>(); + KList loadQueue = new KList<>(); + + for(String i : dim.getRegions()) + { + IrisRegion r = loadRegion(i); + + if(r != null) + { + loadQueue.addAll(r.getLandBiomes()); + loadQueue.addAll(r.getSeaBiomes()); + loadQueue.addAll(r.getShoreBiomes()); + loadQueue.addAll(r.getRidgeBiomeKeys()); + loadQueue.addAll(r.getSpotBiomeKeys()); + } + } + + while(!loadQueue.isEmpty()) + { + String next = loadQueue.pop(); + + if(!touch.contains(next)) + { + touch.add(next); + IrisBiome biome = loadBiome(next); + biome.getGenerators().forEach((i) -> registerGenerator(i.getCachedGenerator(this), dim)); + loadQueue.addAll(biome.getChildren()); + } + } + } + + public BiomeResult sampleBiome(int x, int z) + { + return getCache().getRawBiome(x, z, () -> + { + if(!getDimension().getFocus().equals("")) + { + IrisBiome biome = loadBiome(getDimension().getFocus()); + + for(String i : getDimension().getRegions()) + { + IrisRegion reg = loadRegion(i); + + if(reg.getLandBiomes().contains(biome.getLoadKey())) + { + biome.setInferredType(InferredType.LAND); + break; + } + + if(reg.getSeaBiomes().contains(biome.getLoadKey())) + { + biome.setInferredType(InferredType.SEA); + break; + } + + if(reg.getShoreBiomes().contains(biome.getLoadKey())) + { + biome.setInferredType(InferredType.SHORE); + break; + } + } + + return new BiomeResult(biome, 0); + } + + double wx = getModifiedX(x, z); + double wz = getModifiedZ(x, z); + IrisRegion region = glBiome.getRegion(wx, wz); + BiomeResult res = glBiome.generateRegionData(wx, wz, x, z, region); + + return res; + }); + } }