180 lines
7.9 KiB
Java
180 lines
7.9 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.EntityRendererProvider.Context;
|
|
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(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 minecartRenderState, PoseStack poseStack, MultiBufferSource multiBufferSource, int i) {
|
|
super.render(minecartRenderState, poseStack, multiBufferSource, i);
|
|
poseStack.pushPose();
|
|
long l = minecartRenderState.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 (minecartRenderState.isNewRender) {
|
|
newRender(minecartRenderState, poseStack);
|
|
} else {
|
|
oldRender(minecartRenderState, poseStack);
|
|
}
|
|
|
|
float j = minecartRenderState.hurtTime;
|
|
if (j > 0.0F) {
|
|
poseStack.mulPose(Axis.XP.rotationDegrees(Mth.sin(j) * j * minecartRenderState.damageTime / 10.0F * minecartRenderState.hurtDir));
|
|
}
|
|
|
|
BlockState blockState = minecartRenderState.displayBlockState;
|
|
if (blockState.getRenderShape() != RenderShape.INVISIBLE) {
|
|
poseStack.pushPose();
|
|
poseStack.scale(0.75F, 0.75F, 0.75F);
|
|
poseStack.translate(-0.5F, (minecartRenderState.displayOffset - 8) / 16.0F, 0.5F);
|
|
poseStack.mulPose(Axis.YP.rotationDegrees(90.0F));
|
|
this.renderMinecartContents(minecartRenderState, blockState, poseStack, multiBufferSource, i);
|
|
poseStack.popPose();
|
|
}
|
|
|
|
poseStack.scale(-1.0F, -1.0F, 1.0F);
|
|
this.model.setupAnim(minecartRenderState);
|
|
VertexConsumer vertexConsumer = multiBufferSource.getBuffer(this.model.renderType(MINECART_LOCATION));
|
|
this.model.renderToBuffer(poseStack, vertexConsumer, i, 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 abstractMinecart, S minecartRenderState, float f) {
|
|
super.extractRenderState(abstractMinecart, minecartRenderState, f);
|
|
if (abstractMinecart.getBehavior() instanceof NewMinecartBehavior newMinecartBehavior) {
|
|
newExtractState(abstractMinecart, newMinecartBehavior, minecartRenderState, f);
|
|
minecartRenderState.isNewRender = true;
|
|
} else if (abstractMinecart.getBehavior() instanceof OldMinecartBehavior oldMinecartBehavior) {
|
|
oldExtractState(abstractMinecart, oldMinecartBehavior, minecartRenderState, f);
|
|
minecartRenderState.isNewRender = false;
|
|
}
|
|
|
|
long l = abstractMinecart.getId() * 493286711L;
|
|
minecartRenderState.offsetSeed = l * l * 4392167121L + l * 98761L;
|
|
minecartRenderState.hurtTime = abstractMinecart.getHurtTime() - f;
|
|
minecartRenderState.hurtDir = abstractMinecart.getHurtDir();
|
|
minecartRenderState.damageTime = Math.max(abstractMinecart.getDamage() - f, 0.0F);
|
|
minecartRenderState.displayOffset = abstractMinecart.getDisplayOffset();
|
|
minecartRenderState.displayBlockState = abstractMinecart.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 abstractMinecart) {
|
|
AABB aABB = super.getBoundingBoxForCulling(abstractMinecart);
|
|
return !abstractMinecart.getDisplayBlockState().isAir() ? aABB.expandTowards(0.0, abstractMinecart.getDisplayOffset() * 0.75F / 16.0F, 0.0) : aABB;
|
|
}
|
|
|
|
public Vec3 getRenderOffset(S minecartRenderState) {
|
|
Vec3 vec3 = super.getRenderOffset(minecartRenderState);
|
|
return minecartRenderState.isNewRender && minecartRenderState.renderPos != null
|
|
? vec3.add(
|
|
minecartRenderState.renderPos.x - minecartRenderState.x,
|
|
minecartRenderState.renderPos.y - minecartRenderState.y,
|
|
minecartRenderState.renderPos.z - minecartRenderState.z
|
|
)
|
|
: vec3;
|
|
}
|
|
}
|