SkullBlockRenderer.java

net.minecraft.client.renderer.blockentity.SkullBlockRenderer

信息

  • 全限定名:net.minecraft.client.renderer.blockentity.SkullBlockRenderer
  • 类型:public class
  • 包:net.minecraft.client.renderer.blockentity
  • 源码路径:src/main/java/net/minecraft/client/renderer/blockentity/SkullBlockRenderer.java
  • 起始行号:L42
  • 实现:BlockEntityRenderer<SkullBlockEntity,SkullBlockRenderState>
  • 职责:

    TODO

字段/常量

  • TRANSFORMATIONS

    • 类型: WallAndGroundTransformations<Transformation>
    • 修饰符: public static final
    • 源码定位: L43
    • 说明:

      TODO

  • modelByType

    • 类型: Function<SkullBlock.Type,SkullModelBase>
    • 修饰符: private final
    • 源码定位: L46
    • 说明:

      TODO

  • SKIN_BY_TYPE

    • 类型: Map<SkullBlock.Type,Identifier>
    • 修饰符: private static final
    • 源码定位: L47
    • 说明:

      TODO

  • playerSkinRenderCache

    • 类型: PlayerSkinRenderCache
    • 修饰符: private final
    • 源码定位: L56
    • 说明:

      TODO

内部类/嵌套类型

构造器

public SkullBlockRenderer(BlockEntityRendererProvider.Context context) @ L74

  • 构造器名:SkullBlockRenderer
  • 源码定位:L74
  • 修饰符:public

参数:

  • context: BlockEntityRendererProvider.Context

说明:

TODO

方法

下面的方法块按源码顺序生成。

public static SkullModelBase createModel(EntityModelSet modelSet, SkullBlock.Type type) @ L58

  • 方法名:createModel
  • 源码定位:L58
  • 返回类型:SkullModelBase
  • 修饰符:public static

参数:

  • modelSet: EntityModelSet
  • type: SkullBlock.Type

说明:

TODO

public SkullBlockRenderState createRenderState() @ L80

  • 方法名:createRenderState
  • 源码定位:L80
  • 返回类型:SkullBlockRenderState
  • 修饰符:public

参数:

说明:

TODO

public void extractRenderState(SkullBlockEntity blockEntity, SkullBlockRenderState state, float partialTicks, Vec3 cameraPosition, ModelFeatureRenderer.CrumblingOverlay breakProgress) @ L84

  • 方法名:extractRenderState
  • 源码定位:L84
  • 返回类型:void
  • 修饰符:public

参数:

  • blockEntity: SkullBlockEntity
  • state: SkullBlockRenderState
  • partialTicks: float
  • cameraPosition: Vec3
  • breakProgress: ModelFeatureRenderer.CrumblingOverlay

说明:

TODO

public void submit(SkullBlockRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) @ L105

  • 方法名:submit
  • 源码定位:L105
  • 返回类型:void
  • 修饰符:public

参数:

  • state: SkullBlockRenderState
  • poseStack: PoseStack
  • submitNodeCollector: SubmitNodeCollector
  • camera: CameraRenderState

说明:

TODO

public static void submitSkull(float animationValue, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, int lightCoords, SkullModelBase model, RenderType renderType, int outlineColor, ModelFeatureRenderer.CrumblingOverlay breakProgress) @ L113

  • 方法名:submitSkull
  • 源码定位:L113
  • 返回类型:void
  • 修饰符:public static

参数:

  • animationValue: float
  • poseStack: PoseStack
  • submitNodeCollector: SubmitNodeCollector
  • lightCoords: int
  • model: SkullModelBase
  • renderType: RenderType
  • outlineColor: int
  • breakProgress: ModelFeatureRenderer.CrumblingOverlay

说明:

TODO

private RenderType resolveSkullRenderType(SkullBlock.Type type, SkullBlockEntity entity) @ L128

  • 方法名:resolveSkullRenderType
  • 源码定位:L128
  • 返回类型:RenderType
  • 修饰符:private

