Created
August 9, 2024 21:36
-
-
Save WizardlyBump17/4f44104016efd4486788c4997b71fd98 to your computer and use it in GitHub Desktop.
Some methods to compress coordinates
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Arrays; | |
public class Coord { | |
public static void main(String[] args) { | |
int x = (int) -Math.pow(2, 32); | |
int y = (int) Math.pow(2, 23) - 1; | |
int z = (int) Math.pow(2, 32); | |
int chunkX = x >> 4; | |
int chunkZ = z >> 4; | |
long serializedChunk = serializeChunkPos(chunkX, chunkZ); | |
int[] deserializedChunk = deserializeChunkPos(serializedChunk); | |
int serialized = serializeBlockPos(x, y, z); | |
int[] deserialized = deserializeBlockPos(serialized, chunkX, chunkZ); | |
System.out.println(x + " " + y + " " + z); | |
System.out.println(Arrays.toString(deserialized)); | |
System.out.println(); | |
System.out.println(chunkX + " " + chunkZ); | |
System.out.println(Arrays.toString(deserializedChunk)); | |
} | |
/** | |
* <p> | |
* Serializes the given coordinate into a single integer. | |
* The X and Z are relative to the chunk, so they are in the range [0, 15]. | |
* </p> | |
* <p> | |
* The serialized integer is composed of the following bits: | |
* <ul> | |
* <li>4 bits for the X coordinate</li> | |
* <li>1 bit for the sign of the Y coordinate</li> | |
* <li>23 bits for the absolute value of the Y coordinate</li> | |
* <li>4 bits for the Z coordinate</li> | |
* </ul> | |
* </p> | |
* | |
* @param x the X coordinate | |
* @param y the Y coordinate | |
* @param z the Z coordinate | |
* @return an integer representing the given coordinate | |
*/ | |
public static int serializeBlockPos(int x, int y, int z) { | |
return (x & 15) << 28 | (y < 0 ? 1 : 0) << 27 | (Math.abs(y) & 0x7FFFFF) << 4 | (z & 15); | |
} | |
/** | |
* <p> | |
* Deserializes the given serialized integer into an array of integers representing the X, Y, and Z coordinates. | |
* As the {@link #serializeBlockPos(int, int, int)} method serializes the coordinates relative to the chunk, | |
* you must provide the chunk X and Z coordinates to get the absolute coordinates. | |
* </p> | |
* | |
* @param serialized the serialized integer | |
* @param chunkX the X coordinate of the chunk | |
* @param chunkZ the Z coordinate of the chunk | |
* @return an array of integers representing the X, Y, and Z coordinates | |
* @see #serializeBlockPos(int, int, int) | |
*/ | |
public static int[] deserializeBlockPos(int serialized, int chunkX, int chunkZ) { | |
return new int[] { | |
(chunkX << 4) + ((serialized >> 28) & 15), | |
(serialized >> 27 & 1) == 1 ? -((serialized >> 4) & 0x7FFFFF) : (serialized >> 4) & 0x7FFFFF, | |
(chunkZ << 4) + (serialized & 15) | |
}; | |
} | |
/** | |
* <p> | |
* Serializes the given chunk X and Z coordinates into a single long. | |
* </p> | |
* <p> | |
* The serialized long is composed of the following bits: | |
* <ul> | |
* <li>32 bits for the X coordinate</li> | |
* <li>32 bits for the Z coordinate</li> | |
* </ul> | |
* </p> | |
* | |
* @param x the X coordinate of the chunk | |
* @param z the Z coordinate of the chunk | |
* @return a long representing the given chunk coordinates | |
*/ | |
public static long serializeChunkPos(int x, int z) { | |
return (x & 0xFFFFFFFFL) << 32 | z & 0xFFFFFFFFL; | |
} | |
/** | |
* <p> | |
* Deserializes the given serialized long into an array of integers representing the X and Z coordinates of the chunk. | |
* </p> | |
* | |
* @param serialized the serialized long | |
* @return an array of integers representing the X and Z coordinates of the chunk | |
*/ | |
public static int[] deserializeChunkPos(long serialized) { | |
return new int[] { | |
(int) (serialized >> 32), | |
(int) serialized | |
}; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment