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

(cherry picked from commit 41c0ea98f1)
Dieser Commit ist enthalten in:
dordsor21 2021-09-12 12:36:32 +01:00
Ursprung f5d6d4079a
Commit b6b6ba7265
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 1E53E88969FFCF0B
4 geänderte Dateien mit 76 neuen und 58 gelöschten Zeilen

Datei anzeigen

@ -40,17 +40,17 @@ public class AdjacentAnyMask extends AbstractMask implements ResettableMask {
int x = v.getBlockX(); int x = v.getBlockX();
int y = v.getBlockY(); int y = v.getBlockY();
int z = v.getBlockZ(); 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); 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); 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); 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); 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); 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); return mutable.setComponents(0, -1, 0);
} else { } else {
return null; return null;

Datei anzeigen

@ -1,6 +1,8 @@
package com.fastasyncworldedit.core.function.mask; package com.fastasyncworldedit.core.function.mask;
import com.fastasyncworldedit.core.math.MutableBlockVector3;
import com.sk89q.worldedit.extent.Extent; 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.Mask;
import com.sk89q.worldedit.function.mask.SolidBlockMask; import com.sk89q.worldedit.function.mask.SolidBlockMask;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
@ -9,8 +11,8 @@ import java.util.Arrays;
public class AngleMask extends SolidBlockMask implements ResettableMask { public class AngleMask extends SolidBlockMask implements ResettableMask {
public static double ADJACENT_MOD = 0.5; protected static double ADJACENT_MOD = 0.5;
public static double DIAGONAL_MOD = 1 / Math.sqrt(8); protected static double DIAGONAL_MOD = 1 / Math.sqrt(8);
protected final CachedMask mask; protected final CachedMask mask;
protected final double max; protected final double max;
@ -20,6 +22,13 @@ public class AngleMask extends SolidBlockMask implements ResettableMask {
protected final int maxY; protected final int maxY;
protected final int minY; protected final int minY;
protected final int distance; 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) { public AngleMask(Extent extent, double min, double max, boolean overlay, int distance) {
super(extent); super(extent);
@ -39,26 +48,13 @@ public class AngleMask extends SolidBlockMask implements ResettableMask {
cacheBotZ = Integer.MIN_VALUE; cacheBotZ = Integer.MIN_VALUE;
lastX = Integer.MIN_VALUE; lastX = Integer.MIN_VALUE;
lastY = Integer.MIN_VALUE; lastY = Integer.MIN_VALUE;
lastZ = Integer.MIN_VALUE;
if (cacheHeights != null) { if (cacheHeights != null) {
Arrays.fill(cacheHeights, (byte) 0); Arrays.fill(cacheHeights, (byte) 0);
} }
} }
protected transient int cacheCenZ; protected int getHeight(Extent extent, int x, int y, int z) {
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);
int rx = x - cacheBotX + 16; int rx = x - cacheBotX + 16;
int rz = z - cacheBotZ + 16; int rz = z - cacheBotZ + 16;
int index; int index;
@ -85,7 +81,6 @@ public class AngleMask extends SolidBlockMask implements ResettableMask {
protected boolean testSlope(Extent extent, int x, int y, int z) { protected boolean testSlope(Extent extent, int x, int y, int z) {
double slope; double slope;
boolean aboveMin;
lastY = y; lastY = y;
slope = slope =
Math.abs(getHeight(extent, x + distance, y, z) - getHeight(extent, x - distance, y, z)) 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) { private boolean adjacentAir(Extent extent, MutableBlockVector3 mutable) {
int x = v.getBlockX(); int x = mutable.getBlockX();
int y = v.getBlockY(); int y = mutable.getBlockY();
int z = v.getBlockZ(); int z = mutable.getBlockZ();
if (!mask.test(x + 1, y, z)) { if (!mask.test(extent, mutable.setComponents(x + 1, y, z))) {
return true; return true;
} }
if (!mask.test(x - 1, y, z)) { if (!mask.test(extent, mutable.setComponents(x - 1, y, z))) {
return true; return true;
} }
if (!mask.test(x, y, z + 1)) { if (!mask.test(extent, mutable.setComponents(x, y, z + 1))) {
return true; return true;
} }
if (!mask.test(x, y, z - 1)) { if (!mask.test(extent, mutable.setComponents(x, y, z - 1))) {
return true; 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 true;
} }
return y > minY && !mask.test(x, y - 1, z); return y != minY && !mask.test(extent, mutable.setComponents(x, y - 1, z));
} }
@Override @Override
@ -151,21 +146,23 @@ public class AngleMask extends SolidBlockMask implements ResettableMask {
int z = vector.getBlockZ(); int z = vector.getBlockZ();
if ((lastX == (lastX = x) & lastZ == (lastZ = z))) { if ((lastX == (lastX = x) & lastZ == (lastZ = z))) {
int height = getHeight(getExtent(), x, y, z); int height = getHeight(extent, x, y, z);
if (y <= height) { if (y <= height) {
return overlay ? (lastValue && y == height) : lastValue; 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; return false;
} }
if (overlay) { if (overlay) {
if (y < maxY && !adjacentAir(vector)) { if (y < maxY && !adjacentAir(extent, mutable)) {
return lastValue = false; return lastValue = false;
} }
} }
return testSlope(getExtent(), x, y, z); return testSlope(extent, x, y, z);
} }
@Override @Override

Datei anzeigen

@ -1,20 +1,22 @@
package com.fastasyncworldedit.core.function.mask; package com.fastasyncworldedit.core.function.mask;
import com.fastasyncworldedit.core.math.LocalBlockVectorSet; 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.function.mask.Mask;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import javax.annotation.Nullable;
public class CachedMask extends AbstractDelegateMask implements ResettableMask { 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_checked = new LocalBlockVectorSet();
private transient LocalBlockVectorSet cache_results = new LocalBlockVectorSet(); private transient LocalBlockVectorSet cache_results = new LocalBlockVectorSet();
public CachedMask(Mask mask) { public CachedMask(Mask mask) {
super(mask); super(mask);
cache_checked.setOffset(Integer.MIN_VALUE, Integer.MIN_VALUE); hasExtent = mask instanceof AbstractExtentMask;
cache_results.setOffset(Integer.MIN_VALUE, Integer.MIN_VALUE);
} }
public static CachedMask cache(Mask mask) { public static CachedMask cache(Mask mask) {
@ -26,7 +28,6 @@ public class CachedMask extends AbstractDelegateMask implements ResettableMask {
@Override @Override
public void reset() { public void reset() {
mutable = new MutableBlockVector3();
cache_checked = new LocalBlockVectorSet(); cache_checked = new LocalBlockVectorSet();
cache_results = new LocalBlockVectorSet(); cache_results = new LocalBlockVectorSet();
resetCache(); resetCache();
@ -35,35 +36,55 @@ public class CachedMask extends AbstractDelegateMask implements ResettableMask {
private void resetCache() { private void resetCache() {
cache_checked.clear(); cache_checked.clear();
cache_results.clear(); cache_results.clear();
cache_checked.setOffset(Integer.MIN_VALUE, Integer.MIN_VALUE);
cache_results.setOffset(Integer.MIN_VALUE, Integer.MIN_VALUE);
} }
@Override @Override
public boolean test(BlockVector3 vector) { public boolean test(BlockVector3 vector) {
return test(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ()); int x = vector.getX();
} int y = vector.getY();
int z = vector.getZ();
public boolean test(int x, int y, int z) {
try { try {
boolean check = cache_checked.add(x, y, z); boolean check = cache_checked.add(x, y, z);
if (!check) { if (!check) {
return cache_results.contains(x, y, z); return cache_results.contains(x, y, z);
} }
boolean result = getMask().test(mutable.setComponents(x, y, z)); boolean result = getMask().test(vector);
if (result) { if (result) {
cache_results.add(x, y, z); cache_results.add(x, y, z);
} }
return result; return result;
} catch (UnsupportedOperationException ignored) { } catch (UnsupportedOperationException ignored) {
boolean result = getMask().test(mutable.setComponents(x, y, z)); boolean result = getMask().test(vector);
// Assume that the mask won't be given y outside the world range resetCache();
// if (y < 0 || y > 255) { cache_checked.add(x, y, z);
// return result; 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(); resetCache();
cache_checked.setOffset(x, z);
cache_results.setOffset(x, z);
cache_checked.add(x, y, z); cache_checked.add(x, y, z);
if (result) { if (result) {
cache_results.add(x, y, z); cache_results.add(x, y, z);

Datei anzeigen

@ -21,7 +21,7 @@ public class SurfaceMask extends AdjacentAnyMask {
@Override @Override
public boolean test(BlockVector3 v) { 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 @Override