Start adding new DhSectionPos and unit tests
This commit is contained in:
@@ -0,0 +1,411 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.core.pos;
|
||||
|
||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.coreapi.util.BitShiftUtil;
|
||||
|
||||
/**
|
||||
* The position object used to define LOD objects in the quad trees. <br><br>
|
||||
*
|
||||
* A section contains 64 x 64 LOD columns at a given quality.
|
||||
* The Section detail level is different from the LOD detail level.
|
||||
* For the specifics of how they compare can be viewed in the constants {@link #SECTION_BLOCK_DETAIL_LEVEL},
|
||||
* {@link #SECTION_CHUNK_DETAIL_LEVEL}, and {@link #SECTION_REGION_DETAIL_LEVEL}).<br><br>
|
||||
*
|
||||
* <strong>Why does the smallest render section represent 2x2 MC chunks (section detail level 6)? </strong> <br>
|
||||
* A section defines what unit the quad tree works in, because of that we don't want that unit to be too big or too small. <br>
|
||||
* <strong>Too small</strong>, and we'll have 1,000s of sections running around, all needing individual files and render buffers.<br>
|
||||
* <strong>Too big</strong>, and the LOD dropoff will be very noticeable.<br>
|
||||
* With those thoughts in mind we decided on a smallest section size of 32 data points square (IE 2x2 chunks).
|
||||
*
|
||||
* @author Leetom
|
||||
*/
|
||||
public class DhSectionPos
|
||||
{
|
||||
/**
|
||||
* The lowest detail level a Section position can hold.
|
||||
* This section DetailLevel holds 64 x 64 Block level (detail level 0) LODs.
|
||||
*/
|
||||
public static final byte SECTION_MINIMUM_DETAIL_LEVEL = 6;
|
||||
|
||||
public static final byte SECTION_BLOCK_DETAIL_LEVEL = SECTION_MINIMUM_DETAIL_LEVEL + LodUtil.BLOCK_DETAIL_LEVEL;
|
||||
public static final byte SECTION_CHUNK_DETAIL_LEVEL = SECTION_MINIMUM_DETAIL_LEVEL + LodUtil.CHUNK_DETAIL_LEVEL;
|
||||
public static final byte SECTION_REGION_DETAIL_LEVEL = SECTION_MINIMUM_DETAIL_LEVEL + LodUtil.REGION_DETAIL_LEVEL;
|
||||
|
||||
|
||||
|
||||
public static final int DETAIL_LEVEL_WIDTH = 8;
|
||||
public static final int X_POS_WIDTH = 28;
|
||||
public static final int Z_POS_WIDTH = 28;
|
||||
public static final int X_POS_MISSING_WIDTH = 32 - 28;
|
||||
public static final int Z_POS_MISSING_WIDTH = 32 - 28;
|
||||
|
||||
|
||||
public static final int DETAIL_LEVEL_OFFSET = 0;
|
||||
public static final int POS_X_OFFSET = DETAIL_LEVEL_OFFSET + DETAIL_LEVEL_WIDTH;
|
||||
/** indicates the Y position where the LOD starts relative to the level's minimum height */
|
||||
public static final int POS_Z_OFFSET = POS_X_OFFSET + X_POS_WIDTH;
|
||||
|
||||
public static final long DETAIL_LEVEL_MASK = Byte.MAX_VALUE;
|
||||
public static final int POS_X_MASK = (int) Math.pow(2, X_POS_WIDTH) - 1;
|
||||
public static final int POS_Z_MASK = (int) Math.pow(2, Z_POS_WIDTH) - 1;
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// constructors //
|
||||
//==============//
|
||||
|
||||
/**
|
||||
* This class just holds utility methods for handling a packed
|
||||
* {@link DhSectionPos} and shouldn't be constructed. <Br><br>
|
||||
*
|
||||
* Use one of the {@link DhSectionPos#encode(byte, int, int)} methods instead
|
||||
*/
|
||||
private DhSectionPos() { }
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Note:
|
||||
* no validation is done for whether the detail level is positive
|
||||
* or if the X/Z positions can be represented by available bits.
|
||||
*/
|
||||
public static long encode(byte detailLevel, int x, int z)
|
||||
{
|
||||
long data = 0;
|
||||
data |= detailLevel & DETAIL_LEVEL_MASK;
|
||||
data |= (long) (x & POS_X_MASK) << POS_X_OFFSET;
|
||||
data |= (long) (z & POS_Z_MASK) << POS_Z_OFFSET;
|
||||
return data;
|
||||
}
|
||||
|
||||
public static long encode(DhBlockPos pos) { return encodeBlockPos(pos.x, pos.z); }
|
||||
public static long encode(DhBlockPos2D pos) { return encodeBlockPos(pos.x, pos.z); }
|
||||
public static long encodeBlockPos(int blockX, int blockZ)
|
||||
{
|
||||
long pos = encode(LodUtil.BLOCK_DETAIL_LEVEL, blockX, blockZ);
|
||||
pos = convertToDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, pos);
|
||||
return pos;
|
||||
}
|
||||
|
||||
public static long encode(DhChunkPos pos) { return encodeChunkPos(pos.x, pos.z); }
|
||||
public static long encodeChunkPos(int chunkX, int chunkZ)
|
||||
{
|
||||
long pos = encode(LodUtil.CHUNK_DETAIL_LEVEL, chunkX, chunkZ);
|
||||
pos = convertToDetailLevel(DhSectionPos.SECTION_CHUNK_DETAIL_LEVEL, pos);
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//============//
|
||||
// converters //
|
||||
//============//
|
||||
|
||||
/** uses the absolute detail level aka detail levels like {@link LodUtil#CHUNK_DETAIL_LEVEL} instead of the dhSectionPos detailLevels. */
|
||||
public static long convertToDetailLevel(byte newDetailLevel, long pos)
|
||||
{
|
||||
byte detailLevel = getDetailLevel(pos);
|
||||
int x = getX(pos);
|
||||
int z = getZ(pos);
|
||||
|
||||
// logic originally taken from DhLodPos
|
||||
if (newDetailLevel >= detailLevel)
|
||||
{
|
||||
x = Math.floorDiv(x, BitShiftUtil.powerOfTwo(newDetailLevel - detailLevel));
|
||||
z = Math.floorDiv(z, BitShiftUtil.powerOfTwo(newDetailLevel - detailLevel));
|
||||
}
|
||||
else
|
||||
{
|
||||
x = x * BitShiftUtil.powerOfTwo(detailLevel - newDetailLevel);
|
||||
z = z * BitShiftUtil.powerOfTwo(detailLevel - newDetailLevel);
|
||||
}
|
||||
|
||||
return encode(newDetailLevel, x, z);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==================//
|
||||
// property getters //
|
||||
//==================//
|
||||
|
||||
public static byte getDetailLevel(long pos) { return (byte) ((pos >> DETAIL_LEVEL_OFFSET) & DETAIL_LEVEL_MASK); }
|
||||
public static int getX(long pos)
|
||||
{
|
||||
// unpack the position
|
||||
int x = (int) ((pos >> POS_X_OFFSET) & POS_X_MASK);
|
||||
// add the missing 2's compliment most-significant bits (if not done negative numbers will parse incorrectly)
|
||||
x = (x << X_POS_MISSING_WIDTH) >> X_POS_MISSING_WIDTH;
|
||||
return x;
|
||||
}
|
||||
public static int getZ(long pos)
|
||||
{
|
||||
int Z = (int) ((pos >> POS_Z_OFFSET) & POS_Z_MASK);
|
||||
Z = (Z << Z_POS_MISSING_WIDTH) >> Z_POS_MISSING_WIDTH;
|
||||
return Z;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// getters //
|
||||
//=========//
|
||||
|
||||
/** @return the block X pos that represents the smallest X coordinate of this section */
|
||||
public static int getMinCornerBlockX(long pos)
|
||||
{
|
||||
int halfBlockWidth = DhSectionPos.getBlockWidth(pos) / 2;
|
||||
return DhSectionPos.getCenterBlockPosX(pos) - halfBlockWidth;
|
||||
}
|
||||
/** @return the block Z pos that represents the smallest Z coordinate of this section */
|
||||
public static int getMinCornerBlockZ(long pos)
|
||||
{
|
||||
int halfBlockWidth = DhSectionPos.getBlockWidth(pos) / 2;
|
||||
return DhSectionPos.getCenterBlockPosZ(pos) - halfBlockWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* A detail level of X lower than this section's detail level will return: <br>
|
||||
* 0 -> 1 <br>
|
||||
* 1 -> 2 <br>
|
||||
* 2 -> 4 <br>
|
||||
* 3 -> 8 <br>
|
||||
* etc.
|
||||
*
|
||||
* @return how many {@link DhSectionPos}'s at the given detail level it would take to span the width of this section.
|
||||
*/
|
||||
public static int getWidthCountForLowerDetailedSection(byte returnDetailLevel, long pos)
|
||||
{
|
||||
byte detailLevel = getDetailLevel(pos);
|
||||
|
||||
LodUtil.assertTrue(returnDetailLevel <= detailLevel, "returnDetailLevel must be less than sectionDetail");
|
||||
byte offset = (byte) (detailLevel - returnDetailLevel);
|
||||
return BitShiftUtil.powerOfTwo(offset);
|
||||
}
|
||||
|
||||
/** @return how wide this section is in blocks */
|
||||
public static int getBlockWidth(long pos) { return BitShiftUtil.powerOfTwo(getDetailLevel(pos)); }
|
||||
|
||||
|
||||
public static DhBlockPos2D getCenterBlockPos(long pos) { return new DhBlockPos2D(getCenterBlockPosX(pos), getCenterBlockPosZ(pos)); }
|
||||
|
||||
public static int getCenterBlockPosX(long pos) { return getCenterBlockPosXOrZ(true, pos); }
|
||||
public static int getCenterBlockPosZ(long pos) { return getCenterBlockPosXOrZ(false, pos); }
|
||||
private static int getCenterBlockPosXOrZ(boolean returnX, long pos)
|
||||
{
|
||||
byte detailLevel = getDetailLevel(pos);
|
||||
int x = getX(pos);
|
||||
int z = getZ(pos);
|
||||
|
||||
|
||||
int centerBlockPos = returnX ? x : z;
|
||||
|
||||
if (detailLevel == 0)
|
||||
{
|
||||
// already at block detail level, no conversion necessary
|
||||
return centerBlockPos;
|
||||
}
|
||||
|
||||
// we can't get the center of the position at block level, only attempt to get the position offset for detail levels above 0
|
||||
int positionOffset = 0;
|
||||
if (detailLevel != 1)
|
||||
{
|
||||
positionOffset = BitShiftUtil.powerOfTwo(detailLevel - 1);
|
||||
}
|
||||
|
||||
return (centerBlockPos * BitShiftUtil.powerOfTwo(detailLevel)) + positionOffset;
|
||||
}
|
||||
|
||||
public static int getManhattanBlockDistance(DhBlockPos2D blockPos, long pos)
|
||||
{
|
||||
return Math.abs(getCenterBlockPosX(pos) - blockPos.x)
|
||||
+ Math.abs(getCenterBlockPosZ(pos) - blockPos.z);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==================//
|
||||
// parent child pos //
|
||||
//==================//
|
||||
|
||||
/**
|
||||
* Returns a position 1 detail level lower. <br><br>
|
||||
*
|
||||
* Relative child positions returned for each index: <br>
|
||||
* 0 = (0,0) - North West <br>
|
||||
* 1 = (1,0) - South West <br>
|
||||
* 2 = (0,1) - North East <br>
|
||||
* 3 = (1,1) - South East <br>
|
||||
*
|
||||
* @param child0to3 must be an int between 0 and 3
|
||||
*/
|
||||
public static long getChildByIndex(int child0to3, long pos) throws IllegalArgumentException, IllegalStateException
|
||||
{
|
||||
byte detailLevel = getDetailLevel(pos);
|
||||
int x = getX(pos);
|
||||
int z = getZ(pos);
|
||||
|
||||
if (child0to3 < 0 || child0to3 > 3)
|
||||
{
|
||||
throw new IllegalArgumentException("child0to3 must be between 0 and 3");
|
||||
}
|
||||
if (detailLevel <= 0)
|
||||
{
|
||||
throw new IllegalStateException("section detail must be greater than 0");
|
||||
}
|
||||
|
||||
return DhSectionPos.encode((byte) (detailLevel - 1),
|
||||
x * 2 + (child0to3 & 1),
|
||||
z * 2 + BitShiftUtil.half(child0to3 & 2));
|
||||
}
|
||||
/** Returns this position's child index in its parent */
|
||||
public static int getChildIndexOfParent(long pos) { return (getX(pos) & 1) + BitShiftUtil.square(getZ(pos) & 1); }
|
||||
|
||||
public static long getParentPos(long pos) { return DhSectionPos.encode((byte) (getDetailLevel(pos) + 1), BitShiftUtil.half(getX(pos)), BitShiftUtil.half(getZ(pos))); }
|
||||
|
||||
|
||||
|
||||
public static long getAdjacentPos(EDhDirection dir, long pos) throws IllegalArgumentException
|
||||
{
|
||||
if (dir == EDhDirection.UP || dir == EDhDirection.DOWN)
|
||||
{
|
||||
throw new IllegalArgumentException("getAdjacentPos can't be UP or DOWN, direction given: ["+dir.name()+"].");
|
||||
}
|
||||
|
||||
return DhSectionPos.encode(getDetailLevel(pos),
|
||||
getX(pos) + dir.getNormal().x,
|
||||
getZ(pos) + dir.getNormal().z);
|
||||
}
|
||||
|
||||
//public DhLodPos getSectionBBoxPos() { return new DhLodPos(this.detailLevel, this.x, this.z); }
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// comparisons //
|
||||
//=============//
|
||||
|
||||
public static boolean contains(long aPos, long bPos)
|
||||
{
|
||||
int aMinX = getMinCornerBlockX(aPos);
|
||||
int aMinZ = getMinCornerBlockZ(aPos);
|
||||
|
||||
int bMinX = getMinCornerBlockX(bPos);
|
||||
int bMinZ = getMinCornerBlockZ(bPos);
|
||||
|
||||
int aBlockWidth = getBlockWidth(aPos) - 1; // minus 1 to account for zero based positional indexing
|
||||
int aMaxX = aMinX + aBlockWidth;
|
||||
int aMaxZ = aMinZ + aBlockWidth;
|
||||
|
||||
return aMinX <= bMinX && bMinX <= aMaxX &&
|
||||
aMinZ <= bMinZ && bMinZ <= aMaxZ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===========//
|
||||
// iterators //
|
||||
//===========//
|
||||
|
||||
/** Applies the given consumer to all 4 of this position's children. */
|
||||
public static void forEachChild(IPrimitiveLongConsumer callback, long pos) throws IllegalArgumentException, IllegalStateException
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
callback.accept(getChildByIndex(i, pos));
|
||||
}
|
||||
}
|
||||
|
||||
/** Applies the given consumer to all children of the position at the given section detail level. */
|
||||
public static void forEachChildDownToDetailLevel(byte minSectionDetailLevel, ICancelablePrimitiveLongConsumer callback, long pos) throws IllegalArgumentException, IllegalStateException
|
||||
{
|
||||
boolean stop = callback.accept(pos);
|
||||
if (stop || minSectionDetailLevel == getDetailLevel(pos))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
forEachChildDownToDetailLevel(minSectionDetailLevel, callback, getChildByIndex(i, pos));
|
||||
}
|
||||
}
|
||||
|
||||
/** Applies the given consumer to all children of the position at the given section detail level. */
|
||||
public static void forEachChildAtDetailLevel(byte sectionDetailLevel, IPrimitiveLongConsumer callback, long pos) throws IllegalArgumentException, IllegalStateException
|
||||
{
|
||||
if (sectionDetailLevel == getDetailLevel(pos))
|
||||
{
|
||||
callback.accept(pos);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
forEachChildAtDetailLevel(sectionDetailLevel, callback, getChildByIndex(i, pos));
|
||||
}
|
||||
}
|
||||
|
||||
/** Applies the given consumer to all children of the position at the given section detail level. */
|
||||
public static void forEachPosUpToDetailLevel(byte maxSectionDetailLevel, IPrimitiveLongConsumer callback, long pos)
|
||||
{
|
||||
callback.accept(pos);
|
||||
if (maxSectionDetailLevel == getDetailLevel(pos))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
forEachPosUpToDetailLevel(maxSectionDetailLevel, callback, getParentPos(pos));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// Base methods //
|
||||
//==============//
|
||||
|
||||
public static String toString(long pos) { return getDetailLevel(pos) + "*" + getX(pos) + "," + getZ(pos); }
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// helper methods //
|
||||
//================//
|
||||
|
||||
/** Used instead of {@link java.util.function.Consumer} to prevent unnecessary (un)wrapping. */
|
||||
@FunctionalInterface
|
||||
public interface IPrimitiveLongConsumer
|
||||
{
|
||||
void accept(long value);
|
||||
}
|
||||
|
||||
/** Used instead of {@link java.util.function.Function} to prevent unnecessary (un)wrapping. */
|
||||
@FunctionalInterface
|
||||
public interface ICancelablePrimitiveLongConsumer
|
||||
{
|
||||
/** @return true if this method should cancel further consumers. */
|
||||
boolean accept(long value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,99 +19,134 @@
|
||||
|
||||
package tests;
|
||||
|
||||
import com.seibel.distanthorizons.core.pos.*;
|
||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||
import com.seibel.distanthorizons.core.pos.DhBlockPos2D;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class DhSectionPosTest
|
||||
{
|
||||
|
||||
@Test
|
||||
public void ContainsPosTest()
|
||||
public void basicEncodeDecodeTest()
|
||||
{
|
||||
OldDhSectionPos root = new OldDhSectionPos((byte) 10, 0, 0);
|
||||
OldDhSectionPos child = new OldDhSectionPos((byte) 9, 1, 1);
|
||||
long pos;
|
||||
|
||||
Assert.assertTrue("section pos contains fail", root.contains(child));
|
||||
Assert.assertFalse("section pos contains fail", child.contains(root));
|
||||
// zero pos
|
||||
pos = DhSectionPos.encode((byte) 0, 0, 0);
|
||||
assertSectionPosEqual(0, DhSectionPos.getDetailLevel(pos));
|
||||
assertSectionPosEqual(0, DhSectionPos.getX(pos));
|
||||
assertSectionPosEqual(0, DhSectionPos.getZ(pos));
|
||||
|
||||
// positive values
|
||||
pos = DhSectionPos.encode((byte) 10, 4, 1);
|
||||
assertSectionPosEqual(10, DhSectionPos.getDetailLevel(pos));
|
||||
assertSectionPosEqual(4, DhSectionPos.getX(pos));
|
||||
assertSectionPosEqual(1, DhSectionPos.getZ(pos));
|
||||
|
||||
// negative position, positive detail level
|
||||
pos = DhSectionPos.encode((byte) 2, -1, -4);
|
||||
assertSectionPosEqual(2, DhSectionPos.getDetailLevel(pos));
|
||||
assertSectionPosEqual(-1, DhSectionPos.getX(pos));
|
||||
assertSectionPosEqual(-4, DhSectionPos.getZ(pos));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void containsPosTest()
|
||||
{
|
||||
long root = DhSectionPos.encode((byte) 10, 0, 0);
|
||||
long child = DhSectionPos.encode((byte) 9, 1, 1);
|
||||
|
||||
Assert.assertTrue("section pos contains fail", DhSectionPos.contains(root, child));
|
||||
Assert.assertFalse("section pos contains fail", DhSectionPos.contains(child, root));
|
||||
|
||||
|
||||
root = new OldDhSectionPos((byte) 10, 1, 0);
|
||||
root = DhSectionPos.encode((byte) 10, 1, 0);
|
||||
|
||||
// out of bounds
|
||||
child = new OldDhSectionPos((byte) 9, 0, 0);
|
||||
Assert.assertFalse("position should be out of bounds", root.contains(child));
|
||||
child = new OldDhSectionPos((byte) 9, 1, 1);
|
||||
Assert.assertFalse("position should be out of bounds", root.contains(child));
|
||||
child = DhSectionPos.encode((byte) 9, 0, 0);
|
||||
Assert.assertFalse("position should be out of bounds", DhSectionPos.contains(root, child));
|
||||
child = DhSectionPos.encode((byte) 9, 1, 1);
|
||||
Assert.assertFalse("position should be out of bounds", DhSectionPos.contains(root, child));
|
||||
|
||||
// in bounds
|
||||
child = new OldDhSectionPos((byte) 9, 2, 0);
|
||||
Assert.assertTrue("position should be in bounds", root.contains(child));
|
||||
child = new OldDhSectionPos((byte) 9, 3, 1);
|
||||
Assert.assertTrue("position should be in bounds", root.contains(child));
|
||||
child = DhSectionPos.encode((byte) 9, 2, 0);
|
||||
Assert.assertTrue("position should be in bounds", DhSectionPos.contains(root, child));
|
||||
child = DhSectionPos.encode((byte) 9, 3, 1);
|
||||
Assert.assertTrue("position should be in bounds", DhSectionPos.contains(root, child));
|
||||
|
||||
// out of bounds
|
||||
child = new OldDhSectionPos((byte) 9, 2, 2);
|
||||
Assert.assertFalse("position should be out of bounds", root.contains(child));
|
||||
child = new OldDhSectionPos((byte) 9, 3, 3);
|
||||
Assert.assertFalse("position should be out of bounds", root.contains(child));
|
||||
child = DhSectionPos.encode((byte) 9, 2, 2);
|
||||
Assert.assertFalse("position should be out of bounds", DhSectionPos.contains(root, child));
|
||||
child = DhSectionPos.encode((byte) 9, 3, 3);
|
||||
Assert.assertFalse("position should be out of bounds", DhSectionPos.contains(root, child));
|
||||
|
||||
child = new OldDhSectionPos((byte) 9, 4, 4);
|
||||
Assert.assertFalse("position should be out of bounds", root.contains(child));
|
||||
child = new OldDhSectionPos((byte) 9, 5, 5);
|
||||
Assert.assertFalse("position should be out of bounds", root.contains(child));
|
||||
child = DhSectionPos.encode((byte) 9, 4, 4);
|
||||
Assert.assertFalse("position should be out of bounds", DhSectionPos.contains(root, child));
|
||||
child = DhSectionPos.encode((byte) 9, 5, 5);
|
||||
Assert.assertFalse("position should be out of bounds", DhSectionPos.contains(root, child));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ContainsAdjacentPosTest()
|
||||
public void containsAdjacentPosTest()
|
||||
{
|
||||
// neither should contain the other, they are single blocks that are next to each other
|
||||
OldDhSectionPos left = new OldDhSectionPos((byte) 0, 4606, 0);
|
||||
OldDhSectionPos right = new OldDhSectionPos((byte) 0, 4607, 0);
|
||||
Assert.assertFalse(left.contains(right));
|
||||
Assert.assertFalse(right.contains(left));
|
||||
|
||||
|
||||
long left = DhSectionPos.encode((byte) 0, 4606, 0);
|
||||
long right = DhSectionPos.encode((byte) 0, 4607, 0);
|
||||
Assert.assertFalse(DhSectionPos.contains(left, right));
|
||||
Assert.assertFalse(DhSectionPos.contains(right, left));
|
||||
|
||||
|
||||
// 512 block wide sections that are adjacent, but not overlapping
|
||||
left = new OldDhSectionPos((byte) 9, 0, 0);
|
||||
right = new OldDhSectionPos((byte) 9, 1, 0);
|
||||
Assert.assertFalse(left.contains(right));
|
||||
Assert.assertFalse(right.contains(left));
|
||||
|
||||
left = DhSectionPos.encode((byte) 9, 0, 0);
|
||||
right = DhSectionPos.encode((byte) 9, 1, 0);
|
||||
Assert.assertFalse(DhSectionPos.contains(left, right));
|
||||
Assert.assertFalse(DhSectionPos.contains(right, left));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ParentPosTest()
|
||||
public void parentPosTest()
|
||||
{
|
||||
OldDhSectionPos leaf = new OldDhSectionPos((byte) 0, 0, 0);
|
||||
OldDhSectionPos convert = leaf.convertNewToDetailLevel((byte) 1);
|
||||
OldDhSectionPos parent = leaf.getParentPos();
|
||||
Assert.assertEquals("get parent at 0,0 fail", convert, parent);
|
||||
|
||||
|
||||
leaf = new OldDhSectionPos((byte) 0, 1, 1);
|
||||
convert = leaf.convertNewToDetailLevel((byte) 1);
|
||||
parent = leaf.getParentPos();
|
||||
Assert.assertEquals("get parent at 1,1 fail", convert, parent);
|
||||
|
||||
|
||||
leaf = new OldDhSectionPos((byte) 1, 2, 2);
|
||||
convert = leaf.convertNewToDetailLevel((byte) 2);
|
||||
parent = leaf.getParentPos();
|
||||
Assert.assertEquals("parent upscale fail", convert, parent);
|
||||
convert = leaf.convertNewToDetailLevel((byte) 0);
|
||||
OldDhSectionPos childIndex = leaf.getChildByIndex(0);
|
||||
Assert.assertEquals("child detail fail", convert, childIndex);
|
||||
|
||||
long leaf = DhSectionPos.encode((byte) 0, 0, 0);
|
||||
long convert = DhSectionPos.convertToDetailLevel((byte) 1, leaf);
|
||||
long parent = DhSectionPos.getParentPos(leaf);
|
||||
assertSectionPosEqual("get parent at 0,0 fail", convert, parent);
|
||||
|
||||
|
||||
leaf = DhSectionPos.encode((byte) 0, 1, 1);
|
||||
convert = DhSectionPos.convertToDetailLevel((byte) 1, leaf);
|
||||
parent = DhSectionPos.getParentPos(leaf);
|
||||
assertSectionPosEqual("get parent at 1,1 fail", convert, parent);
|
||||
|
||||
|
||||
leaf = DhSectionPos.encode((byte) 1, 2, 2);
|
||||
convert = DhSectionPos.convertToDetailLevel((byte) 2, leaf);
|
||||
parent = DhSectionPos.getParentPos(leaf);
|
||||
assertSectionPosEqual("parent upscale fail", convert, parent);
|
||||
convert = DhSectionPos.convertToDetailLevel((byte) 0, leaf);
|
||||
long childIndex = DhSectionPos.getChildByIndex(0, leaf);
|
||||
assertSectionPosEqual("child detail fail", convert, childIndex);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ChildPosTest()
|
||||
public void childPosTest()
|
||||
{
|
||||
OldDhSectionPos node = new OldDhSectionPos((byte) 1, 2302, 0);
|
||||
OldDhSectionPos nw = node.getChildByIndex(0);
|
||||
OldDhSectionPos sw = node.getChildByIndex(1);
|
||||
OldDhSectionPos ne = node.getChildByIndex(2);
|
||||
OldDhSectionPos se = node.getChildByIndex(3);
|
||||
long node = DhSectionPos.encode((byte) 1, 2302, 0);
|
||||
long nw = DhSectionPos.getChildByIndex(0, node);
|
||||
long sw = DhSectionPos.getChildByIndex(1, node);
|
||||
long ne = DhSectionPos.getChildByIndex(2, node);
|
||||
long se = DhSectionPos.getChildByIndex(3, node);
|
||||
|
||||
// confirm no children have the same values
|
||||
Assert.assertNotEquals(nw, sw);
|
||||
@@ -119,244 +154,340 @@ public class DhSectionPosTest
|
||||
Assert.assertNotEquals(ne, se);
|
||||
|
||||
// confirm each child has the correct value
|
||||
Assert.assertEquals(nw, new OldDhSectionPos((byte) 0, 4604, 0));
|
||||
Assert.assertEquals(sw, new OldDhSectionPos((byte) 0, 4605, 0));
|
||||
Assert.assertEquals(ne, new OldDhSectionPos((byte) 0, 4604, 1));
|
||||
Assert.assertEquals(se, new OldDhSectionPos((byte) 0, 4605, 1));
|
||||
assertSectionPosEqual(nw, DhSectionPos.encode((byte) 0, 4604, 0));
|
||||
assertSectionPosEqual(sw, DhSectionPos.encode((byte) 0, 4605, 0));
|
||||
assertSectionPosEqual(ne, DhSectionPos.encode((byte) 0, 4604, 1));
|
||||
assertSectionPosEqual(se, DhSectionPos.encode((byte) 0, 4605, 1));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void GetCenterTest()
|
||||
public void getCenterBlockTest()
|
||||
{
|
||||
OldDhSectionPos node = new OldDhSectionPos((byte) 1, 2303, 0);
|
||||
DhBlockPos2D centerBlockPos = node.getCenterBlockPos();
|
||||
long node = DhSectionPos.encode((byte) 1, 2303, 0);
|
||||
DhBlockPos2D centerBlockPos = DhSectionPos.getCenterBlockPos(node);
|
||||
DhBlockPos2D expectedCenterNode = new DhBlockPos2D(4606, 0);
|
||||
Assert.assertEquals("", expectedCenterNode, centerBlockPos);
|
||||
|
||||
|
||||
|
||||
node = new OldDhSectionPos((byte) 10, 0, 0); // 1024 blocks wide
|
||||
centerBlockPos = node.getCenterBlockPos();
|
||||
Assert.assertEquals(expectedCenterNode, centerBlockPos);
|
||||
|
||||
|
||||
|
||||
node = DhSectionPos.encode((byte) 10, 0, 0); // 1024 blocks wide
|
||||
centerBlockPos = DhSectionPos.getCenterBlockPos(node);
|
||||
expectedCenterNode = new DhBlockPos2D(1024 / 2, 1024 / 2);
|
||||
Assert.assertEquals("", expectedCenterNode, centerBlockPos);
|
||||
Assert.assertEquals(expectedCenterNode, centerBlockPos);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void GetCenter2Test()
|
||||
public void getCenterBlock2DTest()
|
||||
{
|
||||
OldDhSectionPos parentNode = new OldDhSectionPos((byte) 2, 1151, 0); // width 4 blocks
|
||||
OldDhSectionPos inputPos = new OldDhSectionPos((byte) 0, 4606, 0); // width 1 block
|
||||
Assert.assertTrue(parentNode.contains(inputPos));
|
||||
|
||||
DhBlockPos2D parentCenter = parentNode.getCenterBlockPos();
|
||||
DhBlockPos2D inputCenter = inputPos.getCenterBlockPos();
|
||||
long parentNode = DhSectionPos.encode((byte) 2, 1151, 0); // width 4 blocks
|
||||
long inputPos = DhSectionPos.encode((byte) 0, 4606, 0); // width 1 block
|
||||
Assert.assertTrue(DhSectionPos.contains(parentNode, inputPos));
|
||||
|
||||
DhBlockPos2D parentCenter = DhSectionPos.getCenterBlockPos(parentNode);
|
||||
DhBlockPos2D inputCenter = DhSectionPos.getCenterBlockPos(inputPos);
|
||||
|
||||
Assert.assertEquals(new DhBlockPos2D(4606, 2), parentCenter);
|
||||
Assert.assertEquals(new DhBlockPos2D(4606, 0), inputCenter);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void CreateFromBlockPos()
|
||||
public void createFromBlockPos()
|
||||
{
|
||||
// origin pos //
|
||||
|
||||
DhBlockPos originBlockPos = new DhBlockPos(0, 0, 0);
|
||||
OldDhSectionPos originSectionPos = new OldDhSectionPos(originBlockPos);
|
||||
Assert.assertEquals(new OldDhSectionPos(OldDhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, 0, 0), originSectionPos);
|
||||
long originsectionPos = DhSectionPos.encode(originBlockPos);
|
||||
assertSectionPosEqual(DhSectionPos.encode(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, 0, 0), originsectionPos);
|
||||
|
||||
|
||||
// offset pos //
|
||||
long offsetSectionPos;
|
||||
|
||||
DhBlockPos offsetBlockPos = new DhBlockPos(1000, 0, 42000);
|
||||
OldDhSectionPos offsetSectionPos = new OldDhSectionPos(offsetBlockPos);
|
||||
Assert.assertEquals(new OldDhSectionPos(OldDhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, 15, 656), offsetSectionPos);
|
||||
offsetSectionPos = DhSectionPos.encode(offsetBlockPos);
|
||||
assertSectionPosEqual(DhSectionPos.encode(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, 15, 656), offsetSectionPos);
|
||||
|
||||
offsetBlockPos = new DhBlockPos(-987654, 0, 46);
|
||||
offsetSectionPos = new OldDhSectionPos(offsetBlockPos);
|
||||
Assert.assertEquals(new OldDhSectionPos(OldDhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, -15433, 0), offsetSectionPos);
|
||||
offsetSectionPos = DhSectionPos.encode(offsetBlockPos);
|
||||
assertSectionPosEqual(DhSectionPos.encode(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, -15433, 0), offsetSectionPos);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void CreateFromBlockPos2D()
|
||||
public void createFromBlockPos2D()
|
||||
{
|
||||
// origin pos //
|
||||
|
||||
DhBlockPos2D originBlockPos = new DhBlockPos2D(0, 0);
|
||||
OldDhSectionPos originSectionPos = new OldDhSectionPos(originBlockPos);
|
||||
Assert.assertEquals(new OldDhSectionPos(OldDhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, 0, 0), originSectionPos);
|
||||
long originSectionPos = DhSectionPos.encode(originBlockPos);
|
||||
assertSectionPosEqual(DhSectionPos.encode(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, 0, 0), originSectionPos);
|
||||
|
||||
|
||||
// offset pos //
|
||||
|
||||
DhBlockPos2D offsetBlockPos = new DhBlockPos2D(1000, 42000);
|
||||
OldDhSectionPos offsetSectionPos = new OldDhSectionPos(offsetBlockPos);
|
||||
Assert.assertEquals(new OldDhSectionPos(OldDhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, 15, 656), offsetSectionPos);
|
||||
long offsetSectionPos = DhSectionPos.encode(offsetBlockPos);
|
||||
assertSectionPosEqual(DhSectionPos.encode(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, 15, 656), offsetSectionPos);
|
||||
|
||||
offsetBlockPos = new DhBlockPos2D(-987654, 46);
|
||||
offsetSectionPos = new OldDhSectionPos(offsetBlockPos);
|
||||
Assert.assertEquals(new OldDhSectionPos(OldDhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, -15433, 0), offsetSectionPos);
|
||||
offsetSectionPos = DhSectionPos.encode(offsetBlockPos);
|
||||
assertSectionPosEqual(DhSectionPos.encode(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, -15433, 0), offsetSectionPos);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void CreateFromChunkPos()
|
||||
public void createFromChunkPos()
|
||||
{
|
||||
// origin pos //
|
||||
|
||||
DhChunkPos originChunkPos = new DhChunkPos(0,0);
|
||||
OldDhSectionPos originSectionPos = new OldDhSectionPos(originChunkPos);
|
||||
Assert.assertEquals(new OldDhSectionPos(OldDhSectionPos.SECTION_CHUNK_DETAIL_LEVEL, 0, 0), originSectionPos);
|
||||
long originSectionPos = DhSectionPos.encode(originChunkPos);
|
||||
assertSectionPosEqual(DhSectionPos.encode(DhSectionPos.SECTION_CHUNK_DETAIL_LEVEL, 0, 0), originSectionPos);
|
||||
|
||||
|
||||
// offset pos //
|
||||
|
||||
DhChunkPos offsetChunkPos = new DhChunkPos(1000, 42000);
|
||||
OldDhSectionPos offsetSectionPos = new OldDhSectionPos(offsetChunkPos);
|
||||
Assert.assertEquals(new OldDhSectionPos(OldDhSectionPos.SECTION_CHUNK_DETAIL_LEVEL, 15, 656), offsetSectionPos);
|
||||
long offsetSectionPos = DhSectionPos.encode(offsetChunkPos);
|
||||
assertSectionPosEqual(DhSectionPos.encode(DhSectionPos.SECTION_CHUNK_DETAIL_LEVEL, 15, 656), offsetSectionPos);
|
||||
|
||||
offsetChunkPos = new DhChunkPos(-987654, 46);
|
||||
offsetSectionPos = new OldDhSectionPos(offsetChunkPos);
|
||||
Assert.assertEquals(new OldDhSectionPos(OldDhSectionPos.SECTION_CHUNK_DETAIL_LEVEL, -15433, 0), offsetSectionPos);
|
||||
offsetSectionPos = DhSectionPos.encode(offsetChunkPos);
|
||||
assertSectionPosEqual(DhSectionPos.encode(DhSectionPos.SECTION_CHUNK_DETAIL_LEVEL, -15433, 0), offsetSectionPos);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ConvertToDetailLevel()
|
||||
public void convertToDetailLevel()
|
||||
{
|
||||
// origin pos //
|
||||
|
||||
OldDhSectionPos originSectionPos = new OldDhSectionPos((byte) 0,0,0);
|
||||
long originSectionPos = DhSectionPos.encode((byte) 0,0,0);
|
||||
|
||||
originSectionPos = originSectionPos.convertNewToDetailLevel((byte) 1);
|
||||
Assert.assertEquals(new OldDhSectionPos((byte) 1, 0, 0), originSectionPos);
|
||||
originSectionPos = DhSectionPos.convertToDetailLevel((byte) 1, originSectionPos);
|
||||
assertSectionPosEqual(DhSectionPos.encode((byte) 1, 0, 0), originSectionPos);
|
||||
|
||||
originSectionPos = originSectionPos.convertNewToDetailLevel(OldDhSectionPos.SECTION_BLOCK_DETAIL_LEVEL);
|
||||
Assert.assertEquals(new OldDhSectionPos(OldDhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, 0, 0), originSectionPos);
|
||||
originSectionPos = DhSectionPos.convertToDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, originSectionPos);
|
||||
assertSectionPosEqual(DhSectionPos.encode(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, 0, 0), originSectionPos);
|
||||
|
||||
originSectionPos = originSectionPos.convertNewToDetailLevel(OldDhSectionPos.SECTION_REGION_DETAIL_LEVEL);
|
||||
Assert.assertEquals(new OldDhSectionPos(OldDhSectionPos.SECTION_REGION_DETAIL_LEVEL, 0, 0), originSectionPos);
|
||||
originSectionPos = DhSectionPos.convertToDetailLevel(DhSectionPos.SECTION_REGION_DETAIL_LEVEL, originSectionPos);
|
||||
assertSectionPosEqual(DhSectionPos.encode(DhSectionPos.SECTION_REGION_DETAIL_LEVEL, 0, 0), originSectionPos);
|
||||
|
||||
|
||||
// offset pos //
|
||||
|
||||
OldDhSectionPos sectionPos = new OldDhSectionPos((byte) 0,-10000,5000);
|
||||
long offsetSectionPos = DhSectionPos.encode((byte) 0,-10000,5000);
|
||||
|
||||
sectionPos = sectionPos.convertNewToDetailLevel((byte) 1);
|
||||
Assert.assertEquals(new OldDhSectionPos((byte) 1, -5000, 2500), sectionPos);
|
||||
offsetSectionPos = DhSectionPos.convertToDetailLevel((byte) 1, offsetSectionPos);
|
||||
assertSectionPosEqual(DhSectionPos.encode((byte) 1, -5000, 2500), offsetSectionPos);
|
||||
|
||||
sectionPos = sectionPos.convertNewToDetailLevel(OldDhSectionPos.SECTION_BLOCK_DETAIL_LEVEL);
|
||||
Assert.assertEquals(new OldDhSectionPos(OldDhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, -157, 78), sectionPos);
|
||||
offsetSectionPos = DhSectionPos.convertToDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, offsetSectionPos);
|
||||
assertSectionPosEqual(DhSectionPos.encode(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, -157, 78), offsetSectionPos);
|
||||
|
||||
sectionPos = sectionPos.convertNewToDetailLevel(OldDhSectionPos.SECTION_REGION_DETAIL_LEVEL);
|
||||
Assert.assertEquals(new OldDhSectionPos(OldDhSectionPos.SECTION_REGION_DETAIL_LEVEL, -1, 0), sectionPos);
|
||||
offsetSectionPos = DhSectionPos.convertToDetailLevel(DhSectionPos.SECTION_REGION_DETAIL_LEVEL, offsetSectionPos);
|
||||
assertSectionPosEqual(DhSectionPos.encode(DhSectionPos.SECTION_REGION_DETAIL_LEVEL, -1, 0), offsetSectionPos);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void GetOffsetWidth()
|
||||
public void getOffsetWidth()
|
||||
{
|
||||
OldDhSectionPos originSectionPos = new OldDhSectionPos((byte) 0,0,0);
|
||||
OldDhSectionPos sectionPos = new OldDhSectionPos((byte) 0,-10000,5000);
|
||||
long originSectionPos = DhSectionPos.encode((byte) 0,0,0);
|
||||
long sectionPos = DhSectionPos.encode((byte) 0,-10000,5000);
|
||||
|
||||
|
||||
|
||||
// 1 -> 0
|
||||
byte returnDetailLevel = 0;
|
||||
originSectionPos = originSectionPos.convertNewToDetailLevel((byte) 1);
|
||||
Assert.assertEquals(2, originSectionPos.getWidthCountForLowerDetailedSection(returnDetailLevel));
|
||||
originSectionPos = DhSectionPos.convertToDetailLevel((byte) 1, originSectionPos);
|
||||
assertSectionPosEqual(2, DhSectionPos.getWidthCountForLowerDetailedSection(returnDetailLevel, originSectionPos));
|
||||
|
||||
sectionPos = sectionPos.convertNewToDetailLevel((byte) 1);
|
||||
Assert.assertEquals(2, sectionPos.getWidthCountForLowerDetailedSection(returnDetailLevel));
|
||||
sectionPos = DhSectionPos.convertToDetailLevel((byte) 1, sectionPos);
|
||||
assertSectionPosEqual(2, DhSectionPos.getWidthCountForLowerDetailedSection(returnDetailLevel, sectionPos));
|
||||
|
||||
|
||||
// 2 -> 1
|
||||
returnDetailLevel = 1;
|
||||
originSectionPos = originSectionPos.convertNewToDetailLevel((byte) 2);
|
||||
Assert.assertEquals(2, originSectionPos.getWidthCountForLowerDetailedSection(returnDetailLevel));
|
||||
originSectionPos = DhSectionPos.convertToDetailLevel((byte) 2, originSectionPos);
|
||||
assertSectionPosEqual(2, DhSectionPos.getWidthCountForLowerDetailedSection(returnDetailLevel, originSectionPos));
|
||||
|
||||
sectionPos = sectionPos.convertNewToDetailLevel((byte) 2);
|
||||
Assert.assertEquals(2, sectionPos.getWidthCountForLowerDetailedSection(returnDetailLevel));
|
||||
sectionPos = DhSectionPos.convertToDetailLevel((byte) 2, sectionPos);
|
||||
assertSectionPosEqual(2, DhSectionPos.getWidthCountForLowerDetailedSection(returnDetailLevel, sectionPos));
|
||||
|
||||
|
||||
// Block -> 0
|
||||
returnDetailLevel = 0;
|
||||
originSectionPos = originSectionPos.convertNewToDetailLevel(OldDhSectionPos.SECTION_BLOCK_DETAIL_LEVEL);
|
||||
Assert.assertEquals(64, originSectionPos.getWidthCountForLowerDetailedSection(returnDetailLevel));
|
||||
originSectionPos = DhSectionPos.convertToDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, originSectionPos);
|
||||
assertSectionPosEqual(64, DhSectionPos.getWidthCountForLowerDetailedSection(returnDetailLevel, originSectionPos));
|
||||
|
||||
sectionPos = sectionPos.convertNewToDetailLevel(OldDhSectionPos.SECTION_BLOCK_DETAIL_LEVEL);
|
||||
Assert.assertEquals(64, sectionPos.getWidthCountForLowerDetailedSection(returnDetailLevel));
|
||||
sectionPos = DhSectionPos.convertToDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, sectionPos);
|
||||
assertSectionPosEqual(64, DhSectionPos.getWidthCountForLowerDetailedSection(returnDetailLevel, sectionPos));
|
||||
|
||||
|
||||
// Region -> 3
|
||||
returnDetailLevel = 3;
|
||||
originSectionPos = originSectionPos.convertNewToDetailLevel(OldDhSectionPos.SECTION_REGION_DETAIL_LEVEL);
|
||||
Assert.assertEquals(4096, originSectionPos.getWidthCountForLowerDetailedSection(returnDetailLevel));
|
||||
originSectionPos = DhSectionPos.convertToDetailLevel(DhSectionPos.SECTION_REGION_DETAIL_LEVEL, originSectionPos);
|
||||
assertSectionPosEqual(4096, DhSectionPos.getWidthCountForLowerDetailedSection(returnDetailLevel, originSectionPos));
|
||||
|
||||
sectionPos = sectionPos.convertNewToDetailLevel(OldDhSectionPos.SECTION_REGION_DETAIL_LEVEL);
|
||||
Assert.assertEquals(4096, sectionPos.getWidthCountForLowerDetailedSection(returnDetailLevel));
|
||||
sectionPos = DhSectionPos.convertToDetailLevel(DhSectionPos.SECTION_REGION_DETAIL_LEVEL, sectionPos);
|
||||
assertSectionPosEqual(4096, DhSectionPos.getWidthCountForLowerDetailedSection(returnDetailLevel, sectionPos));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void GetBlockWidth()
|
||||
public void getBlockWidth()
|
||||
{
|
||||
OldDhSectionPos originSectionPos = new OldDhSectionPos((byte) 0,0,0);
|
||||
OldDhSectionPos sectionPos = new OldDhSectionPos((byte) 0,-10000,5000);
|
||||
long originSectionPos = DhSectionPos.encode((byte) 0,0,0);
|
||||
long sectionPos = DhSectionPos.encode((byte) 0,-10000,5000);
|
||||
|
||||
|
||||
Assert.assertEquals(1, originSectionPos.getBlockWidth());
|
||||
Assert.assertEquals(1, sectionPos.getBlockWidth());
|
||||
assertSectionPosEqual(1, DhSectionPos.getBlockWidth(originSectionPos));
|
||||
assertSectionPosEqual(1, DhSectionPos.getBlockWidth(sectionPos));
|
||||
|
||||
originSectionPos = originSectionPos.convertNewToDetailLevel((byte) 1);
|
||||
Assert.assertEquals(2, originSectionPos.getBlockWidth());
|
||||
sectionPos = sectionPos.convertNewToDetailLevel((byte) 1);
|
||||
Assert.assertEquals(2, sectionPos.getBlockWidth());
|
||||
originSectionPos = DhSectionPos.convertToDetailLevel((byte) 1, originSectionPos);
|
||||
assertSectionPosEqual(2, DhSectionPos.getBlockWidth(originSectionPos));
|
||||
sectionPos = DhSectionPos.convertToDetailLevel((byte) 1, sectionPos);
|
||||
assertSectionPosEqual(2, DhSectionPos.getBlockWidth(sectionPos));
|
||||
|
||||
originSectionPos = originSectionPos.convertNewToDetailLevel(OldDhSectionPos.SECTION_BLOCK_DETAIL_LEVEL);
|
||||
Assert.assertEquals(64, originSectionPos.getBlockWidth());
|
||||
sectionPos = sectionPos.convertNewToDetailLevel(OldDhSectionPos.SECTION_BLOCK_DETAIL_LEVEL);
|
||||
Assert.assertEquals(64, sectionPos.getBlockWidth());
|
||||
originSectionPos = DhSectionPos.convertToDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, originSectionPos);
|
||||
assertSectionPosEqual(64, DhSectionPos.getBlockWidth(originSectionPos));
|
||||
sectionPos = DhSectionPos.convertToDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, sectionPos);
|
||||
assertSectionPosEqual(64, DhSectionPos.getBlockWidth(sectionPos));
|
||||
|
||||
originSectionPos = originSectionPos.convertNewToDetailLevel(OldDhSectionPos.SECTION_REGION_DETAIL_LEVEL);
|
||||
Assert.assertEquals(32768, originSectionPos.getBlockWidth());
|
||||
sectionPos = sectionPos.convertNewToDetailLevel(OldDhSectionPos.SECTION_REGION_DETAIL_LEVEL);
|
||||
Assert.assertEquals(32768, sectionPos.getBlockWidth());
|
||||
originSectionPos = DhSectionPos.convertToDetailLevel(DhSectionPos.SECTION_REGION_DETAIL_LEVEL, originSectionPos);
|
||||
assertSectionPosEqual(32768, DhSectionPos.getBlockWidth(originSectionPos));
|
||||
sectionPos = DhSectionPos.convertToDetailLevel(DhSectionPos.SECTION_REGION_DETAIL_LEVEL, sectionPos);
|
||||
assertSectionPosEqual(32768, DhSectionPos.getBlockWidth(sectionPos));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void GetCenterBlockPos()
|
||||
public void getCenterBlockPos()
|
||||
{
|
||||
OldDhSectionPos originSectionPos = new OldDhSectionPos((byte) 0,0,0);
|
||||
OldDhSectionPos sectionPos = new OldDhSectionPos((byte) 0,-10000,5000);
|
||||
long originSectionPos = DhSectionPos.encode((byte) 0,0,0);
|
||||
long sectionPos = DhSectionPos.encode((byte) 0,-10000,5000);
|
||||
|
||||
|
||||
Assert.assertEquals(new DhBlockPos2D(0, 0), originSectionPos.getCenterBlockPos());
|
||||
Assert.assertEquals(new DhBlockPos2D(-10000, 5000), sectionPos.getCenterBlockPos());
|
||||
Assert.assertEquals(new DhBlockPos2D(0, 0), DhSectionPos.getCenterBlockPos(originSectionPos));
|
||||
Assert.assertEquals(new DhBlockPos2D(-10000, 5000), DhSectionPos.getCenterBlockPos(sectionPos));
|
||||
|
||||
|
||||
originSectionPos = originSectionPos.convertNewToDetailLevel((byte) 1);
|
||||
Assert.assertEquals(new DhBlockPos2D(0, 0), originSectionPos.getCenterBlockPos());
|
||||
sectionPos = sectionPos.convertNewToDetailLevel((byte) 1);
|
||||
Assert.assertEquals(new DhBlockPos2D(-10000, 5000), sectionPos.getCenterBlockPos());
|
||||
originSectionPos = DhSectionPos.convertToDetailLevel((byte) 1, originSectionPos);
|
||||
Assert.assertEquals(new DhBlockPos2D(0, 0), DhSectionPos.getCenterBlockPos(originSectionPos));
|
||||
sectionPos = DhSectionPos.convertToDetailLevel((byte) 1, sectionPos);
|
||||
Assert.assertEquals(new DhBlockPos2D(-10000, 5000), DhSectionPos.getCenterBlockPos(sectionPos));
|
||||
|
||||
|
||||
originSectionPos = originSectionPos.convertNewToDetailLevel(OldDhSectionPos.SECTION_BLOCK_DETAIL_LEVEL);
|
||||
Assert.assertEquals(new DhBlockPos2D(32, 32), originSectionPos.getCenterBlockPos());
|
||||
sectionPos = sectionPos.convertNewToDetailLevel(OldDhSectionPos.SECTION_BLOCK_DETAIL_LEVEL);
|
||||
Assert.assertEquals(new DhBlockPos2D(-10016, 5024), sectionPos.getCenterBlockPos());
|
||||
originSectionPos = DhSectionPos.convertToDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, originSectionPos);
|
||||
Assert.assertEquals(new DhBlockPos2D(32, 32), DhSectionPos.getCenterBlockPos(originSectionPos));
|
||||
sectionPos = DhSectionPos.convertToDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, sectionPos);
|
||||
Assert.assertEquals(new DhBlockPos2D(-10016, 5024), DhSectionPos.getCenterBlockPos(sectionPos));
|
||||
|
||||
|
||||
originSectionPos = DhSectionPos.convertToDetailLevel(DhSectionPos.SECTION_REGION_DETAIL_LEVEL, originSectionPos);
|
||||
Assert.assertEquals(new DhBlockPos2D(16384, 16384), DhSectionPos.getCenterBlockPos(originSectionPos));
|
||||
sectionPos = DhSectionPos.convertToDetailLevel(DhSectionPos.SECTION_REGION_DETAIL_LEVEL, sectionPos);
|
||||
Assert.assertEquals(new DhBlockPos2D(-16384, 16384), DhSectionPos.getCenterBlockPos(sectionPos));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMinCornerBlockPos()
|
||||
{
|
||||
long pos;
|
||||
|
||||
// origin block detail
|
||||
pos = DhSectionPos.encode((byte) 0,0,0);
|
||||
Assert.assertEquals(0, DhSectionPos.getMinCornerBlockX(pos));
|
||||
Assert.assertEquals(0, DhSectionPos.getMinCornerBlockZ(pos));
|
||||
|
||||
// offset block detail
|
||||
pos = DhSectionPos.encode((byte) 0,2,3);
|
||||
Assert.assertEquals(2 * DhSectionPos.getBlockWidth(pos), DhSectionPos.getMinCornerBlockX(pos));
|
||||
Assert.assertEquals(3 * DhSectionPos.getBlockWidth(pos), DhSectionPos.getMinCornerBlockZ(pos));
|
||||
|
||||
// negative offset block detail
|
||||
pos = DhSectionPos.encode((byte) 0,-1,-2);
|
||||
Assert.assertEquals(-1 * DhSectionPos.getBlockWidth(pos), DhSectionPos.getMinCornerBlockX(pos));
|
||||
Assert.assertEquals(-2 * DhSectionPos.getBlockWidth(pos), DhSectionPos.getMinCornerBlockZ(pos));
|
||||
|
||||
|
||||
originSectionPos = originSectionPos.convertNewToDetailLevel(OldDhSectionPos.SECTION_REGION_DETAIL_LEVEL);
|
||||
Assert.assertEquals(new DhBlockPos2D(16384, 16384), originSectionPos.getCenterBlockPos());
|
||||
sectionPos = sectionPos.convertNewToDetailLevel(OldDhSectionPos.SECTION_REGION_DETAIL_LEVEL);
|
||||
Assert.assertEquals(new DhBlockPos2D(-16384, 16384), sectionPos.getCenterBlockPos());
|
||||
// origin chunk detail
|
||||
pos = DhSectionPos.encode(DhSectionPos.SECTION_CHUNK_DETAIL_LEVEL,0,0);
|
||||
Assert.assertEquals(0, DhSectionPos.getMinCornerBlockX(pos));
|
||||
Assert.assertEquals(0, DhSectionPos.getMinCornerBlockZ(pos));
|
||||
|
||||
// offset chunk detail
|
||||
pos = DhSectionPos.encode(DhSectionPos.SECTION_CHUNK_DETAIL_LEVEL,2,3);
|
||||
Assert.assertEquals(2 * DhSectionPos.getBlockWidth(pos), DhSectionPos.getMinCornerBlockX(pos));
|
||||
Assert.assertEquals(3 * DhSectionPos.getBlockWidth(pos), DhSectionPos.getMinCornerBlockZ(pos));
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAdjacentPos()
|
||||
{
|
||||
long pos = DhSectionPos.encode((byte) 0, 0, 0);
|
||||
|
||||
assertSectionPosEqual(DhSectionPos.encode((byte) 0, 0, -1), DhSectionPos.getAdjacentPos(EDhDirection.NORTH, pos));
|
||||
assertSectionPosEqual(DhSectionPos.encode((byte) 0, 0, 1), DhSectionPos.getAdjacentPos(EDhDirection.SOUTH, pos));
|
||||
|
||||
assertSectionPosEqual(DhSectionPos.encode((byte) 0, 1, 0), DhSectionPos.getAdjacentPos(EDhDirection.EAST, pos));
|
||||
assertSectionPosEqual(DhSectionPos.encode((byte) 0, -1, 0), DhSectionPos.getAdjacentPos(EDhDirection.WEST, pos));
|
||||
|
||||
// getting the adjacent position in the up and down position don't make sense
|
||||
Assert.assertThrows(IllegalArgumentException.class, () -> { DhSectionPos.getAdjacentPos(EDhDirection.UP, pos); });
|
||||
Assert.assertThrows(IllegalArgumentException.class, () -> { DhSectionPos.getAdjacentPos(EDhDirection.DOWN, pos); });
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forEachChildIterator()
|
||||
{
|
||||
long pos = DhSectionPos.encode((byte) 1, 0, 0);
|
||||
|
||||
ArrayList<Long> childPosList = new ArrayList<>();
|
||||
AtomicInteger childCount = new AtomicInteger(0);
|
||||
DhSectionPos.forEachChild((childPos) ->
|
||||
{
|
||||
childCount.incrementAndGet();
|
||||
childPosList.add(childPos);
|
||||
}, pos);
|
||||
|
||||
Assert.assertTrue(childPosList.contains(DhSectionPos.encode((byte) 0, 0, 0)));
|
||||
Assert.assertTrue(childPosList.contains(DhSectionPos.encode((byte) 0, 1, 0)));
|
||||
Assert.assertTrue(childPosList.contains(DhSectionPos.encode((byte) 0, 0, 1)));
|
||||
Assert.assertTrue(childPosList.contains(DhSectionPos.encode((byte) 0, 1, 1)));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// helper methods //
|
||||
//================//
|
||||
|
||||
public static void assertSectionPosEqual(long expected, long actual) { assertSectionPosEqual("", expected, actual); }
|
||||
public static void assertSectionPosEqual(String messagePrefix, long expected, long actual)
|
||||
{
|
||||
if (!messagePrefix.endsWith(" "))
|
||||
{
|
||||
messagePrefix += " ";
|
||||
}
|
||||
|
||||
String expectedString = DhSectionPos.toString(expected);
|
||||
String actualString = DhSectionPos.toString(actual);
|
||||
String mismatchSuffix = "expected: ["+expectedString+"] actual: ["+actualString+"].";
|
||||
|
||||
Assert.assertEquals(messagePrefix+"Detail level mismatch, "+mismatchSuffix, DhSectionPos.getDetailLevel(expected), DhSectionPos.getDetailLevel(actual));
|
||||
Assert.assertEquals(messagePrefix+"X Pos mismatch, "+mismatchSuffix, DhSectionPos.getX(expected), DhSectionPos.getX(actual));
|
||||
Assert.assertEquals(messagePrefix+"Z Pos mismatch, "+mismatchSuffix, DhSectionPos.getZ(expected), DhSectionPos.getZ(actual));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user