This commit is contained in:
Daniel Mills 2020-05-19 04:28:47 -04:00
parent b8f79f6559
commit 202a7106a7
27 changed files with 523 additions and 183 deletions

69
plains.json Normal file
View File

@ -0,0 +1,69 @@
{
"children": [],
"decorators": [],
"objects": [],
"name": "Plains",
"layers": [
{
"minHeight": 1,
"terrainZoom": 5,
"maxHeight": 3,
"palette": [
"GRASS_BLOCK"
],
"dispersion": "SCATTER"
},
{
"minHeight": 1,
"terrainZoom": 5,
"maxHeight": 1,
"palette": [
"DIRT"
],
"dispersion": "SCATTER"
},
{
"minHeight": 1,
"terrainZoom": 5,
"maxHeight": 3,
"palette": [
"DIRT",
"COARSE_DIRT"
],
"dispersion": "SCATTER"
},
{
"minHeight": 6,
"terrainZoom": 5,
"maxHeight": 2341,
"palette": [
"STONE",
"ANDESITE",
"STONE"
],
"dispersion": "SCATTER"
}
],
"childShrinkFactor": 1.55,
"derivative": "THE_VOID",
"auxiliaryGenerators": [
{
"offsetX": 0,
"offsetZ": 0.01,
"min": 1,
"seed": 1336,
"max": 5,
"zoom": 3.065
},
{
"offsetX": 0,
"offsetZ": 0,
"min": 1.01,
"seed": 1339,
"max": 2,
"zoom": 1.6
}
],
"highHeight": 3.66669,
"lowHeight": 31.5
}

View File

@ -25,7 +25,7 @@ import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import ninja.bytecode.iris.generator.IrisGenerator; import ninja.bytecode.iris.generator.IrisChunkGenerator;
import ninja.bytecode.iris.object.IrisBiome; import ninja.bytecode.iris.object.IrisBiome;
import ninja.bytecode.iris.object.IrisDimension; import ninja.bytecode.iris.object.IrisDimension;
import ninja.bytecode.iris.object.IrisObject; import ninja.bytecode.iris.object.IrisObject;
@ -84,15 +84,13 @@ public class Iris extends JavaPlugin implements BoardProvider
World world = player.getWorld(); World world = player.getWorld();
List<String> lines = new ArrayList<>(); List<String> lines = new ArrayList<>();
if(world.getGenerator() instanceof IrisGenerator) if(world.getGenerator() instanceof IrisChunkGenerator)
{ {
IrisGenerator g = (IrisGenerator) world.getGenerator(); IrisChunkGenerator g = (IrisChunkGenerator) world.getGenerator();
int x = player.getLocation().getBlockX(); int x = player.getLocation().getBlockX();
int z = player.getLocation().getBlockZ(); int z = player.getLocation().getBlockZ();
IrisDimension dim = g.getDimension(); BiomeResult er = g.sampleTrueBiome(x, z);
BiomeResult er = g.getBiome(x, z);
IrisBiome b = er != null ? er.getBiome() : null; IrisBiome b = er != null ? er.getBiome() : null;
int fh = dim.getFluidHeight();
lines.add("&7&m-----------------"); 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 + "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 + "Loss" + ChatColor.GRAY + ": " + ChatColor.BOLD + "" + ChatColor.GRAY + Form.duration(g.getMetrics().getLoss().getAverage(), 4) + "");
@ -106,8 +104,8 @@ public class Iris extends JavaPlugin implements BoardProvider
{ {
lines.add(ChatColor.GREEN + "Biome" + ChatColor.GRAY + ": " + b.getName()); lines.add(ChatColor.GREEN + "Biome" + ChatColor.GRAY + ": " + b.getName());
lines.add(ChatColor.GREEN + "File" + ChatColor.GRAY + ": " + b.getLoadKey() + ".json"); lines.add(ChatColor.GREEN + "File" + ChatColor.GRAY + ": " + b.getLoadKey() + ".json");
lines.add(ChatColor.GREEN + "Height" + ChatColor.GRAY + ": " + (int) (b.getLowHeight() + fh) + " - " + (int) (b.getHighHeight() + fh) + " (" + (int) (b.getHighHeight() - b.getLowHeight()) + ")");
} }
lines.add("&7&m-----------------"); lines.add("&7&m-----------------");
} }
@ -479,7 +477,7 @@ public class Iris extends JavaPlugin implements BoardProvider
imsg(i, "Creating Iris " + dimm + "..."); imsg(i, "Creating Iris " + dimm + "...");
} }
IrisGenerator gx = new IrisGenerator(dimm, 16); IrisChunkGenerator gx = new IrisChunkGenerator(dimm, 16);
O<Boolean> done = new O<Boolean>(); O<Boolean> done = new O<Boolean>();
done.set(false); done.set(false);
@ -531,7 +529,7 @@ public class Iris extends JavaPlugin implements BoardProvider
@Override @Override
public ChunkGenerator getDefaultWorldGenerator(String worldName, String id) public ChunkGenerator getDefaultWorldGenerator(String worldName, String id)
{ {
return new IrisGenerator("overworld", 16); return new IrisChunkGenerator("overworld", 16);
} }
public static void msg(String string) public static void msg(String string)

