This commit is contained in:
Daniel Mills 2020-05-14 16:39:08 -04:00
parent 14e63bd47d
commit 0566b30406
14 changed files with 339 additions and 54 deletions

View File

@ -31,15 +31,15 @@ public abstract class BiomeChunkGenerator extends DimensionChunkGenerator
public IrisRegion sampleRegion(int x, int z) public IrisRegion sampleRegion(int x, int z)
{ {
double wx = getZoomed(getModifiedX(x, z)); double wx = getModifiedX(x, z);
double wz = getZoomed(getModifiedZ(x, z)); double wz = getModifiedZ(x, z);
return glBiome.getRegion(wx, wz); return glBiome.getRegion(wx, wz);
} }
public BiomeResult sampleBiome(int x, int z) public BiomeResult sampleBiome(int x, int z)
{ {
double wx = getZoomed(getModifiedX(x, z)); double wx = getModifiedX(x, z);
double wz = getZoomed(getModifiedZ(x, z)); double wz = getModifiedZ(x, z);
IrisRegion region = glBiome.getRegion(wx, wz); IrisRegion region = glBiome.getRegion(wx, wz);
return glBiome.generateRegionData(wx, wz, region); return glBiome.generateRegionData(wx, wz, region);
} }

View File

@ -186,7 +186,7 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
{ {
return super.canSpawn(world, x, z); return super.canSpawn(world, x, z);
} }
protected ChunkData generateChunkDataFailure(World world, Random no, int x, int z, BiomeGrid biomeGrid) protected ChunkData generateChunkDataFailure(World world, Random no, int x, int z, BiomeGrid biomeGrid)
{ {
ChunkData c = Bukkit.createChunkData(world); ChunkData c = Bukkit.createChunkData(world);

View File

@ -40,7 +40,7 @@ public class IrisGenerator extends ParallaxChunkGenerator implements IrisContext
@Override @Override
protected void onTick(int ticks) protected void onTick(int ticks)
{ {
super.onTick(ticks);
} }
@Override @Override

View File

@ -13,6 +13,7 @@ import ninja.bytecode.iris.object.IrisObjectPlacement;
import ninja.bytecode.iris.object.atomics.AtomicSliver; import ninja.bytecode.iris.object.atomics.AtomicSliver;
import ninja.bytecode.iris.object.atomics.AtomicSliverMap; import ninja.bytecode.iris.object.atomics.AtomicSliverMap;
import ninja.bytecode.iris.object.atomics.AtomicWorldData; import ninja.bytecode.iris.object.atomics.AtomicWorldData;
import ninja.bytecode.iris.object.atomics.MasterLock;
import ninja.bytecode.iris.util.BiomeMap; import ninja.bytecode.iris.util.BiomeMap;
import ninja.bytecode.iris.util.ChunkPosition; import ninja.bytecode.iris.util.ChunkPosition;
import ninja.bytecode.iris.util.HeightMap; import ninja.bytecode.iris.util.HeightMap;
@ -26,12 +27,15 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
{ {
private KMap<ChunkPosition, AtomicSliver> sliverCache; private KMap<ChunkPosition, AtomicSliver> sliverCache;
protected AtomicWorldData parallaxMap; protected AtomicWorldData parallaxMap;
private int sliverBuffer = 0; private MasterLock masterLock;
private int sliverBuffer;
public ParallaxChunkGenerator(String dimensionName, int threads) public ParallaxChunkGenerator(String dimensionName, int threads)
{ {
super(dimensionName, threads); super(dimensionName, threads);
sliverCache = new KMap<>(); sliverCache = new KMap<>();
sliverBuffer = 0;
masterLock = new MasterLock();
} }
public void onInit(World world, RNG rng) public void onInit(World world, RNG rng)
@ -64,7 +68,9 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
@Override @Override
public void set(int x, int y, int z, BlockData d) public void set(int x, int y, int z, BlockData d)
{ {
getMasterLock().lock((x >> 4) + "." + (z >> 4));
getParallaxSliver(x, z).set(y, d); getParallaxSliver(x, z).set(y, d);
getMasterLock().unlock((x >> 4) + "." + (z >> 4));
} }
@Override @Override
@ -76,22 +82,24 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
public AtomicSliver getParallaxSliver(int wx, int wz) public AtomicSliver getParallaxSliver(int wx, int wz)
{ {
return getParallaxChunk(wx >> 4, wz >> 4).getSliver(wx & 15, wz & 15); getMasterLock().lock("gpc");
getMasterLock().lock((wx >> 4) + "." + (wz >> 4));
AtomicSliverMap map = getParallaxChunk(wx >> 4, wz >> 4);
getMasterLock().unlock("gpc");
AtomicSliver sliver = map.getSliver(wx & 15, wz & 15);
getMasterLock().unlock((wx >> 4) + "." + (wz >> 4));
return sliver;
} }
public boolean hasParallaxChunk(int x, int z) public boolean isParallaxGenerated(int x, int z)
{ {
try return getParallaxChunk(x, z).isParallaxGenerated();
{ }
return getParallaxMap().hasChunk(x, z);
}
catch(IOException e) public boolean isWorldGenerated(int x, int z)
{ {
fail(e); return getParallaxChunk(x, z).isWorldGenerated();
}
return false;
} }
public AtomicSliverMap getParallaxChunk(int x, int z) public AtomicSliverMap getParallaxChunk(int x, int z)
@ -112,45 +120,65 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
@Override @Override
protected void onPostGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid, HeightMap height, BiomeMap biomeMap) protected void onPostGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid, HeightMap height, BiomeMap biomeMap)
{ {
onGenerateParallax(random, x, z); if(getDimension().isPlaceObjects())
getParallaxChunk(x, z).inject(data); {
sliverBuffer = sliverCache.size(); onGenerateParallax(random, x, z);
sliverCache.clear(); getParallaxChunk(x, z).inject(data);
setSliverBuffer(getSliverCache().size());
getParallaxChunk(x, z).setWorldGenerated(true);
getParallaxMap().clean(x + z);
getSliverCache().clear();
getMasterLock().clear();
}
} }
protected void onGenerateParallax(RNG random, int x, int z) protected void onGenerateParallax(RNG random, int x, int z)
{ {
ChunkPosition pos = Iris.data.getObjectLoader().getParallaxSize(); String key = "par." + x + "." + "z";
ChunkPosition rad = Iris.data.getObjectLoader().getParallaxSize();
for(int i = x - pos.getX() / 2; i <= x + pos.getX() / 2; i++) for(int ii = x - (rad.getX() / 2); ii <= x + (rad.getX() / 2); ii++)
{ {
for(int j = z - pos.getZ() / 2; j <= z + pos.getZ() / 2; j++) int i = ii;
{
IrisBiome b = sampleBiome((i * 16) + 7, (j * 16) + 7).getBiome();
int g = 1;
for(IrisObjectPlacement k : b.getObjects()) for(int jj = z - (rad.getZ() / 2); jj <= z + (rad.getZ() / 2); jj++)
{
int j = jj;
if(isParallaxGenerated(ii, jj))
{ {
placeObject(k, i, j, random.nextParallelRNG((i * 30) + (j * 30) + g++)); continue;
} }
if(isWorldGenerated(ii, jj))
{
continue;
}
getTx().queue(key, () ->
{
IrisBiome b = sampleBiome((i * 16) + 7, (j * 16) + 7).getBiome();
int g = 1;
for(IrisObjectPlacement k : b.getObjects())
{
placeObject(k, i, j, random.nextParallelRNG((34 * ((i * 30) + (j * 30) + g++) * i * j) + i - j + 3569222));
}
});
getParallaxChunk(ii, jj).setParallaxGenerated(true);
} }
} }
}
@Override getTx().waitFor(key);
protected void onTick(int ticks)
{
if(ticks % 100 == 0)
{
parallaxMap.clean();
}
} }
protected void placeObject(IrisObjectPlacement o, int x, int z, RNG rng) protected void placeObject(IrisObjectPlacement o, int x, int z, RNG rng)
{ {
for(int i = 0; i < o.getTriesForChunk(rng); i++) for(int i = 0; i < o.getTriesForChunk(rng); i++)
{ {
o.getSchematic(rng).place((x * 16) * rng.nextInt(16), (z * 16) + rng.nextInt(16), this); rng = rng.nextParallelRNG((i * 3 + 8) - 23040);
o.getSchematic(rng).place((x * 16) + rng.nextInt(16), (z * 16) + rng.nextInt(16), this, o, rng);
} }
} }

View File

@ -0,0 +1,41 @@
package ninja.bytecode.iris.object;
import lombok.Data;
@Data
public class IrisAxisRotationClamp
{
private boolean enabled = false;
private double min = 0;
private double max = 0;
private double interval = 0;
public IrisAxisRotationClamp()
{
}
public IrisAxisRotationClamp(boolean enabled, double min, double max, double interval)
{
this.enabled = enabled;
this.min = min;
this.max = max;
this.interval = interval;
}
public boolean isUnlimited()
{
return min == max;
}
public double getRadians(int rng)
{
if(isUnlimited())
{
return Math.toRadians((rng * interval) % 360D);
}
double deg = min + (rng * interval) % (Math.abs(max - min) / 360D);
return Math.toRadians(deg);
}
}

View File

@ -32,6 +32,7 @@ public class IrisDimension extends IrisRegisteredObject
private double seaZoom = 1; private double seaZoom = 1;
private double continentZoom = 1; private double continentZoom = 1;
private double regionZoom = 1; private double regionZoom = 1;
private boolean placeObjects = true;
private transient CNG coordFracture; private transient CNG coordFracture;
private transient Double sinr; private transient Double sinr;

View File

@ -17,6 +17,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import ninja.bytecode.iris.util.BlockDataTools; import ninja.bytecode.iris.util.BlockDataTools;
import ninja.bytecode.iris.util.IObjectPlacer; import ninja.bytecode.iris.util.IObjectPlacer;
import ninja.bytecode.iris.util.RNG;
import ninja.bytecode.shuriken.collections.KMap; import ninja.bytecode.shuriken.collections.KMap;
@Data @Data
@ -37,7 +38,7 @@ public class IrisObject extends IrisRegisteredObject
this.d = d; this.d = d;
center = new BlockVector(w / 2, h / 2, d / 2); center = new BlockVector(w / 2, h / 2, d / 2);
} }
public static BlockVector sampleSize(File file) throws IOException public static BlockVector sampleSize(File file) throws IOException
{ {
FileInputStream in = new FileInputStream(file); FileInputStream in = new FileInputStream(file);
@ -113,13 +114,21 @@ public class IrisObject extends IrisRegisteredObject
} }
} }
public void place(int x, int z, IObjectPlacer placer) public void place(int x, int z, IObjectPlacer placer, IrisObjectPlacement config, RNG rng)
{ {
int y = placer.getHighest(x, z) + getCenter().getBlockY(); boolean yf = rng.nextBoolean();
boolean xf = rng.nextBoolean();
for(BlockVector i : blocks.k()) int spinx = rng.imax() / 1000;
int spiny = rng.imax() / 1000;
int spinz = rng.imax() / 1000;
int y = placer.getHighest(x, z) + config.getRotation().rotate(new BlockVector(0, getCenter().getBlockY(), 0), yf, xf, spinx, spiny, spinz).getBlockY();
for(BlockVector g : blocks.k())
{ {
placer.set(x + i.getBlockX(), y + i.getBlockY(), z + i.getBlockZ(), blocks.get(i)); BlockVector i = g.clone();
i = config.getRotation().rotate(i.clone(), yf, xf, spinx, spiny, spinz).clone();
i = config.getTranslate().translate(i.clone()).clone();
placer.set(x + i.getBlockX(), y + i.getBlockY(), z + i.getBlockZ(), blocks.get(g));
} }
} }

