filter sphere

This commit is contained in:
Jesse Boyd 2019-06-29 00:16:12 +10:00
parent de4dcc0dd5
commit 2b0a310e0e
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
13 changed files with 148 additions and 216 deletions

View File

@ -3,7 +3,6 @@ package com.boydti.fawe.beta;
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks; import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
@ -367,28 +366,6 @@ public class CharFilterBlock extends ChunkFilterBlock {
return BlockTypes.__RESERVED__.getDefaultState(); 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
*/ */

View File

@ -298,25 +298,25 @@ public class DelegateFilterBlock extends FilterBlock {
return parent.toImmutable(); return parent.toImmutable();
} }
@Override // @Override
public BlockVector3 north() { // public BlockVector3 north() {
return parent.north(); // return parent.north();
} // }
//
@Override // @Override
public BlockVector3 east() { // public BlockVector3 east() {
return parent.east(); // return parent.east();
} // }
//
@Override // @Override
public BlockVector3 south() { // public BlockVector3 south() {
return parent.south(); // return parent.south();
} // }
//
@Override // @Override
public BlockVector3 west() { // public BlockVector3 west() {
return parent.west(); // return parent.west();
} // }
@Override @Override
public int getBlockX() { public int getBlockX() {

View File

@ -119,7 +119,6 @@ public abstract class FilterBlock extends BlockVector3 implements Extent, TileEn
/* /*
Extent Extent
*/ */
public boolean setOrdinal(Extent orDefault, int ordinal) { public boolean setOrdinal(Extent orDefault, int ordinal) {
setOrdinal(ordinal); setOrdinal(ordinal);
return true; return true;

View File

@ -88,8 +88,8 @@ public interface IDelegateChunk<U extends IChunk> extends IChunk {
} }
@Override @Override
default void filterBlocks(Filter filter, ChunkFilterBlock block, @Nullable Region region, MutableBlockVector3 unitialized, MutableBlockVector3 unitialized2) { default void filterBlocks(Filter filter, ChunkFilterBlock block, @Nullable Region region) {
getParent().filterBlocks(filter, block, region, unitialized, unitialized2); getParent().filterBlocks(filter, block, region);
} }
@Override @Override

View File

@ -14,10 +14,10 @@ public class NorthVector extends BlockVector3 {
this.parent = parent; this.parent = parent;
} }
@Override // @Override
public BlockVector3 south(BlockVector3 orDefault) { // public BlockVector3 south(BlockVector3 orDefault) {
return parent; // return parent;
} // }
@Override @Override
public int getX() { public int getX() {

View File

@ -51,10 +51,10 @@ public class SingleFilterBlock extends FilterBlock {
return block.getOrdinal(); return block.getOrdinal();
} }
@Override // @Override
public BaseBlock getFullBlockRelative(int x, int y, int z) { // public BaseBlock getFullBlockRelative(int x, int y, int z) {
return block; // return block;
} // }
@Override @Override
public BlockState getBlock() { public BlockState getBlock() {

View File

@ -156,9 +156,6 @@ public abstract class QueueHandler implements Trimable, Runnable {
tasks[i] = forkJoinPoolPrimary.submit(new Runnable() { tasks[i] = forkJoinPoolPrimary.submit(new Runnable() {
@Override @Override
public void run() { public void run() {
MutableBlockVector3 mbv1 = new MutableBlockVector3();
MutableBlockVector3 mbv2 = new MutableBlockVector3();
final Filter newFilter = filter.fork(); final Filter newFilter = filter.fork();
// Create a chunk that we will reuse/reset for each operation // Create a chunk that we will reuse/reset for each operation
final IQueueExtent queue = getQueue(world); final IQueueExtent queue = getQueue(world);
@ -185,7 +182,7 @@ public abstract class QueueHandler implements Trimable, Runnable {
if (newChunk != null) { if (newChunk != null) {
chunk = newChunk; chunk = newChunk;
if (block == null) block = queue.initFilterBlock(); if (block == null) block = queue.initFilterBlock();
chunk.filterBlocks(newFilter, block, region, mbv1, mbv2); chunk.filterBlocks(newFilter, block, region);
} }
queue.submit(chunk); queue.submit(chunk);
} }

View File

@ -103,7 +103,7 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
private <T extends Future<T>> T submitUnchecked(final IChunk<T> chunk) { private <T extends Future<T>> T submitUnchecked(final IChunk<T> chunk) {
if (chunk.isEmpty()) { if (chunk.isEmpty()) {
CHUNK_POOL.add(chunk); CHUNK_POOL.add(chunk);
return (T) (Future) Futures.immediateFuture(null); return (T) Futures.immediateFuture(null);
} }
if (Fawe.isMainThread()) { if (Fawe.isMainThread()) {

View File

@ -7,6 +7,11 @@ public class CharBlocks implements IBlocks {
public final char[][] blocks; public final char[][] blocks;
public final Section[] sections; public final Section[] sections;
public CharBlocks(CharBlocks other) {
this.blocks = other.blocks;
this.sections = other.sections;
}
public CharBlocks() { public CharBlocks() {
blocks = new char[16][]; blocks = new char[16][];
sections = new Section[16]; sections = new Section[16];

View File

@ -20,6 +20,17 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
public HashSet<CompoundTag> entities; public HashSet<CompoundTag> entities;
public HashSet<UUID> entityRemoves; public HashSet<UUID> entityRemoves;
public CharSetBlocks(CharBlocks other) {
super(other);
if (other instanceof CharSetBlocks) {
}
}
public CharSetBlocks() {
}
@Override @Override
public char[] getArray(int layer) { public char[] getArray(int layer) {
return sections[layer].get(this, layer); return sections[layer].get(this, layer);

View File

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

View File

@ -103,37 +103,37 @@ public abstract class BlockVector3 {
return BlockVector3.at(getX(), getY(), getZ()); return BlockVector3.at(getX(), getY(), getZ());
} }
/** // /**
* Get the BlockVector3 to the north<br> // * Get the BlockVector3 to the north<br>
* Normal use you would use north(this), // * Normal use you would use north(this),
* To avoid constructing a new Vector, pass e.g. north(some MutableBlockVector3) // * To avoid constructing a new Vector, pass e.g. north(some MutableBlockVector3)
* There is no gaurantee it will use this provided vector // * There is no gaurantee it will use this provided vector
* @param orDefault the vector to use as the result<br> // * @param orDefault the vector to use as the result<br>
* @return BlockVector3 // * @return BlockVector3
*/ // */
public BlockVector3 north(BlockVector3 orDefault) { // public BlockVector3 north(BlockVector3 orDefault) {
return orDefault.setComponents(getX(), getY(), getZ() - 1); // return orDefault.setComponents(getX(), getY(), getZ() - 1);
} // }
//
public BlockVector3 east(BlockVector3 orDefault) { // public BlockVector3 east(BlockVector3 orDefault) {
return orDefault.setComponents(getX() + 1, getY(), getZ()); // return orDefault.setComponents(getX() + 1, getY(), getZ());
} // }
//
public BlockVector3 south(BlockVector3 orDefault) { // public BlockVector3 south(BlockVector3 orDefault) {
return orDefault.setComponents(getX(), getY(), getZ() + 1); // return orDefault.setComponents(getX(), getY(), getZ() + 1);
} // }
//
public BlockVector3 west(BlockVector3 orDefault) { // public BlockVector3 west(BlockVector3 orDefault) {
return orDefault.setComponents(getX() - 1, getY(), getZ()); // return orDefault.setComponents(getX() - 1, getY(), getZ());
} // }
//
public BlockVector3 up(BlockVector3 orDefault) { // public BlockVector3 up(BlockVector3 orDefault) {
return orDefault.setComponents(getX(), getY() + 1, getZ()); // return orDefault.setComponents(getX(), getY() + 1, getZ());
} // }
//
public BlockVector3 down(BlockVector3 orDefault) { // public BlockVector3 down(BlockVector3 orDefault) {
return orDefault.setComponents(getX(), getY() - 1, getZ()); // return orDefault.setComponents(getX(), getY() - 1, getZ());
} // }
/** /**
* Get the X coordinate. * Get the X coordinate.

View File

@ -25,6 +25,7 @@ import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.IChunk; import com.boydti.fawe.beta.IChunk;
import com.boydti.fawe.beta.IChunkGet; import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.beta.IChunkSet; import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.util.MathMan;
import com.sk89q.worldedit.math.MutableBlockVector3; import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
@ -286,14 +287,54 @@ public class EllipsoidRegion extends AbstractRegion {
return (EllipsoidRegion) super.clone(); 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 @Override
public void filter(IChunk chunk, Filter filter, ChunkFilterBlock block, IChunkGet get, IChunkSet set) { 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 bx = chunk.getX() << 4;
int bz = chunk.getZ() << 4; int bz = chunk.getZ() << 4;
int tx = bx + 15; int tx = bx + 15;
int tz = bz + 15; int tz = bz + 15;
int cx1 = bx - center.getBlockX(); int cx1 = bx - cx;
int cx2 = tx - center.getBlockX(); int cx2 = tx - cx;
int cxMax, cxMin; int cxMax, cxMin;
if (cx1 < cx2) { if (cx1 < cx2) {
cxMin = cx1; cxMin = cx1;
@ -304,8 +345,8 @@ public class EllipsoidRegion extends AbstractRegion {
} }
int cxMin2 = cxMin * cxMin; int cxMin2 = cxMin * cxMin;
int cxMax2 = cxMax * cxMax; int cxMax2 = cxMax * cxMax;
int cz1 = bz - center.getBlockZ(); int cz1 = bz - cz;
int cz2 = tz - center.getBlockZ(); int cz2 = tz - cz;
int czMax, czMin; int czMax, czMin;
if (cz1 < cz2) { if (cz1 < cz2) {
czMin = cz1; czMin = cz1;
@ -319,62 +360,41 @@ public class EllipsoidRegion extends AbstractRegion {
if (sphere) { if (sphere) {
// Does not contain chunk
if (cxMin2 + czMin2 >= radiusLengthSqr) { if (cxMin2 + czMin2 >= radiusLengthSqr) {
return; return;
} }
int diffY2 = radiusLengthSqr - cxMax2 - czMax2; int diffY2 = radiusLengthSqr - cxMax2 - czMax2;
if (diffY2 > 0) { // (shortcut) Contains all of certain layers
diffy2 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);
} }
if (yTopFull != 255) {
int yTopPartial = Math.min(255, cy + diffYPartial);
filterSpherePartial(yTopFull + 1, yTopPartial - 1, bx, bz, filter, block, get, set);
}
}
}
} else { } else {
if (cxMin2 * inverseRadius.getX() + czMin2 * inverseRadius.getZ() > 1) { super.filter(chunk, filter, block, get, set);
return; // TODO optimize
}
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()
}
}