参数:

  • type: SkullBlock.Type
  • entity: SkullBlockEntity

说明:

TODO

public static RenderType getSkullRenderType(SkullBlock.Type type, Identifier texture) @ L139

  • 方法名:getSkullRenderType
  • 源码定位:L139
  • 返回类型:RenderType
  • 修饰符:public static

参数:

  • type: SkullBlock.Type
  • texture: Identifier

说明:

TODO

public static RenderType getPlayerSkinRenderType(Identifier texture) @ L143

  • 方法名:getPlayerSkinRenderType
  • 源码定位:L143
  • 返回类型:RenderType
  • 修饰符:public static

参数:

  • texture: Identifier

说明:

TODO

private static Transformation createWallTransformation(Direction wallDirection) @ L147

  • 方法名:createWallTransformation
  • 源码定位:L147
  • 返回类型:Transformation
  • 修饰符:private static

参数:

  • wallDirection: Direction

说明:

TODO

private static Transformation createGroundTransformation(int segment) @ L157

  • 方法名:createGroundTransformation
  • 源码定位:L157
  • 返回类型:Transformation
  • 修饰符:private static

参数:

  • segment: int

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class SkullBlockRenderer implements BlockEntityRenderer<SkullBlockEntity, SkullBlockRenderState> {
    public static final WallAndGroundTransformations<Transformation> TRANSFORMATIONS = new WallAndGroundTransformations<>(
        SkullBlockRenderer::createWallTransformation, SkullBlockRenderer::createGroundTransformation, 16
    );
    private final Function<SkullBlock.Type, SkullModelBase> modelByType;
    private static final Map<SkullBlock.Type, Identifier> SKIN_BY_TYPE = Util.make(Maps.newHashMap(), map -> {
        map.put(SkullBlock.Types.SKELETON, Identifier.withDefaultNamespace("textures/entity/skeleton/skeleton.png"));
        map.put(SkullBlock.Types.WITHER_SKELETON, Identifier.withDefaultNamespace("textures/entity/skeleton/wither_skeleton.png"));
        map.put(SkullBlock.Types.ZOMBIE, Identifier.withDefaultNamespace("textures/entity/zombie/zombie.png"));
        map.put(SkullBlock.Types.CREEPER, Identifier.withDefaultNamespace("textures/entity/creeper/creeper.png"));
        map.put(SkullBlock.Types.DRAGON, Identifier.withDefaultNamespace("textures/entity/enderdragon/dragon.png"));
        map.put(SkullBlock.Types.PIGLIN, Identifier.withDefaultNamespace("textures/entity/piglin/piglin.png"));
        map.put(SkullBlock.Types.PLAYER, DefaultPlayerSkin.getDefaultTexture());
    });
    private final PlayerSkinRenderCache playerSkinRenderCache;
 
    public static @Nullable SkullModelBase createModel(EntityModelSet modelSet, SkullBlock.Type type) {
        if (type instanceof SkullBlock.Types vanillaType) {
            return (SkullModelBase)(switch (vanillaType) {
                case SKELETON -> new SkullModel(modelSet.bakeLayer(ModelLayers.SKELETON_SKULL));
                case WITHER_SKELETON -> new SkullModel(modelSet.bakeLayer(ModelLayers.WITHER_SKELETON_SKULL));
                case PLAYER -> new SkullModel(modelSet.bakeLayer(ModelLayers.PLAYER_HEAD));
                case ZOMBIE -> new SkullModel(modelSet.bakeLayer(ModelLayers.ZOMBIE_HEAD));
                case CREEPER -> new SkullModel(modelSet.bakeLayer(ModelLayers.CREEPER_HEAD));
                case DRAGON -> new DragonHeadModel(modelSet.bakeLayer(ModelLayers.DRAGON_SKULL));
                case PIGLIN -> new PiglinHeadModel(modelSet.bakeLayer(ModelLayers.PIGLIN_HEAD));
            });
        } else {
            return null;
        }
    }
 
    public SkullBlockRenderer(BlockEntityRendererProvider.Context context) {
        EntityModelSet modelSet = context.entityModelSet();
        this.playerSkinRenderCache = context.playerSkinRenderCache();
        this.modelByType = Util.memoize(type -> createModel(modelSet, type));
    }
 
    public SkullBlockRenderState createRenderState() {
        return new SkullBlockRenderState();
    }
 
    public void extractRenderState(
        SkullBlockEntity blockEntity,
        SkullBlockRenderState state,
        float partialTicks,
        Vec3 cameraPosition,
        ModelFeatureRenderer.@Nullable CrumblingOverlay breakProgress
    ) {
        BlockEntityRenderer.super.extractRenderState(blockEntity, state, partialTicks, cameraPosition, breakProgress);
        state.animationProgress = blockEntity.getAnimation(partialTicks);
        BlockState blockState = blockEntity.getBlockState();
        if (blockState.getBlock() instanceof WallSkullBlock) {
            Direction facing = blockState.getValue(WallSkullBlock.FACING);
            state.transformation = TRANSFORMATIONS.wallTransformation(facing);
        } else {
            state.transformation = TRANSFORMATIONS.freeTransformations(blockState.getValue(SkullBlock.ROTATION));
        }
 
        state.skullType = ((AbstractSkullBlock)blockState.getBlock()).getType();
        state.renderType = this.resolveSkullRenderType(state.skullType, blockEntity);
    }
 
    public void submit(SkullBlockRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) {
        SkullModelBase model = this.modelByType.apply(state.skullType);
        poseStack.pushPose();
        poseStack.mulPose(state.transformation);
        submitSkull(state.animationProgress, poseStack, submitNodeCollector, state.lightCoords, model, state.renderType, 0, state.breakProgress);
        poseStack.popPose();
    }
 
    public static void submitSkull(
        float animationValue,
        PoseStack poseStack,
        SubmitNodeCollector submitNodeCollector,
        int lightCoords,
        SkullModelBase model,
        RenderType renderType,
        int outlineColor,
        ModelFeatureRenderer.@Nullable CrumblingOverlay breakProgress
    ) {
        SkullModelBase.State modelState = new SkullModelBase.State();
        modelState.animationPos = animationValue;
        submitNodeCollector.submitModel(model, modelState, poseStack, renderType, lightCoords, OverlayTexture.NO_OVERLAY, outlineColor, breakProgress);
    }
 
    private RenderType resolveSkullRenderType(SkullBlock.Type type, SkullBlockEntity entity) {
        if (type == SkullBlock.Types.PLAYER) {
            ResolvableProfile ownerProfile = entity.getOwnerProfile();
            if (ownerProfile != null) {
                return this.playerSkinRenderCache.getOrDefault(ownerProfile).renderType();
            }
        }
 
        return getSkullRenderType(type, null);
    }
 
    public static RenderType getSkullRenderType(SkullBlock.Type type, @Nullable Identifier texture) {
        return RenderTypes.entityCutoutZOffset(texture != null ? texture : SKIN_BY_TYPE.get(type));
    }
 
    public static RenderType getPlayerSkinRenderType(Identifier texture) {
        return RenderTypes.entityTranslucent(texture);
    }
 
    private static Transformation createWallTransformation(Direction wallDirection) {
        float offset = 0.25F;
        return new Transformation(
            new Vector3f(0.5F - wallDirection.getStepX() * 0.25F, 0.25F, 0.5F - wallDirection.getStepZ() * 0.25F),
            Axis.YP.rotationDegrees(-wallDirection.getOpposite().toYRot()),
            new Vector3f(-1.0F, -1.0F, 1.0F),
            null
        );
    }
 
    private static Transformation createGroundTransformation(int segment) {
        return new Transformation(
            new Matrix4f().translation(0.5F, 0.0F, 0.5F).rotate(Axis.YP.rotationDegrees(-RotationSegment.convertToDegrees(segment))).scale(-1.0F, -1.0F, 1.0F)
        );
    }
}

引用的其他类