/* * Decompiled with CFR 0.152. * * Could not load the following classes: * org.joml.Quaternionfc */ package net.minecraft.client.renderer.entity; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.math.Axis; import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.SubmitNodeCollector; import net.minecraft.client.renderer.entity.EntityRenderer; import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.renderer.entity.state.PaintingRenderState; import net.minecraft.client.renderer.rendertype.RenderType; import net.minecraft.client.renderer.rendertype.RenderTypes; import net.minecraft.client.renderer.state.CameraRenderState; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.data.AtlasIds; import net.minecraft.resources.Identifier; import net.minecraft.util.Mth; import net.minecraft.world.entity.decoration.Painting; import net.minecraft.world.entity.decoration.PaintingVariant; import net.minecraft.world.level.Level; import org.joml.Quaternionfc; public class PaintingRenderer extends EntityRenderer { private static final Identifier BACK_SPRITE_LOCATION = Identifier.withDefaultNamespace("back"); private final TextureAtlas paintingsAtlas; public PaintingRenderer(EntityRendererProvider.Context context) { super(context); this.paintingsAtlas = context.getAtlas(AtlasIds.PAINTINGS); } @Override public void submit(PaintingRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) { PaintingVariant variant = state.variant; if (variant == null) { return; } poseStack.pushPose(); poseStack.mulPose((Quaternionfc)Axis.YP.rotationDegrees(180 - state.direction.get2DDataValue() * 90)); TextureAtlasSprite frontSprite = this.paintingsAtlas.getSprite(variant.assetId()); TextureAtlasSprite backSprite = this.paintingsAtlas.getSprite(BACK_SPRITE_LOCATION); this.renderPainting(poseStack, submitNodeCollector, RenderTypes.entitySolidZOffsetForward(backSprite.atlasLocation()), state.lightCoordsPerBlock, variant.width(), variant.height(), frontSprite, backSprite); poseStack.popPose(); super.submit(state, poseStack, submitNodeCollector, camera); } @Override public PaintingRenderState createRenderState() { return new PaintingRenderState(); } @Override public void extractRenderState(Painting entity, PaintingRenderState state, float partialTicks) { super.extractRenderState(entity, state, partialTicks); Direction direction = entity.getDirection(); PaintingVariant variant = entity.getVariant().value(); state.direction = direction; state.variant = variant; int width = variant.width(); int height = variant.height(); if (state.lightCoordsPerBlock.length != width * height) { state.lightCoordsPerBlock = new int[width * height]; } float offsetX = (float)(-width) / 2.0f; float offsetY = (float)(-height) / 2.0f; Level level = entity.level(); for (int segmentY = 0; segmentY < height; ++segmentY) { for (int segmentX = 0; segmentX < width; ++segmentX) { float segmentOffsetX = (float)segmentX + offsetX + 0.5f; float segmentOffsetY = (float)segmentY + offsetY + 0.5f; int x = entity.getBlockX(); int y = Mth.floor(entity.getY() + (double)segmentOffsetY); int z = entity.getBlockZ(); switch (direction) { case NORTH: { x = Mth.floor(entity.getX() + (double)segmentOffsetX); break; } case WEST: { z = Mth.floor(entity.getZ() - (double)segmentOffsetX); break; } case SOUTH: { x = Mth.floor(entity.getX() - (double)segmentOffsetX); break; } case EAST: { z = Mth.floor(entity.getZ() + (double)segmentOffsetX); } } state.lightCoordsPerBlock[segmentX + segmentY * width] = LevelRenderer.getLightColor(level, new BlockPos(x, y, z)); } } } private void renderPainting(PoseStack poseStack, SubmitNodeCollector submitNodeCollector, RenderType renderType, int[] lightCoordsMap, int width, int height, TextureAtlasSprite front, TextureAtlasSprite back) { submitNodeCollector.submitCustomGeometry(poseStack, renderType, (pose, buffer) -> { float offsetX = (float)(-width) / 2.0f; float offsetY = (float)(-height) / 2.0f; float edgeHalfWidth = 0.03125f; float backU0 = back.getU0(); float backU1 = back.getU1(); float backV0 = back.getV0(); float backV1 = back.getV1(); float topBottomU0 = back.getU0(); float topBottomU1 = back.getU1(); float topBottomV0 = back.getV0(); float topBottomV1 = back.getV(0.0625f); float leftRightU0 = back.getU0(); float leftRightU1 = back.getU(0.0625f); float leftRightV0 = back.getV0(); float leftRightV1 = back.getV1(); double deltaU = 1.0 / (double)width; double deltaV = 1.0 / (double)height; for (int segmentX = 0; segmentX < width; ++segmentX) { for (int segmentY = 0; segmentY < height; ++segmentY) { float x0 = offsetX + (float)(segmentX + 1); float x1 = offsetX + (float)segmentX; float y0 = offsetY + (float)(segmentY + 1); float y1 = offsetY + (float)segmentY; int lightCoords = lightCoordsMap[segmentX + segmentY * width]; float frontU0 = front.getU((float)(deltaU * (double)(width - segmentX))); float frontU1 = front.getU((float)(deltaU * (double)(width - (segmentX + 1)))); float frontV0 = front.getV((float)(deltaV * (double)(height - segmentY))); float frontV1 = front.getV((float)(deltaV * (double)(height - (segmentY + 1)))); this.vertex(pose, buffer, x0, y1, frontU1, frontV0, -0.03125f, 0, 0, -1, lightCoords); this.vertex(pose, buffer, x1, y1, frontU0, frontV0, -0.03125f, 0, 0, -1, lightCoords); this.vertex(pose, buffer, x1, y0, frontU0, frontV1, -0.03125f, 0, 0, -1, lightCoords); this.vertex(pose, buffer, x0, y0, frontU1, frontV1, -0.03125f, 0, 0, -1, lightCoords); this.vertex(pose, buffer, x0, y0, backU1, backV0, 0.03125f, 0, 0, 1, lightCoords); this.vertex(pose, buffer, x1, y0, backU0, backV0, 0.03125f, 0, 0, 1, lightCoords); this.vertex(pose, buffer, x1, y1, backU0, backV1, 0.03125f, 0, 0, 1, lightCoords); this.vertex(pose, buffer, x0, y1, backU1, backV1, 0.03125f, 0, 0, 1, lightCoords); this.vertex(pose, buffer, x0, y0, topBottomU0, topBottomV0, -0.03125f, 0, 1, 0, lightCoords); this.vertex(pose, buffer, x1, y0, topBottomU1, topBottomV0, -0.03125f, 0, 1, 0, lightCoords); this.vertex(pose, buffer, x1, y0, topBottomU1, topBottomV1, 0.03125f, 0, 1, 0, lightCoords); this.vertex(pose, buffer, x0, y0, topBottomU0, topBottomV1, 0.03125f, 0, 1, 0, lightCoords); this.vertex(pose, buffer, x0, y1, topBottomU0, topBottomV0, 0.03125f, 0, -1, 0, lightCoords); this.vertex(pose, buffer, x1, y1, topBottomU1, topBottomV0, 0.03125f, 0, -1, 0, lightCoords); this.vertex(pose, buffer, x1, y1, topBottomU1, topBottomV1, -0.03125f, 0, -1, 0, lightCoords); this.vertex(pose, buffer, x0, y1, topBottomU0, topBottomV1, -0.03125f, 0, -1, 0, lightCoords); this.vertex(pose, buffer, x0, y0, leftRightU1, leftRightV0, 0.03125f, -1, 0, 0, lightCoords); this.vertex(pose, buffer, x0, y1, leftRightU1, leftRightV1, 0.03125f, -1, 0, 0, lightCoords); this.vertex(pose, buffer, x0, y1, leftRightU0, leftRightV1, -0.03125f, -1, 0, 0, lightCoords); this.vertex(pose, buffer, x0, y0, leftRightU0, leftRightV0, -0.03125f, -1, 0, 0, lightCoords); this.vertex(pose, buffer, x1, y0, leftRightU1, leftRightV0, -0.03125f, 1, 0, 0, lightCoords); this.vertex(pose, buffer, x1, y1, leftRightU1, leftRightV1, -0.03125f, 1, 0, 0, lightCoords); this.vertex(pose, buffer, x1, y1, leftRightU0, leftRightV1, 0.03125f, 1, 0, 0, lightCoords); this.vertex(pose, buffer, x1, y0, leftRightU0, leftRightV0, 0.03125f, 1, 0, 0, lightCoords); } } }); } private void vertex(PoseStack.Pose pose, VertexConsumer buffer, float x, float y, float u, float v, float z, int nx, int ny, int nz, int lightCoords) { buffer.addVertex(pose, x, y, z).setColor(-1).setUv(u, v).setOverlay(OverlayTexture.NO_OVERLAY).setLight(lightCoords).setNormal(pose, nx, ny, nz); } }