diff --git a/src/regions/Directory.java b/src/regions/Directory.java new file mode 100644 index 0000000..dd3fa51 --- /dev/null +++ b/src/regions/Directory.java @@ -0,0 +1,6 @@ +package regions; + +public abstract class Directory +{ + +} diff --git a/src/regions/Octree.java b/src/regions/Octree.java index b409c8a..051c452 100644 --- a/src/regions/Octree.java +++ b/src/regions/Octree.java @@ -2,7 +2,7 @@ package regions; public class Octree extends Tree { - //STATIC + //LOADING AND SAVING //================================================================== Node parseBytes(IntReference index, byte[] bytes, int parentByte) @@ -18,19 +18,19 @@ public class Octree extends Tree ( new Node[] { - parseBytes(index, bytes, (a >> 6 & 3)), - parseBytes(index, bytes, (a >> 4 & 3)), - parseBytes(index, bytes, (a >> 2 & 3)), - parseBytes(index, bytes, (a & 3)), + parseBytes(index, bytes, (a >>> 6 & 3)), + parseBytes(index, bytes, (a >>> 4 & 3)), + parseBytes(index, bytes, (a >>> 2 & 3)), + parseBytes(index, bytes, (a & 3)), - parseBytes(index, bytes, (b >> 6 & 3)), - parseBytes(index, bytes, (b >> 4 & 3)), - parseBytes(index, bytes, (b >> 2 & 3)), - parseBytes(index, bytes, (b & 3)) + parseBytes(index, bytes, (b >>> 6 & 3)), + parseBytes(index, bytes, (b >>> 4 & 3)), + parseBytes(index, bytes, (b >>> 2 & 3)), + parseBytes(index, bytes, (b & 3)) }); } - //INSTANCE + //CONSTRUCTOR //================================================================== public Octree(Owner owner, byte[] bytes) diff --git a/src/regions/Owner.java b/src/regions/Owner.java index 0bbecfd..24f3f90 100644 --- a/src/regions/Owner.java +++ b/src/regions/Owner.java @@ -2,14 +2,14 @@ package regions; import java.util.List; -public class Owner +public class Owner extends Directory { - public final String name; - public final Owner parent; - public final List children; - public final List trees; + public final String name; + public final Directory parent; + public final List children; + public final List trees; - public Owner(String name, Owner parent, List children, List trees) + public Owner(String name, Directory parent, List children, List trees) { this.name = name; this.parent = parent; diff --git a/src/regions/Quadtree.java b/src/regions/Quadtree.java index 28238ca..0ecc300 100644 --- a/src/regions/Quadtree.java +++ b/src/regions/Quadtree.java @@ -2,7 +2,7 @@ package regions; public class Quadtree extends Tree { - //STATIC + //LOADING AND SAVING //================================================================== Node parseBytes(IntReference index, byte[] bytes, int parentByte) @@ -17,14 +17,14 @@ public class Quadtree extends Tree ( new Node[] { - parseBytes(index, bytes, (a >> 6 & 3)), - parseBytes(index, bytes, (a >> 4 & 3)), - parseBytes(index, bytes, (a >> 2 & 3)), - parseBytes(index, bytes, (a & 3)) + parseBytes(index, bytes, (a >>> 6 & 3)), + parseBytes(index, bytes, (a >>> 4 & 3)), + parseBytes(index, bytes, (a >>> 2 & 3)), + parseBytes(index, bytes, (a & 3)) }); } - //INSTANCE + //CONSTRUCTOR //================================================================== public Quadtree(Owner owner, byte[] bytes) diff --git a/src/regions/RegionEvent.java b/src/regions/RegionEvent.java deleted file mode 100644 index 9470fe0..0000000 --- a/src/regions/RegionEvent.java +++ /dev/null @@ -1,15 +0,0 @@ -package regions; - -import org.bukkit.event.Event; - -public class RegionEvent -{ - public final T bukkitEvent; - public final Owner region; - - public RegionEvent(T bukkitEvent, Owner region) - { - this.bukkitEvent = bukkitEvent; - this.region = region; - } -} diff --git a/src/regions/RegionTreeEditor.java b/src/regions/RegionTreeEditor.java new file mode 100644 index 0000000..e4001e7 --- /dev/null +++ b/src/regions/RegionTreeEditor.java @@ -0,0 +1,6 @@ +package regions; + +public class RegionTreeEditor +{ + +} diff --git a/src/regions/Tree.java b/src/regions/Tree.java index e4c14d5..04730be 100644 --- a/src/regions/Tree.java +++ b/src/regions/Tree.java @@ -1,5 +1,12 @@ package regions; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + /** * This is a superclass for octrees, quadtrees, and any other spatial trees.

* @@ -13,16 +20,13 @@ package regions; * smallest box your shape will fit inside of). This box outlines the minimum and maximum * x, y, and z dimensions of the shape.

