diff --git a/src/main/java/dev/tr7zw/entityculling/CullTask.java b/src/main/java/dev/tr7zw/entityculling/CullTask.java index a4b77dd..2825b7b 100644 --- a/src/main/java/dev/tr7zw/entityculling/CullTask.java +++ b/src/main/java/dev/tr7zw/entityculling/CullTask.java @@ -2,7 +2,6 @@ import java.util.ConcurrentModificationException; import java.util.Iterator; -import java.util.Map.Entry; import java.util.Set; import com.logisticscraft.occlusionculling.OcclusionCullingInstance; @@ -16,7 +15,6 @@ import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.BlockPos; import net.minecraft.util.Vec3; -import net.minecraft.world.chunk.Chunk; public class CullTask implements Runnable { @@ -24,8 +22,8 @@ public class CullTask implements Runnable { private final OcclusionCullingInstance culling; private final Minecraft client = Minecraft.getMinecraft(); - private final int sleepDelay = EntityCullingModBase.instance.config.sleepDelay; - private final int hitboxLimit = EntityCullingModBase.instance.config.hitboxLimit; + private final int sleepDelay = EntityCullingMod.instance.config.sleepDelay; + private final int hitboxLimit = EntityCullingMod.instance.config.hitboxLimit; private final Set unCullable; public long lastTime = 0; @@ -45,9 +43,9 @@ public void run() { try { Thread.sleep(sleepDelay); - if (EntityCullingModBase.enabled && client.theWorld != null && client.thePlayer != null && client.thePlayer.ticksExisted > 10 && client.getRenderViewEntity() != null) { + if (EntityCullingMod.enabled && client.theWorld != null && client.thePlayer != null && client.thePlayer.ticksExisted > 10 && client.getRenderViewEntity() != null) { Vec3 cameraMC; - if(EntityCullingModBase.instance.config.debugMode) { + if(EntityCullingMod.instance.config.debugMode) { cameraMC = client.thePlayer.getPositionEyes(0); } else { cameraMC = getCameraPos(); @@ -105,7 +103,7 @@ public void run() { cullable.setCulled(false); continue; } - if(entity.getPositionVector().squareDistanceTo(cameraMC) > EntityCullingModBase.instance.config.tracingDistance * EntityCullingModBase.instance.config.tracingDistance) { + if(entity.getPositionVector().squareDistanceTo(cameraMC) > EntityCullingMod.instance.config.tracingDistance * EntityCullingMod.instance.config.tracingDistance) { cullable.setCulled(false); // If your entity view distance is larger than tracingDistance just render it continue; } @@ -177,7 +175,7 @@ private Vec3 getCameraPos() { } private boolean isSkippableArmorstand(Entity entity) { - if(!EntityCullingModBase.instance.config.skipMarkerArmorStands)return false; + if(!EntityCullingMod.instance.config.skipMarkerArmorStands)return false; return entity instanceof EntityArmorStand && ((EntityArmorStand) entity).hasMarker(); } } diff --git a/src/main/java/dev/tr7zw/entityculling/EntityCullingMod.java b/src/main/java/dev/tr7zw/entityculling/EntityCullingMod.java index 9e2fc1a..66d0cea 100644 --- a/src/main/java/dev/tr7zw/entityculling/EntityCullingMod.java +++ b/src/main/java/dev/tr7zw/entityculling/EntityCullingMod.java @@ -1,39 +1,107 @@ package dev.tr7zw.entityculling; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.logisticscraft.occlusionculling.OcclusionCullingInstance; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.client.settings.KeyBinding; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.InputEvent; -import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent; -import net.minecraftforge.fml.common.gameevent.TickEvent.WorldTickEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import org.lwjgl.input.Keyboard; @Mod(modid = "entityculling", name = "EntityCulling", version = "@VER@", clientSideOnly = true) -public class EntityCullingMod extends EntityCullingModBase { +public class EntityCullingMod { + + public static EntityCullingMod instance = new EntityCullingMod(); + public OcclusionCullingInstance culling; + public boolean debugHitboxes = false; + public static boolean enabled = true; // public static to make it faster for the jvm + public CullTask cullTask; + private Thread cullThread; + protected KeyBinding keybind = new KeyBinding("key.entityculling.toggle", Keyboard.KEY_NONE, "text.entityculling.title"); + + public Config config; + private final File settingsFile = new File("config", "entityculling.json"); + private final Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + //stats + public int renderedBlockEntities = 0; + public int skippedBlockEntities = 0; + public int renderedEntities = 0; + public int skippedEntities = 0; + //public int tickedEntities = 0; + //public int skippedEntityTicks = 0; + + // TODO: Should probably be using FMLPreInitializationEvent public EntityCullingMod() { - onInitialize(); - } + instance = this; + if (settingsFile.exists()) { + try { + config = gson.fromJson(new String(Files.readAllBytes(settingsFile.toPath()), StandardCharsets.UTF_8), + Config.class); + } catch (Exception ex) { + System.out.println("Error while loading config! Creating a new one!"); + ex.printStackTrace(); + } + } + if (config == null) { + config = new Config(); + writeConfig(); + } else { + if (ConfigUpgrader.upgradeConfig(config)) { + writeConfig(); // Config got modified + } + } + culling = new OcclusionCullingInstance(config.tracingDistance, new Provider()); + cullTask = new CullTask(culling, config.blockEntityWhitelist); - @Override - public void initModloader() { + cullThread = new Thread(cullTask, "CullThread"); + cullThread.setUncaughtExceptionHandler((thread, ex) -> { + System.out.println("The CullingThread has crashed! Please report the following stacktrace!"); + ex.printStackTrace(); + }); + cullThread.start(); } - @EventHandler + @Mod.EventHandler public void onPostInit(FMLPostInitializationEvent event) { ClientRegistry.registerKeyBinding(keybind); MinecraftForge.EVENT_BUS.register(this); } + public void writeConfig() { + if (settingsFile.exists()) { + settingsFile.delete(); + } + try { + Files.write(settingsFile.toPath(), gson.toJson(config).getBytes(StandardCharsets.UTF_8)); + } catch (IOException e1) { + e1.printStackTrace(); + } + } + @SubscribeEvent - public void doClientTick(ClientTickEvent event) { - this.clientTick(); + public void onWorldTick(TickEvent.WorldTickEvent event) { + cullTask.requestCull = true; } @SubscribeEvent - public void doWorldTick(WorldTickEvent event) { - this.worldTick(); + public void onClientTick(TickEvent.ClientTickEvent event) { + cullTask.requestCull = true; } @SubscribeEvent @@ -45,4 +113,20 @@ public void onKeyInput(InputEvent.KeyInputEvent event) { public void onMouseInput(InputEvent.MouseInputEvent event) { keyBindPressed(); } + + public void keyBindPressed() { + if (keybind.isPressed()) { + enabled = !enabled; + EntityPlayerSP player = Minecraft.getMinecraft().thePlayer; + if (enabled) { + if (player != null) { + player.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN + "Culling on")); + } + } else { + if (player != null) { + player.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Culling off")); + } + } + } + } } diff --git a/src/main/java/dev/tr7zw/entityculling/EntityCullingModBase.java b/src/main/java/dev/tr7zw/entityculling/EntityCullingModBase.java deleted file mode 100644 index c4967c6..0000000 --- a/src/main/java/dev/tr7zw/entityculling/EntityCullingModBase.java +++ /dev/null @@ -1,108 +0,0 @@ -package dev.tr7zw.entityculling; - -import java.io.File; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.logisticscraft.occlusionculling.OcclusionCullingInstance; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.entity.EntityPlayerSP; -import net.minecraft.client.settings.KeyBinding; -import net.minecraft.util.ChatComponentText; -import net.minecraft.util.EnumChatFormatting; -import org.lwjgl.input.Keyboard; - -public abstract class EntityCullingModBase { - - public static EntityCullingModBase instance = new EntityCullingMod(); - public OcclusionCullingInstance culling; - public boolean debugHitboxes = false; - public static boolean enabled = true; // public static to make it faster for the jvm - public CullTask cullTask; - private Thread cullThread; - protected KeyBinding keybind = new KeyBinding("key.entityculling.toggle", Keyboard.KEY_NONE, "text.entityculling.title"); - - public Config config; - private final File settingsFile = new File("config", "entityculling.json"); - private final Gson gson = new GsonBuilder().setPrettyPrinting().create(); - - //stats - public int renderedBlockEntities = 0; - public int skippedBlockEntities = 0; - public int renderedEntities = 0; - public int skippedEntities = 0; - //public int tickedEntities = 0; - //public int skippedEntityTicks = 0; - - public void onInitialize() { - instance = this; - if (settingsFile.exists()) { - try { - config = gson.fromJson(new String(Files.readAllBytes(settingsFile.toPath()), StandardCharsets.UTF_8), - Config.class); - } catch (Exception ex) { - System.out.println("Error while loading config! Creating a new one!"); - ex.printStackTrace(); - } - } - if (config == null) { - config = new Config(); - writeConfig(); - } else { - if(ConfigUpgrader.upgradeConfig(config)) { - writeConfig(); // Config got modified - } - } - culling = new OcclusionCullingInstance(config.tracingDistance, new Provider()); - cullTask = new CullTask(culling, config.blockEntityWhitelist); - - cullThread = new Thread(cullTask, "CullThread"); - cullThread.setUncaughtExceptionHandler((thread, ex) -> { - System.out.println("The CullingThread has crashed! Please report the following stacktrace!"); - ex.printStackTrace(); - }); - cullThread.start(); - initModloader(); - } - - public void writeConfig() { - if (settingsFile.exists()) - settingsFile.delete(); - try { - Files.write(settingsFile.toPath(), gson.toJson(config).getBytes(StandardCharsets.UTF_8)); - } catch (IOException e1) { - e1.printStackTrace(); - } - } - - public void worldTick() { - cullTask.requestCull = true; - } - - public void clientTick() { - cullTask.requestCull = true; - } - - public void keyBindPressed() { - if (keybind.isPressed()) { - enabled = !enabled; - EntityPlayerSP player = Minecraft.getMinecraft().thePlayer; - if (enabled) { - if (player != null) { - player.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN + "Culling on")); - } - } else { - if (player != null) { - player.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Culling off")); - } - } - } - } - - public abstract void initModloader(); - -} diff --git a/src/main/java/dev/tr7zw/entityculling/mixin/BlockEntityRenderDispatcherMixin.java b/src/main/java/dev/tr7zw/entityculling/mixin/BlockEntityRenderDispatcherMixin.java index b2a9b1d..3caec55 100644 --- a/src/main/java/dev/tr7zw/entityculling/mixin/BlockEntityRenderDispatcherMixin.java +++ b/src/main/java/dev/tr7zw/entityculling/mixin/BlockEntityRenderDispatcherMixin.java @@ -5,7 +5,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import dev.tr7zw.entityculling.EntityCullingModBase; +import dev.tr7zw.entityculling.EntityCullingMod; import dev.tr7zw.entityculling.access.Cullable; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; import net.minecraft.tileentity.TileEntity; @@ -17,11 +17,11 @@ public class BlockEntityRenderDispatcherMixin { public void renderTileEntityAt(TileEntity blockEntity, double p_renderTileEntityAt_2_, double d1, double d2, float f1, int p_renderTileEntityAt_9_, CallbackInfo info) { if (!((Cullable) blockEntity).isForcedVisible() && ((Cullable) blockEntity).isCulled()) { - EntityCullingModBase.instance.skippedBlockEntities++; + EntityCullingMod.instance.skippedBlockEntities++; info.cancel(); return; } - EntityCullingModBase.instance.renderedBlockEntities++; + EntityCullingMod.instance.renderedBlockEntities++; } } diff --git a/src/main/java/dev/tr7zw/entityculling/mixin/CullableMixin.java b/src/main/java/dev/tr7zw/entityculling/mixin/CullableMixin.java index 3cedbd7..2ba753c 100644 --- a/src/main/java/dev/tr7zw/entityculling/mixin/CullableMixin.java +++ b/src/main/java/dev/tr7zw/entityculling/mixin/CullableMixin.java @@ -2,7 +2,7 @@ import org.spongepowered.asm.mixin.Mixin; -import dev.tr7zw.entityculling.EntityCullingModBase; +import dev.tr7zw.entityculling.EntityCullingMod; import dev.tr7zw.entityculling.access.Cullable; import net.minecraft.entity.Entity; import net.minecraft.tileentity.TileEntity; @@ -34,7 +34,7 @@ public void setCulled(boolean value) { @Override public boolean isCulled() { - if(!EntityCullingModBase.enabled)return false; + if(!EntityCullingMod.enabled)return false; return culled; } @@ -45,7 +45,7 @@ public void setOutOfCamera(boolean value) { @Override public boolean isOutOfCamera() { - if(!EntityCullingModBase.enabled)return false; + if(!EntityCullingMod.enabled)return false; return outOfCamera; } diff --git a/src/main/java/dev/tr7zw/entityculling/mixin/DebugHudMixin.java b/src/main/java/dev/tr7zw/entityculling/mixin/DebugHudMixin.java index e3ce0d7..28b8954 100644 --- a/src/main/java/dev/tr7zw/entityculling/mixin/DebugHudMixin.java +++ b/src/main/java/dev/tr7zw/entityculling/mixin/DebugHudMixin.java @@ -7,28 +7,29 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import dev.tr7zw.entityculling.EntityCullingModBase; +import dev.tr7zw.entityculling.EntityCullingMod; import net.minecraft.client.gui.GuiOverlayDebug; @Mixin(GuiOverlayDebug.class) public class DebugHudMixin { public DebugHudMixin() { - EntityCullingModBase.instance.clientTick(); + // This is an ugly hack, but it's fine for now + EntityCullingMod.instance.onClientTick(null); } @Inject(method = "call", at = @At("RETURN")) public List getLeftText(CallbackInfoReturnable> callback) { List list = callback.getReturnValue(); - list.add("[Culling] Last pass: " + EntityCullingModBase.instance.cullTask.lastTime + "ms"); - list.add("[Culling] Rendered Block Entities: " + EntityCullingModBase.instance.renderedBlockEntities + " Skipped: " + EntityCullingModBase.instance.skippedBlockEntities); - list.add("[Culling] Rendered Entities: " + EntityCullingModBase.instance.renderedEntities + " Skipped: " + EntityCullingModBase.instance.skippedEntities); + list.add("[Culling] Last pass: " + EntityCullingMod.instance.cullTask.lastTime + "ms"); + list.add("[Culling] Rendered Block Entities: " + EntityCullingMod.instance.renderedBlockEntities + " Skipped: " + EntityCullingMod.instance.skippedBlockEntities); + list.add("[Culling] Rendered Entities: " + EntityCullingMod.instance.renderedEntities + " Skipped: " + EntityCullingMod.instance.skippedEntities); //list.add("[Culling] Ticked Entities: " + lastTickedEntities + " Skipped: " + lastSkippedEntityTicks); - EntityCullingModBase.instance.renderedBlockEntities = 0; - EntityCullingModBase.instance.skippedBlockEntities = 0; - EntityCullingModBase.instance.renderedEntities = 0; - EntityCullingModBase.instance.skippedEntities = 0; + EntityCullingMod.instance.renderedBlockEntities = 0; + EntityCullingMod.instance.skippedBlockEntities = 0; + EntityCullingMod.instance.renderedEntities = 0; + EntityCullingMod.instance.skippedEntities = 0; return list; } diff --git a/src/main/java/dev/tr7zw/entityculling/mixin/WorldRendererMixin.java b/src/main/java/dev/tr7zw/entityculling/mixin/WorldRendererMixin.java index d143bd3..68675e9 100644 --- a/src/main/java/dev/tr7zw/entityculling/mixin/WorldRendererMixin.java +++ b/src/main/java/dev/tr7zw/entityculling/mixin/WorldRendererMixin.java @@ -6,10 +6,9 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import dev.tr7zw.entityculling.EntityCullingModBase; +import dev.tr7zw.entityculling.EntityCullingMod; import dev.tr7zw.entityculling.access.Cullable; import dev.tr7zw.entityculling.access.EntityRendererInter; -import net.minecraft.client.renderer.EntityRenderer; import net.minecraft.client.renderer.entity.Render; import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.entity.Entity; @@ -29,15 +28,15 @@ public void doRenderEntity(Entity entity, double p_doRenderEntity_2_, double d1, Cullable cullable = (Cullable) entity; if (!cullable.isForcedVisible() && cullable.isCulled()) { EntityRendererInter entityRenderer = (EntityRendererInter) getEntityRenderObject(entity); - if (EntityCullingModBase.instance.config.renderNametagsThroughWalls && entityRenderer.shadowShouldShowName(entity)) { + if (EntityCullingMod.instance.config.renderNametagsThroughWalls && entityRenderer.shadowShouldShowName(entity)) { entityRenderer.shadowRenderNameTag(entity, p_doRenderEntity_2_, d1, d2); //entityRenderer.doRender(entity, entity.posX, entity.posY, entity.posZ, tickDelta, tickDelta); } - EntityCullingModBase.instance.skippedEntities++; + EntityCullingMod.instance.skippedEntities++; info.cancel(); return; } - EntityCullingModBase.instance.renderedEntities++; + EntityCullingMod.instance.renderedEntities++; cullable.setOutOfCamera(false); }