Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-11-13 22:50:06 +01:00
Improve CachedMask a bit - no need to unwrap/wrap blockvectors, allow extents to be parsed
Dieser Commit ist enthalten in:
Ursprung
9014baf6e5
Commit
41c0ea98f1
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren