Permalink
Browse files

Restore generation of hollow shapes.

Unfortunately this is a bit slower than before since we can't cache block
id & data values. However, applying patterns generally isn't too expensive,
and hollow regions were entirely broken before.
  • Loading branch information...
wizjany committed Feb 10, 2019
1 parent cdd7117 commit 6708e8292f83c161fd4d3a8d72db2e98a70433ad
Showing with 85 additions and 0 deletions.
  1. +85 −0 worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryShape.java
@@ -34,8 +34,36 @@

protected final Region extent;

private int cacheOffsetX;
private int cacheOffsetY;
private int cacheOffsetZ;
private int cacheSizeX;
private int cacheSizeY;
private int cacheSizeZ;

/**
* Cache entires:
* 0 = unknown
* -1 = outside
* 1 = inside
*/
private final byte[] cache;

public ArbitraryShape(Region extent) {
this.extent = extent;

BlockVector3 min = extent.getMinimumPoint();
BlockVector3 max = extent.getMaximumPoint();

cacheOffsetX = min.getBlockX() - 1;
cacheOffsetY = min.getBlockY() - 1;
cacheOffsetZ = min.getBlockZ() - 1;

cacheSizeX = max.getX() - cacheOffsetX + 2;
cacheSizeY = max.getY() - cacheOffsetY + 2;
cacheSizeZ = max.getZ() - cacheOffsetZ + 2;

cache = new byte[cacheSizeX * cacheSizeY * cacheSizeZ];
}

protected Region getExtent() {
@@ -81,6 +109,40 @@ public int generate(EditSession editSession, Pattern pattern, boolean hollow) th

BaseBlock material = getMaterial(x, y, z, pattern.apply(position));
if (material == null) {
final int index = (y - cacheOffsetY) + (z - cacheOffsetZ) * cacheSizeY + (x - cacheOffsetX) * cacheSizeY * cacheSizeZ;
cache[index] = -1;
continue;
}

boolean draw = false;
do {
if (!isInsideCached(x + 1, y, z, pattern)) {
draw = true;
break;
}
if (!isInsideCached(x - 1, y, z, pattern)) {
draw = true;
break;
}
if (!isInsideCached(x, y, z + 1, pattern)) {
draw = true;
break;
}
if (!isInsideCached(x, y, z - 1, pattern)) {
draw = true;
break;
}
if (!isInsideCached(x, y + 1, z, pattern)) {
draw = true;
break;
}
if (!isInsideCached(x, y - 1, z, pattern)) {
draw = true;
break;
}
} while (false);

if (!draw) {
continue;
}

@@ -92,4 +154,27 @@ public int generate(EditSession editSession, Pattern pattern, boolean hollow) th
return affected;
}

private boolean isInsideCached(int x, int y, int z, Pattern pattern) {
final int index = (y - cacheOffsetY) + (z - cacheOffsetZ) * cacheSizeY + (x - cacheOffsetX) * cacheSizeY * cacheSizeZ;

switch (cache[index]) {
case 0:
BaseBlock mat = getMaterial(x, y, z, pattern.apply(BlockVector3.at(x, y, z)));
if (mat == null) {
cache[index] = -1;
return false;
}
cache[index] = 1;
return true;

case -1:
// outside
return false;

default:
// inside
return true;
}
}

}

0 comments on commit 6708e82

Please sign in to comment.