Gen Features

This commit is contained in:
Daniel Mills 2020-01-14 21:11:46 -05:00
parent 90846401a5
commit 417a759c40
14 changed files with 344 additions and 89 deletions

View File

@ -9,7 +9,6 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import mortar.api.nms.NMP;
import ninja.bytecode.iris.controller.PackController;
import ninja.bytecode.iris.controller.TimingsController;
import ninja.bytecode.iris.generator.IrisGenerator;
import ninja.bytecode.iris.pack.IrisBiome;

View File

@ -1,5 +1,6 @@
package ninja.bytecode.iris;
import ninja.bytecode.iris.util.InterpolationType;
import ninja.bytecode.iris.util.PerformanceMode;
public class Settings
@ -22,6 +23,11 @@ public class Settings
public static class GeneratorSettings
{
public InterpolationType linearFunction = InterpolationType.BEZIER;
public InterpolationType bilinearFunction = InterpolationType.PARAMETRIC_2;
public InterpolationType trilinearFunction = InterpolationType.BEZIER;
public double linearSampleFractureMultiplier = 11.4;
public double linearSampleFractureScale = 0.21;
public double horizontalZoom = 1; // 0.525
public double heightFracture = 155;
public double beachScale = 76;
@ -35,13 +41,16 @@ public class Settings
public double superHeightScale = 0.95;
public double baseHeight = 0.165;
public int seaLevel = 63;
public double caveDensity = 0;
public double caveDensity = 4;
public double caveScale = 1.45;
public double biomeScale = 2;
public boolean flatBedrock = false;
public boolean genObjects = true;
public double carvingChance = 0.352;
public double cavernChance = 0.321;
public int minCarvingHeight = 75;
public int maxCarvingHeight = 155;
public double carvingChance = 0.6;
public int minCavernHeight = 14;
public int maxCavernHeight = 54;
}
}

View File

