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

View File

@ -12,7 +12,7 @@ public class Settings
public static class PerformanceSettings public static class PerformanceSettings
{ {
public PerformanceMode performanceMode = PerformanceMode.HALF_CPU; public PerformanceMode performanceMode = PerformanceMode.HALF_CPU;
public ObjectMode objectMode = ObjectMode.NONE; public ObjectMode objectMode = ObjectMode.PARALLAX;
public boolean fastMode = false; public boolean fastMode = false;
public int threadPriority = Thread.MAX_PRIORITY; public int threadPriority = Thread.MAX_PRIORITY;
public int threadCount = 4; 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.GenObjectDecorator;
import ninja.bytecode.iris.generator.genobject.PlacedObject; import ninja.bytecode.iris.generator.genobject.PlacedObject;
import ninja.bytecode.iris.generator.layer.GenLayerBiome; 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.GenLayerCliffs;
import ninja.bytecode.iris.generator.layer.GenLayerLayeredNoise; import ninja.bytecode.iris.generator.layer.GenLayerLayeredNoise;
import ninja.bytecode.iris.generator.layer.GenLayerSnow; 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.IrisInterpolation;
import ninja.bytecode.iris.util.MB; import ninja.bytecode.iris.util.MB;
import ninja.bytecode.iris.util.ObjectMode; import ninja.bytecode.iris.util.ObjectMode;
import ninja.bytecode.iris.util.PolygonGenerator;
import ninja.bytecode.iris.util.SChunkVector; import ninja.bytecode.iris.util.SChunkVector;
import ninja.bytecode.shuriken.bench.PrecisionStopwatch; import ninja.bytecode.shuriken.bench.PrecisionStopwatch;
import ninja.bytecode.shuriken.collections.GList; import ninja.bytecode.shuriken.collections.GList;
@ -72,9 +70,6 @@ public class IrisGenerator extends ParallaxWorldGenerator
private GenObjectDecorator god; private GenObjectDecorator god;
private GenLayerLayeredNoise glLNoise; private GenLayerLayeredNoise glLNoise;
private GenLayerBiome glBiome; private GenLayerBiome glBiome;
private GenLayerCaves glCaves;
private GenLayerCarving glCarving;
private GenLayerCaverns glCaverns;
private GenLayerSnow glSnow; private GenLayerSnow glSnow;
private GenLayerCliffs glCliffs; private GenLayerCliffs glCliffs;
private RNG rTerrain; private RNG rTerrain;
@ -128,9 +123,6 @@ public class IrisGenerator extends ParallaxWorldGenerator
rTerrain = new RNG(world.getSeed()); rTerrain = new RNG(world.getSeed());
glLNoise = new GenLayerLayeredNoise(this, world, random, rTerrain.nextParallelRNG(2)); glLNoise = new GenLayerLayeredNoise(this, world, random, rTerrain.nextParallelRNG(2));
glBiome = new GenLayerBiome(this, world, random, rTerrain.nextParallelRNG(4), dim.getBiomes()); 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)); glSnow = new GenLayerSnow(this, world, random, rTerrain.nextParallelRNG(5));
glCliffs = new GenLayerCliffs(this, world, random, rTerrain.nextParallelRNG(9)); glCliffs = new GenLayerCliffs(this, world, random, rTerrain.nextParallelRNG(9));
scatter = new CNG(rTerrain.nextParallelRNG(52), 1, 1).scale(10); scatter = new CNG(rTerrain.nextParallelRNG(52), 1, 1).scale(10);
@ -327,9 +319,30 @@ public class IrisGenerator extends ParallaxWorldGenerator
return hits; return hits;
} }
PolygonGenerator pg = new PolygonGenerator(RNG.r, 2, 0.013, 1, (g) -> g);
@Override @Override
public Biome onGenColumn(int wxxf, int wzxf, int x, int z, ChunkPlan plan, AtomicChunkData data, boolean surfaceOnly) 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(); PrecisionStopwatch s = getMetrics().start();
if(disposed) if(disposed)
{ {
@ -405,20 +418,6 @@ public class IrisGenerator extends ParallaxWorldGenerator
getMetrics().stop("terrain:ms:x256:/chunk:..", s); 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 hw = 0;
int hl = 0; int hl = 0;
@ -482,9 +481,6 @@ public class IrisGenerator extends ParallaxWorldGenerator
disposed = true; disposed = true;
dim = null; dim = null;
glLNoise = null; glLNoise = null;
glCaves = null;
glCarving = null;
glCaverns = null;
glSnow = null; glSnow = null;
glCliffs = null; glCliffs = null;
god.dispose(); god.dispose();

View File

@ -10,7 +10,9 @@ import mortar.api.nms.NMP;
import mortar.api.sched.J; import mortar.api.sched.J;
import mortar.compute.math.M; import mortar.compute.math.M;
import mortar.lang.collection.FinalDouble; import mortar.lang.collection.FinalDouble;
import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.util.ChronoQueue; import ninja.bytecode.iris.util.ChronoQueue;
import ninja.bytecode.iris.util.ObjectMode;
public class WorldReactor public class WorldReactor
{ {
@ -37,6 +39,12 @@ public class WorldReactor
if(world.isChunkLoaded(x, z) || world.loadChunk(x, z, false)) 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); max.add(1);
q.queue(() -> 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()); ((IrisGenerator) this).getMetrics().put("parallax:ms:/chunk", ps.getMillis());

View File

@ -85,6 +85,39 @@ public class PolygonGenerator
return false; 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 * 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 * 1.0 is perfectly in the center of a region