144 lines
6.1 KiB
Java
144 lines
6.1 KiB
Java
package net.minecraft.client.renderer.blockentity;
|
|
|
|
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.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.renderer.blockentity.BlockEntityRendererProvider.Context;
|
|
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;
|
|
|
|
@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(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 bannerBlockEntity, float f, PoseStack poseStack, MultiBufferSource multiBufferSource, int i, int j, Vec3 vec3) {
|
|
BlockState blockState = bannerBlockEntity.getBlockState();
|
|
BannerModel bannerModel;
|
|
BannerFlagModel bannerFlagModel;
|
|
float g;
|
|
if (blockState.getBlock() instanceof BannerBlock) {
|
|
g = -RotationSegment.convertToDegrees((Integer)blockState.getValue(BannerBlock.ROTATION));
|
|
bannerModel = this.standingModel;
|
|
bannerFlagModel = this.standingFlagModel;
|
|
} else {
|
|
g = -((Direction)blockState.getValue(WallBannerBlock.FACING)).toYRot();
|
|
bannerModel = this.wallModel;
|
|
bannerFlagModel = this.wallFlagModel;
|
|
}
|
|
|
|
long l = bannerBlockEntity.getLevel().getGameTime();
|
|
BlockPos blockPos = bannerBlockEntity.getBlockPos();
|
|
float h = ((float)Math.floorMod(blockPos.getX() * 7 + blockPos.getY() * 9 + blockPos.getZ() * 13 + l, 100L) + f) / 100.0F;
|
|
renderBanner(poseStack, multiBufferSource, i, j, g, bannerModel, bannerFlagModel, h, bannerBlockEntity.getBaseColor(), bannerBlockEntity.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);
|
|
}
|
|
}
|