diff options
Diffstat (limited to 'src/main')
6 files changed, 76 insertions, 36 deletions
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java b/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java index 5e0995e6..fa9f6e4f 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java @@ -19,7 +19,7 @@ public class MobGlow { public static boolean shouldMobGlow(Entity entity) { Box box = entity.getBoundingBox(); - if (!entity.isInvisible() && OcclusionCulling.isVisible(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ)) { + if (!entity.isInvisible() && OcclusionCulling.getReducedCuller().isVisible(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ)) { String name = entity.getName().getString(); // Dungeons diff --git a/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java b/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java index 0f73df16..7526c0a8 100644 --- a/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java +++ b/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java @@ -60,7 +60,7 @@ public class RenderHelper { renderFilled(context, Vec3d.of(pos), dimensions, colorComponents, alpha, true); } } else { - if (OcclusionCulling.isVisible(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + dimensions.x, pos.getY() + dimensions.y, pos.getZ() + dimensions.z)) { + if (OcclusionCulling.getRegularCuller().isVisible(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + dimensions.x, pos.getY() + dimensions.y, pos.getZ() + dimensions.z)) { renderFilled(context, Vec3d.of(pos), dimensions, colorComponents, alpha, false); } } diff --git a/src/main/java/de/hysky/skyblocker/utils/render/culling/OcclusionCuller.java b/src/main/java/de/hysky/skyblocker/utils/render/culling/OcclusionCuller.java new file mode 100644 index 00000000..3c48a47e --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/render/culling/OcclusionCuller.java @@ -0,0 +1,45 @@ +package de.hysky.skyblocker.utils.render.culling; + +import com.logisticscraft.occlusionculling.OcclusionCullingInstance; +import com.logisticscraft.occlusionculling.cache.ArrayOcclusionCache; +import com.logisticscraft.occlusionculling.util.Vec3d; + +import de.hysky.skyblocker.utils.render.FrustumUtils; +import net.minecraft.client.MinecraftClient; + +public class OcclusionCuller { + private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); + + private final OcclusionCullingInstance instance; + + // Reused objects to reduce allocation overhead + private final Vec3d cameraPos = new Vec3d(0, 0, 0); + private final Vec3d min = new Vec3d(0, 0, 0); + private final Vec3d max = new Vec3d(0, 0, 0); + + OcclusionCuller(int tracingDistance, WorldProvider worldProvider, double aabbExpansion) { + this.instance = new OcclusionCullingInstance(tracingDistance, worldProvider, new ArrayOcclusionCache(tracingDistance), aabbExpansion); + } + + private void updateCameraPos() { + var camera = CLIENT.gameRenderer.getCamera().getPos(); + cameraPos.set(camera.x, camera.y, camera.z); + } + + /** + * This first checks checks if the bounding box is within the camera's FOV, if + * it is then it checks for whether it's occluded or not. + * + * @return A boolean representing whether the bounding box is fully visible or + * not as per the instance's settings. + */ + public boolean isVisible(double x1, double y1, double z1, double x2, double y2, double z2) { + if (!FrustumUtils.isVisible(x1, y1, z1, x2, y2, z2)) return false; + + updateCameraPos(); + min.set(x1, y1, z1); + max.set(x2, y2, z2); + + return instance.isAABBVisible(min, max, cameraPos); + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/render/culling/OcclusionCulling.java b/src/main/java/de/hysky/skyblocker/utils/render/culling/OcclusionCulling.java index 5f8d1592..b1ff10dd 100644 --- a/src/main/java/de/hysky/skyblocker/utils/render/culling/OcclusionCulling.java +++ b/src/main/java/de/hysky/skyblocker/utils/render/culling/OcclusionCulling.java @@ -1,47 +1,23 @@ package de.hysky.skyblocker.utils.render.culling; -import com.logisticscraft.occlusionculling.OcclusionCullingInstance; -import com.logisticscraft.occlusionculling.cache.ArrayOcclusionCache; -import com.logisticscraft.occlusionculling.util.Vec3d; -import de.hysky.skyblocker.utils.render.FrustumUtils; -import net.minecraft.client.MinecraftClient; - public class OcclusionCulling { private static final int TRACING_DISTANCE = 128; - private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); - private static OcclusionCullingInstance instance = null; - - // Reused objects to reduce allocation overhead - private static final Vec3d cameraPos = new Vec3d(0, 0, 0); - private static final Vec3d min = new Vec3d(0, 0, 0); - private static final Vec3d max = new Vec3d(0, 0, 0); + private static OcclusionCuller regularCuller = null; + private static OcclusionCuller reducedCuller = null; /** - * Initializes the occlusion culling instance + * Initializes the occlusion culling instances */ public static void init() { - instance = new OcclusionCullingInstance(TRACING_DISTANCE, new WorldProvider(), new ArrayOcclusionCache(TRACING_DISTANCE), 2); + regularCuller = new OcclusionCuller(TRACING_DISTANCE, new WorldProvider(), 2); + reducedCuller = new OcclusionCuller(TRACING_DISTANCE, new ReducedWorldProvider(), 0); } - private static void updateCameraPos() { - var camera = CLIENT.gameRenderer.getCamera().getPos(); - cameraPos.set(camera.x, camera.y, camera.z); + public static OcclusionCuller getRegularCuller() { + return regularCuller; } - /** - * This first checks checks if the bounding box is within the camera's FOV, if - * it is then it checks for whether it's occluded or not. - * - * @return A boolean representing whether the bounding box is fully visible or - * not. - */ - public static boolean isVisible(double x1, double y1, double z1, double x2, double y2, double z2) { - if (!FrustumUtils.isVisible(x1, y1, z1, x2, y2, z2)) return false; - - updateCameraPos(); - min.set(x1, y1, z1); - max.set(x2, y2, z2); - - return instance.isAABBVisible(min, max, cameraPos); + public static OcclusionCuller getReducedCuller() { + return reducedCuller; } } diff --git a/src/main/java/de/hysky/skyblocker/utils/render/culling/ReducedWorldProvider.java b/src/main/java/de/hysky/skyblocker/utils/render/culling/ReducedWorldProvider.java new file mode 100644 index 00000000..5a2b9d87 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/render/culling/ReducedWorldProvider.java @@ -0,0 +1,19 @@ +package de.hysky.skyblocker.utils.render.culling; + +import net.minecraft.block.BlockState; +import net.minecraft.registry.tag.BlockTags; +import net.minecraft.util.math.BlockPos; + +public class ReducedWorldProvider extends WorldProvider { + + @Override + public boolean isOpaqueFullCube(int x, int y, int z) { + BlockPos pos = new BlockPos(x, y, z); + BlockState state = this.world.getBlockState(pos); + + //Fixes edge cases where stairs etc aren't treated as being full blocks for the use case + boolean isException = state.isIn(BlockTags.STAIRS) || state.isIn(BlockTags.WALLS) || state.isIn(BlockTags.FENCES); + + return isException || this.world.getBlockState(pos).isOpaqueFullCube(this.world, pos); + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/render/culling/WorldProvider.java b/src/main/java/de/hysky/skyblocker/utils/render/culling/WorldProvider.java index 7ee0f0ed..1d2db238 100644 --- a/src/main/java/de/hysky/skyblocker/utils/render/culling/WorldProvider.java +++ b/src/main/java/de/hysky/skyblocker/utils/render/culling/WorldProvider.java @@ -7,7 +7,7 @@ import net.minecraft.util.math.BlockPos; public class WorldProvider implements DataProvider { private final static MinecraftClient CLIENT = MinecraftClient.getInstance(); - private ClientWorld world = null; + protected ClientWorld world = null; @Override public boolean prepareChunk(int chunkX, int chunkZ) { |