Fixes & Performance

This commit is contained in:
Daniel Mills 2020-07-25 00:04:41 -04:00
parent a75817dde1
commit d42be730c3
15 changed files with 157 additions and 106 deletions

View File

@ -113,22 +113,23 @@ public class Iris extends JavaPlugin implements BoardProvider
int x = player.getLocation().getBlockX();
int z = player.getLocation().getBlockZ();
BiomeResult er = g.sampleTrueBiome(x, z);
BiomeResult erx = g.sampleBiome(x, z);
IrisBiome b = er != null ? er.getBiome() : null;
IrisBiome bx = erx != null ? erx.getBiome() : null;
lines.add("&7&m-----------------");
lines.add(ChatColor.GREEN + "Speed" + ChatColor.GRAY + ": " + ChatColor.BOLD + "" + ChatColor.GRAY + Form.f(g.getMetrics().getPerSecond().getAverage(), 0) + "/s " + Form.duration(g.getMetrics().getTotal().getAverage(), 1) + "");
lines.add(ChatColor.GREEN + "Loss" + ChatColor.GRAY + ": " + ChatColor.BOLD + "" + ChatColor.GRAY + Form.duration(g.getMetrics().getLoss().getAverage(), 4) + "");
lines.add(ChatColor.GREEN + "Generators" + ChatColor.GRAY + ": " + Form.f(CNG.creates));
lines.add(ChatColor.GREEN + "Noise" + ChatColor.GRAY + ": " + Form.f((int) hits.getAverage()));
lines.add(ChatColor.GREEN + "Parallax Regions" + ChatColor.GRAY + ": " + Form.f((int) g.getParallaxMap().getLoadedRegions().size()));
lines.add(ChatColor.GREEN + "Parallax Chunks" + ChatColor.GRAY + ": " + Form.f((int) g.getParallaxMap().getLoadedChunks().size()));
lines.add(ChatColor.GREEN + "Objects" + ChatColor.GRAY + ": " + Form.f(Iris.data.getObjectLoader().count()));
lines.add(ChatColor.GREEN + "Biomes" + ChatColor.GRAY + ": " + Form.f(Iris.data.getBiomeLoader().count()));
lines.add(ChatColor.GREEN + "Regions" + ChatColor.GRAY + ": " + Form.f(Iris.data.getRegionLoader().count()));
lines.add(ChatColor.GREEN + "Height" + ChatColor.GRAY + ": " + (int) g.getTerrainHeight(x, z) + " (" + (int) g.getTerrainWaterHeight(x, z) + ")");
lines.add(ChatColor.GREEN + "Height" + ChatColor.GRAY + ": " + (int) g.getTerrainHeight(x, z) + " (" + (int) g.getTerrainWaterHeight(x, z) + ")");
if(er != null && b != null)
{
lines.add(ChatColor.GREEN + "Biome" + ChatColor.GRAY + ": " + b.getName());
lines.add(ChatColor.GREEN + "Real" + ChatColor.GRAY + ": " + bx.getName());
lines.add(ChatColor.GREEN + "File" + ChatColor.GRAY + ": " + b.getLoadKey() + ".json");
lines.add(ChatColor.GREEN + "File" + ChatColor.GRAY + ": " + b.getLoadKey());
}
lines.add("&7&m-----------------");

View File

