idk, messing around with region filtering

This commit is contained in:
Jesse Boyd
2019-06-26 20:22:21 +10:00
parent 6bc5b4a823
commit de4dcc0dd5
20 changed files with 542 additions and 222 deletions

View File

@ -19,29 +19,27 @@
package com.sk89q.worldedit.regions;
import com.boydti.fawe.beta.ChunkFilterBlock;
import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.IChunk;
import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.config.Settings;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.object.collection.BlockVectorSet;
import com.boydti.fawe.object.collection.LocalBlockVectorSet;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.math.MutableBlockVector2;
import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.storage.ChunkStore;
import java.util.AbstractSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Set;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.regions.Region.Contains.*;
/**
* An axis-aligned cuboid. It can be defined using two corners of the cuboid.
@ -400,13 +398,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
public boolean contains(int x, int z) {
return x >= this.minX && x <= this.maxX && z >= this.minZ && z <= this.maxZ;
}
@Override
public boolean contains(BlockVector3 position) {
BlockVector3 min = getMinimumPoint();
BlockVector3 max = getMaximumPoint();
return position.containedWithin(min, max);
}
@Override
public Iterator<BlockVector3> iterator() {
if (Settings.IMP.HISTORY.COMPRESSION_LEVEL >= 9 || useOldIterator) {
@ -629,35 +621,49 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
}
@Override
public Contains getChunkBounds(int X, int Z, MutableBlockVector3 min, MutableBlockVector3 max) {
int minChunkX = minX >> 4;
if (minChunkX <= X) {
int maxChunkX = maxX >> 4;
if (maxChunkX >= X) {
int minChunkZ = minZ >> 4;
if (minChunkZ <= Z) {
int maxChunkZ = maxZ >> 4;
if (maxChunkZ >= Z) {
int cx1 = X << 4;
int cx2 = cx1 + 15;
int cz1 = Z << 4;
int cz2 = cz1 + 15;
public int getMinY() {
return minY;
}
int bx = Math.max(cx1, minX);
int bz = Math.max(cz1, minZ);
int tx = Math.min(cx2, maxX);
int tz = Math.min(cz2, maxZ);
@Override
public int getMaxY() {
return maxY;
}
min.setComponents(bx & 15, minY, bz & 15);
max.setComponents(tx & 15, maxY, tz & 15);
if (min.getX() == 0 && min.getZ() == 0 && max.getX() == 15 && max.getZ() == 15) {
return FULL;
}
return PARTIAL;
}
}
}
@Override
public void filter(final IChunk chunk, final Filter filter, ChunkFilterBlock block, final IChunkGet get, final IChunkSet set) {
int X = chunk.getX();
int Z = chunk.getZ();
block = block.init(X, Z, get);
if ((minX + 15) >> 4 <= X && (maxX - 15) >> 4 >= X && (minZ + 15) >> 4 <= Z && (maxZ - 15) >> 4 >= Z) {
filter(chunk, filter, block, get, set, minY, maxY);
return;
}
int localMinX = Math.max(minX, X << 4) & 15;
int localMaxX = Math.min(maxX, 15 + X << 4) & 15;
int localMinZ = Math.max(minZ, Z << 4) & 15;
int localMaxZ = Math.min(maxZ, 15 + Z << 4) & 15;
int yStart = (minY & 15);
int yEnd = (maxY & 15);
int minSection = minY >> 4;
int maxSection = maxY >> 4;
if (minSection == maxSection) {
filter(chunk, filter, block, get, set, minSection, localMinX, yStart, localMinZ, localMaxX, yEnd, localMaxZ);
return;
}
if (yStart != 0) {
filter(chunk, filter, block, get, set, minSection, localMinX, yStart, localMinZ, localMaxX, 15, localMaxZ);
minSection++;
}
if (yEnd != 15) {
filter(chunk, filter, block, get, set, minSection, localMinX, 0, localMinZ, localMaxX, 15, localMaxZ);
maxSection--;
}
for (int layer = minSection; layer < maxSection; layer++) {
filter(chunk, filter, block, get, set, layer, localMinX, yStart, localMinZ, localMaxX, yEnd, localMaxZ);
}
return NONE;
}
}

View File

@ -21,6 +21,11 @@ package com.sk89q.worldedit.regions;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.beta.ChunkFilterBlock;
import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.IChunk;
import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.beta.IChunkSet;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.BlockVector2;
@ -290,25 +295,22 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion {
minY += changeY;
}
/**
* Checks to see if a point is inside this region.
*/
@Override
public boolean contains(BlockVector3 position) {
final int blockY = position.getBlockY();
if (blockY < minY || blockY > maxY) {
public boolean contains(int x, int y, int z) {
if (y < minY || y > maxY) {
return false;
}
int px = position.getBlockX();
int pz = position.getBlockZ();
return contains(x, z);
}
double dx = Math.abs(px - center.getBlockX()) * radiusInverse.getX();
double dz = Math.abs(pz - center.getBlockZ()) * radiusInverse.getZ();
@Override
public boolean contains(int x, int z) {
double dx = Math.abs(x - center.getBlockX()) * radiusInverse.getX();
double dz = Math.abs(z - center.getBlockZ()) * radiusInverse.getZ();
return dx * dx + dz * dz <= 1;
}
/**
* Sets the height of the cylinder to fit the specified Y.
*
@ -363,6 +365,16 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion {
return Polygons.polygonizeCylinder(center, radius, maxPoints);
}
@Override
public int getMinY() {
return minY;
}
@Override
public int getMaxY() {
return maxY;
}
/**
* Return a new instance with the given center and radius in the X and Z
* axes with a Y that extends from the bottom of the extent to the top
@ -381,4 +393,17 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion {
int maxY = extent.getMaximumPoint().getBlockY();
return new CylinderRegion(center, radiusVec, minY, maxY);
}
@Override
public void filter(final IChunk chunk, final Filter filter, final ChunkFilterBlock block, final IChunkGet get, final IChunkSet set) {
int bcx = chunk.getX() >> 4;
int bcz = chunk.getZ() >> 4;
int tcx = bcx + 15;
int tcz = bcz + 15;
if (contains(bcx, bcz) && contains(tcx, tcz)) {
filter(chunk, filter, block, get, set, minY, maxY);
return;
}
super.filter(chunk, filter, block, get, set);
}
}

View File

@ -20,6 +20,11 @@
package com.sk89q.worldedit.regions;
import com.boydti.fawe.beta.ChunkFilterBlock;
import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.IChunk;
import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.beta.IChunkSet;
import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
@ -215,19 +220,19 @@ public class EllipsoidRegion extends AbstractRegion {
return chunks;
}
@Override
public boolean contains(BlockVector3 position) {
int cx = position.getBlockX() - center.getBlockX();
@Override
public boolean contains(int x, int y, int z) {
int cx = x - center.getBlockX();
int cx2 = cx * cx;
if (cx2 > radiusSqr.getBlockX()) {
return false;
}
int cz = position.getBlockZ() - center.getBlockZ();
int cz = z - center.getBlockZ();
int cz2 = cz * cz;
if (cz2 > radiusSqr.getBlockZ()) {
return false;
}
int cy = position.getBlockY() - center.getBlockY();
int cy = y - center.getBlockY();
int cy2 = cy * cy;
if (radiusSqr.getBlockY() < 255 && cy2 > radiusSqr.getBlockY()) {
return false;
@ -235,10 +240,30 @@ public class EllipsoidRegion extends AbstractRegion {
if (sphere) {
return cx2 + cy2 + cz2 <= radiusLengthSqr;
}
double cxd = cx * inverseRadius.getX();
double cyd = cy * inverseRadius.getY();
double czd = cz * inverseRadius.getZ();
return cxd * cxd + cyd * cyd + czd * czd <= 1;
double cxd = cx2 * inverseRadius.getX();
double cyd = cy2 * inverseRadius.getY();
double czd = cz2 * inverseRadius.getZ();
return cxd + cyd + czd <= 1;
}
@Override
public boolean contains(int x, int z) {
int cx = x - center.getBlockX();
int cx2 = cx * cx;
if (cx2 > radiusSqr.getBlockX()) {
return false;
}
int cz = z - center.getBlockZ();
int cz2 = cz * cz;
if (cz2 > radiusSqr.getBlockZ()) {
return false;
}
if (sphere) {
return cx2 + cz2 <= radiusLengthSqr;
}
double cxd = cx2 * inverseRadius.getX();
double czd = cz2 * inverseRadius.getZ();
return cxd + czd <= 1;
}
/**
@ -260,4 +285,96 @@ public class EllipsoidRegion extends AbstractRegion {
public EllipsoidRegion clone() {
return (EllipsoidRegion) super.clone();
}
@Override
public void filter(IChunk chunk, Filter filter, ChunkFilterBlock block, IChunkGet get, IChunkSet set) {
int bx = chunk.getX() << 4;
int bz = chunk.getZ() << 4;
int tx = bx + 15;
int tz = bz + 15;
int cx1 = bx - center.getBlockX();
int cx2 = tx - center.getBlockX();
int cxMax, cxMin;
if (cx1 < cx2) {
cxMin = cx1;
cxMax = cx2;
} else {
cxMin = cx2;
cxMax = cx1;
}
int cxMin2 = cxMin * cxMin;
int cxMax2 = cxMax * cxMax;
int cz1 = bz - center.getBlockZ();
int cz2 = tz - center.getBlockZ();
int czMax, czMin;
if (cz1 < cz2) {
czMin = cz1;
czMax = cz2;
} else {
czMin = cz2;
czMax = cz1;
}
int czMin2 = czMin * czMin;
int czMax2 = czMax * czMax;
if (sphere) {
if (cxMin2 + czMin2 >= radiusLengthSqr) {
return;
}
int diffY2 = radiusLengthSqr - cxMax2 - czMax2;
if (diffY2 > 0) {
diffy2
}
} else {
if (cxMin2 * inverseRadius.getX() + czMin2 * inverseRadius.getZ() > 1) {
return;
}
partial = cxMax2 * inverseRadius.getX() + czMax2 * inverseRadius.getZ() > 1;
}
if (partial) {
} else {
// get min y and max y
for (int layer = 0; layer < 16; layer++) {
// if contains all
{
filter(chunk, )
}
}
}
int cy1 = 0 - center.getBlockY();
int cy2 = 255 - center.getBlockY();
int cyMax, cyMin;
if (cy1 < cy2) {
cyMin = cy1;
cyMax = cy2;
} else {
cyMin = cy2;
cyMax = cy1;
}
int cyMin2 = cyMin * cyMin;
int cyMax2 = cyMax * cyMax;
boolean containsMin = contains(bx, bz);
boolean containsMax = contains(tx, tz);
if (containsMin && containsMax) {
// set all
return;
}
for (int layer = 0; layer < 16; layer++) {
if (contains())
}
TODO optimize;
int minY = getMinY();
int maxY = getMaxY();
contains()
}
}

View File

@ -19,6 +19,12 @@
package com.sk89q.worldedit.regions;
import com.boydti.fawe.beta.ChunkFilterBlock;
import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.IChunk;
import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.beta.IChunkSet;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.MutableBlockVector3;
@ -26,12 +32,10 @@ import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.world.World;
import javax.annotation.Nullable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import static com.sk89q.worldedit.regions.Region.Contains.CHECKED;
import static com.sk89q.worldedit.regions.Region.Contains.NONE;
/**
* Represents a physical shape.
*/
@ -137,7 +141,9 @@ public interface Region extends Iterable<BlockVector3>, Cloneable {
* @param position the position
* @return true if contained
*/
boolean contains(BlockVector3 position);
default boolean contains(BlockVector3 position) {
return contains(position.getX(), position.getY(), position.getZ());
}
/**
* Get a list of chunks.
@ -183,32 +189,62 @@ public interface Region extends Iterable<BlockVector3>, Cloneable {
*/
List<BlockVector2> polygonize(int maxPoints);
default Contains getChunkBounds(int X, int Z, MutableBlockVector3 min, MutableBlockVector3 max) {
BlockVector3 pos1 = getMinimumPoint();
BlockVector3 pos2 = getMaximumPoint();
int cx1 = X << 4;
int cx2 = cx1 + 15;
int cz1 = Z << 4;
int cz2 = cz1 + 15;
int bx = Math.max(cx1, pos1.getX());
int bz = Math.max(cz1, pos1.getZ());
int tx = Math.min(cx2, pos2.getX());
int tz = Math.min(cz2, pos2.getZ());
min.setComponents(bx & 15, pos1.getY(), bz & 15);
max.setComponents(tx & 15, pos2.getY(), tz & 15);
if (bx > cx2 || bz > cz2 || tx < cx1 || tz < cz1) {
return NONE;
}
return CHECKED;
default int getMinY() {
return getMinimumPoint().getY();
}
enum Contains {
FULL,
PARTIAL,
CHECKED,
NONE;
default int getMaxY() {
return getMaximumPoint().getY();
}
default void filter(final IChunk chunk, final Filter filter, ChunkFilterBlock block, final IChunkGet get, final IChunkSet set) {
int minSection = Math.max(0, getMinY() >> 4);
int maxSection = Math.min(15, getMaxY() >> 4);
for (int layer = minSection; layer <= maxSection; layer++) {
if (!get.hasSection(layer) || !filter.appliesLayer(chunk, layer)) return;
block = block.init(get, set, layer);
block.filter(filter, this);
}
}
default void filter(final IChunk chunk, final Filter filter, ChunkFilterBlock block, final IChunkGet get, final IChunkSet set, final int minY, final int maxY) {
int minSection = minY >> 4;
int maxSection = maxY >> 4;
int yStart = (minY & 15);
int yEnd = (maxY & 15);
if (minSection == maxSection) {
filter(chunk, filter, block, get, set, minSection, yStart, yEnd);
return;
}
if (yStart != 0) {
filter(chunk, filter, block, get, set, minSection, yStart, 15);
minSection++;
}
if (yEnd != 15) {
filter(chunk, filter, block, get, set, minSection, 0, yEnd);
maxSection--;
}
for (int layer = minSection; layer < maxSection; layer++) {
filter(chunk, filter, block, get, set, layer);
}
return;
}
default void filter(final IChunk chunk, final Filter filter, ChunkFilterBlock block, final IChunkGet get, final IChunkSet set, int layer) {
if (!get.hasSection(layer) || !filter.appliesLayer(chunk, layer)) return;
block = block.init(get, set, layer);
block.filter(filter);
}
default void filter(final IChunk chunk, final Filter filter, ChunkFilterBlock block, final IChunkGet get, final IChunkSet set, int layer, int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {
if (!get.hasSection(layer) || !filter.appliesLayer(chunk, layer)) return;
block = block.init(get, set, layer);
block.filter(filter, minX, minY, minZ, maxX, maxY, maxZ);
}
default void filter(final IChunk chunk, final Filter filter, ChunkFilterBlock block, final IChunkGet get, final IChunkSet set, int layer, int yStart, int yEnd) {
if (!get.hasSection(layer) || !filter.appliesLayer(chunk, layer)) return;
block = block.init(get, set, layer);
block.filter(filter, yStart, yEnd);
}
}

View File

@ -19,16 +19,8 @@
package com.sk89q.worldedit.regions;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.regions.Region.Contains.CHECKED;
import static com.sk89q.worldedit.regions.Region.Contains.FULL;
import static com.sk89q.worldedit.regions.Region.Contains.NONE;
import static com.sk89q.worldedit.regions.Region.Contains.PARTIAL;
import com.google.common.collect.Iterators;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.world.World;
import java.util.ArrayList;
@ -36,6 +28,9 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* An intersection of several other regions. Any location that is contained in one
* of the child regions is considered as contained by this region.