175 lines
		
	
	
	
		
			7.5 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			175 lines
		
	
	
	
		
			7.5 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.client.renderer.entity;
 | |
| 
 | |
| import com.mojang.blaze3d.vertex.PoseStack;
 | |
| import com.mojang.blaze3d.vertex.VertexConsumer;
 | |
| import com.mojang.math.Axis;
 | |
| import java.util.Objects;
 | |
| import net.fabricmc.api.EnvType;
 | |
| import net.fabricmc.api.Environment;
 | |
| import net.minecraft.client.model.MinecartModel;
 | |
| import net.minecraft.client.model.geom.ModelLayerLocation;
 | |
| import net.minecraft.client.renderer.MultiBufferSource;
 | |
| import net.minecraft.client.renderer.block.BlockRenderDispatcher;
 | |
| import net.minecraft.client.renderer.entity.state.MinecartRenderState;
 | |
| import net.minecraft.client.renderer.texture.OverlayTexture;
 | |
| import net.minecraft.resources.ResourceLocation;
 | |
| import net.minecraft.util.Mth;
 | |
| import net.minecraft.world.entity.vehicle.AbstractMinecart;
 | |
| import net.minecraft.world.entity.vehicle.NewMinecartBehavior;
 | |
| import net.minecraft.world.entity.vehicle.OldMinecartBehavior;
 | |
| import net.minecraft.world.level.block.RenderShape;
 | |
| import net.minecraft.world.level.block.state.BlockState;
 | |
| import net.minecraft.world.phys.AABB;
 | |
| import net.minecraft.world.phys.Vec3;
 | |
| 
 | |
| @Environment(EnvType.CLIENT)
 | |
