More Performance

This commit is contained in:
Daniel Mills 2020-08-06 14:48:02 -04:00
parent f1e3210c7a
commit d5d7e9a952
12 changed files with 193 additions and 82 deletions

View File

@ -38,6 +38,7 @@ import com.volmit.iris.util.GroupedExecutor;
import com.volmit.iris.util.IO;
import com.volmit.iris.util.IrisLock;
import com.volmit.iris.util.IrisPostBlockFilter;
import com.volmit.iris.util.IrisStructureResult;
import com.volmit.iris.util.J;
import com.volmit.iris.util.JSONException;
import com.volmit.iris.util.JSONObject;
@ -179,16 +180,15 @@ public class Iris extends MortarPlugin implements BoardProvider
int z = player.getLocation().getBlockZ();
BiomeResult er = g.sampleTrueBiome(x, y, z);
IrisBiome b = er != null ? er.getBiome() : null;
IrisStructureResult st = g.getStructure(x, y, z);
tp.put(g.getMetrics().getSpeed());
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 + "Throughput" + ChatColor.GRAY + ": " + ChatColor.BOLD + "" + ChatColor.GRAY + Form.f((long) tp.getAverage()) + "");
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 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 + "Memory" + ChatColor.GRAY + ": " + mem);
if(er != null && b != null)
@ -197,6 +197,12 @@ public class Iris extends MortarPlugin implements BoardProvider
lines.add(ChatColor.GREEN + "File" + ChatColor.GRAY + ": " + b.getLoadKey());
}
if(st != null)
{
lines.add(ChatColor.GREEN + "Structure" + ChatColor.GRAY + ": " + st.getStructure().getName());
lines.add(ChatColor.GREEN + "Tile" + ChatColor.GRAY + ": " + st.getTile().toString());
}
lines.add("&7&m-----------------");
}

View File

@ -103,15 +103,13 @@ public abstract class BiomeChunkGenerator extends DimensionChunkGenerator
protected double getBiomeHeight(double rx, double rz, int x, int z)
{
double h = 0;
IrisRegion region = glBiome.getRegion(rx, rz);
BiomeResult r = glBiome.generateRegionData(rx, rz, x, z, region);
for(IrisGenerator i : getGenerators().values())
{
h += interpolateGenerator(rx, rz, i);
}
return h + r.getHeightOffset();
return h;
}
protected double interpolateGenerator(double rx, double rz, IrisGenerator gen)

View File