@ -8,7 +8,7 @@ import ninja.bytecode.shuriken.collections.GMap;
import ninja.bytecode.shuriken.execution.TaskExecutor;
public class ExecutionController implements IrisController
{
{
GMap<String, TaskExecutor> executors;
@Override

View File

@ -1,16 +1,10 @@
package ninja.bytecode.iris.controller;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import mortar.logic.queue.ChronoLatch;
import net.md_5.bungee.api.ChatColor;
import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.generator.genobject.GenObject;
@ -28,7 +22,6 @@ import ninja.bytecode.shuriken.execution.TaskExecutor;
import ninja.bytecode.shuriken.execution.TaskExecutor.TaskGroup;
import ninja.bytecode.shuriken.format.F;
import ninja.bytecode.shuriken.io.IO;
import ninja.bytecode.shuriken.io.VoidOutputStream;
import ninja.bytecode.shuriken.json.JSONException;
import ninja.bytecode.shuriken.json.JSONObject;
import ninja.bytecode.shuriken.logging.L;
@ -39,7 +32,6 @@ public class PackController implements IrisController
private GMap<String, IrisDimension> dimensions;
private GMap<String, IrisBiome> biomes;
private GMap<String, GenObjectGroup> genObjectGroups;
private ChronoLatch ll = new ChronoLatch(3000);
private boolean ready;
@Override

View File

@ -16,6 +16,7 @@ import ninja.bytecode.iris.generator.genobject.GenObjectGroup;
import ninja.bytecode.iris.generator.layer.GenLayerBase;
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.GenLayerLayeredNoise;
import ninja.bytecode.iris.generator.layer.GenLayerRidge;
@ -30,6 +31,7 @@ import ninja.bytecode.iris.util.ParallelChunkGenerator;
import ninja.bytecode.shuriken.collections.GList;
import ninja.bytecode.shuriken.collections.GMap;
import ninja.bytecode.shuriken.logging.L;
import ninja.bytecode.shuriken.math.CNG;
import ninja.bytecode.shuriken.math.M;
import ninja.bytecode.shuriken.math.RNG;
@ -63,8 +65,10 @@ public class IrisGenerator extends ParallelChunkGenerator
private GenLayerBiome glBiome;
private GenLayerCaves glCaves;
private GenLayerCarving glCarving;
private GenLayerCaverns glCaverns;
private GenLayerSnow glSnow;
private RNG rTerrain;
private CNG lerpf;
private CompiledDimension dim;
private World world;
private GMap<String, GenObjectGroup> schematicCache = new GMap<>();
@ -87,7 +91,7 @@ public class IrisGenerator extends ParallelChunkGenerator
if(j.getName().equals(i.getName()))
{
internal.remove(j);
L.i(ChatColor.LIGHT_PURPLE + "Internal Biome: " + ChatColor.WHITE+ j.getName() + ChatColor.LIGHT_PURPLE + " overwritten by dimension " + ChatColor.WHITE + dim.getName());
L.i(ChatColor.LIGHT_PURPLE + "Internal Biome: " + ChatColor.WHITE + j.getName() + ChatColor.LIGHT_PURPLE + " overwritten by dimension " + ChatColor.WHITE + dim.getName());
}
}
}
@ -110,12 +114,14 @@ public class IrisGenerator extends ParallelChunkGenerator
{
this.world = world;
rTerrain = new RNG(world.getSeed() + 1024);
lerpf = new CNG(rTerrain.nextParallelRNG(-10000), 1D, 2).scale(Iris.settings.gen.linearSampleFractureScale);
glBase = new GenLayerBase(this, world, random, rTerrain.nextParallelRNG(1));
glLNoise = new GenLayerLayeredNoise(this, world, random, rTerrain.nextParallelRNG(2));
glRidge = new GenLayerRidge(this, world, random, rTerrain.nextParallelRNG(3));
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));
}
@ -140,17 +146,24 @@ public class IrisGenerator extends ParallelChunkGenerator
@Override
public Biome genColumn(int wxx, int wzx, int x, int z, ChunkPlan plan)
{
//@builder
int highest = 0;
int seaLevel = Iris.settings.gen.seaLevel;
double wx = Math.round((double) wxx * Iris.settings.gen.horizontalZoom);
double wz = Math.round((double) wzx * Iris.settings.gen.horizontalZoom);
IrisBiome biome = getBiome(wxx, wzx);
double hv = IrisInterpolation.getBicubicNoise(wxx, wzx, (xf, zf) -> getBiomedHeight((int) Math.round(xf), (int) Math.round(zf), plan));
double hv = IrisInterpolation.getNoise(wxx, wzx,
(xf, zf) -> getBiomedHeight((int) Math.round(xf), (int) Math.round(zf), plan),
(a, b) -> lerpf.noise(a, b),
Iris.settings.gen.linearFunction,
Iris.settings.gen.bilinearFunction,
Iris.settings.gen.trilinearFunction);
hv += glLNoise.generateLayer(hv * Iris.settings.gen.roughness * 215, wxx * Iris.settings.gen.roughness * 0.82, wzx * Iris.settings.gen.roughness * 0.82) * (1.6918 * (hv * 2.35));
hv -= glRidge.generateLayer(hv, wxx, wzx);
int height = (int) Math.round(M.clip(hv, 0D, 1D) * 253);
int max = Math.max(height, seaLevel);
IrisBiome override = null;
//@done
if(height > 61 && height < 65 + (glLNoise.getHeight(wz, wx) * Iris.settings.gen.beachScale))
{
@ -245,6 +258,7 @@ public class IrisGenerator extends ParallelChunkGenerator
glCaves.genCaves(wxx, wzx, x, z, height, this);
glCarving.genCarves(wxx, wzx, x, z, height, this, biome);
glCaverns.genCaverns(wxx, wzx, x, z, height, this, biome);
plan.setRealHeight(x, z, highest);
return biome.getRealBiome();
}

View File

@ -12,7 +12,6 @@ import org.bukkit.generator.BlockPopulator;
import net.md_5.bungee.api.ChatColor;
import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.controller.PackController;
import ninja.bytecode.iris.controller.TimingsController;
import ninja.bytecode.iris.generator.IrisGenerator;
import ninja.bytecode.iris.generator.placer.BukkitPlacer;
@ -27,7 +26,6 @@ import ninja.bytecode.shuriken.math.M;
public class GenObjectDecorator extends BlockPopulator
{
private GMap<String, GenObjectGroup> snowCache;
private GMap<Biome, IrisBiome> biomeMap;
private GMap<Biome, GMap<GenObjectGroup, Double>> populationCache;
private IPlacer placer;
@ -37,7 +35,6 @@ public class GenObjectDecorator extends BlockPopulator
{
biomeMap = new GMap<>();
populationCache = new GMap<>();
snowCache = new GMap<>();
for(IrisBiome i : generator.getLoadedBiomes())
{

View File

@ -1,7 +1,5 @@
package ninja.bytecode.iris.generator.genobject;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;

View File

@ -17,33 +17,22 @@ import ninja.bytecode.shuriken.math.RNG;
public class GenLayerCarving extends GenLayer
{
public CNG carver;
public CNG clipper;
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, 3)
.scale(0.0285)
carver = new CNG(rng.nextParallelRNG(116), 1D, 7)
.scale(0.0057)
.amp(0.5)
.freq(1.1)
.fractureWith(new CNG(rng.nextParallelRNG(18), 1, 3)
.scale(0.005)
.child(new CNG(rng.nextParallelRNG(19), 0.745, 2)
.scale(0.1))
.fractureWith(new CNG(rng.nextParallelRNG(20), 1, 3)
.scale(0.08), 12), 33);
clipper = new CNG(rng.nextParallelRNG(117), 1D, 1)
.scale(0.0009)
.amp(0.0)
.freq(1.1)
.fractureWith(new CNG(rng.nextParallelRNG(18), 1, 3)
.scale(0.005)
.child(new CNG(rng.nextParallelRNG(19), 0.745, 2)
.scale(0.1))
.fractureWith(new CNG(rng.nextParallelRNG(20), 1, 3)
.scale(0.08), 12), 33);
.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
}
@ -66,6 +55,19 @@ public class GenLayerCarving extends GenLayer
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)
{
if(s < Iris.settings.gen.minCarvingHeight)
@ -73,25 +75,30 @@ public class GenLayerCarving extends GenLayer
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--)
{
if(clipper.noise(wzx, i, wxx) < Iris.settings.gen.carvingChance)
double hill = getHill(i);
if(hill < 0.065)
{
double hill = getHill(i);
continue;
}
if(hill < 0.065)
{
continue;
}
if(carver.noise(wxx, i, wzx) < IrisInterpolation.lerpBezier(0.01, 0.425, hill))
{
carved++;
g.setBlock(x, i, z, Material.AIR);
}
if(carve(wxx, i, wzx) < IrisInterpolation.lerpBezier(0, ch, hill))
{
carved++;
g.setBlock(x, i, z, Material.AIR);
}
}

View File

@ -0,0 +1,172 @@
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.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)
{
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++;
g.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 = g.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(g.getType(x, j, z).equals(Material.AIR))
{
fail = true;
break;
}
}
}
if(!fail)
{
MB mb = biome.getSurface(wxx, wzx, g.getRTerrain());
g.setBlock(x, i, z, mb.material, mb.data);
}
else
{
g.setBlock(x, i, z, Material.AIR);
}
}
else if(hit > 1 && hit < g.getGlBase().scatterInt(x, i, z, 4) + 3)
{
if(!fail)
{
MB mb = biome.getDirtRNG();
g.setBlock(x, i, z, mb.material, mb.data);
}
else
{
g.setBlock(x, i, z, Material.AIR);
}
}
}
else
{
hit = 0;
}
}
}
}
@Override
public double generateLayer(double gnoise, double dx, double dz)
{
return gnoise;
}
}

