minecraft-src/net/minecraft/client/renderer/special/PlayerHeadSpecialRenderer.java
2025-09-18 12:27:44 +00:00

121 lines
4.9 KiB
Java

package net.minecraft.client.renderer.special;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.serialization.MapCodec;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.Minecraft;
import net.minecraft.client.model.SkullModelBase;
import net.minecraft.client.model.geom.EntityModelSet;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.SkullBlockRenderer;
import net.minecraft.client.resources.DefaultPlayerSkin;
import net.minecraft.client.resources.PlayerSkin;
import net.minecraft.client.resources.SkinManager;
import net.minecraft.core.component.DataComponents;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.component.ResolvableProfile;
import net.minecraft.world.level.block.SkullBlock;
import org.jetbrains.annotations.Nullable;
import org.joml.Vector3f;
@Environment(EnvType.CLIENT)
public class PlayerHeadSpecialRenderer implements SpecialModelRenderer<PlayerHeadSpecialRenderer.PlayerHeadRenderInfo> {
private final Map<ResolvableProfile, PlayerHeadSpecialRenderer.PlayerHeadRenderInfo> updatedResolvableProfiles = new HashMap();
private final SkinManager skinManager;
private final SkullModelBase modelBase;
private final PlayerHeadSpecialRenderer.PlayerHeadRenderInfo defaultPlayerHeadRenderInfo;
PlayerHeadSpecialRenderer(SkinManager skinManager, SkullModelBase modelBase, PlayerHeadSpecialRenderer.PlayerHeadRenderInfo defaultPlayerHeadRenderInfo) {
this.skinManager = skinManager;
this.modelBase = modelBase;
this.defaultPlayerHeadRenderInfo = defaultPlayerHeadRenderInfo;
}
public void render(
@Nullable PlayerHeadSpecialRenderer.PlayerHeadRenderInfo patterns,
ItemDisplayContext displayContext,
PoseStack poseStack,
MultiBufferSource bufferSource,
int packedLight,
int packedOverlay,
boolean hasFoilType
) {
PlayerHeadSpecialRenderer.PlayerHeadRenderInfo playerHeadRenderInfo = (PlayerHeadSpecialRenderer.PlayerHeadRenderInfo)Objects.requireNonNullElse(
patterns, this.defaultPlayerHeadRenderInfo
);
RenderType renderType = playerHeadRenderInfo.renderType();
SkullBlockRenderer.renderSkull(null, 180.0F, 0.0F, poseStack, bufferSource, packedLight, this.modelBase, renderType);
}
@Override
public void getExtents(Set<Vector3f> output) {
PoseStack poseStack = new PoseStack();
poseStack.translate(0.5F, 0.0F, 0.5F);
poseStack.scale(-1.0F, -1.0F, 1.0F);
this.modelBase.root().getExtentsForGui(poseStack, output);
}
@Nullable
public PlayerHeadSpecialRenderer.PlayerHeadRenderInfo extractArgument(ItemStack stack) {
ResolvableProfile resolvableProfile = stack.get(DataComponents.PROFILE);
if (resolvableProfile == null) {
return null;
} else {
PlayerHeadSpecialRenderer.PlayerHeadRenderInfo playerHeadRenderInfo = (PlayerHeadSpecialRenderer.PlayerHeadRenderInfo)this.updatedResolvableProfiles
.get(resolvableProfile);
if (playerHeadRenderInfo != null) {
return playerHeadRenderInfo;
} else {
ResolvableProfile resolvableProfile2 = resolvableProfile.pollResolve();
return resolvableProfile2 != null ? this.createAndCacheIfTextureIsUnpacked(resolvableProfile2) : null;
}
}
}
@Nullable
private PlayerHeadSpecialRenderer.PlayerHeadRenderInfo createAndCacheIfTextureIsUnpacked(ResolvableProfile profile) {
PlayerSkin playerSkin = this.skinManager.getInsecureSkin(profile.gameProfile(), null);
if (playerSkin != null) {
PlayerHeadSpecialRenderer.PlayerHeadRenderInfo playerHeadRenderInfo = PlayerHeadSpecialRenderer.PlayerHeadRenderInfo.create(playerSkin);
this.updatedResolvableProfiles.put(profile, playerHeadRenderInfo);
return playerHeadRenderInfo;
} else {
return null;
}
}
@Environment(EnvType.CLIENT)
public record PlayerHeadRenderInfo(RenderType renderType) {
static PlayerHeadSpecialRenderer.PlayerHeadRenderInfo create(PlayerSkin skin) {
return new PlayerHeadSpecialRenderer.PlayerHeadRenderInfo(SkullBlockRenderer.getPlayerSkinRenderType(skin.texture()));
}
}
@Environment(EnvType.CLIENT)
public record Unbaked() implements SpecialModelRenderer.Unbaked {
public static final MapCodec<PlayerHeadSpecialRenderer.Unbaked> MAP_CODEC = MapCodec.unit(PlayerHeadSpecialRenderer.Unbaked::new);
@Override
public MapCodec<PlayerHeadSpecialRenderer.Unbaked> type() {
return MAP_CODEC;
}
@Nullable
@Override
public SpecialModelRenderer<?> bake(EntityModelSet modelSet) {
SkullModelBase skullModelBase = SkullBlockRenderer.createModel(modelSet, SkullBlock.Types.PLAYER);
return skullModelBase == null
? null
: new PlayerHeadSpecialRenderer(
Minecraft.getInstance().getSkinManager(), skullModelBase, PlayerHeadSpecialRenderer.PlayerHeadRenderInfo.create(DefaultPlayerSkin.getDefaultSkin())
);
}
}
}