Region filter

This commit is contained in:
Jesse Boyd
2019-05-05 03:58:26 +10:00
parent 27ed596027
commit 7c174beaee
15 changed files with 232 additions and 283 deletions

View File

@ -2,6 +2,8 @@ package com.boydti.fawe.beta;
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypes;
@ -40,7 +42,7 @@ public class CharFilterBlock implements FilterBlock {
}
@Override
public final void filter(final IGetBlocks iget, final ISetBlocks iset, final int layer, final Filter filter) {
public final void filter(final IGetBlocks iget, final ISetBlocks iset, final int layer, final Filter filter, final @Nullable Region region, BlockVector3 min, BlockVector3 max) {
this.layer = layer;
final CharGetBlocks get = (CharGetBlocks) iget;
if (!get.hasSection(layer)) return;
@ -54,7 +56,81 @@ public class CharFilterBlock implements FilterBlock {
setArr = null;
}
this.yy = layer << 4;
if (region == null) {
if (min != null && max != null) {
iterate(min, max, layer, filter);
} else {
iterate(filter);
}
} else {
if (min != null && max != null) {
iterate(region, min, max, layer, filter);
} else {
iterate(region, filter);
}
}
}
private void iterate(final Region region, final Filter filter) {
for (y = 0, index = 0; y < 16; y++) {
int absY = yy + y;
for (z = 0; z < 16; z++) {
int absZ = zz + z;
for (x = 0; x < 16; x++, index++) {
int absX = xx + x;
if (region.contains(absX, absY, absZ)) {
filter.applyBlock(this);
}
}
}
}
}
private void iterate(final Region region, BlockVector3 min, BlockVector3 max, int layer, final Filter filter) {
int by = Math.max(min.getY(), layer << 4) & 15;
int ty = Math.min(max.getY(), 15 + (layer << 4)) & 15;
int bx = min.getX();
int bz = min.getZ();
int tx = max.getX();
int tz = max.getZ();
for (y = by; y <= ty; y++) {
int yIndex = (y << 8);
int absY = yy + y;
for (z = bz; z <= tz; z++) {
int zIndex = yIndex + ((z) << 4);
int absZ = zz + z;
for (x = bx; x <= tx; x++) {
index = zIndex + x;
int absX = xx + x;
if (region.contains(absX, absY, absZ)) {
filter.applyBlock(this);
}
}
}
}
}
private void iterate(BlockVector3 min, BlockVector3 max, int layer, final Filter filter) {
int by = Math.max(min.getY(), layer << 4) & 15;
int ty = Math.min(max.getY(), 15 + (layer << 4)) & 15;
int bx = min.getX();
int bz = min.getZ();
int tx = max.getX();
int tz = max.getZ();
for (y = by; y <= ty; y++) {
int yIndex = (y << 8);
for (z = bz; z <= tz; z++) {
int zIndex = yIndex + ((z) << 4);
for (x = bx; x <= tx; x++) {
index = zIndex + x;
filter.applyBlock(this);
}
}
}
}
private final void iterate(final Filter filter) {
for (y = 0, index = 0; y < 16; y++) {
for (z = 0; z < 16; z++) {
for (x = 0; x < 16; x++, index++) {

View File

@ -16,8 +16,8 @@ public interface Filter {
* @param cz
* @return
*/
default Filter appliesChunk(final int cx, final int cz) {
return this;
default boolean appliesChunk(final int cx, final int cz) {
return true;
}
/**
@ -32,8 +32,8 @@ public interface Filter {
return chunk;
}
default Filter appliesLayer(IChunk chunk, int layer) {
return this;
default boolean appliesLayer(IChunk chunk, int layer) {
return true;
}
/**

View File

@ -1,6 +1,7 @@
package com.boydti.fawe.beta;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
@ -12,7 +13,7 @@ public interface FilterBlock {
FilterBlock init(int X, int Z, IGetBlocks chunk);
void filter(IGetBlocks get, ISetBlocks set, int layer, Filter filter, @Nullable Region region);
void filter(IGetBlocks get, ISetBlocks set, int layer, Filter filter, @Nullable Region region, BlockVector3 min, BlockVector3 max);
void setOrdinal(int ordinal);

View File

@ -1,10 +1,13 @@
package com.boydti.fawe.beta;
import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import javax.annotation.Nullable;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@ -61,23 +64,25 @@ public interface IChunk<T extends Future<T>> extends Trimable, Callable<T> {
return;
}
/**
* Filter
* @param filter the filter
* @param block The filter block
* @param region The region allowed to filter (may be null)
* @param unitialized a mutable block vector (buffer)
* @param unitialized2 a mutable block vector (buffer)
*/
void filter(Filter filter, FilterBlock block, @Nullable Region region, MutableBlockVector3 unitialized, MutableBlockVector3 unitialized2);
/* set - queues a change */
boolean setBiome(int x, int y, int z, BiomeType biome);
boolean setBlock(int x, int y, int z, BlockStateHolder block);
/**
* Set using the filter
* @param filter
*/
void set(Filter filter);
/* get - from the world */
BiomeType getBiome(int x, int z);
BlockState getBlock(int x, int y, int z);
BaseBlock getFullBlock(int x, int y, int z);
void filter(Filter filter, FilterBlock mutable);
}

View File

@ -1,10 +1,13 @@
package com.boydti.fawe.beta;
import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import javax.annotation.Nullable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@ -80,8 +83,8 @@ public interface IDelegateChunk<U extends IChunk> extends IChunk {
}
@Override
default void filter(final Filter filter, final FilterBlock mutable) {
getParent().filter(filter, mutable);
default void filter(Filter filter, FilterBlock block, @Nullable Region region, MutableBlockVector3 unitialized, MutableBlockVector3 unitialized2) {
getParent().filter(filter, block, region, unitialized, unitialized2);
}
@Override
@ -98,9 +101,4 @@ public interface IDelegateChunk<U extends IChunk> extends IChunk {
}
return null;
}
@Override
default void set(final Filter filter) {
getParent().set(filter);
}
}

View File

@ -1,33 +1,25 @@
package com.boydti.fawe.beta;
import com.sk89q.worldedit.regions.Region;
import javax.annotation.Nullable;
public interface IDelegateFilter extends Filter {
Filter getParent();
@Override
default Filter appliesChunk(int cx, int cz) {
Filter copy = getParent().appliesChunk(cx, cz);
if (copy == null) return null;
if (copy != getParent()) {
return newInstance(copy);
} else {
return this;
}
default boolean appliesChunk(int cx, int cz) {
return getParent().appliesChunk(cx, cz);
}
@Override
default IChunk applyChunk(IChunk chunk) {
return getParent().applyChunk(chunk);
default IChunk applyChunk(IChunk chunk, @Nullable Region region) {
return getParent().applyChunk(chunk, region);
}
@Override
default Filter appliesLayer(IChunk chunk, int layer) {
Filter copy = getParent().appliesLayer(chunk, layer);
if (copy == null) return null;
if (copy != getParent()) {
return newInstance(copy);
} else {
return this;
}
default boolean appliesLayer(IChunk chunk, int layer) {
return getParent().appliesLayer(chunk, layer);
}
@Override

View File

@ -1,37 +0,0 @@
package com.boydti.fawe.beta;
import com.sk89q.worldedit.regions.Region;
public class RegionFilter extends DelegateFilter {
private final Region region;
public RegionFilter(Filter parent, Region region) {
super(parent);
this.region = region;
}
@Override
public Filter appliesChunk(int cx, int cz) {
return getParent().appliesChunk(cx, cz);
}
@Override
public Filter appliesLayer(IChunk chunk, int layer) {
return getParent().appliesLayer(chunk, layer);
}
@Override
public void applyBlock(FilterBlock block) {
getParent().applyBlock(block);
}
@Override
public void finishChunk(IChunk chunk) {
getParent().finishChunk(chunk);
}
@Override
public Filter newInstance(Filter other) {
return new RegionFilter(other, region);
}
}

View File

@ -13,6 +13,7 @@ import com.boydti.fawe.util.MemUtil;
import com.boydti.fawe.util.TaskManager;
import com.boydti.fawe.wrappers.WorldWrapper;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.World;
@ -155,6 +156,9 @@ 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);
@ -162,7 +166,7 @@ public abstract class QueueHandler implements Trimable, Runnable {
FilterBlock block = null;
while (true) {
// Get the next chunk pos
// Get the next chunk posWeakChunk
final int X, Z;
synchronized (chunksIter) {
if (!chunksIter.hasNext()) break;
@ -177,12 +181,12 @@ public abstract class QueueHandler implements Trimable, Runnable {
// Initialize
chunk.init(queue, X, Z);
chunk = newFilter.applyChunk(chunk);
chunk = newFilter.applyChunk(chunk, region);
if (chunk == null) continue;
if (block == null) block = queue.initFilterBlock();
chunk.filter(newFilter, block);
chunk.filter(newFilter, block, region, mbv1, mbv2);
queue.submit(chunk);
}

View File

@ -10,11 +10,14 @@ import com.boydti.fawe.beta.ISetBlocks;
import com.boydti.fawe.beta.implementation.SingleThreadQueueExtent;
import com.boydti.fawe.beta.implementation.WorldChunkCache;
import com.boydti.fawe.util.MathMan;
import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import javax.annotation.Nullable;
import java.util.function.Supplier;
/**
@ -36,15 +39,44 @@ public abstract class ChunkHolder implements IChunk, Supplier<IGetBlocks> {
}
@Override
public void filter(final Filter filter, FilterBlock block) {
public void filter(final Filter filter, FilterBlock block, @Nullable Region region, final MutableBlockVector3 min, final MutableBlockVector3 max) {
final IGetBlocks get = getOrCreateGet();
final ISetBlocks set = getOrCreateSet();
block = block.init(X, Z, get);
for (int layer = 0; layer < 16; layer++) {
if (!get.hasSection(layer) || !filter.appliesLayer(this, layer)) continue;
block.filter(get, set, layer, filter);
try {
if (region != null) {
switch (region.getChunkBounds(X, Z, min, max)) {
case NONE:
System.out.println("NONE");
return;
case FULL:
if (min.getY() == 0 && max.getY() == 255) {
break;
}
case PARTIAL:
region = null;
case CHECKED:
default: {
int minLayer = min.getY() >> 4;
int maxLayer = max.getY() >> 4;
System.out.println("Layers " + minLayer + " | " + maxLayer);
block = block.init(X, Z, get);
for (int layer = minLayer; layer < maxLayer; layer++) {
if (!get.hasSection(layer) || !filter.appliesLayer(this, layer)) continue;
block.filter(get, set, layer, filter, region, min, max);
}
return;
}
}
}
block = block.init(X, Z, get);
for (int layer = 0; layer < 16; layer++) {
if (!get.hasSection(layer) || !filter.appliesLayer(this, layer)) continue;
block.filter(get, set, layer, filter, region, null, null);
}
} finally {
filter.finishChunk(this);
}
filter.finishChunk(this);
}
@Override