* - * Next, you divide this cube evenly into 8 sections (2 x 2 x 2) and determine which sections - * your shape fills, which ones it leaves empty, and which ones your shape partially - * intersects.

+ * Next, you divide this cube evenly into 8 more cubes, determining which of these cubes + * your shape fills, which it leaves empty, and which it intersects. Intersected cubes are + * divided again into 8 more cubes, and the process repeats until only completely full + * (true) and completely empty (false) cubes remain.

* - * Intersected cubes are divided again into 8 subsections, and the process repeats until you - * have divided and subdivided your bounding box into only full (true) and - * empty (false) cubes

- * - * Then, given any point in space, you can quickly determine whether the point is inside or - * outside your shape by navigating the tree to reach the smallest cube your point is in. + * With this tree, you can quickly determine whether any arbitrary point is inside or outside + * your shape by navigating the tree to reach the smallest cube containing your point. * * @author Kevin Mathewson * @@ -52,10 +56,18 @@ public abstract class Tree } + + /*---------------------------------------------------- + ------------------------------------------------------ + FROM BYTES + ------------------------------------------------------ + ----------------------------------------------------*/ + + /** - * Defines an object containing a single int field. Used by the parseBytes() - * method to track its current index in the byte array. Node parseBytes() - * is a nested, self-calling method, and index increments with each call. + * Defines an object containing a single int field. Used by the nested, recursive method + * Node parseBytes(), so all the child-calls and parent-calls of the method can + * refer to the same integer, representing the current index within the parsed byte array. */ static final class IntReference { @@ -120,6 +132,119 @@ public abstract class Tree + /*---------------------------------------------------- + ------------------------------------------------------ + TO BYTES + ------------------------------------------------------ + ----------------------------------------------------*/ + + + /** + * Get the 2-bit representation of this node. Used in {@link #getByte(Node node)} + * to construct the parent byte from the bits of four child nodes, xx xx xx xx.

+ * + * @param node the node to evaluate + * @return 2 (full), 1 (empty), or 0 (has children) + */ + public static byte getBits(Node node) + { + return node.full ? (byte) 2 : node.children.length == 0 ? (byte) 1 : (byte) 0; + } + + + /** + * Get byte representation for four child nodes. Returns the following:

+ * + * {@link #getBits(Node node) getBits(a)} << 6 |

+ * {@link #getBits(Node node) getBits(b)} << 4 |

+ * {@link #getBits(Node node) getBits(c)} << 2 |

+ * {@link #getBits(Node node) getBits(d)} + * + * @param a 1st child node + * @param b 2nd child node + * @param c 3rd child node + * @param d 4th child node + * @see {@link #getBits(Node node)} + */ + public static byte getByte(Node a, Node b, Node c, Node d) + { + return (byte) ( getBits(a) << 6 | + getBits(b) << 4 | + getBits(c) << 2 | + getBits(d) + ); + } + + + /** + * Parses the tree rooted at this node, appending in depth-first order the result of invoking + * {@link #getByte(Node, Node, Node, Node) getByte(children)} for each encountered + * node in the tree, skipping childless nodes.

+ * + * NOTE: assumes an OutputStream that appends with each write. + * + * @param node the node to be parsed + * @return a byte array representing the node and all its child nodes + */ + public static void writeBytes(Node node, OutputStream output) + { + try + { + output.write( getByte( node.children[0], + node.children[1], + node.children[2], + node.children[3] )); + } + catch (IOException e) { e.printStackTrace(); } + for (Node child : node.children) + writeBytes(child, output); + } + + + /** + * Parses the tree rooted at this node, appending in depth-first order the result of invoking + * {@link #getByte(Node, Node, Node, Node) getByte(children)} for each encountered + * node in the tree, skipping childless nodes.

+ * + * Writes to a ByteArrayOutputStream. + * + * @param node the root node of the tree to be parsed + * @return a byte array representing the root node and all its child nodes + */ + public static byte[] getBytes(Node node) + { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + writeBytes(node, output); + return output.toByteArray(); + } + + + /** + * Performs {@link #writeBytes(Node, OutputStream)}, using a FileOutputStream of the + * given file as the OutputStream argument. + * + * @param node the root node of the tree to be parsed + * @param destination the file to save to + */ + public static void saveToFile(Node node, File destination) + { + try + { + FileOutputStream output = new FileOutputStream (destination, true); + writeBytes(node, output); + output.close(); + } + catch (FileNotFoundException e) { e.printStackTrace(); } + catch (IOException e) { e.printStackTrace(); } + } + + + + /*---------------------------------------------------- + CONSTRUCTOR + ----------------------------------------------------*/ + + public final Owner owner; public final Node root; diff --git a/src/regions/World.java b/src/regions/World.java deleted file mode 100644 index faaa983..0000000 --- a/src/regions/World.java +++ /dev/null @@ -1,6 +0,0 @@ -package regions; - -public class World -{ - -}