diff --git a/core/src/main/java/com/seibel/lod/core/generation/WorldGenerationQueue.java b/core/src/main/java/com/seibel/lod/core/generation/WorldGenerationQueue.java index 2f32639be..a0c36c74c 100644 --- a/core/src/main/java/com/seibel/lod/core/generation/WorldGenerationQueue.java +++ b/core/src/main/java/com/seibel/lod/core/generation/WorldGenerationQueue.java @@ -209,7 +209,7 @@ public class WorldGenerationQueue implements Closeable catch (Exception e) { LOGGER.error("queueing exception: "+e.getMessage(), e); - generationQueueStarted = false; + this.generationQueueStarted = false; } }); } diff --git a/core/src/main/java/com/seibel/lod/core/render/RenderBufferHandler.java b/core/src/main/java/com/seibel/lod/core/render/RenderBufferHandler.java index c3b48d92f..4474a7b02 100644 --- a/core/src/main/java/com/seibel/lod/core/render/RenderBufferHandler.java +++ b/core/src/main/java/com/seibel/lod/core/render/RenderBufferHandler.java @@ -177,7 +177,7 @@ public class RenderBufferHandler if (renderSection != null) { ColumnRenderSource sectionRenderSource = renderSection.getRenderSource(); - // if the render source is present, attempt to load it + // if the render source is present, attempt to build it if (sectionRenderSource != null) { ColumnRenderSource[] adjacentRenderSources = new ColumnRenderSource[ELodDirection.ADJ_DIRECTIONS.length]; diff --git a/core/src/main/java/com/seibel/lod/core/util/objects/quadTree/QuadNode.java b/core/src/main/java/com/seibel/lod/core/util/objects/quadTree/QuadNode.java index ea5b8523d..8eb349b79 100644 --- a/core/src/main/java/com/seibel/lod/core/util/objects/quadTree/QuadNode.java +++ b/core/src/main/java/com/seibel/lod/core/util/objects/quadTree/QuadNode.java @@ -57,10 +57,10 @@ public class QuadNode /** - * Use {@link QuadNode#getChildValueCount()} if you want the number of non-null child values. + * Use {@link QuadNode#getNonNullChildCount()} if you want the number of non-null child values. * @return the number of non-null child nodes */ - public int getChildCount() + public int getTotalChildCount() { int count = 0; for (int i = 0; i < 4; i++) @@ -74,13 +74,13 @@ public class QuadNode } /** @return the number of children that have non-null values */ - public int getChildValueCount() + public int getNonNullChildCount() { int count = 0; for (int i = 0; i < 4; i++) { QuadNode child = this.getChildByIndex(i); - if (child != null && (child.value != null || child.getChildValueCount() != 0)) + if (child != null && (child.value != null || child.getNonNullChildCount() != 0)) { count++; } @@ -296,29 +296,30 @@ public class QuadNode } - if (nwChild != null) - { - removedItemConsumer.accept(nwChild.value); - } - nwChild = null; - if (neChild != null) + if (this.nwChild != null && removedItemConsumer != null) { - removedItemConsumer.accept(neChild.value); + removedItemConsumer.accept(this.nwChild.value); } - neChild = null; + this.nwChild = null; - if (seChild != null) + if (this.neChild != null && removedItemConsumer != null) { - removedItemConsumer.accept(seChild.value); + removedItemConsumer.accept(this.neChild.value); } - seChild = null; + this.neChild = null; - if (swChild != null) + if (this.seChild != null && removedItemConsumer != null) { - removedItemConsumer.accept(swChild.value); + removedItemConsumer.accept(this.seChild.value); } - swChild = null; + this.seChild = null; + + if (this.swChild != null && removedItemConsumer != null) + { + removedItemConsumer.accept(this.swChild.value); + } + this.swChild = null; } @@ -328,6 +329,6 @@ public class QuadNode //==============// @Override - public String toString() { return "pos: "+this.sectionPos+", children #: "+this.getChildCount()+", value: "+this.value; } + public String toString() { return "pos: "+this.sectionPos+", children #: "+this.getTotalChildCount()+", value: "+this.value; } } diff --git a/core/src/main/java/com/seibel/lod/core/util/objects/quadTree/QuadTree.java b/core/src/main/java/com/seibel/lod/core/util/objects/quadTree/QuadTree.java index b2a42e246..aa502ba8e 100644 --- a/core/src/main/java/com/seibel/lod/core/util/objects/quadTree/QuadTree.java +++ b/core/src/main/java/com/seibel/lod/core/util/objects/quadTree/QuadTree.java @@ -72,7 +72,7 @@ public class QuadTree //=====================// /** @return the node at the given section position */ - public final QuadNode getNode(DhSectionPos pos) throws IndexOutOfBoundsException { return this.getOrSetNode(pos, false, null); } + public final QuadNode getNode(DhSectionPos pos) throws IndexOutOfBoundsException { return this.getOrSetNode(pos, false, null, false); } /** @return the value at the given section position */ public final T getValue(DhSectionPos pos) throws IndexOutOfBoundsException { @@ -88,13 +88,14 @@ public class QuadTree public final T setValue(DhSectionPos pos, T value) throws IndexOutOfBoundsException { T previousValue = this.getValue(pos); - this.getOrSetNode(pos, true, value); + this.getOrSetNode(pos, true, value, true); return previousValue; } - protected final QuadNode getOrSetNode(DhSectionPos pos, boolean setNewValue, T newValue) throws IndexOutOfBoundsException + /** @param runBoundaryChecks should only ever be set to true internally for removing out of bound nodes */ + protected final QuadNode getOrSetNode(DhSectionPos pos, boolean setNewValue, T newValue, boolean runBoundaryChecks) throws IndexOutOfBoundsException { - if (this.isSectionPosInBounds(pos)) + if (!runBoundaryChecks || this.isSectionPosInBounds(pos)) { DhSectionPos rootPos = pos.convertToDetailLevel(this.treeMaxDetailLevel); int ringListPosX = rootPos.sectionX; @@ -224,16 +225,22 @@ public class QuadTree BitShiftUtil.divideByPowerOfTwo(this.centerBlockPos.x, this.treeMaxDetailLevel), BitShiftUtil.divideByPowerOfTwo(this.centerBlockPos.z, this.treeMaxDetailLevel)); - if (!this.topRingList.getCenter().equals(expectedCenterPos)) + if (this.topRingList.getCenter().equals(expectedCenterPos)) { - this.topRingList.moveTo(expectedCenterPos.x, expectedCenterPos.y, (quadNode) -> - { - if (quadNode != null && removedItemConsumer != null) - { - removedItemConsumer.accept(quadNode.value); - } - }); + // tree doesn't need to be moved + return; } + + + // remove out of bounds root nodes + this.topRingList.moveTo(expectedCenterPos.x, expectedCenterPos.y, (quadNode) -> + { + if (quadNode != null && removedItemConsumer != null) + { + removedItemConsumer.accept(quadNode.value); + } + }); + } public final DhBlockPos2D getCenterBlockPos() { return this.centerBlockPos; } @@ -246,27 +253,55 @@ public class QuadTree // base methods // //==============// - public boolean isEmpty() { return this.leafNodeCount() == 0; } // TODO this should be rewritten to short-circuit + public boolean isEmpty() { return this.count() == 0; } // TODO this should be rewritten to short-circuit - public int leafNodeCount() + /** @return the number of non-null nodes in the tree */ + public int count() { int count = 0; for (QuadNode node : this.topRingList) { - if (node != null) + if (node == null) { - Iterator> leafNodeIterator = node.getLeafNodeIterator(); - while (leafNodeIterator.hasNext()) + continue; + } + + Iterator> nodeIterator = node.getNodeIterator(); + while (nodeIterator.hasNext()) + { + if(nodeIterator.next().value != null) { - leafNodeIterator.next(); - count++; + count++; } } } - + return count; } + /** @return the number of leaf nodes in the tree */ + public int leafNodeCount() + { + int count = 0; + for (QuadNode node : this.topRingList) + { + if (node == null) + { + continue; + } + + Iterator> leafNodeIterator = node.getLeafNodeIterator(); + while (leafNodeIterator.hasNext()) + { + leafNodeIterator.next(); + count++; + } + } + + return count; + } + + // TODO comment, currently a tree will always have 9 root nodes, because the tree will grow all the way up to the top, if this is ever changed then these values must also change public int ringListWidth() { return 3; } public int ringListHalfWidth() { return 1; } @@ -309,7 +344,7 @@ public class QuadTree DhSectionPos rootPos = new DhSectionPos(QuadTree.this.treeMaxDetailLevel, pos2D.x, pos2D.y); if (QuadTree.this.isSectionPosInBounds(rootPos)) { - iteratorPosQueue.add(rootPos); + this.iteratorPosQueue.add(rootPos); } } }); @@ -347,9 +382,12 @@ public class QuadTree private final QuadTreeRootPosIterator rootNodeIterator; private Iterator> currentNodeIterator; + private QuadNode lastNode = null; + private final boolean onlyReturnLeaves; + public QuadTreeNodeIterator(boolean onlyReturnLeaves) { this.rootNodeIterator = new QuadTreeRootPosIterator(false); @@ -383,7 +421,8 @@ public class QuadTree } - return this.currentNodeIterator.next(); + this.lastNode = this.currentNodeIterator.next(); + return this.lastNode; } /** @return null if no new iterator could be found */ @@ -403,9 +442,21 @@ public class QuadTree } - /** Unimplemented */ @Override - public void remove() { throw new UnsupportedOperationException("remove"); } + public void remove() + { + if (this.lastNode == null) + { + throw new NoSuchElementException("No last node found."); + } + + + QuadNode node = QuadTree.this.getOrSetNode(this.lastNode.sectionPos, true, null, false); + if (node != null) + { + node.deleteAllChildren(); + } + } @Override public void forEachRemaining(Consumer> action) { Iterator.super.forEachRemaining(action); } diff --git a/core/src/main/java/com/seibel/lod/core/util/objects/quadTree/iterators/QuadTreeNodeIterator.java b/core/src/main/java/com/seibel/lod/core/util/objects/quadTree/iterators/QuadTreeNodeIterator.java index 61a4adfcb..5d22816f1 100644 --- a/core/src/main/java/com/seibel/lod/core/util/objects/quadTree/iterators/QuadTreeNodeIterator.java +++ b/core/src/main/java/com/seibel/lod/core/util/objects/quadTree/iterators/QuadTreeNodeIterator.java @@ -56,7 +56,7 @@ public class QuadTreeNodeIterator implements Iterator> QuadNode childNode = parentNode.getChildByIndex(i); if (childNode != null) { - if (childNode.getChildCount() == 0) + if (childNode.getTotalChildCount() == 0) { this.iteratorNodeQueue.add(childNode); }