476 lines
		
	
	
	
		
			20 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			476 lines
		
	
	
	
		
			20 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.client.renderer.entity;
 | |
| 
 | |
| import com.google.common.collect.ImmutableMap;
 | |
| import com.mojang.blaze3d.vertex.PoseStack;
 | |
| import com.mojang.blaze3d.vertex.VertexConsumer;
 | |
| import java.util.Map;
 | |
| import java.util.function.Supplier;
 | |
| import net.fabricmc.api.EnvType;
 | |
| import net.fabricmc.api.Environment;
 | |
| import net.minecraft.CrashReport;
 | |
| import net.minecraft.CrashReportCategory;
 | |
| import net.minecraft.ReportedException;
 | |
| import net.minecraft.client.Camera;
 | |
| import net.minecraft.client.Minecraft;
 | |
| import net.minecraft.client.Options;
 | |
| import net.minecraft.client.gui.Font;
 | |
| import net.minecraft.client.model.geom.EntityModelSet;
 | |
| import net.minecraft.client.player.AbstractClientPlayer;
 | |
| import net.minecraft.client.renderer.ItemInHandRenderer;
 | |
| import net.minecraft.client.renderer.LightTexture;
 | |
| import net.minecraft.client.renderer.MapRenderer;
 | |
| import net.minecraft.client.renderer.MultiBufferSource;
 | |
| import net.minecraft.client.renderer.RenderType;
 | |
| import net.minecraft.client.renderer.ShapeRenderer;
 | |
| import net.minecraft.client.renderer.Sheets;
 | |
| import net.minecraft.client.renderer.block.BlockRenderDispatcher;
 | |
| import net.minecraft.client.renderer.culling.Frustum;
 | |
| import net.minecraft.client.renderer.debug.DebugRenderer;
 | |
| import net.minecraft.client.renderer.entity.state.EntityRenderState;
 | |
| import net.minecraft.client.renderer.entity.state.HitboxRenderState;
 | |
| import net.minecraft.client.renderer.entity.state.HitboxesRenderState;
 | |
| import net.minecraft.client.renderer.entity.state.PlayerRenderState;
 | |
| import net.minecraft.client.renderer.entity.state.ServerHitboxesRenderState;
 | |
| import net.minecraft.client.renderer.item.ItemModelResolver;
 | |
| import net.minecraft.client.renderer.texture.OverlayTexture;
 | |
| import net.minecraft.client.renderer.texture.TextureAtlasSprite;
 | |
| import net.minecraft.client.renderer.texture.TextureManager;
 | |
| import net.minecraft.client.resources.PlayerSkin;
 | |
| import net.minecraft.client.resources.model.EquipmentAssetManager;
 | |
| import net.minecraft.client.resources.model.ModelBakery;
 | |
| import net.minecraft.core.BlockPos;
 | |
| import net.minecraft.resources.ResourceLocation;
 | |
| import net.minecraft.server.packs.resources.ResourceManager;
 | |
| import net.minecraft.server.packs.resources.ResourceManagerReloadListener;
 | |
| import net.minecraft.util.ARGB;
 | |
| import net.minecraft.util.Mth;
 | |
| import net.minecraft.world.entity.Entity;
 | |
| import net.minecraft.world.entity.EntityType;
 | |
| import net.minecraft.world.entity.player.Player;
 | |
| import net.minecraft.world.level.Level;
 | |
| import net.minecraft.world.level.LevelReader;
 | |
| 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.jetbrains.annotations.Nullable;
 | |
| import org.joml.Quaternionf;
 | |
| import org.joml.Vector3f;
 | |
| 
 | |
| @Environment(EnvType.CLIENT)
 | |
