156 lines
		
	
	
	
		
			6.5 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			156 lines
		
	
	
	
		
			6.5 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.client.renderer.blockentity;
 | |
| 
 | |
| import com.mojang.blaze3d.vertex.PoseStack;
 | |
| import com.mojang.math.Axis;
 | |
| import java.util.Set;
 | |
| import net.fabricmc.api.EnvType;
 | |
| import net.fabricmc.api.Environment;
 | |
| import net.minecraft.client.model.BannerFlagModel;
 | |
| import net.minecraft.client.model.BannerModel;
 | |
| import net.minecraft.client.model.geom.EntityModelSet;
 | |
| import net.minecraft.client.model.geom.ModelLayers;
 | |
| import net.minecraft.client.model.geom.ModelPart;
 | |
| import net.minecraft.client.renderer.MultiBufferSource;
 | |
| import net.minecraft.client.renderer.RenderType;
 | |
| import net.minecraft.client.renderer.Sheets;
 | |
| import net.minecraft.client.resources.model.Material;
 | |
| import net.minecraft.client.resources.model.ModelBakery;
 | |
| import net.minecraft.core.BlockPos;
 | |
| import net.minecraft.core.Direction;
 | |
| import net.minecraft.world.item.DyeColor;
 | |
| import net.minecraft.world.level.block.BannerBlock;
 | |
| import net.minecraft.world.level.block.WallBannerBlock;
 | |
| import net.minecraft.world.level.block.entity.BannerBlockEntity;
 | |
| import net.minecraft.world.level.block.entity.BannerPatternLayers;
 | |
| import net.minecraft.world.level.block.state.BlockState;
 | |
| import net.minecraft.world.level.block.state.properties.RotationSegment;
 | |
| import net.minecraft.world.phys.Vec3;
 | |
| import org.joml.Vector3f;
 | |
| 
 | |
| @Environment(EnvType.CLIENT)
 | |
