From 2b0a310e0ed4626e63d4d197a96f05690acf2c65 Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Sat, 29 Jun 2019 00:16:12 +1000 Subject: [PATCH] filter sphere --- .../com/boydti/fawe/beta/CharFilterBlock.java | 27 +--- .../boydti/fawe/beta/DelegateFilterBlock.java | 38 +++--- .../com/boydti/fawe/beta/FilterBlock.java | 1 - .../com/boydti/fawe/beta/IDelegateChunk.java | 4 +- .../com/boydti/fawe/beta/NorthVector.java | 8 +- .../boydti/fawe/beta/SingleFilterBlock.java | 8 +- .../beta/implementation/QueueHandler.java | 5 +- .../SingleThreadQueueExtent.java | 2 +- .../implementation/blocks/CharBlocks.java | 5 + .../implementation/blocks/CharSetBlocks.java | 11 ++ .../blocks/RegionCharSetBlocks.java | 77 ------------ .../sk89q/worldedit/math/BlockVector3.java | 62 +++++----- .../worldedit/regions/EllipsoidRegion.java | 116 ++++++++++-------- 13 files changed, 148 insertions(+), 216 deletions(-) delete mode 100644 worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/RegionCharSetBlocks.java diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/CharFilterBlock.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/CharFilterBlock.java index a4e2bbc71..459a27b1d 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/CharFilterBlock.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/CharFilterBlock.java @@ -3,7 +3,6 @@ package com.boydti.fawe.beta; import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; @@ -367,31 +366,9 @@ public class CharFilterBlock extends ChunkFilterBlock { return BlockTypes.__RESERVED__.getDefaultState(); } - - - @Override - public BlockVector3 north() { - return this.north; - } - - @Override - public BlockVector3 east() { - return super.east(); - } - - @Override - public BlockVector3 south() { - return super.south(); - } - - @Override - public BlockVector3 west() { - return super.west(); - } - /* - Extent - */ + Extent + */ @Override public char getOrdinalChar(Extent orDefault) { return getOrdinalChar(); diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/DelegateFilterBlock.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/DelegateFilterBlock.java index 88e1f9340..7589300fb 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/DelegateFilterBlock.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/DelegateFilterBlock.java @@ -298,25 +298,25 @@ public class DelegateFilterBlock extends FilterBlock { return parent.toImmutable(); } - @Override - public BlockVector3 north() { - return parent.north(); - } - - @Override - public BlockVector3 east() { - return parent.east(); - } - - @Override - public BlockVector3 south() { - return parent.south(); - } - - @Override - public BlockVector3 west() { - return parent.west(); - } +// @Override +// public BlockVector3 north() { +// return parent.north(); +// } +// +// @Override +// public BlockVector3 east() { +// return parent.east(); +// } +// +// @Override +// public BlockVector3 south() { +// return parent.south(); +// } +// +// @Override +// public BlockVector3 west() { +// return parent.west(); +// } @Override public int getBlockX() { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/FilterBlock.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/FilterBlock.java index 34fc86323..ed2a84be4 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/FilterBlock.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/FilterBlock.java @@ -119,7 +119,6 @@ public abstract class FilterBlock extends BlockVector3 implements Extent, TileEn /* Extent */ - public boolean setOrdinal(Extent orDefault, int ordinal) { setOrdinal(ordinal); return true; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/IDelegateChunk.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/IDelegateChunk.java index 3862c23c5..e36529fc8 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/IDelegateChunk.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/IDelegateChunk.java @@ -88,8 +88,8 @@ public interface IDelegateChunk extends IChunk { } @Override - default void filterBlocks(Filter filter, ChunkFilterBlock block, @Nullable Region region, MutableBlockVector3 unitialized, MutableBlockVector3 unitialized2) { - getParent().filterBlocks(filter, block, region, unitialized, unitialized2); + default void filterBlocks(Filter filter, ChunkFilterBlock block, @Nullable Region region) { + getParent().filterBlocks(filter, block, region); } @Override diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/NorthVector.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/NorthVector.java index 2b3581395..94279a6aa 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/NorthVector.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/NorthVector.java @@ -14,10 +14,10 @@ public class NorthVector extends BlockVector3 { this.parent = parent; } - @Override - public BlockVector3 south(BlockVector3 orDefault) { - return parent; - } +// @Override +// public BlockVector3 south(BlockVector3 orDefault) { +// return parent; +// } @Override public int getX() { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/SingleFilterBlock.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/SingleFilterBlock.java index 8a7add4b6..39a2c04a0 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/SingleFilterBlock.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/SingleFilterBlock.java @@ -51,10 +51,10 @@ public class SingleFilterBlock extends FilterBlock { return block.getOrdinal(); } - @Override - public BaseBlock getFullBlockRelative(int x, int y, int z) { - return block; - } +// @Override +// public BaseBlock getFullBlockRelative(int x, int y, int z) { +// return block; +// } @Override public BlockState getBlock() { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/QueueHandler.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/QueueHandler.java index e7a90b531..665f4043f 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/QueueHandler.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/QueueHandler.java @@ -156,9 +156,6 @@ public abstract class QueueHandler implements Trimable, Runnable { tasks[i] = forkJoinPoolPrimary.submit(new Runnable() { @Override public void run() { - MutableBlockVector3 mbv1 = new MutableBlockVector3(); - MutableBlockVector3 mbv2 = new MutableBlockVector3(); - final Filter newFilter = filter.fork(); // Create a chunk that we will reuse/reset for each operation final IQueueExtent queue = getQueue(world); @@ -185,7 +182,7 @@ public abstract class QueueHandler implements Trimable, Runnable { if (newChunk != null) { chunk = newChunk; if (block == null) block = queue.initFilterBlock(); - chunk.filterBlocks(newFilter, block, region, mbv1, mbv2); + chunk.filterBlocks(newFilter, block, region); } queue.submit(chunk); } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/SingleThreadQueueExtent.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/SingleThreadQueueExtent.java index 661868e8f..cc057334c 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/SingleThreadQueueExtent.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/SingleThreadQueueExtent.java @@ -103,7 +103,7 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent { private > T submitUnchecked(final IChunk chunk) { if (chunk.isEmpty()) { CHUNK_POOL.add(chunk); - return (T) (Future) Futures.immediateFuture(null); + return (T) Futures.immediateFuture(null); } if (Fawe.isMainThread()) { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java index 0b94d17b3..1c50695f2 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java @@ -7,6 +7,11 @@ public class CharBlocks implements IBlocks { public final char[][] blocks; public final Section[] sections; + public CharBlocks(CharBlocks other) { + this.blocks = other.blocks; + this.sections = other.sections; + } + public CharBlocks() { blocks = new char[16][]; sections = new Section[16]; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java index 82d13aa0e..23db45a27 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java @@ -20,6 +20,17 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet { public HashSet entities; public HashSet entityRemoves; + public CharSetBlocks(CharBlocks other) { + super(other); + if (other instanceof CharSetBlocks) { + + } + } + + public CharSetBlocks() { + + } + @Override public char[] getArray(int layer) { return sections[layer].get(this, layer); diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/RegionCharSetBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/RegionCharSetBlocks.java deleted file mode 100644 index caba79543..000000000 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/RegionCharSetBlocks.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.boydti.fawe.beta.implementation.blocks; - -import com.boydti.fawe.FaweCache; -import com.boydti.fawe.beta.IChunkSet; -import com.boydti.fawe.beta.implementation.DelegateChunkSet; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.block.BlockStateHolder; - -public class RegionCharSetBlocks implements DelegateChunkSet { - private final Region region; - private final CharSetBlocks parent; - private final int X, Z; - - public RegionCharSetBlocks(Region region, int X, int Z, CharSetBlocks parent) { - this.region = region; - this.parent = parent; - this.X = X; - this.Z = Z; - } - - @Override - public CharSetBlocks getParent() { - return parent; - } - - public Region getRegion() { - return region; - } - - @Override - public boolean setBiome(int x, int y, int z, BiomeType biome) { - if (region.contains(x, y, z)) { - return parent.setBiome(x, y, z, biome); - } - return false; - } - - public static final CharBlocks.Section EMPTY_REGION = new CharBlocks.Section() { - @Override - public final char[] get(final CharBlocks blocks, final int layer) { - RegionCharSetBlocks checked = (RegionCharSetBlocks) blocks; - Region region = checked.getRegion(); - - blocks.sections[layer] = FULL; - char[] arr = blocks.blocks[layer]; - if (arr == null) { - arr = blocks.blocks[layer] = blocks.load(layer); - } else { - blocks.blocks[layer] = blocks.load(layer, arr); - } - return arr; - } - }; - - public static final CharBlocks.Section NULL = new CharBlocks.Section() { - @Override - public final char[] get(final CharBlocks blocks, final int layer) { - return FaweCache.EMPTY_CHAR_4096; - } - }; - - // EMPTY_CHAR_4096 - - @Override - public boolean setBlock(final int x, final int y, final int z, final BlockStateHolder holder) { - - } - - @Override - public void setTile(final int x, final int y, final int z, final CompoundTag tile) { - if (region.contains(x, y, z)) { - super.setTile(x, y, z, tile); - } - } -} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java index e006aca61..8259ce872 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java @@ -103,37 +103,37 @@ public abstract class BlockVector3 { return BlockVector3.at(getX(), getY(), getZ()); } - /** - * Get the BlockVector3 to the north
- * Normal use you would use north(this), - * To avoid constructing a new Vector, pass e.g. north(some MutableBlockVector3) - * There is no gaurantee it will use this provided vector - * @param orDefault the vector to use as the result
- * @return BlockVector3 - */ - public BlockVector3 north(BlockVector3 orDefault) { - return orDefault.setComponents(getX(), getY(), getZ() - 1); - } - - public BlockVector3 east(BlockVector3 orDefault) { - return orDefault.setComponents(getX() + 1, getY(), getZ()); - } - - public BlockVector3 south(BlockVector3 orDefault) { - return orDefault.setComponents(getX(), getY(), getZ() + 1); - } - - public BlockVector3 west(BlockVector3 orDefault) { - return orDefault.setComponents(getX() - 1, getY(), getZ()); - } - - public BlockVector3 up(BlockVector3 orDefault) { - return orDefault.setComponents(getX(), getY() + 1, getZ()); - } - - public BlockVector3 down(BlockVector3 orDefault) { - return orDefault.setComponents(getX(), getY() - 1, getZ()); - } +// /** +// * Get the BlockVector3 to the north
+// * Normal use you would use north(this), +// * To avoid constructing a new Vector, pass e.g. north(some MutableBlockVector3) +// * There is no gaurantee it will use this provided vector +// * @param orDefault the vector to use as the result
+// * @return BlockVector3 +// */ +// public BlockVector3 north(BlockVector3 orDefault) { +// return orDefault.setComponents(getX(), getY(), getZ() - 1); +// } +// +// public BlockVector3 east(BlockVector3 orDefault) { +// return orDefault.setComponents(getX() + 1, getY(), getZ()); +// } +// +// public BlockVector3 south(BlockVector3 orDefault) { +// return orDefault.setComponents(getX(), getY(), getZ() + 1); +// } +// +// public BlockVector3 west(BlockVector3 orDefault) { +// return orDefault.setComponents(getX() - 1, getY(), getZ()); +// } +// +// public BlockVector3 up(BlockVector3 orDefault) { +// return orDefault.setComponents(getX(), getY() + 1, getZ()); +// } +// +// public BlockVector3 down(BlockVector3 orDefault) { +// return orDefault.setComponents(getX(), getY() - 1, getZ()); +// } /** * Get the X coordinate. diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java index bf5c4d8e3..e01196242 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java @@ -25,6 +25,7 @@ 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.util.MathMan; import com.sk89q.worldedit.math.MutableBlockVector3; import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; @@ -286,14 +287,54 @@ public class EllipsoidRegion extends AbstractRegion { return (EllipsoidRegion) super.clone(); } + private void filterSpherePartial(int y1, int y2, int bx, int bz, Filter filter, ChunkFilterBlock block, IChunkGet get, IChunkSet set) { + int sectionStart = y1 >> 4; + int sectionEnd = y2 >> 4; + + } + + private void filterSpherePartial(int layer, int y1, int y2, int bx, int bz, Filter filter, ChunkFilterBlock block, IChunkGet get, IChunkSet set) { + int cx = center.getBlockX(); + int cy = center.getBlockY(); + int cz = center.getBlockZ(); + + block.init(get, set, layer); + + int by = layer << 4; + int diffY; + for (int y = y1, yy = by + y1; y <= y2; y++, yy++) { + diffY = cy - yy; + int remainderY = radiusLengthSqr - (diffY * diffY); + if (remainderY >= 0) { + for (int z = 0; z < 16; z++) { + int zz = z + bz; + int diffZ = cz - zz; + int remainderZ = remainderY - (diffZ * diffZ); + if (remainderZ >= 0) { + int diffX = MathMan.usqrt(remainderZ); + int minX = Math.max(0, cx - diffX - bx); + int maxX = Math.min(15, cx + diffX - bx); + if (minX != maxX) { + block.filter(filter, minX, y, z, maxX, y, z); + } + } + } + } + } + } + @Override public void filter(IChunk chunk, Filter filter, ChunkFilterBlock block, IChunkGet get, IChunkSet set) { + // Check bounds + // This needs to be able to perform 50M blocks/sec otherwise it becomes a bottleneck + int cx = center.getBlockX(); + int cz = center.getBlockZ(); 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 cx1 = bx - cx; + int cx2 = tx - cx; int cxMax, cxMin; if (cx1 < cx2) { cxMin = cx1; @@ -304,8 +345,8 @@ public class EllipsoidRegion extends AbstractRegion { } int cxMin2 = cxMin * cxMin; int cxMax2 = cxMax * cxMax; - int cz1 = bz - center.getBlockZ(); - int cz2 = tz - center.getBlockZ(); + int cz1 = bz - cz; + int cz2 = tz - cz; int czMax, czMin; if (cz1 < cz2) { czMin = cz1; @@ -319,62 +360,41 @@ public class EllipsoidRegion extends AbstractRegion { if (sphere) { + // Does not contain chunk if (cxMin2 + czMin2 >= radiusLengthSqr) { return; } int diffY2 = radiusLengthSqr - cxMax2 - czMax2; - if (diffY2 > 0) { - diffy2 - } + // (shortcut) Contains all of certain layers + if (diffY2 >= 0) { + // Get the solid layers + int cy = center.getBlockY(); + int diffYFull = MathMan.usqrt(diffY2); + int yBotFull = Math.max(0, cy - diffYFull); + int yTopFull = Math.min(255, cy + diffYFull); + // Set those layers + filter(chunk, filter, block, get, set, yBotFull, yTopFull); + // Fill the remaining layers + if (yBotFull != 0 || yTopFull != 255) { + int diffYPartial = MathMan.usqrt(radiusLengthSqr - cxMin * cxMin - czMin * czMin); + if (yBotFull != 0) { + int yBotPartial = Math.max(0, cy - diffYPartial); + filterSpherePartial(yBotPartial, yBotFull - 1, bx, bz, filter, block, get, set); + } - } 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, ) + if (yTopFull != 255) { + int yTopPartial = Math.min(255, cy + diffYPartial); + filterSpherePartial(yTopFull + 1, yTopPartial - 1, bx, bz, filter, block, get, set); + } } } - } - 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; + super.filter(chunk, filter, block, get, set); + // TODO optimize } - 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() } }