diff --git a/src/main/java/com/volmit/iris/engine/IrisEngine.java b/src/main/java/com/volmit/iris/engine/IrisEngine.java index 427028127..8604b229c 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -19,6 +19,7 @@ package com.volmit.iris.engine; import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; import com.volmit.iris.engine.framework.*; import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.object.IrisBiome; @@ -26,7 +27,11 @@ import com.volmit.iris.engine.object.IrisBiomePaletteLayer; import com.volmit.iris.engine.object.IrisDecorator; import com.volmit.iris.engine.object.IrisObjectPlacement; import com.volmit.iris.engine.parallel.BurstExecutor; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.documentation.ChunkCoordinates; +import com.volmit.iris.util.format.C; +import com.volmit.iris.util.format.Form; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.PrecisionStopwatch; @@ -158,44 +163,63 @@ public class IrisEngine extends BlockPopulator implements Engine { @ChunkCoordinates @Override - public void generate(int x, int z, Hunk vblocks, Hunk vbiomes) { + public void generate(int x, int z, Hunk vblocks, Hunk vbiomes, boolean multicore) { try { PrecisionStopwatch p = PrecisionStopwatch.start(); Hunk blocks = vblocks.listen((xx, y, zz, t) -> catchBlockUpdates(x + xx, y + getMinHeight(), z + zz, t)); + PrecisionStopwatch px = PrecisionStopwatch.start(); - // This is a very weird optimization, but it works - // Basically we precache multicore the biome stream which effectivley - // makes the biome stream, interpolation & noise engine run in parallel without mca - BurstExecutor b = burst().burst(16); + if(multicore) + { + BurstExecutor b = burst().burst(16); + for (int i = 0; i < vblocks.getWidth(); i++) { + int finalI = i; + b.queue(() -> { + for (int j = 0; j < vblocks.getDepth(); j++) { + getFramework().getComplex().getTrueBiomeStream().get(x + finalI, z + j); + getFramework().getComplex().getTrueHeightStream().get(x + finalI, z + j); + } + }); + } - for (int i = 0; i < vblocks.getWidth(); i++) { - int finalI = i; - b.queue(() -> { - for (int j = 0; j < vblocks.getDepth(); j++) { - getFramework().getComplex().getTrueBiomeStream().get(x + finalI, z + j); - } - }); + b.complete(); } - b.complete(); + getMetrics().getPrecache().put(px.getMilliseconds()); switch (getDimension().getTerrainMode()) { case NORMAL -> { getFramework().getEngineParallax().generateParallaxArea(x >> 4, z >> 4); - getFramework().getTerrainActuator().actuate(x, z, vblocks); - getFramework().getBiomeActuator().actuate(x, z, vbiomes); - getFramework().getCaveModifier().modify(x, z, vblocks); - getFramework().getRavineModifier().modify(x, z, vblocks); - getFramework().getPostModifier().modify(x, z, vblocks); - getFramework().getDecorantActuator().actuate(x, z, blocks); + getFramework().getTerrainActuator().actuate(x, z, vblocks, multicore); + getFramework().getBiomeActuator().actuate(x, z, vbiomes, multicore); + getFramework().getCaveModifier().modify(x, z, vblocks, multicore); + getFramework().getRavineModifier().modify(x, z, vblocks, multicore); + getFramework().getPostModifier().modify(x, z, vblocks, multicore); + getFramework().getDecorantActuator().actuate(x, z, blocks, multicore); getFramework().getEngineParallax().insertParallax(x >> 4, z >> 4, blocks); - getFramework().getDepositModifier().modify(x, z, blocks); + getFramework().getDepositModifier().modify(x, z, blocks, multicore); } case ISLANDS -> { - getFramework().getTerrainActuator().actuate(x, z, vblocks); + getFramework().getTerrainActuator().actuate(x, z, vblocks, multicore); } } getMetrics().getTotal().put(p.getMilliseconds()); + + if(IrisSettings.get().getGeneral().isDebug()) + { + KList v = new KList<>(); + KMap g = getMetrics().pull(); + + for(String i : g.sortKNumber()) + { + if(g.get(i) != null) + { + v.add(C.RESET + "" + C.LIGHT_PURPLE + i + ": " + C.UNDERLINE + C.BLUE + Form.duration(g.get(i), 0) + C.RESET + C.GRAY + ""); + } + } + + Iris.debug(v.toString(", ")); + } } catch (Throwable e) { Iris.reportError(e); fail("Failed to generate " + x + ", " + z, e); diff --git a/src/main/java/com/volmit/iris/engine/IrisEngineCompound.java b/src/main/java/com/volmit/iris/engine/IrisEngineCompound.java index df3ade035..85ab10d2a 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngineCompound.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngineCompound.java @@ -213,11 +213,11 @@ public class IrisEngineCompound implements EngineCompound { } @Override - public void generate(int x, int z, Hunk blocks, Hunk postblocks, Hunk biomes) { + public void generate(int x, int z, Hunk blocks, Hunk postblocks, Hunk biomes, boolean multicore) { recycle(); PrecisionStopwatch p = PrecisionStopwatch.start(); if (engines.length == 1 && !getEngine(0).getTarget().isInverted()) { - engines[0].generate(x, z, blocks, biomes); + engines[0].generate(x, z, blocks, biomes, multicore); } else { int i; int offset = 0; @@ -234,7 +234,7 @@ public class IrisEngineCompound implements EngineCompound { cbiome = cbiome.invertY(); } - engine.generate(x, z, cblock, cbiome); + engine.generate(x, z, cblock, cbiome, multicore); blocks.insert(0, doffset, 0, cblock); biomes.insert(0, doffset, 0, cbiome); offset += height; diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java index 796eaaf9b..fc9f304e4 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java @@ -63,7 +63,7 @@ public class IrisBiomeActuator extends EngineAssignedActuator { @BlockCoordinates @Override - public void onActuate(int x, int z, Hunk h) { + public void onActuate(int x, int z, Hunk h, boolean multicore) { PrecisionStopwatch p = PrecisionStopwatch.start(); int zf, maxHeight; IrisBiome ib; diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java index c422c2fa7..16cf9e3a0 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java @@ -80,7 +80,7 @@ public class IrisDecorantActuator extends EngineAssignedActuator { @BlockCoordinates @Override - public void onActuate(int x, int z, Hunk output) { + public void onActuate(int x, int z, Hunk output, boolean multicore) { if (!getEngine().getDimension().isDecorate()) { return; } diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainIslandActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainIslandActuator.java index 84184b3eb..a0a90d8d9 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainIslandActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainIslandActuator.java @@ -53,7 +53,7 @@ public class IrisTerrainIslandActuator extends EngineAssignedActuator @BlockCoordinates @Override - public void onActuate(int x, int z, Hunk h) { + public void onActuate(int x, int z, Hunk h, boolean multicore) { PrecisionStopwatch p = PrecisionStopwatch.start(); int i, zf, depth, surface, realX, realZ; IrisBiome biome; diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java index 8530b4402..a09aebded 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java @@ -22,6 +22,7 @@ import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.EngineAssignedActuator; import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.object.IrisBiome; +import com.volmit.iris.engine.parallel.BurstExecutor; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.math.RNG; @@ -50,77 +51,104 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator @BlockCoordinates @Override - public void onActuate(int x, int z, Hunk h) { + public void onActuate(int x, int z, Hunk h, boolean multicore) { PrecisionStopwatch p = PrecisionStopwatch.start(); - int i, zf, depth, realX, realZ, hf, he, b, fdepth; - IrisBiome biome; - KList blocks, fblocks; - for (int xf = 0; xf < h.getWidth(); xf++) { - for (zf = 0; zf < h.getDepth(); zf++) { - realX = (int) modX(xf + x); - realZ = (int) modZ(zf + z); - b = hasUnder ? (int) Math.round(getDimension().getUndercarriage().get(rng, realX, realZ)) : 0; - he = (int) Math.round(Math.min(h.getHeight(), getComplex().getHeightStream().get(realX, realZ))); - hf = Math.round(Math.max(Math.min(h.getHeight(), getDimension().getFluidHeight()), he)); - biome = getComplex().getTrueBiomeStream().get(realX, realZ); - blocks = null; - fblocks = null; + if(multicore) + { + BurstExecutor e = getEngine().burst().burst(h.getWidth()); + for (int xf = 0; xf < h.getWidth(); xf++) { + int finalXf = xf; + e.queue(() -> terrainSliver(x, z, finalXf, h)); + } - if (hf < b) { - continue; - } + e.complete(); + } - for (i = hf; i >= b; i--) { - if (i >= h.getHeight()) { - continue; - } - - if (i == b) { - if (getDimension().isBedrock()) { - h.set(xf, i, zf, BEDROCK); - lastBedrock = i; - continue; - } - } - - if (carving && getDimension().isCarved(realX, i, realZ, rng, he)) { - continue; - } - - if (i > he && i <= hf) { - fdepth = hf - i; - - if (fblocks == null) { - fblocks = biome.generateSeaLayers(realX, realZ, rng, hf - he, getData()); - } - - if (fblocks.hasIndex(fdepth)) { - h.set(xf, i, zf, fblocks.get(fdepth)); - continue; - } - - h.set(xf, i, zf, getComplex().getFluidStream().get(realX, +realZ)); - continue; - } - - if (i <= he) { - depth = he - i; - if (blocks == null) { - blocks = biome.generateLayers(realX, realZ, rng, he, he, getData(), getComplex()); - } - - if (blocks.hasIndex(depth)) { - h.set(xf, i, zf, blocks.get(depth)); - continue; - } - - h.set(xf, i, zf, getComplex().getRockStream().get(realX, realZ)); - } - } + else + { + for (int xf = 0; xf < h.getWidth(); xf++) { + terrainSliver(x, z, xf, h); } } getEngine().getMetrics().getTerrain().put(p.getMilliseconds()); } + + /** + * This is calling 1/16th of a chunk x/z slice. It is a plane from sky to bedrock 1 thick in the x direction. + * @param x the chunk x in blocks + * @param z the chunk z in blocks + * @param xf the current x slice + * @param h the blockdata + */ + @BlockCoordinates + public void terrainSliver(int x, int z, int xf, Hunk h) { + int i, depth, realX, realZ, hf, he, b, fdepth; + IrisBiome biome; + KList blocks, fblocks; + + for (int zf = 0; zf < h.getDepth(); zf++) { + realX = (int) modX(xf + x); + realZ = (int) modZ(zf + z); + b = hasUnder ? (int) Math.round(getDimension().getUndercarriage().get(rng, realX, realZ)) : 0; + he = (int) Math.round(Math.min(h.getHeight(), getComplex().getHeightStream().get(realX, realZ))); + hf = Math.round(Math.max(Math.min(h.getHeight(), getDimension().getFluidHeight()), he)); + biome = getComplex().getTrueBiomeStream().get(realX, realZ); + blocks = null; + fblocks = null; + + if (hf < b) { + continue; + } + + for (i = hf; i >= b; i--) { + if (i >= h.getHeight()) { + continue; + } + + if (i == b) { + if (getDimension().isBedrock()) { + h.set(xf, i, zf, BEDROCK); + lastBedrock = i; + continue; + } + } + + if (carving && getDimension().isCarved(realX, i, realZ, rng, he)) { + continue; + } + + if (i > he && i <= hf) { + fdepth = hf - i; + + if (fblocks == null) { + fblocks = biome.generateSeaLayers(realX, realZ, rng, hf - he, getData()); + } + + if (fblocks.hasIndex(fdepth)) { + h.set(xf, i, zf, fblocks.get(fdepth)); + continue; + } + + h.set(xf, i, zf, getComplex().getFluidStream().get(realX, +realZ)); + continue; + } + + if (i <= he) { + depth = he - i; + if (blocks == null) { + blocks = biome.generateLayers(realX, realZ, rng, he, he, getData(), getComplex()); + } + + if (blocks.hasIndex(depth)) { + h.set(xf, i, zf, blocks.get(depth)); + continue; + } + + h.set(xf, i, zf, getComplex().getRockStream().get(realX, realZ)); + } + } + } + } } diff --git a/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java b/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java index b1e0af0e0..9b3f5dbda 100644 --- a/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java +++ b/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java @@ -111,7 +111,7 @@ public class LinkedTerrainChunk implements TerrainChunk { } @Override - public void setBlock(int x, int y, int z, BlockData blockData) { + public synchronized void setBlock(int x, int y, int z, BlockData blockData) { rawChunkData.setBlock(x, y, z, blockData); } @@ -123,37 +123,37 @@ public class LinkedTerrainChunk implements TerrainChunk { @Deprecated @Override - public void setBlock(int x, int y, int z, @NotNull Material material) { + public synchronized void setBlock(int x, int y, int z, @NotNull Material material) { rawChunkData.setBlock(x, y, z, material); } @Deprecated @Override - public void setBlock(int x, int y, int z, @NotNull MaterialData material) { + public synchronized void setBlock(int x, int y, int z, @NotNull MaterialData material) { rawChunkData.setBlock(x, y, z, material); } @Deprecated @Override - public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, @NotNull Material material) { + public synchronized void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, @NotNull Material material) { rawChunkData.setRegion(xMin, yMin, zMin, xMax, yMax, zMax, material); } @Deprecated @Override - public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, @NotNull MaterialData material) { + public synchronized void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, @NotNull MaterialData material) { rawChunkData.setRegion(xMin, yMin, zMin, xMax, yMax, zMax, material); } @Override - public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, @NotNull BlockData blockData) { + public synchronized void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, @NotNull BlockData blockData) { rawChunkData.setRegion(xMin, yMin, zMin, xMax, yMax, zMax, blockData); } @NotNull @Deprecated @Override - public Material getType(int x, int y, int z) { + public synchronized Material getType(int x, int y, int z) { return rawChunkData.getType(x, y, z); } diff --git a/src/main/java/com/volmit/iris/engine/framework/Engine.java b/src/main/java/com/volmit/iris/engine/framework/Engine.java index a25210ab7..c756185e1 100644 --- a/src/main/java/com/volmit/iris/engine/framework/Engine.java +++ b/src/main/java/com/volmit/iris/engine/framework/Engine.java @@ -81,7 +81,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro double modifyZ(double z); - void generate(int x, int z, Hunk blocks, Hunk biomes); + void generate(int x, int z, Hunk blocks, Hunk biomes, boolean multicore); EngineMetrics getMetrics(); diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineActuator.java b/src/main/java/com/volmit/iris/engine/framework/EngineActuator.java index c249e4548..6aac05f1f 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineActuator.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineActuator.java @@ -23,5 +23,5 @@ import com.volmit.iris.util.documentation.BlockCoordinates; public interface EngineActuator extends EngineComponent { @BlockCoordinates - void actuate(int x, int z, Hunk output); + void actuate(int x, int z, Hunk output, boolean multicore); } diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedActuator.java b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedActuator.java index 118e98eec..fb0c0428c 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedActuator.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedActuator.java @@ -26,11 +26,11 @@ public abstract class EngineAssignedActuator extends EngineAssignedComponent super(engine, name); } - public abstract void onActuate(int x, int z, Hunk output); + public abstract void onActuate(int x, int z, Hunk output, boolean multicore); @BlockCoordinates @Override - public void actuate(int x, int z, Hunk output) { - onActuate(x, z, output); + public void actuate(int x, int z, Hunk output, boolean multicore) { + onActuate(x, z, output, multicore); } } diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedModifier.java b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedModifier.java index b242d710e..902136e6e 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedModifier.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedModifier.java @@ -25,10 +25,10 @@ public abstract class EngineAssignedModifier extends EngineAssignedComponent super(engine, name); } - public abstract void onModify(int x, int z, Hunk output); + public abstract void onModify(int x, int z, Hunk output, boolean multicore); @Override - public void modify(int x, int z, Hunk output) { - onModify(x, z, output); + public void modify(int x, int z, Hunk output, boolean multicore) { + onModify(x, z, output, multicore); } } diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java b/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java index aff2abbc8..7c6074169 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java @@ -457,7 +457,7 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce PrecisionStopwatch ps = PrecisionStopwatch.start(); TerrainChunk tc = TerrainChunk.create(world, biome); IrisWorld ww = (getComposite() == null || getComposite().getWorld() == null) ? IrisWorld.fromWorld(world) : getComposite().getWorld(); - generateChunkRawData(ww, x, z, tc).run(); + generateChunkRawData(ww, x, z, tc, true).run(); if (!getComposite().getWorld().hasRealWorld()) { getComposite().getWorld().bind(world); @@ -540,7 +540,7 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce .minHeight(w.minHeight()).maxHeight(w.maxHeight()) .injector((xx, yy, zz, biomeBase) -> chunk.setBiomeAt(ox + xx, yy, oz + zz, INMS.get().getTrueBiomeBaseId(biomeBase))) - .build()).run(); + .build(), false).run(); } catch (Throwable e) { Iris.error("======================================"); e.printStackTrace(); @@ -556,12 +556,12 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce } } - public Runnable generateChunkRawData(IrisWorld world, int x, int z, TerrainChunk tc) { + public Runnable generateChunkRawData(IrisWorld world, int x, int z, TerrainChunk tc, boolean multicore) { initialize(world); Hunk blocks = Hunk.view((ChunkData) tc); Hunk biomes = Hunk.view((BiomeGrid) tc); Hunk post = Hunk.newAtomicHunk(biomes.getWidth(), biomes.getHeight(), biomes.getDepth()); - compound.get().generate(x * 16, z * 16, blocks, post, biomes); + compound.get().generate(x * 16, z * 16, blocks, post, biomes, multicore); return () -> blocks.insertSoftly(0, 0, 0, post, (b) -> b == null || B.isAirOrFluid(b)); } diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineCompound.java b/src/main/java/com/volmit/iris/engine/framework/EngineCompound.java index 257e192ff..44257ed44 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineCompound.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineCompound.java @@ -41,7 +41,7 @@ import java.util.List; public interface EngineCompound extends Listener, Hotloadable, DataProvider { IrisDimension getRootDimension(); - void generate(int x, int z, Hunk blocks, Hunk postblocks, Hunk biomes); + void generate(int x, int z, Hunk blocks, Hunk postblocks, Hunk biomes, boolean multicore); IrisWorld getWorld(); diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineMetrics.java b/src/main/java/com/volmit/iris/engine/framework/EngineMetrics.java index 87570ca6d..f777e41aa 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineMetrics.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineMetrics.java @@ -28,6 +28,7 @@ public class EngineMetrics { private final AtomicRollingSequence updates; private final AtomicRollingSequence terrain; private final AtomicRollingSequence biome; + private final AtomicRollingSequence precache; private final AtomicRollingSequence parallax; private final AtomicRollingSequence parallaxInsert; private final AtomicRollingSequence post; @@ -37,6 +38,7 @@ public class EngineMetrics { private final AtomicRollingSequence deposit; public EngineMetrics(int mem) { + this.precache = new AtomicRollingSequence(mem); this.total = new AtomicRollingSequence(mem); this.terrain = new AtomicRollingSequence(mem); this.biome = new AtomicRollingSequence(mem); @@ -52,6 +54,8 @@ public class EngineMetrics { public KMap pull() { KMap v = new KMap<>(); + v.put("total", total.getAverage()); + v.put("precache", precache.getAverage()); v.put("terrain", terrain.getAverage()); v.put("biome", biome.getAverage()); v.put("parallax", parallax.getAverage()); diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineModifier.java b/src/main/java/com/volmit/iris/engine/framework/EngineModifier.java index 21642ae35..fa734bff2 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineModifier.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineModifier.java @@ -23,5 +23,5 @@ import com.volmit.iris.util.documentation.BlockCoordinates; public interface EngineModifier extends EngineComponent { @BlockCoordinates - void modify(int x, int z, Hunk t); + void modify(int x, int z, Hunk t, boolean multicore); } diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java index 1596152f1..6afb645c5 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java @@ -18,6 +18,7 @@ package com.volmit.iris.engine.modifier; +import com.volmit.iris.Iris; import com.volmit.iris.engine.data.B; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.EngineAssignedModifier; @@ -26,6 +27,7 @@ import com.volmit.iris.engine.noise.FastNoiseDouble; import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisCaveLayer; import com.volmit.iris.engine.object.common.CaveResult; +import com.volmit.iris.engine.parallel.BurstExecutor; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.scheduling.PrecisionStopwatch; @@ -48,48 +50,67 @@ public class IrisCaveModifier extends EngineAssignedModifier { } @Override - public void onModify(int x, int z, Hunk a) { + public void onModify(int x, int z, Hunk a, boolean multicore) { if (!getDimension().isCaves()) { return; } PrecisionStopwatch p = PrecisionStopwatch.start(); - for (int i = 0; i < a.getWidth(); i++) { - for (int j = 0; j < a.getDepth(); j++) { - KList caves = genCaves(x + i, z + j, i, j, a); - int he = (int) Math.round(getComplex().getHeightStream().get(x + i, z + j)); - if (caves != null && caves.isNotEmpty()) { - IrisBiome cave = getComplex().getCaveBiomeStream().get(x + i, z + j); + if(multicore) + { + BurstExecutor e = getEngine().burst().burst(a.getWidth()); + for (int i = 0; i < a.getWidth(); i++) { + int finalI = i; + e.queue(() -> modifySliver(x, z, finalI, a)); + } - if (cave == null) { - continue; - } + e.complete(); + } - for (CaveResult cl : caves) { - if (cl.getFloor() < 0 || cl.getFloor() > getEngine().getHeight() || cl.getCeiling() > getEngine().getHeight() || cl.getCeiling() < 0) { - continue; - } - - KList floor = cave.generateLayers(x + i, z + j, rng, cl.getFloor(), cl.getFloor(), getData(), getComplex()); - KList ceiling = cave.generateLayers(x + i + 656, z + j - 656, rng, - he - cl.getCeiling(), - he - cl.getCeiling(), getData(), getComplex()); - - for (int g = 0; g < floor.size(); g++) { - a.set(i, cl.getFloor() - g, j, floor.get(g)); - } - - for (int g = ceiling.size() - 1; g > 0; g--) { - a.set(i, cl.getCeiling() + g, j, ceiling.get(g)); - } - } - } + else + { + for (int i = 0; i < a.getWidth(); i++) { + modifySliver(x, z, i, a); } } getEngine().getMetrics().getCave().put(p.getMilliseconds()); } + public void modifySliver(int x, int z, int finalI, Hunk a) + { + for (int j = 0; j < a.getDepth(); j++) { + KList caves = genCaves(x + finalI, z + j, finalI, j, a); + int he = (int) Math.round(getComplex().getHeightStream().get(x + finalI, z + j)); + if (caves != null && caves.isNotEmpty()) { + IrisBiome cave = getComplex().getCaveBiomeStream().get(x + finalI, z + j); + + if (cave == null) { + continue; + } + + for (CaveResult cl : caves) { + if (cl.getFloor() < 0 || cl.getFloor() > getEngine().getHeight() || cl.getCeiling() > getEngine().getHeight() || cl.getCeiling() < 0) { + continue; + } + + KList floor = cave.generateLayers(x + finalI, z + j, rng, cl.getFloor(), cl.getFloor(), getData(), getComplex()); + KList ceiling = cave.generateLayers(x + finalI + 656, z + j - 656, rng, + he - cl.getCeiling(), + he - cl.getCeiling(), getData(), getComplex()); + + for (int g = 0; g < floor.size(); g++) { + a.set(finalI, cl.getFloor() - g, j, floor.get(g)); + } + + for (int g = ceiling.size() - 1; g > 0; g--) { + a.set(finalI, cl.getCeiling() + g, j, ceiling.get(g)); + } + } + } + } + } + public KList genCaves(double wxx, double wzz, int x, int z, Hunk data) { if (!getDimension().isCaves()) { return EMPTY; diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java index 035e95383..3c549ecb4 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java @@ -40,7 +40,7 @@ public class IrisDepositModifier extends EngineAssignedModifier { } @Override - public void onModify(int x, int z, Hunk output) { + public void onModify(int x, int z, Hunk output, boolean multicore) { PrecisionStopwatch p = PrecisionStopwatch.start(); generateDeposits(rng, output, Math.floorDiv(x, 16), Math.floorDiv(z, 16)); getEngine().getMetrics().getDeposit().put(p.getMilliseconds()); diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java index 67309d589..d04c00f2b 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java @@ -25,6 +25,7 @@ import com.volmit.iris.engine.framework.EngineAssignedModifier; import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.common.CaveResult; +import com.volmit.iris.engine.parallel.BurstExecutor; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.scheduling.PrecisionStopwatch; import org.bukkit.Material; @@ -33,6 +34,8 @@ import org.bukkit.block.data.Levelled; import org.bukkit.block.data.Waterlogged; import org.bukkit.block.data.type.Slab; +import java.util.concurrent.atomic.AtomicInteger; + public class IrisPostModifier extends EngineAssignedModifier { private static final BlockData AIR = B.get("CAVE_AIR"); private static final BlockData WATER = B.get("WATER"); @@ -44,14 +47,33 @@ public class IrisPostModifier extends EngineAssignedModifier { } @Override - public void onModify(int x, int z, Hunk output) { + public void onModify(int x, int z, Hunk output, boolean multicore) { PrecisionStopwatch p = PrecisionStopwatch.start(); - int i, j; - for (i = 0; i < output.getWidth(); i++) { - for (j = 0; j < output.getDepth(); j++) { - post(i, j, output, i + x, j + z); + int i; + AtomicInteger j = new AtomicInteger(); + if(multicore) + { + BurstExecutor e = getEngine().burst().burst(output.getWidth()); + for (i = 0; i < output.getWidth(); i++) { + int finalI = i; + e.queue(() -> { + for (j.set(0); j.get() < output.getDepth(); j.getAndIncrement()) { + post(finalI, j.get(), output, finalI + x, j.get() + z); + } + }); + } + e.complete(); + } + + else + { + for (i = 0; i < output.getWidth(); i++) { + for (j.set(0); j.get() < output.getDepth(); j.getAndIncrement()) { + post(i, j.get(), output, i + x, j.get() + z); + } } } + getEngine().getMetrics().getPost().put(p.getMilliseconds()); } diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisRavineModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisRavineModifier.java index 70f64ae8e..e4a2ae5a7 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisRavineModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisRavineModifier.java @@ -46,7 +46,7 @@ public class IrisRavineModifier extends EngineAssignedModifier { } @Override - public void onModify(int x, int z, Hunk output) { + public void onModify(int x, int z, Hunk output, boolean multicore) { if (!getDimension().isRavines()) { return; }