From 5df7b09ecb1095f9a170e46ecffd3bacd8f99d03 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Sat, 13 Apr 2024 13:19:47 -0700 Subject: [PATCH] Overridden overrides - Only instance items if their *base* baked model has no overrides - ItemRenderer#getModel applies overrides internally, so we have to go directly to the ItemModelShaper - Don't filter the results of ClientLevel#entitiesForRendering, instead do an early exit in LevelRenderer#renderEntity - Avoids allocating a potentially massive list - Only need to loop over the entity list once - Visible entity counter is fixed - Would be nice to continue out of an iteration to avoid other unnecessary checks in the render loop, but I don't think there's a way to do that with mixin - Use a persistent rotation quat in InstanceTree to avoid allocations - Only call setChanged when updating instances in CowVisual, saves a ton of atomic overhead --- .../flywheel/impl/mixin/ClientLevelMixin.java | 32 ------------------- .../impl/mixin/LevelRendererMixin.java | 12 +++++++ .../flywheel/lib/model/part/InstanceTree.java | 7 ++-- .../vanilla/AgeableListComponent.java | 16 +++++----- .../jozufozu/flywheel/vanilla/CowVisual.java | 2 +- .../jozufozu/flywheel/vanilla/ItemVisual.java | 23 ++++++------- src/main/resources/flywheel.impl.mixins.json | 1 - 7 files changed, 35 insertions(+), 58 deletions(-) delete mode 100644 src/main/java/com/jozufozu/flywheel/impl/mixin/ClientLevelMixin.java diff --git a/src/main/java/com/jozufozu/flywheel/impl/mixin/ClientLevelMixin.java b/src/main/java/com/jozufozu/flywheel/impl/mixin/ClientLevelMixin.java deleted file mode 100644 index 57ffbcc71..000000000 --- a/src/main/java/com/jozufozu/flywheel/impl/mixin/ClientLevelMixin.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.jozufozu.flywheel.impl.mixin; - -import java.util.ArrayList; - -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.CallbackInfoReturnable; - -import com.google.common.collect.Lists; -import com.jozufozu.flywheel.api.visualization.VisualizationManager; -import com.jozufozu.flywheel.impl.visualization.VisualizationHelper; - -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.world.entity.Entity; - -@Mixin(ClientLevel.class) -abstract class ClientLevelMixin { - @Inject(method = "entitiesForRendering()Ljava/lang/Iterable;", at = @At("RETURN"), cancellable = true) - private void flywheel$filterEntities(CallbackInfoReturnable> cir) { - if (!VisualizationManager.supportsVisualization((ClientLevel) (Object) this)) { - return; - } - - Iterable entities = cir.getReturnValue(); - ArrayList filtered = Lists.newArrayList(entities); - - filtered.removeIf(VisualizationHelper::shouldSkipRender); - - cir.setReturnValue(filtered); - } -} diff --git a/src/main/java/com/jozufozu/flywheel/impl/mixin/LevelRendererMixin.java b/src/main/java/com/jozufozu/flywheel/impl/mixin/LevelRendererMixin.java index 05c7af4f7..6f1dfa49a 100644 --- a/src/main/java/com/jozufozu/flywheel/impl/mixin/LevelRendererMixin.java +++ b/src/main/java/com/jozufozu/flywheel/impl/mixin/LevelRendererMixin.java @@ -18,7 +18,9 @@ import com.jozufozu.flywheel.api.event.BeginFrameEvent; import com.jozufozu.flywheel.api.event.ReloadLevelRendererEvent; import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.event.RenderStageEvent; +import com.jozufozu.flywheel.api.visualization.VisualizationManager; import com.jozufozu.flywheel.impl.event.RenderContextImpl; +import com.jozufozu.flywheel.impl.visualization.VisualizationHelper; import com.jozufozu.flywheel.impl.visualization.VisualizationManagerImpl; import com.mojang.blaze3d.vertex.PoseStack; @@ -28,8 +30,10 @@ import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderBuffers; import net.minecraft.server.level.BlockDestructionProgress; +import net.minecraft.world.entity.Entity; import net.minecraftforge.common.MinecraftForge; @Mixin(value = LevelRenderer.class, priority = 1001) // Higher priority to go after Sodium @@ -79,6 +83,14 @@ abstract class LevelRendererMixin { } } + // ENTITY CANCELLING + @Inject(method = "renderEntity", at = @At("HEAD"), cancellable = true) + private void flywheel$decideNotToRenderEntity(Entity pEntity, double pCamX, double pCamY, double pCamZ, float pPartialTick, PoseStack pPoseStack, MultiBufferSource pBufferSource, CallbackInfo ci) { + if (VisualizationManager.supportsVisualization(pEntity.level()) && VisualizationHelper.shouldSkipRender(pEntity)) { + ci.cancel(); + } + } + // STAGE DISPATCHING @Unique diff --git a/src/main/java/com/jozufozu/flywheel/lib/model/part/InstanceTree.java b/src/main/java/com/jozufozu/flywheel/lib/model/part/InstanceTree.java index 40486fd98..dc1fb3e9e 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/model/part/InstanceTree.java +++ b/src/main/java/com/jozufozu/flywheel/lib/model/part/InstanceTree.java @@ -39,6 +39,7 @@ public class InstanceTree { @Nullable public TransformedInstance instance; + private final Quaternionf rotation = new Quaternionf(); private final Entry entry; private final PartPose initialPose; @@ -136,7 +137,7 @@ public class InstanceTree { void accept(T t, int i, int j); } - public void render(PoseStack pPoseStack) { + public void updateInstances(PoseStack pPoseStack) { if (this.visible) { pPoseStack.pushPose(); this.translateAndRotate(pPoseStack); @@ -146,7 +147,7 @@ public class InstanceTree { } for (InstanceTree modelpart : this.children.values()) { - modelpart.render(pPoseStack); + modelpart.updateInstances(pPoseStack); } pPoseStack.popPose(); @@ -156,7 +157,7 @@ public class InstanceTree { public void translateAndRotate(PoseStack pPoseStack) { pPoseStack.translate(this.x / 16.0F, this.y / 16.0F, this.z / 16.0F); if (this.xRot != 0.0F || this.yRot != 0.0F || this.zRot != 0.0F) { - pPoseStack.mulPose((new Quaternionf()).rotationZYX(this.zRot, this.yRot, this.xRot)); + pPoseStack.mulPose(rotation.rotationZYX(this.zRot, this.yRot, this.xRot)); } if (this.xScale != 1.0F || this.yScale != 1.0F || this.zScale != 1.0F) { diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/AgeableListComponent.java b/src/main/java/com/jozufozu/flywheel/vanilla/AgeableListComponent.java index c7ce63728..004afbfc9 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/AgeableListComponent.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/AgeableListComponent.java @@ -22,24 +22,24 @@ public abstract class AgeableListComponent { } pPoseStack.translate(0.0F, this.config.babyYHeadOffset / 16.0F, this.config.babyZHeadOffset / 16.0F); - for (InstanceTree p_102081_ : this.headParts()) { - p_102081_.render(pPoseStack); + for (InstanceTree headPart : this.headParts()) { + headPart.updateInstances(pPoseStack); } pPoseStack.popPose(); pPoseStack.pushPose(); float f1 = 1.0F / this.config.babyBodyScale; pPoseStack.scale(f1, f1, f1); pPoseStack.translate(0.0F, this.config.bodyYOffset / 16.0F, 0.0F); - for (InstanceTree p_102071_ : this.bodyParts()) { - p_102071_.render(pPoseStack); + for (InstanceTree bodyPart : this.bodyParts()) { + bodyPart.updateInstances(pPoseStack); } pPoseStack.popPose(); } else { - for (InstanceTree p_102061_ : this.headParts()) { - p_102061_.render(pPoseStack); + for (InstanceTree headPart : this.headParts()) { + headPart.updateInstances(pPoseStack); } - for (InstanceTree p_102051_ : this.bodyParts()) { - p_102051_.render(pPoseStack); + for (InstanceTree bodyPart : this.bodyParts()) { + bodyPart.updateInstances(pPoseStack); } } diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/CowVisual.java b/src/main/java/com/jozufozu/flywheel/vanilla/CowVisual.java index 734aa0b6e..a25c6e2f1 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/CowVisual.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/CowVisual.java @@ -65,7 +65,7 @@ public class CowVisual extends SimpleEntityVisual { cowQuadrupedComponent.root.walkInstances(overlay, light, (i, o, l) -> { i.setOverlay(o); i.light(l); - i.setChanged(); + // We'll #setChanged in the }); stack.setIdentity(); diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ItemVisual.java b/src/main/java/com/jozufozu/flywheel/vanilla/ItemVisual.java index 695d6f358..1877ef090 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/ItemVisual.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/ItemVisual.java @@ -18,6 +18,7 @@ import com.mojang.math.Axis; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.renderer.block.model.ItemOverrides; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.MultiPartBakedModel; import net.minecraft.client.resources.model.SimpleBakedModel; @@ -48,9 +49,7 @@ public class ItemVisual extends SimpleEntityVisual { super(ctx, entity); var item = entity.getItem(); - model = Minecraft.getInstance() - .getItemRenderer() - .getModel(item, entity.level(), null, entity.getId()); + model = getModel(item); isSupported = isSupported(model); @@ -61,11 +60,14 @@ public class ItemVisual extends SimpleEntityVisual { } public static boolean isSupported(ItemEntity entity) { - var model = Minecraft.getInstance() - .getItemRenderer() - .getModel(entity.getItem(), entity.level(), null, entity.getId()); + return isSupported(getModel(entity.getItem())); + } - return isSupported(model); + public static BakedModel getModel(ItemStack stack) { + return Minecraft.getInstance() + .getItemRenderer() + .getItemModelShaper() + .getItemModel(stack); } public static boolean isSupported(BakedModel model) { @@ -73,9 +75,7 @@ public class ItemVisual extends SimpleEntityVisual { return false; } - if (!model.getOverrides() - .getOverrides() - .isEmpty()) { + if (model.getOverrides() != ItemOverrides.EMPTY) { return false; } @@ -110,7 +110,6 @@ public class ItemVisual extends SimpleEntityVisual { .translate(getVisualPosition(ctx.partialTick())); instances.resetCount(); - pPoseStack.pushPose(); ItemStack itemstack = entity.getItem(); int i = itemstack.isEmpty() ? 187 : Item.getId(itemstack.getItem()) + itemstack.getDamageValue(); var random = RANDOM.get(); @@ -158,7 +157,6 @@ public class ItemVisual extends SimpleEntityVisual { } } - pPoseStack.popPose(); instances.discardExtra(); } @@ -199,7 +197,6 @@ public class ItemVisual extends SimpleEntityVisual { } public record ItemKey(ItemStack stack, BakedModel model) { - @Override public boolean equals(Object o) { if (this == o) { diff --git a/src/main/resources/flywheel.impl.mixins.json b/src/main/resources/flywheel.impl.mixins.json index e0ef5268d..99f47ed3c 100644 --- a/src/main/resources/flywheel.impl.mixins.json +++ b/src/main/resources/flywheel.impl.mixins.json @@ -7,7 +7,6 @@ "client": [ "BlockEntityTypeMixin", "ClientChunkCacheMixin", - "ClientLevelMixin", "EntityTypeMixin", "LevelMixin", "LevelRendererMixin",