diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/interfaces/IFullDataSource.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/interfaces/IFullDataSource.java index 6e2845800..622c67d04 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/interfaces/IFullDataSource.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/interfaces/IFullDataSource.java @@ -144,7 +144,7 @@ public interface IFullDataSource int widthInSecPos = BitShiftUtil.powerOfTwo(quadrantDetailLevelDiff); int relWidthForSecPos = sourceRelWidth / widthInSecPos; - DhSectionPos minSecPos = this.getSectionPos().convertToDetailLevel(childDetailLevel); + DhSectionPos minSecPos = this.getSectionPos().convertNewToDetailLevel(childDetailLevel); DhSectionPos inputPos = quadrantPos; @@ -195,7 +195,7 @@ public interface IFullDataSource int widthInSecPos = BitShiftUtil.powerOfTwo(quadrantDetailLevelDiff); int relWidthForSecPos = sourceRelWidth / widthInSecPos; - DhSectionPos minSecPos = this.getSectionPos().convertToDetailLevel(childDetailLevel); + DhSectionPos minSecPos = this.getSectionPos().convertNewToDetailLevel(childDetailLevel); DhSectionPos inputPos = quadrantPos.getChildByIndex(i); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/pos/DhSectionPos.java b/core/src/main/java/com/seibel/distanthorizons/core/pos/DhSectionPos.java index 895dd9a65..b908d89ad 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/pos/DhSectionPos.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/pos/DhSectionPos.java @@ -56,12 +56,12 @@ public class DhSectionPos public final static byte SECTION_REGION_DETAIL_LEVEL = SECTION_MINIMUM_DETAIL_LEVEL + LodUtil.REGION_DETAIL_LEVEL; - public final byte sectionDetailLevel; + public byte sectionDetailLevel; /** in a sectionDetailLevel grid */ - public final int sectionX; + public int sectionX; /** in a sectionDetailLevel grid */ - public final int sectionZ; + public int sectionZ; @@ -76,25 +76,21 @@ public class DhSectionPos this.sectionZ = sectionZ; } - public DhSectionPos(DhBlockPos blockPos) { this(new DhBlockPos2D(blockPos)); } + public DhSectionPos(DhBlockPos blockPos) + { + this(LodUtil.BLOCK_DETAIL_LEVEL, blockPos.x, blockPos.z); + this.convertSelfToDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL); + } public DhSectionPos(DhBlockPos2D blockPos) { - DhLodPos lodPos = new DhLodPos(LodUtil.BLOCK_DETAIL_LEVEL, blockPos.x, blockPos.z); - lodPos = lodPos.convertToDetailLevel(SECTION_BLOCK_DETAIL_LEVEL); - - this.sectionDetailLevel = SECTION_BLOCK_DETAIL_LEVEL; - this.sectionX = lodPos.x; - this.sectionZ = lodPos.z; + this(LodUtil.BLOCK_DETAIL_LEVEL, blockPos.x, blockPos.z); + this.convertSelfToDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL); } public DhSectionPos(DhChunkPos chunkPos) { - DhLodPos lodPos = new DhLodPos(LodUtil.CHUNK_DETAIL_LEVEL, chunkPos.x, chunkPos.z); - lodPos = lodPos.convertToDetailLevel(SECTION_CHUNK_DETAIL_LEVEL); - - this.sectionDetailLevel = SECTION_CHUNK_DETAIL_LEVEL; - this.sectionX = lodPos.x; - this.sectionZ = lodPos.z; + this(LodUtil.CHUNK_DETAIL_LEVEL, chunkPos.x, chunkPos.z); + this.convertSelfToDetailLevel(DhSectionPos.SECTION_CHUNK_DETAIL_LEVEL); } public DhSectionPos(byte detailLevel, DhLodPos dhLodPos) @@ -110,17 +106,34 @@ public class DhSectionPos // converters // //============// + /** uses the absolute detail level aka detail levels like {@link LodUtil#CHUNK_DETAIL_LEVEL} instead of the dhSectionPos detailLevels. */ + public void convertSelfToDetailLevel(byte newDetailLevel) + { + // logic originally taken from DhLodPos + if (newDetailLevel >= this.sectionDetailLevel) + { + this.sectionX = Math.floorDiv(this.sectionX, BitShiftUtil.powerOfTwo(newDetailLevel - this.sectionDetailLevel)); + this.sectionZ = Math.floorDiv(this.sectionZ, BitShiftUtil.powerOfTwo(newDetailLevel - this.sectionDetailLevel)); + } + else + { + this.sectionX = this.sectionX * BitShiftUtil.powerOfTwo(this.sectionDetailLevel - newDetailLevel); + this.sectionZ = this.sectionZ * BitShiftUtil.powerOfTwo(this.sectionDetailLevel - newDetailLevel); + } + + this.sectionDetailLevel = newDetailLevel; + } + /** - * uses the absolute detail level aka detail levels like {@link LodUtil#CHUNK_DETAIL_LEVEL} instead of the dhSectionPos detailLevels + * uses the absolute detail level aka detail levels like {@link LodUtil#CHUNK_DETAIL_LEVEL} instead of the dhSectionPos detailLevels. * * @return the new position closest to negative infinity with the new detail level */ - public DhSectionPos convertToDetailLevel(byte newSectionDetailLevel) + public DhSectionPos convertNewToDetailLevel(byte newSectionDetailLevel) { - DhLodPos lodPos = new DhLodPos(this.sectionDetailLevel, this.sectionX, this.sectionZ); - lodPos = lodPos.convertToDetailLevel(newSectionDetailLevel); + DhSectionPos newPos = new DhSectionPos(this.sectionDetailLevel, this.sectionX, this.sectionZ); + newPos.convertSelfToDetailLevel(newSectionDetailLevel); - DhSectionPos newPos = new DhSectionPos(newSectionDetailLevel, lodPos); return newPos; } @@ -168,7 +181,7 @@ public class DhSectionPos this.sectionZ * BitShiftUtil.powerOfTwo(offset)); } - public DhLodUnit getWidth() { return this.getWidth(this.sectionDetailLevel); } + public DhLodUnit getWidth() { return this.getWidth(this.sectionDetailLevel); } // this always returns 1... public DhLodUnit getWidth(byte returnDetailLevel) { LodUtil.assertTrue(returnDetailLevel <= this.sectionDetailLevel, "returnDetailLevel must be less than sectionDetail"); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/QuadNode.java b/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/QuadNode.java index e2b585c40..8f4d2ba45 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/QuadNode.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/QuadNode.java @@ -180,7 +180,7 @@ public class QuadNode if (!this.sectionPos.contains(inputSectionPos)) { LOGGER.error((replaceValue ? "set " : "get ") + inputSectionPos + " center block: " + inputSectionPos.getCenter().getCornerBlockPos() + ", this pos: " + this.sectionPos + " this center block: " + this.sectionPos.getCenter().getCornerBlockPos()); - throw new IllegalArgumentException("Input section pos " + inputSectionPos + " outside of this quadNode's pos: " + this.sectionPos + ", this node's blockPos: " + this.sectionPos.convertToDetailLevel(LodUtil.BLOCK_DETAIL_LEVEL) + " block width: " + this.sectionPos.getWidth().toBlockWidth() + " input detail level: " + inputSectionPos.convertToDetailLevel(LodUtil.BLOCK_DETAIL_LEVEL) + " width: " + inputSectionPos.getWidth().toBlockWidth()); + throw new IllegalArgumentException("Input section pos " + inputSectionPos + " outside of this quadNode's pos: " + this.sectionPos + ", this node's blockPos: " + this.sectionPos.convertNewToDetailLevel(LodUtil.BLOCK_DETAIL_LEVEL) + " block width: " + this.sectionPos.getWidth().toBlockWidth() + " input detail level: " + inputSectionPos.convertNewToDetailLevel(LodUtil.BLOCK_DETAIL_LEVEL) + " width: " + inputSectionPos.getWidth().toBlockWidth()); } if (inputSectionPos.sectionDetailLevel > this.sectionPos.sectionDetailLevel) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/QuadTree.java b/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/QuadTree.java index 2014e4039..9913d3905 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/QuadTree.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/QuadTree.java @@ -121,7 +121,7 @@ public class QuadTree { if (!runBoundaryChecks || this.isSectionPosInBounds(pos)) { - DhSectionPos rootPos = pos.convertToDetailLevel(this.treeMinDetailLevel); + DhSectionPos rootPos = pos.convertNewToDetailLevel(this.treeMinDetailLevel); int ringListPosX = rootPos.sectionX; int ringListPosZ = rootPos.sectionZ; @@ -156,7 +156,7 @@ public class QuadTree int radius = this.diameterInBlocks() / 2; DhBlockPos2D minPos = this.getCenterBlockPos().add(new DhBlockPos2D(-radius, -radius)); DhBlockPos2D maxPos = this.getCenterBlockPos().add(new DhBlockPos2D(radius, radius)); - throw new IndexOutOfBoundsException("QuadTree GetOrSet failed. Position out of bounds, min pos: " + minPos + ", max pos: " + maxPos + ", min detail level: " + this.treeMaxDetailLevel + ", max detail level: " + this.treeMinDetailLevel + ". Given Position: " + pos + " = block pos: " + pos.convertToDetailLevel(LodUtil.BLOCK_DETAIL_LEVEL)); + throw new IndexOutOfBoundsException("QuadTree GetOrSet failed. Position out of bounds, min pos: " + minPos + ", max pos: " + maxPos + ", min detail level: " + this.treeMaxDetailLevel + ", max detail level: " + this.treeMinDetailLevel + ". Given Position: " + pos + " = block pos: " + pos.convertNewToDetailLevel(LodUtil.BLOCK_DETAIL_LEVEL)); } } @@ -174,7 +174,7 @@ public class QuadTree DhBlockPos2D treeBlockCorner = this.centerBlockPos.add(new DhBlockPos2D(-this.widthInBlocks / 2, -this.widthInBlocks / 2)); DhLodPos treeCornerPos = new DhLodPos((byte) 0, treeBlockCorner.x, treeBlockCorner.z); - DhSectionPos inputSectionCorner = testPos.convertToDetailLevel((byte) 0); + DhSectionPos inputSectionCorner = testPos.convertNewToDetailLevel((byte) 0); DhLodPos inputCornerPos = new DhLodPos((byte) 0, inputSectionCorner.sectionX, inputSectionCorner.sectionZ); int inputBlockWidth = BitShiftUtil.powerOfTwo(testPos.sectionDetailLevel); diff --git a/core/src/test/java/tests/DhSectionPosTest.java b/core/src/test/java/tests/DhSectionPosTest.java index eb36fd675..3d37e5239 100644 --- a/core/src/test/java/tests/DhSectionPosTest.java +++ b/core/src/test/java/tests/DhSectionPosTest.java @@ -83,22 +83,22 @@ public class DhSectionPosTest public void ParentPosTest() { DhSectionPos leaf = new DhSectionPos((byte) 0, 0, 0); - DhSectionPos convert = leaf.convertToDetailLevel((byte) 1); + DhSectionPos convert = leaf.convertNewToDetailLevel((byte) 1); DhSectionPos parent = leaf.getParentPos(); Assert.assertEquals("get parent at 0,0 fail", convert, parent); leaf = new DhSectionPos((byte) 0, 1, 1); - convert = leaf.convertToDetailLevel((byte) 1); + convert = leaf.convertNewToDetailLevel((byte) 1); parent = leaf.getParentPos(); Assert.assertEquals("get parent at 1,1 fail", convert, parent); leaf = new DhSectionPos((byte) 1, 2, 2); - convert = leaf.convertToDetailLevel((byte) 2); + convert = leaf.convertNewToDetailLevel((byte) 2); parent = leaf.getParentPos(); Assert.assertEquals("parent upscale fail", convert, parent); - convert = leaf.convertToDetailLevel((byte) 0); + convert = leaf.convertNewToDetailLevel((byte) 0); DhSectionPos childIndex = leaf.getChildByIndex(0); Assert.assertEquals("child detail fail", convert, childIndex); @@ -231,13 +231,13 @@ public class DhSectionPosTest DhSectionPos originSectionPos = new DhSectionPos((byte) 0,0,0); - originSectionPos = originSectionPos.convertToDetailLevel((byte) 1); + originSectionPos = originSectionPos.convertNewToDetailLevel((byte) 1); Assert.assertEquals(new DhSectionPos((byte) 1, 0, 0), originSectionPos); - originSectionPos = originSectionPos.convertToDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL); + originSectionPos = originSectionPos.convertNewToDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL); Assert.assertEquals(new DhSectionPos(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, 0, 0), originSectionPos); - originSectionPos = originSectionPos.convertToDetailLevel(DhSectionPos.SECTION_REGION_DETAIL_LEVEL); + originSectionPos = originSectionPos.convertNewToDetailLevel(DhSectionPos.SECTION_REGION_DETAIL_LEVEL); Assert.assertEquals(new DhSectionPos(DhSectionPos.SECTION_REGION_DETAIL_LEVEL, 0, 0), originSectionPos); @@ -245,13 +245,13 @@ public class DhSectionPosTest DhSectionPos sectionPos = new DhSectionPos((byte) 0,-10000,5000); - sectionPos = sectionPos.convertToDetailLevel((byte) 1); + sectionPos = sectionPos.convertNewToDetailLevel((byte) 1); Assert.assertEquals(new DhSectionPos((byte) 1, -5000, 2500), sectionPos); - sectionPos = sectionPos.convertToDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL); + sectionPos = sectionPos.convertNewToDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL); Assert.assertEquals(new DhSectionPos(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, -157, 78), sectionPos); - sectionPos = sectionPos.convertToDetailLevel(DhSectionPos.SECTION_REGION_DETAIL_LEVEL); + sectionPos = sectionPos.convertNewToDetailLevel(DhSectionPos.SECTION_REGION_DETAIL_LEVEL); Assert.assertEquals(new DhSectionPos(DhSectionPos.SECTION_REGION_DETAIL_LEVEL, -1, 0), sectionPos); } @@ -263,19 +263,19 @@ public class DhSectionPosTest DhSectionPos sectionPos = new DhSectionPos((byte) 0,-10000,5000); // widths should be the same regardless of position in the world - originSectionPos = originSectionPos.convertToDetailLevel((byte) 1); + originSectionPos = originSectionPos.convertNewToDetailLevel((byte) 1); Assert.assertEquals(1, originSectionPos.getWidth().numberOfLodSectionsWide); - sectionPos = sectionPos.convertToDetailLevel((byte) 1); + sectionPos = sectionPos.convertNewToDetailLevel((byte) 1); Assert.assertEquals(1, sectionPos.getWidth().numberOfLodSectionsWide); - originSectionPos = originSectionPos.convertToDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL); + originSectionPos = originSectionPos.convertNewToDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL); Assert.assertEquals(1, originSectionPos.getWidth().numberOfLodSectionsWide); - sectionPos = sectionPos.convertToDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL); + sectionPos = sectionPos.convertNewToDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL); Assert.assertEquals(1, sectionPos.getWidth().numberOfLodSectionsWide); - originSectionPos = originSectionPos.convertToDetailLevel(DhSectionPos.SECTION_REGION_DETAIL_LEVEL); + originSectionPos = originSectionPos.convertNewToDetailLevel(DhSectionPos.SECTION_REGION_DETAIL_LEVEL); Assert.assertEquals(1, originSectionPos.getWidth().numberOfLodSectionsWide); - sectionPos = sectionPos.convertToDetailLevel(DhSectionPos.SECTION_REGION_DETAIL_LEVEL); + sectionPos = sectionPos.convertNewToDetailLevel(DhSectionPos.SECTION_REGION_DETAIL_LEVEL); Assert.assertEquals(1, sectionPos.getWidth().numberOfLodSectionsWide); } @@ -285,19 +285,19 @@ public class DhSectionPosTest DhSectionPos originSectionPos = new DhSectionPos((byte) 0,0,0); DhSectionPos sectionPos = new DhSectionPos((byte) 0,-10000,5000); - originSectionPos = originSectionPos.convertToDetailLevel((byte) 1); + originSectionPos = originSectionPos.convertNewToDetailLevel((byte) 1); Assert.assertEquals(2, originSectionPos.getWidth((byte) 0).numberOfLodSectionsWide); - sectionPos = sectionPos.convertToDetailLevel((byte) 1); + sectionPos = sectionPos.convertNewToDetailLevel((byte) 1); Assert.assertEquals(2, sectionPos.getWidth((byte) 0).numberOfLodSectionsWide); - originSectionPos = originSectionPos.convertToDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL); + originSectionPos = originSectionPos.convertNewToDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL); Assert.assertEquals(64, originSectionPos.getWidth((byte) 0).numberOfLodSectionsWide); - sectionPos = sectionPos.convertToDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL); + sectionPos = sectionPos.convertNewToDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL); Assert.assertEquals(64, sectionPos.getWidth((byte) 0).numberOfLodSectionsWide); - originSectionPos = originSectionPos.convertToDetailLevel(DhSectionPos.SECTION_REGION_DETAIL_LEVEL); + originSectionPos = originSectionPos.convertNewToDetailLevel(DhSectionPos.SECTION_REGION_DETAIL_LEVEL); Assert.assertEquals(4096, originSectionPos.getWidth((byte) 3).numberOfLodSectionsWide); - sectionPos = sectionPos.convertToDetailLevel(DhSectionPos.SECTION_REGION_DETAIL_LEVEL); + sectionPos = sectionPos.convertNewToDetailLevel(DhSectionPos.SECTION_REGION_DETAIL_LEVEL); Assert.assertEquals(4096, sectionPos.getWidth((byte) 3).numberOfLodSectionsWide); }