View File

@ -1,12 +1,16 @@
package ninja.bytecode.iris.object; package ninja.bytecode.iris.object;
import lombok.Data;
import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.util.RNG; import ninja.bytecode.iris.util.RNG;
import ninja.bytecode.shuriken.collections.KList; import ninja.bytecode.shuriken.collections.KList;
@Data
public class IrisObjectPlacement public class IrisObjectPlacement
{ {
private KList<String> place = new KList<>(); private KList<String> place = new KList<>();
private IrisObjectTranslate translate = new IrisObjectTranslate();
private IrisObjectRotation rotation = new IrisObjectRotation();
private double chance = 1; private double chance = 1;
private int density = 1; private int density = 1;
@ -14,14 +18,14 @@ public class IrisObjectPlacement
{ {
} }
public IrisObject getSchematic(RNG random) public IrisObject getSchematic(RNG random)
{ {
if(place.isEmpty()) if(place.isEmpty())
{ {
return null; return null;
} }
return Iris.data.getObjectLoader().load(place.get(random.nextInt(place.size()))); return Iris.data.getObjectLoader().load(place.get(random.nextInt(place.size())));
} }

View File

@ -0,0 +1,106 @@
package ninja.bytecode.iris.object;
import org.bukkit.util.BlockVector;
import lombok.Data;
@Data
public class IrisObjectRotation
{
private boolean enabled = true;
private IrisAxisRotationClamp xAxis = new IrisAxisRotationClamp();
private IrisAxisRotationClamp yAxis = new IrisAxisRotationClamp(true, 0, 0, 90);
private IrisAxisRotationClamp zAxis = new IrisAxisRotationClamp();
public IrisObjectRotation()
{
}
public double getYRotation(int spin)
{
return getRotation(spin, yAxis);
}
public double getXRotation(int spin)
{
return getRotation(spin, xAxis);
}
public double getZRotation(int spin)
{
return getRotation(spin, zAxis);
}
public double getRotation(int spin, IrisAxisRotationClamp clamp)
{
if(!enabled)
{
return 0;
}
if(!clamp.isEnabled())
{
return 0;
}
return clamp.getRadians(spin);
}
public BlockVector rotate(BlockVector b, boolean yf, boolean xf, int spinx, int spiny, int spinz)
{
if(!canRotate())
{
return b;
}
BlockVector v = b.clone();
if(yf && canRotateY())
{
v.rotateAroundY(getYRotation(spiny));
}
if(xf && canRotateX())
{
v.rotateAroundX(getXRotation(spinx));
}
if(canRotateZ())
{
v.rotateAroundZ(getZRotation(spinz));
}
if(!xf && canRotateX())
{
v.rotateAroundX(getXRotation(spinx));
}
if(!yf && canRotateY())
{
v.rotateAroundY(getYRotation(spiny));
}
return v;
}
public boolean canRotateX()
{
return enabled && xAxis.isEnabled();
}
public boolean canRotateY()
{
return enabled && yAxis.isEnabled();
}
public boolean canRotateZ()
{
return enabled && zAxis.isEnabled();
}
public boolean canRotate()
{
return canRotateX() || canRotateY() || canRotateZ();
}
}

View File

@ -0,0 +1,35 @@
package ninja.bytecode.iris.object;
import org.bukkit.util.BlockVector;
import lombok.Data;
@Data
public class IrisObjectTranslate
{
private int x;
private int y;
private int z;
public IrisObjectTranslate()
{
x = 0;
y = 0;
z = 0;
}
public boolean canTranslate()
{
return x != 0 || y != 0 || z != 0;
}
public BlockVector translate(BlockVector i)
{
if(canTranslate())
{
return (BlockVector) i.clone().add(new BlockVector(x, y, z));
}
return i;
}
}

View File

@ -35,6 +35,11 @@ public class AtomicSliver
public void set(int h, BlockData d) public void set(int h, BlockData d)
{ {
if(d == null)
{
return;
}
block.put(h, d); block.put(h, d);
highestBlock = h > highestBlock ? h : highestBlock; highestBlock = h > highestBlock ? h : highestBlock;
} }

View File

@ -9,14 +9,20 @@ import java.io.OutputStream;
import org.bukkit.generator.ChunkGenerator.BiomeGrid; import org.bukkit.generator.ChunkGenerator.BiomeGrid;
import org.bukkit.generator.ChunkGenerator.ChunkData; import org.bukkit.generator.ChunkGenerator.ChunkData;
import lombok.Data;
import ninja.bytecode.iris.util.HeightMap; import ninja.bytecode.iris.util.HeightMap;
@Data
public class AtomicSliverMap public class AtomicSliverMap
{ {
private final AtomicSliver[] slivers; private final AtomicSliver[] slivers;
private boolean parallaxGenerated;
private boolean worldGenerated;
public AtomicSliverMap() public AtomicSliverMap()
{ {
parallaxGenerated = false;
worldGenerated = false;
slivers = new AtomicSliver[256]; slivers = new AtomicSliver[256];
for(int i = 0; i < 16; i++) for(int i = 0; i < 16; i++)
@ -35,10 +41,12 @@ public class AtomicSliverMap
slivers[i].insert(map.slivers[i]); slivers[i].insert(map.slivers[i]);
} }
} }
public void write(OutputStream out) throws IOException public void write(OutputStream out) throws IOException
{ {
DataOutputStream dos = new DataOutputStream(out); DataOutputStream dos = new DataOutputStream(out);
dos.writeBoolean(isParallaxGenerated());
dos.writeBoolean(isWorldGenerated());
for(int i = 0; i < 256; i++) for(int i = 0; i < 256; i++)
{ {
slivers[i].write(dos); slivers[i].write(dos);
@ -50,6 +58,9 @@ public class AtomicSliverMap
public void read(InputStream in) throws IOException public void read(InputStream in) throws IOException
{ {
DataInputStream din = new DataInputStream(in); DataInputStream din = new DataInputStream(in);
parallaxGenerated = din.readBoolean();
worldGenerated = din.readBoolean();
for(int i = 0; i < 256; i++) for(int i = 0; i < 256; i++)
{ {
slivers[i].read(din); slivers[i].read(din);

View File

@ -7,7 +7,6 @@ import java.io.IOException;
import org.bukkit.World; import org.bukkit.World;
import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.util.ChunkPosition; import ninja.bytecode.iris.util.ChunkPosition;
import ninja.bytecode.shuriken.collections.KMap; import ninja.bytecode.shuriken.collections.KMap;
import ninja.bytecode.shuriken.math.M; import ninja.bytecode.shuriken.math.M;
@ -172,8 +171,6 @@ public class AtomicWorldData
AtomicSliverMap m = dat.get(x & 31, z & 31); AtomicSliverMap m = dat.get(x & 31, z & 31);
loadedChunks.put(pos, m); loadedChunks.put(pos, m);
Iris.info("Loaded chunk: sections: " + loadedSections.size());
return m; return m;
} }
@ -237,11 +234,11 @@ public class AtomicWorldData
return loadedChunks; return loadedChunks;
} }
public void clean() public void clean(int j)
{ {
for(ChunkPosition i : lastRegion.k()) for(ChunkPosition i : lastRegion.k())
{ {
if(M.ms() - lastRegion.get(i) > 3000) if(M.ms() - lastRegion.get(i) > 60000)
{ {
lastRegion.remove(i); lastRegion.remove(i);

View File

@ -0,0 +1,48 @@
package ninja.bytecode.iris.object.atomics;
import java.util.concurrent.locks.ReentrantLock;
import ninja.bytecode.shuriken.collections.KMap;
public class MasterLock
{
private KMap<String, ReentrantLock> locks;
private ReentrantLock lock;
public MasterLock()
{
locks = new KMap<>();
lock = new ReentrantLock();
}
public void clear()
{
locks.clear();
}
public void lock(String key)
{
lock.lock();
if(!locks.containsKey(key))
{
locks.put(key, new ReentrantLock());
}
ReentrantLock l = locks.get(key);
lock.unlock();
l.lock();
}
public void unlock(String key)
{
lock.lock();
if(!locks.containsKey(key))
{
locks.put(key, new ReentrantLock());
}
ReentrantLock l = locks.get(key);
lock.unlock();
l.unlock();
}
}