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)
{
double wx = getZoomed(getModifiedX(x, z));
double wz = getZoomed(getModifiedZ(x, z));
double wx = getModifiedX(x, z);
double wz = getModifiedZ(x, z);
return glBiome.getRegion(wx, wz);
}
public BiomeResult sampleBiome(int x, int z)
{
double wx = getZoomed(getModifiedX(x, z));
double wz = getZoomed(getModifiedZ(x, z));
double wx = getModifiedX(x, z);
double wz = getModifiedZ(x, z);
IrisRegion region = glBiome.getRegion(wx, wz);
return glBiome.generateRegionData(wx, wz, region);
}

View File

@ -40,7 +40,7 @@ public class IrisGenerator extends ParallaxChunkGenerator implements IrisContext
@Override
protected void onTick(int ticks)
{
super.onTick(ticks);
}
@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.AtomicSliverMap;
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.ChunkPosition;
import ninja.bytecode.iris.util.HeightMap;
@ -26,12 +27,15 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
{
private KMap<ChunkPosition, AtomicSliver> sliverCache;
protected AtomicWorldData parallaxMap;
private int sliverBuffer = 0;
private MasterLock masterLock;
private int sliverBuffer;
public ParallaxChunkGenerator(String dimensionName, int threads)
{
super(dimensionName, threads);
sliverCache = new KMap<>();
sliverBuffer = 0;
masterLock = new MasterLock();
}
public void onInit(World world, RNG rng)
@ -64,7 +68,9 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
@Override
public void set(int x, int y, int z, BlockData d)
{
getMasterLock().lock((x >> 4) + "." + (z >> 4));
getParallaxSliver(x, z).set(y, d);
getMasterLock().unlock((x >> 4) + "." + (z >> 4));
}
@Override
@ -76,22 +82,24 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
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 getParallaxMap().hasChunk(x, z);
return getParallaxChunk(x, z).isParallaxGenerated();
}
catch(IOException e)
public boolean isWorldGenerated(int x, int z)
{
fail(e);
}
return false;
return getParallaxChunk(x, z).isWorldGenerated();
}
public AtomicSliverMap getParallaxChunk(int x, int z)
@ -111,46 +119,66 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
@Override
protected void onPostGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid, HeightMap height, BiomeMap biomeMap)
{
if(getDimension().isPlaceObjects())
{
onGenerateParallax(random, x, z);
getParallaxChunk(x, z).inject(data);
sliverBuffer = sliverCache.size();
sliverCache.clear();
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)
{
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;
for(int jj = z - (rad.getZ() / 2); jj <= z + (rad.getZ() / 2); jj++)
{
int j = jj;
if(isParallaxGenerated(ii, jj))
{
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((i * 30) + (j * 30) + g++));
}
placeObject(k, i, j, random.nextParallelRNG((34 * ((i * 30) + (j * 30) + g++) * i * j) + i - j + 3569222));
}
});
getParallaxChunk(ii, jj).setParallaxGenerated(true);
}
}
@Override
protected void onTick(int ticks)
{
if(ticks % 100 == 0)
{
parallaxMap.clean();
}
getTx().waitFor(key);
}
protected void placeObject(IrisObjectPlacement o, int x, int z, RNG rng)
{
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 continentZoom = 1;
private double regionZoom = 1;
private boolean placeObjects = true;
private transient CNG coordFracture;
private transient Double sinr;

View File

@ -17,6 +17,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import ninja.bytecode.iris.util.BlockDataTools;
import ninja.bytecode.iris.util.IObjectPlacer;
import ninja.bytecode.iris.util.RNG;
import ninja.bytecode.shuriken.collections.KMap;
@Data
@ -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();
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 i : blocks.k())
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;
import lombok.Data;
import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.util.RNG;
import ninja.bytecode.shuriken.collections.KList;
@Data
public class IrisObjectPlacement
{
private KList<String> place = new KList<>();
private IrisObjectTranslate translate = new IrisObjectTranslate();
private IrisObjectRotation rotation = new IrisObjectRotation();
private double chance = 1;
private int density = 1;

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)
{
if(d == null)
{
return;
}
block.put(h, d);
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.ChunkData;
import lombok.Data;
import ninja.bytecode.iris.util.HeightMap;
@Data
public class AtomicSliverMap
{
private final AtomicSliver[] slivers;
private boolean parallaxGenerated;
private boolean worldGenerated;
public AtomicSliverMap()
{
parallaxGenerated = false;
worldGenerated = false;
slivers = new AtomicSliver[256];
for(int i = 0; i < 16; i++)
@ -39,6 +45,8 @@ public class AtomicSliverMap
public void write(OutputStream out) throws IOException
{
DataOutputStream dos = new DataOutputStream(out);
dos.writeBoolean(isParallaxGenerated());
dos.writeBoolean(isWorldGenerated());
for(int i = 0; i < 256; i++)
{
slivers[i].write(dos);
@ -50,6 +58,9 @@ public class AtomicSliverMap
public void read(InputStream in) throws IOException
{
DataInputStream din = new DataInputStream(in);
parallaxGenerated = din.readBoolean();
worldGenerated = din.readBoolean();
for(int i = 0; i < 256; i++)
{
slivers[i].read(din);

View File

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