Fixing the rendering anchoring

This commit is contained in:
2026-02-25 16:06:10 +01:00
parent f40d3026e6
commit 6b03a1441a
@@ -78,7 +78,7 @@ public class CloakFeatureRenderer extends FeatureRenderer<PlayerEntityRenderStat
EquipmentModelLoader equipmentModelLoader) { EquipmentModelLoader equipmentModelLoader) {
super(context); super(context);
this.equipmentModelLoader = equipmentModelLoader; this.equipmentModelLoader = equipmentModelLoader;
Arrays.fill(segmentValues, 0.5f); Arrays.fill(segmentValues, 1.0f);
} }
private boolean hasCustomModelForLayer(ItemStack stack, EquipmentModel.LayerType layerType) { private boolean hasCustomModelForLayer(ItemStack stack, EquipmentModel.LayerType layerType) {
@@ -138,147 +138,118 @@ public class CloakFeatureRenderer extends FeatureRenderer<PlayerEntityRenderStat
} }
} }
private void renderCape(MatrixStack matrixStack, VertexConsumer vertexConsumer, private void renderCape(MatrixStack matrixStack, VertexConsumer vertexConsumer, PlayerEntityRenderState playerState,
PlayerEntityRenderState playerState, int light, int overlay) { int light, int overlay) {
float capeWidth = 10.0f / 16.0f; float capeWidth = 10.0f / 16.0f;
float capeHeight = 16.0f / 16.0f; float capeHeight = 16.0f / 16.0f;
float capeDepth = 1.0f / 16.0f; float capeDepth = 1.0f / 16.0f;
float capePartHeight = capeHeight / PARTS; float capePartHeight = capeHeight / PARTS;
matrixStack.push();
matrixStack.translate(0.0f, 1.25, 0.125f);
float x1 = -capeWidth / 2.0f; float x1 = -capeWidth / 2.0f;
float x2 = capeWidth / 2.0f; float x2 = capeWidth / 2.0f;
float z1 = 0.0f;
float z2 = capeDepth;
final float frontU1 = FRONT_RECT.u1(); final float frontU1 = FRONT_RECT.u1();
final float frontU2 = FRONT_RECT.u2(); final float frontU2 = FRONT_RECT.u2();
final float frontV1 = FRONT_RECT.v1(); final float frontV1 = FRONT_RECT.v1();
final float frontV2 = FRONT_RECT.v2(); final float frontV2 = FRONT_RECT.v2();
final float frontPartV = (frontV2 - frontV1) / PARTS; final float frontPartV = (frontV2 - frontV1) / PARTS;
final float backU1 = BACK_RECT.u1(); final float backU1 = BACK_RECT.u1();
final float backU2 = BACK_RECT.u2(); final float backU2 = BACK_RECT.u2();
final float backV1 = BACK_RECT.v1(); final float backV1 = BACK_RECT.v1();
final float backV2 = BACK_RECT.v2(); final float backV2 = BACK_RECT.v2();
final float backPartV = (backV2 - backV1) / PARTS; final float backPartV = (backV2 - backV1) / PARTS;
final float leftU1 = LEFT_EDGE_RECT.u1(); final float leftU1 = LEFT_EDGE_RECT.u1();
final float leftU2 = LEFT_EDGE_RECT.u2(); final float leftU2 = LEFT_EDGE_RECT.u2();
final float leftV1 = LEFT_EDGE_RECT.v1(); final float leftV1 = LEFT_EDGE_RECT.v1();
final float leftV2 = LEFT_EDGE_RECT.v2(); final float leftV2 = LEFT_EDGE_RECT.v2();
final float leftPartV = (leftV2 - leftV1) / PARTS; final float leftPartV = (leftV2 - leftV1) / PARTS;
final float rightU1 = RIGHT_EDGE_RECT.u1(); final float rightU1 = RIGHT_EDGE_RECT.u1();
final float rightU2 = RIGHT_EDGE_RECT.u2(); final float rightU2 = RIGHT_EDGE_RECT.u2();
final float rightV1 = RIGHT_EDGE_RECT.v1(); final float rightV1 = RIGHT_EDGE_RECT.v1();
final float rightV2 = RIGHT_EDGE_RECT.v2(); final float rightV2 = RIGHT_EDGE_RECT.v2();
final float rightPartV = (rightV2 - rightV1) / PARTS; final float rightPartV = (rightV2 - rightV1) / PARTS;
final float topU1 = TOP_RECT.u1(); final float topU1 = TOP_RECT.u1();
final float topU2 = TOP_RECT.u2(); final float topU2 = TOP_RECT.u2();
final float topV1 = TOP_RECT.v1(); final float topV1 = TOP_RECT.v1();
final float topV2 = TOP_RECT.v2(); final float topV2 = TOP_RECT.v2();
final float bottomU1 = BOTTOM_RECT.u1(); final float bottomU1 = BOTTOM_RECT.u1();
final float bottomU2 = BOTTOM_RECT.u2(); final float bottomU2 = BOTTOM_RECT.u2();
final float bottomV1 = BOTTOM_RECT.v1(); final float bottomV1 = BOTTOM_RECT.v1();
final float bottomV2 = BOTTOM_RECT.v2(); final float bottomV2 = BOTTOM_RECT.v2();
float accumulatedY = 0.0f; float curY = 0.0f;
float accumulatedZ = 0.0f; float curZ = 0.0f;
for (int i = 0; i < PARTS; i++) { for (int i = 0; i < PARTS; i++) {
float value = segmentValues[i]; float value = segmentValues[i];
float angle = value * ((float) Math.PI / 2f); float angle = value * ((float) Math.PI / 2f);
float offsetY = -(float) Math.cos(angle) * capePartHeight; // Direction of the segment length
float offsetZ = -(float) Math.sin(angle) * capePartHeight; float dirY = -(float) Math.cos(angle);
float dirZ = (float) Math.sin(angle);
float topY = accumulatedY; // Direction of the segment THICKNESS (perpendicular to length)
float topZ = accumulatedZ; // This ensures thickness is always "outward" from the curve
float thickY = (float) Math.sin(angle) * capeDepth;
float thickZ = (float) Math.cos(angle) * capeDepth;
accumulatedY += offsetY; float nextY = curY + dirY * capePartHeight;
accumulatedZ += offsetZ; float nextZ = curZ + dirZ * capePartHeight;
float bottomY = accumulatedY; // Vertices for the "Inner" face (Front - facing player)
float bottomZ = accumulatedZ; Vec3d innerTopLeft = new Vec3d(x2, curY, curZ);
Vec3d innerTopRight = new Vec3d(x1, curY, curZ);
Vec3d innerBotLeft = new Vec3d(x2, nextY, nextZ);
Vec3d innerBotRight = new Vec3d(x1, nextY, nextZ);
// FRONT // Vertices for the "Outer" face (Back - facing world)
this.renderCapeQuad( // We offset these by the thickness vector
vertexConsumer, matrixStack, Vec3d outerTopLeft = new Vec3d(x2, curY + thickY, curZ + thickZ);
new Vec3d(x2, bottomY, z2 + bottomZ), Vec3d outerTopRight = new Vec3d(x1, curY + thickY, curZ + thickZ);
new Vec3d(x1, bottomY, z2 + bottomZ), Vec3d outerBotLeft = new Vec3d(x2, nextY + thickY, nextZ + thickZ);
new Vec3d(x1, topY, z2 + topZ), Vec3d outerBotRight = new Vec3d(x1, nextY + thickY, nextZ + thickZ);
new Vec3d(x2, topY, z2 + topZ),
frontU1, frontV2 - (frontPartV * i),
frontU2, frontV2 - (frontPartV * (i + 1)),
light, overlay,
0.0f, 0.0f, 1.0f, false);
// BACK // FRONT (Inner) - Changed winding/order to fix flipping
this.renderCapeQuad( this.renderCapeQuad(vertexConsumer, matrixStack,
vertexConsumer, matrixStack, innerBotLeft, innerBotRight, innerTopRight, innerTopLeft,
new Vec3d(x1, bottomY, z1 + bottomZ), frontU1, frontV1 + (frontPartV * i), frontU2, frontV1 + (frontPartV * (i + 1)),
new Vec3d(x2, bottomY, z1 + bottomZ), light, overlay, 0, 0, -1, false);
new Vec3d(x2, topY, z1 + topZ),
new Vec3d(x1, topY, z1 + topZ),
backU1, backV2 - (backPartV * i),
backU2, backV2 - (backPartV * (i + 1)),
light, overlay,
0.0f, 0.0f, 1.0f, false);
// LEFT // BACK (Outer)
this.renderCapeQuad( this.renderCapeQuad(vertexConsumer, matrixStack,
vertexConsumer, matrixStack, outerBotRight, outerBotLeft, outerTopLeft, outerTopRight,
new Vec3d(x2, bottomY, z1 + bottomZ), backU1, backV1 + (backPartV * i), backU2, backV1 + (backPartV * (i + 1)),
new Vec3d(x2, bottomY, z2 + bottomZ), light, overlay, 0, 0, 1, false);
new Vec3d(x2, topY, z2 + topZ),
new Vec3d(x2, topY, z1 + topZ),
leftU1, leftV2 - (leftPartV * i),
leftU2, leftV2 - (leftPartV * (i + 1)),
light, overlay,
1.0f, 0.0f, 0.0f, false);
// RIGHT // LEFT EDGE
this.renderCapeQuad( this.renderCapeQuad(vertexConsumer, matrixStack,
vertexConsumer, matrixStack, innerBotLeft, outerBotLeft, outerTopLeft, innerTopLeft,
new Vec3d(x1, bottomY, z2 + bottomZ), leftU1, leftV1 + (leftPartV * i), leftU2, leftV1 + (leftPartV * (i + 1)),
new Vec3d(x1, bottomY, z1 + bottomZ), light, overlay, 1, 0, 0, false);
new Vec3d(x1, topY, z1 + topZ),
new Vec3d(x1, topY, z2 + topZ), // RIGHT EDGE
rightU1, rightV2 - (rightPartV * i), this.renderCapeQuad(vertexConsumer, matrixStack,
rightU2, rightV2 - (rightPartV * (i + 1)), outerBotRight, innerBotRight, innerTopRight, outerTopRight,
light, overlay, rightU1, rightV1 + (rightPartV * i), rightU2, rightV1 + (rightPartV * (i + 1)),
-1.0f, 0.0f, 0.0f, false); light, overlay, -1, 0, 0, false);
// TOP FACE (Only on first segment)
if (i == 0) {
this.renderCapeQuad(vertexConsumer, matrixStack,
outerTopLeft, outerTopRight, innerTopRight, innerTopLeft,
topU1, topV1, topU2, topV2, light, overlay, 0, 1, 0, false);
} }
// TOP FACE // BOTTOM FACE (Only on last segment)
this.renderCapeQuad( if (i == PARTS - 1) {
vertexConsumer, matrixStack, this.renderCapeQuad(vertexConsumer, matrixStack,
new Vec3d(x2, accumulatedY, z2 + accumulatedZ), innerBotLeft, innerBotRight, outerBotRight, outerBotLeft,
new Vec3d(x1, accumulatedY, z2 + accumulatedZ), bottomU1, bottomV1, bottomU2, bottomV2, light, overlay, 0, -1, 0, false);
new Vec3d(x1, accumulatedY, z1 + accumulatedZ), }
new Vec3d(x2, accumulatedY, z1 + accumulatedZ),
topU1, topV1, topU2, topV2,
light, overlay,
0.0f, 1.0f, 0.0f, true);
// BOTTOM FACE (last segment bottom) curY = nextY;
this.renderCapeQuad( curZ = nextZ;
vertexConsumer, matrixStack, }
new Vec3d(x2, 0.0f, z2),
new Vec3d(x1, 0.0f, z2),
new Vec3d(x1, 0.0f, z1),
new Vec3d(x2, 0.0f, z1),
bottomU1, bottomV1, bottomU2, bottomV2,
light, overlay,
0.0f, 0.0f, 1.0f, false);
matrixStack.pop();
} }
public void render(MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int light, public void render(MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int light,
@@ -312,7 +283,7 @@ public class CloakFeatureRenderer extends FeatureRenderer<PlayerEntityRenderStat
matrixStack.push(); matrixStack.push();
matrixStack.translate(0.0f, -0.5f, 0.7f); matrixStack.translate(0.0f, -0.07f, 0.1f);
if (this.hasCustomModelForLayer(playerEntityRenderState.equippedChestStack, LayerType.HUMANOID)) { if (this.hasCustomModelForLayer(playerEntityRenderState.equippedChestStack, LayerType.HUMANOID)) {
matrixStack.translate(0.0F, -0.053125F, 0.06875F); matrixStack.translate(0.0F, -0.053125F, 0.06875F);