add head endpoint and finish the body renderer
All checks were successful
Deploy App / docker (ubuntu-latest, 2.44.0, 17, 3.8.5) (push) Successful in 1m28s
All checks were successful
Deploy App / docker (ubuntu-latest, 2.44.0, 17, 3.8.5) (push) Successful in 1m28s
This commit is contained in:
parent
1a74b0099b
commit
f63d1cc3ec
@ -24,4 +24,18 @@ public class ImageUtils {
|
|||||||
graphics.dispose();
|
graphics.dispose();
|
||||||
return scaled;
|
return scaled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flip an image.
|
||||||
|
*
|
||||||
|
* @param src the source image
|
||||||
|
* @return the flipped image
|
||||||
|
*/
|
||||||
|
public static BufferedImage flip(@NotNull final BufferedImage src) {
|
||||||
|
BufferedImage flipped = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||||
|
Graphics2D graphics = flipped.createGraphics();
|
||||||
|
graphics.drawImage(src, src.getWidth(), 0, 0, src.getHeight(), 0, 0, src.getWidth(), src.getHeight(), null);
|
||||||
|
graphics.dispose();
|
||||||
|
return flipped;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,8 @@ public final class CachedPlayer extends Player implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private long cached;
|
private long cached;
|
||||||
|
|
||||||
public CachedPlayer(UUID uniqueId, String username, Skin skin, Cape cape, MojangProfile.ProfileProperty[] rawProperties, long cached) {
|
public CachedPlayer(UUID uniqueId, String trimmedUniqueId, String username, Skin skin, Cape cape, MojangProfile.ProfileProperty[] rawProperties, long cached) {
|
||||||
super(uniqueId, username, skin, cape, rawProperties);
|
super(uniqueId, trimmedUniqueId, username, skin, cape, rawProperties);
|
||||||
this.cached = cached;
|
this.cached = cached;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,7 +4,8 @@ import cc.fascinated.common.PlayerUtils;
|
|||||||
import cc.fascinated.config.Config;
|
import cc.fascinated.config.Config;
|
||||||
import cc.fascinated.exception.impl.BadRequestException;
|
import cc.fascinated.exception.impl.BadRequestException;
|
||||||
import cc.fascinated.service.skin.SkinRenderer;
|
import cc.fascinated.service.skin.SkinRenderer;
|
||||||
import cc.fascinated.service.skin.impl.SquareRenderer;
|
import cc.fascinated.service.skin.impl.BodyRenderer;
|
||||||
|
import cc.fascinated.service.skin.impl.HeadRenderer;
|
||||||
import cc.fascinated.service.skin.impl.IsometricHeadRenderer;
|
import cc.fascinated.service.skin.impl.IsometricHeadRenderer;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
@ -14,6 +15,9 @@ import lombok.Getter;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -36,6 +40,11 @@ public class Skin {
|
|||||||
*/
|
*/
|
||||||
private Model model;
|
private Model model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The legacy status of the skin
|
||||||
|
*/
|
||||||
|
private boolean isLegacy = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The skin image for the skin
|
* The skin image for the skin
|
||||||
*/
|
*/
|
||||||
@ -53,6 +62,14 @@ public class Skin {
|
|||||||
this.model = model;
|
this.model = model;
|
||||||
|
|
||||||
this.skinImage = PlayerUtils.getSkinImage(url);
|
this.skinImage = PlayerUtils.getSkinImage(url);
|
||||||
|
if (this.skinImage != null) {
|
||||||
|
try {
|
||||||
|
BufferedImage image = ImageIO.read(new ByteArrayInputStream(this.skinImage));
|
||||||
|
if (image.getWidth() == 64 && image.getHeight() == 32) { // Using the old skin format
|
||||||
|
this.isLegacy = true;
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -91,17 +108,14 @@ public class Skin {
|
|||||||
*/
|
*/
|
||||||
@Getter @AllArgsConstructor
|
@Getter @AllArgsConstructor
|
||||||
public enum Parts {
|
public enum Parts {
|
||||||
|
FACE(new HeadRenderer()),
|
||||||
|
HEAD(new IsometricHeadRenderer()),
|
||||||
|
BODY(new BodyRenderer());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Head parts
|
* The skin part renderer for the part.
|
||||||
*/
|
*/
|
||||||
HEAD(new SquareRenderer(8, 8, 8)),
|
private final SkinRenderer skinRenderer;
|
||||||
HEAD_ISOMETRIC(new IsometricHeadRenderer());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The skin part parser for the part.
|
|
||||||
*/
|
|
||||||
private final SkinRenderer skinPartParser;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the name of the part.
|
* Gets the name of the part.
|
||||||
@ -129,6 +143,77 @@ public class Skin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@AllArgsConstructor @Getter
|
||||||
|
public enum PartPosition {
|
||||||
|
/**
|
||||||
|
* Skin postions
|
||||||
|
*/
|
||||||
|
HEAD(8, 8, 8, 8, new LegacyPartPositionData(8, 8, false)),
|
||||||
|
HEAD_TOP(8, 0, 8, 8, null),
|
||||||
|
HEAD_FRONT(8, 8, 8, 8, null),
|
||||||
|
HEAD_RIGHT(0, 8, 8, 8, null),
|
||||||
|
|
||||||
|
BODY(20, 20, 8, 12, new LegacyPartPositionData(20, 20, false)),
|
||||||
|
BODY_BACK(20, 36, 8, 12, null),
|
||||||
|
BODY_LEFT(32, 52, 8, 12, null),
|
||||||
|
BODY_RIGHT(44, 20, 8, 12, null),
|
||||||
|
|
||||||
|
RIGHT_ARM(44, 20, 4, 12, new LegacyPartPositionData(44, 20, false)),
|
||||||
|
LEFT_ARM(36, 52, 4, 12, new LegacyPartPositionData(43, 20, true)),
|
||||||
|
|
||||||
|
RIGHT_LEG(4, 20, 4, 12, new LegacyPartPositionData(4, 20, false)),
|
||||||
|
LEFT_LEG(20, 52, 4, 12, new LegacyPartPositionData(3, 20, true)),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skin overlay (layer) positions
|
||||||
|
*/
|
||||||
|
HEAD_OVERLAY(40, 8, 8, 8, null),
|
||||||
|
// todo: finish these below
|
||||||
|
HEAD_OVERLAY_TOP(40, 0, 40, 0, null),
|
||||||
|
HEAD_OVERLAY_FRONT(40, 8, 40, 8, null),
|
||||||
|
HEAD_OVERLAY_RIGHT(32, 8, 32, 8, null),
|
||||||
|
|
||||||
|
BODY_OVERLAY(20, 32, 20, 12, null),
|
||||||
|
BODY_OVERLAY_BACK(20, 36, 20, 12, null),
|
||||||
|
BODY_OVERLAY_LEFT(32, 52, 32, 12, null),
|
||||||
|
BODY_OVERLAY_RIGHT(44, 32, 44, 12, null),
|
||||||
|
|
||||||
|
RIGHT_ARM_OVERLAY(44, 32, 44, 12, null),
|
||||||
|
LEFT_ARM_OVERLAY(36, 52, 36, 12, null),
|
||||||
|
|
||||||
|
RIGHT_LEG_OVERLAY(4, 32, 4, 12, null),
|
||||||
|
LEFT_LEG_OVERLAY(20, 52, 20, 12, null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The x, and y position of the part.
|
||||||
|
*/
|
||||||
|
private final int x, y;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The width and height of the part.
|
||||||
|
*/
|
||||||
|
private final int width, height;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The part position data for legacy skins.
|
||||||
|
* This can be null to use the default position.
|
||||||
|
*/
|
||||||
|
private final LegacyPartPositionData legacyData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@AllArgsConstructor @Getter
|
||||||
|
public static class LegacyPartPositionData {
|
||||||
|
/**
|
||||||
|
* The x, and y position of the part.
|
||||||
|
*/
|
||||||
|
private int x, y;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should the part be flipped?
|
||||||
|
*/
|
||||||
|
private boolean flipped;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The model of the skin.
|
* The model of the skin.
|
||||||
*/
|
*/
|
||||||
|
@ -71,6 +71,7 @@ public class PlayerService {
|
|||||||
Tuple<Skin, Cape> skinAndCape = mojangProfile.getSkinAndCape();
|
Tuple<Skin, Cape> skinAndCape = mojangProfile.getSkinAndCape();
|
||||||
CachedPlayer player = new CachedPlayer(
|
CachedPlayer player = new CachedPlayer(
|
||||||
uuid, // Player UUID
|
uuid, // Player UUID
|
||||||
|
UUIDUtils.removeDashes(uuid), // Trimmed UUID
|
||||||
mojangProfile.getName(), // Player Name
|
mojangProfile.getName(), // Player Name
|
||||||
skinAndCape.getLeft(), // Skin
|
skinAndCape.getLeft(), // Skin
|
||||||
skinAndCape.getRight(), // Cape
|
skinAndCape.getRight(), // Cape
|
||||||
@ -134,7 +135,7 @@ public class PlayerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
long before = System.currentTimeMillis();
|
long before = System.currentTimeMillis();
|
||||||
byte[] skinPartBytes = part.getSkinPartParser().renderPart(player.getSkin(), part.getName(), renderOverlay, size);
|
byte[] skinPartBytes = part.getSkinRenderer().renderPart(player.getSkin(), part.getName(), renderOverlay, size);
|
||||||
log.info("Took {}ms to render skin part {} for player: {}", System.currentTimeMillis() - before, part.getName(), player.getUniqueId());
|
log.info("Took {}ms to render skin part {} for player: {}", System.currentTimeMillis() - before, part.getName(), player.getUniqueId());
|
||||||
CachedPlayerSkinPart skinPart = new CachedPlayerSkinPart(
|
CachedPlayerSkinPart skinPart = new CachedPlayerSkinPart(
|
||||||
key,
|
key,
|
||||||
|
@ -8,6 +8,7 @@ import lombok.Getter;
|
|||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.*;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
@ -15,21 +16,47 @@ import java.io.ByteArrayOutputStream;
|
|||||||
@AllArgsConstructor @Getter @Log4j2
|
@AllArgsConstructor @Getter @Log4j2
|
||||||
public abstract class SkinRenderer {
|
public abstract class SkinRenderer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the skin image.
|
||||||
|
*
|
||||||
|
* @param skin the skin
|
||||||
|
* @return the skin image
|
||||||
|
*/
|
||||||
|
public BufferedImage getSkinImage(Skin skin) {
|
||||||
|
try {
|
||||||
|
return ImageIO.read(new ByteArrayInputStream(skin.getSkinImage()));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the skin part image.
|
* Gets the skin part image.
|
||||||
*
|
*
|
||||||
* @param skin the skin
|
* @param skin the skin
|
||||||
* @param x the x position
|
* @param position the part position information
|
||||||
* @param y the y position
|
|
||||||
* @param width the width
|
|
||||||
* @param height the height
|
|
||||||
* @param scale the scale
|
* @param scale the scale
|
||||||
* @return the skin part image
|
* @return the skin part image
|
||||||
*/
|
*/
|
||||||
public BufferedImage getSkinPart(Skin skin, int x, int y, int width, int height, double scale) {
|
public BufferedImage getSkinPart(Skin skin, Skin.PartPosition position, double scale) {
|
||||||
try {
|
try {
|
||||||
BufferedImage skinImage = ImageIO.read(new ByteArrayInputStream(skin.getSkinImage()));
|
BufferedImage skinImage = this.getSkinImage(skin);
|
||||||
BufferedImage part = skinImage.getSubimage(x, y, width, height);
|
if (skinImage == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
BufferedImage part;
|
||||||
|
Skin.LegacyPartPositionData legacyData = position.getLegacyData();
|
||||||
|
if (skin.isLegacy() && legacyData != null) {
|
||||||
|
part = skinImage.getSubimage(legacyData.getX(), legacyData.getY(), position.getWidth(), position.getHeight());
|
||||||
|
if (legacyData.isFlipped()) {
|
||||||
|
part = ImageUtils.flip(part);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
part = skinImage.getSubimage(position.getX(), position.getY(), position.getWidth(), position.getHeight());
|
||||||
|
}
|
||||||
|
if (part == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return ImageUtils.resize(part, scale);
|
return ImageUtils.resize(part, scale);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
return null;
|
return null;
|
||||||
@ -56,6 +83,20 @@ public abstract class SkinRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies an overlay (skin layer) to the head part.
|
||||||
|
*
|
||||||
|
* @param graphics the graphics
|
||||||
|
* @param part the part
|
||||||
|
*/
|
||||||
|
public void applyOverlay(Graphics2D graphics, BufferedImage part) {
|
||||||
|
if (part == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
graphics.drawImage(part, 0, 0, null);
|
||||||
|
graphics.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders a skin part.
|
* Renders a skin part.
|
||||||
*
|
*
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
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 BodyRenderer extends SkinRenderer {
|
||||||
|
|
||||||
|
private static final int WIDTH = 16;
|
||||||
|
private static final int HEIGHT = 32;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] renderPart(Skin skin, String partName, boolean renderOverlay, int size) {
|
||||||
|
log.info("Getting {} part bytes for {} with size {}", partName, skin.getUrl(), size);
|
||||||
|
try {
|
||||||
|
BufferedImage outputImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
Graphics2D graphics = outputImage.createGraphics();
|
||||||
|
|
||||||
|
// Get all the required body parts
|
||||||
|
BufferedImage head = this.getSkinPart(skin, Skin.PartPosition.HEAD, 1);
|
||||||
|
BufferedImage body = this.getSkinPart(skin, Skin.PartPosition.BODY, 1);
|
||||||
|
BufferedImage rightArm = this.getSkinPart(skin, Skin.PartPosition.RIGHT_ARM, 1);
|
||||||
|
BufferedImage leftArm = this.getSkinPart(skin, Skin.PartPosition.LEFT_ARM, 1);
|
||||||
|
BufferedImage rightLeg = this.getSkinPart(skin, Skin.PartPosition.RIGHT_LEG, 1);
|
||||||
|
BufferedImage leftLeg = this.getSkinPart(skin, Skin.PartPosition.LEFT_LEG, 1);
|
||||||
|
|
||||||
|
if (renderOverlay) { // Render the skin layers
|
||||||
|
Graphics2D overlayGraphics = head.createGraphics();
|
||||||
|
|
||||||
|
applyOverlay(overlayGraphics, this.getSkinPart(skin, Skin.PartPosition.HEAD_OVERLAY, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the body
|
||||||
|
graphics.drawImage(head, 4, 0, null);
|
||||||
|
graphics.drawImage(body, 4, 8, null);
|
||||||
|
graphics.drawImage(rightArm, 0, 8, null);
|
||||||
|
graphics.drawImage(leftArm, 12, 8, null);
|
||||||
|
graphics.drawImage(rightLeg, 4, 20, null);
|
||||||
|
graphics.drawImage(leftLeg, 8, 20, null);
|
||||||
|
|
||||||
|
graphics.dispose(); // Clean up
|
||||||
|
return super.getBytes(ImageUtils.resize(outputImage, (double) size / HEIGHT), skin, partName);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("Failed to get {} part bytes for {}", partName, skin.getUrl(), ex);
|
||||||
|
throw new RuntimeException("Failed to get " + partName + " part for " + skin.getUrl());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,34 +10,11 @@ import java.awt.geom.AffineTransform;
|
|||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
@Getter @Log4j2
|
@Getter @Log4j2
|
||||||
public class SquareRenderer extends SkinRenderer {
|
public class HeadRenderer extends SkinRenderer {
|
||||||
|
|
||||||
/**
|
|
||||||
* The x and y position of the part.
|
|
||||||
*/
|
|
||||||
private final int x, y;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The width and height of the part.
|
|
||||||
*/
|
|
||||||
private final int widthAndHeight;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new {@link SquareRenderer}.
|
|
||||||
*
|
|
||||||
* @param x the x position of the part
|
|
||||||
* @param y the y position of the part
|
|
||||||
* @param widthAndHeight the width and height of the part
|
|
||||||
*/
|
|
||||||
public SquareRenderer(int x, int y, int widthAndHeight) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.widthAndHeight = widthAndHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] renderPart(Skin skin, String partName, boolean renderOverlay, int size) {
|
public byte[] renderPart(Skin skin, String partName, boolean renderOverlay, int size) {
|
||||||
double scale = (double) size / this.widthAndHeight;
|
double scale = (double) size / 8d;
|
||||||
log.info("Getting {} part bytes for {} with size {} and scale {}", partName, skin.getUrl(), size, scale);
|
log.info("Getting {} part bytes for {} with size {} and scale {}", partName, skin.getUrl(), size, scale);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -45,7 +22,11 @@ public class SquareRenderer extends SkinRenderer {
|
|||||||
Graphics2D graphics = outputImage.createGraphics();
|
Graphics2D graphics = outputImage.createGraphics();
|
||||||
|
|
||||||
graphics.setTransform(AffineTransform.getScaleInstance(scale, scale));
|
graphics.setTransform(AffineTransform.getScaleInstance(scale, scale));
|
||||||
graphics.drawImage(this.getSkinPart(skin, this.x, this.y, this.widthAndHeight, this.widthAndHeight, 1), 0, 0, null);
|
graphics.drawImage(this.getSkinPart(skin, Skin.PartPosition.HEAD, 1), 0, 0, null);
|
||||||
|
|
||||||
|
if (renderOverlay) { // Render the skin layers
|
||||||
|
applyOverlay(outputImage.createGraphics(), this.getSkinPart(skin, Skin.PartPosition.HEAD_OVERLAY, 1));
|
||||||
|
}
|
||||||
|
|
||||||
return super.getBytes(outputImage, skin, partName);
|
return super.getBytes(outputImage, skin, partName);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
@ -13,7 +13,7 @@ import java.awt.image.BufferedImage;
|
|||||||
@Getter @Log4j2
|
@Getter @Log4j2
|
||||||
public class IsometricHeadRenderer extends SkinRenderer {
|
public class IsometricHeadRenderer extends SkinRenderer {
|
||||||
|
|
||||||
private static final double SKEW_A = 26d / 45d; // 0.57777777
|
private static final double SKEW_A = 26d / 45d; // 0.57777777
|
||||||
private static final double SKEW_B = SKEW_A * 2d; // 1.15555555
|
private static final double SKEW_B = SKEW_A * 2d; // 1.15555555
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,19 +36,19 @@ public class IsometricHeadRenderer extends SkinRenderer {
|
|||||||
Graphics2D graphics = outputImage.createGraphics();
|
Graphics2D graphics = outputImage.createGraphics();
|
||||||
|
|
||||||
// Get all the required head parts
|
// Get all the required head parts
|
||||||
BufferedImage headTop = ImageUtils.resize(this.getSkinPart(skin, 8, 0, 8, 8, 1), scale);
|
BufferedImage headTop = ImageUtils.resize(this.getSkinPart(skin, Skin.PartPosition.HEAD_TOP, 1), scale);
|
||||||
BufferedImage headFront = ImageUtils.resize(this.getSkinPart(skin, 8, 8, 8, 8, 1), scale);
|
BufferedImage headFront = ImageUtils.resize(this.getSkinPart(skin, Skin.PartPosition.HEAD_FRONT, 1), scale);
|
||||||
BufferedImage headRight = ImageUtils.resize(this.getSkinPart(skin, 0, 8, 8, 8, 1), scale);
|
BufferedImage headRight = ImageUtils.resize(this.getSkinPart(skin, Skin.PartPosition.HEAD_RIGHT, 1), scale);
|
||||||
|
|
||||||
if (renderOverlay) {
|
if (renderOverlay) { // Render the skin layers
|
||||||
Graphics2D headGraphics = headTop.createGraphics();
|
Graphics2D headGraphics = headTop.createGraphics();
|
||||||
applyOverlay(headGraphics,this.getSkinPart(skin, 40, 0, 8, 8, 1));
|
applyOverlay(headGraphics, this.getSkinPart(skin, Skin.PartPosition.HEAD_OVERLAY, 1));
|
||||||
|
|
||||||
headGraphics = headFront.createGraphics();
|
headGraphics = headFront.createGraphics();
|
||||||
applyOverlay(headGraphics, this.getSkinPart(skin, 16, 8, 8, 8, 1));
|
applyOverlay(headGraphics, this.getSkinPart(skin, Skin.PartPosition.HEAD_OVERLAY_FRONT, 1));
|
||||||
|
|
||||||
headGraphics = headRight.createGraphics();
|
headGraphics = headRight.createGraphics();
|
||||||
applyOverlay(headGraphics, this.getSkinPart(skin, 32, 8, 8, 8, 1));
|
applyOverlay(headGraphics, this.getSkinPart(skin, Skin.PartPosition.HEAD_OVERLAY_RIGHT, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the head
|
// Draw the head
|
||||||
@ -77,17 +77,6 @@ public class IsometricHeadRenderer extends SkinRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Applies an overlay (skin layer) to the head part.
|
|
||||||
*
|
|
||||||
* @param graphics the graphics
|
|
||||||
* @param part the part
|
|
||||||
*/
|
|
||||||
private void applyOverlay(Graphics2D graphics, BufferedImage part) {
|
|
||||||
graphics.drawImage(part, 0, 0, null);
|
|
||||||
graphics.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws a part of the head.
|
* Draws a part of the head.
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user