diff --git a/core/src/main/java/com/boydti/fawe/object/collection/LocalBlockVectorSet.java b/core/src/main/java/com/boydti/fawe/object/collection/LocalBlockVectorSet.java index b5700da3..35fab081 100644 --- a/core/src/main/java/com/boydti/fawe/object/collection/LocalBlockVectorSet.java +++ b/core/src/main/java/com/boydti/fawe/object/collection/LocalBlockVectorSet.java @@ -210,7 +210,7 @@ public class LocalBlockVectorSet implements Set { if (relX > 1023 || relX < -1024 || relZ > 1023 || relZ < -1024) { throw new UnsupportedOperationException("LocalVectorSet can only contain vectors within 1024 blocks (cuboid) of the first entry. "); } - if (y < 0 || y > 256) { + if (y < 0 || y > 255) { throw new UnsupportedOperationException("LocalVectorSet can only contain vectors from y elem:[0,255]"); } int index = getIndex(x, y, z); diff --git a/core/src/main/java/com/boydti/fawe/object/mask/AngleMask.java b/core/src/main/java/com/boydti/fawe/object/mask/AngleMask.java index a3a40603..3a0e5742 100644 --- a/core/src/main/java/com/boydti/fawe/object/mask/AngleMask.java +++ b/core/src/main/java/com/boydti/fawe/object/mask/AngleMask.java @@ -16,6 +16,7 @@ public class AngleMask extends SolidBlockMask implements ResettableMask { private final double max; private final double min; private final boolean overlay; + private final boolean checkFirst; private int maxY; private transient MutableBlockVector mutable = new MutableBlockVector(); @@ -25,6 +26,7 @@ public class AngleMask extends SolidBlockMask implements ResettableMask { this.mask = new CachedMask(new SolidBlockMask(extent)); this.min = min; this.max = max; + this.checkFirst = max >= (Math.tan(90 * (Math.PI / 180))); this.maxY = extent.getMaximumPoint().getBlockY(); this.overlay = overlay; } @@ -36,6 +38,7 @@ public class AngleMask extends SolidBlockMask implements ResettableMask { cacheBotZ = Integer.MIN_VALUE; lastX = Integer.MIN_VALUE; lastX = Integer.MIN_VALUE; + lastY = Integer.MIN_VALUE; if (cacheHeights != null) { Arrays.fill(cacheHeights, (byte) 0); } @@ -48,7 +51,6 @@ public class AngleMask extends SolidBlockMask implements ResettableMask { private transient int cacheCenterZ; private transient byte[] cacheHeights; - private transient byte[] cacheDistance; private transient int lastY; private transient int lastX = Integer.MIN_VALUE; @@ -70,19 +72,15 @@ public class AngleMask extends SolidBlockMask implements ResettableMask { index = rx + (rz << 8); if (cacheHeights == null) { cacheHeights = new byte[65536]; - cacheDistance = new byte[65536]; } else { Arrays.fill(cacheHeights, (byte) 0); - Arrays.fill(cacheDistance, (byte) 0); } } else { index = rx + (rz << 8); } int result = cacheHeights[index] & 0xFF; - int distance = cacheDistance[index] & 0xFF; - if (result == 0 || distance < Math.abs(result - y)) { + if (y > result) { cacheHeights[index] = (byte) (result = lastY = getExtent().getNearestSurfaceTerrainBlock(x, z, lastY, 0, maxY)); - cacheDistance[index] = (byte) Math.abs(result - y); } return result; } catch (Throwable e) { @@ -94,17 +92,22 @@ public class AngleMask extends SolidBlockMask implements ResettableMask { private boolean testSlope(int x, int y, int z) { double slope; boolean aboveMin; - if ((lastX == (lastX = x) & lastZ == (lastZ = z))) { - return lastValue; - } + lastY = y; slope = Math.abs(getHeight(x + 1, y, z) - getHeight(x - 1, y, z)) * ADJACENT_MOD; - if (slope >= min && max >= Math.max(maxY - y, y)) { - return lastValue = true; + if (checkFirst) { + if (slope >= min) { + return lastValue = true; + } + slope = Math.max(slope, Math.abs(getHeight(x, y, z + 1) - getHeight(x, y, z - 1)) * ADJACENT_MOD); + slope = Math.max(slope, Math.abs(getHeight(x + 1, y, z + 1) - getHeight(x - 1, y, z - 1)) * DIAGONAL_MOD); + slope = Math.max(slope, Math.abs(getHeight(x - 1, y, z + 1) - getHeight(x + 1, y, z - 1)) * DIAGONAL_MOD); + return lastValue = (slope >= min); + } else { + slope = Math.max(slope, Math.abs(getHeight(x, y, z + 1) - getHeight(x, y, z - 1)) * ADJACENT_MOD); + slope = Math.max(slope, Math.abs(getHeight(x + 1, y, z + 1) - getHeight(x - 1, y, z - 1)) * DIAGONAL_MOD); + slope = Math.max(slope, Math.abs(getHeight(x - 1, y, z + 1) - getHeight(x + 1, y, z - 1)) * DIAGONAL_MOD); + return lastValue = (slope >= min && slope <= max); } - slope = Math.max(slope, Math.abs(getHeight(x, y, z + 1) - getHeight(x, y, z - 1)) * ADJACENT_MOD); - slope = Math.max(slope, Math.abs(getHeight(x + 1, y, z + 1) - getHeight(x - 1, y, z - 1)) * DIAGONAL_MOD); - slope = Math.max(slope, Math.abs(getHeight(x - 1, y, z + 1) - getHeight(x + 1, y, z - 1)) * DIAGONAL_MOD); - return lastValue = (slope >= min && slope <= max); } public boolean adjacentAir(Vector v) { @@ -137,6 +140,12 @@ public class AngleMask extends SolidBlockMask implements ResettableMask { int x = vector.getBlockX(); int y = vector.getBlockY(); int z = vector.getBlockZ(); + + if ((lastX == (lastX = x) & lastZ == (lastZ = z))) { + int height = getHeight(x, y, z); + if (y <= height) return overlay ? (lastValue && y == height) : lastValue; + } + if (!mask.test(x, y, z)) { return false; } diff --git a/core/src/main/java/com/boydti/fawe/object/mask/CachedMask.java b/core/src/main/java/com/boydti/fawe/object/mask/CachedMask.java index 37408201..05da2402 100644 --- a/core/src/main/java/com/boydti/fawe/object/mask/CachedMask.java +++ b/core/src/main/java/com/boydti/fawe/object/mask/CachedMask.java @@ -46,21 +46,23 @@ public class CachedMask extends AbstractDelegateMask implements ResettableMask { } public boolean test(int x, int y, int z) { - if (y < 0 || y > 255) return getMask().test(mutable.setComponents(x, y, z)); - if (cache_checked.contains(x, y, z)) { - return cache_results.contains(x, y, z); - } - boolean result = getMask().test(mutable.setComponents(x, y, z)); try { - cache_checked.add(x, y, z); + boolean check = cache_checked.add(x, y, z); + if (!check) { + return cache_results.contains(x, y, z); + } + boolean result = getMask().test(mutable.setComponents(x, y, z)); if (result) cache_results.add(x, y, z); + return result; } catch (UnsupportedOperationException ignore) { + boolean result = getMask().test(mutable.setComponents(x, y, z)); + if (y < 0 || y > 255) return result; resetCache(); cache_checked.setOffset(x, z); cache_results.setOffset(x, z); cache_checked.add(x, y, z); if (result) cache_results.add(x, y, z); + return result; } - return result; } }