diff --git a/mod/src/main/java/dev/loki/lovisual/mixins/optimize/entity/LivingEntityLodMixin.java b/mod/src/main/java/dev/loki/lovisual/mixins/optimize/entity/LivingEntityLodMixin.java new file mode 100644 index 00000000..9c2de03d --- /dev/null +++ b/mod/src/main/java/dev/loki/lovisual/mixins/optimize/entity/LivingEntityLodMixin.java @@ -0,0 +1,43 @@ +package dev.loki.lovisual.mixins.optimize.entity; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import dev.loki.lovisual.features.module.modules.misc.optimize.entity.EntityLod; +import net.minecraft.client.renderer.entity.LivingEntityRenderer; +import net.minecraft.client.renderer.entity.state.LivingEntityRenderState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +/** + * Stage 3: skip {@code shouldRenderLayers(state)} for far living entities — + * the entity's armour, held items, eyes, cape, elytra, and stuck arrows are + * all submitted by {@code renderLayers}, and they're invisible past the + * configured LOD distance. Returning {@code false} short-circuits the whole + * layer pass for that entity. + * + *
The vanilla {@code shouldRenderLayers} returns true for every visible + * entity; we AND it with "not far" so far entities skip the layers but + * close entities render them as usual. + * + *
Ported from {@code zako.opt.mixin.entity.LivingEntityLodMixin} (ZakoOpt, + * LGPL-3.0). Original author: Zako — https://t.me/StarikZako. + * + *
Gated on the {@code entity_lod} toggle via {@link EntityLod#far(double)}. + * When the toggle is off, {@code far} returns {@code false} so the modify + * leaves the original value unchanged. + */ +@Mixin(LivingEntityRenderer.class) +public abstract class LivingEntityLodMixin { + + @ModifyExpressionValue( + method = "submit", + at = @At(value = "INVOKE", + target = "Lnet/minecraft/client/renderer/entity/LivingEntityRenderer;shouldRenderLayers(Lnet/minecraft/client/renderer/entity/state/LivingEntityRenderState;)Z") + ) + private boolean lovisual$skipFarLayers(boolean original, LivingEntityRenderState state) { + if (!original) { + return false; + } + // Stage 1 collapses player LOD into entity LOD — same toggle, same threshold. + return !EntityLod.far(state.distanceToCameraSq); + } +} diff --git a/mod/src/main/java/dev/loki/lovisual/mixins/optimize/GlCommandEncoderClearMixin.java b/mod/src/main/java/dev/loki/lovisual/mixins/optimize/gl/GlCommandEncoderClearMixin.java similarity index 97% rename from mod/src/main/java/dev/loki/lovisual/mixins/optimize/GlCommandEncoderClearMixin.java rename to mod/src/main/java/dev/loki/lovisual/mixins/optimize/gl/GlCommandEncoderClearMixin.java index 29ea2bd2..22ed2415 100644 --- a/mod/src/main/java/dev/loki/lovisual/mixins/optimize/GlCommandEncoderClearMixin.java +++ b/mod/src/main/java/dev/loki/lovisual/mixins/optimize/gl/GlCommandEncoderClearMixin.java @@ -1,4 +1,4 @@ -package dev.loki.lovisual.mixins.optimize; +package dev.loki.lovisual.mixins.optimize.gl; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; diff --git a/mod/src/main/java/dev/loki/lovisual/mixins/optimize/GlCommandEncoderTexBufferMixin.java b/mod/src/main/java/dev/loki/lovisual/mixins/optimize/gl/GlCommandEncoderTexBufferMixin.java similarity index 98% rename from mod/src/main/java/dev/loki/lovisual/mixins/optimize/GlCommandEncoderTexBufferMixin.java rename to mod/src/main/java/dev/loki/lovisual/mixins/optimize/gl/GlCommandEncoderTexBufferMixin.java index ce313052..a6dfe7ee 100644 --- a/mod/src/main/java/dev/loki/lovisual/mixins/optimize/GlCommandEncoderTexBufferMixin.java +++ b/mod/src/main/java/dev/loki/lovisual/mixins/optimize/gl/GlCommandEncoderTexBufferMixin.java @@ -1,4 +1,4 @@ -package dev.loki.lovisual.mixins.optimize; +package dev.loki.lovisual.mixins.optimize.gl; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; diff --git a/mod/src/main/java/dev/loki/lovisual/mixins/optimize/RenderTypesMixin.java b/mod/src/main/java/dev/loki/lovisual/mixins/optimize/gl/RenderTypesMixin.java similarity index 98% rename from mod/src/main/java/dev/loki/lovisual/mixins/optimize/RenderTypesMixin.java rename to mod/src/main/java/dev/loki/lovisual/mixins/optimize/gl/RenderTypesMixin.java index 701211e1..7bbc974d 100644 --- a/mod/src/main/java/dev/loki/lovisual/mixins/optimize/RenderTypesMixin.java +++ b/mod/src/main/java/dev/loki/lovisual/mixins/optimize/gl/RenderTypesMixin.java @@ -1,4 +1,4 @@ -package dev.loki.lovisual.mixins.optimize; +package dev.loki.lovisual.mixins.optimize.gl; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; diff --git a/mod/src/main/java/dev/loki/lovisual/mixins/optimize/OptimizeDebugHudMixin.java b/mod/src/main/java/dev/loki/lovisual/mixins/optimize/hud/OptimizeDebugHudMixin.java similarity index 98% rename from mod/src/main/java/dev/loki/lovisual/mixins/optimize/OptimizeDebugHudMixin.java rename to mod/src/main/java/dev/loki/lovisual/mixins/optimize/hud/OptimizeDebugHudMixin.java index d42cf8f3..1750a422 100644 --- a/mod/src/main/java/dev/loki/lovisual/mixins/optimize/OptimizeDebugHudMixin.java +++ b/mod/src/main/java/dev/loki/lovisual/mixins/optimize/hud/OptimizeDebugHudMixin.java @@ -1,4 +1,4 @@ -package dev.loki.lovisual.mixins.optimize; +package dev.loki.lovisual.mixins.optimize.hud; import dev.loki.lovisual.features.module.lifecycle.Modules; import dev.loki.lovisual.features.module.modules.misc.optimize.Optimize; diff --git a/mod/src/main/java/dev/loki/lovisual/mixins/optimize/particle/BubbleColumnUpParticleMixin.java b/mod/src/main/java/dev/loki/lovisual/mixins/optimize/particle/BubbleColumnUpParticleMixin.java new file mode 100644 index 00000000..94d802ee --- /dev/null +++ b/mod/src/main/java/dev/loki/lovisual/mixins/optimize/particle/BubbleColumnUpParticleMixin.java @@ -0,0 +1,50 @@ +package dev.loki.lovisual.mixins.optimize.particle; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import dev.loki.lovisual.features.module.modules.misc.optimize.particle.BubbleColumnCache; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.particle.BubbleColumnUpParticle; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.material.FluidState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +/** + * Stage 3: bubble-column fluid cache. {@code BubbleColumnUpParticle.tick} + * calls {@code level.getFluidState(pos)} once per particle per tick — but + * thousands of bubble particles share a few columns, so each block's fluid + * is looked up thousands of times. This mixin wraps the call to consult + * {@link BubbleColumnCache} first; on a miss, the original runs and the + * result is stored. + * + *
Ported from {@code zako.opt.mixin.particle.BubbleColumnUpParticleMixin} + * (ZakoOpt, LGPL-3.0). Original author: Zako — https://t.me/StarikZako. + * The cache logic is in {@link BubbleColumnCache} so the mixin stays a thin + * wrapper and the cache is unit-testable without Minecraft types. + * + *
Gated on the {@code microOpts} toggle (Stage 1). When the toggle is off,
+ * the original call runs unchanged.
+ */
+@Mixin(BubbleColumnUpParticle.class)
+public abstract class BubbleColumnUpParticleMixin {
+
+ @WrapOperation(
+ method = "tick",
+ at = @At(value = "INVOKE",
+ target = "Lnet/minecraft/client/multiplayer/ClientLevel;getFluidState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/material/FluidState;")
+ )
+ private FluidState lovisual$cachedFluid(ClientLevel level, BlockPos pos, Operation Three hooks:
+ * Ported from {@code zako.opt.mixin.entity.LevelRendererOutlineMixin}
+ * (ZakoOpt, LGPL-3.0). Original author: Zako — https://t.me/StarikZako.
+ *
+ * Gated on the {@code microOpts} toggle via {@link OutlineTracker#enabled()}.
+ * When the toggle is off, all hooks fall through to the vanilla call.
+ */
+@Mixin(LevelRenderer.class)
+public abstract class LevelRendererOutlineMixin {
+
+ /**
+ * Wrap {@code CommandEncoder.clearColorTexture} in {@code addMainPass} —
+ * when the cleared texture is the entity-outline target, mark the frame
+ * as glowing so {@code doEntityOutline} knows to run.
+ */
+ @WrapOperation(
+ method = "addMainPass",
+ at = @At(value = "INVOKE",
+ target = "Lcom/mojang/blaze3d/systems/CommandEncoder;clearColorTexture(Lcom/mojang/blaze3d/textures/GpuTexture;Lorg/joml/Vector4fc;)V")
+ )
+ private void lovisual$trackOutlineClear(CommandEncoder encoder, GpuTexture texture, Vector4fc color, Operation
+ *
+ *
+ *