Performance tweaks

This commit is contained in:
Daniel Mills 2020-10-29 09:12:27 -04:00
parent 79bd586def
commit 13805edba9
11 changed files with 102 additions and 186 deletions

16
.idea/workspace.xml generated
View File

@ -143,22 +143,22 @@
<screen x="0" y="0" width="1920" height="1050" /> <screen x="0" y="0" width="1920" height="1050" />
</state> </state>
<state x="485" y="234" key="#com.intellij.structuralsearch.plugin.ui.StructuralSearchDialog/-1920.0.1920.1050/1920.0.1920.1050/0.0.1920.1050@0.0.1920.1050" timestamp="1603860057506" /> <state x="485" y="234" key="#com.intellij.structuralsearch.plugin.ui.StructuralSearchDialog/-1920.0.1920.1050/1920.0.1920.1050/0.0.1920.1050@0.0.1920.1050" timestamp="1603860057506" />
<state width="1921" height="983" key="GridCell.Tab.0.bottom" timestamp="1603972262918"> <state width="1921" height="983" key="GridCell.Tab.0.bottom" timestamp="1603976975935">
<screen x="0" y="0" width="1920" height="1050" /> <screen x="0" y="0" width="1920" height="1050" />
</state> </state>
<state width="1921" height="983" key="GridCell.Tab.0.bottom/-1920.0.1920.1050/1920.0.1920.1050/0.0.1920.1050@0.0.1920.1050" timestamp="1603972262918" /> <state width="1921" height="983" key="GridCell.Tab.0.bottom/-1920.0.1920.1050/1920.0.1920.1050/0.0.1920.1050@0.0.1920.1050" timestamp="1603976975935" />
<state width="1921" height="983" key="GridCell.Tab.0.center" timestamp="1603972262917"> <state width="1921" height="983" key="GridCell.Tab.0.center" timestamp="1603976975935">
<screen x="0" y="0" width="1920" height="1050" /> <screen x="0" y="0" width="1920" height="1050" />
</state> </state>
<state width="1921" height="983" key="GridCell.Tab.0.center/-1920.0.1920.1050/1920.0.1920.1050/0.0.1920.1050@0.0.1920.1050" timestamp="1603972262917" /> <state width="1921" height="983" key="GridCell.Tab.0.center/-1920.0.1920.1050/1920.0.1920.1050/0.0.1920.1050@0.0.1920.1050" timestamp="1603976975935" />
<state width="1921" height="983" key="GridCell.Tab.0.left" timestamp="1603972262917"> <state width="1921" height="983" key="GridCell.Tab.0.left" timestamp="1603976975934">
<screen x="0" y="0" width="1920" height="1050" /> <screen x="0" y="0" width="1920" height="1050" />
</state> </state>
<state width="1921" height="983" key="GridCell.Tab.0.left/-1920.0.1920.1050/1920.0.1920.1050/0.0.1920.1050@0.0.1920.1050" timestamp="1603972262917" /> <state width="1921" height="983" key="GridCell.Tab.0.left/-1920.0.1920.1050/1920.0.1920.1050/0.0.1920.1050@0.0.1920.1050" timestamp="1603976975934" />
<state width="1921" height="983" key="GridCell.Tab.0.right" timestamp="1603972262917"> <state width="1921" height="983" key="GridCell.Tab.0.right" timestamp="1603976975935">
<screen x="0" y="0" width="1920" height="1050" /> <screen x="0" y="0" width="1920" height="1050" />
</state> </state>
<state width="1921" height="983" key="GridCell.Tab.0.right/-1920.0.1920.1050/1920.0.1920.1050/0.0.1920.1050@0.0.1920.1050" timestamp="1603972262917" /> <state width="1921" height="983" key="GridCell.Tab.0.right/-1920.0.1920.1050/1920.0.1920.1050/0.0.1920.1050@0.0.1920.1050" timestamp="1603976975935" />
<state x="312" y="0" key="SettingsEditor" timestamp="1603947206451"> <state x="312" y="0" key="SettingsEditor" timestamp="1603947206451">
<screen x="0" y="0" width="1920" height="1050" /> <screen x="0" y="0" width="1920" height="1050" />
</state> </state>

View File

