2025-11-24 22:52:51 +03:00

171 lines
9.5 KiB
Java

/*
* 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<Painting, PaintingRenderState> {
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);
}
}