Skip to content

Commit

Permalink
Improve cube rendering (#41)
Browse files Browse the repository at this point in the history
Co-authored-by: James Ross <[email protected]>
  • Loading branch information
TibiNonEst and Cherry authored Dec 27, 2024
1 parent 4bd33ef commit 1e7c01d
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/rust/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl RenderType {
RenderType::Helm => img
.get_part(Layer::Both, BodyPart::Head, options.model)
.resize(size, size, image::imageops::FilterType::Nearest),
RenderType::Cube => img.render_cube(true, size),
RenderType::Cube => img.render_cube(size, options),
RenderType::Body => img.render_body(options).resize(
size,
size * 2,
Expand Down
68 changes: 56 additions & 12 deletions src/rust/skin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,13 @@ impl MinecraftSkin {
DynamicImage::ImageRgba8(image)
}

pub(crate) fn render_cube(&self, overlay: bool, width: u32) -> DynamicImage {
let scale = (width as f32) / 20.0 as f32;
let height = (18.5 * scale).ceil() as u32;
let _layer_type = match overlay {
true => Layer::Both,
false => Layer::Bottom,
};
let mut render = RgbaImage::new(width, height);
pub(crate) fn render_cube(&self, size: u32, options: RenderOptions) -> DynamicImage {
let scale = (size as f32) / 20.0 as f32;

let x_render_offset = scale.ceil() as i64;
let z_render_offset = x_render_offset / 2;

let mut render = RgbaImage::new(size, size);

let z_offset = scale * 3.0;
let x_offset = scale * 2.0;
Expand All @@ -191,10 +190,18 @@ impl MinecraftSkin {
let head_orig_right = self.0.crop_imm(0, 8, 8, 8);
let head_orig_front = self.0.crop_imm(8, 8, 8, 8);

let head_orig_top_overlay = self.0.crop_imm(40, 0, 8, 8);
let head_orig_right_overlay = self.0.crop_imm(32, 8, 8, 8);
let head_orig_front_overlay = self.0.crop_imm(40, 8, 8, 8);

// Shade right texture darker to show depth
let head_orig_right = head_orig_right.brighten(-4);
let head_orig_right_overlay = head_orig_right_overlay.brighten(-4);

// The warp_into function clears every part of the output image that is not part of the pre-image.
// As a workaround, we ask warp_into to draw into a scratch image, overlay the final image with the
// scratch image, and let the scratch be overwritten.
let mut scratch = RgbaImage::new(width, height);
let mut scratch = RgbaImage::new(size, size);

// head top
let head_top_skew =
Expand All @@ -208,7 +215,12 @@ impl MinecraftSkin {
Rgba([0, 0, 0, 0]),
&mut scratch,
);
imageops::overlay(&mut render, &scratch, 0, 0);
imageops::overlay(
&mut render,
&scratch,
x_render_offset.into(),
z_render_offset.into(),
);

// head front
let head_front_skew =
Expand All @@ -224,7 +236,7 @@ impl MinecraftSkin {
Rgba([0, 0, 0, 0]),
&mut scratch,
);
imageops::overlay(&mut render, &scratch, 0, 0);
imageops::overlay(&mut render, &scratch, x_render_offset, z_render_offset);

// head right
let head_right_skew =
Expand All @@ -238,7 +250,39 @@ impl MinecraftSkin {
Rgba([0, 0, 0, 0]),
&mut scratch,
);
imageops::overlay(&mut render, &scratch, 0, 0);
imageops::overlay(&mut render, &scratch, x_render_offset, z_render_offset);

if options.armored {
// head top overlay
warp_into(
&head_orig_top_overlay.into_rgba8(),
&head_top_skew,
Interpolation::Nearest,
Rgba([0, 0, 0, 0]),
&mut scratch,
);
imageops::overlay(&mut render, &scratch, x_render_offset, z_render_offset);

// head front overlay
warp_into(
&head_orig_front_overlay.into_rgba8(),
&head_front_skew,
Interpolation::Nearest,
Rgba([0, 0, 0, 0]),
&mut scratch,
);
imageops::overlay(&mut render, &scratch, x_render_offset, z_render_offset);

// head right overlay
warp_into(
&head_orig_right_overlay.into_rgba8(),
&head_right_skew,
Interpolation::Nearest,
Rgba([0, 0, 0, 0]),
&mut scratch,
);
imageops::overlay(&mut render, &scratch, x_render_offset, z_render_offset);
}

DynamicImage::ImageRgba8(render)
}
Expand Down
2 changes: 1 addition & 1 deletion src/worker/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export function interpretRequest(request: Request): CraftheadRequest | null {
let armored = false;
let sliceAmt = 1;

if (url.pathname.includes('armor/body') || url.pathname.includes('armor/bust')) {
if (url.pathname.includes('/armor/cube/') || url.pathname.includes('/armor/body/') || url.pathname.includes('/armor/bust/')) {
armored = true;
sliceAmt = 2;
}
Expand Down

0 comments on commit 1e7c01d

Please sign in to comment.