@ -1,166 +0,0 @@
package com.volmit.iris.v2;
import java.util.Random;
import java.util.function.Predicate;
import com.volmit.iris.v2.generator.IrisComplex;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData;
import com.volmit.iris.v2.scaffold.hunk.Hunk;
import com.volmit.iris.v2.scaffold.stream.ProceduralStream;
import com.volmit.iris.manager.IrisDataManager;
import com.volmit.iris.object.IrisBiome;
import com.volmit.iris.object.IrisDecorator;
import com.volmit.iris.object.IrisDimension;
import com.volmit.iris.util.RNG;
import org.bukkit.generator.BlockPopulator;
import org.jetbrains.annotations.NotNull;
public class IrisTerrainGenerator extends BlockPopulator
{
private long seed;
private IrisDataManager data;
private IrisDimension dimension;
private IrisComplex complex;
private RNG rng;
private int parallelism;
private static final Predicate<BlockData> PREDICATE_SOLID = (b) -> b != null && !b.getMaterial().isAir() && !b.getMaterial().equals(Material.WATER) && !b.getMaterial().equals(Material.LAVA);
public IrisTerrainGenerator(long seed, IrisDimension dimension, IrisDataManager data)
{
parallelism = 8;
this.seed = seed;
this.rng = new RNG(seed);
complex = new IrisComplex();
this.data = data;
this.dimension = dimension;
flash();
}
public void flash()
{
complex.flash(seed, dimension, data);
}
public void generateTerrain(int x, int z, Hunk<BlockData> blocks)
{
fill2D(complex.getHeightFluidStream(), blocks, x, z, complex.getTerrainStream());
}
public void generateBiome(int x, int z, Hunk<Biome> blocks)
{
fill2DYLock(complex.getMaxHeightStream(), blocks, x, z, complex.getTrueBiomeDerivativeStream());
}
public void generate(int x, int z, Hunk<BlockData> blocks, Hunk<Biome> biomes)
{
generateTerrain(x, z, blocks);
generateBiome(x, z, biomes);
}
public void generateParallax()
{
}
public void generatePost(int x, int z, Hunk<BlockData> blocks)
{
generateDecorations(x, z, blocks);
}
@Override
public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk)
{
generatePost(chunk.getX(), chunk.getZ(), Hunk.viewBlocks(chunk));
}
private <V, T> void fill2D(ProceduralStream<T> t, Hunk<V> h, double x, double z, ProceduralStream<V> v)
{
t.fill2D(h, x * 16, z * 16, v, parallelism);
}
private <V, T> void fill2DYLock(ProceduralStream<T> t, Hunk<V> h, double x, double z, ProceduralStream<V> v)
{
t.fill2DYLocked(h, x * 16, z * 16, v, parallelism);
}
public void generateDecorations(int x, int z, Hunk<BlockData> blocks)
{
int bx = (x * 16);
int bz = (z * 16);
blocks.iterateSurfaces2D(parallelism, PREDICATE_SOLID, (ax, az, xx, zz, top, bottom, lastBottom, h) ->
{
int rx = bx + xx + ax;
int rz = bz + zz + az;
RNG g = rng.nextParallelRNG(rx).nextParallelRNG(rz);
IrisBiome b = complex.getTrueBiomeStream().get(rx, rz);
boolean surface = lastBottom == -1;
int floor = top + 1;
int ceiling = lastBottom == -1 ? floor < dimension.getFluidHeight() ? dimension.getFluidHeight() : blocks.getHeight() : lastBottom - 1;
int height = ceiling - floor;
if(height < 2)
{
return;
}
IrisDecorator deco = complex.getTerrainSurfaceDecoration().get(rx, rz);
if(deco != null)
{
if(deco.isStacking())
{
int stack = Math.min(g.i(deco.getStackMin(), deco.getStackMax()), height);
for(int i = 0; i < stack; i++)
{
h.set(ax, i + floor, az, deco.getBlockData100(b, rng, rx - i, rz + i, data));
}
if(deco.getTopPalette().isNotEmpty())
{
h.set(ax, stack + floor - 1, az, deco.getBlockDataForTop(b, rng, rx - stack, rz + stack, data));
}
}
else
{
h.set(ax, floor, az, deco.getBlockData100(b, rng, rx, rz, data));
}
}
if(!surface)
{
IrisDecorator cdeco = complex.getTerrainCeilingDecoration().get(rx, rz);
if(cdeco != null)
{
if(cdeco.isStacking())
{
int stack = Math.min(g.i(cdeco.getStackMin(), cdeco.getStackMax()), height);
for(int i = 0; i < stack; i++)
{
h.set(ax, -i + ceiling, az, cdeco.getBlockData100(b, rng, rx - i, rz + i, data));
}
if(cdeco.getTopPalette().isNotEmpty())
{
h.set(ax, -stack + ceiling - 1, az, cdeco.getBlockDataForTop(b, rng, rx - stack, rz + stack, data));
}
}
else
{
h.set(ax, ceiling, az, cdeco.getBlockData100(b, rng, rx, rz, data));
}
}
}
});
}
}

View File

