finished all add/remove methods, finished single block check

This commit is contained in:
BuildTools 2017-03-12 22:04:48 -04:00
parent 9192d598ae
commit f61093c29d
7 changed files with 1340 additions and 472 deletions

View file

@ -2,7 +2,7 @@ package regions;
import java.util.BitSet; import java.util.BitSet;
public class BitRegion2D public class BitRegion2D_OLD
{ {
/* /*
@ -17,7 +17,7 @@ public class BitRegion2D
protected final BitSet blocks; protected final BitSet blocks;
public BitRegion2D() public BitRegion2D_OLD()
{ {
sides = new int[] { 0, 0 }; sides = new int[] { 0, 0 };
blocks = new BitSet(); blocks = new BitSet();

View file

@ -2,7 +2,7 @@ package regions;
import java.util.BitSet; import java.util.BitSet;
public class BitRegion3D public class BitRegion3D_OLD
{ {
/* /*
@ -17,7 +17,7 @@ public class BitRegion3D
protected final BitSet blocks; protected final BitSet blocks;
protected BitRegion3D() protected BitRegion3D_OLD()
{ {
sides = new int[] { 0, 0, 0 }; sides = new int[] { 0, 0, 0 };
blocks = new BitSet(); blocks = new BitSet();

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

@ -77,14 +77,56 @@ public class Quadtree extends Tree
*/ */
/*----------------------------------------------------------------------------
------------------------------------------------------------------------------
contains() SINGLE BLOCK
------------------------------------------------------------------------------
----------------------------------------------------------------------------*/
@Override @Override
public boolean contains(int... coords) public boolean contains(int... coords)
{ {
//TODO finish method if (coords[0] < min[0] || coords[0] >= max[0] ||
return false; 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() * Method for sharing logic among the variants of expandAsNeeded()
* *
* @param xMinExpansion * @param xMinPercent
* @param zMinExpansion * @param zMinPercent
* @param xMaxExpansion * @param xMaxPercent
* @param zMaxExpansion * @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), int xMin = (int) Math.ceil(xMinPercent),
zMinCeil = (int) Math.ceil(zMinExpansion), zMin = (int) Math.ceil(zMinPercent),
xMaxCeil = (int) Math.ceil(xMaxExpansion), xMax = (int) Math.ceil(xMaxPercent),
zMaxCeil = (int) Math.ceil(zMaxExpansion), zMax = (int) Math.ceil(zMaxPercent),
size = nextPowerOfTwo(xMinCeil + xMaxCeil + 1, size = nextPowerOfTwo(xMin + xMax + 1,
zMinCeil + zMaxCeil + 1 zMin + zMax + 1
), ),
xMargin = size - (xMinCeil + xMaxCeil + 1), xMargin = size - (xMin + xMax + 1),
zMargin = size - (zMinCeil + zMaxCeil + 1), zMargin = size - (zMin + zMax + 1),
xMarginHalf = xMargin / 2, xMarginHalf = xMargin / 2,
zMarginHalf = zMargin / 2; zMarginHalf = zMargin / 2;
xMinCeil += xMarginHalf; xMin += xMarginHalf;
zMinCeil += zMarginHalf; zMin += zMarginHalf;
xMaxCeil += xMarginHalf; xMax += xMarginHalf;
zMaxCeil += zMarginHalf; zMax += zMarginHalf;
if (xMargin % 2 == 1) if (xMin - xMinPercent > xMax - xMaxPercent) xMin++; else xMax++;
if (xMargin % 2 == 1) if (xMinCeil - xMinExpansion > xMaxCeil - xMaxExpansion) xMinCeil++; else xMaxCeil++; if (zMargin % 2 == 1) if (zMin - zMinPercent > zMax - zMaxPercent) zMin++; else zMax++;
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);
{
int sideLength = max[0] - min[0];
min[0] -= (sideLength * xMin);
min[1] -= (sideLength * zMin);
max[0] += (sideLength * xMax);
max[1] += (sideLength * zMax);
}
int index; int index;
Node[] children; Node[] children;
@ -150,18 +191,18 @@ public class Quadtree extends Tree
size >>>= 1; size >>>= 1;
index = 0; index = 0;
if (xMinCeil >= size) if (xMin >= size)
xMinCeil -= size; xMin -= size;
else else
{ {
xMaxCeil -= size; xMax -= size;
index += 1; index += 1;
} }
if (zMinCeil >= size) if (zMin >= size)
zMinCeil -= size; zMin -= size;
else else
{ {
zMaxCeil -= size; zMax -= size;
index += 2; index += 2;
} }
@ -188,56 +229,56 @@ public class Quadtree extends Tree
@Override @Override
protected void expandAsNeeded(int... coords) protected void expandAsNeeded(int... coords)
{ {
int sideLength = max[0] - min[0] + 1; int sideLength = max[0] - min[0];
double xMinExpansion = 0, double xMinPercent = 0,
zMinExpansion = 0, zMinPercent = 0,
xMaxExpansion = 0, xMaxPercent = 0,
zMaxExpansion = 0; zMaxPercent = 0;
if (coords[0] < min[0]) xMinExpansion = (min[0] - coords[0]) / sideLength; if (coords[0] < min[0]) xMinPercent = (min[0] - coords[0]) / sideLength;
else if (coords[0] > max[0]) xMaxExpansion = (coords[0] - max[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; if (coords[1] < min[1]) zMinPercent = (min[1] - coords[1]) / sideLength;
else if (coords[1] > max[1]) zMaxExpansion = (coords[1] - max[1]) / sideLength; else if (coords[1] >= max[1]) zMaxPercent = (coords[1] - max[1]) / sideLength;
if (xMinExpansion != 0 || if (xMinPercent != 0 ||
zMinExpansion != 0 || zMinPercent != 0 ||
xMaxExpansion != 0 || xMaxPercent != 0 ||
zMaxExpansion != 0 zMaxPercent != 0
) )
expand(xMinExpansion, expand(xMinPercent,
zMinExpansion, zMinPercent,
xMaxExpansion, xMaxPercent,
zMaxExpansion); zMaxPercent);
} }
@Override @Override
public void expandAsNeeded(int[]... bounds) public void expandAsNeeded(int[]... bounds)
{ {
int sideLength = max[0] - min[0] + 1; int sideLength = max[0] - min[0];
double xMinExpansion = 0, double xMinPercent = 0,
zMinExpansion = 0, zMinPercent = 0,
xMaxExpansion = 0, xMaxPercent = 0,
zMaxExpansion = 0; zMaxPercent = 0;
if (bounds[0][0] < min[0]) xMinExpansion = (min[0] - bounds[0][0]) / sideLength; if (bounds[0][0] < min[0]) xMinPercent = (min[0] - bounds[0][0]) / sideLength;
if (bounds[0][1] > max[0]) xMaxExpansion = (bounds[0][1] - max[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][0] < min[1]) zMinPercent = (min[1] - bounds[1][0]) / sideLength;
if (bounds[1][1] > max[1]) zMaxExpansion = (bounds[1][1] - max[1]) / sideLength; if (bounds[1][1] >= max[1]) zMaxPercent = (bounds[1][1] - max[1]) / sideLength;
if (xMinExpansion != 0 || if (xMinPercent != 0 ||
zMinExpansion != 0 || zMinPercent != 0 ||
xMaxExpansion != 0 || xMaxPercent != 0 ||
zMaxExpansion != 0 zMaxPercent != 0
) )
expand(xMinExpansion, expand(xMinPercent,
zMinExpansion, zMinPercent,
xMaxExpansion, xMaxPercent,
zMaxExpansion); zMaxPercent);
} }
@ -260,8 +301,7 @@ public class Quadtree extends Tree
* @param blockX * @param blockX
* @param blockZ * @param blockZ
*/ */
protected void add(Node node, protected void add(Node node, int half,
int half,
int node_minX, int node_minZ, int node_maxX, int node_maxZ, int node_minX, int node_minZ, int node_maxX, int node_maxZ,
int blockX, int blockZ int blockX, int blockZ
) )
@ -286,16 +326,17 @@ public class Quadtree extends Tree
index += 2; index += 2;
} }
if (half > 1) add(node.children[index], if (half > 1) add(node.children[index], half >>>= 1,
half >>>= 1,
node_minX, node_minZ, node_maxX, node_maxZ, node_minX, node_minZ, node_maxX, node_maxZ,
blockX, blockZ blockX, blockZ
); );
else else
{ {
node.children[index].full = true; node.children[index].full = true;
if (node.children[0].full && node.children[1].full && if (node.children[0].full &&
node.children[2].full && node.children[3].full node.children[1].full &&
node.children[2].full &&
node.children[3].full
) )
{ {
node.full = true; node.full = true;
@ -310,8 +351,7 @@ public class Quadtree extends Tree
{ {
expandAsNeeded(coords); expandAsNeeded(coords);
add(root, add(root, max[0] - min[0] >>> 1,
(max[0] - min[0] + 1) / 2,
this.min[0], this.min[1], this.max[0], this.max[1], this.min[0], this.min[1], this.max[0], this.max[1],
coords[0], coords[1] coords[0], coords[1]
); );
@ -339,8 +379,7 @@ public class Quadtree extends Tree
* @param sel_maxX * @param sel_maxX
* @param sel_maxZ * @param sel_maxZ
*/ */
protected void add(Node node, protected void add(Node node, int half,
int half,
int node_minX, int node_minZ, int node_maxX, int node_maxZ, int node_minX, int node_minZ, int node_maxX, int node_maxZ,
int sel_minX, int sel_minZ, int sel_maxX, int sel_maxZ int sel_minX, int sel_minZ, int sel_maxX, int sel_maxZ
) )
@ -359,22 +398,20 @@ public class Quadtree extends Tree
} }
return; return;
} }
if (node_maxZ < sel_minZ) if (node_maxZ <= sel_minZ)
return; return;
} }
if (node_minZ > sel_maxZ || node_maxZ < sel_minZ) if (node_minZ >= sel_maxZ || node_maxZ <= sel_minZ)
return; 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; return;
if (node.children == null) if (node.children == null)
node.children = Node.emptyNodeArray(4); node.children = Node.emptyNodeArray(4);
int half_minX = min[0] + half, int midpointX = min[0] + half,
half_maxX = half_minX - 1, midpointZ = min[1] + half;
half_minZ = min[1] + half,
half_maxZ = half_minZ - 1;
half >>>= 1; half >>>= 1;
@ -392,27 +429,23 @@ public class Quadtree extends Tree
Z */ Z */
add(node.children[0], add(node.children[0], half,
half, node_minX, node_minZ, midpointX, midpointZ,
node_minX, node_minZ, half_maxX, half_maxZ,
sel_minX, sel_minZ, sel_maxX, sel_maxZ sel_minX, sel_minZ, sel_maxX, sel_maxZ
); );
add(node.children[1], add(node.children[1], half,
half, midpointX, node_minZ, node_maxX, midpointZ,
half_minX, node_minZ, node_maxX, half_maxZ,
sel_minX, sel_minZ, sel_maxX, sel_maxZ sel_minX, sel_minZ, sel_maxX, sel_maxZ
); );
add(node.children[2], add(node.children[2], half,
half, node_minX, midpointZ, midpointX, node_maxZ,
node_minX, half_minZ, half_maxX, node_maxZ,
sel_minX, sel_minZ, sel_maxX, sel_maxZ sel_minX, sel_minZ, sel_maxX, sel_maxZ
); );
add(node.children[3], add(node.children[3], half,
half, midpointX, midpointZ, node_maxX, node_maxZ,
half_minX, half_minZ, node_maxX, node_maxZ,
sel_minX, sel_minZ, sel_maxX, sel_maxZ sel_minX, sel_minZ, sel_maxX, sel_maxZ
); );
@ -431,8 +464,7 @@ public class Quadtree extends Tree
{ {
expandAsNeeded(bounds); expandAsNeeded(bounds);
add(root, add(root, max[0] - min[0] >>> 1,
(max[0] - min[0] + 1) / 2,
min[0], min[1], max[0], max[1], min[0], min[1], max[0], max[1],
bounds[0][0], bounds[1][0], bounds[0][1], bounds[1][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 * @param node
@ -461,43 +527,26 @@ public class Quadtree extends Tree
* @param sel_maxZ * @param sel_maxZ
* @param blocks * @param blocks
*/ */
protected void add(Node node, protected void add(Node node, int half,
int half,
int node_minX, int node_minZ, int node_maxX, int node_maxZ, int node_minX, int node_minZ, int node_maxX, int node_maxZ,
int sel_minX, int sel_minZ, int sel_maxX, int sel_maxZ, int sel_minX, int sel_minZ, int sel_maxX, int sel_maxZ,
BitSet blocks BitSet blocks
) )
{ {
if (node.full) return; if (node.full ||
if (node_minX >= sel_minX) node_minX >= sel_maxX || node_maxX <= sel_minX ||
{ node_minZ >= sel_maxZ || node_maxZ <= sel_minZ ||
if (node_maxX <= sel_maxX) attemptAdd(node,
{ node_minX, node_minZ, node_maxX, node_maxZ,
if (node_minZ >= sel_minZ) sel_minX, sel_minZ, sel_maxX, sel_maxZ,
{ blocks
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)
return; return;
if (node.children == null) if (node.children == null) node.children = Node.emptyNodeArray(4);
node.children = Node.emptyNodeArray(4);
int half_minX = min[0] + half, int midpointX = min[0] + half,
half_maxX = half_minX - 1, midpointZ = min[1] + half;
half_minZ = min[1] + half,
half_maxZ = half_minZ - 1;
half >>>= 1; half >>>= 1;
@ -515,23 +564,23 @@ public class Quadtree extends Tree
Z */ Z */
add(node.children[0], add(node.children[0], half,
node_minX, node_minZ, half_maxX, half_maxZ, half, node_minX, node_minZ, midpointX, midpointZ,
sel_minX, sel_minZ, sel_maxX, sel_maxZ sel_minX, sel_minZ, sel_maxX, sel_maxZ
); );
add(node.children[1], add(node.children[1], half,
half_minX, node_minZ, node_maxX, half_maxZ, half, midpointX, node_minZ, node_maxX, midpointZ,
sel_minX, sel_minZ, sel_maxX, sel_maxZ sel_minX, sel_minZ, sel_maxX, sel_maxZ
); );
add(node.children[2], add(node.children[2], half,
node_minX, half_minZ, half_maxX, node_maxZ, half, node_minX, midpointZ, midpointX, node_maxZ,
sel_minX, sel_minZ, sel_maxX, sel_maxZ sel_minX, sel_minZ, sel_maxX, sel_maxZ
); );
add(node.children[3], add(node.children[3], half,
half_minX, half_minZ, node_maxX, node_maxZ, half, midpointX, midpointZ, node_maxX, node_maxZ,
sel_minX, sel_minZ, sel_maxX, sel_maxZ sel_minX, sel_minZ, sel_maxX, sel_maxZ
); );
@ -550,8 +599,7 @@ public class Quadtree extends Tree
{ {
expandAsNeeded(bounds); expandAsNeeded(bounds);
add(root, add(root, max[0] - min[0] >>> 1,
(max[0] - min[0] + 1) / 2,
min[0], min[1], max[0], max[1], min[0], min[1], max[0], max[1],
bounds[0][0], bounds[1][0], bounds[0][1], bounds[1][1], bounds[0][0], bounds[1][0], bounds[0][1], bounds[1][1],
blocks blocks
@ -583,7 +631,7 @@ public class Quadtree extends Tree
while (!root.full && root.children != null) 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[0].children != null)
{ {
if (root.children[1].children == null && if (root.children[1].children == null &&
@ -651,18 +699,17 @@ public class Quadtree extends Tree
* @param blockX * @param blockX
* @param blockZ * @param blockZ
*/ */
protected void remove(Node node, protected void remove(Node node, int half,
int half,
int node_minX, int node_minZ, int node_maxX, int node_maxZ, int node_minX, int node_minZ, int node_maxX, int node_maxZ,
int blockX, int blockZ int blockX, int blockZ
) )
{ {
if (node.children == null) return;
if (node.full) if (node.full)
{ {
node.full = false; node.full = false;
node.children = Node.emptyNodeArray(4); node.children = Node.fullNodeArray(4);
} }
else if (node.children == null) return;
int index = 0; int index = 0;
@ -681,16 +728,17 @@ public class Quadtree extends Tree
index += 2; index += 2;
} }
if (half > 1) remove(node.children[index], if (half > 1) remove(node.children[index], half >>>= 1,
half >>>= 1,
node_minX, node_minZ, node_maxX, node_maxZ, node_minX, node_minZ, node_maxX, node_maxZ,
blockX, blockZ blockX, blockZ
); );
else else
{ {
node.children[index].full = false; node.children[index].full = false;
if (node.children[0].children == null && node.children[1].children == null && if (node.children[0].children == null &&
node.children[2].children == null && node.children[3].children == null node.children[1].children == null &&
node.children[2].children == null &&
node.children[3].children == null
) )
{ {
node.full = false; node.full = false;
@ -703,8 +751,7 @@ public class Quadtree extends Tree
@Override @Override
public void remove(int... coords) public void remove(int... coords)
{ {
remove(root, remove(root, max[0] - min[0] >>> 1,
(max[0] - min[0] + 1) / 2,
this.min[0], this.min[1], this.max[0], this.max[1], this.min[0], this.min[1], this.max[0], this.max[1],
coords[0], coords[1] coords[0], coords[1]
); );
@ -734,13 +781,14 @@ public class Quadtree extends Tree
* @param sel_maxX * @param sel_maxX
* @param sel_maxZ * @param sel_maxZ
*/ */
protected void remove(Node node, protected void remove(Node node, int half,
int half,
int node_minX, int node_minZ, int node_maxX, int node_maxZ, int node_minX, int node_minZ, int node_maxX, int node_maxZ,
int sel_minX, int sel_minZ, int sel_maxX, int sel_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_minX >= sel_minX)
{ {
if (node_maxX <= sel_maxX) if (node_maxX <= sel_maxX)
@ -754,22 +802,23 @@ public class Quadtree extends Tree
} }
return; return;
} }
if (node_maxZ < sel_minZ) if (node_maxZ <= sel_minZ)
return; return;
} }
if (node_minZ > sel_maxZ || node_maxZ < sel_minZ) if (node_minZ >= sel_maxZ || node_maxZ <= sel_minZ)
return; 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; return;
if (node.full) if (node.full)
node.children = Node.emptyNodeArray(4); {
node.full = false;
node.children = Node.fullNodeArray(4);
}
int half_minX = min[0] + half, int midpointX = min[0] + half,
half_maxX = half_minX - 1, midpointZ = min[1] + half;
half_minZ = min[1] + half,
half_maxZ = half_minZ - 1;
half >>>= 1; half >>>= 1;
@ -787,27 +836,23 @@ public class Quadtree extends Tree
Z */ Z */
remove(node.children[0], remove(node.children[0], half,
half, node_minX, node_minZ, midpointX, midpointZ,
node_minX, node_minZ, half_maxX, half_maxZ,
sel_minX, sel_minZ, sel_maxX, sel_maxZ sel_minX, sel_minZ, sel_maxX, sel_maxZ
); );
remove(node.children[1], remove(node.children[1], half,
half, midpointX, node_minZ, node_maxX, midpointZ,
half_minX, node_minZ, node_maxX, half_maxZ,
sel_minX, sel_minZ, sel_maxX, sel_maxZ sel_minX, sel_minZ, sel_maxX, sel_maxZ
); );
remove(node.children[2], remove(node.children[2], half,
half, node_minX, midpointZ, midpointX, node_maxZ,
node_minX, half_minZ, half_maxX, node_maxZ,
sel_minX, sel_minZ, sel_maxX, sel_maxZ sel_minX, sel_minZ, sel_maxX, sel_maxZ
); );
remove(node.children[3], remove(node.children[3], half,
half, midpointX, midpointZ, node_maxX, node_maxZ,
half_minX, half_minZ, node_maxX, node_maxZ,
sel_minX, sel_minZ, sel_maxX, sel_maxZ sel_minX, sel_minZ, sel_maxX, sel_maxZ
); );
@ -824,8 +869,7 @@ public class Quadtree extends Tree
@Override @Override
public void remove(int[]... bounds) public void remove(int[]... bounds)
{ {
remove(root, remove(root, max[0] - min[0] >>> 1,
(max[0] - min[0] + 1) / 2,
this.min[0], this.min[1], this.max[0], this.max[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] 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 * @param node
@ -856,49 +934,32 @@ public class Quadtree extends Tree
* @param sel_maxZ * @param sel_maxZ
* @param blocks * @param blocks
*/ */
protected void remove(Node node, protected void remove(Node node, int half,
int half, int node_minX, int node_minZ, int node_maxX, int node_maxZ,
int node_minX, int node_minZ, int node_maxX, int node_maxZ,
int sel_minX, int sel_minZ, int sel_maxX, int sel_maxZ, int sel_minX, int sel_minZ, int sel_maxX, int sel_maxZ,
BitSet blocks BitSet blocks
) )
{ {
if (node.children == null) return; if ((!node.full && node.children == null) ||
if (node_minX >= sel_minX) node_minX >= sel_maxX || node_maxX <= sel_minX ||
{ node_minZ >= sel_maxZ || node_maxZ <= sel_minZ ||
if (node_maxX <= sel_maxX) attemptRemove(node,
{ node_minX, node_minZ, node_maxX, node_maxZ,
if (node_minZ >= sel_minZ) sel_minX, sel_minZ, sel_maxX, sel_maxZ,
{ blocks
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)
return; return;
if (node.full) if (node.children == null) node.children = Node.fullNodeArray(4);
node.children = Node.emptyNodeArray(4);
int half_minX = min[0] + half, int midpointX = min[0] + half,
half_maxX = half_minX - 1, midpointZ = min[1] + half;
half_minZ = min[1] + half,
half_maxZ = half_minZ - 1;
half >>>= 1; half >>>= 1;
/* child index: /* child index:
X X X X
Z Z
@ -910,28 +971,28 @@ public class Quadtree extends Tree
Z */ Z */
remove(node.children[0], remove(node.children[0], half,
half, node_minX, node_minZ, midpointX, midpointZ,
node_minX, node_minZ, half_maxX, half_maxZ, sel_minX, sel_minZ, sel_maxX, sel_maxZ,
sel_minX, sel_minZ, sel_maxX, sel_maxZ blocks
); );
remove(node.children[1], remove(node.children[1], half,
half, midpointX, node_minZ, node_maxX, midpointZ,
half_minX, node_minZ, node_maxX, half_maxZ, sel_minX, sel_minZ, sel_maxX, sel_maxZ,
sel_minX, sel_minZ, sel_maxX, sel_maxZ blocks
); );
remove(node.children[2], remove(node.children[2], half,
half, node_minX, midpointZ, midpointX, node_maxZ,
node_minX, half_minZ, half_maxX, node_maxZ, sel_minX, sel_minZ, sel_maxX, sel_maxZ,
sel_minX, sel_minZ, sel_maxX, sel_maxZ blocks
); );
remove(node.children[3], remove(node.children[3], half,
half, midpointX, midpointZ, node_maxX, node_maxZ,
half_minX, half_minZ, node_maxX, node_maxZ, sel_minX, sel_minZ, sel_maxX, sel_maxZ,
sel_minX, sel_minZ, sel_maxX, sel_maxZ blocks
); );
if (node.children[0].children == null && node.children[1].children == null && if (node.children[0].children == null && node.children[1].children == null &&
@ -947,9 +1008,8 @@ public class Quadtree extends Tree
@Override @Override
public void remove(BitSet blocks, int[]... bounds) public void remove(BitSet blocks, int[]... bounds)
{ {
remove(root, remove(root, max[0] - min[0] >>> 1,
(max[0] - min[0] + 1) / 2, min[0], min[1], max[0], max[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], bounds[0][0], bounds[1][0], bounds[0][1], bounds[1][1],
blocks blocks
); );

View file

@ -28,7 +28,7 @@ import java.util.BitSet;
* @author Kevin Mathewson * @author Kevin Mathewson
* *
*/ */
public abstract class Tree public abstract class Tree extends BitRegionUtil
{ {
/** /**
* Tree node containing a boolean and an array of sub-nodes * Tree node containing a boolean and an array of sub-nodes
@ -58,7 +58,24 @@ public abstract class Tree
{ {
Node[] array = new Node[length]; Node[] array = new Node[length];
for (int i = 0; i < length; i++) for (int i = 0; i < length; i++)
{
array[i] = new Node(false); 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; 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;
}
}
}
}
/** /**
* *
*/ */