mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-18 18:23:06 +00:00
Rotation
This commit is contained in:
parent
14e63bd47d
commit
0566b30406
@ -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);
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
|
||||
{
|
||||
return super.canSpawn(world, x, z);
|
||||
}
|
||||
|
||||
|
||||
protected ChunkData generateChunkDataFailure(World world, Random no, int x, int z, BiomeGrid biomeGrid)
|
||||
{
|
||||
ChunkData c = Bukkit.createChunkData(world);
|
||||
|
@ -40,7 +40,7 @@ public class IrisGenerator extends ParallaxChunkGenerator implements IrisContext
|
||||
@Override
|
||||
protected void onTick(int ticks)
|
||||
{
|
||||
super.onTick(ticks);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -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)
|
||||
{
|
||||
fail(e);
|
||||
}
|
||||
|
||||
return false;
|
||||
public boolean isWorldGenerated(int x, int z)
|
||||
{
|
||||
return getParallaxChunk(x, z).isWorldGenerated();
|
||||
}
|
||||
|
||||
public AtomicSliverMap getParallaxChunk(int x, int z)
|
||||
@ -112,45 +120,65 @@ 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)
|
||||
{
|
||||
onGenerateParallax(random, x, z);
|
||||
getParallaxChunk(x, z).inject(data);
|
||||
sliverBuffer = sliverCache.size();
|
||||
sliverCache.clear();
|
||||
if(getDimension().isPlaceObjects())
|
||||
{
|
||||
onGenerateParallax(random, x, z);
|
||||
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)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
IrisBiome b = sampleBiome((i * 16) + 7, (j * 16) + 7).getBiome();
|
||||
int g = 1;
|
||||
int i = ii;
|
||||
|
||||
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
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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
|
||||
@ -37,7 +38,7 @@ public class IrisObject extends IrisRegisteredObject
|
||||
this.d = d;
|
||||
center = new BlockVector(w / 2, h / 2, d / 2);
|
||||
}
|
||||
|
||||
|
||||
public static BlockVector sampleSize(File file) throws IOException
|
||||
{
|
||||
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();
|
||||
|
||||
for(BlockVector i : blocks.k())
|
||||
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 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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
@ -14,14 +18,14 @@ public class IrisObjectPlacement
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public IrisObject getSchematic(RNG random)
|
||||
{
|
||||
if(place.isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return Iris.data.getObjectLoader().load(place.get(random.nextInt(place.size())));
|
||||
}
|
||||
|
||||
|
106
src/main/java/ninja/bytecode/iris/object/IrisObjectRotation.java
Normal file
106
src/main/java/ninja/bytecode/iris/object/IrisObjectRotation.java
Normal 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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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++)
|
||||
@ -35,10 +41,12 @@ public class AtomicSliverMap
|
||||
slivers[i].insert(map.slivers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user