Files
Backend/src/main/java/cc.fascinated/service/skin/impl/IsometricHeadRenderer.java
Liam d9e6becebb
All checks were successful
Deploy App / docker (ubuntu-latest, 2.44.0, 17, 3.8.5) (push) Successful in 1m32s
fix overlay on player head
2024-04-11 07:45:16 +01:00

85 lines
3.4 KiB
Java

package cc.fascinated.service.skin.impl;
import cc.fascinated.common.ImageUtils;
import cc.fascinated.model.player.Skin;
import cc.fascinated.service.skin.SkinRenderer;
import lombok.Getter;
import lombok.extern.log4j.Log4j2;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
@Getter @Log4j2
public class IsometricHeadRenderer extends SkinRenderer {
private static final double SKEW_A = 26d / 45d; // 0.57777777
private static final double SKEW_B = SKEW_A * 2d; // 1.15555555
/**
* The head transforms
*/
private static final AffineTransform HEAD_TRANSFORM = new AffineTransform(1d, -SKEW_A, 1, SKEW_A, 0, 0);
private static final AffineTransform FRONT_TRANSFORM = new AffineTransform(1d, -SKEW_A, 0d, SKEW_B, 0d, SKEW_A);
private static final AffineTransform RIGHT_TRANSFORM = new AffineTransform(1d, SKEW_A, 0d, SKEW_B, 0d, 0d);
@Override
public byte[] renderPart(Skin skin, String partName, boolean renderOverlay, int size) {
double scale = (size / 8d) / 2.5;
log.info("Getting {} part bytes for {} with size {} and scale {}", partName, skin.getUrl(), size, scale);
double x, y, z; // The x, y, and z positions
double zOffset = scale * 3.5d;
double xOffset = scale * 2d;
BufferedImage outputImage = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = outputImage.createGraphics();
// Get all the required head parts
BufferedImage headTop = this.getSkinPart(skin, Skin.PartPosition.HEAD_TOP, scale);
BufferedImage headFront = this.getSkinPart(skin, Skin.PartPosition.HEAD_FRONT, scale);
BufferedImage headRight = this.getSkinPart(skin, Skin.PartPosition.HEAD_RIGHT, scale);
if (renderOverlay) { // Render the skin layers
applyOverlay(headTop, this.getSkinPart(skin, Skin.PartPosition.HEAD_OVERLAY_TOP, scale));
applyOverlay(headFront, this.getSkinPart(skin, Skin.PartPosition.HEAD_OVERLAY_FRONT, scale));
applyOverlay(headRight, this.getSkinPart(skin, Skin.PartPosition.HEAD_OVERLAY_RIGHT, scale));
}
// Draw the top of the head
x = xOffset;
y = -0.5;
z = zOffset;
// The head is offset by 2 pixels for whatever reason
drawPart(graphics, headTop, HEAD_TRANSFORM, y - z, x + z, headTop.getWidth(), headTop.getHeight() + 2);
// Draw the front of the head
x = xOffset + 8 * scale;
y = 0;
z = zOffset - 0.5;
drawPart(graphics, headFront, FRONT_TRANSFORM, y + x, x + z, headFront.getWidth(), headFront.getHeight());
// Draw the right side of the head
x = xOffset;
y = 0;
z = zOffset;
drawPart(graphics, headRight, RIGHT_TRANSFORM, x + y + 1, z - y - 0.5, headRight.getWidth(), headRight.getHeight());
return super.getBytes(outputImage, skin, partName);
}
/**
* Draws a part of the head.
*
* @param graphics the graphics
* @param part the part
* @param transform the transform
* @param x the x position
* @param y the y position
* @param width the width
* @param height the height
*/
private void drawPart(Graphics2D graphics, BufferedImage part, AffineTransform transform, double x, double y, int width, int height) {
graphics.setTransform(transform);
graphics.drawImage(part, (int) x, (int) y, width, height, null);
}
}