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>
<version>1.14</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.5</version>
</dependency>
</dependencies>
</project>

View File

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

View File

@ -24,6 +24,7 @@ import com.volmit.iris.Iris;
import com.volmit.iris.IrisContext;
import com.volmit.iris.IrisDataManager;
import com.volmit.iris.IrisMetrics;
import com.volmit.iris.gen.atomics.AtomicCache;
import com.volmit.iris.gen.atomics.AtomicMulticache;
import com.volmit.iris.noise.CNG;
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.J;
import com.volmit.iris.util.M;
import com.volmit.iris.util.PrecisionStopwatch;
import com.volmit.iris.util.RNG;
import lombok.Data;
@ -57,6 +57,7 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
protected ChronoLatch perSecond;
protected ChronoLatch tickLatch;
protected ChronoLatch pushLatch;
private AtomicCache<IrisDimension> dimCache;
protected IrisMetrics metrics;
protected World world;
protected int generated;
@ -80,6 +81,7 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
initialized = false;
failing = false;
pregenDone = false;
dimCache = new AtomicCache<>();
dev = false;
}
@ -123,7 +125,7 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
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)
@ -322,8 +324,6 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
fastPregen = false;
}
PrecisionStopwatch sx = PrecisionStopwatch.start();
if(failing)
{
return generateChunkDataFailure(world, no, x, z, biomeGrid);
@ -331,7 +331,6 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
try
{
PrecisionStopwatch s = PrecisionStopwatch.start();
RNG random = new RNG(world.getSeed());
init(world, random.nextParallelRNG(0));
@ -347,12 +346,10 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
onGenerate(random, x, z, c, biomeGrid);
}
metrics.getTotal().put(s.getMilliseconds());
generated++;
long hits = CNG.hits;
CNG.hits = 0;
Iris.instance.hit(hits);
metrics.getLoss().put(sx.getMilliseconds() - s.getMilliseconds());
setHotloadable(true);
return c;
}
@ -405,6 +402,7 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
public void onHotload()
{
hlast = M.ms();
dimCache.reset();
}
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 CAVE_AIR = B.get("CAVE_AIR");
protected static final BlockData BEDROCK = Material.BEDROCK.createBlockData();
protected static final BlockData WATER = Material.WATER.createBlockData();
public DimensionChunkGenerator(String dimensionName)
{

View File

@ -3,6 +3,7 @@ package com.volmit.iris.gen;
import java.awt.Color;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Random;
import org.bukkit.Bukkit;
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.Function2;
import com.volmit.iris.util.KMap;
import com.volmit.iris.util.PrecisionStopwatch;
import com.volmit.iris.util.RNG;
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
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 GenLayerCave glCave;
private GenLayerCarve glCarve;
protected GenLayerBiome glBiome;
private RNG rockRandom;
protected IrisLock regLock;
private KMap<String, IrisGenerator> generators;
protected GenLayerBiome glBiome;
protected CNG masterFracture;
protected ChronoLatch cwarn = new ChronoLatch(1000);
@ -113,15 +113,19 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
boolean caverning = false;
KList<Integer> cavernHeights = new KList<>();
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
for(int k = Math.max(height, fluidHeight); k >= 0; k--)
for(int k = max; k >= 0; k--)
{
boolean cavernSurface = false;
boolean bedrock = k == 0;
boolean underwater = k > height && k <= fluidHeight;
// Bedrock
if(k == 0)
if(bedrock)
{
if(biomeMap != null)
{
@ -145,6 +149,7 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
continue;
}
// Carved Surface
else if(carvable && caverning)
{
lastCavernHeight = k;
@ -153,16 +158,14 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
caverning = false;
}
boolean underwater = k > height && k <= fluidHeight;
// Set Biome
if(!bxx && biomeMap != null)
if(!biomeAssigned && biomeMap != null)
{
bxx = true;
biomeAssigned = true;
sliver.set(k, biome.getGroundBiome(masterRandom, rz, k, rx));
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);
sliver.set(kv, skyBiome);
@ -275,14 +278,14 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
for(IrisDepositGenerator k : getDimension().getDeposits())
{
k.generate(data, ro, this);
k.generate(data, ro, this, x, z);
}
for(IrisDepositGenerator k : region.getDeposits())
{
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++)
{
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)
{
double wx = getZoomed(rx);
double wz = getZoomed(rz);
double h = getBiomeHeight(wx, wz, rx, rz);
double h = getBiomeHeight(rx, rz);
return h;
}
@ -670,8 +671,10 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
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;
for(IrisGenerator i : getGenerators().values())

View File

@ -10,9 +10,44 @@ public enum InterpolationMethod
@DontObfuscate
BILINEAR,
@DontObfuscate
BILINEAR_BEZIER,
@DontObfuscate
BILINEAR_PARAMETRIC_2,
@DontObfuscate
BILINEAR_PARAMETRIC_4,
@DontObfuscate
BILINEAR_PARAMETRIC_1_5,
@DontObfuscate
BICUBIC,
@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++)
{
@ -170,7 +170,7 @@ public class IrisDepositGenerator
int x = 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)
{
@ -187,7 +187,7 @@ public class IrisDepositGenerator
int h = rng.i(i, a);
if(h > maxHeight || h < minHeight || h > height - 7)
if(h > maxHeight || h < minHeight || h > height - 2)
{
return;
}
@ -198,14 +198,14 @@ public class IrisDepositGenerator
int ny = j.getBlockY() + h;
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;
}
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;
}

View File

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

View File

@ -223,7 +223,7 @@ public class IrisObject extends IrisRegistrant
continue;
}
if(yy <= placer.getFluidHeight() && data instanceof Waterlogged)
if(config.isWaterloggable() && yy <= placer.getFluidHeight() && data instanceof Waterlogged)
{
((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.")
private boolean underwater = false;
@DontObfuscate
@Desc("If set to true, Blocks placed underwater that could be waterlogged are waterlogged.")
private boolean waterloggable = true;
@DontObfuscate
@Desc("If set to true, objects will place on the fluid height level Such as boats.")
private boolean onwater = false;

View File

@ -120,7 +120,11 @@ public class IrisStructurePlacement
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)

View File

@ -1,9 +1,13 @@
package com.volmit.iris.util;
import com.volmit.iris.noise.CNG;
import com.volmit.iris.object.InterpolationMethod;
import com.volmit.iris.object.NoiseStyle;
public class IrisInterpolation
{
private static CNG cng = NoiseStyle.IRIS_DOUBLE.create(RNG.r);
public static double bezier(double 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);
}
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)
{
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);
}
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)
{
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)
@ -127,9 +177,50 @@ public class IrisInterpolation
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)
{
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)
@ -140,6 +231,26 @@ public class IrisInterpolation
}
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 fz = (int) Math.floor(z / rad);
@ -159,6 +270,46 @@ public class IrisInterpolation
//@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)
{
int fx = (int) Math.floor(x / rad);
@ -195,7 +346,94 @@ public class IrisInterpolation
//@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)
{
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 fz = (int) Math.floor(z / rad);
@ -227,7 +465,79 @@ public class IrisInterpolation
n.noise(x3, z1),
n.noise(x3, z2),
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
}
@ -243,11 +553,71 @@ public class IrisInterpolation
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))
{
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);
}