mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-04-05 15:26:28 +00:00
"Perfection"
This commit is contained in:
@@ -64,7 +64,6 @@ public class IrisGenerator extends ParallaxWorldGenerator
|
||||
//@done
|
||||
|
||||
private boolean disposed;
|
||||
private double[][][] scatterCache;
|
||||
private CNG scatter;
|
||||
private MB ICE = new MB(Material.ICE);
|
||||
private MB PACKED_ICE = new MB(Material.PACKED_ICE);
|
||||
@@ -110,7 +109,7 @@ public class IrisGenerator extends ParallaxWorldGenerator
|
||||
|
||||
public double scatter(int x, int y, int z)
|
||||
{
|
||||
return scatterCache[Math.abs(x) % 16][Math.abs(y) % 16][Math.abs(z) % 16];
|
||||
return scatter.noise(x, y, z);
|
||||
}
|
||||
|
||||
public boolean scatterChance(int x, int y, int z, double chance)
|
||||
@@ -125,8 +124,7 @@ public class IrisGenerator extends ParallaxWorldGenerator
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//@builder
|
||||
random = new Random(world.getSeed());
|
||||
rTerrain = new RNG(world.getSeed());
|
||||
glLNoise = new GenLayerLayeredNoise(this, world, random, rTerrain.nextParallelRNG(2));
|
||||
glBiome = new GenLayerBiome(this, world, random, rTerrain.nextParallelRNG(4), dim.getBiomes());
|
||||
@@ -135,28 +133,12 @@ public class IrisGenerator extends ParallaxWorldGenerator
|
||||
glCaverns = new GenLayerCaverns(this, world, random, rTerrain.nextParallelRNG(-3));
|
||||
glSnow = new GenLayerSnow(this, world, random, rTerrain.nextParallelRNG(5));
|
||||
glCliffs = new GenLayerCliffs(this, world, random, rTerrain.nextParallelRNG(9));
|
||||
scatterCache = new double[16][][];
|
||||
scatter = new CNG(rTerrain.nextParallelRNG(52), 1, 1).scale(10);
|
||||
|
||||
|
||||
if(Iris.settings.performance.objectMode.equals(ObjectMode.PARALLAX))
|
||||
{
|
||||
god = new GenObjectDecorator(this);
|
||||
}
|
||||
//@done
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
scatterCache[i] = new double[16][];
|
||||
|
||||
for(int j = 0; j < 16; j++)
|
||||
{
|
||||
scatterCache[i][j] = new double[16];
|
||||
|
||||
for(int k = 0; k < 16; k++)
|
||||
{
|
||||
scatterCache[i][j][k] = scatter.noise(i, j, k);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -185,6 +167,7 @@ public class IrisGenerator extends ParallaxWorldGenerator
|
||||
|
||||
public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome)
|
||||
{
|
||||
random = new Random(world.getSeed());
|
||||
PrecisionStopwatch s = getMetrics().start();
|
||||
ChunkData d = super.generateChunkData(world, random, x, z, biome);
|
||||
getMetrics().stop("chunk:ms", s);
|
||||
@@ -312,7 +295,7 @@ public class IrisGenerator extends ParallaxWorldGenerator
|
||||
{
|
||||
GList<BlockPopulator> p = new GList<>();
|
||||
|
||||
if(Iris.settings.performance.objectMode.equals(ObjectMode.FAST_LIGHTING) || Iris.settings.performance.objectMode.equals(ObjectMode.LIGHTING))
|
||||
if(Iris.settings.performance.objectMode.equals(ObjectMode.QUICK_N_DIRTY) || Iris.settings.performance.objectMode.equals(ObjectMode.LIGHTING))
|
||||
{
|
||||
p.add(god = new GenObjectDecorator(this));
|
||||
}
|
||||
@@ -406,7 +389,7 @@ public class IrisGenerator extends ParallaxWorldGenerator
|
||||
|
||||
else
|
||||
{
|
||||
MB mbx = biome.getScatterChanceSingle();
|
||||
MB mbx = biome.getScatterChanceSingle(scatter(wxx, i, wzx));
|
||||
|
||||
if(!mbx.material.equals(Material.AIR))
|
||||
{
|
||||
@@ -549,4 +532,10 @@ public class IrisGenerator extends ParallaxWorldGenerator
|
||||
{
|
||||
dispose();
|
||||
}
|
||||
|
||||
public void inject(CompiledDimension dimension)
|
||||
{
|
||||
this.dim = dimension;
|
||||
onInit(getWorld(), rTerrain);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package ninja.bytecode.iris.generator;
|
||||
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
@@ -11,204 +10,45 @@ import mortar.api.nms.NMP;
|
||||
import mortar.api.sched.J;
|
||||
import mortar.compute.math.M;
|
||||
import mortar.lang.collection.FinalDouble;
|
||||
import ninja.bytecode.iris.generator.atomics.AtomicChunkData;
|
||||
import ninja.bytecode.iris.util.ChronoQueue;
|
||||
import ninja.bytecode.iris.util.ChunkPlan;
|
||||
import ninja.bytecode.iris.util.SMCAVector;
|
||||
import ninja.bytecode.shuriken.bench.PrecisionStopwatch;
|
||||
import ninja.bytecode.shuriken.collections.GList;
|
||||
import ninja.bytecode.shuriken.collections.GMap;
|
||||
import ninja.bytecode.shuriken.execution.ChronoLatch;
|
||||
import ninja.bytecode.shuriken.execution.NastyRunnable;
|
||||
import ninja.bytecode.shuriken.execution.TaskExecutor;
|
||||
import ninja.bytecode.shuriken.math.RNG;
|
||||
|
||||
public class WorldReactor
|
||||
{
|
||||
private final World world;
|
||||
private IrisGenerator gen;
|
||||
|
||||
public WorldReactor(World world)
|
||||
{
|
||||
this.world = world;
|
||||
|
||||
if(!(world.getGenerator() instanceof IrisGenerator))
|
||||
{
|
||||
throw new IllegalArgumentException(world.getName() + " is not an iris world.");
|
||||
}
|
||||
|
||||
this.gen = ((IrisGenerator) world.getGenerator());
|
||||
}
|
||||
|
||||
public void generateMultipleRegions(GMap<SMCAVector, TaskExecutor> g, boolean force, double mst, Consumer<Double> progress, Runnable done)
|
||||
public void generateRegionNormal(Player p, boolean force, double mst, Consumer<Double> progress, Runnable done)
|
||||
{
|
||||
ChronoLatch cl = new ChronoLatch(50);
|
||||
GMap<SMCAVector, Double> p = new GMap<>();
|
||||
ReentrantLock r = new ReentrantLock();
|
||||
for(SMCAVector i : g.k())
|
||||
ChronoQueue q = new ChronoQueue(mst, 10240);
|
||||
FinalDouble of = new FinalDouble(0D);
|
||||
FinalDouble max = new FinalDouble(0D);
|
||||
|
||||
for(int xx = p.getLocation().getChunk().getX() - 32; xx < p.getLocation().getChunk().getX() + 32; xx++)
|
||||
{
|
||||
generateRegion(i.getX(), i.getZ(), g.get(i), force, mst / (double) g.size(), (xp) ->
|
||||
int x = xx;
|
||||
|
||||
for(int zz = p.getLocation().getChunk().getZ() - 32; zz < p.getLocation().getChunk().getZ() + 32; zz++)
|
||||
{
|
||||
r.lock();
|
||||
p.put(i, xp);
|
||||
double m = 0;
|
||||
int z = zz;
|
||||
|
||||
for(double j : p.v())
|
||||
if(world.isChunkLoaded(x, z) || world.loadChunk(x, z, false))
|
||||
{
|
||||
m += j;
|
||||
}
|
||||
r.unlock();
|
||||
|
||||
double h = m / (double) p.size();
|
||||
|
||||
if(h == 1D || cl.flip())
|
||||
{
|
||||
progress.accept(h);
|
||||
}
|
||||
}, () ->
|
||||
{
|
||||
p.remove(i);
|
||||
|
||||
if(p.isEmpty())
|
||||
{
|
||||
done.run();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void generateRegion(int mx, int mz, TaskExecutor executor, boolean force, double mst, Consumer<Double> progress, Runnable done)
|
||||
{
|
||||
J.a(() ->
|
||||
{
|
||||
FinalDouble of = new FinalDouble(0D);
|
||||
FinalDouble max = new FinalDouble(0D);
|
||||
PrecisionStopwatch t = PrecisionStopwatch.start();
|
||||
GMap<SMCAVector, AtomicChunkData> data = new GMap<>();
|
||||
GMap<SMCAVector, ChunkPlan> plan = new GMap<>();
|
||||
GList<NastyRunnable> parallax = new GList<>();
|
||||
GList<NastyRunnable> noise = new GList<>();
|
||||
GList<Runnable> chunk = new GList<>();
|
||||
ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
for(int xx = mx << 5; xx < (mx << 5) + 32; xx++)
|
||||
{
|
||||
int x = xx;
|
||||
|
||||
for(int zz = mz << 5; zz < (mz << 5) + 32; zz++)
|
||||
{
|
||||
int z = zz;
|
||||
SMCAVector w = new SMCAVector(x, z);
|
||||
|
||||
if(!force && world.loadChunk(x, z, false))
|
||||
{
|
||||
// continue;
|
||||
}
|
||||
|
||||
max.add(1);
|
||||
parallax.add(() ->
|
||||
q.queue(() ->
|
||||
{
|
||||
gen.doGenParallax(x, z);
|
||||
of.add(1);
|
||||
progress.accept(of.get() / max.get());
|
||||
});
|
||||
|
||||
max.add(0.1);
|
||||
noise.add(() ->
|
||||
{
|
||||
AtomicChunkData tydata = new AtomicChunkData(world);
|
||||
ChunkPlan typlan = new ChunkPlan();
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
for(int j = 0; j < 16; j++)
|
||||
{
|
||||
gen.onGenColumn((x << 4) + i, (z << 4) + j, i, j, typlan, tydata, true);
|
||||
}
|
||||
}
|
||||
|
||||
gen.getWorldData().getChunk(x, z).inject(tydata);
|
||||
gen.onPostChunk(world, x, z, new RNG(world.getSeed()), tydata, typlan);
|
||||
|
||||
lock.lock();
|
||||
data.put(w, tydata);
|
||||
plan.put(w, typlan);
|
||||
lock.unlock();
|
||||
of.add(1);
|
||||
progress.accept(of.get() / max.get());
|
||||
});
|
||||
|
||||
max.add(4);
|
||||
chunk.add(() ->
|
||||
{
|
||||
if(world.loadChunk(x, z, false))
|
||||
{
|
||||
world.regenerateChunk(x, z);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
world.loadChunk(x, z, true);
|
||||
}
|
||||
world.regenerateChunk(x, z);
|
||||
|
||||
Chunk cc = world.getChunkAt(x, z);
|
||||
NMP.host.relight(cc);
|
||||
cc.unload(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
of.add(1);
|
||||
|
||||
executor.startWork().queue(parallax).execute();
|
||||
executor.startWork().queue(noise).execute();
|
||||
|
||||
gen.setSplicer((world, random, x, z, biome) ->
|
||||
{
|
||||
SMCAVector w = new SMCAVector(x, z);
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
for(int j = 0; j < 16; j++)
|
||||
{
|
||||
try
|
||||
{
|
||||
biome.setBiome((x << 4) + i, (z << 4) + j, plan.get(w).getBiome(i, j).getRealBiome());
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AtomicChunkData f = data.get(w);
|
||||
|
||||
if(f != null)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return f;
|
||||
});
|
||||
|
||||
t.end();
|
||||
J.s(() ->
|
||||
{
|
||||
PrecisionStopwatch s = PrecisionStopwatch.start();
|
||||
ChronoQueue q = new ChronoQueue(mst, 1096);
|
||||
int m = 0;
|
||||
for(Runnable i : chunk)
|
||||
{
|
||||
int gg = m;
|
||||
|
||||
q.queue(() ->
|
||||
{
|
||||
i.run();
|
||||
of.add(4);
|
||||
if(gg == chunk.size() - 1)
|
||||
if(of.get() == max.get())
|
||||
{
|
||||
progress.accept(1D);
|
||||
s.end();
|
||||
q.dieSlowly();
|
||||
done.run();
|
||||
}
|
||||
@@ -217,61 +57,16 @@ public class WorldReactor
|
||||
{
|
||||
progress.accept(M.clip(of.get() / max.get(), 0D, 1D));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
m++;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public void generateRegionNormal(Player p, boolean force, double mst, Consumer<Double> progress, Runnable done)
|
||||
{
|
||||
ChronoQueue q = new ChronoQueue(mst, 1024);
|
||||
FinalDouble of = new FinalDouble(0D);
|
||||
FinalDouble max = new FinalDouble(0D);
|
||||
|
||||
for(int xx = p.getLocation().getChunk().getX() - 32; xx < p.getLocation().getChunk().getX() + 32; xx++)
|
||||
{
|
||||
int x = xx;
|
||||
|
||||
for(int zz = p.getLocation().getChunk().getX() - 32; zz < p.getLocation().getChunk().getX() + 32; zz++)
|
||||
{
|
||||
int z = zz;
|
||||
|
||||
max.add(1);
|
||||
|
||||
q.queue(() ->
|
||||
{
|
||||
if(world.loadChunk(x, z, false))
|
||||
{
|
||||
world.regenerateChunk(x, z);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
world.loadChunk(x, z, true);
|
||||
}
|
||||
|
||||
Chunk cc = world.getChunkAt(x, z);
|
||||
NMP.host.relight(cc);
|
||||
of.add(1);
|
||||
|
||||
if(of.get() == max.get())
|
||||
{
|
||||
progress.accept(1D);
|
||||
q.dieSlowly();
|
||||
done.run();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
progress.accept(M.clip(of.get() / max.get(), 0D, 1D));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
q.dieSlowly();
|
||||
J.s(() ->
|
||||
{
|
||||
q.dieSlowly();
|
||||
}, 20);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
|
||||
import mortar.api.sched.S;
|
||||
import mortar.logic.format.F;
|
||||
import mortar.util.text.C;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
@@ -27,6 +28,7 @@ import ninja.bytecode.shuriken.collections.GList;
|
||||
import ninja.bytecode.shuriken.collections.GMap;
|
||||
import ninja.bytecode.shuriken.collections.GSet;
|
||||
import ninja.bytecode.shuriken.execution.ChronoLatch;
|
||||
import ninja.bytecode.shuriken.execution.J;
|
||||
import ninja.bytecode.shuriken.logging.L;
|
||||
import ninja.bytecode.shuriken.math.M;
|
||||
import ninja.bytecode.shuriken.math.RNG;
|
||||
@@ -102,44 +104,57 @@ public class GenObjectDecorator extends BlockPopulator
|
||||
@Override
|
||||
public void populate(World world, Random random, Chunk source)
|
||||
{
|
||||
try
|
||||
Runnable m = () ->
|
||||
{
|
||||
if(g.isDisposed())
|
||||
try
|
||||
{
|
||||
placeHistory.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
GSet<IrisBiome> hits = new GSet<>();
|
||||
int cx = source.getX();
|
||||
int cz = source.getZ();
|
||||
|
||||
for(int i = 0; i < Iris.settings.performance.decorationAccuracy; i++)
|
||||
{
|
||||
int x = (cx << 4) + random.nextInt(16);
|
||||
int z = (cz << 4) + random.nextInt(16);
|
||||
IrisBiome biome = g.getBiome((int) g.getOffsetX(x), (int) g.getOffsetZ(z));
|
||||
|
||||
if(hits.contains(biome))
|
||||
if(g.isDisposed())
|
||||
{
|
||||
continue;
|
||||
placeHistory.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
GMap<GenObjectGroup, Double> objects = populationCache.get(biome);
|
||||
GSet<IrisBiome> hits = new GSet<>();
|
||||
int cx = source.getX();
|
||||
int cz = source.getZ();
|
||||
|
||||
if(objects == null)
|
||||
for(int i = 0; i < Iris.settings.performance.decorationAccuracy; i++)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int x = (cx << 4) + random.nextInt(16);
|
||||
int z = (cz << 4) + random.nextInt(16);
|
||||
IrisBiome biome = g.getBiome((int) g.getOffsetX(x), (int) g.getOffsetZ(z));
|
||||
|
||||
hits.add(biome);
|
||||
populate(world, cx, cz, random, biome);
|
||||
if(hits.contains(biome))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
GMap<GenObjectGroup, Double> objects = populationCache.get(biome);
|
||||
|
||||
if(objects == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
hits.add(biome);
|
||||
populate(world, cx, cz, random, biome);
|
||||
}
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
};
|
||||
|
||||
if(Iris.settings.performance.objectMode.equals(ObjectMode.QUICK_N_DIRTY))
|
||||
{
|
||||
J.a(m);
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
else
|
||||
{
|
||||
e.printStackTrace();
|
||||
m.run();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,7 +210,7 @@ public class GenObjectDecorator extends BlockPopulator
|
||||
}
|
||||
}
|
||||
|
||||
if(Iris.settings.performance.objectMode.equals(ObjectMode.FAST_LIGHTING))
|
||||
if(Iris.settings.performance.objectMode.equals(ObjectMode.QUICK_N_DIRTY))
|
||||
{
|
||||
placer = new NMSPlacer(world);
|
||||
}
|
||||
@@ -210,28 +225,48 @@ public class GenObjectDecorator extends BlockPopulator
|
||||
placer = new BukkitPlacer(world, false);
|
||||
}
|
||||
|
||||
Location start = go.place(x, by, z, placer);
|
||||
|
||||
if(start != null)
|
||||
Runnable rx = () ->
|
||||
{
|
||||
g.hitObject();
|
||||
if(Iris.settings.performance.verbose)
|
||||
{
|
||||
L.v(C.GRAY + "Placed " + C.DARK_GREEN + i.getName() + C.WHITE + "/" + C.DARK_GREEN + go.getName() + C.GRAY + " at " + C.DARK_GREEN + F.f(start.getBlockX()) + " " + F.f(start.getBlockY()) + " " + F.f(start.getBlockZ()));
|
||||
}
|
||||
Location start = go.place(x, by, z, placer);
|
||||
|
||||
if(Iris.settings.performance.debugMode)
|
||||
if(start != null)
|
||||
{
|
||||
placeHistory.add(new PlacedObject(start.getBlockX(), start.getBlockY(), start.getBlockZ(), i.getName() + ":" + go.getName()));
|
||||
|
||||
if(placeHistory.size() > Iris.settings.performance.placeHistoryLimit)
|
||||
g.hitObject();
|
||||
if(Iris.settings.performance.verbose)
|
||||
{
|
||||
while(placeHistory.size() > Iris.settings.performance.placeHistoryLimit)
|
||||
L.v(C.GRAY + "Placed " + C.DARK_GREEN + i.getName() + C.WHITE + "/" + C.DARK_GREEN + go.getName() + C.GRAY + " at " + C.DARK_GREEN + F.f(start.getBlockX()) + " " + F.f(start.getBlockY()) + " " + F.f(start.getBlockZ()));
|
||||
}
|
||||
|
||||
if(Iris.settings.performance.debugMode)
|
||||
{
|
||||
placeHistory.add(new PlacedObject(start.getBlockX(), start.getBlockY(), start.getBlockZ(), i.getName() + ":" + go.getName()));
|
||||
|
||||
if(placeHistory.size() > Iris.settings.performance.placeHistoryLimit)
|
||||
{
|
||||
placeHistory.remove(0);
|
||||
while(placeHistory.size() > Iris.settings.performance.placeHistoryLimit)
|
||||
{
|
||||
placeHistory.remove(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if(Iris.settings.performance.objectMode.equals(ObjectMode.QUICK_N_DIRTY))
|
||||
{
|
||||
new S(20)
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
rx.run();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
rx.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,7 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator
|
||||
|
||||
public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome)
|
||||
{
|
||||
random = new Random(world.getSeed());
|
||||
if(splicer != null)
|
||||
{
|
||||
AtomicChunkData d = splicer.onSpliceAvailable(world, random, x, z, biome);
|
||||
|
||||
Reference in New Issue
Block a user