From f61093c29d28c08ca461626216033240161d04ea Mon Sep 17 00:00:00 2001 From: BuildTools Date: Sun, 12 Mar 2017 22:04:48 -0400 Subject: [PATCH] finished all add/remove methods, finished single block check --- ...{BitRegion2D.java => BitRegion2D_OLD.java} | 4 +- ...{BitRegion3D.java => BitRegion3D_OLD.java} | 4 +- src/regions/BitRegionUtil.java | 416 +++++++++ src/regions/CoordRegion.java | 7 - src/regions/Octree.java | 825 +++++++++++++----- src/regions/Quadtree.java | 510 ++++++----- src/regions/Tree.java | 46 +- 7 files changed, 1340 insertions(+), 472 deletions(-) rename src/regions/{BitRegion2D.java => BitRegion2D_OLD.java} (99%) rename src/regions/{BitRegion3D.java => BitRegion3D_OLD.java} (99%) create mode 100644 src/regions/BitRegionUtil.java delete mode 100644 src/regions/CoordRegion.java diff --git a/src/regions/BitRegion2D.java b/src/regions/BitRegion2D_OLD.java similarity index 99% rename from src/regions/BitRegion2D.java rename to src/regions/BitRegion2D_OLD.java index 548459a..4e446fe 100644 --- a/src/regions/BitRegion2D.java +++ b/src/regions/BitRegion2D_OLD.java @@ -2,7 +2,7 @@ package regions; import java.util.BitSet; -public class BitRegion2D +public class BitRegion2D_OLD { /* ╔══════════════════════════════════════════════════════════════════════════════════════════════╗ @@ -17,7 +17,7 @@ public class BitRegion2D protected final BitSet blocks; - public BitRegion2D() + public BitRegion2D_OLD() { sides = new int[] { 0, 0 }; blocks = new BitSet(); diff --git a/src/regions/BitRegion3D.java b/src/regions/BitRegion3D_OLD.java similarity index 99% rename from src/regions/BitRegion3D.java rename to src/regions/BitRegion3D_OLD.java index 2fbba59..e0f6f36 100644 --- a/src/regions/BitRegion3D.java +++ b/src/regions/BitRegion3D_OLD.java @@ -2,7 +2,7 @@ package regions; import java.util.BitSet; -public class BitRegion3D +public class BitRegion3D_OLD { /* ╔══════════════════════════════════════════════════════════════════════════════════════════════╗ @@ -17,7 +17,7 @@ public class BitRegion3D protected final BitSet blocks; - protected BitRegion3D() + protected BitRegion3D_OLD() { sides = new int[] { 0, 0, 0 }; blocks = new BitSet(); diff --git a/src/regions/BitRegionUtil.java b/src/regions/BitRegionUtil.java new file mode 100644 index 0000000..6aee707 --- /dev/null +++ b/src/regions/BitRegionUtil.java @@ -0,0 +1,416 @@ +package regions; + +import java.util.BitSet; + +/** + * + * @author Kevin Mathewson + * + */ +public class BitRegionUtil +{ + /* + ╔══════════════════════════════════════════════════════════════════════════════════════════════╗ + ║ ╔══════════════════════════════════════════════════════════════════════════════════════════╗ ║ + ║ ║ ║ ║ + ║ ║ 2D REGION ║ ║ + ║ ║ ║ ║ + ║ ╚══════════════════════════════════════════════════════════════════════════════════════════╝ ║ + ╚══════════════════════════════════════════════════════════════════════════════════════════════╝ */ + + public static class _2D + { + /*---------------------------------------------------------------------------- + ------------------------------------------------------------------------------ + index() + ------------------------------------------------------------------------------ + ----------------------------------------------------------------------------*/ + + + /** + * + * @param x + * @param z + * @param maxX2 + * @param maxZ2 + * @return + */ + public static int index(int x, int z, int maxX2, int maxZ2) + { + if (x < 0 || x >= maxX2 || z < 0 || z >= maxZ2) return -1; + + return (z * maxX2) + x; + } + + + /** + * + * @param x + * @param z + * @param minX2 + * @param minZ2 + * @param maxX2 + * @param maxZ2 + * @return + */ + public static int index(int x, int z, int minX2, int minZ2, int maxX2, int maxZ2) + { + if (x < minX2 || x >= maxX2 || z < minZ2 || z >= maxZ2) return -1; + + x -= minX2; + z -= minZ2; + maxX2 -= minX2; + + return (z * maxX2) + x; + } + + + /*---------------------------------------------------------------------------- + ------------------------------------------------------------------------------ + contains() + ------------------------------------------------------------------------------ + ----------------------------------------------------------------------------*/ + + + /** + * + * @param x + * @param z + * @param maxX2 + * @param maxZ2 + * @param blocks + * @return + */ + public static boolean contains(int x, int z, int maxX2, int maxZ2, BitSet blocks) + { + int index = index(x, z, maxX2, maxZ2); + + return index == -1 ? false : blocks.get(index); + } + + + /** + * + * @param x + * @param z + * @param minX2 + * @param minZ2 + * @param maxX2 + * @param maxZ2 + * @param blocks + * @return + */ + public static boolean contains(int x, int z, int minX2, int minZ2, int maxX2, int maxZ2, BitSet blocks) + { + int index = index(x, z, minX2, minZ2, maxX2, maxZ2); + + return index == -1 ? false : blocks.get(index); + } + + + /*---------------------------------------------------------------------------- + ------------------------------------------------------------------------------ + EVALUATE + ------------------------------------------------------------------------------ + ----------------------------------------------------------------------------*/ + + + /** + * + * @param value + * @param minX1 + * @param minZ1 + * @param maxX1 + * @param maxZ1 + * @param maxX2 + * @param maxZ2 + * @param blocks + * @return + */ + public static boolean testFor(boolean value, + int minX1, int minZ1, + int maxX1, int maxZ1, + int maxX2, int maxZ2, + BitSet blocks + ) + { + int z, x, index; + for (z = minZ1; z < maxZ1; z++) + { + index = index(x = minX1, z, maxX2, maxZ2); + for (; x < maxX1; x++) + { + if (blocks.get(index++) == value) + return true; + } + } + return false; + } + + + /** + * + * @param minX1 + * @param minZ1 + * @param minY1 + * @param maxX1 + * @param maxZ1 + * @param maxY1 + * @param maxX2 + * @param maxZ2 + * @param maxY2 + * @param blocks + * @return + */ + public static int compareRegion(int minX1, int minZ1, + int maxX1, int maxZ1, + int maxX2, int maxZ2, + BitSet blocks + ) + { + boolean firstBlock = blocks.get(index(minX1, minZ1, maxX2, maxZ2)); + + return testFor(!firstBlock, minX1, minZ1, maxX1, maxZ1, maxX2, maxZ2, blocks) + + ? 0 : firstBlock ? 2 : 1; + } + + + /** + * + * @param minX1 + * @param minZ1 + * @param maxX1 + * @param maxZ1 + * @param minX2 + * @param minZ2 + * @param maxX2 + * @param maxZ2 + * @param blocks + * @return + */ + public static int compareRegion(int minX1, int minZ1, int maxX1, int maxZ1, + int minX2, int minZ2, int maxX2, int maxZ2, + BitSet blocks + ) + { + minX1 -= minX2; minZ1 -= minZ2; + maxX1 -= minX2; maxZ1 -= minZ2; + maxX2 -= minX2; maxZ2 -= minZ2; + + return compareRegion(minX1, minZ1, maxX1, maxZ1, maxX2, maxZ2, blocks); + } + } + + /* + ╔══════════════════════════════════════════════════════════════════════════════════════════════╗ + ║ ╔══════════════════════════════════════════════════════════════════════════════════════════╗ ║ + ║ ║ ║ ║ + ║ ║ 3D REGION ║ ║ + ║ ║ ║ ║ + ║ ╚══════════════════════════════════════════════════════════════════════════════════════════╝ ║ + ╚══════════════════════════════════════════════════════════════════════════════════════════════╝ */ + + public static class _3D + { + /*---------------------------------------------------------------------------- + ------------------------------------------------------------------------------ + index() + ------------------------------------------------------------------------------ + ----------------------------------------------------------------------------*/ + + + /** + * + * @param x + * @param z + * @param y + * @param maxX2 + * @param maxZ2 + * @param maxY2 + * @return + */ + public static int index(int x, int z, int y, int maxX2, int maxZ2, int maxY2) + { + if (x < 0 || x >= maxX2 || z < 0 || z >= maxZ2 || y < 0 || y >= maxY2) return -1; + + return (y * maxZ2 * maxX2) + (z * maxX2) + x; + } + + + /** + * + * @param x + * @param z + * @param y + * @param minX2 + * @param minZ2 + * @param minY2 + * @param maxX2 + * @param maxZ2 + * @param maxY2 + * @return + */ + public static int index(int x, int z, int y, int minX2, int minZ2, int minY2, int maxX2, int maxZ2, int maxY2) + { + if (x < minX2 || x >= maxX2 || z < minZ2 || z >= maxZ2 || y < minY2 || y >= maxY2) return -1; + + x -= minX2; + z -= minZ2; + y -= minY2; + maxX2 -= minX2; + maxZ2 -= minZ2; + + return (y * maxZ2 * maxX2) + (z * maxX2) + x; + } + + + /*---------------------------------------------------------------------------- + ------------------------------------------------------------------------------ + contains() + ------------------------------------------------------------------------------ + ----------------------------------------------------------------------------*/ + + + /** + * + * @param x + * @param z + * @param y + * @param maxX2 + * @param maxZ2 + * @param maxY2 + * @param blocks + * @return + */ + public static boolean contains(int x, int z, int y, int maxX2, int maxZ2, int maxY2, BitSet blocks) + { + int index = index(x, z, y, maxX2, maxZ2, maxY2); + + return index == -1 ? false : blocks.get(index); + } + + + /** + * + * @param x + * @param z + * @param y + * @param minX2 + * @param minZ2 + * @param minY2 + * @param maxX2 + * @param maxZ2 + * @param maxY2 + * @param blocks + * @return + */ + public static boolean contains(int x, int z, int y, int minX2, int minZ2, int minY2, int maxX2, int maxZ2, int maxY2, BitSet blocks) + { + int index = index(x, z, y, minX2, minZ2, minY2, maxX2, maxZ2, maxY2); + + return index == -1 ? false : blocks.get(index); + } + + + /*---------------------------------------------------------------------------- + ------------------------------------------------------------------------------ + EVALUATE + ------------------------------------------------------------------------------ + ----------------------------------------------------------------------------*/ + + + /** + * + * @param value + * @param minX1 + * @param minZ1 + * @param minY1 + * @param maxX1 + * @param maxZ1 + * @param maxY1 + * @param maxX2 + * @param maxZ2 + * @param maxY2 + * @param blocks + * @return + */ + public static boolean testFor(boolean value, + int minX1, int minZ1, int minY1, + int maxX1, int maxZ1, int maxY1, + int maxX2, int maxZ2, int maxY2, + BitSet blocks + ) + { + int y, z, x, index; + for (y = minY1; y < maxY1; y++) for (z = minZ1; z < maxZ1; z++) + { + index = index(x = minX1, z, y, maxX2, maxZ2, maxY2); + for (; x < maxX1; x++) + { + if (blocks.get(index++) == value) + return true; + } + } + return false; + } + + + /** + * + * @param minX1 + * @param minZ1 + * @param minY1 + * @param maxX1 + * @param maxZ1 + * @param maxY1 + * @param maxX2 + * @param maxZ2 + * @param maxY2 + * @param blocks + * @return + */ + public static int compareRegion(int minX1, int minZ1, int minY1, + int maxX1, int maxZ1, int maxY1, + int maxX2, int maxZ2, int maxY2, + BitSet blocks + ) + { + boolean firstBlock = blocks.get(index(minX1, minZ1, minY1, maxX2, maxZ2, maxY2)); + + return testFor(!firstBlock, minX1, minZ1, minY1, maxX1, maxZ1, maxY1, maxX2, maxZ2, maxY2, blocks) + + ? 0 : firstBlock ? 2 : 1; + } + + + /** + * + * @param minX1 + * @param minZ1 + * @param minY1 + * @param maxX1 + * @param maxZ1 + * @param maxY1 + * @param minX2 + * @param minZ2 + * @param minY2 + * @param maxX2 + * @param maxZ2 + * @param maxY2 + * @param blocks + * @return + */ + public static int compareRegion(int minX1, int minZ1, int minY1, int maxX1, int maxZ1, int maxY1, + int minX2, int minZ2, int minY2, int maxX2, int maxZ2, int maxY2, + BitSet blocks + ) + { + minX1 -= minX2; minZ1 -= minZ2; minY1 -= minY2; + maxX1 -= minX2; maxZ1 -= minZ2; maxY1 -= minY2; + maxX2 -= minX2; maxZ2 -= minZ2; maxY2 -= minY2; + + return compareRegion(minX1, minZ1, minY1, maxX1, maxZ1, maxY1, maxX2, maxZ2, maxY2, blocks); + } + } +} diff --git a/src/regions/CoordRegion.java b/src/regions/CoordRegion.java deleted file mode 100644 index 92ed37e..0000000 --- a/src/regions/CoordRegion.java +++ /dev/null @@ -1,7 +0,0 @@ -package regions; - -public class CoordRegion -{ - // 2896 is the maximum side length for a 3D, square, resolution 1 region with height 256 - // 128 is the coarsest resolution for a 3D region -} diff --git a/src/regions/Octree.java b/src/regions/Octree.java index 9fc4056..f2200bb 100644 --- a/src/regions/Octree.java +++ b/src/regions/Octree.java @@ -89,11 +89,44 @@ public class Octree extends Tree @Override public boolean contains(int... coords) { - if (coords[0] < min[0] || coords[0] > max[0] || - coords[1] < min[1] || coords[1] > max[1] || - coords[2] < min[2] || coords[2] > max[2] + if (coords[0] < min[0] || coords[0] >= max[0] || + coords[1] < min[1] || coords[1] >= max[1] || + coords[2] < min[2] || coords[2] >= max[2] ) return false; + + int half = max[0] - min[0] >>> 1, + minX = min[0], + minZ = min[1], + minY = min[2]; + + Node node = root; + int index; + while (true) + { + if (node.full) return true; + else if (node.children == null) + return false; + + index = 0; + if (minX + half <= coords[0]) + { + minX += half; + index += 1; + } + if (minZ + half <= coords[1]) + { + minZ += half; + index += 2; + } + if (minY + half <= coords[2]) + { + minY += half; + index += 4; + } + half >>>= 1; + node = node.children[index]; + } } @@ -113,87 +146,84 @@ public class Octree extends Tree ----------------------------------------------------------------------------*/ /** * - * @param xMinExpansion - * @param zMinExpansion - * @param yMinExpansion - * @param xMaxExpansion - * @param zMaxExpansion - * @param yMaxExpansion + * @param xMinPercent + * @param zMinPercent + * @param yMinPercent + * @param xMaxPercent + * @param zMaxPercent + * @param yMaxPercent */ - protected void expand(double xMinExpansion, double zMinExpansion, double yMinExpansion, - double xMaxExpansion, double zMaxExpansion, double yMaxExpansion + protected void expand(double xMinPercent, double zMinPercent, double yMinPercent, + double xMaxPercent, double zMaxPercent, double yMaxPercent ) { - int xMinCeil = (int) Math.ceil(xMinExpansion), - zMinCeil = (int) Math.ceil(zMinExpansion), - yMinCeil = (int) Math.ceil(yMinExpansion), - xMaxCeil = (int) Math.ceil(xMaxExpansion), - zMaxCeil = (int) Math.ceil(zMaxExpansion), - yMaxCeil = (int) Math.ceil(yMaxExpansion), + int xMin = (int) Math.ceil(xMinPercent), + zMin = (int) Math.ceil(zMinPercent), + yMin = (int) Math.ceil(yMinPercent), + xMax = (int) Math.ceil(xMaxPercent), + zMax = (int) Math.ceil(zMaxPercent), + yMax = (int) Math.ceil(yMaxPercent), - size = nextPowerOfTwo(xMinCeil + xMaxCeil + 1, - zMinCeil + zMaxCeil + 1, - yMinCeil + yMaxCeil + 1 + size = nextPowerOfTwo(xMin + xMax + 1, + zMin + zMax + 1, + yMin + yMax + 1 ), - xMargin = size - (xMinCeil + xMaxCeil + 1), - zMargin = size - (zMinCeil + zMaxCeil + 1), - yMargin = size - (yMinCeil + yMaxCeil + 1), + xMargin = size - (xMin + xMax + 1), + zMargin = size - (zMin + zMax + 1), + yMargin = size - (yMin + yMax + 1), xMarginHalf = xMargin / 2, zMarginHalf = zMargin / 2, yMarginHalf = yMargin / 2; - xMinCeil += xMarginHalf; - zMinCeil += zMarginHalf; - yMinCeil += yMarginHalf; - xMaxCeil += xMarginHalf; - zMaxCeil += zMarginHalf; - yMaxCeil += yMarginHalf; + xMin += xMarginHalf; + zMin += zMarginHalf; + yMin += yMarginHalf; + xMax += xMarginHalf; + zMax += zMarginHalf; + yMax += yMarginHalf; + if (xMargin % 2 == 1) if (xMin - xMinPercent > xMax - xMaxPercent) xMin++; else xMax++; + if (zMargin % 2 == 1) if (zMin - zMinPercent > zMax - zMaxPercent) zMin++; else zMax++; + if (yMargin % 2 == 1) if (yMin - yMinPercent > yMax - yMaxPercent) yMin++; else yMax++; - if (xMargin % 2 == 1) if (xMinCeil - xMinExpansion > xMaxCeil - xMaxExpansion) xMinCeil++; else xMaxCeil++; - - if (zMargin % 2 == 1) if (zMinCeil - zMinExpansion > zMaxCeil - zMaxExpansion) zMinCeil++; else zMaxCeil++; - - if (yMargin % 2 == 1) if (yMinCeil - yMinExpansion > yMaxCeil - yMaxExpansion) yMinCeil++; else yMaxCeil++; - - int sideLength = max[0] - min[0] + 1; - min[0] -= (sideLength * xMinCeil); - min[1] -= (sideLength * zMinCeil); - min[2] -= (sideLength * yMinCeil); - max[0] += (sideLength * xMaxCeil); - max[1] += (sideLength * zMaxCeil); - max[2] += (sideLength * yMaxCeil); + int sideLength = max[0] - min[0]; + min[0] -= (sideLength * xMin); + min[1] -= (sideLength * zMin); + min[2] -= (sideLength * yMin); + max[0] += (sideLength * xMax); + max[1] += (sideLength * zMax); + max[2] += (sideLength * yMax); int index; Node[] children; Node[] newRootChildren = children = Node.emptyNodeArray(8); - while(true) + while (true) { size >>>= 1; index = 0; - if (xMinCeil >= size) - xMinCeil -= size; + if (xMin >= size) + xMin -= size; else { - xMaxCeil -= size; + xMax -= size; index += 1; } - if (zMinCeil >= size) - zMinCeil -= size; + if (zMin >= size) + zMin -= size; else { - zMaxCeil -= size; + zMax -= size; index += 2; } - if (yMinCeil >= size) - yMinCeil -= size; + if (yMin >= size) + yMin -= size; else { - yMaxCeil -= size; + yMax -= size; index += 4; } @@ -220,74 +250,74 @@ public class Octree extends Tree @Override protected void expandAsNeeded(int... coords) { - int sideLength = max[0] - min[0] + 1; + int sideLength = max[0] - min[0]; - double xMinExpansion = 0, - zMinExpansion = 0, - yMinExpansion = 0, - xMaxExpansion = 0, - zMaxExpansion = 0, - yMaxExpansion = 0; + double xMinPercent = 0, + zMinPercent = 0, + yMinPercent = 0, + xMaxPercent = 0, + zMaxPercent = 0, + yMaxPercent = 0; - if (coords[0] < min[0]) xMinExpansion = (min[0] - coords[0]) / sideLength; - else if (coords[0] > max[0]) xMaxExpansion = (coords[0] - max[0]) / sideLength; + if (coords[0] < min[0]) xMinPercent = (min[0] - coords[0]) / sideLength; + else if (coords[0] >= max[0]) xMaxPercent = (coords[0] - max[0]) / sideLength; - if (coords[1] < min[1]) xMinExpansion = (min[1] - coords[1]) / sideLength; - else if (coords[1] > max[1]) xMaxExpansion = (coords[1] - max[1]) / sideLength; + if (coords[1] < min[1]) xMinPercent = (min[1] - coords[1]) / sideLength; + else if (coords[1] >= max[1]) xMaxPercent = (coords[1] - max[1]) / sideLength; - if (coords[2] < min[2]) xMinExpansion = (min[2] - coords[2]) / sideLength; - else if (coords[2] > max[2]) xMaxExpansion = (coords[2] - max[2]) / sideLength; + if (coords[2] < min[2]) xMinPercent = (min[2] - coords[2]) / sideLength; + else if (coords[2] >= max[2]) xMaxPercent = (coords[2] - max[2]) / sideLength; - if (xMinExpansion != 0 || - zMinExpansion != 0 || - yMinExpansion != 0 || - xMaxExpansion != 0 || - zMaxExpansion != 0 || - yMaxExpansion != 0 + if (xMinPercent != 0 || + zMinPercent != 0 || + yMinPercent != 0 || + xMaxPercent != 0 || + zMaxPercent != 0 || + yMaxPercent != 0 ) - expand(xMinExpansion, - zMinExpansion, - yMinExpansion, - xMaxExpansion, - zMaxExpansion, - yMaxExpansion); + expand(xMinPercent, + zMinPercent, + yMinPercent, + xMaxPercent, + zMaxPercent, + yMaxPercent); } @Override public void expandAsNeeded(int[]... bounds) { - int sideLength = max[0] - min[0] + 1; + int sideLength = max[0] - min[0]; - double xMinExpansion = 0, - zMinExpansion = 0, - yMinExpansion = 0, - xMaxExpansion = 0, - zMaxExpansion = 0, - yMaxExpansion = 0; + double xMinPercent = 0, + zMinPercent = 0, + yMinPercent = 0, + xMaxPercent = 0, + zMaxPercent = 0, + yMaxPercent = 0; - if (bounds[0][0] < min[0]) xMinExpansion = (min[0] - bounds[0][0]) / sideLength; - if (bounds[0][1] > max[0]) xMaxExpansion = (bounds[0][1] - max[0]) / sideLength; + if (bounds[0][0] < min[0]) xMinPercent = (min[0] - bounds[0][0]) / sideLength; + if (bounds[0][1] >= max[0]) xMaxPercent = (bounds[0][1] - max[0]) / sideLength; - if (bounds[1][0] < min[1]) zMinExpansion = (min[1] - bounds[1][0]) / sideLength; - if (bounds[1][1] > max[1]) zMaxExpansion = (bounds[1][1] - max[1]) / sideLength; + if (bounds[1][0] < min[1]) zMinPercent = (min[1] - bounds[1][0]) / sideLength; + if (bounds[1][1] >= max[1]) zMaxPercent = (bounds[1][1] - max[1]) / sideLength; - if (bounds[2][0] < min[2]) yMinExpansion = (min[2] - bounds[2][0]) / sideLength; - if (bounds[2][1] > max[2]) yMaxExpansion = (bounds[2][1] - max[2]) / sideLength; + if (bounds[2][0] < min[2]) yMinPercent = (min[2] - bounds[2][0]) / sideLength; + if (bounds[2][1] >= max[2]) yMaxPercent = (bounds[2][1] - max[2]) / sideLength; - if (xMinExpansion != 0 || - zMinExpansion != 0 || - yMinExpansion != 0 || - xMaxExpansion != 0 || - zMaxExpansion != 0 || - yMaxExpansion != 0 + if (xMinPercent != 0 || + zMinPercent != 0 || + yMinPercent != 0 || + xMaxPercent != 0 || + zMaxPercent != 0 || + yMaxPercent != 0 ) - expand(xMinExpansion, - zMinExpansion, - yMinExpansion, - xMaxExpansion, - zMaxExpansion, - yMaxExpansion); + expand(xMinPercent, + zMinPercent, + yMinPercent, + xMaxPercent, + zMaxPercent, + yMaxPercent); } @@ -310,8 +340,7 @@ public class Octree extends Tree * @param blockX * @param blockZ */ - protected void add(Node node, - int half, + protected void add(Node node, int half, int node_minX, int node_minZ, int node_minY, int node_maxX, int node_maxZ, int node_maxY, int blockX, int blockZ, int blockY ) @@ -343,8 +372,7 @@ public class Octree extends Tree index += 4; } - if (half > 1) add(node.children[index], - half >>>= 1, + if (half > 1) add(node.children[index], half >>>= 1, node_minX, node_minZ, node_minY, node_maxX, node_maxZ, node_maxY, blockX, blockZ, blockY ); @@ -369,8 +397,7 @@ public class Octree extends Tree { expandAsNeeded(coords); - add(root, - (max[0] - min[0] + 1) / 2, + add(root, max[0] - min[0] >>> 1, min[0], min[1], min[2], max[0], max[1], max[2], coords[0], coords[1], coords[2] ); @@ -402,8 +429,7 @@ public class Octree extends Tree * @param sel_maxZ * @param sel_maxY */ - protected void add(Node node, - int half, + protected void add(Node node, int half, int node_minX, int node_minZ, int node_minY, int node_maxX, int node_maxZ, int node_maxY, int sel_minX, int sel_minZ, int sel_minY, int sel_maxX, int sel_maxZ, int sel_maxY ) @@ -426,30 +452,27 @@ public class Octree extends Tree } return; } - if (node_maxY < sel_minY) + if (node_maxY <= sel_minY) return; } - if (node_minY > sel_maxY || node_maxY < sel_minY) + if (node_minY >= sel_maxY || node_maxY <= sel_minY) return; } - if (node_maxZ < sel_minZ || node_minY > sel_maxY || node_maxY < sel_minY) + if (node_maxZ <= sel_minZ || node_minY >= sel_maxY || node_maxY <= sel_minY) return; } - if (node_minZ > sel_maxZ || node_maxZ < sel_minZ || node_minY > sel_maxY || node_maxY < sel_minY) + if (node_minZ >= sel_maxZ || node_maxZ <= sel_minZ || node_minY >= sel_maxY || node_maxY <= sel_minY) return; } - if (node_maxX < sel_minX || node_minZ > sel_maxZ || node_maxZ < sel_minZ || node_minY > sel_maxY || node_maxY < sel_minY) + if (node_maxX <= sel_minX || node_minZ >= sel_maxZ || node_maxZ <= sel_minZ || node_minY >= sel_maxY || node_maxY <= sel_minY) return; if (node.children == null) node.children = Node.emptyNodeArray(8); - int half_minX = min[0] + half, - half_maxX = half_minX - 1, - half_minZ = min[1] + half, - half_maxZ = half_minZ - 1, - half_minY = min[2] + half, - half_maxY = half_minY - 1; + int midpointX = min[0] + half, + midpointZ = min[1] + half, + midpointY = min[2] + half; half >>>= 1; @@ -469,49 +492,49 @@ public class Octree extends Tree add(node.children[0], half, - node_minX, node_minZ, node_minY, half_maxX, half_maxZ, half_maxY, + node_minX, node_minZ, node_minY, midpointX, midpointZ, midpointY, sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY ); add(node.children[1], half, - half_minX, node_minZ, node_minY, node_maxX, half_maxZ, half_maxY, + midpointX, node_minZ, node_minY, node_maxX, midpointZ, midpointY, sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY ); add(node.children[2], half, - node_minX, half_minZ, node_minY, half_maxX, node_maxZ, half_maxY, + node_minX, midpointZ, node_minY, midpointX, node_maxZ, midpointY, sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY ); add(node.children[3], half, - half_minX, half_minZ, node_minY, node_maxX, node_maxZ, half_maxY, + midpointX, midpointZ, node_minY, node_maxX, node_maxZ, midpointY, sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY ); add(node.children[4], half, - node_minX, node_minZ, half_minY, half_maxX, half_maxZ, node_maxY, + node_minX, node_minZ, midpointY, midpointX, midpointZ, node_maxY, sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY ); add(node.children[5], half, - half_minX, node_minZ, half_minY, node_maxX, half_maxZ, node_maxY, + midpointX, node_minZ, midpointY, node_maxX, midpointZ, node_maxY, sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY ); add(node.children[6], half, - node_minX, half_minZ, half_minY, half_maxX, node_maxZ, node_maxY, + node_minX, midpointZ, midpointY, midpointX, node_maxZ, node_maxY, sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY ); add(node.children[7], half, - half_minX, half_minZ, half_minY, node_maxX, node_maxZ, node_maxY, + midpointX, midpointZ, midpointY, node_maxX, node_maxZ, node_maxY, sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY ); @@ -532,8 +555,7 @@ public class Octree extends Tree { expandAsNeeded(bounds); - add(root, - (max[0] - min[0] + 1), + add(root, max[0] - min[0] >>> 1, min[0], min[1], min[2], max[0], max[1], max[2], bounds[0][0], bounds[1][0], bounds[2][0], bounds[0][1], bounds[1][1], bounds[2][1] ); @@ -548,6 +570,44 @@ public class Octree extends Tree ----------------------------------------------------------------------------*/ + /** + * + * @param node + * @param node_minX + * @param node_minZ + * @param node_minY + * @param node_maxX + * @param node_maxZ + * @param node_maxY + * @param sel_minX + * @param sel_minZ + * @param sel_minY + * @param sel_maxX + * @param sel_maxZ + * @param sel_maxY + * @param blocks + * @return + */ + protected static boolean attemptAdd(Node node, + int node_minX, int node_minZ, int node_minY, int node_maxX, int node_maxZ, int node_maxY, + int sel_minX, int sel_minZ, int sel_minY, int sel_maxX, int sel_maxZ, int sel_maxY, + BitSet blocks + ) + { + int partial = _3D.compareRegion(node_minX, node_minZ, node_minY, node_maxX, node_maxZ, node_maxY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY, + blocks + ); + + if (partial == 0) return false; + if (partial == 1) return true; + + node.full = false; + node.children = null; + return true; + } + + /** * * @param node @@ -566,55 +626,29 @@ public class Octree extends Tree * @param sel_maxY * @param blocks */ - protected void add(Node node, - int half, + protected void add(Node node, int half, int node_minX, int node_minZ, int node_minY, int node_maxX, int node_maxZ, int node_maxY, int sel_minX, int sel_minZ, int sel_minY, int sel_maxX, int sel_maxZ, int sel_maxY, BitSet blocks ) { - if (node.full) return; - if (node_minX >= sel_minX) - { - if (node_maxX <= sel_maxX) - { - if (node_minZ >= sel_minZ) - { - if (node_maxZ <= sel_maxZ) - { - if (node_minY >= sel_minY) - { - if (node_maxY <= sel_maxY) - { - node.full = true; - node.children = null; - } - return; - } - if (node_maxY < sel_minY) - return; - } - if (node_minY > sel_maxY || node_maxY < sel_minY) - return; - } - if (node_maxZ < sel_minZ || node_minY > sel_maxY || node_maxY < sel_minY) - return; - } - if (node_minZ > sel_maxZ || node_maxZ < sel_minZ || node_minY > sel_maxY || node_maxY < sel_minY) - return; - } - if (node_maxX < sel_minX || node_minZ > sel_maxZ || node_maxZ < sel_minZ || node_minY > sel_maxY || node_maxY < sel_minY) + if (node.full || + node_minX >= sel_maxX || node_maxX <= sel_minX || + node_minZ >= sel_maxZ || node_maxZ <= sel_minZ || + node_minY >= sel_maxY || node_maxY <= sel_minY || + attemptAdd(node, + node_minX, node_minZ, node_minY, node_maxX, node_maxZ, node_maxY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY, + blocks + )) return; if (node.children == null) node.children = Node.emptyNodeArray(8); - int half_minX = min[0] + half, - half_maxX = half_minX - 1, - half_minZ = min[1] + half, - half_maxZ = half_minZ - 1, - half_minY = min[2] + half, - half_maxY = half_minY - 1; + int midpointX = min[0] + half, + midpointZ = min[1] + half, + midpointY = min[2] + half; half >>>= 1; @@ -632,52 +666,52 @@ public class Octree extends Tree ║ ║ ║ ║ ║ ║ Z ╚═════════╩═════════╝ Z ╚═════════╩═════════╝*/ - add(node.children[0], - half, - node_minX, node_minZ, node_minY, half_maxX, half_maxZ, half_maxY, - sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY + add(node.children[0], half, + node_minX, node_minZ, node_minY, midpointX, midpointZ, midpointY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY, + blocks ); - add(node.children[1], - half, - half_minX, node_minZ, node_minY, node_maxX, half_maxZ, half_maxY, - sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY + add(node.children[1], half, + midpointX, node_minZ, node_minY, node_maxX, midpointZ, midpointY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY, + blocks ); - add(node.children[2], - half, - node_minX, half_minZ, node_minY, half_maxX, node_maxZ, half_maxY, - sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY + add(node.children[2], half, + node_minX, midpointZ, node_minY, midpointX, node_maxZ, midpointY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY, + blocks ); - add(node.children[3], - half, - half_minX, half_minZ, node_minY, node_maxX, node_maxZ, half_maxY, - sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY + add(node.children[3], half, + midpointX, midpointZ, node_minY, node_maxX, node_maxZ, midpointY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY, + blocks ); - add(node.children[4], - half, - node_minX, node_minZ, half_minY, half_maxX, half_maxZ, node_maxY, - sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY + add(node.children[4], half, + node_minX, node_minZ, midpointY, midpointX, midpointZ, node_maxY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY, + blocks ); - add(node.children[5], - half, - half_minX, node_minZ, half_minY, node_maxX, half_maxZ, node_maxY, - sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY + add(node.children[5], half, + midpointX, node_minZ, midpointY, node_maxX, midpointZ, node_maxY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY, + blocks ); - add(node.children[6], - half, - node_minX, half_minZ, half_minY, half_maxX, node_maxZ, node_maxY, - sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY + add(node.children[6], half, + node_minX, midpointZ, midpointY, midpointX, node_maxZ, node_maxY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY, + blocks ); - add(node.children[7], - half, - half_minX, half_minZ, half_minY, node_maxX, node_maxZ, node_maxY, - sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY + add(node.children[7], half, + midpointX, midpointZ, midpointY, node_maxX, node_maxZ, node_maxY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY, + blocks ); if (node.children[0].full && node.children[1].full && @@ -697,8 +731,7 @@ public class Octree extends Tree { expandAsNeeded(bounds); - add(root, - (max[0] - min[0] + 1), + add(root, max[0] - min[0] >>> 1, min[0], min[1], min[2], max[0], max[1], max[2], bounds[0][0], bounds[1][0], bounds[2][0], bounds[0][1], bounds[1][1], bounds[2][1], blocks @@ -730,7 +763,7 @@ public class Octree extends Tree while (!root.full && root.children != null) { - half = (max[0] - min[0] + 1) / 2; + half = max[0] - min[0] >>> 1; if (root.children[0].children != null) { if (root.children[1].children == null && @@ -857,11 +890,83 @@ public class Octree extends Tree ------------------------------------------------------------------------------ ----------------------------------------------------------------------------*/ + + /** + * + * @param node + * @param half + * @param node_minX + * @param node_minZ + * @param node_maxX + * @param node_maxZ + * @param blockX + * @param blockZ + */ + protected void remove(Node node, int half, + int node_minX, int node_minZ, int node_minY, int node_maxX, int node_maxZ, int node_maxY, + int blockX, int blockZ, int blockY + ) + { + if (node.full) + { + node.full = false; + node.children = Node.fullNodeArray(4); + } + else if (node.children == null) return; + + int index = 0; + + if (node_minX + half > blockX) + node_maxX -= half; + else + { + node_minX += half; + index += 1; + } + if (node_minZ + half > blockZ) + node_maxZ -= half; + else + { + node_minZ += half; + index += 2; + } + if (node_minY + half > blockY) + node_maxY -= half; + else + { + node_minY += half; + index += 4; + } + + if (half > 1) add(node.children[index], half >>>= 1, + node_minX, node_minZ, node_minY, node_maxX, node_maxZ, node_maxY, + blockX, blockZ, blockY + ); + else + { + node.children[index].full = true; + if (node.children[0].full && node.children[1].full && + node.children[2].full && node.children[3].full && + node.children[4].full && node.children[5].full && + node.children[6].full && node.children[7].full + ) + { + node.full = true; + node.children = null; + } + } + } + @Override public void remove(int... coords) { - // TODO Auto-generated method stub + remove(root, max[0] - min[0] >>> 1, + min[0], min[1], min[2], max[0], max[1], max[2], + coords[0], coords[1], coords[2] + ); + + trimAsNeeded(); } @@ -873,10 +978,150 @@ public class Octree extends Tree ----------------------------------------------------------------------------*/ + /** + * + * @param node + * @param half + * @param node_minX + * @param node_minZ + * @param node_minY + * @param node_maxX + * @param node_maxZ + * @param node_maxY + * @param sel_minX + * @param sel_minZ + * @param sel_minY + * @param sel_maxX + * @param sel_maxZ + * @param sel_maxY + */ + protected void remove(Node node, + int half, + int node_minX, int node_minZ, int node_minY, int node_maxX, int node_maxZ, int node_maxY, + int sel_minX, int sel_minZ, int sel_minY, int sel_maxX, int sel_maxZ, int sel_maxY + ) + { + if (!node.full && node.children == null) return; + + if (node_minX >= sel_minX) + { + if (node_maxX <= sel_maxX) + { + if (node_minZ >= sel_minZ) + { + if (node_maxZ <= sel_maxZ) + { + if (node_minY >= sel_minY) + { + if (node_maxY <= sel_maxY) + { + node.full = true; + node.children = null; + } + return; + } + if (node_maxY <= sel_minY) + return; + } + if (node_minY >= sel_maxY || node_maxY <= sel_minY) + return; + } + if (node_maxZ <= sel_minZ || node_minY >= sel_maxY || node_maxY <= sel_minY) + return; + } + if (node_minZ >= sel_maxZ || node_maxZ <= sel_minZ || node_minY >= sel_maxY || node_maxY <= sel_minY) + return; + } + if (node_maxX <= sel_minX || node_minZ >= sel_maxZ || node_maxZ <= sel_minZ || node_minY >= sel_maxY || node_maxY <= sel_minY) + return; + + if (node.full) + { + node.full = false; + node.children = Node.fullNodeArray(8); + } + + int midpointX = min[0] + half, + midpointZ = min[1] + half, + midpointY = min[2] + half; + + half >>>= 1; + + + /* child index: + Y → Y + X → X X → X + Z ╔═════════╦═════════╗ Z ╔═════════╦═════════╗ + ║ ║ ║ ║ ║ ║ + ║ 0 ║ 1 ║ ║ 4 ║ 5 ║ + ║ ║ ║ ║ ║ ║ + ↓ ╠═════════╬═════════╣ ↓ ╠═════════╬═════════╣ + ║ ║ ║ ║ ║ ║ + ║ 2 ║ 3 ║ ║ 6 ║ 7 ║ + ║ ║ ║ ║ ║ ║ + Z ╚═════════╩═════════╝ Z ╚═════════╩═════════╝*/ + + remove(node.children[0], half, + node_minX, node_minZ, node_minY, midpointX, midpointZ, midpointY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY + ); + + remove(node.children[1], half, + midpointX, node_minZ, node_minY, node_maxX, midpointZ, midpointY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY + ); + + remove(node.children[2], half, + node_minX, midpointZ, node_minY, midpointX, node_maxZ, midpointY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY + ); + + remove(node.children[3], half, + midpointX, midpointZ, node_minY, node_maxX, node_maxZ, midpointY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY + ); + + remove(node.children[4], half, + node_minX, node_minZ, midpointY, midpointX, midpointZ, node_maxY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY + ); + + remove(node.children[5], half, + midpointX, node_minZ, midpointY, node_maxX, midpointZ, node_maxY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY + ); + + remove(node.children[6], half, + node_minX, midpointZ, midpointY, midpointX, node_maxZ, node_maxY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY + ); + + remove(node.children[7], half, + midpointX, midpointZ, midpointY, node_maxX, node_maxZ, node_maxY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY + ); + + if (node.children[0].children == null && node.children[1].children == null && + node.children[2].children == null && node.children[3].children == null && + node.children[4].children == null && node.children[5].children == null && + node.children[6].children == null && node.children[7].children == null + ) + { + node.full = false; + node.children = null; + } + } + + @Override public void remove(int[]... bounds) { - // TODO Auto-generated method stub + remove(root, max[0] - min[0] >>> 1, + min[0], min[1], min[2], max[0], max[1], max[2], + bounds[0][0], bounds[1][0], bounds[2][0], bounds[0][1], bounds[1][1], bounds[2][1] + ); + + trimAsNeeded(); } @@ -888,9 +1133,173 @@ public class Octree extends Tree ----------------------------------------------------------------------------*/ + /** + * + * @param node + * @param node_minX + * @param node_minZ + * @param node_minY + * @param node_maxX + * @param node_maxZ + * @param node_maxY + * @param sel_minX + * @param sel_minZ + * @param sel_minY + * @param sel_maxX + * @param sel_maxZ + * @param sel_maxY + * @param blocks + * @return + */ + protected static boolean attemptRemove(Node node, + int node_minX, int node_minZ, int node_minY, int node_maxX, int node_maxZ, int node_maxY, + int sel_minX, int sel_minZ, int sel_minY, int sel_maxX, int sel_maxZ, int sel_maxY, + BitSet blocks + ) + { + int partial = _3D.compareRegion(node_minX, node_minZ, node_minY, node_maxX, node_maxZ, node_maxY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY, + blocks + ); + + if (partial == 0) return false; + if (partial == 1) return true; + + node.full = false; + node.children = null; + return true; + } + + + /** + * + * @param node + * @param half + * @param node_minX + * @param node_minZ + * @param node_minY + * @param node_maxX + * @param node_maxZ + * @param node_maxY + * @param sel_minX + * @param sel_minZ + * @param sel_minY + * @param sel_maxX + * @param sel_maxZ + * @param sel_maxY + */ + protected void remove(Node node, int half, + int node_minX, int node_minZ, int node_minY, int node_maxX, int node_maxZ, int node_maxY, + int sel_minX, int sel_minZ, int sel_minY, int sel_maxX, int sel_maxZ, int sel_maxY, + BitSet blocks + ) + { + if ((!node.full && node.children == null) || + node_minX >= sel_maxX || node_maxX <= sel_minX || + node_minZ >= sel_maxZ || node_maxZ <= sel_minZ || + node_minY >= sel_maxY || node_maxY <= sel_minY || + attemptRemove(node, + node_minX, node_minZ, node_minY, node_maxX, node_maxZ, node_maxY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY, + blocks + )) + return; + + if (node.full) + { + node.full = false; + node.children = Node.fullNodeArray(8); + } + + int midpointX = min[0] + half, + midpointZ = min[1] + half, + midpointY = min[2] + half; + + half >>>= 1; + + + /* child index: + Y → Y + X → X X → X + Z ╔═════════╦═════════╗ Z ╔═════════╦═════════╗ + ║ ║ ║ ║ ║ ║ + ║ 0 ║ 1 ║ ║ 4 ║ 5 ║ + ║ ║ ║ ║ ║ ║ + ↓ ╠═════════╬═════════╣ ↓ ╠═════════╬═════════╣ + ║ ║ ║ ║ ║ ║ + ║ 2 ║ 3 ║ ║ 6 ║ 7 ║ + ║ ║ ║ ║ ║ ║ + Z ╚═════════╩═════════╝ Z ╚═════════╩═════════╝*/ + + remove(node.children[0], half, + node_minX, node_minZ, node_minY, midpointX, midpointZ, midpointY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY, + blocks + ); + + remove(node.children[1], half, + midpointX, node_minZ, node_minY, node_maxX, midpointZ, midpointY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY, + blocks + ); + + remove(node.children[2], half, + node_minX, midpointZ, node_minY, midpointX, node_maxZ, midpointY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY, + blocks + ); + + remove(node.children[3], half, + midpointX, midpointZ, node_minY, node_maxX, node_maxZ, midpointY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY, + blocks + ); + + remove(node.children[4], half, + node_minX, node_minZ, midpointY, midpointX, midpointZ, node_maxY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY, + blocks + ); + + remove(node.children[5], half, + midpointX, node_minZ, midpointY, node_maxX, midpointZ, node_maxY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY, + blocks + ); + + remove(node.children[6], half, + node_minX, midpointZ, midpointY, midpointX, node_maxZ, node_maxY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY, + blocks + ); + + remove(node.children[7], half, + midpointX, midpointZ, midpointY, node_maxX, node_maxZ, node_maxY, + sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY, + blocks + ); + + if (node.children[0].children == null && node.children[1].children == null && + node.children[2].children == null && node.children[3].children == null && + node.children[4].children == null && node.children[5].children == null && + node.children[6].children == null && node.children[7].children == null + ) + { + node.full = false; + node.children = null; + } + } + + @Override public void remove(BitSet blocks, int[]... bounds) { - // TODO Auto-generated method stub + remove(root, max[0] - min[0] >>> 1, + min[0], min[1], min[2], max[0], max[1], max[2], + bounds[0][0], bounds[1][0], bounds[2][0], bounds[0][1], bounds[1][1], bounds[2][1], + blocks + ); + + trimAsNeeded(); } } diff --git a/src/regions/Quadtree.java b/src/regions/Quadtree.java index 444b44f..0bf0481 100644 --- a/src/regions/Quadtree.java +++ b/src/regions/Quadtree.java @@ -77,14 +77,56 @@ public class Quadtree extends Tree ╚══════════════════════════════════════════════════════════════════════════════════════════════╝ */ + /*---------------------------------------------------------------------------- + ------------------------------------------------------------------------------ + contains() SINGLE BLOCK + ------------------------------------------------------------------------------ + ----------------------------------------------------------------------------*/ + @Override public boolean contains(int... coords) { - //TODO finish method - return false; + if (coords[0] < min[0] || coords[0] >= max[0] || + coords[1] < min[1] || coords[1] >= max[1] + ) + return false; + + int half = max[0] - min[0] >>> 1, + minX = min[0], + minZ = min[1]; + + Node node = root; + int index; + while (true) + { + if (node.full) return true; + else if (node.children == null) + return false; + + index = 0; + if (minX + half <= coords[0]) + { + minX += half; + index += 1; + } + if (minZ + half <= coords[1]) + { + minZ += half; + index += 2; + } + half >>>= 1; + node = node.children[index]; + } } + /*---------------------------------------------------------------------------- + ------------------------------------------------------------------------------ + contains() BOUNDED SELECTION + ------------------------------------------------------------------------------ + ----------------------------------------------------------------------------*/ + + /* ╔══════════════════════════════════════════════════════════════════════════════════════════════╗ ║ ╔══════════════════════════════════════════════════════════════════════════════════════════╗ ║ @@ -103,43 +145,42 @@ public class Quadtree extends Tree /** * Method for sharing logic among the variants of expandAsNeeded() * - * @param xMinExpansion - * @param zMinExpansion - * @param xMaxExpansion - * @param zMaxExpansion + * @param xMinPercent + * @param zMinPercent + * @param xMaxPercent + * @param zMaxPercent */ - protected void expand(double xMinExpansion, double zMinExpansion, double xMaxExpansion, double zMaxExpansion) + protected void expand(double xMinPercent, double zMinPercent, double xMaxPercent, double zMaxPercent) { - int xMinCeil = (int) Math.ceil(xMinExpansion), - zMinCeil = (int) Math.ceil(zMinExpansion), - xMaxCeil = (int) Math.ceil(xMaxExpansion), - zMaxCeil = (int) Math.ceil(zMaxExpansion), + int xMin = (int) Math.ceil(xMinPercent), + zMin = (int) Math.ceil(zMinPercent), + xMax = (int) Math.ceil(xMaxPercent), + zMax = (int) Math.ceil(zMaxPercent), - size = nextPowerOfTwo(xMinCeil + xMaxCeil + 1, - zMinCeil + zMaxCeil + 1 + size = nextPowerOfTwo(xMin + xMax + 1, + zMin + zMax + 1 ), - xMargin = size - (xMinCeil + xMaxCeil + 1), - zMargin = size - (zMinCeil + zMaxCeil + 1), + xMargin = size - (xMin + xMax + 1), + zMargin = size - (zMin + zMax + 1), xMarginHalf = xMargin / 2, zMarginHalf = zMargin / 2; - xMinCeil += xMarginHalf; - zMinCeil += zMarginHalf; - xMaxCeil += xMarginHalf; - zMaxCeil += zMarginHalf; - - if (xMargin % 2 == 1) if (xMinCeil - xMinExpansion > xMaxCeil - xMaxExpansion) xMinCeil++; else xMaxCeil++; - - if (zMargin % 2 == 1) if (zMinCeil - zMinExpansion > zMaxCeil - zMaxExpansion) zMinCeil++; else zMaxCeil++; - - int sideLength = max[0] - min[0] + 1; - min[0] -= (sideLength * xMinCeil); - min[1] -= (sideLength * zMinCeil); - max[0] += (sideLength * xMaxCeil); - max[1] += (sideLength * zMaxCeil); + xMin += xMarginHalf; + zMin += zMarginHalf; + xMax += xMarginHalf; + zMax += zMarginHalf; + if (xMargin % 2 == 1) if (xMin - xMinPercent > xMax - xMaxPercent) xMin++; else xMax++; + if (zMargin % 2 == 1) if (zMin - zMinPercent > zMax - zMaxPercent) zMin++; else zMax++; + { + int sideLength = max[0] - min[0]; + min[0] -= (sideLength * xMin); + min[1] -= (sideLength * zMin); + max[0] += (sideLength * xMax); + max[1] += (sideLength * zMax); + } int index; Node[] children; @@ -150,18 +191,18 @@ public class Quadtree extends Tree size >>>= 1; index = 0; - if (xMinCeil >= size) - xMinCeil -= size; + if (xMin >= size) + xMin -= size; else { - xMaxCeil -= size; + xMax -= size; index += 1; } - if (zMinCeil >= size) - zMinCeil -= size; + if (zMin >= size) + zMin -= size; else { - zMaxCeil -= size; + zMax -= size; index += 2; } @@ -188,56 +229,56 @@ public class Quadtree extends Tree @Override protected void expandAsNeeded(int... coords) { - int sideLength = max[0] - min[0] + 1; + int sideLength = max[0] - min[0]; - double xMinExpansion = 0, - zMinExpansion = 0, - xMaxExpansion = 0, - zMaxExpansion = 0; + double xMinPercent = 0, + zMinPercent = 0, + xMaxPercent = 0, + zMaxPercent = 0; - if (coords[0] < min[0]) xMinExpansion = (min[0] - coords[0]) / sideLength; - else if (coords[0] > max[0]) xMaxExpansion = (coords[0] - max[0]) / sideLength; + if (coords[0] < min[0]) xMinPercent = (min[0] - coords[0]) / sideLength; + else if (coords[0] >= max[0]) xMaxPercent = (coords[0] - max[0]) / sideLength; - if (coords[1] < min[1]) zMinExpansion = (min[1] - coords[1]) / sideLength; - else if (coords[1] > max[1]) zMaxExpansion = (coords[1] - max[1]) / sideLength; + if (coords[1] < min[1]) zMinPercent = (min[1] - coords[1]) / sideLength; + else if (coords[1] >= max[1]) zMaxPercent = (coords[1] - max[1]) / sideLength; - if (xMinExpansion != 0 || - zMinExpansion != 0 || - xMaxExpansion != 0 || - zMaxExpansion != 0 + if (xMinPercent != 0 || + zMinPercent != 0 || + xMaxPercent != 0 || + zMaxPercent != 0 ) - expand(xMinExpansion, - zMinExpansion, - xMaxExpansion, - zMaxExpansion); + expand(xMinPercent, + zMinPercent, + xMaxPercent, + zMaxPercent); } @Override public void expandAsNeeded(int[]... bounds) { - int sideLength = max[0] - min[0] + 1; + int sideLength = max[0] - min[0]; - double xMinExpansion = 0, - zMinExpansion = 0, - xMaxExpansion = 0, - zMaxExpansion = 0; + double xMinPercent = 0, + zMinPercent = 0, + xMaxPercent = 0, + zMaxPercent = 0; - if (bounds[0][0] < min[0]) xMinExpansion = (min[0] - bounds[0][0]) / sideLength; - if (bounds[0][1] > max[0]) xMaxExpansion = (bounds[0][1] - max[0]) / sideLength; + if (bounds[0][0] < min[0]) xMinPercent = (min[0] - bounds[0][0]) / sideLength; + if (bounds[0][1] >= max[0]) xMaxPercent = (bounds[0][1] - max[0]) / sideLength; - if (bounds[1][0] < min[1]) zMinExpansion = (min[1] - bounds[1][0]) / sideLength; - if (bounds[1][1] > max[1]) zMaxExpansion = (bounds[1][1] - max[1]) / sideLength; + if (bounds[1][0] < min[1]) zMinPercent = (min[1] - bounds[1][0]) / sideLength; + if (bounds[1][1] >= max[1]) zMaxPercent = (bounds[1][1] - max[1]) / sideLength; - if (xMinExpansion != 0 || - zMinExpansion != 0 || - xMaxExpansion != 0 || - zMaxExpansion != 0 + if (xMinPercent != 0 || + zMinPercent != 0 || + xMaxPercent != 0 || + zMaxPercent != 0 ) - expand(xMinExpansion, - zMinExpansion, - xMaxExpansion, - zMaxExpansion); + expand(xMinPercent, + zMinPercent, + xMaxPercent, + zMaxPercent); } @@ -260,8 +301,7 @@ public class Quadtree extends Tree * @param blockX * @param blockZ */ - protected void add(Node node, - int half, + protected void add(Node node, int half, int node_minX, int node_minZ, int node_maxX, int node_maxZ, int blockX, int blockZ ) @@ -286,16 +326,17 @@ public class Quadtree extends Tree index += 2; } - if (half > 1) add(node.children[index], - half >>>= 1, + if (half > 1) add(node.children[index], half >>>= 1, node_minX, node_minZ, node_maxX, node_maxZ, blockX, blockZ ); else { node.children[index].full = true; - if (node.children[0].full && node.children[1].full && - node.children[2].full && node.children[3].full + if (node.children[0].full && + node.children[1].full && + node.children[2].full && + node.children[3].full ) { node.full = true; @@ -310,8 +351,7 @@ public class Quadtree extends Tree { expandAsNeeded(coords); - add(root, - (max[0] - min[0] + 1) / 2, + add(root, max[0] - min[0] >>> 1, this.min[0], this.min[1], this.max[0], this.max[1], coords[0], coords[1] ); @@ -339,8 +379,7 @@ public class Quadtree extends Tree * @param sel_maxX * @param sel_maxZ */ - protected void add(Node node, - int half, + protected void add(Node node, int half, int node_minX, int node_minZ, int node_maxX, int node_maxZ, int sel_minX, int sel_minZ, int sel_maxX, int sel_maxZ ) @@ -359,22 +398,20 @@ public class Quadtree extends Tree } return; } - if (node_maxZ < sel_minZ) + if (node_maxZ <= sel_minZ) return; } - if (node_minZ > sel_maxZ || node_maxZ < sel_minZ) + if (node_minZ >= sel_maxZ || node_maxZ <= sel_minZ) return; } - if (node_maxX < sel_minX || node_minZ > sel_maxZ || node_maxZ < sel_minZ) + if (node_maxX <= sel_minX || node_minZ >= sel_maxZ || node_maxZ <= sel_minZ) return; if (node.children == null) node.children = Node.emptyNodeArray(4); - int half_minX = min[0] + half, - half_maxX = half_minX - 1, - half_minZ = min[1] + half, - half_maxZ = half_minZ - 1; + int midpointX = min[0] + half, + midpointZ = min[1] + half; half >>>= 1; @@ -392,27 +429,23 @@ public class Quadtree extends Tree ║ ║ ║ Z ╚═════════╩═════════╝*/ - add(node.children[0], - half, - node_minX, node_minZ, half_maxX, half_maxZ, + add(node.children[0], half, + node_minX, node_minZ, midpointX, midpointZ, sel_minX, sel_minZ, sel_maxX, sel_maxZ ); - add(node.children[1], - half, - half_minX, node_minZ, node_maxX, half_maxZ, + add(node.children[1], half, + midpointX, node_minZ, node_maxX, midpointZ, sel_minX, sel_minZ, sel_maxX, sel_maxZ ); - add(node.children[2], - half, - node_minX, half_minZ, half_maxX, node_maxZ, + add(node.children[2], half, + node_minX, midpointZ, midpointX, node_maxZ, sel_minX, sel_minZ, sel_maxX, sel_maxZ ); - add(node.children[3], - half, - half_minX, half_minZ, node_maxX, node_maxZ, + add(node.children[3], half, + midpointX, midpointZ, node_maxX, node_maxZ, sel_minX, sel_minZ, sel_maxX, sel_maxZ ); @@ -431,8 +464,7 @@ public class Quadtree extends Tree { expandAsNeeded(bounds); - add(root, - (max[0] - min[0] + 1) / 2, + add(root, max[0] - min[0] >>> 1, min[0], min[1], max[0], max[1], bounds[0][0], bounds[1][0], bounds[0][1], bounds[1][1] ); @@ -447,6 +479,40 @@ public class Quadtree extends Tree ----------------------------------------------------------------------------*/ + /** + * + * @param node + * @param node_minX + * @param node_minZ + * @param node_maxX + * @param node_maxZ + * @param sel_minX + * @param sel_minZ + * @param sel_maxX + * @param sel_maxZ + * @param blocks + * @return + */ + protected static boolean attemptAdd(Node node, + int node_minX, int node_minZ, int node_maxX, int node_maxZ, + int sel_minX, int sel_minZ, int sel_maxX, int sel_maxZ, + BitSet blocks + ) + { + int partial = _2D.compareRegion(node_minX, node_minZ, node_maxX, node_maxZ, + sel_minX, sel_minZ, sel_maxX, sel_maxZ, + blocks + ); + + if (partial == 0) return false; + if (partial == 1) return true; + + node.full = true; + node.children = null; + return true; + } + + /** * * @param node @@ -461,43 +527,26 @@ public class Quadtree extends Tree * @param sel_maxZ * @param blocks */ - protected void add(Node node, - int half, + protected void add(Node node, int half, int node_minX, int node_minZ, int node_maxX, int node_maxZ, int sel_minX, int sel_minZ, int sel_maxX, int sel_maxZ, BitSet blocks ) { - if (node.full) return; - if (node_minX >= sel_minX) - { - if (node_maxX <= sel_maxX) - { - if (node_minZ >= sel_minZ) - { - if (node_maxZ <= sel_maxZ) - { - node.full = true; - node.children = null; - } - return; - } - if (node_maxZ < sel_minZ) - return; - } - if (node_minZ > sel_maxZ || node_maxZ < sel_minZ) - return; - } - if (node_maxX < sel_minX || node_minZ > sel_maxZ || node_maxZ < sel_minZ) + if (node.full || + node_minX >= sel_maxX || node_maxX <= sel_minX || + node_minZ >= sel_maxZ || node_maxZ <= sel_minZ || + attemptAdd(node, + node_minX, node_minZ, node_maxX, node_maxZ, + sel_minX, sel_minZ, sel_maxX, sel_maxZ, + blocks + )) return; - if (node.children == null) - node.children = Node.emptyNodeArray(4); + if (node.children == null) node.children = Node.emptyNodeArray(4); - int half_minX = min[0] + half, - half_maxX = half_minX - 1, - half_minZ = min[1] + half, - half_maxZ = half_minZ - 1; + int midpointX = min[0] + half, + midpointZ = min[1] + half; half >>>= 1; @@ -515,23 +564,23 @@ public class Quadtree extends Tree ║ ║ ║ Z ╚═════════╩═════════╝*/ - add(node.children[0], - node_minX, node_minZ, half_maxX, half_maxZ, half, + add(node.children[0], half, + node_minX, node_minZ, midpointX, midpointZ, sel_minX, sel_minZ, sel_maxX, sel_maxZ ); - add(node.children[1], - half_minX, node_minZ, node_maxX, half_maxZ, half, + add(node.children[1], half, + midpointX, node_minZ, node_maxX, midpointZ, sel_minX, sel_minZ, sel_maxX, sel_maxZ ); - add(node.children[2], - node_minX, half_minZ, half_maxX, node_maxZ, half, + add(node.children[2], half, + node_minX, midpointZ, midpointX, node_maxZ, sel_minX, sel_minZ, sel_maxX, sel_maxZ ); - add(node.children[3], - half_minX, half_minZ, node_maxX, node_maxZ, half, + add(node.children[3], half, + midpointX, midpointZ, node_maxX, node_maxZ, sel_minX, sel_minZ, sel_maxX, sel_maxZ ); @@ -550,8 +599,7 @@ public class Quadtree extends Tree { expandAsNeeded(bounds); - add(root, - (max[0] - min[0] + 1) / 2, + add(root, max[0] - min[0] >>> 1, min[0], min[1], max[0], max[1], bounds[0][0], bounds[1][0], bounds[0][1], bounds[1][1], blocks @@ -583,7 +631,7 @@ public class Quadtree extends Tree while (!root.full && root.children != null) { - half = (max[0] - min[0] + 1) / 2; + half = max[0] - min[0] >>> 1; if (root.children[0].children != null) { if (root.children[1].children == null && @@ -651,18 +699,17 @@ public class Quadtree extends Tree * @param blockX * @param blockZ */ - protected void remove(Node node, - int half, + protected void remove(Node node, int half, int node_minX, int node_minZ, int node_maxX, int node_maxZ, int blockX, int blockZ ) { - if (node.children == null) return; if (node.full) { node.full = false; - node.children = Node.emptyNodeArray(4); + node.children = Node.fullNodeArray(4); } + else if (node.children == null) return; int index = 0; @@ -681,16 +728,17 @@ public class Quadtree extends Tree index += 2; } - if (half > 1) remove(node.children[index], - half >>>= 1, + if (half > 1) remove(node.children[index], half >>>= 1, node_minX, node_minZ, node_maxX, node_maxZ, blockX, blockZ ); else { node.children[index].full = false; - if (node.children[0].children == null && node.children[1].children == null && - node.children[2].children == null && node.children[3].children == null + if (node.children[0].children == null && + node.children[1].children == null && + node.children[2].children == null && + node.children[3].children == null ) { node.full = false; @@ -703,8 +751,7 @@ public class Quadtree extends Tree @Override public void remove(int... coords) { - remove(root, - (max[0] - min[0] + 1) / 2, + remove(root, max[0] - min[0] >>> 1, this.min[0], this.min[1], this.max[0], this.max[1], coords[0], coords[1] ); @@ -734,13 +781,14 @@ public class Quadtree extends Tree * @param sel_maxX * @param sel_maxZ */ - protected void remove(Node node, - int half, + protected void remove(Node node, int half, int node_minX, int node_minZ, int node_maxX, int node_maxZ, int sel_minX, int sel_minZ, int sel_maxX, int sel_maxZ ) { - if (node.children == null) return; + if (!node.full && node.children == null) + return; + if (node_minX >= sel_minX) { if (node_maxX <= sel_maxX) @@ -754,22 +802,23 @@ public class Quadtree extends Tree } return; } - if (node_maxZ < sel_minZ) + if (node_maxZ <= sel_minZ) return; } - if (node_minZ > sel_maxZ || node_maxZ < sel_minZ) + if (node_minZ >= sel_maxZ || node_maxZ <= sel_minZ) return; } - if (node_maxX < sel_minX || node_minZ > sel_maxZ || node_maxZ < sel_minZ) + if (node_maxX <= sel_minX || node_minZ >= sel_maxZ || node_maxZ <= sel_minZ) return; if (node.full) - node.children = Node.emptyNodeArray(4); + { + node.full = false; + node.children = Node.fullNodeArray(4); + } - int half_minX = min[0] + half, - half_maxX = half_minX - 1, - half_minZ = min[1] + half, - half_maxZ = half_minZ - 1; + int midpointX = min[0] + half, + midpointZ = min[1] + half; half >>>= 1; @@ -787,27 +836,23 @@ public class Quadtree extends Tree ║ ║ ║ Z ╚═════════╩═════════╝*/ - remove(node.children[0], - half, - node_minX, node_minZ, half_maxX, half_maxZ, + remove(node.children[0], half, + node_minX, node_minZ, midpointX, midpointZ, sel_minX, sel_minZ, sel_maxX, sel_maxZ ); - remove(node.children[1], - half, - half_minX, node_minZ, node_maxX, half_maxZ, + remove(node.children[1], half, + midpointX, node_minZ, node_maxX, midpointZ, sel_minX, sel_minZ, sel_maxX, sel_maxZ ); - remove(node.children[2], - half, - node_minX, half_minZ, half_maxX, node_maxZ, + remove(node.children[2], half, + node_minX, midpointZ, midpointX, node_maxZ, sel_minX, sel_minZ, sel_maxX, sel_maxZ ); - remove(node.children[3], - half, - half_minX, half_minZ, node_maxX, node_maxZ, + remove(node.children[3], half, + midpointX, midpointZ, node_maxX, node_maxZ, sel_minX, sel_minZ, sel_maxX, sel_maxZ ); @@ -824,8 +869,7 @@ public class Quadtree extends Tree @Override public void remove(int[]... bounds) { - remove(root, - (max[0] - min[0] + 1) / 2, + remove(root, max[0] - min[0] >>> 1, this.min[0], this.min[1], this.max[0], this.max[1], bounds[0][0], bounds[1][0], bounds[0][1], bounds[1][1] ); @@ -842,6 +886,40 @@ public class Quadtree extends Tree ----------------------------------------------------------------------------*/ + /** + * + * @param node + * @param node_minX + * @param node_minZ + * @param node_maxX + * @param node_maxZ + * @param sel_minX + * @param sel_minZ + * @param sel_maxX + * @param sel_maxZ + * @param blocks + * @return + */ + protected static boolean attemptRemove(Node node, + int node_minX, int node_minZ, int node_maxX, int node_maxZ, + int sel_minX, int sel_minZ, int sel_maxX, int sel_maxZ, + BitSet blocks + ) + { + int partial = _2D.compareRegion(node_minX, node_minZ, node_maxX, node_maxZ, + sel_minX, sel_minZ, sel_maxX, sel_maxZ, + blocks + ); + + if (partial == 0) return false; + if (partial == 1) return true; + + node.full = false; + node.children = null; + return true; + } + + /** * * @param node @@ -856,49 +934,32 @@ public class Quadtree extends Tree * @param sel_maxZ * @param blocks */ - protected void remove(Node node, - int half, - int node_minX, int node_minZ, int node_maxX, int node_maxZ, + protected void remove(Node node, int half, + int node_minX, int node_minZ, int node_maxX, int node_maxZ, int sel_minX, int sel_minZ, int sel_maxX, int sel_maxZ, BitSet blocks ) { - if (node.children == null) return; - if (node_minX >= sel_minX) - { - if (node_maxX <= sel_maxX) - { - if (node_minZ >= sel_minZ) - { - if (node_maxZ <= sel_maxZ) - { - node.full = false; - node.children = null; - } - return; - } - if (node_maxZ < sel_minZ) - return; - } - if (node_minZ > sel_maxZ || node_maxZ < sel_minZ) - return; - } - if (node_maxX < sel_minX || node_minZ > sel_maxZ || node_maxZ < sel_minZ) + if ((!node.full && node.children == null) || + node_minX >= sel_maxX || node_maxX <= sel_minX || + node_minZ >= sel_maxZ || node_maxZ <= sel_minZ || + attemptRemove(node, + node_minX, node_minZ, node_maxX, node_maxZ, + sel_minX, sel_minZ, sel_maxX, sel_maxZ, + blocks + )) return; - if (node.full) - node.children = Node.emptyNodeArray(4); + if (node.children == null) node.children = Node.fullNodeArray(4); - int half_minX = min[0] + half, - half_maxX = half_minX - 1, - half_minZ = min[1] + half, - half_maxZ = half_minZ - 1; + int midpointX = min[0] + half, + midpointZ = min[1] + half; half >>>= 1; /* child index: - + X → X Z ╔═════════╦═════════╗ ║ ║ ║ @@ -910,28 +971,28 @@ public class Quadtree extends Tree ║ ║ ║ Z ╚═════════╩═════════╝*/ - remove(node.children[0], - half, - node_minX, node_minZ, half_maxX, half_maxZ, - sel_minX, sel_minZ, sel_maxX, sel_maxZ + remove(node.children[0], half, + node_minX, node_minZ, midpointX, midpointZ, + sel_minX, sel_minZ, sel_maxX, sel_maxZ, + blocks ); - remove(node.children[1], - half, - half_minX, node_minZ, node_maxX, half_maxZ, - sel_minX, sel_minZ, sel_maxX, sel_maxZ + remove(node.children[1], half, + midpointX, node_minZ, node_maxX, midpointZ, + sel_minX, sel_minZ, sel_maxX, sel_maxZ, + blocks ); - remove(node.children[2], - half, - node_minX, half_minZ, half_maxX, node_maxZ, - sel_minX, sel_minZ, sel_maxX, sel_maxZ + remove(node.children[2], half, + node_minX, midpointZ, midpointX, node_maxZ, + sel_minX, sel_minZ, sel_maxX, sel_maxZ, + blocks ); - remove(node.children[3], - half, - half_minX, half_minZ, node_maxX, node_maxZ, - sel_minX, sel_minZ, sel_maxX, sel_maxZ + remove(node.children[3], half, + midpointX, midpointZ, node_maxX, node_maxZ, + sel_minX, sel_minZ, sel_maxX, sel_maxZ, + blocks ); if (node.children[0].children == null && node.children[1].children == null && @@ -947,9 +1008,8 @@ public class Quadtree extends Tree @Override public void remove(BitSet blocks, int[]... bounds) { - remove(root, - (max[0] - min[0] + 1) / 2, - this.min[0], this.min[1], this.max[0], this.max[1], + remove(root, max[0] - min[0] >>> 1, + min[0], min[1], max[0], max[1], bounds[0][0], bounds[1][0], bounds[0][1], bounds[1][1], blocks ); diff --git a/src/regions/Tree.java b/src/regions/Tree.java index 3a75d60..80807f7 100644 --- a/src/regions/Tree.java +++ b/src/regions/Tree.java @@ -28,7 +28,7 @@ import java.util.BitSet; * @author Kevin Mathewson * */ -public abstract class Tree +public abstract class Tree extends BitRegionUtil { /** * Tree node containing a boolean and an array of sub-nodes @@ -58,7 +58,24 @@ public abstract class Tree { Node[] array = new Node[length]; for (int i = 0; i < length; i++) + { array[i] = new Node(false); + } + return array; + } + + /** + * Returns an array containing the given number of childless full nodes + * + * @param length desired size of array + */ + public static Node[] fullNodeArray(int length) + { + Node[] array = new Node[length]; + for (int i = 0; i < length; i++) + { + array[i] = new Node(true); + } return array; } } @@ -445,33 +462,6 @@ public abstract class Tree ----------------------------------------------------------------------------*/ - /** - * - */ - public void trimAsNeededOLD() //TODO replace with abstract, adjust bounds - { - outerloop: - while (true) - { - for (Node child1 : root.children) - { - if (child1.children != null) - { - for (Node child2 : root.children) - { - if (child2.children != null) - { - break outerloop; - } - } - root.children = child1.children; - break; - } - } - } - } - - /** * */