добавлен BlockLocationSerializer
This commit is contained in:
@@ -8,6 +8,10 @@ import lombok.*;
|
|||||||
public class BlockLocation implements Cloneable {
|
public class BlockLocation implements Cloneable {
|
||||||
private int x, y, z;
|
private int x, y, z;
|
||||||
|
|
||||||
|
public static BlockLocation ZERO() {
|
||||||
|
return new BlockLocation(0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
public void setXYZ(int x, int y, int z) {
|
public void setXYZ(int x, int y, int z) {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package mc.core.network.proto_1_12_2.serializers;
|
||||||
|
|
||||||
|
import mc.core.world.block.BlockLocation;
|
||||||
|
|
||||||
|
import static com.google.common.math.IntMath.isPowerOfTwo;
|
||||||
|
|
||||||
|
public class BlockLocationSerializer {
|
||||||
|
private static final int[] MULTIPLY_DE_BRUIJN_BIT_POSITION = new int[] {0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9};
|
||||||
|
private static final int NUM_X_BITS = 1 + log2(smallestEncompassingPowerOfTwo(30000000));
|
||||||
|
private static final int NUM_Z_BITS = NUM_X_BITS;
|
||||||
|
private static final int NUM_Y_BITS = 64 - NUM_X_BITS - NUM_Z_BITS;
|
||||||
|
private static final int Y_SHIFT = NUM_Z_BITS;
|
||||||
|
private static final int X_SHIFT = Y_SHIFT + NUM_Y_BITS;
|
||||||
|
private static final long X_MASK = (1L << NUM_X_BITS) - 1L;
|
||||||
|
private static final long Y_MASK = (1L << NUM_Y_BITS) - 1L;
|
||||||
|
private static final long Z_MASK = (1L << NUM_Z_BITS) - 1L;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* net.minecraft.util.math.MathHelper#log2(int)
|
||||||
|
*/
|
||||||
|
private static int log2(int value) {
|
||||||
|
return log2DeBruijn(value) - (isPowerOfTwo(value) ? 0 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* net.minecraft.util.math.MathHelper#log2DeBruijn(int)
|
||||||
|
*/
|
||||||
|
private static int log2DeBruijn(int value) {
|
||||||
|
value = isPowerOfTwo(value) ? value : smallestEncompassingPowerOfTwo(value);
|
||||||
|
return MULTIPLY_DE_BRUIJN_BIT_POSITION[(int)((long)value * 125613361L >> 27) & 31];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* net.minecraft.util.math.MathHelper#smallestEncompassingPowerOfTwo(int)
|
||||||
|
*/
|
||||||
|
private static int smallestEncompassingPowerOfTwo(int value) {
|
||||||
|
int i = value - 1;
|
||||||
|
i = i | i >> 1;
|
||||||
|
i = i | i >> 2;
|
||||||
|
i = i | i >> 4;
|
||||||
|
i = i | i >> 8;
|
||||||
|
i = i | i >> 16;
|
||||||
|
return i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long toLong(BlockLocation location) {
|
||||||
|
return ((long)location.getX() & X_MASK) << X_SHIFT |
|
||||||
|
((long)location.getY() & Y_MASK) << Y_SHIFT |
|
||||||
|
((long)location.getZ() & Z_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BlockLocation fromLong(long value) {
|
||||||
|
BlockLocation location = BlockLocation.ZERO();
|
||||||
|
fromLong(value, location);
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void fromLong(long value, BlockLocation location) {
|
||||||
|
location.setX((int)(value << 64 - X_SHIFT - NUM_X_BITS >> 64 - NUM_X_BITS));
|
||||||
|
location.setY((int)(value << 64 - Y_SHIFT - NUM_Y_BITS >> 64 - NUM_Y_BITS));
|
||||||
|
location.setZ((int)(value << 64 - NUM_Z_BITS >> 64 - NUM_Z_BITS));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package mc.core.network.proto_1_12_2.serializers;
|
||||||
|
|
||||||
|
import mc.core.world.block.BlockLocation;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class TestBlockLocationSerializer {
|
||||||
|
private static final ThreadLocalRandom rnd = ThreadLocalRandom.current();
|
||||||
|
private static final int minI = 0, maxI = 10;
|
||||||
|
private int x, y, z;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() {
|
||||||
|
x = rnd.nextInt(minI, maxI);
|
||||||
|
y = rnd.nextInt(minI, maxI);
|
||||||
|
z = rnd.nextInt(minI, maxI);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
BlockLocation location = new BlockLocation(x, y, z);
|
||||||
|
final long serializedCoords = BlockLocationSerializer.toLong(location);
|
||||||
|
|
||||||
|
BlockLocation deserLoc = BlockLocationSerializer.fromLong(serializedCoords);
|
||||||
|
|
||||||
|
assertEquals(location, deserLoc);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user