@ -15,12 +15,14 @@ import com.volmit.iris.object.IrisBiomeMutation;
import com.volmit.iris.object.IrisObjectPlacement;
import com.volmit.iris.object.IrisRegion;
import com.volmit.iris.object.IrisStructurePlacement;
import com.volmit.iris.object.TileResult;
import com.volmit.iris.util.BiomeMap;
import com.volmit.iris.util.CaveResult;
import com.volmit.iris.util.ChunkPosition;
import com.volmit.iris.util.HeightMap;
import com.volmit.iris.util.IObjectPlacer;
import com.volmit.iris.util.IrisLock;
import com.volmit.iris.util.IrisStructureResult;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.KMap;
import com.volmit.iris.util.NastyRunnable;
@ -195,6 +197,65 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
Iris.data.getObjectLoader().clean();
}
public IrisStructureResult getStructure(int x, int y, int z)
{
IrisBiome b = sampleTrueBiome(x, z).getBiome();
IrisRegion r = sampleRegion(x, z);
RNG ro = getMasterRandom().nextParallelRNG(496888 + (x >> 4) + (z >> 4));
int h = (int) Math.round(getTerrainHeight(x, z));
KList<IrisStructurePlacement> p = new KList<>();
for(IrisStructurePlacement i : r.getStructures())
{
if(i.getHeight() > -1)
{
if(y >= i.getHeight() && y <= i.getHeight() + (i.getStructure().getGridHeight() * i.getStructure().getMaxLayers()))
{
p.add(i);
}
}
else if(y >= h && y <= i.getStructure().getGridHeight() + h)
{
p.add(i);
}
}
for(IrisStructurePlacement i : b.getStructures())
{
if(i.getHeight() > -1)
{
if(y >= i.getHeight() && y <= i.getHeight() + (i.getStructure().getGridHeight() * i.getStructure().getMaxLayers()))
{
p.add(i);
}
}
else if(y >= h && y <= i.getStructure().getGridHeight() + h)
{
p.add(i);
}
}
for(IrisStructurePlacement i : p)
{
if(!i.hasStructure(ro, x, y, z))
{
continue;
}
int hv = (i.getHeight() == -1 ? 0 : i.getHeight()) + (Math.floorDiv(y, i.getStructure().getGridHeight()) * i.getStructure().getGridHeight());
TileResult tile = i.getStructure().getTile(ro, Math.floorDiv(i.gridSize(), x) * i.gridSize(), hv, Math.floorDiv(i.gridSize(), z) * i.gridSize());
if(tile != null && tile.getTile() != null)
{
return new IrisStructureResult(tile.getTile(), i.getStructure());
}
}
return null;
}
protected void onGenerateParallax(RNG random, int x, int z)
{
String key = "par." + x + "." + "z";
@ -222,8 +283,7 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
getAccelerant().queue(key, () ->
{
IrisBiome b = sampleTrueBiome((i * 16) + 7, (j * 16) + 7).getBiome();
RNG ro = random.nextParallelRNG(496888 + i + j);
RNG ro = getMasterRandom().nextParallelRNG(496888 + i + j);
int g = 1;
@ -261,12 +321,20 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
for(IrisStructurePlacement k : r.getStructures())
{
k.place(this, random, i, j);
q.add(() ->
{
k.place(this, random, i, j);
});
lockq.unlock();
}
for(IrisStructurePlacement k : b.getStructures())
{
k.place(this, random, i, j);
q.add(() ->
{
k.place(this, random, i, j);
});
lockq.unlock();
}
for(IrisObjectPlacement k : b.getObjects())

View File

@ -74,7 +74,6 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
try
{
KList<Runnable> surfaces = new KList<>();
int highestPlaced = 0;
BlockData block;
int fluidHeight = getDimension().getFluidHeight();
@ -89,65 +88,26 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
IrisRegion region = sampleRegion(rx, rz);
BiomeResult biomeResult = sampleTrueBiome(rx, rz, noise);
IrisBiome biome = biomeResult.getBiome();
double airReversal = biomeResult.getHeightOffset();
if(biome == null)
{
throw new RuntimeException("Null Biome!");
}
if(cachingAllowed && !sampled)
{
try
{
cacheTrueBiome[(z << 4) | x] = biomeResult;
cacheHeightMap[(z << 4) | x] = height;
}
catch(Throwable e)
{
Iris.error("Failed to write cache at " + x + " " + z + " in chunk " + cx + " " + cz);
}
}
cacheBiome(cachingAllowed && !sampled, x, z, biomeResult, height);
cacheInternalBiome(cachingAllowed && !sampled, x, z, biome);
KList<BlockData> layers = biome.generateLayers(wx, wz, masterRandom, height, height - getFluidHeight());
KList<BlockData> seaLayers = biome.isSea() ? biome.generateSeaLayers(wx, wz, masterRandom, fluidHeight - height) : new KList<>();
if(cachingAllowed && !sampled)
{
cacheInternalBiome(x, z, biome);
}
boolean caverning = false;
KList<Integer> cavernHeights = new KList<>();
int lastCavernHeight = -1;
if(height > fluidHeight && airReversal < 0 && biomeResult.getAir() != null && biomeResult.getAir().getBlockData().isNotEmpty())
{
RNG randomx = masterRandom.nextParallelRNG(95288);
int realHeight = (int) Math.floor(height - airReversal);
for(int k = height + 1; k < realHeight; k++)
{
sliver.set(k, biomeResult.getAir().get(randomx, wx, k, wz));
}
}
for(int k = Math.max(height, fluidHeight); k < Math.max(height, fluidHeight) + 12 + Math.abs(airReversal); k++)
{
if(k < Math.max(height, fluidHeight) + 12)
{
if(biomeMap != null)
{
sliver.set(k, biome.getGroundBiome(masterRandom, rz, k, rx));
}
}
}
// From Height to Bedrock
for(int k = Math.max(height, fluidHeight); k >= 0; k--)
{
boolean cavernSurface = false;
// Bedrock
if(k == 0)
{
if(biomeMap != null)
@ -160,6 +120,7 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
continue;
}
// Carving
if(carvable && glCarve.isCarved(rx, k, rz))
{
if(biomeMap != null)
@ -183,44 +144,54 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
boolean underwater = k > height && k <= fluidHeight;
// Set Biome
if(biomeMap != null)
{
sliver.set(k, biome.getGroundBiome(masterRandom, rz, k, rx));
biomeMap.setBiome(x, z, biome);
}
// Set Sea Material (water/lava)
if(underwater)
{
block = seaLayers.hasIndex(fluidHeight - k) ? layers.get(depth) : getDimension().getFluid(rockRandom, wx, k, wz);
}
// Set Surface Material for cavern layer surfaces
else if(layers.hasIndex(lastCavernHeight - k))
{
block = layers.get(lastCavernHeight - k);
}
// Set Surface Material for true surface
else
{
block = layers.hasIndex(depth) ? layers.get(depth) : getDimension().getRock(rockRandom, wx, k, wz);
depth++;
}
// Set block and update heightmaps
sliver.set(k, block);
highestPlaced = Math.max(highestPlaced, k);
// Decorate underwater surface
if(!cavernSurface && (k == height && block.getMaterial().isSolid() && k < fluidHeight))
{
decorateUnderwater(biome, sliver, wx, k, wz, rx, rz, block);
}
// Decorate Cavern surfaces, but not the true surface
if((carvable && cavernSurface) && !(k == Math.max(height, fluidHeight) && block.getMaterial().isSolid() && k < 255 && k >= fluidHeight))
{
decorateLand(biome, sliver, wx, k, wz, rx, rz, block);
}
}
// Carve out biomes
KList<CaveResult> caveResults = glCave.genCaves(rx, rz, x, z, sliver);
IrisBiome caveBiome = glBiome.generateData(InferredType.CAVE, wx, wz, rx, rz, region).getBiome();
// Decorate Cave Biome Height Sections
if(caveBiome != null)
{
for(CaveResult i : caveResults)
@ -258,20 +229,17 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
block = sliver.get(Math.max(height, fluidHeight));
// Decorate True Surface
if(block.getMaterial().isSolid())
{
decorateLand(biome, sliver, wx, Math.max(height, fluidHeight), wz, rx, rz, block);
}
// Update Height Map
if(!sampled && cachingAllowed && highestPlaced < height)
{
cacheHeightMap[(z << 4) | x] = highestPlaced;
}
for(Runnable i : surfaces)
{
i.run();
}
}
catch(Throwable e)
@ -280,6 +248,31 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
}
}
protected void cacheInternalBiome(boolean b, int x, int z, IrisBiome bv)
{
if(b)
{
cacheInternalBiome(x, z, bv);
}
}
private void cacheBiome(boolean b, int x, int z, BiomeResult biomeResult, int height)
{
if(b)
{
try
{
cacheTrueBiome[(z << 4) | x] = biomeResult;
cacheHeightMap[(z << 4) | x] = height;
}
catch(Throwable e)
{
Iris.error("Failed to write cache at " + x + " " + z);
}
}
}
@Override
protected void onGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid)
{

View File

@ -147,7 +147,7 @@ public class GenLayerBiome extends GenLayer
{
if(i.getType().equals(type) && i.isRidge(rng, rawX, rawZ))
{
return new BiomeResult(Iris.data.getBiomeLoader().load(i.getBiome()).infer(i.getAs(), type), 0.5, i.getRidgeHeight(rng, rawX, rawZ), i.getAir());
return new BiomeResult(Iris.data.getBiomeLoader().load(i.getBiome()).infer(i.getAs(), type), 0.5);
}
}
@ -155,7 +155,7 @@ public class GenLayerBiome extends GenLayer
{
if(i.getType().equals(type) && i.isSpot(rng, rawX, rawZ))
{
return new BiomeResult(Iris.data.getBiomeLoader().load(i.getBiome()).infer(i.getAs(), type), 0.5, i.getSpotHeight(rng, rawX, rawZ), i.getAir());
return new BiomeResult(Iris.data.getBiomeLoader().load(i.getBiome()).infer(i.getAs(), type), 0.5);
}
}

View File

@ -112,17 +112,25 @@ public class IrisStructure extends IrisRegistrant
public boolean isWall(RNG rng, double x, double y, double z, StructureTileFace face)
{
if(face == StructureTileFace.DOWN && maxLayers == 1)
if((face == StructureTileFace.DOWN || face == StructureTileFace.UP) && maxLayers == 1)
{
return true;
}
return isWall(rng, x, y, z, (face.ordinal() + 12) * 3);
}
int gs = getGridSize() + 1;
int gh = getGridHeight() + 1;
int gx = getTileHorizon(x);
int gy = getTileVertical(y);
int gz = getTileHorizon(z);
int hx = face.x();
int hy = face.y();
int hz = face.z();
private boolean isWall(RNG rng, double x, double y, double z, int side)
{
return getWallGenerator(rng).fitDoubleD(0, 1, (getTileHorizon(x) + side) / wallChanceZoom, (getTileVertical(y) + side) / wallChanceZoom, (getTileHorizon(z) - side) / wallChanceZoom) < getWallChance();
int tx = (gx * 2) + (hx * gs);
int ty = (gy * 2) + (hy * gh);
int tz = (gz * 2) + (hz * gs);
return getWallGenerator(rng).fitDoubleD(0, 1, (tx) / wallChanceZoom, ty / wallChanceZoom, tz / wallChanceZoom) < getWallChance();
}
public int getTileHorizon(double v)

View File

@ -55,19 +55,20 @@ public class IrisStructurePlacement
int h;
RNG rnp = rng.nextParallelRNG(cx - (cz * cz));
int s = gridSize() - (getStructure().isMergeEdges() ? 1 : 0);
int sh = gridHeight() - (getStructure().isMergeEdges() ? 1 : 0);
for(int i = cx << 4; i < (cx << 4) + 15; i += Math.max(s / 2, 1))
{
for(int j = cz << 4; j < (cz << 4) + 15; j += Math.max(s / 2, 1))
{
for(int k = 0; k < s * getStructure().getMaxLayers(); k += Math.max(s, 1))
for(int k = 0; k < s * getStructure().getMaxLayers(); k += Math.max(sh, 1))
{
if(!hasStructure(rng, i, k, j))
{
continue;
}
h = (height == -1 ? 0 : height) + (Math.floorDiv(k, s) * s);
h = (height == -1 ? 0 : height) + (Math.floorDiv(k, sh) * sh);
t = getStructure().getTile(rng, i / zoom, h / zoom, j / zoom);
if(t != null)
@ -106,6 +107,11 @@ public class IrisStructurePlacement
return getStructure().getGridSize();
}
public int gridHeight()
{
return getStructure().getGridHeight();
}
public IrisStructure getStructure()
{
return structure.aquire(() -> Iris.data.getStructureLoader().load(getTileset()));

View File

@ -45,6 +45,16 @@ public class IrisStructureTile
{
}
public String toString()
{
return (ceiling.required() ? "C" : "") +
(floor.required() ? "F" : "") + "| "+
(north.required() ? "X" : "-") +
(south.required() ? "X" : "-") +
(east.required() ? "X" : "-") +
(west.required() ? "X" : "-") + " |";
}
public boolean likeAGlove(boolean floor, boolean ceiling, KList<StructureTileFace> walls)
{

View File

@ -9,6 +9,21 @@ public enum StructureTileFace
EAST,
WEST;
public int x()
{
return this.equals(EAST) ? 1 : this.equals(WEST) ? -1 : 0;
}
public int y()
{
return this.equals(UP) ? 1 : this.equals(DOWN) ? -1 : 0;
}
public int z()
{
return this.equals(SOUTH) ? 1 : this.equals(NORTH) ? -1 : 0;
}
public StructureTileFace rotate90CW()
{
switch(this)

View File

@ -1,7 +1,6 @@
package com.volmit.iris.util;
import com.volmit.iris.object.IrisBiome;
import com.volmit.iris.object.IrisBiomePaletteLayer;
import lombok.Data;
@ -9,23 +8,12 @@ import lombok.Data;
public class BiomeResult
{
private IrisBiome biome;
private IrisBiomePaletteLayer air;
private double heightOffset;
private double distance;
public BiomeResult(IrisBiome biome, double distance)
{
this.biome = biome;
this.distance = distance;
this.heightOffset = 0;
}
public BiomeResult(IrisBiome biome, double distance, double height, IrisBiomePaletteLayer air)
{
this.biome = biome;
this.distance = distance;
this.heightOffset = height;
this.air = air;
}
public boolean is(BiomeResult r)

View File

@ -67,7 +67,7 @@ public class CellGenerator
return ((fn.GetCellular((float) ((x * cellScale) + (cng.noise(x, z) * shuffle)),
(float) ((y * cellScale) + (cng.noise(x, y) * shuffle))
(float) ((y * 8 * cellScale) + (cng.noise(x, y * 8) * shuffle))
, (float) ((z * cellScale) + (cng.noise(z, x) * shuffle))) + 1f) / 2f) * (possibilities - 1);
}

View File

@ -0,0 +1,19 @@
package com.volmit.iris.util;
import com.volmit.iris.object.IrisStructure;
import com.volmit.iris.object.IrisStructureTile;
import lombok.Data;
@Data
public class IrisStructureResult
{
private IrisStructureTile tile;
private IrisStructure structure;
public IrisStructureResult(IrisStructureTile tile, IrisStructure structure)
{
this.tile = tile;
this.structure = structure;
}
}