Crop and reorder skull textures to eliminate unused space

Should reduce memory & storage usage for Bedrock clients
This commit is contained in:
davchoo 2022-07-27 22:32:18 -04:00
parent 8244afa8c7
commit 15fd5353e1
No known key found for this signature in database
GPG key ID: A0168C8E45799B7D
5 changed files with 127 additions and 32 deletions

View file

@ -53,7 +53,7 @@ import java.util.zip.ZipOutputStream;
public class SkullResourcePackManager {
private static final long RESOURCE_PACK_VERSION = 6;
private static final long RESOURCE_PACK_VERSION = 9;
private static final Path SKULL_SKIN_CACHE_PATH = GeyserImpl.getInstance().getBootstrap().getConfigFolder().resolve("cache").resolve("player_skulls");
@ -112,21 +112,24 @@ public class SkullResourcePackManager {
}
BufferedImage image = SkinProvider.requestImage(skinUrl, null);
if (image.getHeight() != 64) {
// We have to resize legacy skins to 64x64 for them to be displayed properly
BufferedImage modernSkin = new BufferedImage(64, 64, image.getType());
// Resize skins to 48x16 to save on space and memory
BufferedImage skullTexture = new BufferedImage(48, 16, image.getType());
// Reorder skin parts to fit into the space
// Right, Front, Left, Back, Top, Bottom - head
// Right, Front, Left, Back, Top, Bottom - hat
Graphics g = skullTexture.createGraphics();
// Right, Front, Left, Back of the head
g.drawImage(image, 0, 0, 32, 8, 0, 8, 32, 16, null);
// Right, Front, Left, Back of the hat
g.drawImage(image, 0, 8, 32, 16, 32, 8, 64, 16, null);
// Top and bottom of the head
g.drawImage(image, 32, 0, 48, 8, 8, 0, 24, 8, null);
// Top and bottom of the hat
g.drawImage(image, 32, 8, 48, 16, 40, 0, 56, 8, null);
g.dispose();
image.flush();
Graphics g = modernSkin.createGraphics();
g.drawImage(image, 0, 0, null);
g.setColor(new Color(0, 0, 0, 0));
g.fillRect(0, 32, 64, 32);
g.dispose();
image.flush();
image = modernSkin;
}
ImageIO.write(image, "png", skinPath.toFile());
ImageIO.write(skullTexture, "png", skinPath.toFile());
SKULL_SKINS.put(skinHash, skinPath);
GeyserImpl.getInstance().getLogger().debug("Cached player skull to " + skinPath + " for " + skinHash);
}

View file

@ -4,8 +4,8 @@
{
"description": {
"identifier": "geometry.geyser.player_skull",
"texture_width": 64,
"texture_height": 64
"texture_width": 48,
"texture_height": 16
},
"bones": [
{
@ -33,7 +33,18 @@
"parent": "root_z",
"pivot": [0, 24, 0],
"cubes": [
{"origin": [-4, 8, -4], "size": [8, 8, 8], "uv": [0, 0]}
{
"origin": [-4, 8, -4],
"size": [8, 8, 8],
"uv": {
"north": {"uv": [8, 0], "uv_size": [8, 8]},
"east": {"uv": [0, 0], "uv_size": [8, 8]},
"south": {"uv": [24, 0], "uv_size": [8, 8]},
"west": {"uv": [16, 0], "uv_size": [8, 8]},
"up": {"uv": [32, 0], "uv_size": [8, 8]},
"down": {"uv": [40, 8], "uv_size": [8, -8]}
}
}
]
},
{
@ -41,10 +52,22 @@
"parent": "player_skull",
"pivot": [0, 24, 0],
"cubes": [
{"origin": [-4, 8, -4], "size": [8, 8, 8], "uv": [32, 0], "inflate": 0.25}
{
"origin": [-4, 8, -4],
"size": [8, 8, 8],
"inflate": 0.25,
"uv": {
"north": {"uv": [8, 8], "uv_size": [8, 8]},
"east": {"uv": [0, 8], "uv_size": [8, 8]},
"south": {"uv": [24, 8], "uv_size": [8, 8]},
"west": {"uv": [16, 8], "uv_size": [8, 8]},
"up": {"uv": [32, 8], "uv_size": [8, 8]},
"down": {"uv": [40, 16], "uv_size": [8, -8]}
}
}
]
}
]
}
]
}
}

View file