View File

@ -32,4 +32,6 @@ public interface IrisContext
public int getHeight(int x, int z); public int getHeight(int x, int z);
public World getWorld(); public World getWorld();
public void onHotloaded();
} }

View File

@ -11,7 +11,8 @@ import lombok.Data;
import ninja.bytecode.iris.object.IrisBiome; import ninja.bytecode.iris.object.IrisBiome;
import ninja.bytecode.iris.object.IrisBiomeDecorator; import ninja.bytecode.iris.object.IrisBiomeDecorator;
import ninja.bytecode.iris.object.IrisDimension; import ninja.bytecode.iris.object.IrisDimension;
import ninja.bytecode.iris.object.IrisNoiseLayer; import ninja.bytecode.iris.object.IrisGenerator;
import ninja.bytecode.iris.object.IrisNoiseGenerator;
import ninja.bytecode.iris.object.IrisObjectPlacement; import ninja.bytecode.iris.object.IrisObjectPlacement;
import ninja.bytecode.iris.object.IrisRegion; import ninja.bytecode.iris.object.IrisRegion;
import ninja.bytecode.iris.util.IO; import ninja.bytecode.iris.util.IO;
@ -27,6 +28,7 @@ public class IrisDataManager
private ResourceLoader<IrisBiome> biomeLoader; private ResourceLoader<IrisBiome> biomeLoader;
private ResourceLoader<IrisRegion> regionLoader; private ResourceLoader<IrisRegion> regionLoader;
private ResourceLoader<IrisDimension> dimensionLoader; private ResourceLoader<IrisDimension> dimensionLoader;
private ResourceLoader<IrisGenerator> generatorLoader;
private ObjectResourceLoader objectLoader; private ObjectResourceLoader objectLoader;
public void hotloaded() public void hotloaded()
@ -35,6 +37,7 @@ public class IrisDataManager
this.regionLoader = new ResourceLoader<>(packs, "regions", "Region", IrisRegion.class); this.regionLoader = new ResourceLoader<>(packs, "regions", "Region", IrisRegion.class);
this.biomeLoader = new ResourceLoader<>(packs, "biomes", "Biome", IrisBiome.class); this.biomeLoader = new ResourceLoader<>(packs, "biomes", "Biome", IrisBiome.class);
this.dimensionLoader = new ResourceLoader<>(packs, "dimensions", "Dimension", IrisDimension.class); this.dimensionLoader = new ResourceLoader<>(packs, "dimensions", "Dimension", IrisDimension.class);
this.generatorLoader = new ResourceLoader<>(packs, "generators", "Generator", IrisGenerator.class);
this.objectLoader = new ObjectResourceLoader(packs, "objects", "Object"); this.objectLoader = new ObjectResourceLoader(packs, "objects", "Object");
writeExamples(); writeExamples();
} }
@ -68,9 +71,29 @@ public class IrisDataManager
new File(examples, "example-pack/regions").mkdirs(); new File(examples, "example-pack/regions").mkdirs();
new File(examples, "example-pack/biomes").mkdirs(); new File(examples, "example-pack/biomes").mkdirs();
new File(examples, "example-pack/dimensions").mkdirs(); new File(examples, "example-pack/dimensions").mkdirs();
new File(examples, "example-pack/generators").mkdirs();
IO.writeAll(new File(examples, "biome-list.txt"), biomes); IO.writeAll(new File(examples, "biome-list.txt"), biomes);
IO.writeAll(new File(examples, "environment-list.txt"), envs); IO.writeAll(new File(examples, "environment-list.txt"), envs);
IrisGenerator gen = new IrisGenerator();
IrisNoiseGenerator n = new IrisNoiseGenerator();
n.setSeed(1000);
IrisNoiseGenerator nf = new IrisNoiseGenerator();
nf.setIrisBased(false);
nf.setOctaves(3);
nf.setOpacity(16);
nf.setZoom(24);
nf.setSeed(44);
n.getFracture().add(nf);
IrisNoiseGenerator nf2 = new IrisNoiseGenerator();
nf2.setIrisBased(false);
nf2.setOctaves(8);
nf2.setOpacity(24);
nf2.setZoom(64);
nf2.setSeed(55);
n.getFracture().add(nf2);
gen.getComposite().add(n);
IrisDimension dim = new IrisDimension(); IrisDimension dim = new IrisDimension();
IrisRegion region = new IrisRegion(); IrisRegion region = new IrisRegion();
@ -86,7 +109,6 @@ public class IrisDataManager
o.getPlace().add("schematic2"); o.getPlace().add("schematic2");
IrisBiome biome = new IrisBiome(); IrisBiome biome = new IrisBiome();
biome.getAuxiliaryGenerators().add(new IrisNoiseLayer());
biome.getChildren().add("another_biome"); biome.getChildren().add("another_biome");
biome.getDecorators().add(new IrisBiomeDecorator()); biome.getDecorators().add(new IrisBiomeDecorator());
biome.getObjects().add(o); biome.getObjects().add(o);
@ -94,6 +116,7 @@ public class IrisDataManager
IO.writeAll(new File(examples, "example-pack/biomes/example-biome.json"), new JSONObject(new Gson().toJson(biome)).toString(4)); IO.writeAll(new File(examples, "example-pack/biomes/example-biome.json"), new JSONObject(new Gson().toJson(biome)).toString(4));
IO.writeAll(new File(examples, "example-pack/regions/example-region.json"), new JSONObject(new Gson().toJson(region)).toString(4)); IO.writeAll(new File(examples, "example-pack/regions/example-region.json"), new JSONObject(new Gson().toJson(region)).toString(4));
IO.writeAll(new File(examples, "example-pack/dimensions/example-dimension.json"), new JSONObject(new Gson().toJson(dim)).toString(4)); IO.writeAll(new File(examples, "example-pack/dimensions/example-dimension.json"), new JSONObject(new Gson().toJson(dim)).toString(4));
IO.writeAll(new File(examples, "example-pack/generators/example-generator.json"), new JSONObject(new Gson().toJson(gen)).toString(4));
} }
catch(Throwable e) catch(Throwable e)

