Improve CachedMask a bit - no need to unwrap/wrap blockvectors, allow extents to be parsed

(cherry picked from commit 41c0ea98f16ecbfadced41e4be277ad6ceda6b1a)
This commit is contained in:
dordsor21 2021-09-12 12:36:32 +01:00
parent f5d6d4079a
commit b6b6ba7265
No known key found for this signature in database
GPG Key ID: 1E53E88969FFCF0B
4 changed files with 76 additions and 58 deletions

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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