@ -24,8 +24,7 @@ public class TestGen
{ {
public static void gen(Player p) public static void gen(Player p)
{ {
IrisTerrainGenerator tg = new IrisTerrainGenerator(1337, Iris.globaldata.getDimensionLoader().load("overworld"), Iris.globaldata);
p.teleport(new Location(new WorldCreator("t/" + UUID.randomUUID().toString()) p.teleport(new Location(new WorldCreator("t/" + UUID.randomUUID().toString())
.generator(EngineCompositeGenerator.newStudioWorld("overworld")).createWorld(), 0, 200, 0)); .generator(EngineCompositeGenerator.newStudioWorld("flat")).createWorld(), 0, 70, 0));
} }
} }

View File

@ -85,10 +85,11 @@ public class IrisComplex implements DataProvider
public IrisComplex(Engine engine) public IrisComplex(Engine engine)
{ {
int cacheSize = 8192; int cacheSize = 1024;
BlockData glass = B.getBlockData("GLASS"); BlockData glass = B.getBlockData("GLASS");
this.rng = new RNG(engine.getWorld().getSeed()); this.rng = new RNG(engine.getWorld().getSeed());
this.data = data; this.data = engine.getData();
double height = engine.getHeight();
fluidHeight = engine.getDimension().getFluidHeight(); fluidHeight = engine.getDimension().getFluidHeight();
generators = new KList<>(); generators = new KList<>();
RNG rng = new RNG(engine.getWorld().getSeed()); RNG rng = new RNG(engine.getWorld().getSeed());
@ -157,11 +158,10 @@ public class IrisComplex implements DataProvider
trueBiomeStream = heightStream trueBiomeStream = heightStream
.convertAware2D((h, x, z) -> .convertAware2D((h, x, z) ->
fixBiomeType(h, baseBiomeStream.get(x, z), fixBiomeType(h, baseBiomeStream.get(x, z),
regionStream.get(x, z), x, z, fluidHeight)) regionStream.get(x, z), x, z, fluidHeight));
.cache2D(cacheSize);
trueBiomeDerivativeStream = trueBiomeStream.convert(IrisBiome::getDerivative); trueBiomeDerivativeStream = trueBiomeStream.convert(IrisBiome::getDerivative);
heightFluidStream = heightStream.max(fluidHeight); heightFluidStream = heightStream.max(fluidHeight);
maxHeightStream = ProceduralStream.ofDouble((x, z) -> 255D); maxHeightStream = ProceduralStream.ofDouble((x, z) -> height);
terrainSurfaceDecoration = trueBiomeStream terrainSurfaceDecoration = trueBiomeStream
.convertAware2D((b, xx,zz) -> decorateFor(b, xx, zz, DecorationPart.NONE)); .convertAware2D((b, xx,zz) -> decorateFor(b, xx, zz, DecorationPart.NONE));
terrainCeilingDecoration = trueBiomeStream terrainCeilingDecoration = trueBiomeStream

View File

@ -13,6 +13,22 @@ public class IrisBiomeActuator extends EngineAssignedActuator<Biome>
@Override @Override
public void actuate(int x, int z, Hunk<Biome> output) { public void actuate(int x, int z, Hunk<Biome> output) {
getComplex().getMaxHeightStream().fill2DYLocked(output, x, z, getComplex().getTrueBiomeDerivativeStream(), getParallelism()); output.compute2D(getParallelism(), (xx, yy, zz, h) -> {
int i,zf;
Biome v;
for(int xf = 0; xf < h.getWidth(); xf++)
{
for(zf = 0; zf < h.getDepth(); zf++)
{
v = getComplex().getTrueBiomeDerivativeStream().get(xx+xf+x, zz+zf+z);
for(i = 0; i < h.getHeight(); i++)
{
h.set(xx+xf, i, zz+zf, v);
}
}
}
});
} }
} }

View File

@ -3,6 +3,7 @@ package com.volmit.iris.v2.generator.actuator;
import com.volmit.iris.v2.scaffold.engine.Engine; import com.volmit.iris.v2.scaffold.engine.Engine;
import com.volmit.iris.v2.scaffold.engine.EngineAssignedActuator; import com.volmit.iris.v2.scaffold.engine.EngineAssignedActuator;
import com.volmit.iris.v2.scaffold.hunk.Hunk; import com.volmit.iris.v2.scaffold.hunk.Hunk;
import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
public class IrisTerrainActuator extends EngineAssignedActuator<BlockData> public class IrisTerrainActuator extends EngineAssignedActuator<BlockData>
@ -13,6 +14,22 @@ public class IrisTerrainActuator extends EngineAssignedActuator<BlockData>
@Override @Override
public void actuate(int x, int z, Hunk<BlockData> output) { public void actuate(int x, int z, Hunk<BlockData> output) {
getComplex().getHeightFluidStream().fill2D(output, x, z, getComplex().getTerrainStream(), getParallelism()); output.compute2D(getParallelism(), (xx, yy, zz, h) -> {
int i,zf;
double he;
for(int xf = 0; xf < h.getWidth(); xf++)
{
for(zf = 0; zf < h.getDepth(); zf++)
{
he = Math.min(h.getHeight(), getComplex().getHeightFluidStream().get(xx+xf+x, zz+zf+z));
for(i = 0; i < he; i++)
{
h.set(xx+xf, i, zz+zf, getComplex().getTerrainStream().get(xx+xf+x, i, zz+zf+z));
}
}
}
});
} }
} }

