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);
}
// BOTTOM FACE (Only on last segment)
if (i == PARTS - 1) {
this.renderCapeQuad(vertexConsumer, matrixStack,
innerBotLeft, innerBotRight, outerBotRight, outerBotLeft,
bottomU1, bottomV1, bottomU2, bottomV2, light, overlay, 0, -1, 0, false);
}
curY = nextY;
curZ = nextZ;
} }
// TOP FACE
this.renderCapeQuad(
vertexConsumer, matrixStack,
new Vec3d(x2, accumulatedY, z2 + accumulatedZ),
new Vec3d(x1, accumulatedY, z2 + accumulatedZ),
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)
this.renderCapeQuad(
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);