From b6b6ba72658850ef7bfd7d83ddb7e995bac828e5 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Sun, 12 Sep 2021 12:36:32 +0100 Subject: [PATCH] Improve CachedMask a bit - no need to unwrap/wrap blockvectors, allow extents to be parsed (cherry picked from commit 41c0ea98f16ecbfadced41e4be277ad6ceda6b1a) --- .../core/function/mask/AdjacentAnyMask.java | 12 ++-- .../core/function/mask/AngleMask.java | 61 +++++++++---------- .../core/function/mask/CachedMask.java | 59 ++++++++++++------ .../core/function/mask/SurfaceMask.java | 2 +- 4 files changed, 76 insertions(+), 58 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/AdjacentAnyMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/AdjacentAnyMask.java index a72150d65..43aaed3dc 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/AdjacentAnyMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/AdjacentAnyMask.java @@ -40,17 +40,17 @@ public class AdjacentAnyMask extends AbstractMask implements ResettableMask { int x = v.getBlockX(); int y = v.getBlockY(); int z = v.getBlockZ(); - if (mask.test(x + 1, y, z)) { + if (mask.test(mutable.setComponents(x + 1, y, z))) { return mutable.setComponents(1, 0, 0); - } else if (mask.test(x - 1, y, z)) { + } else if (mask.test(mutable.setComponents(x - 1, y, z))) { return mutable.setComponents(-1, 0, 0); - } else if (mask.test(x, y, z + 1)) { + } else if (mask.test(mutable.setComponents(x, y, z + 1))) { return mutable.setComponents(0, 0, 1); - } else if (mask.test(x, y, z - 1)) { + } else if (mask.test(mutable.setComponents(x, y, z - 1))) { return mutable.setComponents(0, 0, -1); - } else if (y < maxY && mask.test(x, y + 1, z)) { + } else if (y < maxY && mask.test(mutable.setComponents(x, y + 1, z))) { return mutable.setComponents(0, 1, 0); - } else if (y > minY && mask.test(x, y - 1, z)) { + } else if (y > minY && mask.test(mutable.setComponents(x, y - 1, z))) { return mutable.setComponents(0, -1, 0); } else { return null; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/AngleMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/AngleMask.java index cb124b843..cdb370e62 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/AngleMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/AngleMask.java @@ -1,6 +1,8 @@ package com.fastasyncworldedit.core.function.mask; +import com.fastasyncworldedit.core.math.MutableBlockVector3; import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.function.mask.AbstractExtentMask; import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.SolidBlockMask; import com.sk89q.worldedit.math.BlockVector3; @@ -9,8 +11,8 @@ import java.util.Arrays; public class AngleMask extends SolidBlockMask implements ResettableMask { - public static double ADJACENT_MOD = 0.5; - public static double DIAGONAL_MOD = 1 / Math.sqrt(8); + protected static double ADJACENT_MOD = 0.5; + protected static double DIAGONAL_MOD = 1 / Math.sqrt(8); protected final CachedMask mask; protected final double max; @@ -20,6 +22,13 @@ public class AngleMask extends SolidBlockMask implements ResettableMask { protected final int maxY; protected final int minY; protected final int distance; + protected transient int cacheBotX = Integer.MIN_VALUE; + protected transient int cacheBotZ = Integer.MIN_VALUE; + protected transient byte[] cacheHeights; + protected transient int lastY; + protected transient int lastX = Integer.MIN_VALUE; + protected transient int lastZ = Integer.MIN_VALUE; + protected transient boolean lastValue; public AngleMask(Extent extent, double min, double max, boolean overlay, int distance) { super(extent); @@ -39,26 +48,13 @@ public class AngleMask extends SolidBlockMask implements ResettableMask { cacheBotZ = Integer.MIN_VALUE; lastX = Integer.MIN_VALUE; lastY = Integer.MIN_VALUE; + lastZ = Integer.MIN_VALUE; if (cacheHeights != null) { Arrays.fill(cacheHeights, (byte) 0); } } - protected transient int cacheCenZ; - protected transient int cacheBotX = Integer.MIN_VALUE; - protected transient int cacheBotZ = Integer.MIN_VALUE; - protected transient int cacheCenterZ; - - protected transient byte[] cacheHeights; - - protected transient int lastY; - protected transient int lastX = Integer.MIN_VALUE; - protected transient int lastZ = Integer.MIN_VALUE; - protected transient boolean foundY; - protected transient boolean lastValue; - - public int getHeight(Extent extent, int x, int y, int z) { - // return extent.getNearestSurfaceTerrainBlock(x, z, y, 0, maxY); + protected int getHeight(Extent extent, int x, int y, int z) { int rx = x - cacheBotX + 16; int rz = z - cacheBotZ + 16; int index; @@ -85,7 +81,6 @@ public class AngleMask extends SolidBlockMask implements ResettableMask { protected boolean testSlope(Extent extent, int x, int y, int z) { double slope; - boolean aboveMin; lastY = y; slope = Math.abs(getHeight(extent, x + distance, y, z) - getHeight(extent, x - distance, y, z)) @@ -122,26 +117,26 @@ public class AngleMask extends SolidBlockMask implements ResettableMask { } } - public boolean adjacentAir(BlockVector3 v) { - int x = v.getBlockX(); - int y = v.getBlockY(); - int z = v.getBlockZ(); - if (!mask.test(x + 1, y, z)) { + private boolean adjacentAir(Extent extent, MutableBlockVector3 mutable) { + int x = mutable.getBlockX(); + int y = mutable.getBlockY(); + int z = mutable.getBlockZ(); + if (!mask.test(extent, mutable.setComponents(x + 1, y, z))) { return true; } - if (!mask.test(x - 1, y, z)) { + if (!mask.test(extent, mutable.setComponents(x - 1, y, z))) { return true; } - if (!mask.test(x, y, z + 1)) { + if (!mask.test(extent, mutable.setComponents(x, y, z + 1))) { return true; } - if (!mask.test(x, y, z - 1)) { + if (!mask.test(extent, mutable.setComponents(x, y, z - 1))) { return true; } - if (y < maxY && !mask.test(x, y + 1, z)) { + if (y != maxY && !mask.test(extent, mutable.setComponents(x, y + 1, z))) { return true; } - return y > minY && !mask.test(x, y - 1, z); + return y != minY && !mask.test(extent, mutable.setComponents(x, y - 1, z)); } @Override @@ -151,21 +146,23 @@ public class AngleMask extends SolidBlockMask implements ResettableMask { int z = vector.getBlockZ(); if ((lastX == (lastX = x) & lastZ == (lastZ = z))) { - int height = getHeight(getExtent(), x, y, z); + int height = getHeight(extent, x, y, z); if (y <= height) { return overlay ? (lastValue && y == height) : lastValue; } } - if (!mask.test(x, y, z)) { + MutableBlockVector3 mutable = new MutableBlockVector3(x, y, z); + + if (!mask.test(extent, mutable)) { return false; } if (overlay) { - if (y < maxY && !adjacentAir(vector)) { + if (y < maxY && !adjacentAir(extent, mutable)) { return lastValue = false; } } - return testSlope(getExtent(), x, y, z); + return testSlope(extent, x, y, z); } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/CachedMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/CachedMask.java index 7d3adbed0..be926b2fb 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/CachedMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/CachedMask.java @@ -1,20 +1,22 @@ package com.fastasyncworldedit.core.function.mask; import com.fastasyncworldedit.core.math.LocalBlockVectorSet; -import com.fastasyncworldedit.core.math.MutableBlockVector3; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.function.mask.AbstractExtentMask; import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.math.BlockVector3; +import javax.annotation.Nullable; + public class CachedMask extends AbstractDelegateMask implements ResettableMask { - private transient MutableBlockVector3 mutable = new MutableBlockVector3(); + private final boolean hasExtent; private transient LocalBlockVectorSet cache_checked = new LocalBlockVectorSet(); private transient LocalBlockVectorSet cache_results = new LocalBlockVectorSet(); public CachedMask(Mask mask) { super(mask); - cache_checked.setOffset(Integer.MIN_VALUE, Integer.MIN_VALUE); - cache_results.setOffset(Integer.MIN_VALUE, Integer.MIN_VALUE); + hasExtent = mask instanceof AbstractExtentMask; } public static CachedMask cache(Mask mask) { @@ -26,7 +28,6 @@ public class CachedMask extends AbstractDelegateMask implements ResettableMask { @Override public void reset() { - mutable = new MutableBlockVector3(); cache_checked = new LocalBlockVectorSet(); cache_results = new LocalBlockVectorSet(); resetCache(); @@ -35,35 +36,55 @@ public class CachedMask extends AbstractDelegateMask implements ResettableMask { private void resetCache() { cache_checked.clear(); cache_results.clear(); - cache_checked.setOffset(Integer.MIN_VALUE, Integer.MIN_VALUE); - cache_results.setOffset(Integer.MIN_VALUE, Integer.MIN_VALUE); } @Override public boolean test(BlockVector3 vector) { - return test(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ()); - } - - public boolean test(int x, int y, int z) { + int x = vector.getX(); + int y = vector.getY(); + int z = vector.getZ(); try { 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)); + boolean result = getMask().test(vector); if (result) { cache_results.add(x, y, z); } return result; } catch (UnsupportedOperationException ignored) { - boolean result = getMask().test(mutable.setComponents(x, y, z)); - // Assume that the mask won't be given y outside the world range - // if (y < 0 || y > 255) { - // return result; - //} + boolean result = getMask().test(vector); + resetCache(); + cache_checked.add(x, y, z); + if (result) { + cache_results.add(x, y, z); + } + return result; + } + } + + public boolean test(@Nullable Extent extent, BlockVector3 vector) { + if (!hasExtent || !(extent instanceof AbstractExtentMask)) { + return test(vector); + } + int x = vector.getX(); + int y = vector.getY(); + int z = vector.getZ(); + AbstractExtentMask mask = (AbstractExtentMask) getMask(); + try { + boolean check = cache_checked.add(x, y, z); + if (!check) { + return cache_results.contains(x, y, z); + } + boolean result = mask.test(extent, vector); + if (result) { + cache_results.add(x, y, z); + } + return result; + } catch (UnsupportedOperationException ignored) { + boolean result = mask.test(extent, vector); 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); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/SurfaceMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/SurfaceMask.java index 6d935e103..36fe46edb 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/SurfaceMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/SurfaceMask.java @@ -21,7 +21,7 @@ public class SurfaceMask extends AdjacentAnyMask { @Override public boolean test(BlockVector3 v) { - return !getParentMask().test(v.getBlockX(), v.getBlockY(), v.getBlockZ()) && super.test(v); + return !getParentMask().test(v) && super.test(v); } @Override