Fix parallax

This commit is contained in:
Daniel Mills 2020-01-21 18:43:00 -05:00
parent 75da6d4df1
commit ca21758889
9 changed files with 67 additions and 468 deletions

View File

@ -22,6 +22,7 @@ import ninja.bytecode.iris.generator.genobject.PlacedObject;
import ninja.bytecode.iris.pack.CompiledDimension;
import ninja.bytecode.iris.pack.IrisBiome;
import ninja.bytecode.iris.util.BiomeLayer;
import ninja.bytecode.iris.util.ObjectMode;
import ninja.bytecode.shuriken.collections.GList;
import ninja.bytecode.shuriken.collections.GMap;
import ninja.bytecode.shuriken.execution.ChronoLatch;
@ -255,7 +256,6 @@ public class CommandIris implements CommandExecutor
{
Consumer<String> m = (msg) ->
{
J.s(() ->
{
String mm = msg;
@ -280,7 +280,6 @@ public class CommandIris implements CommandExecutor
{
J.s(() ->
{
World i = Bukkit.getWorld(fi);
CompiledDimension dim = c.getDimension(f.get(fi));
@ -311,6 +310,7 @@ public class CommandIris implements CommandExecutor
ChronoLatch cl = new ChronoLatch(3000);
Player p = (Player) sender;
World ww = ((Player) sender).getWorld();
msg(p, "Regenerating View Distance");
WorldReactor r = new WorldReactor(ww);

View File

@ -12,7 +12,7 @@ public class Settings
public static class PerformanceSettings
{
public PerformanceMode performanceMode = PerformanceMode.HALF_CPU;
public ObjectMode objectMode = ObjectMode.NONE;
public ObjectMode objectMode = ObjectMode.PARALLAX;
public boolean fastMode = false;
public int threadPriority = Thread.MAX_PRIORITY;
public int threadCount = 4;

View File

@ -18,9 +18,6 @@ import ninja.bytecode.iris.generator.atomics.AtomicChunkData;
import ninja.bytecode.iris.generator.genobject.GenObjectDecorator;
import ninja.bytecode.iris.generator.genobject.PlacedObject;
import ninja.bytecode.iris.generator.layer.GenLayerBiome;
import ninja.bytecode.iris.generator.layer.GenLayerCarving;
import ninja.bytecode.iris.generator.layer.GenLayerCaverns;
import ninja.bytecode.iris.generator.layer.GenLayerCaves;
import ninja.bytecode.iris.generator.layer.GenLayerCliffs;
import ninja.bytecode.iris.generator.layer.GenLayerLayeredNoise;
import ninja.bytecode.iris.generator.layer.GenLayerSnow;
@ -34,6 +31,7 @@ import ninja.bytecode.iris.util.InterpolationMode;
import ninja.bytecode.iris.util.IrisInterpolation;
import ninja.bytecode.iris.util.MB;
import ninja.bytecode.iris.util.ObjectMode;
import ninja.bytecode.iris.util.PolygonGenerator;
import ninja.bytecode.iris.util.SChunkVector;
import ninja.bytecode.shuriken.bench.PrecisionStopwatch;
import ninja.bytecode.shuriken.collections.GList;
@ -72,9 +70,6 @@ public class IrisGenerator extends ParallaxWorldGenerator
private GenObjectDecorator god;
private GenLayerLayeredNoise glLNoise;
private GenLayerBiome glBiome;
private GenLayerCaves glCaves;
private GenLayerCarving glCarving;
private GenLayerCaverns glCaverns;
private GenLayerSnow glSnow;
private GenLayerCliffs glCliffs;
private RNG rTerrain;
@ -128,9 +123,6 @@ public class IrisGenerator extends ParallaxWorldGenerator
rTerrain = new RNG(world.getSeed());
glLNoise = new GenLayerLayeredNoise(this, world, random, rTerrain.nextParallelRNG(2));
glBiome = new GenLayerBiome(this, world, random, rTerrain.nextParallelRNG(4), dim.getBiomes());
glCaves = new GenLayerCaves(this, world, random, rTerrain.nextParallelRNG(-1));
glCarving = new GenLayerCarving(this, world, random, rTerrain.nextParallelRNG(-2));
glCaverns = new GenLayerCaverns(this, world, random, rTerrain.nextParallelRNG(-3));
glSnow = new GenLayerSnow(this, world, random, rTerrain.nextParallelRNG(5));
glCliffs = new GenLayerCliffs(this, world, random, rTerrain.nextParallelRNG(9));
scatter = new CNG(rTerrain.nextParallelRNG(52), 1, 1).scale(10);
@ -327,9 +319,30 @@ public class IrisGenerator extends ParallaxWorldGenerator
return hits;
}
PolygonGenerator pg = new PolygonGenerator(RNG.r, 2, 0.013, 1, (g) -> g);
@Override
public Biome onGenColumn(int wxxf, int wzxf, int x, int z, ChunkPlan plan, AtomicChunkData data, boolean surfaceOnly)
{
/////////////////////////
if(false)
{
int height = 64;
int girth = 3;
for(int j = 1; j < (girth * 2) + 1; j++)
{
int i = j > girth ? girth - j : j;
if(pg.hasBorder(12, i, wxxf, wzxf))
{
data.setBlock(x, height + j, z, Material.STAINED_GLASS, (byte) 15);
}
}
return Biome.VOID;
}
/////////////////////////
PrecisionStopwatch s = getMetrics().start();
if(disposed)
{
@ -405,20 +418,6 @@ public class IrisGenerator extends ParallaxWorldGenerator
getMetrics().stop("terrain:ms:x256:/chunk:..", s);
if(!surfaceOnly)
{
PrecisionStopwatch c = getMetrics().start();
glCaves.genCaves(wxx, wzx, x, z, height, this, data);
getMetrics().stop("caves:ms:x256:/terrain:..", c);
PrecisionStopwatch v = getMetrics().start();
glCaverns.genCaverns(wxx, wzx, x, z, height, this, biome, data);
getMetrics().stop("caverns:ms:x256:/terrain:..", v);
}
PrecisionStopwatch c = getMetrics().start();
glCarving.genCarves(wxx, wzx, x, z, height, this, biome, data);
getMetrics().stop("carving:ms:x256:/terrain:..", c);
int hw = 0;
int hl = 0;
@ -482,9 +481,6 @@ public class IrisGenerator extends ParallaxWorldGenerator
disposed = true;
dim = null;
glLNoise = null;
glCaves = null;
glCarving = null;
glCaverns = null;
glSnow = null;
glCliffs = null;
god.dispose();

View File

@ -10,7 +10,9 @@ import mortar.api.nms.NMP;
import mortar.api.sched.J;
import mortar.compute.math.M;
import mortar.lang.collection.FinalDouble;
import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.util.ChronoQueue;
import ninja.bytecode.iris.util.ObjectMode;
public class WorldReactor
{
@ -37,6 +39,12 @@ public class WorldReactor
if(world.isChunkLoaded(x, z) || world.loadChunk(x, z, false))
{
if(Iris.settings.performance.objectMode.equals(ObjectMode.PARALLAX) && world.getGenerator() instanceof IrisGenerator)
{
IrisGenerator gg = ((IrisGenerator) world.getGenerator());
gg.getWorldData().deleteChunk(x, z);
}
max.add(1);
q.queue(() ->
{

View File

@ -1,178 +0,0 @@
package ninja.bytecode.iris.generator.layer;
import java.util.Random;
import org.bukkit.Material;
import org.bukkit.World;
import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.generator.IrisGenerator;
import ninja.bytecode.iris.generator.atomics.AtomicChunkData;
import ninja.bytecode.iris.pack.IrisBiome;
import ninja.bytecode.iris.util.GenLayer;
import ninja.bytecode.iris.util.IrisInterpolation;
import ninja.bytecode.iris.util.MB;
import ninja.bytecode.shuriken.math.CNG;
import ninja.bytecode.shuriken.math.M;
import ninja.bytecode.shuriken.math.RNG;
public class GenLayerCarving extends GenLayer
{
private CNG carver;
private CNG fract;
private CNG ruff;
public GenLayerCarving(IrisGenerator iris, World world, Random random, RNG rng)
{
super(iris, world, random, rng);
//@builder
carver = new CNG(rng.nextParallelRNG(116), 1D, 7)
.scale(0.0057)
.amp(0.5)
.freq(1.1);
fract = new CNG(rng.nextParallelRNG(20), 1, 3)
.scale(0.0302);
ruff = new CNG(rng.nextParallelRNG(20), 1, 2)
.scale(0.0702);
//@done
}
public double getHill(double height)
{
double min = Iris.settings.gen.minCarvingHeight;
double max = Iris.settings.gen.maxCarvingHeight;
double mid = IrisInterpolation.lerp(min, max, 0.5);
if(height >= min && height <= mid)
{
return IrisInterpolation.lerpBezier(0, 1, M.lerpInverse(min, mid, height));
}
else if(height >= mid && height <= max)
{
return IrisInterpolation.lerpBezier(1, 0, M.lerpInverse(mid, max, height));
}
return 0;
}
public double carve(double x, double y, double z)
{
double cx = 77D;
double cz = 11D;
double rx = ruff.noise(x, z, y) * cz;
double ry = ruff.noise(z, y, x) * cz;
double rz = ruff.noise(y, x, z) * cz;
double fx = fract.noise(x + rx, z - ry, y + rz) * cx;
double fy = fract.noise(z - ry, y + rx, x - rz) * cx;
double fz = fract.noise(y + rz, x - rx, z + ry) * cx;
return carver.noise(x + fx, y - fy, z + fz);
}
public void genCarves(double wxx, double wzx, int x, int z, int s, IrisGenerator g, IrisBiome biome, AtomicChunkData data)
{
if(!Iris.settings.gen.genCarving)
{
return;
}
if(s < Iris.settings.gen.minCarvingHeight)
{
return;
}
double ch = Iris.settings.gen.carvingChance;
int txy = (int) IrisInterpolation.lerp(Iris.settings.gen.minCarvingHeight, Iris.settings.gen.maxCarvingHeight, 0.5);
if(carve(wxx, txy, wzx) < ch / 2D)
{
return;
}
int hit = 0;
int carved = 0;
for(int i = Math.min(Iris.settings.gen.maxCarvingHeight, s); i > Iris.settings.gen.minCarvingHeight; i--)
{
double hill = getHill(i);
if(hill < 0.065)
{
continue;
}
if(carve(wxx, i, wzx) < IrisInterpolation.lerpBezier(0, ch, hill))
{
carved++;
data.setBlock(x, i, z, Material.AIR);
}
}
if(carved > 4)
{
boolean fail = false;
for(int i = Iris.settings.gen.maxCarvingHeight; i > Iris.settings.gen.minCarvingHeight; i--)
{
Material m = data.getType(x, i, z);
if(!m.equals(Material.AIR))
{
hit++;
if(hit == 1)
{
fail = false;
if(i > 5)
{
for(int j = i; j > i - 5; j--)
{
if(data.getType(x, j, z).equals(Material.AIR))
{
fail = true;
break;
}
}
}
if(!fail)
{
MB mb = biome.getSurface(wxx, wzx, g.getRTerrain());
data.setBlock(x, i, z, mb.material, mb.data);
}
else
{
data.setBlock(x, i, z, Material.AIR);
}
}
else if(hit > 1 && hit < g.scatterInt(x, i, z, 4) + 3)
{
if(!fail)
{
MB mb = biome.getSubSurface(wxx, i, wzx, g.getRTerrain());
data.setBlock(x, i, z, mb.material, mb.data);
}
else
{
data.setBlock(x, i, z, Material.AIR);
}
}
}
else
{
hit = 0;
}
}
}
}
@Override
public double generateLayer(double gnoise, double dx, double dz)
{
return gnoise;
}
}

View File

@ -1,178 +0,0 @@
package ninja.bytecode.iris.generator.layer;
import java.util.Random;
import org.bukkit.Material;
import org.bukkit.World;
import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.generator.IrisGenerator;
import ninja.bytecode.iris.generator.atomics.AtomicChunkData;
import ninja.bytecode.iris.pack.IrisBiome;
import ninja.bytecode.iris.util.GenLayer;
import ninja.bytecode.iris.util.IrisInterpolation;
import ninja.bytecode.iris.util.MB;
import ninja.bytecode.shuriken.math.CNG;
import ninja.bytecode.shuriken.math.M;
import ninja.bytecode.shuriken.math.RNG;
public class GenLayerCaverns extends GenLayer
{
private CNG carver;
private CNG fract;
private CNG ruff;
public GenLayerCaverns(IrisGenerator iris, World world, Random random, RNG rng)
{
super(iris, world, random, rng);
//@builder
carver = new CNG(rng.nextParallelRNG(116), 1D, 7)
.scale(0.0057)
.amp(0.5)
.freq(1.1);
fract = new CNG(rng.nextParallelRNG(20), 1, 3)
.scale(0.0302);
ruff = new CNG(rng.nextParallelRNG(20), 1, 2)
.scale(0.0702);
//@done
}
public double getHill(double height)
{
double min = Iris.settings.gen.minCavernHeight;
double max = Iris.settings.gen.maxCavernHeight;
double mid = IrisInterpolation.lerp(min, max, 0.5);
if(height >= min && height <= mid)
{
return IrisInterpolation.lerpBezier(0, 1, M.lerpInverse(min, mid, height));
}
else if(height >= mid && height <= max)
{
return IrisInterpolation.lerpBezier(1, 0, M.lerpInverse(mid, max, height));
}
return 0;
}
public double cavern(double x, double y, double z)
{
double cx = 77D;
double cz = 11D;
double rx = ruff.noise(x, z, y) * cz;
double ry = ruff.noise(z, y, x) * cz;
double rz = ruff.noise(y, x, z) * cz;
double fx = fract.noise(x + rx, z - ry, y + rz) * cx;
double fy = fract.noise(z - ry, y + rx, x - rz) * cx;
double fz = fract.noise(y + rz, x - rx, z + ry) * cx;
return carver.noise(x + fx, y - fy, z + fz);
}
public void genCaverns(double wxx, double wzx, int x, int z, int s, IrisGenerator g, IrisBiome biome, AtomicChunkData data)
{
if(!Iris.settings.gen.genCaverns || Iris.settings.performance.fastMode)
{
return;
}
if(s < Iris.settings.gen.minCavernHeight)
{
return;
}
double ch = Iris.settings.gen.cavernChance;
int txy = (int) IrisInterpolation.lerp(Iris.settings.gen.minCavernHeight, Iris.settings.gen.maxCavernHeight, 0.5);
if(cavern(wxx, txy, wzx) < ch / 2D)
{
return;
}
int hit = 0;
int carved = 0;
for(int i = Math.min(Iris.settings.gen.maxCavernHeight, s); i > Iris.settings.gen.minCavernHeight; i--)
{
double hill = getHill(i);
if(hill < 0.065)
{
continue;
}
if(cavern(wxx, i, wzx) < IrisInterpolation.lerpBezier(0, ch, hill))
{
carved++;
data.setBlock(x, i, z, Material.AIR);
}
}
if(carved > 4)
{
boolean fail = false;
for(int i = Iris.settings.gen.maxCavernHeight; i > Iris.settings.gen.minCavernHeight; i--)
{
Material m = data.getType(x, i, z);
if(!m.equals(Material.AIR))
{
hit++;
if(hit == 1)
{
fail = false;
if(i > 5)
{
for(int j = i; j > i - 5; j--)
{
if(data.getType(x, j, z).equals(Material.AIR))
{
fail = true;
break;
}
}
}
if(!fail)
{
MB mb = biome.getSurface(wxx, wzx, g.getRTerrain());
data.setBlock(x, i, z, mb.material, mb.data);
}
else
{
data.setBlock(x, i, z, Material.AIR);
}
}
else if(hit > 1 && hit < g.scatterInt(x, i, z, 4) + 3)
{
if(!fail)
{
MB mb = biome.getSubSurface(wxx, i, wzx, g.getRTerrain());
data.setBlock(x, i, z, mb.material, mb.data);
}
else
{
data.setBlock(x, i, z, Material.AIR);
}
}
}
else
{
hit = 0;
}
}
}
}
@Override
public double generateLayer(double gnoise, double dx, double dz)
{
return gnoise;
}
}

View File

@ -1,83 +0,0 @@
package ninja.bytecode.iris.generator.layer;
import java.util.Random;
import org.bukkit.Material;
import org.bukkit.World;
import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.generator.IrisGenerator;
import ninja.bytecode.iris.generator.atomics.AtomicChunkData;
import ninja.bytecode.iris.util.GenLayer;
import ninja.bytecode.iris.util.PolygonGenerator;
import ninja.bytecode.shuriken.math.CNG;
import ninja.bytecode.shuriken.math.RNG;
public class GenLayerCaves extends GenLayer
{
private CNG caveHeight;
private CNG caveGirth;
private CNG caveClamp;
private PolygonGenerator caveVeins;
public GenLayerCaves(IrisGenerator iris, World world, Random random, RNG rng)
{
super(iris, world, random, rng);
caveHeight = new CNG(rng.nextParallelRNG(-100001), 1D, 3).scale(0.00222);
caveGirth = new CNG(rng.nextParallelRNG(-100002), 1D, 3).scale(0.03);
caveClamp = new CNG(rng.nextParallelRNG(-10000), 1D, 3).scale(0.1422);
caveVeins = new PolygonGenerator(rng.nextParallelRNG(-99999), 4, 0.002 * Iris.settings.gen.caveScale, 1, (g) -> g.fractureWith(new CNG(rng.nextParallelRNG(-5555), 1D, 4).scale(0.02), 70));
}
public void genCaves(double wxx, double wzx, int x, int z, int s, IrisGenerator g, AtomicChunkData data)
{
if(!Iris.settings.gen.genCaves || Iris.settings.performance.fastMode)
{
return;
}
for(double itr = 0; itr < 0.1 * Iris.settings.gen.caveDensity; itr += 0.1)
{
double thickness = 0.25 + itr + (0.5 * caveClamp.noise(wxx, wzx));
double size = (3.88D * thickness);
double variance = 3.34D * thickness;
double w = size + (variance * caveGirth.noise(wxx, wzx));
double h = size + (variance * caveGirth.noise(wzx, wxx));
double width = 0;
double height = h;
double elevation = (caveHeight.noise(wxx + (19949D * itr), wzx - (19949D * itr)) * (350)) - 80;
while(width <= w && height > 1D)
{
width += 2;
height -= 2;
if(caveVeins.hasBorder(3, width, wxx - (19949D * itr), wzx + (19949D * itr)))
{
double r = (((caveGirth.noise(wxx, wzx, width)) * variance) + height) / 2D;
for(int i = (int) -r; i < r; i++)
{
if(i + height > s)
{
break;
}
Material t = data.getType(x, (int) (elevation + i) - 55, z);
if(t.equals(Material.BEDROCK) || t.equals(Material.WATER) || t.equals(Material.STATIONARY_WATER))
{
continue;
}
data.setBlock(x, (int) (elevation + i) - 55, z, Material.AIR);
}
}
}
}
}
@Override
public double generateLayer(double gnoise, double dx, double dz)
{
return gnoise;
}
}

View File

@ -164,6 +164,7 @@ public abstract class ParallaxWorldGenerator extends ParallelChunkGenerator impl
}
}
g.execute();
}
((IrisGenerator) this).getMetrics().put("parallax:ms:/chunk", ps.getMillis());

View File

@ -85,6 +85,39 @@ public class PolygonGenerator
return false;
}
public boolean hasBorder3D(int checks, double distance, double... dims)
{
int current = getIndex(dims);
double ajump = 360D / (double) checks;
int hit = -1;
int hit2 = -1;
if(dims.length == 3)
{
for(int i = 0; i < checks; i++)
{
double dx = M.sin((float) Math.toRadians(ajump * i));
double dz = M.cos((float) Math.toRadians(ajump * i));
double dy = Math.tan(Math.toRadians(ajump * i));
int d = getIndex((dx * distance) + dims[0], (dz * distance) + dims[1], (dy * distance) + dims[2]);
if(current != d)
{
if(hit >= 0 && hit != current && hit != d)
{
return true;
}
if(hit < 0)
{
hit = d;
}
}
}
}
return false;
}
/**
* Returns 0.0 to 1.0 where 0.0 is directly on the border of another region and
* 1.0 is perfectly in the center of a region