Загрузка данных


package com.smartmobculling.mixin;

import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.Camera;
import net.minecraft.client.render.WorldRenderer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.entity.Entity;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.util.math.Vec3d;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(WorldRenderer.class)
public class SmartMobCullingMixin {

    @Inject(
        method = "renderEntity",
        at = @At("HEAD"),
        cancellable = true
    )
    private void smartmobculling$skipInvisibleMobs(
            Entity entity,
            double cameraX,
            double cameraY,
            double cameraZ,
            float tickDelta,
            MatrixStack matrices,
            VertexConsumerProvider vertexConsumers,
            CallbackInfo ci
    ) {
        if (!(entity instanceof MobEntity)) {
            return;
        }

        MinecraftClient client = MinecraftClient.getInstance();

        if (client.world == null || client.player == null) {
            return;
        }

        Camera camera = client.gameRenderer.getCamera();

        Vec3d cameraPos = camera.getPos();
        Vec3d entityPos = entity.getBoundingBox().getCenter();

        Vec3d toEntity = entityPos.subtract(cameraPos);

        if (toEntity.lengthSquared() < 0.0001) {
            return;
        }

        toEntity = toEntity.normalize();

        float yaw = camera.getYaw();
        float pitch = camera.getPitch();

        double yawRad = Math.toRadians(yaw);
        double pitchRad = Math.toRadians(pitch);

        Vec3d forward = new Vec3d(
                -Math.sin(yawRad) * Math.cos(pitchRad),
                -Math.sin(pitchRad),
                Math.cos(yawRad) * Math.cos(pitchRad)
        );

        double dot = forward.dotProduct(toEntity);

        // Моб находится позади направления камеры.
        if (dot < -0.15) {
            ci.cancel();
        }
    }
}