Fix Interpolation

This commit is contained in:
Daniel Mills 2020-08-18 01:16:30 -04:00
parent 1d8691fed8
commit 9ca8739514
13 changed files with 545 additions and 80 deletions

View File

@ -149,5 +149,10 @@
<artifactId>zt-zip</artifactId> <artifactId>zt-zip</artifactId>
<version>1.14</version> <version>1.14</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.5</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -12,7 +12,6 @@ public class IrisMetrics
private final RollingSequence post; private final RollingSequence post;
private final RollingSequence total; private final RollingSequence total;
private final RollingSequence perSecond; private final RollingSequence perSecond;
private final RollingSequence loss;
public int generators = 0; public int generators = 0;
public int noiseHits = 0; public int noiseHits = 0;
@ -23,7 +22,6 @@ public class IrisMetrics
post = new RollingSequence(memory); post = new RollingSequence(memory);
total = new RollingSequence(memory); total = new RollingSequence(memory);
perSecond = new RollingSequence(5); perSecond = new RollingSequence(5);
loss = new RollingSequence(memory);
} }
public double getSpeed() public double getSpeed()

View File

@ -24,6 +24,7 @@ import com.volmit.iris.Iris;
import com.volmit.iris.IrisContext; import com.volmit.iris.IrisContext;
import com.volmit.iris.IrisDataManager; import com.volmit.iris.IrisDataManager;
import com.volmit.iris.IrisMetrics; import com.volmit.iris.IrisMetrics;
import com.volmit.iris.gen.atomics.AtomicCache;
import com.volmit.iris.gen.atomics.AtomicMulticache; import com.volmit.iris.gen.atomics.AtomicMulticache;
import com.volmit.iris.noise.CNG; import com.volmit.iris.noise.CNG;
import com.volmit.iris.object.IrisBiome; import com.volmit.iris.object.IrisBiome;
@ -36,7 +37,6 @@ import com.volmit.iris.util.B;
import com.volmit.iris.util.ChronoLatch; import com.volmit.iris.util.ChronoLatch;
import com.volmit.iris.util.J; import com.volmit.iris.util.J;
import com.volmit.iris.util.M; import com.volmit.iris.util.M;
import com.volmit.iris.util.PrecisionStopwatch;
import com.volmit.iris.util.RNG; import com.volmit.iris.util.RNG;
import lombok.Data; import lombok.Data;
@ -57,6 +57,7 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
protected ChronoLatch perSecond; protected ChronoLatch perSecond;
protected ChronoLatch tickLatch; protected ChronoLatch tickLatch;
protected ChronoLatch pushLatch; protected ChronoLatch pushLatch;
private AtomicCache<IrisDimension> dimCache;
protected IrisMetrics metrics; protected IrisMetrics metrics;
protected World world; protected World world;
protected int generated; protected int generated;
@ -80,6 +81,7 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
initialized = false; initialized = false;
failing = false; failing = false;
pregenDone = false; pregenDone = false;
dimCache = new AtomicCache<>();
dev = false; dev = false;
} }
@ -123,7 +125,7 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
public IrisDimension loadDimension(String i) public IrisDimension loadDimension(String i)
{ {
return (getData() == null ? Iris.globaldata : getData()).getDimensionLoader().load(i); return dimCache.aquire(() -> (getData() == null ? Iris.globaldata : getData()).getDimensionLoader().load(i));
} }
public IrisGenerator loadGenerator(String i) public IrisGenerator loadGenerator(String i)
@ -322,8 +324,6 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
fastPregen = false; fastPregen = false;
} }
PrecisionStopwatch sx = PrecisionStopwatch.start();
if(failing) if(failing)
{ {
return generateChunkDataFailure(world, no, x, z, biomeGrid); return generateChunkDataFailure(world, no, x, z, biomeGrid);
@ -331,7 +331,6 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
try try
{ {
PrecisionStopwatch s = PrecisionStopwatch.start();
RNG random = new RNG(world.getSeed()); RNG random = new RNG(world.getSeed());
init(world, random.nextParallelRNG(0)); init(world, random.nextParallelRNG(0));
@ -347,12 +346,10 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
onGenerate(random, x, z, c, biomeGrid); onGenerate(random, x, z, c, biomeGrid);
} }
metrics.getTotal().put(s.getMilliseconds());
generated++; generated++;
long hits = CNG.hits; long hits = CNG.hits;
CNG.hits = 0; CNG.hits = 0;
Iris.instance.hit(hits); Iris.instance.hit(hits);
metrics.getLoss().put(sx.getMilliseconds() - s.getMilliseconds());
setHotloadable(true); setHotloadable(true);
return c; return c;
} }
@ -405,6 +402,7 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
public void onHotload() public void onHotload()
{ {
hlast = M.ms(); hlast = M.ms();
dimCache.reset();
} }
protected void fail(Throwable e) protected void fail(Throwable e)

View File

