/* * Decompiled with CFR 0.152. * * Could not load the following classes: * org.jspecify.annotations.Nullable */ package net.minecraft.client.renderer.entity; import com.mojang.blaze3d.vertex.PoseStack; import java.util.ArrayList; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.SubmitNodeCollector; import net.minecraft.client.renderer.culling.Frustum; import net.minecraft.client.renderer.entity.EntityRenderDispatcher; import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.renderer.entity.state.EntityRenderState; import net.minecraft.client.renderer.state.CameraRenderState; import net.minecraft.client.server.IntegratedServer; import net.minecraft.core.BlockPos; import net.minecraft.core.Vec3i; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; import net.minecraft.util.ARGB; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityAttachment; import net.minecraft.world.entity.Leashable; import net.minecraft.world.entity.vehicle.AbstractMinecart; import net.minecraft.world.entity.vehicle.NewMinecartBehavior; import net.minecraft.world.level.Level; import net.minecraft.world.level.LightLayer; import net.minecraft.world.level.block.RenderShape; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.VoxelShape; import org.jspecify.annotations.Nullable; public abstract class EntityRenderer { private static final float SHADOW_POWER_FALLOFF_Y = 0.5f; private static final float MAX_SHADOW_RADIUS = 32.0f; public static final float NAMETAG_SCALE = 0.025f; protected final EntityRenderDispatcher entityRenderDispatcher; private final Font font; protected float shadowRadius; protected float shadowStrength = 1.0f; protected EntityRenderer(EntityRendererProvider.Context context) { this.entityRenderDispatcher = context.getEntityRenderDispatcher(); this.font = context.getFont(); } public final int getPackedLightCoords(T entity, float partialTickTime) { BlockPos blockPos = BlockPos.containing(((Entity)entity).getLightProbePosition(partialTickTime)); return LightTexture.pack(this.getBlockLightLevel(entity, blockPos), this.getSkyLightLevel(entity, blockPos)); } protected int getSkyLightLevel(T entity, BlockPos blockPos) { return ((Entity)entity).level().getBrightness(LightLayer.SKY, blockPos); } protected int getBlockLightLevel(T entity, BlockPos blockPos) { if (((Entity)entity).isOnFire()) { return 15; } return ((Entity)entity).level().getBrightness(LightLayer.BLOCK, blockPos); } public boolean shouldRender(T entity, Frustum culler, double camX, double camY, double camZ) { Leashable leashable; Entity leashHolder; if (!((Entity)entity).shouldRender(camX, camY, camZ)) { return false; } if (!this.affectedByCulling(entity)) { return true; } AABB boundingBox = this.getBoundingBoxForCulling(entity).inflate(0.5); if (boundingBox.hasNaN() || boundingBox.getSize() == 0.0) { boundingBox = new AABB(((Entity)entity).getX() - 2.0, ((Entity)entity).getY() - 2.0, ((Entity)entity).getZ() - 2.0, ((Entity)entity).getX() + 2.0, ((Entity)entity).getY() + 2.0, ((Entity)entity).getZ() + 2.0); } if (culler.isVisible(boundingBox)) { return true; } if (entity instanceof Leashable && (leashHolder = (leashable = (Leashable)entity).getLeashHolder()) != null) { AABB leasherBox = this.entityRenderDispatcher.getRenderer(leashHolder).getBoundingBoxForCulling(leashHolder); return culler.isVisible(leasherBox) || culler.isVisible(boundingBox.minmax(leasherBox)); } return false; } protected AABB getBoundingBoxForCulling(T entity) { return ((Entity)entity).getBoundingBox(); } protected boolean affectedByCulling(T entity) { return true; } public Vec3 getRenderOffset(S state) { if (((EntityRenderState)state).passengerOffset != null) { return ((EntityRenderState)state).passengerOffset; } return Vec3.ZERO; } public void submit(S state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) { if (((EntityRenderState)state).leashStates != null) { for (EntityRenderState.LeashState leashState : ((EntityRenderState)state).leashStates) { submitNodeCollector.submitLeash(poseStack, leashState); } } this.submitNameTag(state, poseStack, submitNodeCollector, camera); } protected boolean shouldShowName(T entity, double distanceToCameraSq) { return ((Entity)entity).shouldShowName() || ((Entity)entity).hasCustomName() && entity == this.entityRenderDispatcher.crosshairPickEntity; } public Font getFont() { return this.font; } protected void submitNameTag(S state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) { if (((EntityRenderState)state).nameTag != null) { submitNodeCollector.submitNameTag(poseStack, ((EntityRenderState)state).nameTagAttachment, 0, ((EntityRenderState)state).nameTag, !((EntityRenderState)state).isDiscrete, ((EntityRenderState)state).lightCoords, ((EntityRenderState)state).distanceToCameraSq, camera); } } protected @Nullable Component getNameTag(T entity) { return ((Entity)entity).getDisplayName(); } protected float getShadowRadius(S state) { return this.shadowRadius; } protected float getShadowStrength(S state) { return this.shadowStrength; } public abstract S createRenderState(); public final S createRenderState(T entity, float partialTicks) { S state = this.createRenderState(); this.extractRenderState(entity, state, partialTicks); this.finalizeRenderState(entity, state); return state; } public void extractRenderState(T entity, S state, float partialTicks) { Leashable leashable; Entity entity2; NewMinecartBehavior behavior; AbstractMinecart minecart; Object object; ((EntityRenderState)state).entityType = ((Entity)entity).getType(); ((EntityRenderState)state).x = Mth.lerp((double)partialTicks, ((Entity)entity).xOld, ((Entity)entity).getX()); ((EntityRenderState)state).y = Mth.lerp((double)partialTicks, ((Entity)entity).yOld, ((Entity)entity).getY()); ((EntityRenderState)state).z = Mth.lerp((double)partialTicks, ((Entity)entity).zOld, ((Entity)entity).getZ()); ((EntityRenderState)state).isInvisible = ((Entity)entity).isInvisible(); ((EntityRenderState)state).ageInTicks = (float)((Entity)entity).tickCount + partialTicks; ((EntityRenderState)state).boundingBoxWidth = ((Entity)entity).getBbWidth(); ((EntityRenderState)state).boundingBoxHeight = ((Entity)entity).getBbHeight(); ((EntityRenderState)state).eyeHeight = ((Entity)entity).getEyeHeight(); if (((Entity)entity).isPassenger() && (object = ((Entity)entity).getVehicle()) instanceof AbstractMinecart && (object = (minecart = (AbstractMinecart)object).getBehavior()) instanceof NewMinecartBehavior && (behavior = (NewMinecartBehavior)object).cartHasPosRotLerp()) { double cartLerpX = Mth.lerp((double)partialTicks, minecart.xOld, minecart.getX()); double cartLerpY = Mth.lerp((double)partialTicks, minecart.yOld, minecart.getY()); double cartLerpZ = Mth.lerp((double)partialTicks, minecart.zOld, minecart.getZ()); ((EntityRenderState)state).passengerOffset = behavior.getCartLerpPosition(partialTicks).subtract(new Vec3(cartLerpX, cartLerpY, cartLerpZ)); } else { ((EntityRenderState)state).passengerOffset = null; } if (this.entityRenderDispatcher.camera != null) { boolean shouldShowName; ((EntityRenderState)state).distanceToCameraSq = this.entityRenderDispatcher.distanceToSqr((Entity)entity); boolean bl = shouldShowName = ((EntityRenderState)state).distanceToCameraSq < 4096.0 && this.shouldShowName(entity, ((EntityRenderState)state).distanceToCameraSq); if (shouldShowName) { ((EntityRenderState)state).nameTag = this.getNameTag(entity); ((EntityRenderState)state).nameTagAttachment = ((Entity)entity).getAttachments().getNullable(EntityAttachment.NAME_TAG, 0, ((Entity)entity).getYRot(partialTicks)); } else { ((EntityRenderState)state).nameTag = null; } } ((EntityRenderState)state).isDiscrete = ((Entity)entity).isDiscrete(); Level level = ((Entity)entity).level(); if (entity instanceof Leashable && (entity2 = (leashable = (Leashable)entity).getLeashHolder()) instanceof Entity) { int leashCount; Entity roper = entity2; float entityYRot = ((Entity)entity).getPreciseBodyRotation(partialTicks) * ((float)Math.PI / 180); Vec3 attachOffset = leashable.getLeashOffset(partialTicks); BlockPos entityEyePos = BlockPos.containing(((Entity)entity).getEyePosition(partialTicks)); BlockPos roperEyePos = BlockPos.containing(roper.getEyePosition(partialTicks)); int startBlockLight = this.getBlockLightLevel(entity, entityEyePos); int endBlockLight = this.entityRenderDispatcher.getRenderer(roper).getBlockLightLevel(roper, roperEyePos); int startSkyLight = level.getBrightness(LightLayer.SKY, entityEyePos); int endSkyLight = level.getBrightness(LightLayer.SKY, roperEyePos); boolean quadConnection = roper.supportQuadLeashAsHolder() && leashable.supportQuadLeash(); int n = leashCount = quadConnection ? 4 : 1; if (((EntityRenderState)state).leashStates == null || ((EntityRenderState)state).leashStates.size() != leashCount) { ((EntityRenderState)state).leashStates = new ArrayList(leashCount); for (int i = 0; i < leashCount; ++i) { ((EntityRenderState)state).leashStates.add(new EntityRenderState.LeashState()); } } if (quadConnection) { float roperYRot = roper.getPreciseBodyRotation(partialTicks) * ((float)Math.PI / 180); Vec3 holderPos = roper.getPosition(partialTicks); Vec3[] leashableAttachmentPoints = leashable.getQuadLeashOffsets(); Vec3[] roperAttachmentPoints = roper.getQuadLeashHolderOffsets(); for (int i = 0; i < leashCount; ++i) { EntityRenderState.LeashState leashState = ((EntityRenderState)state).leashStates.get(i); leashState.offset = leashableAttachmentPoints[i].yRot(-entityYRot); leashState.start = ((Entity)entity).getPosition(partialTicks).add(leashState.offset); leashState.end = holderPos.add(roperAttachmentPoints[i].yRot(-roperYRot)); leashState.startBlockLight = startBlockLight; leashState.endBlockLight = endBlockLight; leashState.startSkyLight = startSkyLight; leashState.endSkyLight = endSkyLight; leashState.slack = false; } } else { Vec3 rotatedAttachOffset = attachOffset.yRot(-entityYRot); EntityRenderState.LeashState leashState = ((EntityRenderState)state).leashStates.getFirst(); leashState.offset = rotatedAttachOffset; leashState.start = ((Entity)entity).getPosition(partialTicks).add(rotatedAttachOffset); leashState.end = roper.getRopeHoldPosition(partialTicks); leashState.startBlockLight = startBlockLight; leashState.endBlockLight = endBlockLight; leashState.startSkyLight = startSkyLight; leashState.endSkyLight = endSkyLight; } } else { ((EntityRenderState)state).leashStates = null; } ((EntityRenderState)state).displayFireAnimation = ((Entity)entity).displayFireAnimation(); Minecraft minecraft = Minecraft.getInstance(); boolean appearsGlowing = minecraft.shouldEntityAppearGlowing((Entity)entity); ((EntityRenderState)state).outlineColor = appearsGlowing ? ARGB.opaque(((Entity)entity).getTeamColor()) : 0; ((EntityRenderState)state).lightCoords = this.getPackedLightCoords(entity, partialTicks); } protected void finalizeRenderState(T entity, S state) { Minecraft minecraft = Minecraft.getInstance(); Level level = ((Entity)entity).level(); this.extractShadow(state, minecraft, level); } private void extractShadow(S state, Minecraft minecraft, Level level) { ((EntityRenderState)state).shadowPieces.clear(); if (minecraft.options.entityShadows().get().booleanValue() && !((EntityRenderState)state).isInvisible) { double distSq; float pow; float shadowRadius; ((EntityRenderState)state).shadowRadius = shadowRadius = Math.min(this.getShadowRadius(state), 32.0f); if (shadowRadius > 0.0f && (pow = (float)((1.0 - (distSq = ((EntityRenderState)state).distanceToCameraSq) / 256.0) * (double)this.getShadowStrength(state))) > 0.0f) { int x0 = Mth.floor(((EntityRenderState)state).x - (double)shadowRadius); int x1 = Mth.floor(((EntityRenderState)state).x + (double)shadowRadius); int z0 = Mth.floor(((EntityRenderState)state).z - (double)shadowRadius); int z1 = Mth.floor(((EntityRenderState)state).z + (double)shadowRadius); float depth = Math.min(pow / 0.5f - 1.0f, shadowRadius); int y0 = Mth.floor(((EntityRenderState)state).y - (double)depth); int y1 = Mth.floor(((EntityRenderState)state).y); BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); for (int z = z0; z <= z1; ++z) { for (int x = x0; x <= x1; ++x) { pos.set(x, 0, z); ChunkAccess chunk = level.getChunk(pos); for (int y = y0; y <= y1; ++y) { pos.setY(y); this.extractShadowPiece(state, level, pow, pos, chunk); } } } } } else { ((EntityRenderState)state).shadowRadius = 0.0f; } } private void extractShadowPiece(S state, Level level, float pow, BlockPos.MutableBlockPos pos, ChunkAccess chunk) { float powerAtDepth = pow - (float)(((EntityRenderState)state).y - (double)pos.getY()) * 0.5f; Vec3i belowPos = pos.below(); BlockState belowState = chunk.getBlockState((BlockPos)belowPos); if (belowState.getRenderShape() == RenderShape.INVISIBLE) { return; } int brightness = level.getMaxLocalRawBrightness(pos); if (brightness <= 3) { return; } if (!belowState.isCollisionShapeFullBlock(chunk, (BlockPos)belowPos)) { return; } VoxelShape belowShape = belowState.getShape(chunk, (BlockPos)belowPos); if (belowShape.isEmpty()) { return; } float alpha = Mth.clamp(powerAtDepth * 0.5f * LightTexture.getBrightness(level.dimensionType(), brightness), 0.0f, 1.0f); float relativeX = (float)((double)pos.getX() - ((EntityRenderState)state).x); float relativeY = (float)((double)pos.getY() - ((EntityRenderState)state).y); float relativeZ = (float)((double)pos.getZ() - ((EntityRenderState)state).z); ((EntityRenderState)state).shadowPieces.add(new EntityRenderState.ShadowPiece(relativeX, relativeY, relativeZ, belowShape, alpha)); } private static @Nullable Entity getServerSideEntity(Entity entity) { ServerLevel level; IntegratedServer server = Minecraft.getInstance().getSingleplayerServer(); if (server != null && (level = server.getLevel(entity.level().dimension())) != null) { return level.getEntity(entity.getId()); } return null; } }