| public class BannerRenderer implements BlockEntityRenderer<BannerBlockEntity> {
 | |
| 	private static final int MAX_PATTERNS = 16;
 | |
| 	private static final float SIZE = 0.6666667F;
 | |
| 	private final BannerModel standingModel;
 | |
| 	private final BannerModel wallModel;
 | |
| 	private final BannerFlagModel standingFlagModel;
 | |
| 	private final BannerFlagModel wallFlagModel;
 | |
| 
 | |
| 	public BannerRenderer(BlockEntityRendererProvider.Context context) {
 | |
| 		this(context.getModelSet());
 | |
| 	}
 | |
| 
 | |
| 	public BannerRenderer(EntityModelSet modelSet) {
 | |
| 		this.standingModel = new BannerModel(modelSet.bakeLayer(ModelLayers.STANDING_BANNER));
 | |
| 		this.wallModel = new BannerModel(modelSet.bakeLayer(ModelLayers.WALL_BANNER));
 | |
| 		this.standingFlagModel = new BannerFlagModel(modelSet.bakeLayer(ModelLayers.STANDING_BANNER_FLAG));
 | |
| 		this.wallFlagModel = new BannerFlagModel(modelSet.bakeLayer(ModelLayers.WALL_BANNER_FLAG));
 | |
| 	}
 | |
| 
 | |
| 	public void render(
 | |
| 		BannerBlockEntity blockEntity, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight, int packedOverlay, Vec3 cameraPos
 | |
| 	) {
 | |
| 		BlockState blockState = blockEntity.getBlockState();
 | |
| 		BannerModel bannerModel;
 | |
| 		BannerFlagModel bannerFlagModel;
 | |
| 		float f;
 | |
| 		if (blockState.getBlock() instanceof BannerBlock) {
 | |
| 			f = -RotationSegment.convertToDegrees((Integer)blockState.getValue(BannerBlock.ROTATION));
 | |
| 			bannerModel = this.standingModel;
 | |
| 			bannerFlagModel = this.standingFlagModel;
 | |
| 		} else {
 | |
| 			f = -((Direction)blockState.getValue(WallBannerBlock.FACING)).toYRot();
 | |
| 			bannerModel = this.wallModel;
 | |
| 			bannerFlagModel = this.wallFlagModel;
 | |
| 		}
 | |
| 
 | |
| 		long l = blockEntity.getLevel().getGameTime();
 | |
| 		BlockPos blockPos = blockEntity.getBlockPos();
 | |
| 		float g = ((float)Math.floorMod(blockPos.getX() * 7 + blockPos.getY() * 9 + blockPos.getZ() * 13 + l, 100L) + partialTick) / 100.0F;
 | |
| 		renderBanner(poseStack, bufferSource, packedLight, packedOverlay, f, bannerModel, bannerFlagModel, g, blockEntity.getBaseColor(), blockEntity.getPatterns());
 | |
| 	}
 | |
| 
 | |
| 	public void renderInHand(
 | |
| 		PoseStack poseStack, MultiBufferSource bufferSource, int packedLight, int packedOverlay, DyeColor baseColor, BannerPatternLayers patterns
 | |
| 	) {
 | |
| 		renderBanner(poseStack, bufferSource, packedLight, packedOverlay, 0.0F, this.standingModel, this.standingFlagModel, 0.0F, baseColor, patterns);
 | |
| 	}
 | |
| 
 | |
| 	private static void renderBanner(
 | |
| 		PoseStack poseStack,
 | |
| 		MultiBufferSource bufferSource,
 | |
| 		int packedLight,
 | |
| 		int packedOverlay,
 | |
| 		float rotation,
 | |
| 		BannerModel standingModel,
 | |
| 		BannerFlagModel standingFlagModel,
 | |
| 		float angle,
 | |
| 		DyeColor baseColor,
 | |
| 		BannerPatternLayers patterns
 | |
| 	) {
 | |
| 		poseStack.pushPose();
 | |
| 		poseStack.translate(0.5F, 0.0F, 0.5F);
 | |
| 		poseStack.mulPose(Axis.YP.rotationDegrees(rotation));
 | |
| 		poseStack.scale(0.6666667F, -0.6666667F, -0.6666667F);
 | |
| 		standingModel.renderToBuffer(poseStack, ModelBakery.BANNER_BASE.buffer(bufferSource, RenderType::entitySolid), packedLight, packedOverlay);
 | |
| 		standingFlagModel.setupAnim(angle);
 | |
| 		renderPatterns(poseStack, bufferSource, packedLight, packedOverlay, standingFlagModel.root(), ModelBakery.BANNER_BASE, true, baseColor, patterns);
 | |
| 		poseStack.popPose();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param banner if {@code true}, uses banner material; otherwise if {@code false} uses shield material
 | |
| 	 */
 | |
| 	public static void renderPatterns(
 | |
| 		PoseStack poseStack,
 | |
| 		MultiBufferSource bufferSource,
 | |
| 		int packedLight,
 | |
| 		int packedOverlay,
 | |
| 		ModelPart flagPart,
 | |
| 		Material flagMaterial,
 | |
| 		boolean banner,
 | |
| 		DyeColor baseColor,
 | |
| 		BannerPatternLayers patterns
 | |
| 	) {
 | |
| 		renderPatterns(poseStack, bufferSource, packedLight, packedOverlay, flagPart, flagMaterial, banner, baseColor, patterns, false, true);
 | |
| 	}
 | |
| 
 | |
| 	public static void renderPatterns(
 | |
| 		PoseStack poseStack,
 | |
| 		MultiBufferSource bufferSource,
 | |
| 		int packedLight,
 | |
| 		int packedOverlay,
 | |
| 		ModelPart flagPart,
 | |
| 		Material flagMaterial,
 | |
| 		boolean banner,
 | |
| 		DyeColor baseColor,
 | |
| 		BannerPatternLayers patterns,
 | |
| 		boolean withGlint,
 | |
| 		boolean noEntity
 | |
| 	) {
 | |
| 		flagPart.render(poseStack, flagMaterial.buffer(bufferSource, RenderType::entitySolid, noEntity, withGlint), packedLight, packedOverlay);
 | |
| 		renderPatternLayer(poseStack, bufferSource, packedLight, packedOverlay, flagPart, banner ? Sheets.BANNER_BASE : Sheets.SHIELD_BASE, baseColor);
 | |
| 
 | |
| 		for (int i = 0; i < 16 && i < patterns.layers().size(); i++) {
 | |
| 			BannerPatternLayers.Layer layer = (BannerPatternLayers.Layer)patterns.layers().get(i);
 | |
| 			Material material = banner ? Sheets.getBannerMaterial(layer.pattern()) : Sheets.getShieldMaterial(layer.pattern());
 | |
| 			renderPatternLayer(poseStack, bufferSource, packedLight, packedOverlay, flagPart, material, layer.color());
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private static void renderPatternLayer(
 | |
| 		PoseStack poseStack, MultiBufferSource buffer, int packedLight, int packedOverlay, ModelPart flagPart, Material material, DyeColor color
 | |
| 	) {
 | |
| 		int i = color.getTextureDiffuseColor();
 | |
| 		flagPart.render(poseStack, material.buffer(buffer, RenderType::entityNoOutline), packedLight, packedOverlay, i);
 | |
| 	}
 | |
| 
 | |
| 	public void getExtents(Set<Vector3f> output) {
 | |
| 		PoseStack poseStack = new PoseStack();
 | |
| 		poseStack.translate(0.5F, 0.0F, 0.5F);
 | |
| 		poseStack.scale(0.6666667F, -0.6666667F, -0.6666667F);
 | |
| 		this.standingModel.root().getExtentsForGui(poseStack, output);
 | |
| 		this.standingFlagModel.setupAnim(0.0F);
 | |
| 		this.standingFlagModel.root().getExtentsForGui(poseStack, output);
 | |
| 	}
 | |
| }
 |