View File

@ -22,10 +22,10 @@ public class GenLayerCaves extends GenLayer
public GenLayerCaves(IrisGenerator iris, World world, Random random, RNG rng)
{
super(iris, world, random, rng);
caveHeight = new CNG(rng.nextParallelRNG(-100001), 1D, 7).scale(0.00222);
caveGirth = new CNG(rng.nextParallelRNG(-100002), 1D, 12).scale(0.03);
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 MaxingGenerator(rng.nextParallelRNG(-99999), 22, 0.002 * Iris.settings.gen.caveScale, 1, (g) -> g.fractureWith(new CNG(rng.nextParallelRNG(-5555), 1D, 4).scale(0.02), 70));
caveVeins = new MaxingGenerator(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)

View File

@ -14,17 +14,17 @@ public class GenLayerFracture extends GenLayer
{
private CNG gen;
private CNG cond;
private double shootHeight = 0.563;
private double shootHeight = 0.963;
public GenLayerFracture(IrisGenerator iris, World world, Random random, RNG rng)
{
//@builder
super(iris, world, random, rng);
gen = new CNG(rng.nextParallelRNG(40), 1D, 12)
gen = new CNG(rng.nextParallelRNG(40), 1D, 2)
.scale(0.023)
.fractureWith(new CNG(rng.nextParallelRNG(41), 1D, 1)
.scale(0.05), 333);
cond = new CNG(rng.nextParallelRNG(42), 1D, 12)
cond = new CNG(rng.nextParallelRNG(42), 1D, 2)
.scale(0.038)
.fractureWith(new CNG(rng.nextParallelRNG(43), 1D, 1)
.scale(0.025), 299);

View File

@ -19,7 +19,7 @@ public enum Direction
S(0, 0, 1, CuboidDirection.South),
E(1, 0, 0, CuboidDirection.East),
W(-1, 0, 0, CuboidDirection.West);
private static GMap<GBiset<Direction, Direction>, DOP> permute = null;
private int x;

View File

@ -0,0 +1,11 @@
package ninja.bytecode.iris.util;
public enum InterpolationType
{
LINEAR,
PARAMETRIC_2,
PARAMETRIC_4,
PARAMETRIC_NH,
BEZIER,
NONE;
}

View File

@ -1,68 +1,101 @@
package ninja.bytecode.iris.util;
import ninja.bytecode.iris.Iris;
import ninja.bytecode.shuriken.math.M;
public class IrisInterpolation
{
public static double bezier(double t)
{
return t * t * (3.0d - 2.0d * t);
return t * t * (3.0d - 2.0d * t);
}
public static double parametric(double t, double alpha)
{
double sqt = Math.pow(t, alpha);
return sqt / (alpha * (sqt - Math.pow(t, alpha - 1)) + 1.0d);
double sqt = Math.pow(t, alpha);
return sqt / (alpha * (sqt - Math.pow(t, alpha - 1)) + 1.0d);
}
public static double lerp(double a, double b, double f)
{
return a + (f * (b - a));
}
public static double lerpBezier(double a, double b, double f)
{
return a + (bezier(f) * (b - a));
}
public static double lerpParametric(double a, double b, double f, double v)
{
return a + (parametric(f, v) * (b - a));
}
public static double blerp(double a, double b, double c, double d, double tx, double ty)
{
return lerp(lerp(a, b, tx), lerp(c, d, tx), ty);
}
public static double blerp(double a, double b, double c, double d, double tx, double ty, InterpolationType type)
{
if(type.equals(InterpolationType.LINEAR))
{
return blerp(a, b, c, d, tx, ty);
}
if(type.equals(InterpolationType.BEZIER))
{
return blerpBezier(a, b, c, d, tx, ty);
}
if(type.equals(InterpolationType.PARAMETRIC_2))
{
return blerpParametric(a, b, c, d, tx, ty, 2);
}
if(type.equals(InterpolationType.PARAMETRIC_4))
{
return blerpParametric(a, b, c, d, tx, ty, 4);
}
if(type.equals(InterpolationType.PARAMETRIC_NH))
{
return blerpParametric(a, b, c, d, tx, ty, -0.5);
}
return 0;
}
public static double blerpBezier(double a, double b, double c, double d, double tx, double ty)
{
return lerpBezier(lerpBezier(a, b, tx), lerpBezier(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);
}
public static double getLinearNoise(int x, int z, NoiseProvider n)
public static double getLinearNoise(int x, int z, NoiseProvider n, NoiseProvider f, InterpolationType type)
{
int h = 29;
int xa = x - h;
int za = z - h;
int xb = x + h;
int zb = z + h;
double na = n.noise(xa, za);
double nb = n.noise(xa, zb);
double nc = n.noise(xb, za);
double nd = n.noise(xb, zb);
double hfx = f.noise(x, z) * Iris.settings.gen.linearSampleFractureMultiplier;
double hfz = f.noise(z, x) * Iris.settings.gen.linearSampleFractureMultiplier;
double na = n.noise(xa + hfx, za + hfz);
double nb = n.noise(xa + hfx, zb - hfz);
double nc = n.noise(xb - hfx, za + hfz);
double nd = n.noise(xb - hfx, zb - hfz);
double px = M.rangeScale(0, 1, xa, xb, x);
double pz = M.rangeScale(0, 1, za, zb, z);
return blerpBezier(na, nc, nb, nd, px, pz);
return blerp(na, nc, nb, nd, px, pz, type);
}
public static double getBilinearNoise(int x, int z, NoiseProvider n)
public static double getBilinearNoise(int x, int z, NoiseProvider n, NoiseProvider f, InterpolationType linear, InterpolationType bilinear)
{
int h = 1;
int fx = x >> h;
@ -71,17 +104,17 @@ public class IrisInterpolation
int za = (fz << h) - 15;
int xb = ((fx + 1) << h) + 15;
int zb = ((fz + 1) << h) + 15;
double na = getLinearNoise(xa, za, n);
double nb = getLinearNoise(xa, zb, n);
double nc = getLinearNoise(xb, za, n);
double nd = getLinearNoise(xb, zb, n);
double na = getLinearNoise(xa, za, n, f, linear);
double nb = getLinearNoise(xa, zb, n, f, linear);
double nc = getLinearNoise(xb, za, n, f, linear);
double nd = getLinearNoise(xb, zb, n, f, linear);
double px = M.rangeScale(0, 1, xa, xb, x);
double pz = M.rangeScale(0, 1, za, zb, z);
return blerpBezier(na, nc, nb, nd, px, pz);
return blerp(na, nc, nb, nd, px, pz, bilinear);
}
public static double getBicubicNoise(int x, int z, NoiseProvider n)
public static double getTrilinearNoise(int x, int z, NoiseProvider n, NoiseProvider f, InterpolationType linear, InterpolationType bilinear, InterpolationType trilinear)
{
int h = 6;
int fx = x >> h;
@ -90,13 +123,36 @@ public class IrisInterpolation
int za = (fz << h);
int xb = ((fx + 1) << h);
int zb = ((fz + 1) << h);
double na = getBilinearNoise(xa, za, n);
double nb = getBilinearNoise(xa, zb, n);
double nc = getBilinearNoise(xb, za, n);
double nd = getBilinearNoise(xb, zb, n);
double na = getBilinearNoise(xa, za, n, f, linear, bilinear);
double nb = getBilinearNoise(xa, zb, n, f, linear, bilinear);
double nc = getBilinearNoise(xb, za, n, f, linear, bilinear);
double nd = getBilinearNoise(xb, zb, n, f, linear, bilinear);
double px = M.rangeScale(0, 1, xa, xb, x);
double pz = M.rangeScale(0, 1, za, zb, z);
return blerpBezier(na, nc, nb, nd, px, pz);
return blerp(na, nc, nb, nd, px, pz, trilinear);
}
public static double getNoise(int x, int z, NoiseProvider n, NoiseProvider fli, InterpolationType linear, InterpolationType bilinear, InterpolationType trilinear)
{
if(linear.equals(InterpolationType.NONE))
{
return n.noise(x, z);
}
else if(bilinear.equals(InterpolationType.NONE))
{
return getLinearNoise(x, z, n, fli, linear);
}
else if(trilinear.equals(InterpolationType.NONE))
{
return getBilinearNoise(x, z, n, fli, linear, bilinear);
}
else
{
return getTrilinearNoise(x, z, n, fli, linear, bilinear, trilinear);
}
}
}