View File

@ -0,0 +1,23 @@
package com.volmit.iris.v2.scaffold.cache;
public interface Cache<V>
{
public int getId();
public V get(int x, int z);
public static long key(int x, int z)
{
return (((long)x) << 32) | (z & 0xffffffffL);
}
public static int keyX(long key)
{
return (int)(key >> 32);
}
public static int keyZ(long key)
{
return (int)key;
}
}

View File

@ -0,0 +1,10 @@
package com.volmit.iris.v2.scaffold.cache;
import com.volmit.iris.util.V;
public interface Multicache
{
public <V> Cache<V> getCache(int id);
public <V> Cache<V> createCache();
}

View File

@ -22,6 +22,11 @@ public interface Engine
public void generate(int x, int z, Hunk<BlockData> blocks, Hunk<Biome> biomes); public void generate(int x, int z, Hunk<BlockData> blocks, Hunk<Biome> biomes);
public default int getHeight()
{
return getTarget().getHeight();
}
public default IrisDataManager getData() public default IrisDataManager getData()
{ {
return getTarget().getData(); return getTarget().getData();

View File

@ -1,8 +1,11 @@
package com.volmit.iris.v2.scaffold.engine; package com.volmit.iris.v2.scaffold.engine;
import com.mysql.jdbc.profiler.ProfilerEvent;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.manager.IrisDataManager; import com.volmit.iris.manager.IrisDataManager;
import com.volmit.iris.object.IrisDimension; import com.volmit.iris.object.IrisDimension;
import com.volmit.iris.util.Form;
import com.volmit.iris.util.PrecisionStopwatch;
import com.volmit.iris.v2.generator.IrisEngineCompound; import com.volmit.iris.v2.generator.IrisEngineCompound;
import com.volmit.iris.v2.scaffold.hunk.Hunk; import com.volmit.iris.v2.scaffold.hunk.Hunk;
import org.bukkit.Location; import org.bukkit.Location;
@ -106,7 +109,9 @@ public class EngineCompositeGenerator extends ChunkGenerator {
ChunkData chunk = createChunkData(world); ChunkData chunk = createChunkData(world);
Hunk<BlockData> blocks = Hunk.view(chunk); Hunk<BlockData> blocks = Hunk.view(chunk);
Hunk<Biome> biomes = Hunk.view(biome); Hunk<Biome> biomes = Hunk.view(biome);
PrecisionStopwatch p = PrecisionStopwatch.start();
compound.generate(x * 16, z * 16, blocks, biomes); compound.generate(x * 16, z * 16, blocks, biomes);
System.out.println("Generated " + x + "," + z + " in " + Form.duration(p.getMilliseconds(), 0));
return chunk; return chunk;
} }

View File

@ -2,20 +2,27 @@ package com.volmit.iris.v2.scaffold.stream.utility;
import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.volmit.iris.v2.scaffold.cache.Cache;
import com.volmit.iris.v2.scaffold.stream.BasicStream; import com.volmit.iris.v2.scaffold.stream.BasicStream;
import com.volmit.iris.v2.scaffold.stream.ProceduralStream; import com.volmit.iris.v2.scaffold.stream.ProceduralStream;
import com.volmit.iris.util.ChunkPosition; import com.volmit.iris.util.ChunkPosition;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.concurrent.TimeUnit;
public class CachedStream2D<T> extends BasicStream<T> implements ProceduralStream<T> public class CachedStream2D<T> extends BasicStream<T> implements ProceduralStream<T>
{ {
private final ProceduralStream<T> stream; private final ProceduralStream<T> stream;
private final LoadingCache<ChunkPosition, T> cache; private final LoadingCache<Long, T> cache;
public CachedStream2D(ProceduralStream<T> stream, int size) public CachedStream2D(ProceduralStream<T> stream, int size)
{ {
super(); super();
this.stream = stream; this.stream = stream;
cache = Caffeine.newBuilder().maximumSize(size).build((b) -> stream.get(b.getX(), b.getZ())); cache = Caffeine.newBuilder()
.maximumSize(size)
.build((b) -> stream.get(Cache.keyX(b), Cache.keyZ(b)));
} }
@Override @Override
@ -33,7 +40,7 @@ public class CachedStream2D<T> extends BasicStream<T> implements ProceduralStrea
@Override @Override
public T get(double x, double z) public T get(double x, double z)
{ {
return cache.get(new ChunkPosition((int) x, (int) z)); return cache.get(Cache.key((int) x, (int) z));
} }
@Override @Override