| public class EntityRenderDispatcher implements ResourceManagerReloadListener {
 | |
| 	private static final RenderType SHADOW_RENDER_TYPE = RenderType.entityShadow(ResourceLocation.withDefaultNamespace("textures/misc/shadow.png"));
 | |
| 	private static final float MAX_SHADOW_RADIUS = 32.0F;
 | |
| 	private static final float SHADOW_POWER_FALLOFF_Y = 0.5F;
 | |
| 	private Map<EntityType<?>, EntityRenderer<?, ?>> renderers = ImmutableMap.of();
 | |
| 	/**
 | |
| 	 * lists the various player skin types with their associated Renderer class instances.
 | |
| 	 */
 | |
| 	private Map<PlayerSkin.Model, EntityRenderer<? extends Player, ?>> playerRenderers = Map.of();
 | |
| 	public final TextureManager textureManager;
 | |
| 	private Level level;
 | |
| 	public Camera camera;
 | |
| 	private Quaternionf cameraOrientation;
 | |
| 	public Entity crosshairPickEntity;
 | |
| 	private final ItemModelResolver itemModelResolver;
 | |
| 	private final MapRenderer mapRenderer;
 | |
| 	private final BlockRenderDispatcher blockRenderDispatcher;
 | |
| 	private final ItemInHandRenderer itemInHandRenderer;
 | |
| 	private final Font font;
 | |
| 	public final Options options;
 | |
| 	private final Supplier<EntityModelSet> entityModels;
 | |
| 	private final EquipmentAssetManager equipmentAssets;
 | |
| 	private boolean shouldRenderShadow = true;
 | |
| 	private boolean renderHitBoxes;
 | |
| 
 | |
| 	public <E extends Entity> int getPackedLightCoords(E entity, float partialTicks) {
 | |
| 		return this.getRenderer(entity).getPackedLightCoords(entity, partialTicks);
 | |
| 	}
 | |
| 
 | |
| 	public EntityRenderDispatcher(
 | |
| 		Minecraft minecraft,
 | |
| 		TextureManager textureManager,
 | |
| 		ItemModelResolver itemModelResolver,
 | |
| 		ItemRenderer itemRenderer,
 | |
| 		MapRenderer mapRenderer,
 | |
| 		BlockRenderDispatcher blockRenderDispatcher,
 | |
| 		Font font,
 | |
| 		Options options,
 | |
| 		Supplier<EntityModelSet> entityModels,
 | |
| 		EquipmentAssetManager equipmentModels
 | |
| 	) {
 | |
| 		this.textureManager = textureManager;
 | |
| 		this.itemModelResolver = itemModelResolver;
 | |
| 		this.mapRenderer = mapRenderer;
 | |
| 		this.itemInHandRenderer = new ItemInHandRenderer(minecraft, this, itemRenderer, itemModelResolver);
 | |
| 		this.blockRenderDispatcher = blockRenderDispatcher;
 | |
| 		this.font = font;
 | |
| 		this.options = options;
 | |
| 		this.entityModels = entityModels;
 | |
| 		this.equipmentAssets = equipmentModels;
 | |
| 	}
 | |
| 
 | |
| 	public <T extends Entity> EntityRenderer<? super T, ?> getRenderer(T entity) {
 | |
| 		if (entity instanceof AbstractClientPlayer abstractClientPlayer) {
 | |
| 			PlayerSkin.Model model = abstractClientPlayer.getSkin().model();
 | |
| 			EntityRenderer<? extends Player, ?> entityRenderer = (EntityRenderer<? extends Player, ?>)this.playerRenderers.get(model);
 | |
| 			return (EntityRenderer<? super T, ?>)(entityRenderer != null ? entityRenderer : (EntityRenderer)this.playerRenderers.get(PlayerSkin.Model.WIDE));
 | |
| 		} else {
 | |
| 			return (EntityRenderer<? super T, ?>)this.renderers.get(entity.getType());
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public <S extends EntityRenderState> EntityRenderer<?, ? super S> getRenderer(S renderState) {
 | |
| 		if (renderState instanceof PlayerRenderState playerRenderState) {
 | |
| 			PlayerSkin.Model model = playerRenderState.skin.model();
 | |
| 			EntityRenderer<? extends Player, ?> entityRenderer = (EntityRenderer<? extends Player, ?>)this.playerRenderers.get(model);
 | |
| 			return (EntityRenderer<?, ? super S>)(entityRenderer != null ? entityRenderer : (EntityRenderer)this.playerRenderers.get(PlayerSkin.Model.WIDE));
 | |
| 		} else {
 | |
| 			return (EntityRenderer<?, ? super S>)this.renderers.get(renderState.entityType);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public void prepare(Level level, Camera activeRenderInfo, Entity entity) {
 | |
| 		this.level = level;
 | |
| 		this.camera = activeRenderInfo;
 | |
| 		this.cameraOrientation = activeRenderInfo.rotation();
 | |
| 		this.crosshairPickEntity = entity;
 | |
| 	}
 | |
| 
 | |
| 	public void overrideCameraOrientation(Quaternionf cameraOrientation) {
 | |
| 		this.cameraOrientation = cameraOrientation;
 | |
| 	}
 | |
| 
 | |
| 	public void setRenderShadow(boolean renderShadow) {
 | |
| 		this.shouldRenderShadow = renderShadow;
 | |
| 	}
 | |
| 
 | |
| 	public void setRenderHitBoxes(boolean debugBoundingBox) {
 | |
| 		this.renderHitBoxes = debugBoundingBox;
 | |
| 	}
 | |
| 
 | |
| 	public boolean shouldRenderHitBoxes() {
 | |
| 		return this.renderHitBoxes;
 | |
| 	}
 | |
| 
 | |
| 	public <E extends Entity> boolean shouldRender(E entity, Frustum frustum, double camX, double camY, double camZ) {
 | |
| 		EntityRenderer<? super E, ?> entityRenderer = this.getRenderer(entity);
 | |
| 		return entityRenderer.shouldRender(entity, frustum, camX, camY, camZ);
 | |
| 	}
 | |
| 
 | |
| 	public <E extends Entity> void render(
 | |
| 		E entity, double xOffset, double yOffset, double zOffset, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight
 | |
| 	) {
 | |
| 		EntityRenderer<? super E, ?> entityRenderer = this.getRenderer(entity);
 | |
| 		this.render(entity, xOffset, yOffset, zOffset, partialTick, poseStack, bufferSource, packedLight, entityRenderer);
 | |
| 	}
 | |
| 
 | |
| 	private <E extends Entity, S extends EntityRenderState> void render(
 | |
| 		E entity,
 | |
| 		double xOffset,
 | |
| 		double yOffset,
 | |
| 		double zOffset,
 | |
| 		float partialTick,
 | |
| 		PoseStack poseStack,
 | |
| 		MultiBufferSource bufferSource,
 | |
| 		int packedLight,
 | |
| 		EntityRenderer<? super E, S> renderer
 | |
| 	) {
 | |
| 		S entityRenderState;
 | |
| 		try {
 | |
| 			entityRenderState = renderer.createRenderState(entity, partialTick);
 | |
| 		} catch (Throwable var19) {
 | |
| 			CrashReport crashReport = CrashReport.forThrowable(var19, "Extracting render state for an entity in world");
 | |
| 			CrashReportCategory crashReportCategory = crashReport.addCategory("Entity being extracted");
 | |
| 			entity.fillCrashReportCategory(crashReportCategory);
 | |
| 			CrashReportCategory crashReportCategory2 = this.fillRendererDetails(xOffset, yOffset, zOffset, renderer, crashReport);
 | |
| 			crashReportCategory2.setDetail("Delta", partialTick);
 | |
| 			throw new ReportedException(crashReport);
 | |
| 		}
 | |
| 
 | |
| 		try {
 | |
| 			this.render(entityRenderState, xOffset, yOffset, zOffset, poseStack, bufferSource, packedLight, renderer);
 | |
| 		} catch (Throwable var18) {
 | |
| 			CrashReport crashReport = CrashReport.forThrowable(var18, "Rendering entity in world");
 | |
| 			CrashReportCategory crashReportCategory = crashReport.addCategory("Entity being rendered");
 | |
| 			entity.fillCrashReportCategory(crashReportCategory);
 | |
| 			throw new ReportedException(crashReport);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public <S extends EntityRenderState> void render(
 | |
| 		S renderState, double xOffset, double yOffset, double zOffset, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight
 | |
| 	) {
 | |
| 		EntityRenderer<?, ? super S> entityRenderer = this.getRenderer(renderState);
 | |
| 		this.render(renderState, xOffset, yOffset, zOffset, poseStack, bufferSource, packedLight, entityRenderer);
 | |
| 	}
 | |
| 
 | |
| 	private <S extends EntityRenderState> void render(
 | |
| 		S renderState,
 | |
| 		double xOffset,
 | |
| 		double yOffset,
 | |
| 		double zOffset,
 | |
| 		PoseStack poseStack,
 | |
| 		MultiBufferSource bufferSource,
 | |
| 		int packedLight,
 | |
| 		EntityRenderer<?, S> renderer
 | |
| 	) {
 | |
| 		try {
 | |
| 			Vec3 vec3 = renderer.getRenderOffset(renderState);
 | |
| 			double d = xOffset + vec3.x();
 | |
| 			double e = yOffset + vec3.y();
 | |
| 			double f = zOffset + vec3.z();
 | |
| 			poseStack.pushPose();
 | |
| 			poseStack.translate(d, e, f);
 | |
| 			renderer.render(renderState, poseStack, bufferSource, packedLight);
 | |
| 			if (renderState.displayFireAnimation) {
 | |
| 				this.renderFlame(poseStack, bufferSource, renderState, Mth.rotationAroundAxis(Mth.Y_AXIS, this.cameraOrientation, new Quaternionf()));
 | |
| 			}
 | |
| 
 | |
| 			if (renderState instanceof PlayerRenderState) {
 | |
| 				poseStack.translate(-vec3.x(), -vec3.y(), -vec3.z());
 | |
| 			}
 | |
| 
 | |
| 			if (this.options.entityShadows().get() && this.shouldRenderShadow && !renderState.isInvisible) {
 | |
| 				float g = renderer.getShadowRadius(renderState);
 | |
| 				if (g > 0.0F) {
 | |
| 					double h = renderState.distanceToCameraSq;
 | |
| 					float i = (float)((1.0 - h / 256.0) * renderer.getShadowStrength(renderState));
 | |
| 					if (i > 0.0F) {
 | |
| 						renderShadow(poseStack, bufferSource, renderState, i, this.level, Math.min(g, 32.0F));
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			if (!(renderState instanceof PlayerRenderState)) {
 | |
| 				poseStack.translate(-vec3.x(), -vec3.y(), -vec3.z());
 | |
| 			}
 | |
| 
 | |
| 			if (renderState.hitboxesRenderState != null) {
 | |
| 				this.renderHitboxes(poseStack, renderState, renderState.hitboxesRenderState, bufferSource);
 | |
| 			}
 | |
| 
 | |
| 			poseStack.popPose();
 | |
| 		} catch (Throwable var23) {
 | |
| 			CrashReport crashReport = CrashReport.forThrowable(var23, "Rendering entity in world");
 | |
| 			CrashReportCategory crashReportCategory = crashReport.addCategory("EntityRenderState being rendered");
 | |
| 			renderState.fillCrashReportCategory(crashReportCategory);
 | |
| 			this.fillRendererDetails(xOffset, yOffset, zOffset, renderer, crashReport);
 | |
| 			throw new ReportedException(crashReport);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private <S extends EntityRenderState> CrashReportCategory fillRendererDetails(
 | |
| 		double xOffset, double yOffset, double zOffset, EntityRenderer<?, S> renderer, CrashReport crashReport
 | |
| 	) {
 | |
| 		CrashReportCategory crashReportCategory = crashReport.addCategory("Renderer details");
 | |
| 		crashReportCategory.setDetail("Assigned renderer", renderer);
 | |
| 		crashReportCategory.setDetail("Location", CrashReportCategory.formatLocation(this.level, xOffset, yOffset, zOffset));
 | |
| 		return crashReportCategory;
 | |
| 	}
 | |
| 
 | |
| 	private void renderHitboxes(PoseStack poseStack, EntityRenderState renderState, HitboxesRenderState hitboxesRenderState, MultiBufferSource bufferSource) {
 | |
| 		VertexConsumer vertexConsumer = bufferSource.getBuffer(RenderType.lines());
 | |
| 		renderHitboxesAndViewVector(poseStack, hitboxesRenderState, vertexConsumer, renderState.eyeHeight);
 | |
| 		ServerHitboxesRenderState serverHitboxesRenderState = renderState.serverHitboxesRenderState;
 | |
| 		if (serverHitboxesRenderState != null) {
 | |
| 			if (serverHitboxesRenderState.missing()) {
 | |
| 				HitboxRenderState hitboxRenderState = (HitboxRenderState)hitboxesRenderState.hitboxes().getFirst();
 | |
| 				DebugRenderer.renderFloatingText(poseStack, bufferSource, "Missing", renderState.x, hitboxRenderState.y1() + 1.5, renderState.z, -65536);
 | |
| 			} else if (serverHitboxesRenderState.hitboxes() != null) {
 | |
| 				poseStack.pushPose();
 | |
| 				poseStack.translate(
 | |
| 					serverHitboxesRenderState.serverEntityX() - renderState.x,
 | |
| 					serverHitboxesRenderState.serverEntityY() - renderState.y,
 | |
| 					serverHitboxesRenderState.serverEntityZ() - renderState.z
 | |
| 				);
 | |
| 				renderHitboxesAndViewVector(poseStack, serverHitboxesRenderState.hitboxes(), vertexConsumer, serverHitboxesRenderState.eyeHeight());
 | |
| 				Vec3 vec3 = new Vec3(serverHitboxesRenderState.deltaMovementX(), serverHitboxesRenderState.deltaMovementY(), serverHitboxesRenderState.deltaMovementZ());
 | |
| 				ShapeRenderer.renderVector(poseStack, vertexConsumer, new Vector3f(), vec3, -256);
 | |
| 				poseStack.popPose();
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private static void renderHitboxesAndViewVector(PoseStack poseStack, HitboxesRenderState hitboxesRenderState, VertexConsumer consumer, float eyeHeight) {
 | |
| 		for (HitboxRenderState hitboxRenderState : hitboxesRenderState.hitboxes()) {
 | |
| 			renderHitbox(poseStack, consumer, hitboxRenderState);
 | |
| 		}
 | |
| 
 | |
| 		Vec3 vec3 = new Vec3(hitboxesRenderState.viewX(), hitboxesRenderState.viewY(), hitboxesRenderState.viewZ());
 | |
| 		ShapeRenderer.renderVector(poseStack, consumer, new Vector3f(0.0F, eyeHeight, 0.0F), vec3.scale(2.0), -16776961);
 | |
| 	}
 | |
| 
 | |
| 	private static void renderHitbox(PoseStack posStack, VertexConsumer consumer, HitboxRenderState hitbox) {
 | |
| 		posStack.pushPose();
 | |
| 		posStack.translate(hitbox.offsetX(), hitbox.offsetY(), hitbox.offsetZ());
 | |
| 		ShapeRenderer.renderLineBox(
 | |
| 			posStack, consumer, hitbox.x0(), hitbox.y0(), hitbox.z0(), hitbox.x1(), hitbox.y1(), hitbox.z1(), hitbox.red(), hitbox.green(), hitbox.blue(), 1.0F
 | |
| 		);
 | |
| 		posStack.popPose();
 | |
| 	}
 | |
| 
 | |
| 	private void renderFlame(PoseStack poseStack, MultiBufferSource bufferSource, EntityRenderState renderState, Quaternionf quaternion) {
 | |
| 		TextureAtlasSprite textureAtlasSprite = ModelBakery.FIRE_0.sprite();
 | |
| 		TextureAtlasSprite textureAtlasSprite2 = ModelBakery.FIRE_1.sprite();
 | |
| 		poseStack.pushPose();
 | |
| 		float f = renderState.boundingBoxWidth * 1.4F;
 | |
| 		poseStack.scale(f, f, f);
 | |
| 		float g = 0.5F;
 | |
| 		float h = 0.0F;
 | |
| 		float i = renderState.boundingBoxHeight / f;
 | |
| 		float j = 0.0F;
 | |
| 		poseStack.mulPose(quaternion);
 | |
| 		poseStack.translate(0.0F, 0.0F, 0.3F - (int)i * 0.02F);
 | |
| 		float k = 0.0F;
 | |
| 		int l = 0;
 | |
| 		VertexConsumer vertexConsumer = bufferSource.getBuffer(Sheets.cutoutBlockSheet());
 | |
| 
 | |
| 		for (PoseStack.Pose pose = poseStack.last(); i > 0.0F; l++) {
 | |
| 			TextureAtlasSprite textureAtlasSprite3 = l % 2 == 0 ? textureAtlasSprite : textureAtlasSprite2;
 | |
| 			float m = textureAtlasSprite3.getU0();
 | |
| 			float n = textureAtlasSprite3.getV0();
 | |
| 			float o = textureAtlasSprite3.getU1();
 | |
| 			float p = textureAtlasSprite3.getV1();
 | |
| 			if (l / 2 % 2 == 0) {
 | |
| 				float q = o;
 | |
| 				o = m;
 | |
| 				m = q;
 | |
| 			}
 | |
| 
 | |
| 			fireVertex(pose, vertexConsumer, -g - 0.0F, 0.0F - j, k, o, p);
 | |
| 			fireVertex(pose, vertexConsumer, g - 0.0F, 0.0F - j, k, m, p);
 | |
| 			fireVertex(pose, vertexConsumer, g - 0.0F, 1.4F - j, k, m, n);
 | |
| 			fireVertex(pose, vertexConsumer, -g - 0.0F, 1.4F - j, k, o, n);
 | |
| 			i -= 0.45F;
 | |
| 			j -= 0.45F;
 | |
| 			g *= 0.9F;
 | |
| 			k -= 0.03F;
 | |
| 		}
 | |
| 
 | |
| 		poseStack.popPose();
 | |
| 	}
 | |
| 
 | |
| 	private static void fireVertex(PoseStack.Pose matrixEntry, VertexConsumer buffer, float x, float y, float z, float texU, float texV) {
 | |
| 		buffer.addVertex(matrixEntry, x, y, z).setColor(-1).setUv(texU, texV).setUv1(0, 10).setLight(240).setNormal(matrixEntry, 0.0F, 1.0F, 0.0F);
 | |
| 	}
 | |
| 
 | |
| 	private static void renderShadow(
 | |
| 		PoseStack poseStack, MultiBufferSource bufferSource, EntityRenderState renderState, float strength, LevelReader level, float size
 | |
| 	) {
 | |
| 		float f = Math.min(strength / 0.5F, size);
 | |
| 		int i = Mth.floor(renderState.x - size);
 | |
| 		int j = Mth.floor(renderState.x + size);
 | |
| 		int k = Mth.floor(renderState.y - f);
 | |
| 		int l = Mth.floor(renderState.y);
 | |
| 		int m = Mth.floor(renderState.z - size);
 | |
| 		int n = Mth.floor(renderState.z + size);
 | |
| 		PoseStack.Pose pose = poseStack.last();
 | |
| 		VertexConsumer vertexConsumer = bufferSource.getBuffer(SHADOW_RENDER_TYPE);
 | |
| 		BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
 | |
| 
 | |
| 		for (int o = m; o <= n; o++) {
 | |
| 			for (int p = i; p <= j; p++) {
 | |
| 				mutableBlockPos.set(p, 0, o);
 | |
| 				ChunkAccess chunkAccess = level.getChunk(mutableBlockPos);
 | |
| 
 | |
| 				for (int q = k; q <= l; q++) {
 | |
| 					mutableBlockPos.setY(q);
 | |
| 					float g = strength - (float)(renderState.y - mutableBlockPos.getY()) * 0.5F;
 | |
| 					renderBlockShadow(pose, vertexConsumer, chunkAccess, level, mutableBlockPos, renderState.x, renderState.y, renderState.z, size, g);
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private static void renderBlockShadow(
 | |
| 		PoseStack.Pose pose, VertexConsumer consumer, ChunkAccess chunk, LevelReader level, BlockPos pos, double x, double y, double z, float size, float weight
 | |
| 	) {
 | |
| 		BlockPos blockPos = pos.below();
 | |
| 		BlockState blockState = chunk.getBlockState(blockPos);
 | |
| 		if (blockState.getRenderShape() != RenderShape.INVISIBLE && level.getMaxLocalRawBrightness(pos) > 3) {
 | |
| 			if (blockState.isCollisionShapeFullBlock(chunk, blockPos)) {
 | |
| 				VoxelShape voxelShape = blockState.getShape(chunk, blockPos);
 | |
| 				if (!voxelShape.isEmpty()) {
 | |
| 					float f = LightTexture.getBrightness(level.dimensionType(), level.getMaxLocalRawBrightness(pos));
 | |
| 					float g = weight * 0.5F * f;
 | |
| 					if (g >= 0.0F) {
 | |
| 						if (g > 1.0F) {
 | |
| 							g = 1.0F;
 | |
| 						}
 | |
| 
 | |
| 						int i = ARGB.color(Mth.floor(g * 255.0F), 255, 255, 255);
 | |
| 						AABB aABB = voxelShape.bounds();
 | |
| 						double d = pos.getX() + aABB.minX;
 | |
| 						double e = pos.getX() + aABB.maxX;
 | |
| 						double h = pos.getY() + aABB.minY;
 | |
| 						double j = pos.getZ() + aABB.minZ;
 | |
| 						double k = pos.getZ() + aABB.maxZ;
 | |
| 						float l = (float)(d - x);
 | |
| 						float m = (float)(e - x);
 | |
| 						float n = (float)(h - y);
 | |
| 						float o = (float)(j - z);
 | |
| 						float p = (float)(k - z);
 | |
| 						float q = -l / 2.0F / size + 0.5F;
 | |
| 						float r = -m / 2.0F / size + 0.5F;
 | |
| 						float s = -o / 2.0F / size + 0.5F;
 | |
| 						float t = -p / 2.0F / size + 0.5F;
 | |
| 						shadowVertex(pose, consumer, i, l, n, o, q, s);
 | |
| 						shadowVertex(pose, consumer, i, l, n, p, q, t);
 | |
| 						shadowVertex(pose, consumer, i, m, n, p, r, t);
 | |
| 						shadowVertex(pose, consumer, i, m, n, o, r, s);
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private static void shadowVertex(PoseStack.Pose pose, VertexConsumer consumer, int color, float offsetX, float offsetY, float offsetZ, float u, float v) {
 | |
| 		Vector3f vector3f = pose.pose().transformPosition(offsetX, offsetY, offsetZ, new Vector3f());
 | |
| 		consumer.addVertex(vector3f.x(), vector3f.y(), vector3f.z(), color, u, v, OverlayTexture.NO_OVERLAY, 15728880, 0.0F, 1.0F, 0.0F);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * World sets this RenderManager's worldObj to the world provided
 | |
| 	 */
 | |
| 	public void setLevel(@Nullable Level level) {
 | |
| 		this.level = level;
 | |
| 		if (level == null) {
 | |
| 			this.camera = null;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public double distanceToSqr(Entity entity) {
 | |
| 		return this.camera.getPosition().distanceToSqr(entity.position());
 | |
| 	}
 | |
| 
 | |
| 	public double distanceToSqr(double x, double y, double z) {
 | |
| 		return this.camera.getPosition().distanceToSqr(x, y, z);
 | |
| 	}
 | |
| 
 | |
| 	public Quaternionf cameraOrientation() {
 | |
| 		return this.cameraOrientation;
 | |
| 	}
 | |
| 
 | |
| 	public ItemInHandRenderer getItemInHandRenderer() {
 | |
| 		return this.itemInHandRenderer;
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public void onResourceManagerReload(ResourceManager resourceManager) {
 | |
| 		EntityRendererProvider.Context context = new EntityRendererProvider.Context(
 | |
| 			this,
 | |
| 			this.itemModelResolver,
 | |
| 			this.mapRenderer,
 | |
| 			this.blockRenderDispatcher,
 | |
| 			resourceManager,
 | |
| 			(EntityModelSet)this.entityModels.get(),
 | |
| 			this.equipmentAssets,
 | |
| 			this.font
 | |
| 		);
 | |
| 		this.renderers = EntityRenderers.createEntityRenderers(context);
 | |
| 		this.playerRenderers = EntityRenderers.createPlayerRenderers(context);
 | |
| 	}
 | |
| }
 |