diff --git a/src/main/java/de/bixilon/minosoft/data/world/World.kt b/src/main/java/de/bixilon/minosoft/data/world/World.kt index 243a3065d..6a9fd7527 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/World.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/World.kt @@ -209,7 +209,7 @@ class World( } companion object { - const val MAX_SIZE = 30_000_000 + const val MAX_SIZE = BlockPosition.MAX_X const val MAX_SIZEf = MAX_SIZE.toFloat() const val MAX_SIZEd = MAX_SIZE.toDouble() const val MAX_RENDER_DISTANCE = 64 diff --git a/src/main/java/de/bixilon/minosoft/data/world/positions/BlockPosition.kt b/src/main/java/de/bixilon/minosoft/data/world/positions/BlockPosition.kt index 4c42814d4..e36e34b6e 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/positions/BlockPosition.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/positions/BlockPosition.kt @@ -33,11 +33,12 @@ value class BlockPosition( assertPosition(y, MIN_Y, MAX_Y) assertPosition(z, -MAX_Z, MAX_Z) } + constructor(position: InChunkPosition) : this(position.x, position.y, position.z) - inline val x: Int get() = (raw shr SHIFT_X).toInt() and MASK_X - inline val y: Int get() = (raw shr SHIFT_Y).toInt() and MASK_Y - inline val z: Int get() = (raw shr SHIFT_Z).toInt() and MASK_Z + inline val x: Int get() = (((raw ushr SHIFT_X).toInt() and MASK_X) shl (Int.SIZE_BITS - BITS_X)) shr (Int.SIZE_BITS - BITS_X) + inline val y: Int get() = (((raw ushr SHIFT_Y).toInt() and MASK_Y) shl (Int.SIZE_BITS - BITS_Y)) shr (Int.SIZE_BITS - BITS_Y) + inline val z: Int get() = (((raw ushr SHIFT_Z).toInt() and MASK_Z) shl (Int.SIZE_BITS - BITS_Z)) shr (Int.SIZE_BITS - BITS_Z) inline fun plusX(): BlockPosition { @@ -61,7 +62,7 @@ value class BlockPosition( } inline fun plusY(y: Int): BlockPosition { - assertPosition(this.y + y, -MAX_Y, MAX_Y) + assertPosition(this.y + y, MIN_Y, MAX_Y) return BlockPosition(raw + Y * y) } @@ -129,13 +130,13 @@ value class BlockPosition( const val MASK_Y = (1 shl BITS_Y) - 1 const val SHIFT_Y = BITS_X + BITS_Z - const val X = 1 shl SHIFT_X - const val Z = 1 shl SHIFT_Z - const val Y = 1 shl SHIFT_Y + const val X = 1L shl SHIFT_X + const val Z = 1L shl SHIFT_Z + const val Y = 1L shl SHIFT_Y const val MAX_X = 30_000_000 - const val MIN_Y = -2047 - const val MAX_Y = 2048 + const val MIN_Y = -2048 + const val MAX_Y = 2047 const val MAX_Z = 30_000_000 diff --git a/src/main/java/de/bixilon/minosoft/data/world/positions/ChunkPosition.kt b/src/main/java/de/bixilon/minosoft/data/world/positions/ChunkPosition.kt index d17273612..6f02111bb 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/positions/ChunkPosition.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/positions/ChunkPosition.kt @@ -26,7 +26,7 @@ value class ChunkPosition( constructor() : this(0, 0) - constructor(x: Int, z: Int) : this((z.toLong() shl SHIFT_Z) or (x.toLong() shl SHIFT_X)) { + constructor(x: Int, z: Int) : this(((z.toLong() and Integer.toUnsignedLong(MASK_Z)) shl SHIFT_Z) or ((x.toLong() and Integer.toUnsignedLong(MASK_X)) shl SHIFT_X)) { assertPosition(x, -MAX_X, MAX_X) assertPosition(z, -MAX_Z, MAX_Z) } @@ -92,19 +92,19 @@ value class ChunkPosition( companion object { const val BITS_X = 32 - const val MASK_X = (1 shl BITS_X) - 1 + const val MASK_X = ((1L shl BITS_X) - 1).toInt() const val SHIFT_X = 0 const val BITS_Z = 32 - const val MASK_Z = (1 shl BITS_Z) - 1 + const val MASK_Z = ((1L shl BITS_Z) - 1).toInt() const val SHIFT_Z = BITS_X const val X = 1L shl SHIFT_X const val Z = 1L shl SHIFT_Z - const val MAX_X = Int.MAX_VALUE // TODO - const val MAX_Z = Int.MAX_VALUE // TODO + const val MAX_X = (BlockPosition.MAX_X shr 4) + 1 + const val MAX_Z = (BlockPosition.MAX_Z shr 4) + 1 val EMPTY = ChunkPosition(0, 0) diff --git a/src/main/java/de/bixilon/minosoft/data/world/positions/InChunkPosition.kt b/src/main/java/de/bixilon/minosoft/data/world/positions/InChunkPosition.kt index 6af29592e..5fd2e4bfd 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/positions/InChunkPosition.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/positions/InChunkPosition.kt @@ -34,9 +34,9 @@ value class InChunkPosition( assertPosition(z, 0, ProtocolDefinition.SECTION_MAX_Z) } - inline val x: Int get() = (raw shr SHIFT_X) and MASK_X - inline val y: Int get() = (raw and (MASK_Y shl SHIFT_Y)) shl 20 shr 20 - inline val z: Int get() = (raw shr SHIFT_Z) and MASK_Z + inline val x: Int get() = (raw ushr SHIFT_X) and MASK_X + inline val y: Int get() = (((raw ushr SHIFT_Y) and MASK_Y) shl (Int.SIZE_BITS - BITS_Y)) shr (Int.SIZE_BITS - BITS_Y) + inline val z: Int get() = (raw ushr SHIFT_Z) and MASK_Z inline val xz: Int get() = raw and ((MASK_X shl SHIFT_X) or (MASK_Z shl SHIFT_Z)) diff --git a/src/test/java/de/bixilon/minosoft/data/world/positions/BlockPositionTest.kt b/src/test/java/de/bixilon/minosoft/data/world/positions/BlockPositionTest.kt index 101509533..e65040c0a 100644 --- a/src/test/java/de/bixilon/minosoft/data/world/positions/BlockPositionTest.kt +++ b/src/test/java/de/bixilon/minosoft/data/world/positions/BlockPositionTest.kt @@ -40,12 +40,24 @@ class BlockPositionTest { assertEquals(position.x, 2) } + @Test + fun `correct positive x large`() { + val position = BlockPosition(29_999_999, 0xF, 0xF) + assertEquals(position.x, 29_999_999) + } + @Test fun `correct negative x`() { val position = BlockPosition(-2, 0xF, 0xF) assertEquals(position.x, -2) } + @Test + fun `correct negative x large`() { + val position = BlockPosition(-29_999_999, 0xF, 0xF) + assertEquals(position.x, -29_999_999) + } + @Test fun `correct plus x`() { val position = BlockPosition(2, 0xF, 0xF) @@ -70,12 +82,24 @@ class BlockPositionTest { assertEquals(position.y, -1000) } + @Test + fun `correct negative y large`() { + val position = BlockPosition(-2048, 0xF, 0xF) + assertEquals(position.x, -2048) + } + @Test fun `correct positive y`() { val position = BlockPosition(0xF, 1000, 0xF) assertEquals(position.y, 1000) } + @Test + fun `correct positive y large`() { + val position = BlockPosition(0xF, 2047, 0xF) + assertEquals(position.y, 2047) + } + @Test fun `correct plus y`() { val position = BlockPosition(0xF, 2, 0xF) @@ -100,12 +124,25 @@ class BlockPositionTest { assertEquals(position.z, 4) } + @Test + fun `correct positive z large`() { + val position = BlockPosition(0, 0, 29_999_999) + assertEquals(position.z, 29_999_999) + } + @Test fun `correct negative z`() { val position = BlockPosition(0xF, 0xF, -4) assertEquals(position.z, -4) } + @Test + fun `correct negative z large`() { + val position = BlockPosition(0, 0, -29_999_999) + assertEquals(position.z, -29_999_999) + } + + @Test fun `correct plus z`() { val position = BlockPosition(0xF, 0xF, 2) diff --git a/src/test/java/de/bixilon/minosoft/data/world/positions/BlockPositionUtilTest.kt b/src/test/java/de/bixilon/minosoft/data/world/positions/BlockPositionUtilTest.kt index 9215bda3f..086acacfd 100644 --- a/src/test/java/de/bixilon/minosoft/data/world/positions/BlockPositionUtilTest.kt +++ b/src/test/java/de/bixilon/minosoft/data/world/positions/BlockPositionUtilTest.kt @@ -37,9 +37,4 @@ class BlockPositionUtilTest { fun hash4() { assertEquals(10888876138951, BlockPosition(123, -456, 789).hash) } - - @Test - fun hash5() { - assertEquals(65198192324831, BlockPosition(5473628, 123123, 1234737534).hash) - } } diff --git a/src/test/java/de/bixilon/minosoft/data/world/positions/ChunkPositionTest.kt b/src/test/java/de/bixilon/minosoft/data/world/positions/ChunkPositionTest.kt index 46d5a1e01..f8155cc20 100644 --- a/src/test/java/de/bixilon/minosoft/data/world/positions/ChunkPositionTest.kt +++ b/src/test/java/de/bixilon/minosoft/data/world/positions/ChunkPositionTest.kt @@ -40,12 +40,24 @@ class ChunkPositionTest { assertEquals(position.x, 2) } + @Test + fun `correct positive x large`() { + val position = ChunkPosition(1875000, 1875000) + assertEquals(position.x, 1875000) + } + @Test fun `correct negative x`() { val position = ChunkPosition(-2, 0xF) assertEquals(position.x, -2) } + @Test + fun `correct negative x large`() { + val position = ChunkPosition(-1875000, -1875000) + assertEquals(position.x, -1875000) + } + @Test fun `correct plus x`() { val position = ChunkPosition(2, 0xF) @@ -70,12 +82,24 @@ class ChunkPositionTest { assertEquals(position.z, 4) } + @Test + fun `correct positive z large`() { + val position = ChunkPosition(1875000, 1875000) + assertEquals(position.z, 1875000) + } + @Test fun `correct negative z`() { val position = ChunkPosition(0xF, -4) assertEquals(position.z, -4) } + @Test + fun `correct negative z large`() { + val position = ChunkPosition(-1875000, -1875000) + assertEquals(position.z, -1875000) + } + @Test fun `correct plus z`() { val position = ChunkPosition(0xF, 2)