-
Notifications
You must be signed in to change notification settings - Fork 69
/
AddressTools.java
109 lines (90 loc) · 4.38 KB
/
AddressTools.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
* This file is part of Cubic Chunks Mod, licensed under the MIT License (MIT).
*
* Copyright (c) 2015 contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package cubicchunks.util;
public class AddressTools {
// Anvil format details:
// within a region file, each chunk coord gets 5 bits
// the coord for each region is capped at 27 bits
// here's the encoding scheme for 64 bits of space:
// y: 20 bits, signed, 1,048,576 chunks, 16,777,216 blocks
// x: 22 bits, signed, 4,194,304 chunks, 67,108,864 blocks
// z: 22 bits, signed, 4,194,304 chunks, 67,108,864 blocks
// World.setBlock() caps block x,z at -30m to 30m, so our 22-bit cap on chunk x,z is just right!
// the Anvil format gives 32 bits to each chunk coordinate, but we're only giving 22 bits
// moving at 8 blocks/s (which is like minecart speed), it would take ~48 days to reach the x or z edge from the center
// at the same speed, it would take ~24 days to reach the top from the bottom
// that seems like enough room for a minecraft world
// 0 1 |2 3 4| 5 6 |
// 0123456789012345678901234567890123456789012345678901234567890123
// yyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxzzzzzzzzzzzzzzzzzzzzzz
private static final int Y_BITS = 20;
private static final int X_BITS = 22;
private static final int Z_BITS = 22;
private static final int Z_BIT_OFFSET = 0;
private static final int X_BIT_OFFSET = Z_BIT_OFFSET + Z_BITS;
private static final int Y_BIT_OFFSET = X_BIT_OFFSET + X_BITS;
public static final int MIN_CUBE_Y = Bits.getMinSigned(Y_BITS);
public static final int MAX_CUBE_Y = Bits.getMaxSigned(Y_BITS);
public static final int MIN_CUBE_X = Bits.getMinSigned(X_BITS);
public static final int MAX_CUBE_X = Bits.getMaxSigned(X_BITS);
public static final int MIN_CUBE_Z = Bits.getMinSigned(Z_BITS);
public static final int MAX_CUBE_Z = Bits.getMaxSigned(Z_BITS);
public static final int MIN_BLOCK_Y = Coords.cubeToMinBlock(MIN_CUBE_Y);
public static final int MAX_BLOCK_Y = Coords.cubeToMaxBlock(MAX_CUBE_Y);
public static long getAddress(int x, int y, int z) {
return Bits.packSignedToLong(y, Y_BITS, Y_BIT_OFFSET)
| Bits.packSignedToLong(x, X_BITS, X_BIT_OFFSET)
| Bits.packSignedToLong(z, Z_BITS, Z_BIT_OFFSET);
}
public static long getAddress(int x, int z) {
return Bits.packSignedToLong(x, X_BITS, X_BIT_OFFSET)
| Bits.packSignedToLong(z, Z_BITS, Z_BIT_OFFSET);
}
public static int getY(long address) {
return Bits.unpackSigned(address, Y_BITS, Y_BIT_OFFSET);
}
public static int getX(long address) {
return Bits.unpackSigned(address, X_BITS, X_BIT_OFFSET);
}
public static int getZ(long address) {
return Bits.unpackSigned(address, Z_BITS, Z_BIT_OFFSET);
}
public static long cubeToColumn(long cubeAddress) {
return getAddress(getX(cubeAddress), getZ(cubeAddress));
}
public static int getLocalAddress(int localX, int localY, int localZ) {
return Bits.packUnsignedToInt(localX, 4, 0)
| Bits.packUnsignedToInt(localY, 4, 4)
| Bits.packUnsignedToInt(localZ, 4, 8);
}
public static int getLocalX(int localAddress) {
return Bits.unpackUnsigned(localAddress, 4, 0);
}
public static int getLocalY(int localAddress) {
return Bits.unpackUnsigned(localAddress, 4, 4);
}
public static int getLocalZ(int localAddress) {
return Bits.unpackUnsigned(localAddress, 4, 8);
}
}