Skip to content

Commit

Permalink
Fix PlayerModelHud not rendering when minecraft GUI scale is not 1 (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Mersid authored Jan 15, 2024
1 parent 0b95c14 commit 8e914fb
Showing 1 changed file with 78 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@
import meteordevelopment.meteorclient.systems.hud.HudRenderer;
import meteordevelopment.meteorclient.utils.render.color.Color;
import meteordevelopment.meteorclient.utils.render.color.SettingColor;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ingame.InventoryScreen;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.MathHelper;
import org.joml.Quaternionf;
import org.joml.Vector3f;

import static meteordevelopment.meteorclient.MeteorClient.mc;

Expand Down Expand Up @@ -42,13 +46,6 @@ public class PlayerModelHud extends HudElement {
.build()
);

private final Setting<Boolean> copyPitch = sgGeneral.add(new BoolSetting.Builder()
.name("copy-pitch")
.description("Makes the player model's pitch equal to yours.")
.defaultValue(true)
.build()
);

private final Setting<Integer> customYaw = sgGeneral.add(new IntSetting.Builder()
.name("custom-yaw")
.description("Custom yaw for when copy yaw is off.")
Expand All @@ -59,6 +56,13 @@ public class PlayerModelHud extends HudElement {
.build()
);

private final Setting<Boolean> copyPitch = sgGeneral.add(new BoolSetting.Builder()
.name("copy-pitch")
.description("Makes the player model's pitch equal to yours.")
.defaultValue(true)
.build()
);

private final Setting<Integer> customPitch = sgGeneral.add(new IntSetting.Builder()
.name("custom-pitch")
.description("Custom pitch for when copy pitch is off.")
Expand All @@ -69,6 +73,13 @@ public class PlayerModelHud extends HudElement {
.build()
);

private final Setting<CenterOrientation> centerOrientation = sgGeneral.add(new EnumSetting.Builder<CenterOrientation>()
.name("center-orientation")
.description("Which direction the player faces when the HUD model faces directly forward.")
.defaultValue(CenterOrientation.South)
.build()
);

// Background

private final Setting<Boolean> background = sgBackground.add(new BoolSetting.Builder()
Expand Down Expand Up @@ -98,10 +109,12 @@ public void render(HudRenderer renderer) {
PlayerEntity player = mc.player;
if (player == null) return;

float yaw = copyYaw.get() ? MathHelper.wrapDegrees(player.prevYaw + (player.getYaw() - player.prevYaw) * mc.getTickDelta()) : (float) customYaw.get();
float offset = centerOrientation.get() == CenterOrientation.North ? 180 : 0;

float yaw = copyYaw.get() ? MathHelper.wrapDegrees(player.prevYaw + (player.getYaw() - player.prevYaw) * mc.getTickDelta() + offset) : (float) customYaw.get();
float pitch = copyPitch.get() ? player.getPitch() : (float) customPitch.get();

InventoryScreen.drawEntity(renderer.drawContext, x, y, (int) (x + (25 * scale.get())), (int) (y + (66 * scale.get())), (int) (30 * scale.get()), 0, -yaw, -pitch, player);
drawEntity(renderer.drawContext, x, y, (int) (30 * scale.get()), -yaw, -pitch, player);
});

if (background.get()) {
Expand All @@ -116,4 +129,60 @@ public void render(HudRenderer renderer) {
private void calculateSize() {
setSize(50 * scale.get(), 75 * scale.get());
}

/**
* Draws an entity to the screen. The default version provided by InventoryScreen has had its parameters changed
* such that it's no longer appropriate for this use case. As the new version uses rotation based on the mouse
* position relative to itself, it causes some odd angle positioning that may also look "stuck" to one corner,
* and the model's facing may change depending on how we reposition the element.
* Additionally, it uses OpenGL scissors, which causes the player model to get cut when the Minecraft GUI scale is not 1x.
* This version of drawEntity should fix these issues.
*/
private void drawEntity(DrawContext context, int x, int y, int size, float yaw, float pitch, LivingEntity entity) {

float tanYaw = (float) Math.atan((yaw) / 40.0f);
float tanPitch = (float) Math.atan((pitch) / 40.0f);

// By default, the origin of the drawEntity command is the top-center, facing down and straight to the south.
// This means that the player model is upside-down. We'll apply a rotation of PI radians (180 degrees) to fix this.
// This does have the downside of setting the origin to the bottom-center corner, though, so we'll have
// to compensate for this later.
Quaternionf quaternion = new Quaternionf().rotateZ((float) Math.PI);

// The drawEntity command draws the entity using some entity parameters, so we'll have to manipulate some of
// those to draw as we want. But first, we'll save the previous values, so we can restore them later.
float previousBodyYaw = entity.bodyYaw;
float previousYaw = entity.getYaw();
float previousPitch = entity.getPitch();
float previousPrevHeadYaw = entity.prevHeadYaw; // A perplexing name, I know!
float prevHeadYaw = entity.headYaw;

// Apply the rotation parameters
entity.bodyYaw = 180.0f + tanYaw * 20.0f;
entity.setYaw(180.0f + tanYaw * 40.0f);
entity.setPitch(-tanPitch * 20.0f);
entity.headYaw = entity.getYaw();
entity.prevHeadYaw = entity.getYaw();

// Recall the player's origin is now the bottom-center corner, so we'll have to offset the draw by half the width
// to get it to render in the center.
// As for the y parameter, adding the element's height draws it at the bottom, but in practice we want the player
// to "float" somewhat, so we'll multiply it by some constant to have it hover. It turns out 0.9 is a good value.
// The vector3 parameter applies a translation to the player's model. Given that we're simply offsetting
// the draw in the x and y parameters, we won't really need this, so we'll set it to default.
// It doesn't seem like quaternionf2 does anything, so we'll leave it null to save some computation.
InventoryScreen.drawEntity(context, x + getWidth() / 2, y + getHeight() * 0.9f, size, new Vector3f(), quaternion, null, entity);

// Restore the previous values
entity.bodyYaw = previousBodyYaw;
entity.setYaw(previousYaw);
entity.setPitch(previousPitch);
entity.prevHeadYaw = previousPrevHeadYaw;
entity.headYaw = prevHeadYaw;
}

private enum CenterOrientation {
North,
South
}
}

0 comments on commit 8e914fb

Please sign in to comment.