| public abstract class AbstractMinecartRenderer<T extends AbstractMinecart, S extends MinecartRenderState> extends EntityRenderer<T, S> {
 | |
| 	private static final ResourceLocation MINECART_LOCATION = ResourceLocation.withDefaultNamespace("textures/entity/minecart.png");
 | |
| 	private static final float DISPLAY_BLOCK_SCALE = 0.75F;
 | |
| 	protected final MinecartModel model;
 | |
| 	private final BlockRenderDispatcher blockRenderer;
 | |
| 
 | |
| 	public AbstractMinecartRenderer(EntityRendererProvider.Context context, ModelLayerLocation modelLayer) {
 | |
| 		super(context);
 | |
| 		this.shadowRadius = 0.7F;
 | |
| 		this.model = new MinecartModel(context.bakeLayer(modelLayer));
 | |
| 		this.blockRenderer = context.getBlockRenderDispatcher();
 | |
| 	}
 | |
| 
 | |
| 	public void render(S renderState, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight) {
 | |
| 		super.render(renderState, poseStack, bufferSource, packedLight);
 | |
| 		poseStack.pushPose();
 | |
| 		long l = renderState.offsetSeed;
 | |
| 		float f = (((float)(l >> 16 & 7L) + 0.5F) / 8.0F - 0.5F) * 0.004F;
 | |
| 		float g = (((float)(l >> 20 & 7L) + 0.5F) / 8.0F - 0.5F) * 0.004F;
 | |
| 		float h = (((float)(l >> 24 & 7L) + 0.5F) / 8.0F - 0.5F) * 0.004F;
 | |
| 		poseStack.translate(f, g, h);
 | |
| 		if (renderState.isNewRender) {
 | |
| 			newRender(renderState, poseStack);
 | |
| 		} else {
 | |
| 			oldRender(renderState, poseStack);
 | |
| 		}
 | |
| 
 | |
| 		float i = renderState.hurtTime;
 | |
| 		if (i > 0.0F) {
 | |
| 			poseStack.mulPose(Axis.XP.rotationDegrees(Mth.sin(i) * i * renderState.damageTime / 10.0F * renderState.hurtDir));
 | |
| 		}
 | |
| 
 | |
| 		BlockState blockState = renderState.displayBlockState;
 | |
| 		if (blockState.getRenderShape() != RenderShape.INVISIBLE) {
 | |
| 			poseStack.pushPose();
 | |
| 			poseStack.scale(0.75F, 0.75F, 0.75F);
 | |
| 			poseStack.translate(-0.5F, (renderState.displayOffset - 8) / 16.0F, 0.5F);
 | |
| 			poseStack.mulPose(Axis.YP.rotationDegrees(90.0F));
 | |
| 			this.renderMinecartContents(renderState, blockState, poseStack, bufferSource, packedLight);
 | |
| 			poseStack.popPose();
 | |
| 		}
 | |
| 
 | |
| 		poseStack.scale(-1.0F, -1.0F, 1.0F);
 | |
| 		this.model.setupAnim(renderState);
 | |
| 		VertexConsumer vertexConsumer = bufferSource.getBuffer(this.model.renderType(MINECART_LOCATION));
 | |
| 		this.model.renderToBuffer(poseStack, vertexConsumer, packedLight, OverlayTexture.NO_OVERLAY);
 | |
| 		poseStack.popPose();
 | |
| 	}
 | |
| 
 | |
| 	private static <S extends MinecartRenderState> void newRender(S renderState, PoseStack poseStack) {
 | |
| 		poseStack.mulPose(Axis.YP.rotationDegrees(renderState.yRot));
 | |
| 		poseStack.mulPose(Axis.ZP.rotationDegrees(-renderState.xRot));
 | |
| 		poseStack.translate(0.0F, 0.375F, 0.0F);
 | |
| 	}
 | |
| 
 | |
| 	private static <S extends MinecartRenderState> void oldRender(S renderState, PoseStack poseStack) {
 | |
| 		double d = renderState.x;
 | |
| 		double e = renderState.y;
 | |
| 		double f = renderState.z;
 | |
| 		float g = renderState.xRot;
 | |
| 		float h = renderState.yRot;
 | |
| 		if (renderState.posOnRail != null && renderState.frontPos != null && renderState.backPos != null) {
 | |
| 			Vec3 vec3 = renderState.frontPos;
 | |
| 			Vec3 vec32 = renderState.backPos;
 | |
| 			poseStack.translate(renderState.posOnRail.x - d, (vec3.y + vec32.y) / 2.0 - e, renderState.posOnRail.z - f);
 | |
| 			Vec3 vec33 = vec32.add(-vec3.x, -vec3.y, -vec3.z);
 | |
| 			if (vec33.length() != 0.0) {
 | |
| 				vec33 = vec33.normalize();
 | |
| 				h = (float)(Math.atan2(vec33.z, vec33.x) * 180.0 / Math.PI);
 | |
| 				g = (float)(Math.atan(vec33.y) * 73.0);
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		poseStack.translate(0.0F, 0.375F, 0.0F);
 | |
| 		poseStack.mulPose(Axis.YP.rotationDegrees(180.0F - h));
 | |
| 		poseStack.mulPose(Axis.ZP.rotationDegrees(-g));
 | |
| 	}
 | |
| 
 | |
| 	public void extractRenderState(T entity, S reusedState, float partialTick) {
 | |
| 		super.extractRenderState(entity, reusedState, partialTick);
 | |
| 		if (entity.getBehavior() instanceof NewMinecartBehavior newMinecartBehavior) {
 | |
| 			newExtractState(entity, newMinecartBehavior, reusedState, partialTick);
 | |
| 			reusedState.isNewRender = true;
 | |
| 		} else if (entity.getBehavior() instanceof OldMinecartBehavior oldMinecartBehavior) {
 | |
| 			oldExtractState(entity, oldMinecartBehavior, reusedState, partialTick);
 | |
| 			reusedState.isNewRender = false;
 | |
| 		}
 | |
| 
 | |
| 		long l = entity.getId() * 493286711L;
 | |
| 		reusedState.offsetSeed = l * l * 4392167121L + l * 98761L;
 | |
| 		reusedState.hurtTime = entity.getHurtTime() - partialTick;
 | |
| 		reusedState.hurtDir = entity.getHurtDir();
 | |
| 		reusedState.damageTime = Math.max(entity.getDamage() - partialTick, 0.0F);
 | |
| 		reusedState.displayOffset = entity.getDisplayOffset();
 | |
| 		reusedState.displayBlockState = entity.getDisplayBlockState();
 | |
| 	}
 | |
| 
 | |
| 	private static <T extends AbstractMinecart, S extends MinecartRenderState> void newExtractState(
 | |
| 		T minecart, NewMinecartBehavior behavior, S renderState, float partialTick
 | |
| 	) {
 | |
| 		if (behavior.cartHasPosRotLerp()) {
 | |
| 			renderState.renderPos = behavior.getCartLerpPosition(partialTick);
 | |
| 			renderState.xRot = behavior.getCartLerpXRot(partialTick);
 | |
| 			renderState.yRot = behavior.getCartLerpYRot(partialTick);
 | |
| 		} else {
 | |
| 			renderState.renderPos = null;
 | |
| 			renderState.xRot = minecart.getXRot();
 | |
| 			renderState.yRot = minecart.getYRot();
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private static <T extends AbstractMinecart, S extends MinecartRenderState> void oldExtractState(
 | |
| 		T minecart, OldMinecartBehavior behavior, S renderState, float partialTick
 | |
| 	) {
 | |
| 		float f = 0.3F;
 | |
| 		renderState.xRot = minecart.getXRot(partialTick);
 | |
| 		renderState.yRot = minecart.getYRot(partialTick);
 | |
| 		double d = renderState.x;
 | |
| 		double e = renderState.y;
 | |
| 		double g = renderState.z;
 | |
| 		Vec3 vec3 = behavior.getPos(d, e, g);
 | |
| 		if (vec3 != null) {
 | |
| 			renderState.posOnRail = vec3;
 | |
| 			Vec3 vec32 = behavior.getPosOffs(d, e, g, 0.3F);
 | |
| 			Vec3 vec33 = behavior.getPosOffs(d, e, g, -0.3F);
 | |
| 			renderState.frontPos = (Vec3)Objects.requireNonNullElse(vec32, vec3);
 | |
| 			renderState.backPos = (Vec3)Objects.requireNonNullElse(vec33, vec3);
 | |
| 		} else {
 | |
| 			renderState.posOnRail = null;
 | |
| 			renderState.frontPos = null;
 | |
| 			renderState.backPos = null;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	protected void renderMinecartContents(S renderState, BlockState state, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight) {
 | |
| 		this.blockRenderer.renderSingleBlock(state, poseStack, bufferSource, packedLight, OverlayTexture.NO_OVERLAY);
 | |
| 	}
 | |
| 
 | |
| 	protected AABB getBoundingBoxForCulling(T minecraft) {
 | |
| 		AABB aABB = super.getBoundingBoxForCulling(minecraft);
 | |
| 		return !minecraft.getDisplayBlockState().isAir() ? aABB.expandTowards(0.0, minecraft.getDisplayOffset() * 0.75F / 16.0F, 0.0) : aABB;
 | |
| 	}
 | |
| 
 | |
| 	public Vec3 getRenderOffset(S renderState) {
 | |
| 		Vec3 vec3 = super.getRenderOffset(renderState);
 | |
| 		return renderState.isNewRender && renderState.renderPos != null
 | |
| 			? vec3.add(renderState.renderPos.x - renderState.x, renderState.renderPos.y - renderState.y, renderState.renderPos.z - renderState.z)
 | |
| 			: vec3;
 | |
| 	}
 | |
| }
 |