@ -36,6 +36,7 @@ public abstract class BiomeChunkGenerator extends DimensionChunkGenerator
private KMap<ChunkPosition, BiomeResult> biomeHitCache;
private KMap<ChunkPosition, BiomeResult> ceilingBiomeHitCache;
protected ChronoLatch cwarn = new ChronoLatch(1000);
private IrisBiome[] biomeCache;
public BiomeChunkGenerator(String dimensionName)
{
@ -45,6 +46,7 @@ public abstract class BiomeChunkGenerator extends DimensionChunkGenerator
regLock = new ReentrantLock();
biomeHitCache = new KMap<>();
ceilingBiomeHitCache = new KMap<>();
biomeCache = new IrisBiome[256];
}
public void onInit(World world, RNG rng)
@ -54,15 +56,25 @@ public abstract class BiomeChunkGenerator extends DimensionChunkGenerator
masterFracture = CNG.signature(rng.nextParallelRNG(13)).scale(0.12);
}
protected IrisBiome getCachedBiome(int x, int z)
{
return biomeCache[(z << 4) | x];
}
protected void cacheBiome(int x, int z, IrisBiome b)
{
biomeCache[(z << 4) | x] = b;
}
public KMap<ChunkPosition, BiomeResult> getBiomeHitCache()
{
return getDimension().isInverted() ? ceilingBiomeHitCache : biomeHitCache;
}
@Override
public void onHotloaded()
public void onHotload()
{
super.onHotloaded();
super.onHotload();
biomeHitCache = new KMap<>();
ceilingBiomeHitCache = new KMap<>();
loadGenerators();

View File

@ -11,6 +11,9 @@ import ninja.bytecode.iris.util.RNG;
public abstract class CeilingChunkGenerator extends ParallaxChunkGenerator
{
protected boolean generatingCeiling = false;
protected boolean ceilingCached = false;
protected IrisDimension cacheCeiling = null;
protected IrisDimension cacheFloor = null;
public CeilingChunkGenerator(String dimensionName, int threads)
{
@ -38,6 +41,15 @@ public abstract class CeilingChunkGenerator extends ParallaxChunkGenerator
}
}
@Override
public void onHotload()
{
super.onHotload();
ceilingCached = false;
cacheCeiling = null;
cacheFloor = null;
}
private void targetFloor()
{
generatingCeiling = false;
@ -61,11 +73,21 @@ public abstract class CeilingChunkGenerator extends ParallaxChunkGenerator
public IrisDimension getFloorDimension()
{
return super.getDimension();
if(cacheFloor != null)
{
return cacheFloor;
}
return cacheFloor = super.getDimension();
}
public IrisDimension getCeilingDimension()
{
if(ceilingCached)
{
return cacheCeiling;
}
if(getFloorDimension().getCeiling().isEmpty())
{
return null;
@ -78,6 +100,9 @@ public abstract class CeilingChunkGenerator extends ParallaxChunkGenerator
c.setInverted(true);
}
ceilingCached = true;
cacheCeiling = c;
return c;
}

View File

@ -261,7 +261,7 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
return generateChunkDataFailure(world, no, x, z, biomeGrid);
}
public void onHotloaded()
public void onHotload()
{
}

View File

@ -63,7 +63,7 @@ public class IrisChunkGenerator extends CeilingChunkGenerator implements IrisCon
@Override
protected void onChunkLoaded(Chunk c)
{
updateLights();
}
@Override
@ -83,4 +83,10 @@ public class IrisChunkGenerator extends CeilingChunkGenerator implements IrisCon
{
}
@Override
public void onHotloaded()
{
onHotload();
}
}

View File