@ -27,6 +27,7 @@ public abstract class DimensionChunkGenerator extends ContextualChunkGenerator
protected static final BlockData AIR = Material.AIR.createBlockData(); protected static final BlockData AIR = Material.AIR.createBlockData();
protected static final BlockData CAVE_AIR = B.get("CAVE_AIR"); protected static final BlockData CAVE_AIR = B.get("CAVE_AIR");
protected static final BlockData BEDROCK = Material.BEDROCK.createBlockData(); protected static final BlockData BEDROCK = Material.BEDROCK.createBlockData();
protected static final BlockData WATER = Material.WATER.createBlockData();
public DimensionChunkGenerator(String dimensionName) public DimensionChunkGenerator(String dimensionName)
{ {

View File

@ -3,6 +3,7 @@ package com.volmit.iris.gen;
import java.awt.Color; import java.awt.Color;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Random;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
@ -22,6 +23,7 @@ import com.volmit.iris.util.BiomeResult;
import com.volmit.iris.util.Form; import com.volmit.iris.util.Form;
import com.volmit.iris.util.Function2; import com.volmit.iris.util.Function2;
import com.volmit.iris.util.KMap; import com.volmit.iris.util.KMap;
import com.volmit.iris.util.PrecisionStopwatch;
import com.volmit.iris.util.RNG; import com.volmit.iris.util.RNG;
import lombok.Data; import lombok.Data;
@ -65,6 +67,16 @@ public class IrisChunkGenerator extends PostBlockChunkGenerator implements IrisC
} }
} }
@Override
public ChunkData generateChunkData(World world, Random no, int x, int z, BiomeGrid biomeGrid)
{
PrecisionStopwatch s = PrecisionStopwatch.start();
ChunkData c = super.generateChunkData(world, no, x, z, biomeGrid);
s.end();
metrics.getTotal().put(s.getMilliseconds());
return c;
}
@Override @Override
protected void onGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid) protected void onGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid)
{ {

View File

@ -46,10 +46,10 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
private long lastChunkLoad = M.ms(); private long lastChunkLoad = M.ms();
private GenLayerCave glCave; private GenLayerCave glCave;
private GenLayerCarve glCarve; private GenLayerCarve glCarve;
protected GenLayerBiome glBiome;
private RNG rockRandom; private RNG rockRandom;
protected IrisLock regLock; protected IrisLock regLock;
private KMap<String, IrisGenerator> generators; private KMap<String, IrisGenerator> generators;
protected GenLayerBiome glBiome;
protected CNG masterFracture; protected CNG masterFracture;
protected ChronoLatch cwarn = new ChronoLatch(1000); protected ChronoLatch cwarn = new ChronoLatch(1000);
@ -113,15 +113,19 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
boolean caverning = false; boolean caverning = false;
KList<Integer> cavernHeights = new KList<>(); KList<Integer> cavernHeights = new KList<>();
int lastCavernHeight = -1; int lastCavernHeight = -1;
boolean bxx = false; boolean biomeAssigned = false;
int max = Math.max(height, fluidHeight);
int biomeMax = Math.min(max + 16, 255);
// From Height to Bedrock // From Height to Bedrock
for(int k = Math.max(height, fluidHeight); k >= 0; k--) for(int k = max; k >= 0; k--)
{ {
boolean cavernSurface = false; boolean cavernSurface = false;
boolean bedrock = k == 0;
boolean underwater = k > height && k <= fluidHeight;
// Bedrock // Bedrock
if(k == 0) if(bedrock)
{ {
if(biomeMap != null) if(biomeMap != null)
{ {
@ -145,6 +149,7 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
continue; continue;
} }
// Carved Surface
else if(carvable && caverning) else if(carvable && caverning)
{ {
lastCavernHeight = k; lastCavernHeight = k;
@ -153,16 +158,14 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
caverning = false; caverning = false;
} }
boolean underwater = k > height && k <= fluidHeight;
// Set Biome // Set Biome
if(!bxx && biomeMap != null) if(!biomeAssigned && biomeMap != null)
{ {
bxx = true; biomeAssigned = true;
sliver.set(k, biome.getGroundBiome(masterRandom, rz, k, rx)); sliver.set(k, biome.getGroundBiome(masterRandom, rz, k, rx));
biomeMap.setBiome(x, z, biome); biomeMap.setBiome(x, z, biome);
for(int kv = Math.max(height, fluidHeight); kv < Math.min(Math.max(height, fluidHeight) + 16, 255); kv++) for(int kv = max; kv < biomeMax; kv++)
{ {
Biome skyBiome = biome.getSkyBiome(masterRandom, rz, kv, rx); Biome skyBiome = biome.getSkyBiome(masterRandom, rz, kv, rx);
sliver.set(kv, skyBiome); sliver.set(kv, skyBiome);
@ -275,14 +278,14 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
for(IrisDepositGenerator k : getDimension().getDeposits()) for(IrisDepositGenerator k : getDimension().getDeposits())
{ {
k.generate(data, ro, this); k.generate(data, ro, this, x, z);
} }
for(IrisDepositGenerator k : region.getDeposits()) for(IrisDepositGenerator k : region.getDeposits())
{ {
for(int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++) for(int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++)
{ {
k.generate(data, ro, this); k.generate(data, ro, this, x, z);
} }
} }
@ -290,7 +293,7 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
{ {
for(int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++) for(int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++)
{ {
k.generate(data, ro, this); k.generate(data, ro, this, x, z);
} }
} }
} }
@ -493,9 +496,7 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
private double getNoiseHeight(int rx, int rz) private double getNoiseHeight(int rx, int rz)
{ {
double wx = getZoomed(rx); double h = getBiomeHeight(rx, rz);
double wz = getZoomed(rz);
double h = getBiomeHeight(wx, wz, rx, rz);
return h; return h;
} }
@ -670,8 +671,10 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
return generators; return generators;
} }
protected double getBiomeHeight(double rx, double rz, int x, int z) protected double getBiomeHeight(double rrx, double rrz)
{ {
double rx = rrx;
double rz = rrz;
double h = 0; double h = 0;
for(IrisGenerator i : getGenerators().values()) for(IrisGenerator i : getGenerators().values())

View File

@ -10,9 +10,44 @@ public enum InterpolationMethod
@DontObfuscate @DontObfuscate
BILINEAR, BILINEAR,
@DontObfuscate
BILINEAR_BEZIER,
@DontObfuscate
BILINEAR_PARAMETRIC_2,
@DontObfuscate
BILINEAR_PARAMETRIC_4,
@DontObfuscate
BILINEAR_PARAMETRIC_1_5,
@DontObfuscate @DontObfuscate
BICUBIC, BICUBIC,
@DontObfuscate @DontObfuscate
HERMITE HERMITE,
@DontObfuscate
CATMULL_ROM_SPLINE,
@DontObfuscate
HERMITE_TENSE,
@DontObfuscate
HERMITE_LOOSE,
@DontObfuscate
HERMITE_LOOSE_HALF_POSITIVE_BIAS,
@DontObfuscate
HERMITE_LOOSE_HALF_NEGATIVE_BIAS,
@DontObfuscate
HERMITE_LOOSE_FULL_POSITIVE_BIAS,
@DontObfuscate
HERMITE_LOOSE_FULL_NEGATIVE_BIAS,
;
} }

View File

@ -153,7 +153,7 @@ public class IrisDepositGenerator
}); });
} }
public void generate(ChunkData data, RNG rng, TerrainChunkGenerator g) public void generate(ChunkData data, RNG rng, TerrainChunkGenerator g, int cx, int cz)
{ {
for(int l = 0; l < rng.i(getMinPerChunk(), getMaxPerChunk()); l++) for(int l = 0; l < rng.i(getMinPerChunk(), getMaxPerChunk()); l++)
{ {
@ -170,7 +170,7 @@ public class IrisDepositGenerator
int x = rng.i(af, bf); int x = rng.i(af, bf);
int z = rng.i(af, bf); int z = rng.i(af, bf);
int height = (int) (Math.round(g.getTerrainHeight(x, z))) - 7; int height = (int) (Math.round(g.getTerrainHeight((cx << 4) + x, (cz << 4) + z))) - 7;
if(height <= 0) if(height <= 0)
{ {
@ -187,7 +187,7 @@ public class IrisDepositGenerator
int h = rng.i(i, a); int h = rng.i(i, a);
if(h > maxHeight || h < minHeight || h > height - 7) if(h > maxHeight || h < minHeight || h > height - 2)
{ {
return; return;
} }
@ -198,14 +198,14 @@ public class IrisDepositGenerator
int ny = j.getBlockY() + h; int ny = j.getBlockY() + h;
int nz = j.getBlockZ() + z; int nz = j.getBlockZ() + z;
if(ny > height - 7 || nx > 15 || nx < 0 || ny > 255 || ny < 0 || nz < 0 || nz > 15) if(ny > height - 2 || nx > 15 || nx < 0 || ny > 255 || ny < 0 || nz < 0 || nz > 15)
{ {
continue; continue;
} }
BlockData b = data.getBlockData(nx, ny, nz); BlockData b = data.getBlockData(nx, ny, nz);
if(b.getMaterial().equals(Material.ICE) || b.getMaterial().equals(Material.PACKED_ICE) || b.getMaterial().equals(B.mat("BLUE_ICE")) || b.getMaterial().equals(B.mat("FROSTED_ICE")) || b.getMaterial().equals(Material.SAND) || b.getMaterial().equals(Material.RED_SAND) || !b.getMaterial().isSolid()) if(b.getMaterial().equals(Material.ICE) || b.getMaterial().equals(Material.PACKED_ICE) || b.getMaterial().equals(B.mat("BLUE_ICE")) || b.getMaterial().equals(B.mat("FROSTED_ICE")) || b.getMaterial().equals(Material.SAND) || b.getMaterial().equals(Material.RED_SAND) || !B.isSolid(b.getMaterial()))
{ {
continue; continue;
} }

View File

@ -22,7 +22,8 @@ import lombok.EqualsAndHashCode;
@Desc("Represents a composite generator of noise gens") @Desc("Represents a composite generator of noise gens")
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
public class IrisGenerator extends IrisRegistrant { public class IrisGenerator extends IrisRegistrant
{
@MinNumber(0.001) @MinNumber(0.001)
@DontObfuscate @DontObfuscate
@Desc("The zoom or frequency.") @Desc("The zoom or frequency.")
@ -101,91 +102,114 @@ public class IrisGenerator extends IrisRegistrant {
private transient AtomicCache<CellGenerator> cellGen = new AtomicCache<>(); private transient AtomicCache<CellGenerator> cellGen = new AtomicCache<>();
public IrisGenerator() { public IrisGenerator()
{
} }
public double getMax() { public double getMax()
{
return opacity; return opacity;
} }
public boolean hasCliffs() { public boolean hasCliffs()
{
return cliffHeightMax > 0; return cliffHeightMax > 0;
} }
public CellGenerator getCellGenerator(long seed) { public CellGenerator getCellGenerator(long seed)
{
return cellGen.aquire(() -> new CellGenerator(new RNG(seed + 239466))); return cellGen.aquire(() -> new CellGenerator(new RNG(seed + 239466)));
} }
public <T extends IRare> T fitRarity(KList<T> b, long superSeed, double rx, double rz) { public <T extends IRare> T fitRarity(KList<T> b, long superSeed, double rx, double rz)
if (b.size() == 0) { {
if(b.size() == 0)
{
return null; return null;
} }
if (b.size() == 1) { if(b.size() == 1)
{
return b.get(0); return b.get(0);
} }
KList<T> rarityMapped = new KList<>(); KList<T> rarityMapped = new KList<>();
boolean o = false; boolean o = false;
int max = 1; int max = 1;
for (T i : b) { for(T i : b)
if (i.getRarity() > max) { {
if(i.getRarity() > max)
{
max = i.getRarity(); max = i.getRarity();
} }
} }
max++; max++;
for (T i : b) { for(T i : b)
for (int j = 0; j < max - i.getRarity(); j++) { {
if (o = !o) { for(int j = 0; j < max - i.getRarity(); j++)
{
if(o = !o)
{
rarityMapped.add(i); rarityMapped.add(i);
} }
else { else
{
rarityMapped.add(0, i); rarityMapped.add(0, i);
} }
} }
} }
if (rarityMapped.size() == 1) { if(rarityMapped.size() == 1)
{
return rarityMapped.get(0); return rarityMapped.get(0);
} }
if (rarityMapped.isEmpty()) { if(rarityMapped.isEmpty())
{
throw new RuntimeException("BAD RARITY MAP! RELATED TO: " + b.toString(", or possibly ")); throw new RuntimeException("BAD RARITY MAP! RELATED TO: " + b.toString(", or possibly "));
} }
return fit(rarityMapped, superSeed, rx, rz); return fit(rarityMapped, superSeed, rx, rz);
} }
public <T> T fit(T[] v, long superSeed, double rx, double rz) { public <T> T fit(T[] v, long superSeed, double rx, double rz)
if (v.length == 0) { {
if(v.length == 0)
{
return null; return null;
} }
if (v.length == 1) { if(v.length == 1)
{
return v[0]; return v[0];
} }
return v[fit(0, v.length - 1, superSeed, rx, rz)]; return v[fit(0, v.length - 1, superSeed, rx, rz)];
} }
public <T> T fit(List<T> v, long superSeed, double rx, double rz) { public <T> T fit(List<T> v, long superSeed, double rx, double rz)
if (v.size() == 0) { {
if(v.size() == 0)
{
return null; return null;
} }
if (v.size() == 1) { if(v.size() == 1)
{
return v.get(0); return v.get(0);
} }
return v.get(fit(0, v.size() - 1, superSeed, rx, rz)); return v.get(fit(0, v.size() - 1, superSeed, rx, rz));
} }
public int fit(int min, int max, long superSeed, double rx, double rz) { public int fit(int min, int max, long superSeed, double rx, double rz)
if (min == max) { {
if(min == max)
{
return min; return min;
} }
@ -194,8 +218,10 @@ public class IrisGenerator extends IrisRegistrant {
return (int) Math.round(IrisInterpolation.lerp(min, max, noise)); return (int) Math.round(IrisInterpolation.lerp(min, max, noise));
} }
public int fit(double min, double max, long superSeed, double rx, double rz) { public int fit(double min, double max, long superSeed, double rx, double rz)
if (min == max) { {
if(min == max)
{
return (int) Math.round(min); return (int) Math.round(min);
} }
@ -204,8 +230,10 @@ public class IrisGenerator extends IrisRegistrant {
return (int) Math.round(IrisInterpolation.lerp(min, max, noise)); return (int) Math.round(IrisInterpolation.lerp(min, max, noise));
} }
public double fitDouble(double min, double max, long superSeed, double rx, double rz) { public double fitDouble(double min, double max, long superSeed, double rx, double rz)
if (min == max) { {
if(min == max)
{
return min; return min;
} }
@ -214,12 +242,15 @@ public class IrisGenerator extends IrisRegistrant {
return IrisInterpolation.lerp(min, max, noise); return IrisInterpolation.lerp(min, max, noise);
} }
public double getHeight(double rx, double rz, long superSeed) { public double getHeight(double rx, double rz, long superSeed)
{
return getHeight(rx, 0, rz, superSeed); return getHeight(rx, 0, rz, superSeed);
} }
public double getHeight(double rx, double ry, double rz, long superSeed) { public double getHeight(double rx, double ry, double rz, long superSeed)
if (composite.isEmpty()) { {
if(composite.isEmpty())
{
Iris.warn("Useless Generator: Composite is empty in " + getLoadKey()); Iris.warn("Useless Generator: Composite is empty in " + getLoadKey());
return 0; return 0;
} }
@ -228,16 +259,17 @@ public class IrisGenerator extends IrisRegistrant {
double h = 0; double h = 0;
double tp = 0; double tp = 0;
for (IrisNoiseGenerator i : composite) { for(IrisNoiseGenerator i : composite)
{
tp += i.getOpacity(); tp += i.getOpacity();
h += i.getNoise(seed + superSeed + hc, (rx + offsetX) / zoom, (rz + offsetZ) / zoom); h += i.getNoise(seed + superSeed + hc, (rx + offsetX) / zoom, (rz + offsetZ) / zoom);
} }
double v = (h / tp) * opacity; double v = (h / tp) * opacity;
if (Double.isNaN(v)) { if(Double.isNaN(v))
Iris.warn("Nan value on gen: " + getLoadKey() + ": H = " + h + " TP = " + tp + " OPACITY = " + opacity {
+ " ZOOM = " + zoom); Iris.warn("Nan value on gen: " + getLoadKey() + ": H = " + h + " TP = " + tp + " OPACITY = " + opacity + " ZOOM = " + zoom);
} }
v = hasCliffs() ? cliff(rx, rz, v, superSeed + 294596 + hc) : v; v = hasCliffs() ? cliff(rx, rz, v, superSeed + 294596 + hc) : v;
@ -246,29 +278,32 @@ public class IrisGenerator extends IrisRegistrant {
return v; return v;
} }
public double cell(double rx, double rz, double v, double superSeed) { public double cell(double rx, double rz, double v, double superSeed)
{
getCellGenerator(seed + 46222).setShuffle(getCellFractureShuffle()); getCellGenerator(seed + 46222).setShuffle(getCellFractureShuffle());
return getCellGenerator(seed + 46222).getDistance(rx / getCellFractureZoom(), return getCellGenerator(seed + 46222).getDistance(rx / getCellFractureZoom(), rz / getCellFractureZoom()) > getCellPercentSize() ? (v * getCellFractureHeight()) : v;
rz / getCellFractureZoom()) > getCellPercentSize() ? (v * getCellFractureHeight()) : v;
} }
private boolean hasCellCracks() { private boolean hasCellCracks()
{
return getCellFractureHeight() != 0; return getCellFractureHeight() != 0;
} }
public double getCliffHeight(double rx, double rz, double superSeed) { public double getCliffHeight(double rx, double rz, double superSeed)
{
int hc = (int) ((cliffHeightMin * 10) + 10 + cliffHeightMax + interpolationScale * seed + offsetX + offsetZ); int hc = (int) ((cliffHeightMin * 10) + 10 + cliffHeightMax + interpolationScale * seed + offsetX + offsetZ);
double h = cliffHeightGenerator.getNoise((long) (seed + superSeed + hc), (rx + offsetX) / zoom, double h = cliffHeightGenerator.getNoise((long) (seed + superSeed + hc), (rx + offsetX) / zoom, (rz + offsetZ) / zoom);
(rz + offsetZ) / zoom);
return IrisInterpolation.lerp(cliffHeightMin, cliffHeightMax, h); return IrisInterpolation.lerp(cliffHeightMin, cliffHeightMax, h);
} }
public double cliff(double rx, double rz, double v, double superSeed) { public double cliff(double rx, double rz, double v, double superSeed)
{
double cliffHeight = getCliffHeight(rx, rz, superSeed - 34857); double cliffHeight = getCliffHeight(rx, rz, superSeed - 34857);
return (Math.round((v * 255D) / cliffHeight) * cliffHeight) / 255D; return (Math.round((v * 255D) / cliffHeight) * cliffHeight) / 255D;
} }
public IrisGenerator rescale(double scale) { public IrisGenerator rescale(double scale)
{
zoom /= scale; zoom /= scale;
return this; return this;
} }

View File

@ -223,7 +223,7 @@ public class IrisObject extends IrisRegistrant
continue; continue;
} }
if(yy <= placer.getFluidHeight() && data instanceof Waterlogged) if(config.isWaterloggable() && yy <= placer.getFluidHeight() && data instanceof Waterlogged)
{ {
((Waterlogged) data).setWaterlogged(true); ((Waterlogged) data).setWaterlogged(true);
} }

View File

@ -64,6 +64,10 @@ public class IrisObjectPlacement
@Desc("If set to true, objects will place on the terrain height, ignoring the water surface.") @Desc("If set to true, objects will place on the terrain height, ignoring the water surface.")
private boolean underwater = false; private boolean underwater = false;
@DontObfuscate
@Desc("If set to true, Blocks placed underwater that could be waterlogged are waterlogged.")
private boolean waterloggable = true;
@DontObfuscate @DontObfuscate
@Desc("If set to true, objects will place on the fluid height level Such as boats.") @Desc("If set to true, objects will place on the fluid height level Such as boats.")
private boolean onwater = false; private boolean onwater = false;

View File

@ -120,7 +120,11 @@ public class IrisStructurePlacement
private IrisObjectPlacement getConfig() private IrisObjectPlacement getConfig()
{ {
return config.aquire(() -> new IrisObjectPlacement()); return config.aquire(() -> {
IrisObjectPlacement p = new IrisObjectPlacement();
p.setWaterloggable(false);
return p;
});
} }
public IrisObject load(ContextualChunkGenerator g, String s) public IrisObject load(ContextualChunkGenerator g, String s)

View File

@ -1,9 +1,13 @@
package com.volmit.iris.util; package com.volmit.iris.util;
import com.volmit.iris.noise.CNG;
import com.volmit.iris.object.InterpolationMethod; import com.volmit.iris.object.InterpolationMethod;
import com.volmit.iris.object.NoiseStyle;
public class IrisInterpolation public class IrisInterpolation
{ {
private static CNG cng = NoiseStyle.IRIS_DOUBLE.create(RNG.r);
public static double bezier(double t) public static double bezier(double t)
{ {
return t * t * (3.0d - 2.0d * t); return t * t * (3.0d - 2.0d * t);
@ -85,6 +89,11 @@ public class IrisInterpolation
return lerpBezier(lerpBezier(a, b, tx), lerpBezier(c, d, tx), ty); return lerpBezier(lerpBezier(a, b, tx), lerpBezier(c, d, tx), ty);
} }
public static double blerpSinCenter(double a, double b, double c, double d, double tx, double ty)
{
return lerpCenterSin(lerpCenterSin(a, b, tx), lerpCenterSin(c, d, tx), ty);
}
public static double blerpParametric(double a, double b, double c, double d, double tx, double ty, double v) public static double blerpParametric(double a, double b, double c, double d, double tx, double ty, double v)
{ {
return lerpParametric(lerpParametric(a, b, tx, v), lerpParametric(c, d, tx, v), ty, v); return lerpParametric(lerpParametric(a, b, tx, v), lerpParametric(c, d, tx, v), ty, v);
@ -109,9 +118,50 @@ public class IrisInterpolation
return (a0 * p1 + a1 * m0 + a2 * m1 + a3 * p2); return (a0 * p1 + a1 * m0 + a2 * m1 + a3 * p2);
} }
public static double hermiteBezier(double p0, double p1, double p2, double p3, double mu, double tension, double bias)
{
return bezier(hermite(p0, p1, p2, p3, mu, tension, bias));
}
public static double hermiteParametric(double p0, double p1, double p2, double p3, double mu, double tension, double bias, double a)
{
return parametric(hermite(p0, p1, p2, p3, mu, tension, bias), a);
}
public static double bihermite(double p00, double p01, double p02, double p03, double p10, double p11, double p12, double p13, double p20, double p21, double p22, double p23, double p30, double p31, double p32, double p33, double mux, double muy, double tension, double bias) public static double bihermite(double p00, double p01, double p02, double p03, double p10, double p11, double p12, double p13, double p20, double p21, double p22, double p23, double p30, double p31, double p32, double p33, double mux, double muy, double tension, double bias)
{ {
return hermite(hermite(p00, p01, p02, p03, muy, tension, bias), hermite(p10, p11, p12, p13, muy, tension, bias), hermite(p20, p21, p22, p23, muy, tension, bias), hermite(p30, p31, p32, p33, muy, tension, bias), mux, tension, bias); //@builder
return hermite(
hermite(p00, p01, p02, p03, muy, tension, bias),
hermite(p10, p11, p12, p13, muy, tension, bias),
hermite(p20, p21, p22, p23, muy, tension, bias),
hermite(p30, p31, p32, p33, muy, tension, bias),
mux, tension, bias);
//@done
}
public static double bihermiteBezier(double p00, double p01, double p02, double p03, double p10, double p11, double p12, double p13, double p20, double p21, double p22, double p23, double p30, double p31, double p32, double p33, double mux, double muy, double tension, double bias)
{
//@builder
return hermiteBezier(
hermiteBezier(p00, p01, p02, p03, muy, tension, bias),
hermiteBezier(p10, p11, p12, p13, muy, tension, bias),
hermiteBezier(p20, p21, p22, p23, muy, tension, bias),
hermiteBezier(p30, p31, p32, p33, muy, tension, bias),
mux, tension, bias);
//@done
}
public static double bihermiteParametric(double p00, double p01, double p02, double p03, double p10, double p11, double p12, double p13, double p20, double p21, double p22, double p23, double p30, double p31, double p32, double p33, double mux, double muy, double tension, double bias, double a)
{
//@builder
return hermiteParametric(
hermiteParametric(p00, p01, p02, p03, muy, tension, bias, a),
hermiteParametric(p10, p11, p12, p13, muy, tension, bias, a),
hermiteParametric(p20, p21, p22, p23, muy, tension, bias, a),
hermiteParametric(p30, p31, p32, p33, muy, tension, bias, a),
mux, tension, bias, a);
//@done
} }
public static double cubic(double p0, double p1, double p2, double p3, double mu) public static double cubic(double p0, double p1, double p2, double p3, double mu)
@ -127,9 +177,50 @@ public class IrisInterpolation
return a0 * mu * mu2 + a1 * mu2 + a2 * mu + a3; return a0 * mu * mu2 + a1 * mu2 + a2 * mu + a3;
} }
public static double cubicBezier(double p0, double p1, double p2, double p3, double mu)
{
return bezier(cubic(p0, p1, p2, p3, mu));
}
public static double cubicParametric(double p0, double p1, double p2, double p3, double mu, double a)
{
return parametric(cubic(p0, p1, p2, p3, mu), a);
}
public static double bicubic(double p00, double p01, double p02, double p03, double p10, double p11, double p12, double p13, double p20, double p21, double p22, double p23, double p30, double p31, double p32, double p33, double mux, double muy) public static double bicubic(double p00, double p01, double p02, double p03, double p10, double p11, double p12, double p13, double p20, double p21, double p22, double p23, double p30, double p31, double p32, double p33, double mux, double muy)
{ {
return cubic(cubic(p00, p01, p02, p03, muy), cubic(p10, p11, p12, p13, muy), cubic(p20, p21, p22, p23, muy), cubic(p30, p31, p32, p33, muy), mux); //@builder
return cubic(
cubic(p00, p01, p02, p03, muy),
cubic(p10, p11, p12, p13, muy),
cubic(p20, p21, p22, p23, muy),
cubic(p30, p31, p32, p33, muy),
mux);
//@done
}
public static double bicubicBezier(double p00, double p01, double p02, double p03, double p10, double p11, double p12, double p13, double p20, double p21, double p22, double p23, double p30, double p31, double p32, double p33, double mux, double muy)
{
//@builder
return cubicBezier(
cubicBezier(p00, p01, p02, p03, muy),
cubicBezier(p10, p11, p12, p13, muy),
cubicBezier(p20, p21, p22, p23, muy),
cubicBezier(p30, p31, p32, p33, muy),
mux);
//@done
}
public static double bicubicParametric(double p00, double p01, double p02, double p03, double p10, double p11, double p12, double p13, double p20, double p21, double p22, double p23, double p30, double p31, double p32, double p33, double mux, double muy, double a)
{
//@builder
return cubicParametric(
cubicParametric(p00, p01, p02, p03, muy,a),
cubicParametric(p10, p11, p12, p13, muy,a),
cubicParametric(p20, p21, p22, p23, muy,a),
cubicParametric(p30, p31, p32, p33, muy,a),
mux, a);
//@done
} }
public static double trilerp(double v1, double v2, double v3, double v4, double v5, double v6, double v7, double v8, double x, double y, double z) public static double trilerp(double v1, double v2, double v3, double v4, double v5, double v6, double v7, double v8, double x, double y, double z)
@ -140,6 +231,26 @@ public class IrisInterpolation
} }
public static double getBilinearNoise(int x, int z, double rad, NoiseProvider n) public static double getBilinearNoise(int x, int z, double rad, NoiseProvider n)
{
int fx = (int) Math.floor(x / rad);
int fz = (int) Math.floor(z / rad);
int x1 = (int) Math.round(fx * rad);
int z1 = (int) Math.round(fz * rad);
int x2 = (int) Math.round((fx + 1) * rad);
int z2 = (int) Math.round((fz + 1) * rad);
double px = rangeScale(0, 1, x1, x2, x);
double pz = rangeScale(0, 1, z1, z2, z);
//@builder
return blerp(
n.noise(x1, z1),
n.noise(x2, z1),
n.noise(x1, z2),
n.noise(x2, z2),
px, pz);
//@done
}
public static double getBilinearBezierNoise(int x, int z, double rad, NoiseProvider n)
{ {
int fx = (int) Math.floor(x / rad); int fx = (int) Math.floor(x / rad);
int fz = (int) Math.floor(z / rad); int fz = (int) Math.floor(z / rad);
@ -159,6 +270,46 @@ public class IrisInterpolation
//@done //@done
} }
public static double getBilinearParametricNoise(int x, int z, double rad, NoiseProvider n, double a)
{
int fx = (int) Math.floor(x / rad);
int fz = (int) Math.floor(z / rad);
int x1 = (int) Math.round(fx * rad);
int z1 = (int) Math.round(fz * rad);
int x2 = (int) Math.round((fx + 1) * rad);
int z2 = (int) Math.round((fz + 1) * rad);
double px = rangeScale(0, 1, x1, x2, x);
double pz = rangeScale(0, 1, z1, z2, z);
//@builder
return blerpParametric(
n.noise(x1, z1),
n.noise(x2, z1),
n.noise(x1, z2),
n.noise(x2, z2),
px, pz, a);
//@done
}
public static double getBilinearCenterSineNoise(int x, int z, double rad, NoiseProvider n)
{
int fx = (int) Math.floor(x / rad);
int fz = (int) Math.floor(z / rad);
int x1 = (int) Math.round(fx * rad);
int z1 = (int) Math.round(fz * rad);
int x2 = (int) Math.round((fx + 1) * rad);
int z2 = (int) Math.round((fz + 1) * rad);
double px = rangeScale(0, 1, x1, x2, x);
double pz = rangeScale(0, 1, z1, z2, z);
//@builder
return blerpSinCenter(
n.noise(x1, z1),
n.noise(x2, z1),
n.noise(x1, z2),
n.noise(x2, z2),
px, pz);
//@done
}
public static double getBicubicNoise(int x, int z, double rad, NoiseProvider n) public static double getBicubicNoise(int x, int z, double rad, NoiseProvider n)
{ {
int fx = (int) Math.floor(x / rad); int fx = (int) Math.floor(x / rad);
@ -195,7 +346,94 @@ public class IrisInterpolation
//@done //@done
} }
public static double getBicubicBezierNoise(int x, int z, double rad, NoiseProvider n)
{
int fx = (int) Math.floor(x / rad);
int fz = (int) Math.floor(z / rad);
int x0 = (int) Math.round((fx - 1) * rad);
int z0 = (int) Math.round((fz - 1) * rad);
int x1 = (int) Math.round(fx * rad);
int z1 = (int) Math.round(fz * rad);
int x2 = (int) Math.round((fx + 1) * rad);
int z2 = (int) Math.round((fz + 1) * rad);
int x3 = (int) Math.round((fx + 2) * rad);
int z3 = (int) Math.round((fz + 2) * rad);
double px = rangeScale(0, 1, x1, x2, x);
double pz = rangeScale(0, 1, z1, z2, z);
//@builder
return bicubicBezier(
n.noise(x0, z0),
n.noise(x0, z1),
n.noise(x0, z2),
n.noise(x0, z3),
n.noise(x1, z0),
n.noise(x1, z1),
n.noise(x1, z2),
n.noise(x1, z3),
n.noise(x2, z0),
n.noise(x2, z1),
n.noise(x2, z2),
n.noise(x2, z3),
n.noise(x3, z0),
n.noise(x3, z1),
n.noise(x3, z2),
n.noise(x3, z3),
px, pz);
//@done
}
public static double getBicubicParametricNoise(int x, int z, double rad, NoiseProvider n, double a)
{
int fx = (int) Math.floor(x / rad);
int fz = (int) Math.floor(z / rad);
int x0 = (int) Math.round((fx - 1) * rad);
int z0 = (int) Math.round((fz - 1) * rad);
int x1 = (int) Math.round(fx * rad);
int z1 = (int) Math.round(fz * rad);
int x2 = (int) Math.round((fx + 1) * rad);
int z2 = (int) Math.round((fz + 1) * rad);
int x3 = (int) Math.round((fx + 2) * rad);
int z3 = (int) Math.round((fz + 2) * rad);
double px = rangeScale(0, 1, x1, x2, x);
double pz = rangeScale(0, 1, z1, z2, z);
//@builder
return bicubicParametric(
n.noise(x0, z0),
n.noise(x0, z1),
n.noise(x0, z2),
n.noise(x0, z3),
n.noise(x1, z0),
n.noise(x1, z1),
n.noise(x1, z2),
n.noise(x1, z3),
n.noise(x2, z0),
n.noise(x2, z1),
n.noise(x2, z2),
n.noise(x2, z3),
n.noise(x3, z0),
n.noise(x3, z1),
n.noise(x3, z2),
n.noise(x3, z3),
px, pz, a);
//@done
}
public static double getHermiteNoise(int x, int z, double rad, NoiseProvider n) public static double getHermiteNoise(int x, int z, double rad, NoiseProvider n)
{
return getHermiteNoise(x, z, rad, n, 0.5, 0);
}
public static double getHermiteBezierNoise(int x, int z, double rad, NoiseProvider n)
{
return getHermiteBezierNoise(x, z, rad, n, 0.5, 0);
}
public static double getHermiteParametricNoise(int x, int z, double rad, NoiseProvider n, double a)
{
return getHermiteParametricNoise(x, z, rad, n, 0.5, 0, a);
}
public static double getHermiteNoise(int x, int z, double rad, NoiseProvider n, double t, double b)
{ {
int fx = (int) Math.floor(x / rad); int fx = (int) Math.floor(x / rad);
int fz = (int) Math.floor(z / rad); int fz = (int) Math.floor(z / rad);
@ -227,7 +465,79 @@ public class IrisInterpolation
n.noise(x3, z1), n.noise(x3, z1),
n.noise(x3, z2), n.noise(x3, z2),
n.noise(x3, z3), n.noise(x3, z3),
px, pz, 0.0000000001, 0.5); px, pz, t, b);
//@done
}
public static double getHermiteBezierNoise(int x, int z, double rad, NoiseProvider n, double t, double b)
{
int fx = (int) Math.floor(x / rad);
int fz = (int) Math.floor(z / rad);
int x0 = (int) Math.round((fx - 1) * rad);
int z0 = (int) Math.round((fz - 1) * rad);
int x1 = (int) Math.round(fx * rad);
int z1 = (int) Math.round(fz * rad);
int x2 = (int) Math.round((fx + 1) * rad);
int z2 = (int) Math.round((fz + 1) * rad);
int x3 = (int) Math.round((fx + 2) * rad);
int z3 = (int) Math.round((fz + 2) * rad);
double px = rangeScale(0, 1, x1, x2, x);
double pz = rangeScale(0, 1, z1, z2, z);
//@builder
return bihermiteBezier(
n.noise(x0, z0),
n.noise(x0, z1),
n.noise(x0, z2),
n.noise(x0, z3),
n.noise(x1, z0),
n.noise(x1, z1),
n.noise(x1, z2),
n.noise(x1, z3),
n.noise(x2, z0),
n.noise(x2, z1),
n.noise(x2, z2),
n.noise(x2, z3),
n.noise(x3, z0),
n.noise(x3, z1),
n.noise(x3, z2),
n.noise(x3, z3),
px, pz, t, b);
//@done
}
public static double getHermiteParametricNoise(int x, int z, double rad, NoiseProvider n, double t, double b, double a)
{
int fx = (int) Math.floor(x / rad);
int fz = (int) Math.floor(z / rad);
int x0 = (int) Math.round((fx - 1) * rad);
int z0 = (int) Math.round((fz - 1) * rad);
int x1 = (int) Math.round(fx * rad);
int z1 = (int) Math.round(fz * rad);
int x2 = (int) Math.round((fx + 1) * rad);
int z2 = (int) Math.round((fz + 1) * rad);
int x3 = (int) Math.round((fx + 2) * rad);
int z3 = (int) Math.round((fz + 2) * rad);
double px = rangeScale(0, 1, x1, x2, x);
double pz = rangeScale(0, 1, z1, z2, z);
//@builder
return bihermiteParametric(
n.noise(x0, z0),
n.noise(x0, z1),
n.noise(x0, z2),
n.noise(x0, z3),
n.noise(x1, z0),
n.noise(x1, z1),
n.noise(x1, z2),
n.noise(x1, z3),
n.noise(x2, z0),
n.noise(x2, z1),
n.noise(x2, z2),
n.noise(x2, z3),
n.noise(x3, z0),
n.noise(x3, z1),
n.noise(x3, z2),
n.noise(x3, z3),
px, pz, t, b, a);
//@done //@done
} }
@ -243,11 +553,71 @@ public class IrisInterpolation
return getBicubicNoise(x, z, rad, n); return getBicubicNoise(x, z, rad, n);
} }
else if(method.equals(InterpolationMethod.BILINEAR_BEZIER))
{
return getBilinearBezierNoise(x, z, rad, n);
}
else if(method.equals(InterpolationMethod.BILINEAR_PARAMETRIC_2))
{
return getBilinearParametricNoise(x, z, rad, n, 2);
}
else if(method.equals(InterpolationMethod.BILINEAR_PARAMETRIC_4))
{
return getBilinearParametricNoise(x, z, rad, n, 4);
}
else if(method.equals(InterpolationMethod.BILINEAR_PARAMETRIC_1_5))
{
return getBilinearParametricNoise(x, z, rad, n, 1.5);
}
else if(method.equals(InterpolationMethod.BICUBIC))
{
return getBilinearNoise(x, z, rad, n);
}
else if(method.equals(InterpolationMethod.HERMITE)) else if(method.equals(InterpolationMethod.HERMITE))
{ {
return getHermiteNoise(x, z, rad, n); return getHermiteNoise(x, z, rad, n);
} }
else if(method.equals(InterpolationMethod.HERMITE_TENSE))
{
return getHermiteNoise(x, z, rad, n, 0.8D, 0D);
}
else if(method.equals(InterpolationMethod.CATMULL_ROM_SPLINE))
{
return getHermiteNoise(x, z, rad, n, 1D, 0D);
}
else if(method.equals(InterpolationMethod.HERMITE_LOOSE))
{
return getHermiteNoise(x, z, rad, n, 0D, 0D);
}
else if(method.equals(InterpolationMethod.HERMITE_LOOSE_HALF_NEGATIVE_BIAS))
{
return getHermiteNoise(x, z, rad, n, 0D, -0.5D);
}
else if(method.equals(InterpolationMethod.HERMITE_LOOSE_HALF_POSITIVE_BIAS))
{
return getHermiteNoise(x, z, rad, n, 0D, 0.5D);
}
else if(method.equals(InterpolationMethod.HERMITE_LOOSE_FULL_NEGATIVE_BIAS))
{
return getHermiteNoise(x, z, rad, n, 0D, -1D);
}
else if(method.equals(InterpolationMethod.HERMITE_LOOSE_FULL_POSITIVE_BIAS))
{
return getHermiteNoise(x, z, rad, n, 0D, 1D);
}
return n.noise(x, z); return n.noise(x, z);
} }