206 lines
5.9 KiB
Java
206 lines
5.9 KiB
Java
package net.minecraft.client.renderer.blockentity;
|
|
|
|
import com.mojang.blaze3d.vertex.PoseStack;
|
|
import com.mojang.blaze3d.vertex.VertexConsumer;
|
|
import com.mojang.math.Axis;
|
|
import java.util.List;
|
|
import net.fabricmc.api.EnvType;
|
|
import net.fabricmc.api.Environment;
|
|
import net.minecraft.client.Minecraft;
|
|
import net.minecraft.client.player.LocalPlayer;
|
|
import net.minecraft.client.renderer.MultiBufferSource;
|
|
import net.minecraft.client.renderer.RenderType;
|
|
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider.Context;
|
|
import net.minecraft.client.renderer.texture.OverlayTexture;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
import net.minecraft.util.ARGB;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.world.level.block.entity.BeaconBeamOwner;
|
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
import net.minecraft.world.phys.Vec3;
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public class BeaconRenderer<T extends BlockEntity & BeaconBeamOwner> implements BlockEntityRenderer<T> {
|
|
public static final ResourceLocation BEAM_LOCATION = ResourceLocation.withDefaultNamespace("textures/entity/beacon_beam.png");
|
|
public static final int MAX_RENDER_Y = 2048;
|
|
private static final float BEAM_SCALE_THRESHOLD = 96.0F;
|
|
public static final float SOLID_BEAM_RADIUS = 0.2F;
|
|
public static final float BEAM_GLOW_RADIUS = 0.25F;
|
|
|
|
public BeaconRenderer(Context context) {
|
|
}
|
|
|
|
@Override
|
|
public void render(T blockEntity, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight, int packedOverlay, Vec3 cameraPos) {
|
|
long l = blockEntity.getLevel().getGameTime();
|
|
float f = (float)cameraPos.subtract(blockEntity.getBlockPos().getCenter()).horizontalDistance();
|
|
LocalPlayer localPlayer = Minecraft.getInstance().player;
|
|
float g = localPlayer != null && localPlayer.isScoping() ? 1.0F : Math.max(1.0F, f / 96.0F);
|
|
List<BeaconBeamOwner.Section> list = blockEntity.getBeamSections();
|
|
int i = 0;
|
|
|
|
for (int j = 0; j < list.size(); j++) {
|
|
BeaconBeamOwner.Section section = (BeaconBeamOwner.Section)list.get(j);
|
|
renderBeaconBeam(poseStack, bufferSource, partialTick, g, l, i, j == list.size() - 1 ? 2048 : section.getHeight(), section.getColor());
|
|
i += section.getHeight();
|
|
}
|
|
}
|
|
|
|
private static void renderBeaconBeam(
|
|
PoseStack poseStack, MultiBufferSource bufferSource, float partialTick, float radius, long gameTime, int yOffset, int height, int color
|
|
) {
|
|
renderBeaconBeam(poseStack, bufferSource, BEAM_LOCATION, partialTick, 1.0F, gameTime, yOffset, height, color, 0.2F * radius, 0.25F * radius);
|
|
}
|
|
|
|
public static void renderBeaconBeam(
|
|
PoseStack poseStack,
|
|
MultiBufferSource bufferSource,
|
|
ResourceLocation beamLocation,
|
|
float partialTick,
|
|
float textureScale,
|
|
long gameTime,
|
|
int yOffset,
|
|
int height,
|
|
int color,
|
|
float beamRadius,
|
|
float glowRadius
|
|
) {
|
|
int i = yOffset + height;
|
|
poseStack.pushPose();
|
|
poseStack.translate(0.5, 0.0, 0.5);
|
|
float f = Math.floorMod(gameTime, 40) + partialTick;
|
|
float g = height < 0 ? f : -f;
|
|
float h = Mth.frac(g * 0.2F - Mth.floor(g * 0.1F));
|
|
poseStack.pushPose();
|
|
poseStack.mulPose(Axis.YP.rotationDegrees(f * 2.25F - 45.0F));
|
|
float j = 0.0F;
|
|
float m = 0.0F;
|
|
float n = -beamRadius;
|
|
float o = 0.0F;
|
|
float p = 0.0F;
|
|
float q = -beamRadius;
|
|
float r = 0.0F;
|
|
float s = 1.0F;
|
|
float t = -1.0F + h;
|
|
float u = height * textureScale * (0.5F / beamRadius) + t;
|
|
renderPart(
|
|
poseStack,
|
|
bufferSource.getBuffer(RenderType.beaconBeam(beamLocation, false)),
|
|
color,
|
|
yOffset,
|
|
i,
|
|
0.0F,
|
|
beamRadius,
|
|
beamRadius,
|
|
0.0F,
|
|
n,
|
|
0.0F,
|
|
0.0F,
|
|
q,
|
|
0.0F,
|
|
1.0F,
|
|
u,
|
|
t
|
|
);
|
|
poseStack.popPose();
|
|
j = -glowRadius;
|
|
float k = -glowRadius;
|
|
m = -glowRadius;
|
|
n = -glowRadius;
|
|
r = 0.0F;
|
|
s = 1.0F;
|
|
t = -1.0F + h;
|
|
u = height * textureScale + t;
|
|
renderPart(
|
|
poseStack,
|
|
bufferSource.getBuffer(RenderType.beaconBeam(beamLocation, true)),
|
|
ARGB.color(32, color),
|
|
yOffset,
|
|
i,
|
|
j,
|
|
k,
|
|
glowRadius,
|
|
m,
|
|
n,
|
|
glowRadius,
|
|
glowRadius,
|
|
glowRadius,
|
|
0.0F,
|
|
1.0F,
|
|
u,
|
|
t
|
|
);
|
|
poseStack.popPose();
|
|
}
|
|
|
|
private static void renderPart(
|
|
PoseStack poseStack,
|
|
VertexConsumer consumer,
|
|
int color,
|
|
int minY,
|
|
int maxY,
|
|
float x1,
|
|
float z1,
|
|
float x2,
|
|
float z2,
|
|
float x3,
|
|
float z3,
|
|
float x4,
|
|
float z4,
|
|
float minU,
|
|
float maxU,
|
|
float minV,
|
|
float maxV
|
|
) {
|
|
PoseStack.Pose pose = poseStack.last();
|
|
renderQuad(pose, consumer, color, minY, maxY, x1, z1, x2, z2, minU, maxU, minV, maxV);
|
|
renderQuad(pose, consumer, color, minY, maxY, x4, z4, x3, z3, minU, maxU, minV, maxV);
|
|
renderQuad(pose, consumer, color, minY, maxY, x2, z2, x4, z4, minU, maxU, minV, maxV);
|
|
renderQuad(pose, consumer, color, minY, maxY, x3, z3, x1, z1, minU, maxU, minV, maxV);
|
|
}
|
|
|
|
private static void renderQuad(
|
|
PoseStack.Pose pose,
|
|
VertexConsumer consumer,
|
|
int color,
|
|
int minY,
|
|
int maxY,
|
|
float minX,
|
|
float minZ,
|
|
float maxX,
|
|
float maxZ,
|
|
float minU,
|
|
float maxU,
|
|
float minV,
|
|
float maxV
|
|
) {
|
|
addVertex(pose, consumer, color, maxY, minX, minZ, maxU, minV);
|
|
addVertex(pose, consumer, color, minY, minX, minZ, maxU, maxV);
|
|
addVertex(pose, consumer, color, minY, maxX, maxZ, minU, maxV);
|
|
addVertex(pose, consumer, color, maxY, maxX, maxZ, minU, minV);
|
|
}
|
|
|
|
private static void addVertex(PoseStack.Pose pose, VertexConsumer consumer, int color, int y, float x, float z, float u, float v) {
|
|
consumer.addVertex(pose, x, (float)y, z)
|
|
.setColor(color)
|
|
.setUv(u, v)
|
|
.setOverlay(OverlayTexture.NO_OVERLAY)
|
|
.setLight(15728880)
|
|
.setNormal(pose, 0.0F, 1.0F, 0.0F);
|
|
}
|
|
|
|
@Override
|
|
public boolean shouldRenderOffScreen(T blockEntity) {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public int getViewDistance() {
|
|
return Minecraft.getInstance().options.getEffectiveRenderDistance() * 16;
|
|
}
|
|
|
|
@Override
|
|
public boolean shouldRender(T blockEntity, Vec3 cameraPos) {
|
|
return Vec3.atCenterOf(blockEntity.getBlockPos()).multiply(1.0, 0.0, 1.0).closerThan(cameraPos.multiply(1.0, 0.0, 1.0), this.getViewDistance());
|
|
}
|
|
}
|