diff --git a/bukkit/src/main/java/com/volmit/iris/platform/bukkit/IrisBukkitChunkGenerator.java b/bukkit/src/main/java/com/volmit/iris/platform/bukkit/IrisBukkitChunkGenerator.java index 3722ee9f6..7b0121c84 100644 --- a/bukkit/src/main/java/com/volmit/iris/platform/bukkit/IrisBukkitChunkGenerator.java +++ b/bukkit/src/main/java/com/volmit/iris/platform/bukkit/IrisBukkitChunkGenerator.java @@ -5,8 +5,8 @@ import art.arcane.chrono.PrecisionStopwatch; import art.arcane.spatial.hunk.Hunk; import com.volmit.iris.engine.EngineConfiguration; import com.volmit.iris.engine.Engine; -import com.volmit.iris.engine.feature.IrisFeatureSizedTarget; -import com.volmit.iris.engine.feature.IrisFeatureTarget; +import com.volmit.iris.engine.feature.FeatureSizedTarget; +import com.volmit.iris.engine.feature.FeatureTarget; import com.volmit.iris.engine.pipeline.PipedHunkStack; import com.volmit.iris.platform.IrisPlatform; import com.volmit.iris.platform.PlatformBlock; @@ -46,7 +46,7 @@ public class IrisBukkitChunkGenerator extends ChunkGenerator implements Closeabl initEngine(world); ChunkData data = Bukkit.createChunkData(world); Hunk chunk = new ChunkDataHunkView(data); - IrisFeatureSizedTarget targetSize = IrisFeatureSizedTarget.builder() + FeatureSizedTarget targetSize = FeatureSizedTarget.builder() .width(chunk.getWidth()) .height(chunk.getHeight()) .depth(chunk.getDepth()) @@ -54,7 +54,7 @@ public class IrisBukkitChunkGenerator extends ChunkGenerator implements Closeabl .offsetZ(z << 4) .offsetY(0) .build(); - IrisFeatureTarget blockTarget = new IrisFeatureTarget<>(chunk, targetSize); + FeatureTarget blockTarget = new FeatureTarget<>(chunk, targetSize); PipedHunkStack stack = new PipedHunkStack(); stack.register(PlatformBlock.class, blockTarget); engine.get().getPlumbing().generate(engine.get(), targetSize, stack); diff --git a/engine/src/main/java/com/volmit/iris/engine/Engine.java b/engine/src/main/java/com/volmit/iris/engine/Engine.java index 053dac842..c3c031cc4 100644 --- a/engine/src/main/java/com/volmit/iris/engine/Engine.java +++ b/engine/src/main/java/com/volmit/iris/engine/Engine.java @@ -36,20 +36,22 @@ public class Engine implements Closeable { private final EngineData data; public Engine(IrisPlatform platform, PlatformWorld world, EngineConfiguration configuration) throws IOException { - PrecisionStopwatch p = PrecisionStopwatch.start(); - this.configuration = configuration; + this.configuration = configuration.validate(); this.platform = platform; this.world = world; i("Initializing Iris Engine for " + platform.getPlatformName() + " in " + world.getName() + " with " + configuration.getThreads() + " priority " + configuration.getThreadPriority() + " threads in " + (configuration.isMutable() ? "edit mode" : "production mode")); - this.data = new EngineData(this); - this.seedManager = getSeedManager(); this.blockCache = new EngineBlockCache(this); this.registry = EngineRegistry.builder() - .blockRegistry(new PlatformRegistry<>("Block", platform.getBlocks())) - .biomeRegistry(new PlatformRegistry<>("Biome", platform.getBiomes())) - .build(); + .blockRegistry(new PlatformRegistry<>("Block", platform.getBlocks())) + .biomeRegistry(new PlatformRegistry<>("Biome", platform.getBiomes())) + .build(); + this.data = new EngineData(this).loadData( + getConfiguration().isMutable() + ? getPlatform().getStudioFolder() + : getWorld().getIrisDataFolder(), getConfiguration().getDimension()); + this.seedManager = getSeedManager(); this.executor = new EngineExecutor(this); this.plumbing = EnginePlumbing.builder().engine(this) .pipeline(EnginePipeline.builder() @@ -58,9 +60,6 @@ public class Engine implements Closeable { .build()) .build()) .build(); - data.loadData(getConfiguration().isMutable() - ? getPlatform().getStudioFolder() - : getWorld().getIrisDataFolder(), getConfiguration().getDimension()); } public PlatformBlock block(String block) diff --git a/engine/src/main/java/com/volmit/iris/engine/EngineConfiguration.java b/engine/src/main/java/com/volmit/iris/engine/EngineConfiguration.java index d15233793..332683cd4 100644 --- a/engine/src/main/java/com/volmit/iris/engine/EngineConfiguration.java +++ b/engine/src/main/java/com/volmit/iris/engine/EngineConfiguration.java @@ -8,11 +8,19 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + @Builder @Data @NoArgsConstructor @AllArgsConstructor public class EngineConfiguration { + @Builder.Default + private int chunkSize = 16; + @Builder.Default private boolean mutable = false; @@ -27,4 +35,27 @@ public class EngineConfiguration { @Builder.Default private PlatformNamespaceKey dimension = new NSK("overworld", "main"); + + public EngineConfiguration validate() throws IOException { + validateChunkSize(); + return this; + } + + private void validateChunkSize() throws IOException { + if(Arrays.binarySearch(allowedChunkSizes, chunkSize) < 0) { + throw new IOException("Invalid Chunk Size: " + chunkSize + " Allowed Chunk Sizes are: " + Arrays.toString(allowedChunkSizes)); + } + } + + private static final int[] allowedChunkSizes; + + static { + allowedChunkSizes = new int[16]; + + for(int i = 0; i < allowedChunkSizes.length; i++) { + allowedChunkSizes[i] = (int) Math.pow(2, i+1); + } + + Arrays.sort(allowedChunkSizes); // for binary sorting + } } diff --git a/engine/src/main/java/com/volmit/iris/engine/EngineData.java b/engine/src/main/java/com/volmit/iris/engine/EngineData.java index 1f0c2a84e..db8dcd3cd 100644 --- a/engine/src/main/java/com/volmit/iris/engine/EngineData.java +++ b/engine/src/main/java/com/volmit/iris/engine/EngineData.java @@ -77,7 +77,7 @@ public class EngineData implements TypeAdapterFactory { } } - public void loadData(File folder, PlatformNamespaceKey dimension) throws IOException { + public EngineData loadData(File folder, PlatformNamespaceKey dimension) throws IOException { i("Loading Data in " + folder.getPath()); for(File i : folder.listFiles()) { if(i.isDirectory() && i.getName().equals(dimension.getNamespace())) { @@ -101,6 +101,8 @@ public class EngineData implements TypeAdapterFactory { if(dim == null) { f("Failed to load dimension " + dimension); } + + return this; } private void generateCodeWorkspace(File file) throws IOException { diff --git a/engine/src/main/java/com/volmit/iris/engine/dimension/IrisBiome.java b/engine/src/main/java/com/volmit/iris/engine/dimension/IrisBiome.java index 2303b3479..2fe261fb6 100644 --- a/engine/src/main/java/com/volmit/iris/engine/dimension/IrisBiome.java +++ b/engine/src/main/java/com/volmit/iris/engine/dimension/IrisBiome.java @@ -21,4 +21,7 @@ public class IrisBiome extends EngineResolvable { @Builder.Default private IrisSurface surface = new IrisSurface(); + + @Builder.Default + private IrisRange height = IrisRange.flat(1); } diff --git a/engine/src/main/java/com/volmit/iris/engine/feature/Feature.java b/engine/src/main/java/com/volmit/iris/engine/feature/Feature.java new file mode 100644 index 000000000..da51d2ea1 --- /dev/null +++ b/engine/src/main/java/com/volmit/iris/engine/feature/Feature.java @@ -0,0 +1,33 @@ +package com.volmit.iris.engine.feature; + +import com.volmit.iris.engine.Engine; +import com.volmit.iris.platform.PlatformNamespaced; +import lombok.Data; + +@Data +public abstract class Feature { + private final String name; + private final Engine engine; + private boolean heightAgnostic; + + public Feature(String name, Engine engine) + { + this.engine = engine; + this.name = name; + this.heightAgnostic = true; + } + + public FeatureTask task(FeatureSizedTarget target, FeatureTarget origin, FeatureStorage storage, int verticalExecutionSize, int horizontalExecutionSize, FeatureTaskTiming timings) + { + return new FeatureTask<>(engine, this, storage, target, origin, verticalExecutionSize, horizontalExecutionSize, heightAgnostic, timings); + } + + public FeatureTask task(FeatureSizedTarget target, FeatureTarget origin, FeatureStorage storage, int horizontalExecutionSize, FeatureTaskTiming timings) + { + return new FeatureTask<>(engine, this, storage, target, origin, Integer.MAX_VALUE, horizontalExecutionSize, heightAgnostic, timings); + } + + public abstract S prepare(Engine engine, FeatureSizedTarget target, FeatureStorage storage); + + public abstract void generate(Engine engine, S state, FeatureTarget target, FeatureStorage storage); +} diff --git a/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureSizedTarget.java b/engine/src/main/java/com/volmit/iris/engine/feature/FeatureSizedTarget.java similarity index 60% rename from engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureSizedTarget.java rename to engine/src/main/java/com/volmit/iris/engine/feature/FeatureSizedTarget.java index 91c51ba46..bbf8bc37a 100644 --- a/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureSizedTarget.java +++ b/engine/src/main/java/com/volmit/iris/engine/feature/FeatureSizedTarget.java @@ -1,6 +1,5 @@ package com.volmit.iris.engine.feature; -import art.arcane.amulet.geometry.Vec; import art.arcane.amulet.range.IntegerRange; import art.arcane.spatial.hunk.storage.ArrayHunk; import art.arcane.spatial.hunk.view.HunkView; @@ -11,14 +10,13 @@ import lombok.Data; import lombok.NoArgsConstructor; import java.util.List; -import java.util.stream.Collectors; import java.util.stream.Stream; @Builder @NoArgsConstructor @AllArgsConstructor @Data -public class IrisFeatureSizedTarget { +public class FeatureSizedTarget { @Builder.Default private final int width = 16; @Builder.Default @@ -32,51 +30,51 @@ public class IrisFeatureSizedTarget { @Builder.Default private final int offsetZ = 0; - public IrisFeatureTarget hunked() + public FeatureTarget hunked() { - return new IrisFeatureTarget<>(new ArrayHunk<>(width, height, depth), this); + return new FeatureTarget<>(new ArrayHunk<>(width, height, depth), this); } - public IrisFeatureTarget hunked(IrisFeatureTarget origin) + public FeatureTarget hunked(FeatureTarget origin) { - return new IrisFeatureTarget<>(new HunkView<>(origin.getHunk(), width, height, depth, offsetX - origin.getOffsetX(), offsetY - origin.getOffsetY(), offsetZ - origin.getOffsetZ()), this); + return new FeatureTarget<>(new HunkView<>(origin.getHunk(), width, height, depth, offsetX - origin.getOffsetX(), offsetY - origin.getOffsetY(), offsetZ - origin.getOffsetZ()), this); } - Stream splitX() { + Stream splitX() { if(width <= 1) { return Stream.of(this); } - return Stream.of(IrisFeatureSizedTarget.builder() + return Stream.of(FeatureSizedTarget.builder() .width(width/2).height(height).depth(depth) .offsetX(offsetX).offsetY(offsetY).offsetZ(offsetZ).build(), - IrisFeatureSizedTarget.builder() + FeatureSizedTarget.builder() .width(width - (width/2)).height(height).depth(depth) .offsetX(offsetX + (width/2)).offsetY(offsetY).offsetZ(offsetZ).build()); } - Stream splitY() { + Stream splitY() { if(height <= 1) { return Stream.of(this); } - return Stream.of(IrisFeatureSizedTarget.builder() + return Stream.of(FeatureSizedTarget.builder() .width(width).height(height/2).depth(depth) .offsetX(offsetX).offsetY(offsetY).offsetZ(offsetZ).build(), - IrisFeatureSizedTarget.builder() + FeatureSizedTarget.builder() .width(width).height(height - (height / 2)).depth(depth) .offsetX(offsetX).offsetY(offsetY + (height/2)).offsetZ(offsetZ).build()); } - Stream splitZ() { + Stream splitZ() { if(depth <= 1) { return Stream.of(this); } - return Stream.of(IrisFeatureSizedTarget.builder() + return Stream.of(FeatureSizedTarget.builder() .width(width).height(height).depth(depth/2) .offsetX(offsetX).offsetY(offsetY).offsetZ(offsetZ).build(), - IrisFeatureSizedTarget.builder() + FeatureSizedTarget.builder() .width(width).height(height).depth(depth - (depth/2)) .offsetX(offsetX).offsetY(offsetY).offsetZ(offsetZ + (depth/2)).build()); } @@ -126,15 +124,15 @@ public class IrisFeatureSizedTarget { return new IntegerRange(0, getDepth() - 1); } - public static IrisFeatureSizedTarget mergedSize(Stream targets, boolean x, boolean y, boolean z) { - List t = targets.toList(); - return IrisFeatureSizedTarget.builder() - .width(x ? t.stream().mapToInt(IrisFeatureSizedTarget::getWidth).sum() : t[0].getWidth()) - .height(y ? t.stream().mapToInt(IrisFeatureSizedTarget::getHeight).sum() : t[0].getHeight()) - .depth(z ? t.stream().mapToInt(IrisFeatureSizedTarget::getDepth).sum() : t[0].getDepth()) - .offsetX(x ? t.stream().mapToInt(IrisFeatureSizedTarget::getOffsetX).min().orElse(0) : t[0].getOffsetX()) - .offsetY(y ? t.stream().mapToInt(IrisFeatureSizedTarget::getOffsetY).min().orElse(0) : t[0].getOffsetY()) - .offsetZ(z ? t.stream().mapToInt(IrisFeatureSizedTarget::getOffsetZ).min().orElse(0) : t[0].getOffsetZ()) + public static FeatureSizedTarget mergedSize(Stream targets, boolean x, boolean y, boolean z) { + List t = targets.toList(); + return FeatureSizedTarget.builder() + .width(x ? t.stream().mapToInt(FeatureSizedTarget::getWidth).sum() : t[0].getWidth()) + .height(y ? t.stream().mapToInt(FeatureSizedTarget::getHeight).sum() : t[0].getHeight()) + .depth(z ? t.stream().mapToInt(FeatureSizedTarget::getDepth).sum() : t[0].getDepth()) + .offsetX(x ? t.stream().mapToInt(FeatureSizedTarget::getOffsetX).min().orElse(0) : t[0].getOffsetX()) + .offsetY(y ? t.stream().mapToInt(FeatureSizedTarget::getOffsetY).min().orElse(0) : t[0].getOffsetY()) + .offsetZ(z ? t.stream().mapToInt(FeatureSizedTarget::getOffsetZ).min().orElse(0) : t[0].getOffsetZ()) .build(); } } diff --git a/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureState.java b/engine/src/main/java/com/volmit/iris/engine/feature/FeatureState.java similarity index 55% rename from engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureState.java rename to engine/src/main/java/com/volmit/iris/engine/feature/FeatureState.java index 71258b89e..9ad083483 100644 --- a/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureState.java +++ b/engine/src/main/java/com/volmit/iris/engine/feature/FeatureState.java @@ -1,5 +1,5 @@ package com.volmit.iris.engine.feature; -public interface IrisFeatureState { +public interface FeatureState { } diff --git a/engine/src/main/java/com/volmit/iris/engine/feature/FeatureStorage.java b/engine/src/main/java/com/volmit/iris/engine/feature/FeatureStorage.java new file mode 100644 index 000000000..d27bd00b6 --- /dev/null +++ b/engine/src/main/java/com/volmit/iris/engine/feature/FeatureStorage.java @@ -0,0 +1,22 @@ +package com.volmit.iris.engine.feature; + +import com.volmit.iris.engine.dimension.IrisBiome; +import com.volmit.iris.util.NoiseCache; +import com.volmit.iris.util.ShortNoiseCache; +import lombok.Data; + +@Data +public class FeatureStorage { + private ShortNoiseCache heightmap; + private NoiseCache biomemap; + private final int width; + private final int height; + + public FeatureStorage(int width, int height) + { + this.width = width; + this.height = height; + this.heightmap = new ShortNoiseCache(width, height); + this.biomemap = new NoiseCache<>(width, height); + } +} diff --git a/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureTarget.java b/engine/src/main/java/com/volmit/iris/engine/feature/FeatureTarget.java similarity index 53% rename from engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureTarget.java rename to engine/src/main/java/com/volmit/iris/engine/feature/FeatureTarget.java index 39c49f95d..d991b1e26 100644 --- a/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureTarget.java +++ b/engine/src/main/java/com/volmit/iris/engine/feature/FeatureTarget.java @@ -3,40 +3,36 @@ package com.volmit.iris.engine.feature; import art.arcane.spatial.hunk.Hunk; import art.arcane.spatial.hunk.view.HunkView; import com.volmit.iris.platform.PlatformNamespaced; -import lombok.AllArgsConstructor; -import lombok.Builder; import lombok.Data; import lombok.EqualsAndHashCode; -import java.util.Collections; import java.util.List; -import java.util.function.Function; import java.util.stream.Stream; @Data @EqualsAndHashCode(callSuper = true) -public class IrisFeatureTarget extends IrisFeatureSizedTarget { +public class FeatureTarget extends FeatureSizedTarget { private final Hunk hunk; - public IrisFeatureTarget(Hunk hunk, int offsetX, int offsetY, int offsetZ) + public FeatureTarget(Hunk hunk, int offsetX, int offsetY, int offsetZ) { super(hunk.getWidth(), hunk.getHeight(), hunk.getDepth(), offsetX, offsetY, offsetZ); this.hunk = hunk; } - public IrisFeatureTarget(Hunk hunk, IrisFeatureSizedTarget target) + public FeatureTarget(Hunk hunk, FeatureSizedTarget target) { this(hunk, target.getOffsetX(), target.getOffsetY(), target.getOffsetZ()); } - public static IrisFeatureTarget mergedTarget(Stream> targets, IrisFeatureTarget origin, boolean x, boolean y, boolean z) + public static FeatureTarget mergedTarget(Stream> targets, FeatureTarget origin, boolean x, boolean y, boolean z) { - List> t = targets.toList(); - IrisFeatureSizedTarget mergedSize = IrisFeatureSizedTarget.mergedSize(t.stream().map(i -> i), x, y, z); + List> t = targets.toList(); + FeatureSizedTarget mergedSize = FeatureSizedTarget.mergedSize(t.stream().map(i -> i), x, y, z); Hunk hunk = new HunkView<>(origin.getHunk(), mergedSize.getWidth(), mergedSize.getHeight(), mergedSize.getDepth(), mergedSize.getOffsetX() - origin.getOffsetX(), mergedSize.getOffsetY() - origin.getOffsetY(), mergedSize.getOffsetZ() - origin.getOffsetZ()); - return new IrisFeatureTarget<>(hunk, mergedSize); + return new FeatureTarget<>(hunk, mergedSize); } } diff --git a/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureTask.java b/engine/src/main/java/com/volmit/iris/engine/feature/FeatureTask.java similarity index 60% rename from engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureTask.java rename to engine/src/main/java/com/volmit/iris/engine/feature/FeatureTask.java index 86957fe49..d2e0ea96c 100644 --- a/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureTask.java +++ b/engine/src/main/java/com/volmit/iris/engine/feature/FeatureTask.java @@ -18,19 +18,20 @@ import java.util.concurrent.RecursiveTask; */ @Builder @AllArgsConstructor -public class IrisFeatureTask extends RecursiveTask> implements Callable> { +public class FeatureTask extends RecursiveTask> implements Callable> { private final Engine engine; - private final IrisFeature feature; - private final IrisFeatureSizedTarget size; - private final IrisFeatureTarget origin; + private final Feature feature; + private final FeatureStorage storage; + private final FeatureSizedTarget size; + private final FeatureTarget origin; private final int verticalPrepareSize; private final int horizontalPrepareSize; private final boolean heightAgnostic; - private final IrisFeatureTaskTiming timings; + private final FeatureTaskTiming timings; @Override - protected IrisFeatureTarget compute() { - IrisFeatureTarget result; + protected FeatureTarget compute() { + FeatureTarget result; PrecisionStopwatch p = null; if(timings != null) @@ -40,24 +41,24 @@ public class IrisFeatureTask verticalPrepareSize * 2) { - result = IrisFeatureTarget.mergedTarget(size.splitY() - .map(i -> engine.getExecutor().getForks().submit((ForkJoinTask>) with(i))) + result = FeatureTarget.mergedTarget(size.splitY() + .map(i -> engine.getExecutor().getForks().submit((ForkJoinTask>) with(i))) .map(ForkJoinTask::join), origin, false, true, false); } else if(size.getWidth() > horizontalPrepareSize * 2) { - result = IrisFeatureTarget.mergedTarget(size.splitX().map(i -> engine.getExecutor().getForks().submit((ForkJoinTask>) with(i))) + result = FeatureTarget.mergedTarget(size.splitX().map(i -> engine.getExecutor().getForks().submit((ForkJoinTask>) with(i))) .map(ForkJoinTask::join), origin, true, false, false); } else if(size.getDepth() > horizontalPrepareSize * 2) { - result = IrisFeatureTarget.mergedTarget(size.splitZ().map(i -> engine.getExecutor().getForks().submit((ForkJoinTask>) with(i))) + result = FeatureTarget.mergedTarget(size.splitZ().map(i -> engine.getExecutor().getForks().submit((ForkJoinTask>) with(i))) .map(ForkJoinTask::join), origin, false, false, true); } else { - IrisPreparedFeature preparedFeature = new IrisPreparedFeature<>(engine, feature, size, feature.prepare(engine, size)); - result = preparedFeature.generate(origin); + IrisPreparedFeature preparedFeature = new IrisPreparedFeature<>(engine, feature, size, feature.prepare(engine, size, storage)); + result = preparedFeature.generate(origin, storage); } if(timings != null) @@ -68,13 +69,13 @@ public class IrisFeatureTask with(IrisFeatureSizedTarget size) + private FeatureTask with(FeatureSizedTarget size) { - return new IrisFeatureTask<>(engine, feature, size, origin, verticalPrepareSize, horizontalPrepareSize, heightAgnostic, null); + return new FeatureTask<>(engine, feature, storage, size, origin, verticalPrepareSize, horizontalPrepareSize, heightAgnostic, null); } @Override - public IrisFeatureTarget call() throws Exception { + public FeatureTarget call() throws Exception { return compute(); } } diff --git a/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureTaskTiming.java b/engine/src/main/java/com/volmit/iris/engine/feature/FeatureTaskTiming.java similarity index 70% rename from engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureTaskTiming.java rename to engine/src/main/java/com/volmit/iris/engine/feature/FeatureTaskTiming.java index 14a5d6b96..04b6bb76d 100644 --- a/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureTaskTiming.java +++ b/engine/src/main/java/com/volmit/iris/engine/feature/FeatureTaskTiming.java @@ -1,6 +1,6 @@ package com.volmit.iris.engine.feature; @FunctionalInterface -public interface IrisFeatureTaskTiming { +public interface FeatureTaskTiming { void onCompleted(double ms); } diff --git a/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeature.java b/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeature.java deleted file mode 100644 index dda45969c..000000000 --- a/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeature.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.volmit.iris.engine.feature; - -import com.volmit.iris.engine.Engine; -import com.volmit.iris.platform.PlatformNamespaced; -import lombok.Data; - -@Data -public abstract class IrisFeature { - private final String name; - private final Engine engine; - private boolean heightAgnostic; - - public IrisFeature(String name, Engine engine) - { - this.engine = engine; - this.name = name; - this.heightAgnostic = true; - } - - public IrisFeatureTask task(IrisFeatureSizedTarget target, IrisFeatureTarget origin, int verticalExecutionSize, int horizontalExecutionSize, IrisFeatureTaskTiming timings) - { - return new IrisFeatureTask<>(engine, this, target, origin, verticalExecutionSize, horizontalExecutionSize, heightAgnostic, timings); - } - - public IrisFeatureTask task(IrisFeatureSizedTarget target, IrisFeatureTarget origin, int horizontalExecutionSize, IrisFeatureTaskTiming timings) - { - return new IrisFeatureTask<>(engine, this, target, origin, Integer.MAX_VALUE, horizontalExecutionSize, heightAgnostic, timings); - } - - public abstract S prepare(Engine engine, IrisFeatureSizedTarget target); - - public abstract void generate(Engine engine, S state, IrisFeatureTarget target); -} diff --git a/engine/src/main/java/com/volmit/iris/engine/feature/IrisPreparedFeature.java b/engine/src/main/java/com/volmit/iris/engine/feature/IrisPreparedFeature.java index 5b17c3b60..7c6cdde72 100644 --- a/engine/src/main/java/com/volmit/iris/engine/feature/IrisPreparedFeature.java +++ b/engine/src/main/java/com/volmit/iris/engine/feature/IrisPreparedFeature.java @@ -7,16 +7,15 @@ import lombok.Data; @Builder @Data -public class IrisPreparedFeature { +public class IrisPreparedFeature { private final Engine engine; - private final IrisFeature feature; - private final IrisFeatureSizedTarget size; + private final Feature feature; + private final FeatureSizedTarget size; private final S state; - public IrisFeatureTarget generate(IrisFeatureTarget origin) - { - IrisFeatureTarget target = size.hunked(origin); - feature.generate(engine, state, target); + public FeatureTarget generate(FeatureTarget origin, FeatureStorage storage) { + FeatureTarget target = size.hunked(origin); + feature.generate(engine, state, target, storage); return target; } } diff --git a/engine/src/main/java/com/volmit/iris/engine/feature/features/FeatureTerrain.java b/engine/src/main/java/com/volmit/iris/engine/feature/features/FeatureTerrain.java index d17f44a3b..3e58c84db 100644 --- a/engine/src/main/java/com/volmit/iris/engine/feature/features/FeatureTerrain.java +++ b/engine/src/main/java/com/volmit/iris/engine/feature/features/FeatureTerrain.java @@ -4,17 +4,13 @@ import art.arcane.amulet.range.IntegerRange; import art.arcane.source.NoisePlane; import art.arcane.source.util.NoisePreset; import com.volmit.iris.engine.Engine; -import com.volmit.iris.engine.feature.IrisFeature; -import com.volmit.iris.engine.feature.IrisFeatureSizedTarget; -import com.volmit.iris.engine.feature.IrisFeatureState; -import com.volmit.iris.engine.feature.IrisFeatureTarget; +import com.volmit.iris.engine.feature.*; import com.volmit.iris.platform.PlatformBlock; import com.volmit.iris.util.ShortNoiseCache; import lombok.AllArgsConstructor; import lombok.Data; -public class FeatureTerrain extends IrisFeature -{ +public class FeatureTerrain extends Feature { private final PlatformBlock stone; private final NoisePlane generator; @@ -26,18 +22,12 @@ public class FeatureTerrain extends IrisFeature target) { - for(int x : target.localX()) { - for(int z : target.localZ()) { + public void generate(Engine engine, TerrainFeatureState state, FeatureTarget target, FeatureStorage storage) { + for(int x : target.x()) { + for(int z : target.z()) { int h = state.getNoise().get(x, z); - for(int y : new IntegerRange(target.y().getLeftEndpoint(), Math.min(target.y().getRightEndpoint(), h))) - { + for(int y : new IntegerRange(target.y().getLeftEndpoint(), Math.min(target.y().getRightEndpoint(), h))) { target.getHunk().set(x, y, z, stone); } } @@ -59,7 +48,7 @@ public class FeatureTerrain extends IrisFeature phases; - public void generate(Engine engine, IrisFeatureSizedTarget target, PipedHunkStack stack) { + public void generate(Engine engine, FeatureSizedTarget target, PipedHunkStack stack) { + FeatureStorage storage = new FeatureStorage(engine.getConfiguration().getChunkSize(), engine.getConfiguration().getChunkSize()); + for(PipelinePhase i : phases) { - i.generate(engine, target, stack); + i.generate(engine, target, stack, storage); } } } diff --git a/engine/src/main/java/com/volmit/iris/engine/pipeline/EnginePlumbing.java b/engine/src/main/java/com/volmit/iris/engine/pipeline/EnginePlumbing.java index 805ae46d7..6ee389246 100644 --- a/engine/src/main/java/com/volmit/iris/engine/pipeline/EnginePlumbing.java +++ b/engine/src/main/java/com/volmit/iris/engine/pipeline/EnginePlumbing.java @@ -1,7 +1,7 @@ package com.volmit.iris.engine.pipeline; import com.volmit.iris.engine.Engine; -import com.volmit.iris.engine.feature.IrisFeatureSizedTarget; +import com.volmit.iris.engine.feature.FeatureSizedTarget; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -17,7 +17,7 @@ public class EnginePlumbing { @Singular private final List pipelines; - public void generate(Engine engine, IrisFeatureSizedTarget target, PipedHunkStack stack) + public void generate(Engine engine, FeatureSizedTarget target, PipedHunkStack stack) { for(EnginePipeline i : pipelines) { diff --git a/engine/src/main/java/com/volmit/iris/engine/pipeline/PipedHunkStack.java b/engine/src/main/java/com/volmit/iris/engine/pipeline/PipedHunkStack.java index 0db732dda..ccd5e35e4 100644 --- a/engine/src/main/java/com/volmit/iris/engine/pipeline/PipedHunkStack.java +++ b/engine/src/main/java/com/volmit/iris/engine/pipeline/PipedHunkStack.java @@ -1,27 +1,27 @@ package com.volmit.iris.engine.pipeline; -import com.volmit.iris.engine.feature.IrisFeatureTarget; +import com.volmit.iris.engine.feature.FeatureTarget; import com.volmit.iris.platform.PlatformNamespaced; import java.util.HashMap; import java.util.Map; public class PipedHunkStack { - private final Map, IrisFeatureTarget> hunks; + private final Map, FeatureTarget> hunks; public PipedHunkStack() { this.hunks = new HashMap<>(); } - public void register(Class clazz, IrisFeatureTarget hunk) + public void register(Class clazz, FeatureTarget hunk) { hunks.put(clazz, hunk); } @SuppressWarnings("unchecked") - public IrisFeatureTarget hunk(Class hunk) + public FeatureTarget hunk(Class hunk) { - return (IrisFeatureTarget) hunks.get(hunk); + return (FeatureTarget) hunks.get(hunk); } } diff --git a/engine/src/main/java/com/volmit/iris/engine/pipeline/PipelinePhase.java b/engine/src/main/java/com/volmit/iris/engine/pipeline/PipelinePhase.java index d8922b9dd..c1adb1ec9 100644 --- a/engine/src/main/java/com/volmit/iris/engine/pipeline/PipelinePhase.java +++ b/engine/src/main/java/com/volmit/iris/engine/pipeline/PipelinePhase.java @@ -1,8 +1,9 @@ package com.volmit.iris.engine.pipeline; import com.volmit.iris.engine.Engine; -import com.volmit.iris.engine.feature.IrisFeatureSizedTarget; -import com.volmit.iris.engine.feature.IrisFeatureTarget; +import com.volmit.iris.engine.feature.FeatureSizedTarget; +import com.volmit.iris.engine.feature.FeatureStorage; +import com.volmit.iris.engine.feature.FeatureTarget; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -20,8 +21,8 @@ public class PipelinePhase @Singular private final List> tasks; - public List> generate(Engine engine, IrisFeatureSizedTarget target, PipedHunkStack stack) { - return engine.getExecutor().getForks().invokeAll(tasks.stream().map(i -> i.task(target, stack.hunk(i.getTarget()))) + public List> generate(Engine engine, FeatureSizedTarget target, PipedHunkStack stack, FeatureStorage storage) { + return engine.getExecutor().getForks().invokeAll(tasks.stream().map(i -> i.task(target, stack.hunk(i.getTarget()), storage)) .collect(Collectors.toList())).stream().map(i -> { try { return i.get(); diff --git a/engine/src/main/java/com/volmit/iris/engine/pipeline/PipelineTask.java b/engine/src/main/java/com/volmit/iris/engine/pipeline/PipelineTask.java index fb31722c0..b3b553d02 100644 --- a/engine/src/main/java/com/volmit/iris/engine/pipeline/PipelineTask.java +++ b/engine/src/main/java/com/volmit/iris/engine/pipeline/PipelineTask.java @@ -1,11 +1,8 @@ package com.volmit.iris.engine.pipeline; import art.arcane.amulet.range.IntegerRange; +import com.volmit.iris.engine.feature.*; import com.volmit.iris.engine.optimizer.HunkSlizeConfiguration; -import com.volmit.iris.engine.feature.IrisFeature; -import com.volmit.iris.engine.feature.IrisFeatureSizedTarget; -import com.volmit.iris.engine.feature.IrisFeatureTarget; -import com.volmit.iris.engine.feature.IrisFeatureTask; import com.volmit.iris.engine.optimizer.IrisOptimizer; import com.volmit.iris.platform.PlatformNamespaced; import lombok.AllArgsConstructor; @@ -19,13 +16,13 @@ import static art.arcane.amulet.MagicalSugar.*; @Data public class PipelineTask { - private final IrisFeature feature; + private final Feature feature; private final Class target; private final IntegerRange verticalEnvelope; private final IntegerRange horizontalEnvelope; private final IrisOptimizer optimizer; - public PipelineTask(IrisFeature feature, Class target, IntegerRange verticalEnvelope, IntegerRange horizontalEnvelope) + public PipelineTask(Feature feature, Class target, IntegerRange verticalEnvelope, IntegerRange horizontalEnvelope) { this.feature = feature; this.target = target; @@ -36,13 +33,13 @@ public class PipelineTask this.optimizer = new IrisOptimizer<>(256, configurations, configurations[0], 0.75); } - public PipelineTask(IrisFeature feature, Class target) + public PipelineTask(Feature feature, Class target) { this(feature, target, 1 to 16, 1 to 16); } - public IrisFeatureTask task(IrisFeatureSizedTarget target, IrisFeatureTarget origin){ + public FeatureTask task(FeatureSizedTarget target, FeatureTarget origin, FeatureStorage storage){ HunkSlizeConfiguration configuration = optimizer.nextParameters(); - return feature.task(target, origin,configuration.getVerticalSlice(), configuration.getHorizontalSlize(), (ms) -> optimizer.report(configuration, ms)); + return feature.task(target, origin, storage, configuration.getVerticalSlice(), configuration.getHorizontalSlize(), (ms) -> optimizer.report(configuration, ms)); } } diff --git a/engine/src/main/java/com/volmit/iris/util/NoiseCache.java b/engine/src/main/java/com/volmit/iris/util/NoiseCache.java new file mode 100644 index 000000000..136a16b72 --- /dev/null +++ b/engine/src/main/java/com/volmit/iris/util/NoiseCache.java @@ -0,0 +1,23 @@ +package com.volmit.iris.util; + +public class NoiseCache { + private final int width; + private final int height; + private final Object[] cache; + + public NoiseCache(int width, int height) + { + this.width = width; + this.height = height; + cache = new Object[width * height]; + } + + public void set(int x, int y, T v) { + this.cache[y % this.height * this.width + x % this.width] = v; + } + + @SuppressWarnings("unchecked") + public T get(int x, int y) { + return (T) this.cache[y % this.height * this.width + x % this.width]; + } +}