@ -76,12 +76,13 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
@Override
public int getHighest(int x, int z)
{
return sampleSliver(x, z).getHighestBlock();
return getHighest(x, z, false);
}
public int getHighestGround(int x, int z)
@Override
public int getHighest(int x, int z, boolean ignoreFluid)
{
return sampleSliver(x, z).getHighestGround();
return (int) Math.round(ignoreFluid ? getTerrainHeight(x, z) : getTerrainWaterHeight(x, z));
}
@Override
@ -150,6 +151,7 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
if(getDimension().isPlaceObjects())
{
onGenerateParallax(random, x, z);
injectBiomeSky(x, z, grid);
getParallaxChunk(x, z).inject(data);
setSliverBuffer(getSliverCache().size());
getParallaxChunk(x, z).setWorldGenerated(true);
@ -161,6 +163,39 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
super.onPostParallaxPostGenerate(random, x, z, data, grid, height, biomeMap);
}
protected void injectBiomeSky(int x, int z, BiomeGrid grid)
{
if(getDimension().isInverted())
{
return;
}
int rx;
int rz;
for(int i = 0; i < 16; i++)
{
rx = (x * 16) + i;
for(int j = 0; j < 16; j++)
{
rz = (z * 16) + j;
int min = sampleSliver(rx, rz).getHighestBiome();
int max = getParallaxSliver(rx, rz).getHighestBlock();
if(min < max)
{
IrisBiome biome = getCachedBiome(i, j);
for(int g = min; g <= max; g++)
{
grid.setBiome(i, g, j, biome.getSkyBiome(masterRandom, rz, g, rx));
}
}
}
}
}
protected void onGenerateParallax(RNG random, int x, int z)
{
String key = "par." + x + "." + "z";

View File

@ -1,10 +1,7 @@
package ninja.bytecode.iris.generator;
import java.util.concurrent.locks.ReentrantLock;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.data.Bisected;
import org.bukkit.block.data.Bisected.Half;
import org.bukkit.block.data.BlockData;
@ -18,7 +15,6 @@ import ninja.bytecode.iris.object.IrisRegion;
import ninja.bytecode.iris.object.atomics.AtomicSliver;
import ninja.bytecode.iris.util.BiomeMap;
import ninja.bytecode.iris.util.BiomeResult;
import ninja.bytecode.iris.util.BlockPosition;
import ninja.bytecode.iris.util.HeightMap;
import ninja.bytecode.iris.util.RNG;
import ninja.bytecode.shuriken.collections.KList;
@ -29,8 +25,6 @@ import ninja.bytecode.shuriken.math.M;
public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
{
protected static final BlockData AIR = Material.AIR.createBlockData();
private KList<BlockPosition> updateBlocks = new KList<>();
private ReentrantLock relightLock = new ReentrantLock();
private long lastUpdateRequest = M.ms();
private long lastChunkLoad = M.ms();
private GenLayerCave glCave;
@ -48,60 +42,6 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
glCave = new GenLayerCave(this, rng.nextParallelRNG(238948));
}
public void queueUpdate(int x, int y, int z)
{
if(M.ms() - lastUpdateRequest > 3000 && M.ms() - lastChunkLoad > 3000)
{
updateBlocks.clear();
}
updateBlocks.add(new BlockPosition(x, y, z));
lastUpdateRequest = M.ms();
}
public void updateLights()
{
if(M.ms() - lastUpdateRequest > 3000 && M.ms() - lastChunkLoad > 3000)
{
updateBlocks.clear();
}
for(BlockPosition i : updateBlocks.copy())
{
if(getWorld().isChunkLoaded(i.getChunkX(), i.getChunkZ()))
{
updateBlocks.remove(i);
Block b = getWorld().getBlockAt(i.getX(), i.getY(), i.getZ());
BlockData bd = b.getBlockData();
b.setBlockData(AIR, false);
b.setBlockData(bd, true);
}
}
while(updateBlocks.size() > 5000)
{
updateBlocks.remove(0);
}
lastChunkLoad = M.ms();
}
public void checkUnderwater(int x, int y, int z, BlockData d)
{
if(d.getMaterial().equals(Material.SEA_PICKLE) || d.getMaterial().equals(Material.SOUL_SAND) || d.getMaterial().equals(Material.MAGMA_BLOCK))
{
queueUpdate(x, y, z);
}
}
public void checkSurface(int x, int y, int z, BlockData d)
{
if(d.getMaterial().equals(Material.SEA_PICKLE) || d.getMaterial().equals(Material.TORCH) || d.getMaterial().equals(Material.REDSTONE_TORCH) || d.getMaterial().equals(Material.TORCH))
{
queueUpdate(x, y, z);
}
}
@Override
protected void onGenerateColumn(int cx, int cz, int rx, int rz, int x, int z, AtomicSliver sliver, BiomeMap biomeMap)
{
@ -119,8 +59,9 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
IrisBiome biome = sampleTrueBiome(rx, rz).getBiome();
KList<BlockData> layers = biome.generateLayers(wx, wz, masterRandom, height);
KList<BlockData> seaLayers = biome.isSea() ? biome.generateSeaLayers(wx, wz, masterRandom, fluidHeight - height) : new KList<>();
cacheBiome(x, z, biome);
for(int k = Math.max(height, fluidHeight); k < 255; k++)
for(int k = Math.max(height, fluidHeight); k < Math.max(height, fluidHeight) + 3; k++)
{
if(k < Math.max(height, fluidHeight) + 3)
{
@ -129,14 +70,6 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
sliver.set(k, biome.getGroundBiome(masterRandom, rz, k, rx));
}
}
else if(!getDimension().isInverted())
{
if(biomeMap != null)
{
sliver.set(k, biome.getSkyBiome(masterRandom, rx, k, rz));
}
}
}
for(int k = Math.max(height, fluidHeight); k >= 0; k--)
@ -177,7 +110,6 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
if(stack == 1)
{
sliver.set(k + 1, d);
checkUnderwater(rx, k + 1, rz, d);
}
else if(k < fluidHeight - stack)
@ -185,7 +117,6 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
for(int l = 0; l < stack; l++)
{
sliver.set(k + l + 1, d);
checkUnderwater(rx, k + l + 1, rz, d);
}
}
@ -330,4 +261,19 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
return (int) Math.round(noise) + fluidHeight;
}
public int getFluidHeight()
{
return getDimension().getFluidHeight();
}
public double getTerrainHeight(int x, int z)
{
return getNoiseHeight(x, z) + getFluidHeight();
}
public double getTerrainWaterHeight(int x, int z)
{
return Math.max(getTerrainHeight(x, z), getFluidHeight());
}
}

View File

@ -258,16 +258,16 @@ public class IrisBiome extends IrisRegistrant
public Biome getSkyBiome(RNG rng, double x, double y, double z)
{
if(biomeSkyScatter.isEmpty())
{
return getGroundBiome(rng, x, y, z);
}
if(biomeSkyScatter.size() == 1)
{
return biomeSkyScatter.get(0);
}
if(biomeSkyScatter.isEmpty())
{
return getGroundBiome(rng, x, y, z);
}
return biomeSkyScatter.get(getBiomeGenerator(rng).fit(0, biomeSkyScatter.size() - 1, x, y, z));
}