View File

@ -19,7 +19,7 @@ public class IrisHotloadManager
latch = new ChronoLatch(3000); latch = new ChronoLatch(3000);
} }
public void check() public void check(IrisContext ch)
{ {
if(!latch.flip()) if(!latch.flip())
{ {
@ -46,6 +46,7 @@ public class IrisHotloadManager
watchers.clear(); watchers.clear();
Iris.success("Hotloading Iris (" + c + " File" + (c == 1 ? "" : "s") + " changed)"); Iris.success("Hotloading Iris (" + c + " File" + (c == 1 ? "" : "s") + " changed)");
Iris.data.hotloaded(); Iris.data.hotloaded();
ch.onHotloaded();
} }
}); });
} }

View File

@ -0,0 +1,9 @@
package ninja.bytecode.iris;
import lombok.Data;
@Data
public class IrisSettings
{
private int threads = 16;
}

View File

@ -1,32 +1,147 @@
package ninja.bytecode.iris.generator; package ninja.bytecode.iris.generator;
import java.util.function.Function; import java.util.concurrent.locks.ReentrantLock;
import org.bukkit.World; import org.bukkit.World;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.layer.GenLayerBiome; import ninja.bytecode.iris.layer.GenLayerBiome;
import ninja.bytecode.iris.object.IrisBiome; import ninja.bytecode.iris.object.IrisBiome;
import ninja.bytecode.iris.object.IrisBiomeGeneratorLink;
import ninja.bytecode.iris.object.IrisGenerator;
import ninja.bytecode.iris.object.IrisRegion; import ninja.bytecode.iris.object.IrisRegion;
import ninja.bytecode.iris.util.BiomeResult; import ninja.bytecode.iris.util.BiomeResult;
import ninja.bytecode.iris.util.CNG;
import ninja.bytecode.iris.util.ChunkPosition;
import ninja.bytecode.iris.util.IrisInterpolation; import ninja.bytecode.iris.util.IrisInterpolation;
import ninja.bytecode.iris.util.RNG; import ninja.bytecode.iris.util.RNG;
import ninja.bytecode.shuriken.collections.KList;
import ninja.bytecode.shuriken.collections.KMap;
import ninja.bytecode.shuriken.math.M;
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
public abstract class BiomeChunkGenerator extends DimensionChunkGenerator public abstract class BiomeChunkGenerator extends DimensionChunkGenerator
{ {
protected ReentrantLock regLock;
protected KMap<String, IrisGenerator> generators;
protected GenLayerBiome glBiome; protected GenLayerBiome glBiome;
protected CNG masterFracture;
protected KMap<ChunkPosition, BiomeResult> biomeHitCache;
public BiomeChunkGenerator(String dimensionName) public BiomeChunkGenerator(String dimensionName)
{ {
super(dimensionName); super(dimensionName);
generators = new KMap<>();
regLock = new ReentrantLock();
biomeHitCache = new KMap<>();
} }
public void onInit(World world, RNG rng) public void onInit(World world, RNG rng)
{ {
loadGenerators();
glBiome = new GenLayerBiome(this, masterRandom.nextParallelRNG(1)); glBiome = new GenLayerBiome(this, masterRandom.nextParallelRNG(1));
masterFracture = CNG.signature(rng.nextParallelRNG(13)).scale(0.12);
}
public void onHotloaded()
{
biomeHitCache = new KMap<>();
generators.clear();
loadGenerators();
}
public void registerGenerator(IrisGenerator g)
{
regLock.lock();
if(g.getLoadKey() == null || generators.containsKey(g.getLoadKey()))
{
regLock.unlock();
return;
}
regLock.unlock();
generators.put(g.getLoadKey(), g);
}
protected double getBiomeHeight(double rx, double rz)
{
double h = 0;
for(IrisGenerator i : generators.values())
{
h += interpolateGenerator(rx, rz, i);
}
return h;
}
protected double interpolateGenerator(double rx, double rz, IrisGenerator gen)
{
double hi = IrisInterpolation.getNoise(gen.getInterpolationFunction(), (int) Math.round(rx), (int) Math.round(rz), gen.getInterpolationScale(), (xx, zz) ->
{
IrisBiome b = sampleBiome((int) xx, (int) zz).getBiome();
for(IrisBiomeGeneratorLink i : b.getGenerators())
{
if(i.getGenerator().equals(gen.getLoadKey()))
{
return i.getMin();
}
}
return getDimension().getFluidHeight();
});
double lo = IrisInterpolation.getNoise(gen.getInterpolationFunction(), (int) Math.round(rx), (int) Math.round(rz), gen.getInterpolationScale(), (xx, zz) ->
{
IrisBiome b = sampleBiome((int) xx, (int) zz).getBiome();
for(IrisBiomeGeneratorLink i : b.getGenerators())
{
if(i.getGenerator().equals(gen.getLoadKey()))
{
return i.getMax();
}
}
return getDimension().getFluidHeight();
});
return M.lerp(lo, hi, gen.getHeight(rx, rz, world.getSeed() + 239945));
}
protected void loadGenerators()
{
KList<String> touch = new KList<>();
KList<String> loadQueue = new KList<>();
for(String i : getDimension().getRegions())
{
IrisRegion r = Iris.data.getRegionLoader().load(i);
if(r != null)
{
loadQueue.addAll(r.getLandBiomes());
loadQueue.addAll(r.getSeaBiomes());
loadQueue.addAll(r.getShoreBiomes());
}
}
while(!loadQueue.isEmpty())
{
String next = loadQueue.pop();
if(!touch.contains(next))
{
touch.add(next);
IrisBiome biome = Iris.data.getBiomeLoader().load(next);
biome.getGenerators().forEach((i) -> registerGenerator(i.getCachedGenerator()));
loadQueue.addAll(biome.getChildren());
}
}
} }
public IrisRegion sampleRegion(int x, int z) public IrisRegion sampleRegion(int x, int z)
@ -38,38 +153,19 @@ public abstract class BiomeChunkGenerator extends DimensionChunkGenerator
public BiomeResult sampleBiome(int x, int z) public BiomeResult sampleBiome(int x, int z)
{ {
ChunkPosition pos = new ChunkPosition(x, z);
if(biomeHitCache.containsKey(pos))
{
return biomeHitCache.get(pos);
}
double wx = getModifiedX(x, z); double wx = getModifiedX(x, z);
double wz = 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); BiomeResult res = glBiome.generateRegionData(wx, wz, region);
} biomeHitCache.put(pos, res);
protected double interpolateAuxiliaryHeight(double rx, double rz) return res;
{
return IrisInterpolation.getNoise(getDimension().getInterpolationAuxiliaryFunction(), (int) Math.round(rx), (int) Math.round(rz), getDimension().getInterpolationAuxiliaryScale(), (xx, zz) ->
{
double xv = xx / getDimension().getTerrainZoom();
double zv = zz / getDimension().getTerrainZoom();
BiomeResult neighborResult = glBiome.generateData(xv, zv);
return neighborResult.getBiome().getAuxiliaryHeight(xv, zv, getWorld().getSeed() * 3923);
});
}
protected double interpolateHeight(double rx, double rz, Function<IrisBiome, Double> property)
{
return IrisInterpolation.getNoise(getDimension().getInterpolationFunction(), (int) Math.round(rx), (int) Math.round(rz), getDimension().getInterpolationScale(), (xx, zz) ->
{
BiomeResult neighborResult = glBiome.generateData(xx / getDimension().getTerrainZoom(), zz / getDimension().getTerrainZoom());
return property.apply(neighborResult.getBiome());
});
}
protected double interpolateSurface(double rx, double rz, Function<IrisBiome, Double> property)
{
return IrisInterpolation.getNoise(getDimension().getInterpolationSurfaceFunction(), (int) Math.round(rx), (int) Math.round(rz), getDimension().getInterpolationSurfaceScale(), (xx, zz) ->
{
BiomeResult neighborResult = glBiome.generateData(xx / getDimension().getTerrainZoom(), zz / getDimension().getTerrainZoom());
return property.apply(neighborResult.getBiome());
});
} }
} }

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);
@ -231,7 +231,7 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
this.world = world; this.world = world;
} }
Iris.hotloader.check(); Iris.hotloader.check((IrisContext) this);
if(this instanceof IrisContext) if(this instanceof IrisContext)
{ {
@ -260,6 +260,11 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
return generateChunkDataFailure(world, no, x, z, biomeGrid); return generateChunkDataFailure(world, no, x, z, biomeGrid);
} }
public void onHotloaded()
{
}
protected void fail(Throwable e) protected void fail(Throwable e)
{ {

View File

@ -31,12 +31,18 @@ public abstract class DimensionChunkGenerator extends ContextualChunkGenerator
public double getModifiedX(int rx, int rz) public double getModifiedX(int rx, int rz)
{ {
return (getDimension().cosRotate() * rx) + (-getDimension().sinRotate() * rz) + getDimension().getCoordFracture(masterRandom, 39392).fitDoubleD(-getDimension().getCoordFractureDistance() / 2, getDimension().getCoordFractureDistance() / 2, rx, rz); return (getDimension().cosRotate() * rx) +
(-getDimension().sinRotate() * rz) +
getDimension().getCoordFracture(masterRandom, 39392).fitDoubleD(-getDimension().getCoordFractureDistance() / 2, getDimension().getCoordFractureDistance() / 2, rx, rz);
} }
public double getModifiedZ(int rx, int rz) public double getModifiedZ(int rx, int rz)
{ {
return (getDimension().sinRotate() * rx) + (getDimension().cosRotate() * rz) + getDimension().getCoordFracture(masterRandom, 39392).fitDoubleD(-getDimension().getCoordFractureDistance() / 2, getDimension().getCoordFractureDistance() / 2, rx, rz); return (getDimension().sinRotate() * rx) +
(getDimension().cosRotate() * rz) +
getDimension().getCoordFracture(masterRandom, 39392).fitDoubleD(-getDimension().getCoordFractureDistance() / 2, getDimension().getCoordFractureDistance() / 2, rx, rz);
} }
public double getZoomed(double modified) public double getZoomed(double modified)

View File

@ -12,9 +12,9 @@ import ninja.bytecode.iris.util.BiomeResult;
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
public class IrisGenerator extends ParallaxChunkGenerator implements IrisContext public class IrisChunkGenerator extends ParallaxChunkGenerator implements IrisContext
{ {
public IrisGenerator(String dimensionName, int threads) public IrisChunkGenerator(String dimensionName, int threads)
{ {
super(dimensionName, threads); super(dimensionName, threads);
} }

View File

@ -120,6 +120,8 @@ 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)
{ {
biomeHitCache.clear();
if(getDimension().isPlaceObjects()) if(getDimension().isPlaceObjects())
{ {
onGenerateParallax(random, x, z); onGenerateParallax(random, x, z);

View File

@ -11,7 +11,6 @@ import ninja.bytecode.iris.object.IrisRegion;
import ninja.bytecode.iris.object.atomics.AtomicSliver; import ninja.bytecode.iris.object.atomics.AtomicSliver;
import ninja.bytecode.iris.util.BiomeMap; import ninja.bytecode.iris.util.BiomeMap;
import ninja.bytecode.iris.util.BiomeResult; import ninja.bytecode.iris.util.BiomeResult;
import ninja.bytecode.iris.util.CNG;
import ninja.bytecode.iris.util.RNG; import ninja.bytecode.iris.util.RNG;
import ninja.bytecode.shuriken.collections.KList; import ninja.bytecode.shuriken.collections.KList;
@ -22,7 +21,6 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
protected static final BlockData AIR = Material.AIR.createBlockData(); protected static final BlockData AIR = Material.AIR.createBlockData();
protected static final BlockData STONE = Material.STONE.createBlockData(); protected static final BlockData STONE = Material.STONE.createBlockData();
protected static final BlockData WATER = Material.WATER.createBlockData(); protected static final BlockData WATER = Material.WATER.createBlockData();
protected CNG terrainNoise;
public TerrainChunkGenerator(String dimensionName, int threads) public TerrainChunkGenerator(String dimensionName, int threads)
{ {
@ -32,7 +30,6 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
public void onInit(World world, RNG rng) public void onInit(World world, RNG rng)
{ {
super.onInit(world, rng); super.onInit(world, rng);
terrainNoise = CNG.signature(masterRandom.nextParallelRNG(2));
} }
@Override @Override
@ -77,13 +74,10 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
protected double getNoiseHeight(int rx, int rz) protected double getNoiseHeight(int rx, int rz)
{ {
double ox = getModifiedX(rx, rz); double wx = getZoomed(rx);
double oz = getModifiedZ(rx, rz); double wz = getZoomed(rz);
double wx = getZoomed(ox);
double wz = getZoomed(oz); return getBiomeHeight(wx, wz);
double lo = interpolateHeight(ox, oz, (b) -> b.getLowHeight());
double hi = interpolateSurface(ox, oz, (b) -> b.getHighHeight());
return lo + (terrainNoise.fitDoubleD(0, hi - lo, wx, wz)) + interpolateAuxiliaryHeight(rx, rz);
} }
public BiomeResult sampleTrueBiome(int x, int z) public BiomeResult sampleTrueBiome(int x, int z)

View File

@ -7,6 +7,7 @@ import org.bukkit.block.data.BlockData;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import ninja.bytecode.iris.generator.BiomeChunkGenerator;
import ninja.bytecode.iris.util.CNG; import ninja.bytecode.iris.util.CNG;
import ninja.bytecode.iris.util.CellGenerator; import ninja.bytecode.iris.util.CellGenerator;
import ninja.bytecode.iris.util.RNG; import ninja.bytecode.iris.util.RNG;
@ -15,18 +16,16 @@ import ninja.bytecode.shuriken.logging.L;
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
public class IrisBiome extends IrisRegisteredObject public class IrisBiome extends IrisRegistrant
{ {
private String name = "A Biome"; private String name = "A Biome";
private Biome derivative = Biome.THE_VOID; private Biome derivative = Biome.THE_VOID;
private double highHeight = 3;
private double lowHeight = 1;
private double childShrinkFactor = 1.5; private double childShrinkFactor = 1.5;
private KList<String> children = new KList<>(); private KList<String> children = new KList<>();
private KList<IrisBiomePaletteLayer> layers = new KList<IrisBiomePaletteLayer>().qadd(new IrisBiomePaletteLayer()); private KList<IrisBiomePaletteLayer> layers = new KList<IrisBiomePaletteLayer>().qadd(new IrisBiomePaletteLayer());
private KList<IrisBiomeDecorator> decorators = new KList<IrisBiomeDecorator>(); private KList<IrisBiomeDecorator> decorators = new KList<IrisBiomeDecorator>();
private KList<IrisObjectPlacement> objects = new KList<IrisObjectPlacement>(); private KList<IrisObjectPlacement> objects = new KList<IrisObjectPlacement>();
private KList<IrisNoiseLayer> auxiliaryGenerators = new KList<IrisNoiseLayer>(); private KList<IrisBiomeGeneratorLink> generators = new KList<IrisBiomeGeneratorLink>().qadd(new IrisBiomeGeneratorLink());
private transient ReentrantLock lock = new ReentrantLock(); private transient ReentrantLock lock = new ReentrantLock();
private transient CellGenerator childrenCell; private transient CellGenerator childrenCell;
private transient InferredType inferredType; private transient InferredType inferredType;
@ -38,22 +37,16 @@ public class IrisBiome extends IrisRegisteredObject
} }
public double getAuxiliaryHeight(double rx, double rz, long superSeed) public double getHeight(double x, double z, long seed)
{ {
if(auxiliaryGenerators.isEmpty()) double height = 0;
for(IrisBiomeGeneratorLink i : generators)
{ {
return 0; height += i.getHeight(x, z, seed);
} }
int hc = hashCode(); return Math.max(0, Math.min(height, 255));
double h = 0;
for(IrisNoiseLayer i : auxiliaryGenerators)
{
h += i.getNoise(superSeed + hc, rx, rz);
}
return h;
} }
public CellGenerator getChildrenGenerator(RNG random, int sig, double scale) public CellGenerator getChildrenGenerator(RNG random, int sig, double scale)

View File

@ -0,0 +1,47 @@
package ninja.bytecode.iris.object;
import lombok.Data;
import net.md_5.bungee.api.ChatColor;
import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.generator.BiomeChunkGenerator;
import ninja.bytecode.iris.util.IrisInterpolation;
@Data
public class IrisBiomeGeneratorLink
{
private String generator = "default";
private int min = 0;
private int max = 0;
private transient IrisGenerator gen;
public IrisBiomeGeneratorLink()
{
}
public IrisGenerator getCachedGenerator()
{
if(gen == null)
{
gen = Iris.data.getGeneratorLoader().load(getGenerator());
if(gen == null)
{
gen = new IrisGenerator();
}
Iris.success("Registered Generator " + ChatColor.WHITE + gen.getLoadKey());
}
return gen;
}
public double getHeight(double x, double z, long seed)
{
double g = getCachedGenerator().getHeight(x, z, seed);
g = g < 0 ? 0 : g;
g = g > 1 ? 1 : g;
return IrisInterpolation.lerp(min, max, g);
}
}

View File

@ -10,15 +10,13 @@ import ninja.bytecode.shuriken.collections.KList;
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
public class IrisDimension extends IrisRegisteredObject public class IrisDimension extends IrisRegistrant
{ {
private String name = "A Dimension"; private String name = "A Dimension";
private InterpolationMethod interpolationFunction = InterpolationMethod.BICUBIC; private InterpolationMethod interpolationFunction = InterpolationMethod.BICUBIC;
private double interpolationScale = 63; private double interpolationScale = 63;
private InterpolationMethod interpolationSurfaceFunction = InterpolationMethod.BICUBIC; private InterpolationMethod interpolationSurfaceFunction = InterpolationMethod.BICUBIC;
private double interpolationSurfaceScale = 4; private double interpolationSurfaceScale = 4;
private InterpolationMethod interpolationAuxiliaryFunction = InterpolationMethod.BICUBIC;
private double interpolationAuxiliaryScale = 7;
private Environment environment = Environment.NORMAL; private Environment environment = Environment.NORMAL;
private KList<String> regions = new KList<>(); private KList<String> regions = new KList<>();
private int fluidHeight = 127; private int fluidHeight = 127;

View File

@ -0,0 +1,45 @@
package ninja.bytecode.iris.object;
import lombok.Data;
import lombok.EqualsAndHashCode;
import ninja.bytecode.shuriken.collections.KList;
@Data
@EqualsAndHashCode(callSuper = false)
public class IrisGenerator extends IrisRegistrant
{
private double zoom = 1;
private double opacity = 1;
private double offsetX = 0;
private double offsetZ = 0;
private long seed = 1;
private InterpolationMethod interpolationFunction = InterpolationMethod.BICUBIC;
private double interpolationScale = 7;
private KList<IrisNoiseGenerator> composite = new KList<IrisNoiseGenerator>();
public double getMax()
{
return opacity;
}
public double getHeight(double rx, double rz, long superSeed)
{
if(composite.isEmpty())
{
return 0;
}
int hc = hashCode();
double h = 0;
double tp = 0;
for(IrisNoiseGenerator i : composite)
{
tp += i.getOpacity();
h += i.getNoise(seed + superSeed + hc, (rx + offsetX) / zoom, (rz + offsetZ) / zoom);
}
return (h / tp) * opacity;
}
}

View File

@ -0,0 +1,89 @@
package ninja.bytecode.iris.object;
import java.util.concurrent.locks.ReentrantLock;
import lombok.Data;
import ninja.bytecode.iris.util.CNG;
import ninja.bytecode.iris.util.IrisInterpolation;
import ninja.bytecode.iris.util.RNG;
import ninja.bytecode.shuriken.collections.KList;
@Data
public class IrisNoiseGenerator
{
private double zoom = 1;
private double opacity = 1;
private double offsetX = 0;
private double offsetY = 0;
private double offsetZ = 0;
private long seed = 0;
private boolean parametric = false;
private boolean bezier = false;
private boolean sinCentered = false;
private double exponent = 1;
private boolean enabled = true;
private boolean irisBased = true;
private int octaves = 1;
private KList<IrisNoiseGenerator> fracture = new KList<>();
private transient ReentrantLock lock;
private transient CNG generator;
public IrisNoiseGenerator()
{
lock = new ReentrantLock();
}
public IrisNoiseGenerator(boolean enabled)
{
this();
this.enabled = enabled;
}
protected CNG getGenerator(long superSeed)
{
if(generator == null)
{
lock.lock();
generator = irisBased ? CNG.signature(new RNG(superSeed + 33955677 - seed)) : new CNG(new RNG(superSeed + 33955677 - seed), 1D, octaves);
lock.unlock();
}
return generator;
}
public double getMax()
{
return getOffsetY() + opacity;
}
public double getNoise(long superSeed, double xv, double zv)
{
if(!enabled)
{
return offsetY;
}
double x = xv;
double z = zv;
int g = 33;
for(IrisNoiseGenerator i : fracture)
{
if(i.isEnabled())
{
x += i.getNoise(superSeed + seed + g, xv, zv);
z -= i.getNoise(superSeed + seed + g, zv, xv);
}
g += 819;
}
double n = getGenerator(superSeed).fitDoubleD(0, opacity, (x / zoom) + offsetX, (z / zoom) + offsetZ);
n = (exponent != 1 ? Math.pow(n, exponent) : n) + offsetY;
n = parametric ? IrisInterpolation.parametric(n, 1) : n;
n = bezier ? IrisInterpolation.bezier(n) : n;
n = sinCentered ? IrisInterpolation.sinCenter(n) : n;
return n;
}
}

View File

@ -1,41 +0,0 @@
package ninja.bytecode.iris.object;
import java.util.concurrent.locks.ReentrantLock;
import ninja.bytecode.iris.util.CNG;
import ninja.bytecode.iris.util.RNG;
public class IrisNoiseLayer
{
private double zoom = 1;
private double offsetX = 0;
private double offsetZ = 0;
private long seed = 0;
private double min = 0;
private double max = 10;
private transient ReentrantLock lock;
private transient CNG generator;
public IrisNoiseLayer()
{
lock = new ReentrantLock();
}
protected CNG getGenerator(long superSeed)
{
if(generator == null)
{
lock.lock();
generator = CNG.signature(new RNG(superSeed + 33955677 - seed));
lock.unlock();
}
return generator;
}
public double getNoise(long superSeed, double x, double z)
{
return getGenerator(superSeed).fitDoubleD(min, max, (x / zoom) + offsetX, (z / zoom) + offsetZ);
}
}

View File

@ -22,7 +22,7 @@ import ninja.bytecode.shuriken.collections.KMap;
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
public class IrisObject extends IrisRegisteredObject public class IrisObject extends IrisRegistrant
{ {
private KMap<BlockVector, BlockData> blocks; private KMap<BlockVector, BlockData> blocks;
private int w; private int w;

View File

@ -10,7 +10,7 @@ import ninja.bytecode.shuriken.collections.KList;
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
public class IrisRegion extends IrisRegisteredObject public class IrisRegion extends IrisRegistrant
{ {
private String name = "A Region"; private String name = "A Region";
private double shoreRatio = 0.13; private double shoreRatio = 0.13;

View File

@ -3,7 +3,7 @@ package ninja.bytecode.iris.object;
import lombok.Data; import lombok.Data;
@Data @Data
public class IrisRegisteredObject public class IrisRegistrant
{ {
private String loadKey; private String loadKey;
} }

View File

@ -1,42 +0,0 @@
package ninja.bytecode.iris.objectproperty;
import java.lang.reflect.Field;
import lombok.Data;
@Data
public class ObjectProperty<T>
{
private Class<? extends T> type;
private String fieldName;
private String name;
private String description;
private Object instance;
private Field field;
public ObjectProperty(Class<? extends T> type, String fieldName) throws Throwable
{
this.type = type;
this.fieldName = fieldName;
field = type.getDeclaredField(name);
field.setAccessible(true);
if(field.isAnnotationPresent(Property.class))
{
Property p = field.getAnnotation(Property.class);
name = p.name();
description = p.description();
}
}
public void set(T value) throws Throwable
{
field.set(instance, value);
}
@SuppressWarnings("unchecked")
public T get() throws Throwable
{
return (T) field.get(instance);
}
}

View File

@ -1,16 +0,0 @@
package ninja.bytecode.iris.objectproperty;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target(TYPE)
public @interface PropertyObject
{
String name();
String description();
}

View File

@ -0,0 +1,9 @@
package ninja.bytecode.iris.util;
import ninja.bytecode.iris.object.IrisBiome;
import ninja.bytecode.shuriken.collections.KMap;
public class BiomeDominance extends KMap<IrisBiome, Double>
{
private static final long serialVersionUID = 9055245062942178392L;
}

View File

@ -14,4 +14,9 @@ public class BiomeResult
this.biome = biome; this.biome = biome;
this.distance = distance; this.distance = distance;
} }
public boolean is(BiomeResult r)
{
return biome.getName().equals(r.biome.getName());
}
} }

View File

@ -91,7 +91,7 @@ public class ObjectResourceLoader extends ResourceLoader<IrisObject>
} }
lock.lock(); lock.lock();
for(File i : getFolders()) for(File i : getFolders(name))
{ {
for(File j : i.listFiles()) for(File j : i.listFiles())
{ {

View File

@ -6,15 +6,16 @@ import java.util.concurrent.locks.ReentrantLock;
import com.google.gson.Gson; import com.google.gson.Gson;
import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.object.IrisRegisteredObject; import ninja.bytecode.iris.object.IrisRegistrant;
import ninja.bytecode.shuriken.collections.KList; import ninja.bytecode.shuriken.collections.KList;
import ninja.bytecode.shuriken.collections.KMap; import ninja.bytecode.shuriken.collections.KMap;
public class ResourceLoader<T extends IrisRegisteredObject> public class ResourceLoader<T extends IrisRegistrant>
{ {
protected File root; protected File root;
protected String folderName; protected String folderName;
protected String resourceTypeName; protected String resourceTypeName;
protected KMap<String, File> folderMapCache;
protected KMap<String, T> loadCache; protected KMap<String, T> loadCache;
protected KList<File> folderCache; protected KList<File> folderCache;
protected Class<? extends T> objectClass; protected Class<? extends T> objectClass;
@ -23,6 +24,7 @@ public class ResourceLoader<T extends IrisRegisteredObject>
public ResourceLoader(File root, String folderName, String resourceTypeName, Class<? extends T> objectClass) public ResourceLoader(File root, String folderName, String resourceTypeName, Class<? extends T> objectClass)
{ {
lock = new ReentrantLock(); lock = new ReentrantLock();
folderMapCache = new KMap<>();
this.objectClass = objectClass; this.objectClass = objectClass;
this.resourceTypeName = resourceTypeName; this.resourceTypeName = resourceTypeName;
this.root = root; this.root = root;
@ -62,7 +64,7 @@ public class ResourceLoader<T extends IrisRegisteredObject>
} }
lock.lock(); lock.lock();
for(File i : getFolders()) for(File i : getFolders(name))
{ {
for(File j : i.listFiles()) for(File j : i.listFiles())
{ {
@ -111,9 +113,55 @@ public class ResourceLoader<T extends IrisRegisteredObject>
return folderCache; return folderCache;
} }
public KList<File> getFolders(String rc)
{
KList<File> folders = getFolders().copy();
if(rc.contains(":"))
{
for(File i : folders.copy())
{
if(!rc.startsWith(i.getName() + ":"))
{
folders.remove(i);
}
}
}
return folders;
}
public void clearCache() public void clearCache()
{ {
loadCache.clear(); loadCache.clear();
folderCache = null; folderCache = null;
} }
public File fileFor(T b)
{
for(File i : getFolders())
{
for(File j : i.listFiles())
{
if(j.isFile() && j.getName().endsWith(".json") && j.getName().split("\\Q.\\E")[0].equals(b.getLoadKey()))
{
return j;
}
}
File file = new File(i, b.getLoadKey() + ".json");
if(file.exists())
{
return file;
}
}
return null;
}
public boolean isLoaded(String next)
{
return loadCache.containsKey(next);
}
} }