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

298 lines
15 KiB
Java

/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* org.joml.Matrix4f
* org.joml.Quaternionf
* org.joml.Quaternionfc
*/
package net.minecraft.client.renderer.entity;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Axis;
import com.mojang.math.Transformation;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.OrderedSubmitNodeCollector;
import net.minecraft.client.renderer.SubmitNodeCollector;
import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.client.renderer.entity.state.BlockDisplayEntityRenderState;
import net.minecraft.client.renderer.entity.state.DisplayEntityRenderState;
import net.minecraft.client.renderer.entity.state.ItemDisplayEntityRenderState;
import net.minecraft.client.renderer.entity.state.TextDisplayEntityRenderState;
import net.minecraft.client.renderer.item.ItemModelResolver;
import net.minecraft.client.renderer.rendertype.RenderTypes;
import net.minecraft.client.renderer.state.CameraRenderState;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.util.FormattedCharSequence;
import net.minecraft.world.entity.Display;
import net.minecraft.world.phys.AABB;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
import org.joml.Quaternionfc;
public abstract class DisplayRenderer<T extends Display, S, ST extends DisplayEntityRenderState>
extends EntityRenderer<T, ST> {
private final EntityRenderDispatcher entityRenderDispatcher;
protected DisplayRenderer(EntityRendererProvider.Context context) {
super(context);
this.entityRenderDispatcher = context.getEntityRenderDispatcher();
}
@Override
protected AABB getBoundingBoxForCulling(T entity) {
return ((Display)entity).getBoundingBoxForCulling();
}
@Override
protected boolean affectedByCulling(T entity) {
return ((Display)entity).affectedByCulling();
}
private static int getBrightnessOverride(Display entity) {
Display.RenderState renderState = entity.renderState();
return renderState != null ? renderState.brightnessOverride() : -1;
}
@Override
protected int getSkyLightLevel(T entity, BlockPos blockPos) {
int packedBrightnessOverride = DisplayRenderer.getBrightnessOverride(entity);
if (packedBrightnessOverride != -1) {
return LightTexture.sky(packedBrightnessOverride);
}
return super.getSkyLightLevel(entity, blockPos);
}
@Override
protected int getBlockLightLevel(T entity, BlockPos blockPos) {
int packedBrightnessOverride = DisplayRenderer.getBrightnessOverride(entity);
if (packedBrightnessOverride != -1) {
return LightTexture.block(packedBrightnessOverride);
}
return super.getBlockLightLevel(entity, blockPos);
}
@Override
protected float getShadowRadius(ST state) {
Display.RenderState renderState = ((DisplayEntityRenderState)state).renderState;
if (renderState == null) {
return 0.0f;
}
return renderState.shadowRadius().get(((DisplayEntityRenderState)state).interpolationProgress);
}
@Override
protected float getShadowStrength(ST state) {
Display.RenderState renderState = ((DisplayEntityRenderState)state).renderState;
if (renderState == null) {
return 0.0f;
}
return renderState.shadowStrength().get(((DisplayEntityRenderState)state).interpolationProgress);
}
@Override
public void submit(ST state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) {
Display.RenderState renderState = ((DisplayEntityRenderState)state).renderState;
if (renderState == null || !((DisplayEntityRenderState)state).hasSubState()) {
return;
}
float interpolationProgress = ((DisplayEntityRenderState)state).interpolationProgress;
super.submit(state, poseStack, submitNodeCollector, camera);
poseStack.pushPose();
poseStack.mulPose((Quaternionfc)this.calculateOrientation(renderState, state, new Quaternionf()));
Transformation transformation = renderState.transformation().get(interpolationProgress);
poseStack.mulPose(transformation.getMatrix());
this.submitInner(state, poseStack, submitNodeCollector, ((DisplayEntityRenderState)state).lightCoords, interpolationProgress);
poseStack.popPose();
}
private Quaternionf calculateOrientation(Display.RenderState renderState, ST state, Quaternionf output) {
return switch (renderState.billboardConstraints()) {
default -> throw new MatchException(null, null);
case Display.BillboardConstraints.FIXED -> output.rotationYXZ((float)(-Math.PI) / 180 * ((DisplayEntityRenderState)state).entityYRot, (float)Math.PI / 180 * ((DisplayEntityRenderState)state).entityXRot, 0.0f);
case Display.BillboardConstraints.HORIZONTAL -> output.rotationYXZ((float)(-Math.PI) / 180 * ((DisplayEntityRenderState)state).entityYRot, (float)Math.PI / 180 * DisplayRenderer.transformXRot(((DisplayEntityRenderState)state).cameraXRot), 0.0f);
case Display.BillboardConstraints.VERTICAL -> output.rotationYXZ((float)(-Math.PI) / 180 * DisplayRenderer.transformYRot(((DisplayEntityRenderState)state).cameraYRot), (float)Math.PI / 180 * ((DisplayEntityRenderState)state).entityXRot, 0.0f);
case Display.BillboardConstraints.CENTER -> output.rotationYXZ((float)(-Math.PI) / 180 * DisplayRenderer.transformYRot(((DisplayEntityRenderState)state).cameraYRot), (float)Math.PI / 180 * DisplayRenderer.transformXRot(((DisplayEntityRenderState)state).cameraXRot), 0.0f);
};
}
private static float transformYRot(float cameraYRot) {
return cameraYRot - 180.0f;
}
private static float transformXRot(float cameraXRot) {
return -cameraXRot;
}
private static <T extends Display> float entityYRot(T entity, float partialTicks) {
return entity.getYRot(partialTicks);
}
private static <T extends Display> float entityXRot(T entity, float partialTicks) {
return entity.getXRot(partialTicks);
}
protected abstract void submitInner(ST var1, PoseStack var2, SubmitNodeCollector var3, int var4, float var5);
@Override
public void extractRenderState(T entity, ST state, float partialTicks) {
super.extractRenderState(entity, state, partialTicks);
((DisplayEntityRenderState)state).renderState = ((Display)entity).renderState();
((DisplayEntityRenderState)state).interpolationProgress = ((Display)entity).calculateInterpolationProgress(partialTicks);
((DisplayEntityRenderState)state).entityYRot = DisplayRenderer.entityYRot(entity, partialTicks);
((DisplayEntityRenderState)state).entityXRot = DisplayRenderer.entityXRot(entity, partialTicks);
Camera camera = this.entityRenderDispatcher.camera;
((DisplayEntityRenderState)state).cameraXRot = camera.xRot();
((DisplayEntityRenderState)state).cameraYRot = camera.yRot();
}
public static class TextDisplayRenderer
extends DisplayRenderer<Display.TextDisplay, Display.TextDisplay.TextRenderState, TextDisplayEntityRenderState> {
private final Font font;
protected TextDisplayRenderer(EntityRendererProvider.Context context) {
super(context);
this.font = context.getFont();
}
@Override
public TextDisplayEntityRenderState createRenderState() {
return new TextDisplayEntityRenderState();
}
@Override
public void extractRenderState(Display.TextDisplay entity, TextDisplayEntityRenderState state, float partialTicks) {
super.extractRenderState(entity, state, partialTicks);
state.textRenderState = entity.textRenderState();
state.cachedInfo = entity.cacheDisplay(this::splitLines);
}
private Display.TextDisplay.CachedInfo splitLines(Component input, int width) {
List<FormattedCharSequence> lines = this.font.split(input, width);
ArrayList<Display.TextDisplay.CachedLine> result = new ArrayList<Display.TextDisplay.CachedLine>(lines.size());
int maxLineWidth = 0;
for (FormattedCharSequence line : lines) {
int lineWidth = this.font.width(line);
maxLineWidth = Math.max(maxLineWidth, lineWidth);
result.add(new Display.TextDisplay.CachedLine(line, lineWidth));
}
return new Display.TextDisplay.CachedInfo(result, maxLineWidth);
}
@Override
public void submitInner(TextDisplayEntityRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, int lightCoords, float interpolationProgress) {
int backgroundColor;
Display.TextDisplay.TextRenderState renderState = state.textRenderState;
byte flags = renderState.flags();
boolean seeThrough = (flags & 2) != 0;
boolean useDefaultBackground = (flags & 4) != 0;
boolean shadow = (flags & 1) != 0;
Display.TextDisplay.Align alignment = Display.TextDisplay.getAlign(flags);
byte textOpacity = (byte)renderState.textOpacity().get(interpolationProgress);
if (useDefaultBackground) {
float backgroundAlpha = Minecraft.getInstance().options.getBackgroundOpacity(0.25f);
backgroundColor = (int)(backgroundAlpha * 255.0f) << 24;
} else {
backgroundColor = renderState.backgroundColor().get(interpolationProgress);
}
float y = 0.0f;
Matrix4f pose = poseStack.last().pose();
pose.rotate((float)Math.PI, 0.0f, 1.0f, 0.0f);
pose.scale(-0.025f, -0.025f, -0.025f);
Display.TextDisplay.CachedInfo cachedInfo = state.cachedInfo;
boolean lineSpacing = true;
int lineHeight = this.font.lineHeight + 1;
int width = cachedInfo.width();
int height = cachedInfo.lines().size() * lineHeight - 1;
pose.translate(1.0f - (float)width / 2.0f, (float)(-height), 0.0f);
if (backgroundColor != 0) {
submitNodeCollector.submitCustomGeometry(poseStack, seeThrough ? RenderTypes.textBackgroundSeeThrough() : RenderTypes.textBackground(), (lambdaPose, buffer) -> {
buffer.addVertex(lambdaPose, -1.0f, -1.0f, 0.0f).setColor(backgroundColor).setLight(lightCoords);
buffer.addVertex(lambdaPose, -1.0f, (float)height, 0.0f).setColor(backgroundColor).setLight(lightCoords);
buffer.addVertex(lambdaPose, (float)width, (float)height, 0.0f).setColor(backgroundColor).setLight(lightCoords);
buffer.addVertex(lambdaPose, (float)width, -1.0f, 0.0f).setColor(backgroundColor).setLight(lightCoords);
});
}
OrderedSubmitNodeCollector textCollector = submitNodeCollector.order(backgroundColor != 0 ? 1 : 0);
for (Display.TextDisplay.CachedLine line : cachedInfo.lines()) {
float offset = switch (alignment) {
default -> throw new MatchException(null, null);
case Display.TextDisplay.Align.LEFT -> 0.0f;
case Display.TextDisplay.Align.RIGHT -> width - line.width();
case Display.TextDisplay.Align.CENTER -> (float)width / 2.0f - (float)line.width() / 2.0f;
};
textCollector.submitText(poseStack, offset, y, line.contents(), shadow, seeThrough ? Font.DisplayMode.SEE_THROUGH : Font.DisplayMode.POLYGON_OFFSET, lightCoords, textOpacity << 24 | 0xFFFFFF, 0, 0);
y += (float)lineHeight;
}
}
}
public static class ItemDisplayRenderer
extends DisplayRenderer<Display.ItemDisplay, Display.ItemDisplay.ItemRenderState, ItemDisplayEntityRenderState> {
private final ItemModelResolver itemModelResolver;
protected ItemDisplayRenderer(EntityRendererProvider.Context context) {
super(context);
this.itemModelResolver = context.getItemModelResolver();
}
@Override
public ItemDisplayEntityRenderState createRenderState() {
return new ItemDisplayEntityRenderState();
}
@Override
public void extractRenderState(Display.ItemDisplay entity, ItemDisplayEntityRenderState state, float partialTicks) {
super.extractRenderState(entity, state, partialTicks);
Display.ItemDisplay.ItemRenderState itemRenderState = entity.itemRenderState();
if (itemRenderState != null) {
this.itemModelResolver.updateForNonLiving(state.item, itemRenderState.itemStack(), itemRenderState.itemTransform(), entity);
} else {
state.item.clear();
}
}
@Override
public void submitInner(ItemDisplayEntityRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, int lightCoords, float interpolationProgress) {
if (state.item.isEmpty()) {
return;
}
poseStack.mulPose((Quaternionfc)Axis.YP.rotation((float)Math.PI));
state.item.submit(poseStack, submitNodeCollector, lightCoords, OverlayTexture.NO_OVERLAY, state.outlineColor);
}
}
public static class BlockDisplayRenderer
extends DisplayRenderer<Display.BlockDisplay, Display.BlockDisplay.BlockRenderState, BlockDisplayEntityRenderState> {
protected BlockDisplayRenderer(EntityRendererProvider.Context context) {
super(context);
}
@Override
public BlockDisplayEntityRenderState createRenderState() {
return new BlockDisplayEntityRenderState();
}
@Override
public void extractRenderState(Display.BlockDisplay entity, BlockDisplayEntityRenderState state, float partialTicks) {
super.extractRenderState(entity, state, partialTicks);
state.blockRenderState = entity.blockRenderState();
}
@Override
public void submitInner(BlockDisplayEntityRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, int lightCoords, float interpolationProgress) {
submitNodeCollector.submitBlock(poseStack, state.blockRenderState.blockState(), lightCoords, OverlayTexture.NO_OVERLAY, state.outlineColor);
}
}
}