@ -4,8 +4,8 @@
{
"description": {
"identifier": "geometry.geyser.player_skull_floor_${quadrant}",
"texture_width": 64,
"texture_height": 64
"texture_width": 48,
"texture_height": 16
},
"bones": [
{
@ -13,7 +13,18 @@
"pivot": [0, 24, 0],
"rotation": [0, ${y_rotation}, 0],
"cubes": [
{"origin": [-4, 0.5, -4], "size": [8, 8, 8], "uv": [0, 0]}
{
"origin": [-4, 0.5, -4],
"size": [8, 8, 8],
"uv": {
"north": {"uv": [8, 0], "uv_size": [8, 8]},
"east": {"uv": [0, 0], "uv_size": [8, 8]},
"south": {"uv": [24, 0], "uv_size": [8, 8]},
"west": {"uv": [16, 0], "uv_size": [8, 8]},
"up": {"uv": [32, 0], "uv_size": [8, 8]},
"down": {"uv": [40, 8], "uv_size": [8, -8]}
}
}
]
},
{
@ -21,7 +32,19 @@
"parent": "head",
"pivot": [0, 24, 0],
"cubes": [
{"origin": [-4, 0.5, -4], "size": [8, 8, 8], "uv": [32, 0], "inflate": 0.5}
{
"origin": [-4, 0.5, -4],
"size": [8, 8, 8],
"inflate": 0.5,
"uv": {
"north": {"uv": [8, 8], "uv_size": [8, 8]},
"east": {"uv": [0, 8], "uv_size": [8, 8]},
"south": {"uv": [24, 8], "uv_size": [8, 8]},
"west": {"uv": [16, 8], "uv_size": [8, 8]},
"up": {"uv": [32, 8], "uv_size": [8, 8]},
"down": {"uv": [40, 16], "uv_size": [8, -8]}
}
}
]
}
]

View file

@ -4,15 +4,26 @@
{
"description": {
"identifier": "geometry.geyser.player_skull_hand",
"texture_width": 64,
"texture_height": 64
"texture_width": 48,
"texture_height": 16
},
"bones": [
{
"name": "head",
"pivot": [0, 24, 0],
"cubes": [
{"origin": [-4, 4, -4], "size": [8, 8, 8], "uv": [0, 0]}
{
"origin": [-4, 4, -4],
"size": [8, 8, 8],
"uv": {
"north": {"uv": [8, 0], "uv_size": [8, 8]},
"east": {"uv": [0, 0], "uv_size": [8, 8]},
"south": {"uv": [24, 0], "uv_size": [8, 8]},
"west": {"uv": [16, 0], "uv_size": [8, 8]},
"up": {"uv": [32, 0], "uv_size": [8, 8]},
"down": {"uv": [40, 8], "uv_size": [8, -8]}
}
}
]
},
{
@ -20,7 +31,19 @@
"parent": "head",
"pivot": [0, 24, 0],
"cubes": [
{"origin": [-4, 4, -4], "size": [8, 8, 8], "uv": [32, 0], "inflate": 0.5}
{
"origin": [-4, 4, -4],
"size": [8, 8, 8],
"inflate": 0.5,
"uv": {
"north": {"uv": [8, 8], "uv_size": [8, 8]},
"east": {"uv": [0, 8], "uv_size": [8, 8]},
"south": {"uv": [24, 8], "uv_size": [8, 8]},
"west": {"uv": [16, 8], "uv_size": [8, 8]},
"up": {"uv": [32, 8], "uv_size": [8, 8]},
"down": {"uv": [40, 16], "uv_size": [8, -8]}
}
}
]
}
]

View file

@ -4,15 +4,26 @@
{
"description": {
"identifier": "geometry.geyser.player_skull_wall",
"texture_width": 64,
"texture_height": 64
"texture_width": 48,
"texture_height": 16
},
"bones": [
{
"name": "head",
"pivot": [0, 24, 0],
"cubes": [
{"origin": [-4, 4, -0.5], "size": [8, 8, 8], "uv": [0, 0]}
{
"origin": [-4, 4, -0.5],
"size": [8, 8, 8],
"uv": {
"north": {"uv": [8, 0], "uv_size": [8, 8]},
"east": {"uv": [0, 0], "uv_size": [8, 8]},
"south": {"uv": [24, 0], "uv_size": [8, 8]},
"west": {"uv": [16, 0], "uv_size": [8, 8]},
"up": {"uv": [32, 0], "uv_size": [8, 8]},
"down": {"uv": [40, 8], "uv_size": [8, -8]}
}
}
]
},
{
@ -20,7 +31,19 @@
"parent": "head",
"pivot": [0, 24, 0],
"cubes": [
{"origin": [-4, 4, -0.5], "size": [8, 8, 8], "uv": [32, 0], "inflate": 0.5}
{
"origin": [-4, 4, -0.5],
"size": [8, 8, 8],
"inflate": 0.5,
"uv": {
"north": {"uv": [8, 8], "uv_size": [8, 8]},
"east": {"uv": [0, 8], "uv_size": [8, 8]},
"south": {"uv": [24, 8], "uv_size": [8, 8]},
"west": {"uv": [16, 8], "uv_size": [8, 8]},
"up": {"uv": [32, 8], "uv_size": [8, 8]},
"down": {"uv": [40, 16], "uv_size": [8, -8]}
}
}
]
}
]