View File

@ -83,6 +83,7 @@ public class IrisDepositGenerator
rot.setYAxis(yc);
rot.setZAxis(zc);
p.setRotation(rot);
p.setUnderwater(true);
return p;
}
@ -145,8 +146,22 @@ public class IrisDepositGenerator
public void generate(int x, int z, RNG rng, ParallaxChunkGenerator g)
{
IrisObject clump = getClump(rng);
int height = (int) (g.getHighestGround(x, z) - (clump.getH() * 1.5));
int h = rng.i(Math.max(0, minHeight), Math.min(height, Math.min(256, maxHeight)));
int height = (int) (Math.round(g.getTerrainHeight(x, z)));
int i = Math.max(0, minHeight);
int a = Math.min(height, Math.min(256, maxHeight));
if(i >= a)
{
return;
}
int h = rng.i(i, a);
if(h > maxHeight || h < minHeight)
{
return;
}
clump.place(x, h, z, g, config, rng);
}
}

View File

@ -139,6 +139,11 @@ public class IrisDimension extends IrisRegistrant
public BlockData getRock(RNG rng, double x, double y, double z)
{
if(getRockData().size() == 1)
{
return getRockData().get(0);
}
if(rockLayerGenerator == null)
{
cacheRockGenerator(rng);
@ -199,6 +204,11 @@ public class IrisDimension extends IrisRegistrant
public BlockData getFluid(RNG rng, double x, double y, double z)
{
if(getFluidData().size() == 1)
{
return getFluidData().get(0);
}
if(fluidLayerGenerator == null)
{
cacheFluidGenerator(rng);

View File

@ -131,7 +131,7 @@ public class IrisObject extends IrisRegistrant
int spinx = rng.imax() / 1000;
int spiny = rng.imax() / 1000;
int spinz = rng.imax() / 1000;
int y = yv < 0 ? placer.getHighest(x, z) + config.getRotation().rotate(new BlockVector(0, getCenter().getBlockY(), 0), yf, xf, spinx, spiny, spinz).getBlockY() : yv;
int y = yv < 0 ? placer.getHighest(x, z, config.isUnderwater()) + config.getRotation().rotate(new BlockVector(0, getCenter().getBlockY(), 0), yf, xf, spinx, spiny, spinz).getBlockY() : yv;
KMap<ChunkPosition, Integer> heightmap = config.getSnow() > 0 ? new KMap<>() : null;
for(BlockVector g : blocks.k())

View File

@ -30,6 +30,9 @@ public class IrisObjectPlacement
@Desc("If the chance check passes, place this many in a single chunk")
private int density = 1;
@Desc("If set to true, objects will place on the terrain height, ignoring the water surface.")
private boolean underwater = false;
public IrisObjectPlacement()
{

View File

@ -4,7 +4,6 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.bukkit.Material;
import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData;
import org.bukkit.generator.ChunkGenerator.BiomeGrid;
@ -22,7 +21,6 @@ public class AtomicSliver
private KMap<Integer, BlockData> block;
private KMap<Integer, Biome> biome;
private int highestBlock = 0;
private int highestGround = 0;
private int highestBiome = 0;
private int x;
private int z;
@ -44,11 +42,6 @@ public class AtomicSliver
block.put(h, d);
highestBlock = h > highestBlock ? h : highestBlock;
if(!d.getMaterial().equals(Material.WATER) && !d.getMaterial().equals(Material.LAVA))
{
highestGround = h > highestGround ? h : highestGround;
}
}
public void setSilently(int h, BlockData d)
@ -104,7 +97,6 @@ public class AtomicSliver
this.block = new KMap<Integer, BlockData>();
int h = din.readByte() - Byte.MIN_VALUE;
highestBlock = h;
highestGround = din.readByte() - Byte.MIN_VALUE;
for(int i = 0; i <= h; i++)
{
@ -115,7 +107,6 @@ public class AtomicSliver
public void write(DataOutputStream dos) throws IOException
{
dos.writeByte(highestBlock + Byte.MIN_VALUE);
dos.writeByte(highestGround + Byte.MIN_VALUE);
for(int i = 0; i <= highestBlock; i++)
{

View File

@ -6,6 +6,8 @@ public interface IObjectPlacer
{
public int getHighest(int x, int z);
public int getHighest(int x, int z, boolean ignoreFluid);
public void set(int x, int y, int z, BlockData d);
public BlockData get(int x, int y, int z);

View File

@ -32,6 +32,11 @@ public class ResourceLoader<T extends IrisRegistrant>
loadCache = new KMap<>();
}
public long count()
{
return loadCache.size();
}
protected T loadFile(File j, String key, String name)
{
try