package net.minecraft.client.renderer.entity; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Axis; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.model.ArmorStandArmorModel; import net.minecraft.client.model.ArmorStandModel; import net.minecraft.client.model.geom.ModelLayers; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.entity.layers.CustomHeadLayer; import net.minecraft.client.renderer.entity.layers.HumanoidArmorLayer; import net.minecraft.client.renderer.entity.layers.ItemInHandLayer; import net.minecraft.client.renderer.entity.layers.WingsLayer; import net.minecraft.client.renderer.entity.state.ArmorStandRenderState; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; import net.minecraft.world.entity.decoration.ArmorStand; import org.jetbrains.annotations.Nullable; @Environment(EnvType.CLIENT) public class ArmorStandRenderer extends LivingEntityRenderer { /** * A constant instance of the armor stand texture, wrapped inside a ResourceLocation wrapper. */ public static final ResourceLocation DEFAULT_SKIN_LOCATION = ResourceLocation.withDefaultNamespace("textures/entity/armorstand/wood.png"); private final ArmorStandArmorModel bigModel = this.getModel(); private final ArmorStandArmorModel smallModel; public ArmorStandRenderer(EntityRendererProvider.Context context) { super(context, new ArmorStandModel(context.bakeLayer(ModelLayers.ARMOR_STAND)), 0.0F); this.smallModel = new ArmorStandModel(context.bakeLayer(ModelLayers.ARMOR_STAND_SMALL)); this.addLayer( new HumanoidArmorLayer<>( this, new ArmorStandArmorModel(context.bakeLayer(ModelLayers.ARMOR_STAND_INNER_ARMOR)), new ArmorStandArmorModel(context.bakeLayer(ModelLayers.ARMOR_STAND_OUTER_ARMOR)), new ArmorStandArmorModel(context.bakeLayer(ModelLayers.ARMOR_STAND_SMALL_INNER_ARMOR)), new ArmorStandArmorModel(context.bakeLayer(ModelLayers.ARMOR_STAND_SMALL_OUTER_ARMOR)), context.getEquipmentRenderer() ) ); this.addLayer(new ItemInHandLayer<>(this, context.getItemRenderer())); this.addLayer(new WingsLayer<>(this, context.getModelSet(), context.getEquipmentRenderer())); this.addLayer(new CustomHeadLayer<>(this, context.getModelSet(), context.getItemRenderer())); } public ResourceLocation getTextureLocation(ArmorStandRenderState renderState) { return DEFAULT_SKIN_LOCATION; } public ArmorStandRenderState createRenderState() { return new ArmorStandRenderState(); } public void extractRenderState(ArmorStand entity, ArmorStandRenderState reusedState, float partialTick) { super.extractRenderState(entity, reusedState, partialTick); HumanoidMobRenderer.extractHumanoidRenderState(entity, reusedState, partialTick); reusedState.yRot = Mth.rotLerp(partialTick, entity.yRotO, entity.getYRot()); reusedState.isMarker = entity.isMarker(); reusedState.isSmall = entity.isSmall(); reusedState.showArms = entity.showArms(); reusedState.showBasePlate = entity.showBasePlate(); reusedState.bodyPose = entity.getBodyPose(); reusedState.headPose = entity.getHeadPose(); reusedState.leftArmPose = entity.getLeftArmPose(); reusedState.rightArmPose = entity.getRightArmPose(); reusedState.leftLegPose = entity.getLeftLegPose(); reusedState.rightLegPose = entity.getRightLegPose(); reusedState.wiggle = (float)(entity.level().getGameTime() - entity.lastHit) + partialTick; } public void render(ArmorStandRenderState renderState, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight) { this.model = renderState.isSmall ? this.smallModel : this.bigModel; super.render(renderState, poseStack, bufferSource, packedLight); } protected void setupRotations(ArmorStandRenderState renderState, PoseStack poseStack, float bodyRot, float scale) { poseStack.mulPose(Axis.YP.rotationDegrees(180.0F - bodyRot)); if (renderState.wiggle < 5.0F) { poseStack.mulPose(Axis.YP.rotationDegrees(Mth.sin(renderState.wiggle / 1.5F * (float) Math.PI) * 3.0F)); } } protected boolean shouldShowName(ArmorStand entity, double distanceToCameraSq) { return entity.isCustomNameVisible(); } @Nullable protected RenderType getRenderType(ArmorStandRenderState renderState, boolean isVisible, boolean renderTranslucent, boolean appearsGlowing) { if (!renderState.isMarker) { return super.getRenderType(renderState, isVisible, renderTranslucent, appearsGlowing); } else { ResourceLocation resourceLocation = this.getTextureLocation(renderState); if (renderTranslucent) { return RenderType.entityTranslucent(resourceLocation, false); } else { return isVisible ? RenderType.entityCutoutNoCull(resourceLocation, false) : null; } } } }