mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-02 07:56:48 +00:00
ffs
This commit is contained in:
parent
4f53b058fa
commit
5d6224db08
@ -1,6 +1,7 @@
|
|||||||
package com.volmit.iris.platform.bukkit;
|
package com.volmit.iris.platform.bukkit;
|
||||||
|
|
||||||
import art.arcane.amulet.io.IO;
|
import art.arcane.amulet.io.IO;
|
||||||
|
import art.arcane.amulet.logging.LogListener;
|
||||||
import com.volmit.iris.engine.EngineConfiguration;
|
import com.volmit.iris.engine.EngineConfiguration;
|
||||||
import com.volmit.iris.platform.IrisPlatform;
|
import com.volmit.iris.platform.IrisPlatform;
|
||||||
import com.volmit.iris.platform.PlatformBiome;
|
import com.volmit.iris.platform.PlatformBiome;
|
||||||
@ -14,10 +15,13 @@ import com.volmit.iris.platform.bukkit.wrapper.BukkitWorld;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Warning;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.WorldCreator;
|
import org.bukkit.WorldCreator;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
|
import org.bukkit.command.ConsoleCommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
@ -29,11 +33,16 @@ import java.util.Arrays;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class IrisBukkit extends JavaPlugin implements IrisPlatform {
|
public class IrisBukkit extends JavaPlugin implements IrisPlatform, LogListener {
|
||||||
|
private static final String TAG = ChatColor.DARK_GRAY + "[" + ChatColor.GREEN + "Iris" + ChatColor.DARK_GREEN + "/";
|
||||||
|
private static final String TAG_STRIPPED = ChatColor.stripColor(TAG);
|
||||||
private static IrisBukkit instance;
|
private static IrisBukkit instance;
|
||||||
|
private ConsoleCommandSender consoleSender;
|
||||||
|
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
instance = this;
|
instance = this;
|
||||||
|
consoleSender = Bukkit.getConsoleSender();
|
||||||
|
LogListener.listener.set(this);
|
||||||
|
|
||||||
getServer().getScheduler().scheduleSyncDelayedTask(this, () -> {
|
getServer().getScheduler().scheduleSyncDelayedTask(this, () -> {
|
||||||
World world = Bukkit.createWorld(new WorldCreator("iristests/" + UUID.randomUUID()).generator(new IrisBukkitChunkGenerator(this, EngineConfiguration.builder()
|
World world = Bukkit.createWorld(new WorldCreator("iristests/" + UUID.randomUUID()).generator(new IrisBukkitChunkGenerator(this, EngineConfiguration.builder()
|
||||||
@ -84,6 +93,36 @@ public class IrisBukkit extends JavaPlugin implements IrisPlatform {
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void messageConsole(String color, String key, Object o) {
|
||||||
|
try {
|
||||||
|
consoleSender.sendMessage(TAG + key + ChatColor.DARK_GRAY + "]: " + color + o.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
catch(Throwable e) {
|
||||||
|
System.out.println(TAG_STRIPPED + key + "]: " + o.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void logError(String k, Object o) {
|
||||||
|
messageConsole(ChatColor.RED.toString(), k, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void logInfo(String k, Object o) {
|
||||||
|
messageConsole(ChatColor.WHITE.toString(), k, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void logWarning(String k, Object o) {
|
||||||
|
messageConsole(ChatColor.YELLOW.toString(), k, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void logDebug(String k, Object o) {
|
||||||
|
messageConsole(ChatColor.GRAY.toString(), k, o);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPlatformName() {
|
public String getPlatformName() {
|
||||||
return "Bukkit";
|
return "Bukkit";
|
||||||
@ -155,4 +194,24 @@ public class IrisBukkit extends JavaPlugin implements IrisPlatform {
|
|||||||
.timings(true)
|
.timings(true)
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void i(String s, Object o) {
|
||||||
|
logInfo(s, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void f(String s, Object o) {
|
||||||
|
logError(s, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void w(String s, Object o) {
|
||||||
|
logWarning(s, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void d(String s, Object o) {
|
||||||
|
logDebug(s, o);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,11 +10,15 @@ import com.volmit.iris.engine.feature.FeatureTarget;
|
|||||||
import com.volmit.iris.engine.pipeline.PipedHunkStack;
|
import com.volmit.iris.engine.pipeline.PipedHunkStack;
|
||||||
import com.volmit.iris.platform.IrisPlatform;
|
import com.volmit.iris.platform.IrisPlatform;
|
||||||
import com.volmit.iris.platform.block.PlatformBlock;
|
import com.volmit.iris.platform.block.PlatformBlock;
|
||||||
|
import com.volmit.iris.platform.bukkit.util.StaticBiomeProvider;
|
||||||
import com.volmit.iris.platform.bukkit.wrapper.BukkitWorld;
|
import com.volmit.iris.platform.bukkit.wrapper.BukkitWorld;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.block.Biome;
|
||||||
|
import org.bukkit.generator.BiomeProvider;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
import com.volmit.iris.platform.bukkit.util.ChunkDataHunkView;
|
import com.volmit.iris.platform.bukkit.util.ChunkDataHunkView;
|
||||||
|
import org.bukkit.generator.WorldInfo;
|
||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -31,13 +35,15 @@ public class IrisBukkitChunkGenerator extends ChunkGenerator implements Closeabl
|
|||||||
private final AtomicInteger perSecond;
|
private final AtomicInteger perSecond;
|
||||||
private final PrecisionStopwatch p = PrecisionStopwatch.start();
|
private final PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||||
private final Average a = new Average(128);
|
private final Average a = new Average(128);
|
||||||
|
private final StaticBiomeProvider staticBiomeProvider;
|
||||||
|
|
||||||
public IrisBukkitChunkGenerator(IrisPlatform platform, EngineConfiguration configuration) {
|
public IrisBukkitChunkGenerator(IrisPlatform platform, EngineConfiguration configuration) {
|
||||||
this.perSecond = new AtomicInteger(0);
|
this.perSecond = new AtomicInteger(0);
|
||||||
this.platform = platform;
|
this.platform = platform;
|
||||||
this.configuration = configuration;
|
this.configuration = configuration;
|
||||||
engine = new AtomicReference<>();
|
this.staticBiomeProvider = new StaticBiomeProvider(Biome.PLAINS);
|
||||||
engineLock = new ReentrantLock();
|
this.engine = new AtomicReference<>();
|
||||||
|
this.engineLock = new ReentrantLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -94,8 +100,48 @@ public class IrisBukkitChunkGenerator extends ChunkGenerator implements Closeabl
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeProvider getDefaultBiomeProvider(WorldInfo worldInfo) {
|
||||||
|
return staticBiomeProvider;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
engine.get().close();
|
engine.get().close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldGenerateNoise() {
|
||||||
|
return super.shouldGenerateNoise();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldGenerateSurface() {
|
||||||
|
return super.shouldGenerateSurface();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldGenerateBedrock() {
|
||||||
|
return super.shouldGenerateBedrock();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldGenerateCaves() {
|
||||||
|
return super.shouldGenerateCaves();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldGenerateDecorations() {
|
||||||
|
return super.shouldGenerateDecorations();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldGenerateMobs() {
|
||||||
|
return super.shouldGenerateMobs();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldGenerateStructures() {
|
||||||
|
return super.shouldGenerateStructures();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.volmit.iris.platform.bukkit.util;
|
||||||
|
|
||||||
|
import org.bukkit.block.Biome;
|
||||||
|
import org.bukkit.generator.BiomeProvider;
|
||||||
|
import org.bukkit.generator.WorldInfo;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class StaticBiomeProvider extends BiomeProvider {
|
||||||
|
private static final List<Biome> ALL_BIOMES = Arrays.stream(Biome.values()).without((i) -> i.equals(Biome.CUSTOM)).toList().unmodifiable();
|
||||||
|
private final Biome defaultBiome;
|
||||||
|
|
||||||
|
public StaticBiomeProvider(Biome defaultBiome) {
|
||||||
|
this.defaultBiome = defaultBiome;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Biome getBiome(WorldInfo worldInfo, int x, int y, int z) {
|
||||||
|
return defaultBiome;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Biome> getBiomes(WorldInfo worldInfo) {
|
||||||
|
return ALL_BIOMES;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package com.volmit.iris.engine;
|
package com.volmit.iris.engine;
|
||||||
|
|
||||||
|
import com.volmit.iris.engine.feature.features.FeatureError;
|
||||||
import com.volmit.iris.engine.feature.features.FeatureTerrain;
|
import com.volmit.iris.engine.feature.features.FeatureTerrain;
|
||||||
import com.volmit.iris.engine.pipeline.EnginePipeline;
|
import com.volmit.iris.engine.pipeline.EnginePipeline;
|
||||||
import com.volmit.iris.engine.pipeline.EnginePlumbing;
|
import com.volmit.iris.engine.pipeline.EnginePlumbing;
|
||||||
@ -51,6 +52,11 @@ public class Engine implements Closeable {
|
|||||||
this.seedManager = getSeedManager();
|
this.seedManager = getSeedManager();
|
||||||
this.executor = new EngineExecutor(this);
|
this.executor = new EngineExecutor(this);
|
||||||
this.plumbing = EnginePlumbing.builder().engine(this)
|
this.plumbing = EnginePlumbing.builder().engine(this)
|
||||||
|
.errorPipeline(EnginePipeline.builder()
|
||||||
|
.phase(PipelinePhase.builder()
|
||||||
|
.task(new PipelineTask<>(new FeatureError(this), PlatformBlock.class))
|
||||||
|
.build())
|
||||||
|
.build())
|
||||||
.pipeline(EnginePipeline.builder()
|
.pipeline(EnginePipeline.builder()
|
||||||
.phase(PipelinePhase.builder()
|
.phase(PipelinePhase.builder()
|
||||||
.task(new PipelineTask<>(new FeatureTerrain(this), PlatformBlock.class))
|
.task(new PipelineTask<>(new FeatureTerrain(this), PlatformBlock.class))
|
||||||
@ -59,18 +65,15 @@ public class Engine implements Closeable {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlatformBlock block(String block)
|
public PlatformBlock block(String block) {
|
||||||
{
|
|
||||||
return blockCache.get(block);
|
return blockCache.get(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlatformNamespaceKey key(String nsk)
|
public PlatformNamespaceKey key(String nsk) {
|
||||||
{
|
|
||||||
return getPlatform().key(nsk);
|
return getPlatform().key(nsk);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Optional<Engine> context()
|
public static Optional<Engine> context() {
|
||||||
{
|
|
||||||
WeakReference<Engine> reference = engineContext.get(Thread.currentThread());
|
WeakReference<Engine> reference = engineContext.get(Thread.currentThread());
|
||||||
|
|
||||||
if(reference != null)
|
if(reference != null)
|
||||||
|
@ -8,12 +8,14 @@ import lombok.Data;
|
|||||||
public abstract class Feature<T extends PlatformNamespaced, S extends FeatureState> {
|
public abstract class Feature<T extends PlatformNamespaced, S extends FeatureState> {
|
||||||
private final String name;
|
private final String name;
|
||||||
private final Engine engine;
|
private final Engine engine;
|
||||||
|
private boolean optimize;
|
||||||
private boolean heightAgnostic;
|
private boolean heightAgnostic;
|
||||||
|
|
||||||
public Feature(String name, Engine engine)
|
public Feature(String name, Engine engine)
|
||||||
{
|
{
|
||||||
this.engine = engine;
|
this.engine = engine;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.optimize = true;
|
||||||
this.heightAgnostic = true;
|
this.heightAgnostic = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,13 +45,13 @@ public class FeatureSizedTarget {
|
|||||||
if(width <= 1) {
|
if(width <= 1) {
|
||||||
return Stream.of(this);
|
return Stream.of(this);
|
||||||
}
|
}
|
||||||
|
int wo2 = width/2;
|
||||||
return Stream.of(FeatureSizedTarget.builder()
|
return Stream.of(FeatureSizedTarget.builder()
|
||||||
.width(width/2).height(height).depth(depth)
|
.width(wo2).height(height).depth(depth)
|
||||||
.offsetX(offsetX).offsetY(offsetY).offsetZ(offsetZ).build(),
|
.offsetX(offsetX).offsetY(offsetY).offsetZ(offsetZ).build(),
|
||||||
FeatureSizedTarget.builder()
|
FeatureSizedTarget.builder()
|
||||||
.width(width - (width/2)).height(height).depth(depth)
|
.width(width - wo2).height(height).depth(depth)
|
||||||
.offsetX(offsetX + (width/2)).offsetY(offsetY).offsetZ(offsetZ).build());
|
.offsetX(offsetX + wo2).offsetY(offsetY).offsetZ(offsetZ).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<FeatureSizedTarget> splitY() {
|
Stream<FeatureSizedTarget> splitY() {
|
||||||
@ -59,12 +59,13 @@ public class FeatureSizedTarget {
|
|||||||
return Stream.of(this);
|
return Stream.of(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ho2 = height / 2;
|
||||||
return Stream.of(FeatureSizedTarget.builder()
|
return Stream.of(FeatureSizedTarget.builder()
|
||||||
.width(width).height(height/2).depth(depth)
|
.width(width).height(ho2).depth(depth)
|
||||||
.offsetX(offsetX).offsetY(offsetY).offsetZ(offsetZ).build(),
|
.offsetX(offsetX).offsetY(offsetY).offsetZ(offsetZ).build(),
|
||||||
FeatureSizedTarget.builder()
|
FeatureSizedTarget.builder()
|
||||||
.width(width).height(height - (height / 2)).depth(depth)
|
.width(width).height(height - ho2).depth(depth)
|
||||||
.offsetX(offsetX).offsetY(offsetY + (height/2)).offsetZ(offsetZ).build());
|
.offsetX(offsetX).offsetY(offsetY + ho2).offsetZ(offsetZ).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<FeatureSizedTarget> splitZ() {
|
Stream<FeatureSizedTarget> splitZ() {
|
||||||
@ -72,12 +73,13 @@ public class FeatureSizedTarget {
|
|||||||
return Stream.of(this);
|
return Stream.of(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int do2 = depth / 2;
|
||||||
return Stream.of(FeatureSizedTarget.builder()
|
return Stream.of(FeatureSizedTarget.builder()
|
||||||
.width(width).height(height).depth(depth/2)
|
.width(width).height(height).depth(do2)
|
||||||
.offsetX(offsetX).offsetY(offsetY).offsetZ(offsetZ).build(),
|
.offsetX(offsetX).offsetY(offsetY).offsetZ(offsetZ).build(),
|
||||||
FeatureSizedTarget.builder()
|
FeatureSizedTarget.builder()
|
||||||
.width(width).height(height).depth(depth - (depth/2))
|
.width(width).height(height).depth(depth - do2)
|
||||||
.offsetX(offsetX).offsetY(offsetY).offsetZ(offsetZ + (depth/2)).build());
|
.offsetX(offsetX).offsetY(offsetY).offsetZ(offsetZ + do2).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getAbsoluteMaxX()
|
public int getAbsoluteMaxX()
|
||||||
|
@ -34,13 +34,11 @@ public class FeatureTask<T extends PlatformNamespaced, S extends FeatureState> e
|
|||||||
FeatureTarget<T> result;
|
FeatureTarget<T> result;
|
||||||
PrecisionStopwatch p = null;
|
PrecisionStopwatch p = null;
|
||||||
|
|
||||||
if(timings != null)
|
if(timings != null) {
|
||||||
{
|
|
||||||
p = PrecisionStopwatch.start();
|
p = PrecisionStopwatch.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!heightAgnostic && size.getHeight() > verticalPrepareSize * 2) {
|
if(!heightAgnostic && size.getHeight() > verticalPrepareSize * 2) {
|
||||||
|
|
||||||
result = FeatureTarget.mergedTarget(size.splitY()
|
result = FeatureTarget.mergedTarget(size.splitY()
|
||||||
.map(i -> engine.getExecutor().getForks().submit((ForkJoinTask<FeatureTarget<T>>) with(i)))
|
.map(i -> engine.getExecutor().getForks().submit((ForkJoinTask<FeatureTarget<T>>) with(i)))
|
||||||
.map(ForkJoinTask::join), origin, false, true, false);
|
.map(ForkJoinTask::join), origin, false, true, false);
|
||||||
@ -61,8 +59,7 @@ public class FeatureTask<T extends PlatformNamespaced, S extends FeatureState> e
|
|||||||
result = preparedFeature.generate(origin, storage);
|
result = preparedFeature.generate(origin, storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(timings != null)
|
if(timings != null) {
|
||||||
{
|
|
||||||
timings.onCompleted(p.getMilliseconds());
|
timings.onCompleted(p.getMilliseconds());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.volmit.iris.engine.feature.features;
|
||||||
|
|
||||||
|
import com.volmit.iris.engine.Engine;
|
||||||
|
import com.volmit.iris.engine.feature.Feature;
|
||||||
|
import com.volmit.iris.engine.feature.FeatureSizedTarget;
|
||||||
|
import com.volmit.iris.engine.feature.FeatureState;
|
||||||
|
import com.volmit.iris.engine.feature.FeatureStorage;
|
||||||
|
import com.volmit.iris.engine.feature.FeatureTarget;
|
||||||
|
import com.volmit.iris.platform.block.PlatformBlock;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
public class FeatureError extends Feature<PlatformBlock, FeatureError.State> {
|
||||||
|
private static final State DEFAULT_STATE = new State();
|
||||||
|
private final PlatformBlock ERROR_BLOCK;
|
||||||
|
|
||||||
|
public FeatureError(Engine engine) {
|
||||||
|
super("error", engine);
|
||||||
|
setOptimize(false);
|
||||||
|
ERROR_BLOCK = engine.block("red_sandstone");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public State prepare(Engine engine, FeatureSizedTarget target, FeatureStorage storage) {
|
||||||
|
return DEFAULT_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(Engine engine, State state, FeatureTarget<PlatformBlock> target, FeatureStorage storage) {
|
||||||
|
target.forXZ((x, z) -> target.forYCap((y -> target.getHunk().set(x, y, z, ERROR_BLOCK)), 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class State implements FeatureState {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,40 +1,73 @@
|
|||||||
package com.volmit.iris.engine.feature.features;
|
package com.volmit.iris.engine.feature.features;
|
||||||
|
|
||||||
import art.arcane.source.NoisePlane;
|
import art.arcane.source.NoisePlane;
|
||||||
|
import art.arcane.source.interpolator.CubicInterpolator;
|
||||||
|
import art.arcane.source.interpolator.Interpolator;
|
||||||
|
import art.arcane.source.interpolator.LinearInterpolator;
|
||||||
|
import art.arcane.source.interpolator.StarcastInterpolator;
|
||||||
|
import art.arcane.source.noise.provider.MirroredCacheProvider;
|
||||||
import art.arcane.source.util.NoisePreset;
|
import art.arcane.source.util.NoisePreset;
|
||||||
|
import art.arcane.spatial.hunk.Hunk;
|
||||||
|
import art.arcane.spatial.hunk.storage.ArrayHunk;
|
||||||
import com.volmit.iris.engine.Engine;
|
import com.volmit.iris.engine.Engine;
|
||||||
import com.volmit.iris.engine.feature.*;
|
import com.volmit.iris.engine.feature.*;
|
||||||
import com.volmit.iris.platform.block.PlatformBlock;
|
import com.volmit.iris.platform.block.PlatformBlock;
|
||||||
import com.volmit.iris.util.ShortNoiseCache;
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
public class FeatureTerrain extends Feature<PlatformBlock, FeatureTerrain.State> {
|
public class FeatureTerrain extends Feature<PlatformBlock, FeatureTerrain.State> {
|
||||||
private final PlatformBlock stone;
|
private final PlatformBlock stone;
|
||||||
private final NoisePlane generator;
|
private final NoisePlane generator;
|
||||||
|
private final NoisePlane generator2;
|
||||||
|
|
||||||
public FeatureTerrain(Engine engine) {
|
public FeatureTerrain(Engine engine) {
|
||||||
super("terrain", engine);
|
super("terrain", engine);
|
||||||
|
setOptimize(true);
|
||||||
stone = engine.block("stone");
|
stone = engine.block("stone");
|
||||||
this.generator = NoisePreset.NATURAL.create(1234).fit(0, 64).scale(0.2);
|
this.generator = NoisePreset.NATURAL.create(1234);
|
||||||
|
this.generator2 = NoisePreset.NATURAL.create(6664).fit(0, 1).scale(0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public State prepare(Engine engine, FeatureSizedTarget target, FeatureStorage storage) {
|
public State prepare(Engine engine, FeatureSizedTarget target, FeatureStorage storage) {
|
||||||
target.forXZ((x, z) -> storage.getHeight().set(x & storage.getW() - 1, z & storage.getH() - 1, (short) generator.noise(x, z)));
|
Hunk<Double> snc = new ArrayHunk<>(target.getWidth(), target.getHeight(), target.getDepth());
|
||||||
return new State(storage.getHeight());
|
short n;
|
||||||
|
int fdx,fdz;
|
||||||
|
for(int x : target.x()) {
|
||||||
|
fdx = Math.floorMod(x, target.getWidth());
|
||||||
|
for(int z : target.z()) {
|
||||||
|
fdz = Math.floorMod(z, target.getDepth());
|
||||||
|
n = (short) generator.noise(x, z);
|
||||||
|
for(int y = 0; y < n; y++) {
|
||||||
|
if(generator2.noise(x,y,z) > 0.5) {
|
||||||
|
snc.set(fdx, y, fdz, 1D);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new State(snc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generate(Engine engine, State state, FeatureTarget<PlatformBlock> target, FeatureStorage storage) {
|
public void generate(Engine engine, State state, FeatureTarget<PlatformBlock> target, FeatureStorage storage) {
|
||||||
target.forXZ((x, z) -> target.forYCap((y -> {
|
int y;
|
||||||
target.getHunk().set(x, y, z, stone);
|
for(int x : target.localX()) {
|
||||||
}), state.getNoise().get(x, z)));
|
for(int z : target.localZ()) {
|
||||||
|
for(int i = 0; i < target.getHeight(); i++) {
|
||||||
|
Double v = state.getNoise().get(x, i, z);
|
||||||
|
v = v == null ? 0f : v;
|
||||||
|
if(v >= 0.5) {
|
||||||
|
target.getHunk().set(x,i, z, stone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public static class State implements FeatureState {
|
public static class State implements FeatureState {
|
||||||
private final ShortNoiseCache noise;
|
private final Hunk<Double> noise;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,11 @@ public class HunkSlizeConfiguration {
|
|||||||
private final int verticalSlice;
|
private final int verticalSlice;
|
||||||
private final int horizontalSlize;
|
private final int horizontalSlize;
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return "H" + horizontalSlize + "" + ((verticalSlice < 8192) ? ("V" + verticalSlice) : "");
|
||||||
|
}
|
||||||
|
|
||||||
public static List<HunkSlizeConfiguration> generateConfigurations(IntegerRange vertical, IntegerRange horizontal)
|
public static List<HunkSlizeConfiguration> generateConfigurations(IntegerRange vertical, IntegerRange horizontal)
|
||||||
{
|
{
|
||||||
List<HunkSlizeConfiguration> configurations = new ArrayList<>();
|
List<HunkSlizeConfiguration> configurations = new ArrayList<>();
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
package com.volmit.iris.engine.optimizer;
|
package com.volmit.iris.engine.optimizer;
|
||||||
|
|
||||||
import art.arcane.chrono.Average;
|
import art.arcane.chrono.Average;
|
||||||
|
import art.arcane.spatial.hunk.storage.AtomicDoubleHunk;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class IrisOptimizationAttempt<T> {
|
public class IrisOptimizationAttempt<T> {
|
||||||
private final Average average;
|
private double value;
|
||||||
private final AtomicInteger runs;
|
private final AtomicInteger runs;
|
||||||
private final int testRuns;
|
private final int testRuns;
|
||||||
private final T parameters;
|
private final T parameters;
|
||||||
@ -16,13 +17,13 @@ public class IrisOptimizationAttempt<T> {
|
|||||||
{
|
{
|
||||||
this.parameters = parameters;
|
this.parameters = parameters;
|
||||||
this.testRuns = testRuns;
|
this.testRuns = testRuns;
|
||||||
this.average = new Average(testRuns);
|
this.value = 0;
|
||||||
this.runs = new AtomicInteger(0);
|
this.runs = new AtomicInteger(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getAverageTime()
|
public double getAverageTime()
|
||||||
{
|
{
|
||||||
return average.getAverage();
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isComplete()
|
public boolean isComplete()
|
||||||
@ -31,7 +32,7 @@ public class IrisOptimizationAttempt<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void report(double ms) {
|
public void report(double ms) {
|
||||||
average.put(ms);
|
value += ms;
|
||||||
runs.incrementAndGet();
|
runs.incrementAndGet();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package com.volmit.iris.engine.optimizer;
|
package com.volmit.iris.engine.optimizer;
|
||||||
|
|
||||||
|
import art.arcane.amulet.format.Form;
|
||||||
|
import art.arcane.chrono.Average;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.Singular;
|
import lombok.Singular;
|
||||||
@ -12,58 +14,72 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class IrisOptimizer<T> {
|
public class IrisOptimizer<T> {
|
||||||
|
private final String optimizedFeatureName;
|
||||||
private final int testRuns;
|
private final int testRuns;
|
||||||
|
private int dummyRuns;
|
||||||
private final List<T> options;
|
private final List<T> options;
|
||||||
|
private final Map<T, Double> results;
|
||||||
private final Map<T, IrisOptimizationAttempt<T>> attempts = new ConcurrentHashMap<>();
|
private final Map<T, IrisOptimizationAttempt<T>> attempts = new ConcurrentHashMap<>();
|
||||||
private T defaultOption;
|
private T defaultOption;
|
||||||
private final double chanceToTest;
|
private final double chanceToTest;
|
||||||
private double bestTime;
|
private double bestTime;
|
||||||
|
|
||||||
public IrisOptimizer(int testRuns, List<T> options, T defaultOption, double chanceToTest)
|
public IrisOptimizer(int testRuns, List<T> options, T defaultOption, double chanceToTest, String optimizedFeatureName) {
|
||||||
{
|
|
||||||
this.bestTime = Double.MAX_VALUE;
|
this.bestTime = Double.MAX_VALUE;
|
||||||
|
this.dummyRuns = 1024;
|
||||||
this.testRuns = testRuns;
|
this.testRuns = testRuns;
|
||||||
|
this.results = new HashMap<>();
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
this.optimizedFeatureName = optimizedFeatureName;
|
||||||
this.defaultOption = defaultOption;
|
this.defaultOption = defaultOption;
|
||||||
this.chanceToTest = chanceToTest;
|
this.chanceToTest = chanceToTest;
|
||||||
|
|
||||||
for(T i : options)
|
for(T i : options) {
|
||||||
{
|
|
||||||
attempts.put(i, new IrisOptimizationAttempt<>(i, testRuns));
|
attempts.put(i, new IrisOptimizationAttempt<>(i, testRuns));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString()
|
public String toString() {
|
||||||
{
|
|
||||||
return "optimizer";
|
return "optimizer";
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void report(T parameters, double ms)
|
public synchronized void report(T parameters, double ms)
|
||||||
{
|
{
|
||||||
|
if(dummyRuns-- > 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
IrisOptimizationAttempt<T> attempt = attempts.get(parameters);
|
IrisOptimizationAttempt<T> attempt = attempts.get(parameters);
|
||||||
|
|
||||||
if(attempt != null)
|
if(attempt != null) {
|
||||||
{
|
|
||||||
attempt.report(ms);
|
attempt.report(ms);
|
||||||
|
|
||||||
if(attempt.isComplete())
|
if(attempt.isComplete()) {
|
||||||
{
|
results.put(parameters, attempt.getAverageTime());
|
||||||
attempts.remove(parameters);
|
attempts.remove(parameters);
|
||||||
double result = attempt.getAverageTime();
|
double result = attempt.getAverageTime();
|
||||||
|
|
||||||
if(result < bestTime)
|
if(result < bestTime) {
|
||||||
{
|
|
||||||
bestTime = result;
|
bestTime = result;
|
||||||
defaultOption = attempt.getParameters();
|
defaultOption = attempt.getParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
d("Attempted " + optimizedFeatureName + " with " + defaultOption.toString() + " " + Form.duration(attempt.getAverageTime(), 2));
|
||||||
|
|
||||||
|
if(attempts.isEmpty()) {
|
||||||
|
d("Fully Optimized " + optimizedFeatureName + " with " + defaultOption.toString());
|
||||||
|
|
||||||
|
for(T i : results.keySet()) {
|
||||||
|
d(i.toString() + ": " + Form.duration(results.get(i), 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public T nextParameters()
|
public T nextParameters() {
|
||||||
{
|
if(!attempts.isEmpty() && Math.r(chanceToTest)) {
|
||||||
if(!attempts.isEmpty() && Math.r(chanceToTest))
|
|
||||||
{
|
|
||||||
return attempts.k().popRandom();
|
return attempts.k().popRandom();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,12 +16,18 @@ public class EnginePlumbing {
|
|||||||
private final Engine engine;
|
private final Engine engine;
|
||||||
@Singular
|
@Singular
|
||||||
private final List<EnginePipeline> pipelines;
|
private final List<EnginePipeline> pipelines;
|
||||||
|
private final EnginePipeline errorPipeline;
|
||||||
|
|
||||||
public void generate(Engine engine, FeatureSizedTarget target, PipedHunkStack stack)
|
public void generate(Engine engine, FeatureSizedTarget target, PipedHunkStack stack) {
|
||||||
{
|
for(EnginePipeline i : pipelines) {
|
||||||
for(EnginePipeline i : pipelines)
|
|
||||||
{
|
|
||||||
i.generate(engine, target, stack);
|
i.generate(engine, target, stack);
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
}
|
||||||
|
|
||||||
|
catch(Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
getErrorPipeline().generate(engine, target, stack);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ public class PipelinePhase
|
|||||||
.collect(Collectors.toList())).stream().map(i -> {
|
.collect(Collectors.toList())).stream().map(i -> {
|
||||||
try {
|
try {
|
||||||
return i.get();
|
return i.get();
|
||||||
} catch(InterruptedException | ExecutionException e) {
|
} catch(Throwable e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
|
@ -30,16 +30,15 @@ public class PipelineTask<T extends PlatformNamespaced>
|
|||||||
this.horizontalEnvelope = horizontalEnvelope;
|
this.horizontalEnvelope = horizontalEnvelope;
|
||||||
List<HunkSlizeConfiguration> configurations = feature.isHeightAgnostic() ? HunkSlizeConfiguration.generateConfigurations(Integer.MAX_VALUE, horizontalEnvelope)
|
List<HunkSlizeConfiguration> configurations = feature.isHeightAgnostic() ? HunkSlizeConfiguration.generateConfigurations(Integer.MAX_VALUE, horizontalEnvelope)
|
||||||
: HunkSlizeConfiguration.generateConfigurations(verticalEnvelope, horizontalEnvelope);
|
: HunkSlizeConfiguration.generateConfigurations(verticalEnvelope, horizontalEnvelope);
|
||||||
this.optimizer = new IrisOptimizer<>(256, configurations, configurations[0], 0.75);
|
this.optimizer = new IrisOptimizer<>(128, configurations, configurations[0], 1, feature.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public PipelineTask(Feature<T, ?> feature, Class<T> target)
|
public PipelineTask(Feature<T, ?> feature, Class<T> target) {
|
||||||
{
|
|
||||||
this(feature, target, 1 to 16, 1 to 16);
|
this(feature, target, 1 to 16, 1 to 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FeatureTask<T, ?> task(FeatureSizedTarget target, FeatureTarget<T> origin, FeatureStorage storage){
|
public FeatureTask<T, ?> task(FeatureSizedTarget target, FeatureTarget<T> origin, FeatureStorage storage){
|
||||||
HunkSlizeConfiguration configuration = optimizer.nextParameters();
|
HunkSlizeConfiguration configuration = getFeature().isOptimize() ? optimizer.nextParameters() : optimizer.getDefaultOption();
|
||||||
return feature.task(target, origin, storage, configuration.getVerticalSlice(), configuration.getHorizontalSlize(), (ms) -> optimizer.report(configuration, ms));
|
return feature.task(target, origin, storage, configuration.getVerticalSlice(), configuration.getHorizontalSlize(), (ms) -> optimizer.report(configuration, ms));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,14 @@ import java.io.File;
|
|||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public interface IrisPlatform {
|
public interface IrisPlatform {
|
||||||
|
void logError(String k, Object o);
|
||||||
|
|
||||||
|
void logInfo(String k, Object o);
|
||||||
|
|
||||||
|
void logWarning(String k, Object o);
|
||||||
|
|
||||||
|
void logDebug(String k, Object o);
|
||||||
|
|
||||||
String getPlatformName();
|
String getPlatformName();
|
||||||
|
|
||||||
Stream<PlatformBlock> getBlocks();
|
Stream<PlatformBlock> getBlocks();
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.volmit.iris.util;
|
||||||
|
|
||||||
|
import art.arcane.source.NoisePlane;
|
||||||
|
import art.arcane.spatial.hunk.Hunk;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class HunkedNoisePlane implements NoisePlane {
|
||||||
|
private final Hunk<Double> noise;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double noise(double x, double y, double z) {
|
||||||
|
Double d = noise.get(Math.floorMod((int)x, noise.getWidth()), Math.floorMod((int)y, noise.getHeight()), Math.floorMod((int)z, noise.getDepth()));
|
||||||
|
|
||||||
|
return d != null ? d : 0;
|
||||||
|
}
|
||||||
|
}
|
@ -13,10 +13,10 @@ public class ShortNoiseCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void set(int x, int y, short v) {
|
public void set(int x, int y, short v) {
|
||||||
this.cache[y % this.height * this.width + x % this.width] = v;
|
this.cache[(Math.floorMod(y,this.height) * this.width) + Math.floorMod(x, this.width)] = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
public short get(int x, int y) {
|
public short get(int x, int y) {
|
||||||
return this.cache[y % this.height * this.width + x % this.width];
|
return this.cache[(Math.floorMod(y,this.height) * this.width) + Math.floorMod(x,this.width)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user