Merge branch 'master' into 1.15

This commit is contained in:
gnembon committed 2020-01-24 15:06:49 -04:00
commit e2ceb90d13
2 files changed
+131 -20

No files matched your search

+41 -19
View File
@@ -2732,25 +2732,26 @@ public class Expression
* map(range(10), str('%.1f',rand(_))) => [0.0, 0.4, 0.6, 1.9, 2.8, 3.8, 5.3, 2.2, 1.6, 5.6]
* </pre>
*
* <h3><code>perlin(x), perlin(x,y), perlin(x,y,z), perlin(x,y,z,seed)</code></h3>
* <p>returns a noise value from <code>0.0</code> to <code>1.0</code> (roughly) for 1, 2 or 3 dimensional coordinate. The default seed it samples from is <code>0</code>, but seed can be
* <h3><code>perlin(x), perlin(x, y), perlin(x, y, z), perlin(x, y, z, seed)</code></h3>
* <p>returns a noise value from <code>0.0</code> to <code>1.0</code> (roughly) for 1, 2 or 3 dimensional coordinate.
* The default seed it samples from is <code>0</code>, but seed can be
* specified as a 4th argument as well. In case you need 1D or 2D noise values with custom seed, use <code>null</code>
* for <code>z</code>, or <code>y</code> and <code>z</code> arguments respectively.</p>
* <p> Perlin noise is based on a square grid and generates rougher maps comparing to Simplex, which is creamier,
* but the in-game implementation allows to sample up to 3D noise. Querying for lower-dimensional result, rather than
* <p> Perlin noise is based on a square grid and generates rougher maps comparing to Simplex, which is creamier.
* Querying for lower-dimensional result, rather than
* affixing unused dimensions to constants has a speed benefit,
* </p>
* <p>Thou shall not sample from noise changing seed frequently. Scarpet will keep track of the last 256 perlin seeds used for sampling
* providing similar speed comparing to the default seed of <code>0</code>. In case the app engine uses more than 256 seeds at the same time,
* switching between them can get much more expensive.</p>
*
* <h3><code>simplex(x,y), simplex(x,y,seed)</code></h3>
* <p>returns a noise value from <code>0.0</code> to <code>1.0</code> (roughly) for 2 dimensional coordinate.
* <h3><code>simplex(x, y), simplex(x, y, z), simplex(x, y, z, seed)</code></h3>
* <p>returns a noise value from <code>0.0</code> to <code>1.0</code> (roughly) for 2 or 3 dimensional coordinate.
* The default seed it samples from is <code>0</code>, but seed can be
* specified as a 3rd argument as well</p>
* <p> Simplex noise is based on a triangular grid and generates smoother maps comparing to Perlin,
* but the in-game implementation only allows to sample 2D noise. To sample 1D simplex noise, affix other coordinate
* to a constant.
* specified as a 4th argument as well. In case you need 2D noise values with custom seed, use <code>null</code>
* for <code>z</code> argument.</p>
* <p> Simplex noise is based on a triangular grid and generates smoother maps comparing to Perlin.
* To sample 1D simplex noise, affix other coordinate to a constant.
* </p>
* <p>Thou shall not sample from noise changing seed frequently. Scarpet will keep track of the last 256 simplex seeds used for sampling
* providing similar speed comparing to the default seed of <code>0</code>. In case the app engine uses more than 256 seeds at the same time,
@@ -3044,16 +3045,37 @@ public class Expression
addLazyFunction("simplex", -1, (c, t, lv) -> {
SimplexNoiseSampler sampler;
if (lv.size() == 2)
sampler = SimplexNoiseSampler.instance;
else if (lv.size() == 3)
sampler = SimplexNoiseSampler.getSimplex(NumericValue.asNumber(lv.get(2).evalValue(c)).getLong());
Value x, y, z;
if (lv.size() >= 4)
{
x = lv.get(0).evalValue(c);
y = lv.get(1).evalValue(c);
z = lv.get(2).evalValue(c);
sampler = SimplexNoiseSampler.getSimplex(NumericValue.asNumber(lv.get(3).evalValue(c)).getLong());
}
else
throw new InternalExpressionException("'simplex' requires two or three arguments");
double x = NumericValue.asNumber(lv.get(0).evalValue(c)).getDouble();
double y = NumericValue.asNumber(lv.get(1).evalValue(c)).getDouble();
Value value = new NumericValue(sampler.sample(x,y));
return (cc, tt) -> value;
{
sampler = SimplexNoiseSampler.instance;
z = Value.NULL;
if (lv.size() < 2 )
throw new InternalExpressionException("'simplex' requires at least two dimensions to sample from");
x = NumericValue.asNumber(lv.get(0).evalValue(c));
y = NumericValue.asNumber(lv.get(1).evalValue(c));
if (lv.size() > 2)
z = NumericValue.asNumber(lv.get(2).evalValue(c));
}
double result;
if (z instanceof NullValue)
result = sampler.sample2d(NumericValue.asNumber(x).getDouble(), NumericValue.asNumber(y).getDouble());
else
result = sampler.sample3d(
NumericValue.asNumber(x).getDouble(),
NumericValue.asNumber(y).getDouble(),
NumericValue.asNumber(z).getDouble());
Value ret = new NumericValue(result);
return (cc, tt) -> ret;
});
addUnaryFunction("print", (v) ->
@@ -38,7 +38,7 @@ public class SimplexNoiseSampler extends PerlinNoiseSampler {
return g;
}
public double sample(double x, double y) {
public double sample2d(double x, double y) {
double d = (x + y) * SKEW_FACTOR_2D;
int i = PerlinNoiseSampler.floor(x + d);
int j = PerlinNoiseSampler.floor(y + d);
@@ -73,6 +73,95 @@ public class SimplexNoiseSampler extends PerlinNoiseSampler {
return 35.0D * (aa + ab + ac)+0.5;
}
public double sample3d(double d, double e, double f) {
double g = 0.3333333333333333D;
double h = (d + e + f) * 0.3333333333333333D;
int i = floor(d + h);
int j = floor(e + h);
int k = floor(f + h);
double l = 0.16666666666666666D;
double m = (double)(i + j + k) * 0.16666666666666666D;
double n = (double)i - m;
double o = (double)j - m;
double p = (double)k - m;
double q = d - n;
double r = e - o;
double s = f - p;
byte z;
byte aa;
byte ab;
byte ac;
byte ad;
byte bc;
if (q >= r) {
if (r >= s) {
z = 1;
aa = 0;
ab = 0;
ac = 1;
ad = 1;
bc = 0;
} else if (q >= s) {
z = 1;
aa = 0;
ab = 0;
ac = 1;
ad = 0;
bc = 1;
} else {
z = 0;
aa = 0;
ab = 1;
ac = 1;
ad = 0;
bc = 1;
}
} else if (r < s) {
z = 0;
aa = 0;
ab = 1;
ac = 0;
ad = 1;
bc = 1;
} else if (q < s) {
z = 0;
aa = 1;
ab = 0;
ac = 0;
ad = 1;
bc = 1;
} else {
z = 0;
aa = 1;
ab = 0;
ac = 1;
ad = 1;
bc = 0;
}
double bd = q - (double)z + 0.16666666666666666D;
double be = r - (double)aa + 0.16666666666666666D;
double bf = s - (double)ab + 0.16666666666666666D;
double bg = q - (double)ac + 0.3333333333333333D;
double bh = r - (double)ad + 0.3333333333333333D;
double bi = s - (double)bc + 0.3333333333333333D;
double bj = q - 1.0D + 0.5D;
double bk = r - 1.0D + 0.5D;
double bl = s - 1.0D + 0.5D;
int bm = i & 255;
int bn = j & 255;
int bo = k & 255;
int bp = this.getGradient(bm + this.getGradient(bn + this.getGradient(bo))) % 12;
int bq = this.getGradient(bm + z + this.getGradient(bn + aa + this.getGradient(bo + ab))) % 12;
int br = this.getGradient(bm + ac + this.getGradient(bn + ad + this.getGradient(bo + bc))) % 12;
int bs = this.getGradient(bm + 1 + this.getGradient(bn + 1 + this.getGradient(bo + 1))) % 12;
double bt = this.grad(bp, q, r, s, 0.6D);
double bu = this.grad(bq, bd, be, bf, 0.6D);
double bv = this.grad(br, bg, bh, bi, 0.6D);
double bw = this.grad(bs, bj, bk, bl, 0.6D);
return 16.0D * (bt + bu + bv + bw) + 0.5;
}
static {
SKEW_FACTOR_2D = 0.5D * (sqrt3 - 1.0D);
UNSKEW_FACTOR_2D = (3.0D - sqrt3) / 6.0D;