mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-26 14:00:26 +00:00
Guarded nested corner blocks
- Fell back to per-group grid sampling when a height sample nests inside another on the same thread - Covered nested sampling with a bit-exact parity test
This commit is contained in:
1 parent
b03f1c90e1
commit
ab468a198d
2 files changed
+58
-2
No files matched your search
@@ -1896,14 +1896,24 @@ public class IrisComplex implements DataProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int grid = biomeBoundsSamplingStep;
|
int grid = biomeBoundsSamplingStep;
|
||||||
if (!ChunkCorners.supports(grid)) {
|
GridBoundsCache cache = gridBoundsCache.get();
|
||||||
|
if (!ChunkCorners.supports(grid) || cache.cornersInUse) {
|
||||||
for (int interpolatorIndex = 0; interpolatorIndex < frozenInterpolators.length; interpolatorIndex++) {
|
for (int interpolatorIndex = 0; interpolatorIndex < frozenInterpolators.length; interpolatorIndex++) {
|
||||||
h += interpolateGenerators(engine, frozenInterpolators[interpolatorIndex], interpolatorIndex, frozenGenerators[interpolatorIndex], x, z, seed);
|
h += interpolateGenerators(engine, frozenInterpolators[interpolatorIndex], interpolatorIndex, frozenGenerators[interpolatorIndex], x, z, seed);
|
||||||
}
|
}
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
GridBoundsCache cache = gridBoundsCache.get();
|
cache.cornersInUse = true;
|
||||||
|
try {
|
||||||
|
return cornerBlockHeight(cache, engine, grid, x, z, seed);
|
||||||
|
} finally {
|
||||||
|
cache.cornersInUse = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private double cornerBlockHeight(GridBoundsCache cache, Engine engine, int grid, double x, double z, long seed) {
|
||||||
|
double h = 0;
|
||||||
int xi = (int) Math.floor(x);
|
int xi = (int) Math.floor(x);
|
||||||
int zi = (int) Math.floor(z);
|
int zi = (int) Math.floor(z);
|
||||||
int gx = xi & ~(grid - 1);
|
int gx = xi & ~(grid - 1);
|
||||||
@@ -2343,6 +2353,7 @@ public class IrisComplex implements DataProvider {
|
|||||||
private final BoundsSampler sampler = new BoundsSampler();
|
private final BoundsSampler sampler = new BoundsSampler();
|
||||||
private ChunkCorners recentCorners;
|
private ChunkCorners recentCorners;
|
||||||
private ChunkCorners previousCorners;
|
private ChunkCorners previousCorners;
|
||||||
|
private boolean cornersInUse;
|
||||||
|
|
||||||
private ChunkCorners chunkCorners(int chunkX, int chunkZ, int groups, int grid) {
|
private ChunkCorners chunkCorners(int chunkX, int chunkZ, int groups, int grid) {
|
||||||
ChunkCorners recent = recentCorners;
|
ChunkCorners recent = recentCorners;
|
||||||
|
|||||||
+45
@@ -88,6 +88,24 @@ public class IrisComplexChunkCornersTest {
|
|||||||
assertEquals(40, counting.calls);
|
assertEquals(40, counting.calls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void nestedHeightSamplesLeaveTheOuterChunkBlockIntact() throws Exception {
|
||||||
|
ReentrantGenerator reentrant = new ReentrantGenerator();
|
||||||
|
IrisInterpolator[] interpolators = {new ZeroFreeInterpolator(), new PatchInterpolator(4, -2D)};
|
||||||
|
IrisGenerator[][] generators = {{reentrant}, {new WaveGenerator(0.5D)}};
|
||||||
|
IrisComplex candidate = createComplex(4, interpolators, generators);
|
||||||
|
IrisComplex reference = createComplex(4, interpolators, generators);
|
||||||
|
SplittableRandom random = new SplittableRandom(99L);
|
||||||
|
for (int sample = 0; sample < 4_000; sample++) {
|
||||||
|
double x = coordinate(random);
|
||||||
|
double z = coordinate(random);
|
||||||
|
reentrant.target = reference;
|
||||||
|
double expected = expectedHeight(reference, interpolators, generators, x, z);
|
||||||
|
reentrant.target = candidate;
|
||||||
|
assertEquals(Double.doubleToRawLongBits(expected), Double.doubleToRawLongBits(interpolatedHeight(candidate, x, z)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void nonFiniteCornersFailTheSameWayAndAreRetried() throws Exception {
|
public void nonFiniteCornersFailTheSameWayAndAreRetried() throws Exception {
|
||||||
NaNCornerInterpolator interpolator = new NaNCornerInterpolator();
|
NaNCornerInterpolator interpolator = new NaNCornerInterpolator();
|
||||||
@@ -191,6 +209,13 @@ public class IrisComplexChunkCornersTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class ZeroFreeInterpolator extends IrisInterpolator {
|
||||||
|
@Override
|
||||||
|
public NoiseBounds interpolateBounds(double x, double z, NoiseBoundsProvider provider) {
|
||||||
|
return new NoiseBounds(x * 0.01D - 1D, z * 0.01D + 3D);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final class ZeroInterpolator extends IrisInterpolator {
|
private static final class ZeroInterpolator extends IrisInterpolator {
|
||||||
private final boolean negative;
|
private final boolean negative;
|
||||||
|
|
||||||
@@ -227,6 +252,26 @@ public class IrisComplexChunkCornersTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class ReentrantGenerator extends IrisGenerator {
|
||||||
|
private IrisComplex target;
|
||||||
|
private boolean nested;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getHeight(double x, double z, long seed) {
|
||||||
|
if (nested) {
|
||||||
|
return Math.cos(x * 0.13D) * 0.5D;
|
||||||
|
}
|
||||||
|
nested = true;
|
||||||
|
try {
|
||||||
|
return (interpolatedHeight(target, x + 4099D, z - 2053D) + interpolatedHeight(target, x - 8191D, z + 1031D)) * 0.001D;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
} finally {
|
||||||
|
nested = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final class WaveGenerator extends IrisGenerator {
|
private static final class WaveGenerator extends IrisGenerator {
|
||||||
private final double amplitude;
|
private final double amplitude;
|
||||||
private int invocations;
|
private int invocations;
|
||||||
|
|||||||
Reference in new issue
Block a user