mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-03 08:26:11 +00:00
Fixes
This commit is contained in:
parent
e88519f474
commit
0a72a1acfc
@ -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<PlatformBlock> 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<PlatformBlock> blockTarget = new IrisFeatureTarget<>(chunk, targetSize);
|
||||
FeatureTarget<PlatformBlock> blockTarget = new FeatureTarget<>(chunk, targetSize);
|
||||
PipedHunkStack stack = new PipedHunkStack();
|
||||
stack.register(PlatformBlock.class, blockTarget);
|
||||
engine.get().getPlumbing().generate(engine.get(), targetSize, stack);
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -21,4 +21,7 @@ public class IrisBiome extends EngineResolvable {
|
||||
|
||||
@Builder.Default
|
||||
private IrisSurface surface = new IrisSurface();
|
||||
|
||||
@Builder.Default
|
||||
private IrisRange height = IrisRange.flat(1);
|
||||
}
|
||||
|
@ -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<T extends PlatformNamespaced, S extends FeatureState> {
|
||||
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<T, S> task(FeatureSizedTarget target, FeatureTarget<T> origin, FeatureStorage storage, int verticalExecutionSize, int horizontalExecutionSize, FeatureTaskTiming timings)
|
||||
{
|
||||
return new FeatureTask<>(engine, this, storage, target, origin, verticalExecutionSize, horizontalExecutionSize, heightAgnostic, timings);
|
||||
}
|
||||
|
||||
public FeatureTask<T, S> task(FeatureSizedTarget target, FeatureTarget<T> 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<T> target, FeatureStorage storage);
|
||||
}
|
@ -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 <T extends PlatformNamespaced> IrisFeatureTarget<T> hunked()
|
||||
public <T extends PlatformNamespaced> FeatureTarget<T> hunked()
|
||||
{
|
||||
return new IrisFeatureTarget<>(new ArrayHunk<>(width, height, depth), this);
|
||||
return new FeatureTarget<>(new ArrayHunk<>(width, height, depth), this);
|
||||
}
|
||||
|
||||
public <T extends PlatformNamespaced> IrisFeatureTarget<T> hunked(IrisFeatureTarget<T> origin)
|
||||
public <T extends PlatformNamespaced> FeatureTarget<T> hunked(FeatureTarget<T> 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<IrisFeatureSizedTarget> splitX() {
|
||||
Stream<FeatureSizedTarget> 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<IrisFeatureSizedTarget> splitY() {
|
||||
Stream<FeatureSizedTarget> 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<IrisFeatureSizedTarget> splitZ() {
|
||||
Stream<FeatureSizedTarget> 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<IrisFeatureSizedTarget> targets, boolean x, boolean y, boolean z) {
|
||||
List<IrisFeatureSizedTarget> 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<FeatureSizedTarget> targets, boolean x, boolean y, boolean z) {
|
||||
List<FeatureSizedTarget> 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();
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
package com.volmit.iris.engine.feature;
|
||||
|
||||
public interface IrisFeatureState {
|
||||
public interface FeatureState {
|
||||
|
||||
}
|
@ -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<IrisBiome> 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);
|
||||
}
|
||||
}
|
@ -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<T extends PlatformNamespaced> extends IrisFeatureSizedTarget {
|
||||
public class FeatureTarget<T extends PlatformNamespaced> extends FeatureSizedTarget {
|
||||
private final Hunk<T> hunk;
|
||||
|
||||
public IrisFeatureTarget(Hunk<T> hunk, int offsetX, int offsetY, int offsetZ)
|
||||
public FeatureTarget(Hunk<T> hunk, int offsetX, int offsetY, int offsetZ)
|
||||
{
|
||||
super(hunk.getWidth(), hunk.getHeight(), hunk.getDepth(), offsetX, offsetY, offsetZ);
|
||||
this.hunk = hunk;
|
||||
}
|
||||
|
||||
public IrisFeatureTarget(Hunk<T> hunk, IrisFeatureSizedTarget target)
|
||||
public FeatureTarget(Hunk<T> hunk, FeatureSizedTarget target)
|
||||
{
|
||||
this(hunk, target.getOffsetX(), target.getOffsetY(), target.getOffsetZ());
|
||||
}
|
||||
|
||||
public static <V extends PlatformNamespaced> IrisFeatureTarget<V> mergedTarget(Stream<IrisFeatureTarget<V>> targets, IrisFeatureTarget<V> origin, boolean x, boolean y, boolean z)
|
||||
public static <V extends PlatformNamespaced> FeatureTarget<V> mergedTarget(Stream<FeatureTarget<V>> targets, FeatureTarget<V> origin, boolean x, boolean y, boolean z)
|
||||
{
|
||||
List<IrisFeatureTarget<V>> t = targets.toList();
|
||||
IrisFeatureSizedTarget mergedSize = IrisFeatureSizedTarget.mergedSize(t.stream().map(i -> i), x, y, z);
|
||||
List<FeatureTarget<V>> t = targets.toList();
|
||||
FeatureSizedTarget mergedSize = FeatureSizedTarget.mergedSize(t.stream().map(i -> i), x, y, z);
|
||||
Hunk<V> 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);
|
||||
}
|
||||
}
|
@ -18,19 +18,20 @@ import java.util.concurrent.RecursiveTask;
|
||||
*/
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
public class IrisFeatureTask<T extends PlatformNamespaced, S extends IrisFeatureState> extends RecursiveTask<IrisFeatureTarget<T>> implements Callable<IrisFeatureTarget<T>> {
|
||||
public class FeatureTask<T extends PlatformNamespaced, S extends FeatureState> extends RecursiveTask<FeatureTarget<T>> implements Callable<FeatureTarget<T>> {
|
||||
private final Engine engine;
|
||||
private final IrisFeature<T, S> feature;
|
||||
private final IrisFeatureSizedTarget size;
|
||||
private final IrisFeatureTarget<T> origin;
|
||||
private final Feature<T, S> feature;
|
||||
private final FeatureStorage storage;
|
||||
private final FeatureSizedTarget size;
|
||||
private final FeatureTarget<T> origin;
|
||||
private final int verticalPrepareSize;
|
||||
private final int horizontalPrepareSize;
|
||||
private final boolean heightAgnostic;
|
||||
private final IrisFeatureTaskTiming timings;
|
||||
private final FeatureTaskTiming timings;
|
||||
|
||||
@Override
|
||||
protected IrisFeatureTarget<T> compute() {
|
||||
IrisFeatureTarget<T> result;
|
||||
protected FeatureTarget<T> compute() {
|
||||
FeatureTarget<T> result;
|
||||
PrecisionStopwatch p = null;
|
||||
|
||||
if(timings != null)
|
||||
@ -40,24 +41,24 @@ public class IrisFeatureTask<T extends PlatformNamespaced, S extends IrisFeature
|
||||
|
||||
if(!heightAgnostic && size.getHeight() > verticalPrepareSize * 2) {
|
||||
|
||||
result = IrisFeatureTarget.mergedTarget(size.splitY()
|
||||
.map(i -> engine.getExecutor().getForks().submit((ForkJoinTask<IrisFeatureTarget<T>>) with(i)))
|
||||
result = FeatureTarget.mergedTarget(size.splitY()
|
||||
.map(i -> engine.getExecutor().getForks().submit((ForkJoinTask<FeatureTarget<T>>) 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<IrisFeatureTarget<T>>) with(i)))
|
||||
result = FeatureTarget.mergedTarget(size.splitX().map(i -> engine.getExecutor().getForks().submit((ForkJoinTask<FeatureTarget<T>>) 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<IrisFeatureTarget<T>>) with(i)))
|
||||
result = FeatureTarget.mergedTarget(size.splitZ().map(i -> engine.getExecutor().getForks().submit((ForkJoinTask<FeatureTarget<T>>) with(i)))
|
||||
.map(ForkJoinTask::join), origin, false, false, true);
|
||||
}
|
||||
|
||||
else {
|
||||
IrisPreparedFeature<T, S> preparedFeature = new IrisPreparedFeature<>(engine, feature, size, feature.prepare(engine, size));
|
||||
result = preparedFeature.generate(origin);
|
||||
IrisPreparedFeature<T, S> 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<T extends PlatformNamespaced, S extends IrisFeature
|
||||
return result;
|
||||
}
|
||||
|
||||
private IrisFeatureTask<T, S> with(IrisFeatureSizedTarget size)
|
||||
private FeatureTask<T, S> 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<T> call() throws Exception {
|
||||
public FeatureTarget<T> call() throws Exception {
|
||||
return compute();
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package com.volmit.iris.engine.feature;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface IrisFeatureTaskTiming {
|
||||
public interface FeatureTaskTiming {
|
||||
void onCompleted(double ms);
|
||||
}
|
@ -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<T extends PlatformNamespaced, S extends IrisFeatureState> {
|
||||
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<T, S> task(IrisFeatureSizedTarget target, IrisFeatureTarget<T> origin, int verticalExecutionSize, int horizontalExecutionSize, IrisFeatureTaskTiming timings)
|
||||
{
|
||||
return new IrisFeatureTask<>(engine, this, target, origin, verticalExecutionSize, horizontalExecutionSize, heightAgnostic, timings);
|
||||
}
|
||||
|
||||
public IrisFeatureTask<T, S> task(IrisFeatureSizedTarget target, IrisFeatureTarget<T> 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<T> target);
|
||||
}
|
@ -7,16 +7,15 @@ import lombok.Data;
|
||||
|
||||
@Builder
|
||||
@Data
|
||||
public class IrisPreparedFeature<T extends PlatformNamespaced, S extends IrisFeatureState> {
|
||||
public class IrisPreparedFeature<T extends PlatformNamespaced, S extends FeatureState> {
|
||||
private final Engine engine;
|
||||
private final IrisFeature<T, S> feature;
|
||||
private final IrisFeatureSizedTarget size;
|
||||
private final Feature<T, S> feature;
|
||||
private final FeatureSizedTarget size;
|
||||
private final S state;
|
||||
|
||||
public IrisFeatureTarget<T> generate(IrisFeatureTarget<T> origin)
|
||||
{
|
||||
IrisFeatureTarget<T> target = size.hunked(origin);
|
||||
feature.generate(engine, state, target);
|
||||
public FeatureTarget<T> generate(FeatureTarget<T> origin, FeatureStorage storage) {
|
||||
FeatureTarget<T> target = size.hunked(origin);
|
||||
feature.generate(engine, state, target, storage);
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
@ -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<PlatformBlock, FeatureTerrain.TerrainFeatureState>
|
||||
{
|
||||
public class FeatureTerrain extends Feature<PlatformBlock, FeatureTerrain.TerrainFeatureState> {
|
||||
private final PlatformBlock stone;
|
||||
private final NoisePlane generator;
|
||||
|
||||
@ -26,18 +22,12 @@ public class FeatureTerrain extends IrisFeature<PlatformBlock, FeatureTerrain.Te
|
||||
}
|
||||
|
||||
@Override
|
||||
public TerrainFeatureState prepare(Engine engine, IrisFeatureSizedTarget target) {
|
||||
final ShortNoiseCache noise = new ShortNoiseCache(target.getWidth(), target.getDepth());
|
||||
int cx,cz;
|
||||
public TerrainFeatureState prepare(Engine engine, FeatureSizedTarget target, FeatureStorage storage) {
|
||||
final ShortNoiseCache noise = storage.getHeightmap();
|
||||
|
||||
for(int x : target.x())
|
||||
{
|
||||
cx = x - target.getOffsetX();
|
||||
|
||||
for(int z : target.z())
|
||||
{
|
||||
cz = z - target.getOffsetZ();
|
||||
noise.set(cx, cz, (short) generator.noise(x, z));
|
||||
for(int x : target.x()) {
|
||||
for(int z : target.z()) {
|
||||
noise.set(x & storage.getWidth() - 1, z & storage.getHeight() - 1, (short) generator.noise(x, z));
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,12 +35,11 @@ public class FeatureTerrain extends IrisFeature<PlatformBlock, FeatureTerrain.Te
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(Engine engine, TerrainFeatureState state, IrisFeatureTarget<PlatformBlock> target) {
|
||||
for(int x : target.localX()) {
|
||||
for(int z : target.localZ()) {
|
||||
public void generate(Engine engine, TerrainFeatureState state, FeatureTarget<PlatformBlock> 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<PlatformBlock, FeatureTerrain.Te
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public static class TerrainFeatureState implements IrisFeatureState {
|
||||
public static class TerrainFeatureState implements FeatureState {
|
||||
private final ShortNoiseCache noise;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
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 com.volmit.iris.engine.feature.FeatureStorage;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
@ -17,9 +18,11 @@ public class EnginePipeline
|
||||
@Singular
|
||||
private final List<PipelinePhase> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<EnginePipeline> pipelines;
|
||||
|
||||
public void generate(Engine engine, IrisFeatureSizedTarget target, PipedHunkStack stack)
|
||||
public void generate(Engine engine, FeatureSizedTarget target, PipedHunkStack stack)
|
||||
{
|
||||
for(EnginePipeline i : pipelines)
|
||||
{
|
||||
|
@ -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<Class<? extends PlatformNamespaced>, IrisFeatureTarget<? extends PlatformNamespaced>> hunks;
|
||||
private final Map<Class<? extends PlatformNamespaced>, FeatureTarget<? extends PlatformNamespaced>> hunks;
|
||||
|
||||
public PipedHunkStack()
|
||||
{
|
||||
this.hunks = new HashMap<>();
|
||||
}
|
||||
|
||||
public void register(Class<? extends PlatformNamespaced> clazz, IrisFeatureTarget<? extends PlatformNamespaced> hunk)
|
||||
public void register(Class<? extends PlatformNamespaced> clazz, FeatureTarget<? extends PlatformNamespaced> hunk)
|
||||
{
|
||||
hunks.put(clazz, hunk);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends PlatformNamespaced> IrisFeatureTarget<T> hunk(Class<?> hunk)
|
||||
public <T extends PlatformNamespaced> FeatureTarget<T> hunk(Class<?> hunk)
|
||||
{
|
||||
return (IrisFeatureTarget<T>) hunks.get(hunk);
|
||||
return (FeatureTarget<T>) hunks.get(hunk);
|
||||
}
|
||||
}
|
||||
|
@ -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<PipelineTask<?>> tasks;
|
||||
|
||||
public List<IrisFeatureTarget<?>> 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<FeatureTarget<?>> 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();
|
||||
|
@ -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<T extends PlatformNamespaced>
|
||||
{
|
||||
private final IrisFeature<T, ?> feature;
|
||||
private final Feature<T, ?> feature;
|
||||
private final Class<T> target;
|
||||
private final IntegerRange verticalEnvelope;
|
||||
private final IntegerRange horizontalEnvelope;
|
||||
private final IrisOptimizer<HunkSlizeConfiguration> optimizer;
|
||||
|
||||
public PipelineTask(IrisFeature<T, ?> feature, Class<T> target, IntegerRange verticalEnvelope, IntegerRange horizontalEnvelope)
|
||||
public PipelineTask(Feature<T, ?> feature, Class<T> target, IntegerRange verticalEnvelope, IntegerRange horizontalEnvelope)
|
||||
{
|
||||
this.feature = feature;
|
||||
this.target = target;
|
||||
@ -36,13 +33,13 @@ public class PipelineTask<T extends PlatformNamespaced>
|
||||
this.optimizer = new IrisOptimizer<>(256, configurations, configurations[0], 0.75);
|
||||
}
|
||||
|
||||
public PipelineTask(IrisFeature<T, ?> feature, Class<T> target)
|
||||
public PipelineTask(Feature<T, ?> feature, Class<T> target)
|
||||
{
|
||||
this(feature, target, 1 to 16, 1 to 16);
|
||||
}
|
||||
|
||||
public IrisFeatureTask<T, ?> task(IrisFeatureSizedTarget target, IrisFeatureTarget<T> origin){
|
||||
public FeatureTask<T, ?> task(FeatureSizedTarget target, FeatureTarget<T> 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));
|
||||
}
|
||||
}
|
||||
|
23
engine/src/main/java/com/volmit/iris/util/NoiseCache.java
Normal file
23
engine/src/main/java/com/volmit/iris/util/NoiseCache.java
Normal file
@ -0,0 +1,23 @@
|
||||
package com.volmit.iris.util;
|
||||
|
||||
public class NoiseCache<T> {
|
||||
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];
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user